Fix StartOS 0.4 TypeScript packaging to match SDK API
This commit is contained in:
+389
@@ -0,0 +1,389 @@
|
||||
import { DeepMap } from 'deep-equality-data-structures';
|
||||
import * as P from './exver';
|
||||
/**
|
||||
* Compile-time utility type that validates a version string literal conforms to semver format.
|
||||
*
|
||||
* Resolves to `unknown` if valid, `never` if invalid. Used with {@link testTypeVersion}.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* type Valid = ValidateVersion<"1.2.3"> // unknown (valid)
|
||||
* type Invalid = ValidateVersion<"-3"> // never (invalid)
|
||||
* ```
|
||||
*/
|
||||
export type ValidateVersion<T extends String> = T extends `-${infer A}` ? never : T extends `${infer A}-${string}` ? ValidateVersion<A> : T extends `${bigint}` ? unknown : T extends `${bigint}.${infer A}` ? ValidateVersion<A> : never;
|
||||
/**
|
||||
* Compile-time utility type that validates an extended version string literal.
|
||||
*
|
||||
* Extended versions have the format `upstream:downstream` or `#flavor:upstream:downstream`.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* type Valid = ValidateExVer<"1.2.3:0"> // valid
|
||||
* type Flavored = ValidateExVer<"#bitcoin:1.0:0"> // valid
|
||||
* type Bad = ValidateExVer<"1.2-3"> // never (invalid)
|
||||
* ```
|
||||
*/
|
||||
export type ValidateExVer<T extends string> = T extends `#${string}:${infer A}:${infer B}` ? ValidateVersion<A> & ValidateVersion<B> : T extends `${infer A}:${infer B}` ? ValidateVersion<A> & ValidateVersion<B> : never;
|
||||
/**
|
||||
* Validates a tuple of extended version string literals at compile time.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* type Valid = ValidateExVers<["1.0:0", "2.0:0"]> // valid
|
||||
* ```
|
||||
*/
|
||||
export type ValidateExVers<T> = T extends [] ? unknown[] : T extends [infer A, ...infer B] ? ValidateExVer<A & string> & ValidateExVers<B> : never[];
|
||||
type Anchor = {
|
||||
type: 'Anchor';
|
||||
operator: P.CmpOp;
|
||||
version: ExtendedVersion;
|
||||
};
|
||||
type And = {
|
||||
type: 'And';
|
||||
left: VersionRange;
|
||||
right: VersionRange;
|
||||
};
|
||||
type Or = {
|
||||
type: 'Or';
|
||||
left: VersionRange;
|
||||
right: VersionRange;
|
||||
};
|
||||
type Not = {
|
||||
type: 'Not';
|
||||
value: VersionRange;
|
||||
};
|
||||
type Flavor = {
|
||||
type: 'Flavor';
|
||||
flavor: string | null;
|
||||
};
|
||||
type FlavorNot = {
|
||||
type: 'FlavorNot';
|
||||
flavors: Set<string | null>;
|
||||
};
|
||||
type FlavorAtom = Flavor | FlavorNot;
|
||||
/**
|
||||
* Splits a number line of versions in half, so that every possible semver is either to the left or right.
|
||||
* The `side` field handles inclusively.
|
||||
*
|
||||
* # Example
|
||||
* Consider the version `1.2.3`. For side=-1 the version point is like `1.2.2.999*.999*.**` (that is, 1.2.3.0.0.** is greater) and
|
||||
* for side=+1 the point is like `1.2.3.0.0.**.1` (that is, 1.2.3.0.0.** is less).
|
||||
*/
|
||||
type VersionRangePoint = {
|
||||
upstream: Version;
|
||||
downstream: Version;
|
||||
side: -1 | 1;
|
||||
};
|
||||
/**
|
||||
* Truth tables for version numbers and flavors. For each flavor we need a separate table, which
|
||||
* is quite straightforward. But in order to exhaustively enumerate the boolean values of every
|
||||
* combination of flavors and versions we also need tables for flavor negations.
|
||||
*/
|
||||
type VersionRangeTables = DeepMap<FlavorAtom, VersionRangeTable> | boolean;
|
||||
/**
|
||||
* A truth table for version numbers. This is easiest to picture as a number line, cut up into
|
||||
* ranges of versions between version points.
|
||||
*/
|
||||
declare class VersionRangeTable {
|
||||
protected points: Array<VersionRangePoint>;
|
||||
protected values: boolean[];
|
||||
private constructor();
|
||||
static zip(a: VersionRangeTable, b: VersionRangeTable, func: (a: boolean, b: boolean) => boolean): VersionRangeTable;
|
||||
/**
|
||||
* Creates a version table which is `true` for the given flavor, and `false` for any other flavor.
|
||||
*/
|
||||
static eqFlavor(flavor: string | null): VersionRangeTables;
|
||||
/**
|
||||
* Creates a version table with exactly two ranges (to the left and right of the given point) and with `false` for any other flavor.
|
||||
* This is easiest to understand by looking at `VersionRange.tables`.
|
||||
*/
|
||||
static cmpPoint(flavor: string | null, point: VersionRangePoint, left: boolean, right: boolean): VersionRangeTables;
|
||||
/**
|
||||
* Helper for `cmpPoint`.
|
||||
*/
|
||||
static cmp(version: ExtendedVersion, side: -1 | 1, left: boolean, right: boolean): VersionRangeTables;
|
||||
static not(tables: VersionRangeTables): boolean | DeepMap<FlavorAtom, VersionRangeTable, FlavorAtom, VersionRangeTable>;
|
||||
static and(a_tables: VersionRangeTables, b_tables: VersionRangeTables): VersionRangeTables;
|
||||
static or(...in_tables: VersionRangeTables[]): VersionRangeTables;
|
||||
/**
|
||||
* If this is true for all versions or false for all versions, returen that value. Otherwise return null.
|
||||
*/
|
||||
static collapse(tables: VersionRangeTables): boolean | null;
|
||||
/**
|
||||
* Expresses this truth table as a series of version range operators.
|
||||
* https://en.wikipedia.org/wiki/Canonical_normal_form#Minterms
|
||||
*/
|
||||
static minterms(tables: VersionRangeTables): VersionRange;
|
||||
}
|
||||
/**
|
||||
* Represents a parsed version range expression used to match against {@link Version} or {@link ExtendedVersion} values.
|
||||
*
|
||||
* Version ranges support standard comparison operators (`=`, `>`, `<`, `>=`, `<=`, `!=`),
|
||||
* caret (`^`) and tilde (`~`) ranges, boolean logic (`&&`, `||`, `!`), and flavor matching (`#flavor`).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const range = VersionRange.parse(">=1.0.0:0 && <2.0.0:0")
|
||||
* const version = ExtendedVersion.parse("1.5.0:0")
|
||||
* console.log(range.satisfiedBy(version)) // true
|
||||
*
|
||||
* // Combine ranges with boolean logic
|
||||
* const combined = VersionRange.and(
|
||||
* VersionRange.parse(">=1.0:0"),
|
||||
* VersionRange.parse("<3.0:0"),
|
||||
* )
|
||||
*
|
||||
* // Match a specific flavor
|
||||
* const flavored = VersionRange.parse("#bitcoin")
|
||||
* ```
|
||||
*/
|
||||
export declare class VersionRange {
|
||||
atom: Anchor | And | Or | Not | P.Any | P.None | Flavor;
|
||||
constructor(atom: Anchor | And | Or | Not | P.Any | P.None | Flavor);
|
||||
toStringParens(parent: 'And' | 'Or' | 'Not'): string;
|
||||
/** Serializes this version range back to its canonical string representation. */
|
||||
toString(): string;
|
||||
private static parseAtom;
|
||||
private static parseRange;
|
||||
/**
|
||||
* Parses a version range string into a `VersionRange`.
|
||||
*
|
||||
* @param range - A version range expression, e.g. `">=1.0.0:0 && <2.0.0:0"`, `"^1.2:0"`, `"*"`
|
||||
* @returns The parsed `VersionRange`
|
||||
* @throws If the string is not a valid version range expression
|
||||
*/
|
||||
static parse(range: string): VersionRange;
|
||||
/**
|
||||
* Creates a version range from a comparison operator and an {@link ExtendedVersion}.
|
||||
*
|
||||
* @param operator - One of `"="`, `">"`, `"<"`, `">="`, `"<="`, `"!="`, `"^"`, `"~"`
|
||||
* @param version - The version to compare against
|
||||
*/
|
||||
static anchor(operator: P.CmpOp, version: ExtendedVersion): VersionRange;
|
||||
/**
|
||||
* Creates a version range that matches only versions with the specified flavor.
|
||||
*
|
||||
* @param flavor - The flavor string to match, or `null` for the default (unflavored) variant
|
||||
*/
|
||||
static flavor(flavor: string | null): VersionRange;
|
||||
/**
|
||||
* Parses a legacy "emver" format version range string.
|
||||
*
|
||||
* @param range - A version range in the legacy emver format
|
||||
* @returns The parsed `VersionRange`
|
||||
*/
|
||||
static parseEmver(range: string): VersionRange;
|
||||
/** Returns the intersection of this range with another (logical AND). */
|
||||
and(right: VersionRange): VersionRange;
|
||||
/** Returns the union of this range with another (logical OR). */
|
||||
or(right: VersionRange): VersionRange;
|
||||
/** Returns the negation of this range (logical NOT). */
|
||||
not(): VersionRange;
|
||||
/**
|
||||
* Returns the logical AND (intersection) of multiple version ranges.
|
||||
* Short-circuits on `none()` and skips `any()`.
|
||||
*/
|
||||
static and(...xs: Array<VersionRange>): VersionRange;
|
||||
/**
|
||||
* Returns the logical OR (union) of multiple version ranges.
|
||||
* Short-circuits on `any()` and skips `none()`.
|
||||
*/
|
||||
static or(...xs: Array<VersionRange>): VersionRange;
|
||||
/** Returns a version range that matches all versions (wildcard `*`). */
|
||||
static any(): VersionRange;
|
||||
/** Returns a version range that matches no versions (`!`). */
|
||||
static none(): VersionRange;
|
||||
/**
|
||||
* Returns `true` if the given version satisfies this range.
|
||||
*
|
||||
* @param version - A {@link Version} or {@link ExtendedVersion} to test
|
||||
*/
|
||||
satisfiedBy(version: Version | ExtendedVersion): boolean;
|
||||
tables(): VersionRangeTables;
|
||||
/** Returns `true` if any version exists that could satisfy this range. */
|
||||
satisfiable(): boolean;
|
||||
/** Returns `true` if this range and `other` share at least one satisfying version. */
|
||||
intersects(other: VersionRange): boolean;
|
||||
/**
|
||||
* Returns a canonical (simplified) form of this range using minterm expansion.
|
||||
* Useful for normalizing complex boolean expressions into a minimal representation.
|
||||
*/
|
||||
normalize(): VersionRange;
|
||||
}
|
||||
/**
|
||||
* Represents a semantic version number with numeric segments and optional prerelease identifiers.
|
||||
*
|
||||
* Follows semver precedence rules: numeric segments are compared left-to-right,
|
||||
* and a version with prerelease identifiers has lower precedence than the same version without.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const v = Version.parse("1.2.3")
|
||||
* console.log(v.toString()) // "1.2.3"
|
||||
* console.log(v.compare(Version.parse("1.3.0"))) // "less"
|
||||
*
|
||||
* const pre = Version.parse("2.0.0-beta.1")
|
||||
* console.log(pre.compare(Version.parse("2.0.0"))) // "less" (prerelease < release)
|
||||
* ```
|
||||
*/
|
||||
export declare class Version {
|
||||
/** The numeric version segments (e.g. `[1, 2, 3]` for `"1.2.3"`). */
|
||||
number: number[];
|
||||
/** Optional prerelease identifiers (e.g. `["beta", 1]` for `"-beta.1"`). */
|
||||
prerelease: (string | number)[];
|
||||
constructor(
|
||||
/** The numeric version segments (e.g. `[1, 2, 3]` for `"1.2.3"`). */
|
||||
number: number[],
|
||||
/** Optional prerelease identifiers (e.g. `["beta", 1]` for `"-beta.1"`). */
|
||||
prerelease: (string | number)[]);
|
||||
/** Serializes this version to its string form (e.g. `"1.2.3"` or `"1.0.0-beta.1"`). */
|
||||
toString(): string;
|
||||
/**
|
||||
* Compares this version against another using semver precedence rules.
|
||||
*
|
||||
* @param other - The version to compare against
|
||||
* @returns `'greater'`, `'equal'`, or `'less'`
|
||||
*/
|
||||
compare(other: Version): 'greater' | 'equal' | 'less';
|
||||
/**
|
||||
* Compares two versions, returning a numeric value suitable for use with `Array.sort()`.
|
||||
*
|
||||
* @returns `-1` if less, `0` if equal, `1` if greater
|
||||
*/
|
||||
compareForSort(other: Version): -1 | 0 | 1;
|
||||
/**
|
||||
* Parses a version string into a `Version` instance.
|
||||
*
|
||||
* @param version - A semver-compatible string, e.g. `"1.2.3"` or `"1.0.0-beta.1"`
|
||||
* @throws If the string is not a valid version
|
||||
*/
|
||||
static parse(version: string): Version;
|
||||
/**
|
||||
* Returns `true` if this version satisfies the given {@link VersionRange}.
|
||||
* Internally treats this as an unflavored {@link ExtendedVersion} with downstream `0`.
|
||||
*/
|
||||
satisfies(versionRange: VersionRange): boolean;
|
||||
}
|
||||
/**
|
||||
* Represents an extended version with an optional flavor, an upstream version, and a downstream version.
|
||||
*
|
||||
* The format is `#flavor:upstream:downstream` (e.g. `#bitcoin:1.2.3:0`) or `upstream:downstream`
|
||||
* for unflavored versions. Flavors allow multiple variants of a package to coexist.
|
||||
*
|
||||
* - **flavor**: An optional string identifier for the variant (e.g. `"bitcoin"`, `"litecoin"`)
|
||||
* - **upstream**: The version of the upstream software being packaged
|
||||
* - **downstream**: The version of the StartOS packaging itself
|
||||
*
|
||||
* Versions with different flavors are incomparable (comparison returns `null`).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const v = ExtendedVersion.parse("#bitcoin:1.2.3:0")
|
||||
* console.log(v.flavor) // "bitcoin"
|
||||
* console.log(v.upstream) // Version { number: [1, 2, 3] }
|
||||
* console.log(v.downstream) // Version { number: [0] }
|
||||
* console.log(v.toString()) // "#bitcoin:1.2.3:0"
|
||||
*
|
||||
* const range = VersionRange.parse(">=1.0.0:0")
|
||||
* console.log(v.satisfies(range)) // true
|
||||
* ```
|
||||
*/
|
||||
export declare class ExtendedVersion {
|
||||
/** The flavor identifier (e.g. `"bitcoin"`), or `null` for unflavored versions. */
|
||||
flavor: string | null;
|
||||
/** The upstream software version. */
|
||||
upstream: Version;
|
||||
/** The downstream packaging version. */
|
||||
downstream: Version;
|
||||
constructor(
|
||||
/** The flavor identifier (e.g. `"bitcoin"`), or `null` for unflavored versions. */
|
||||
flavor: string | null,
|
||||
/** The upstream software version. */
|
||||
upstream: Version,
|
||||
/** The downstream packaging version. */
|
||||
downstream: Version);
|
||||
/** Serializes this extended version to its string form (e.g. `"#bitcoin:1.2.3:0"` or `"1.0.0:1"`). */
|
||||
toString(): string;
|
||||
/**
|
||||
* Compares this extended version against another.
|
||||
*
|
||||
* @returns `'greater'`, `'equal'`, `'less'`, or `null` if the flavors differ (incomparable)
|
||||
*/
|
||||
compare(other: ExtendedVersion): 'greater' | 'equal' | 'less' | null;
|
||||
/**
|
||||
* Lexicographic comparison — compares flavors alphabetically first, then versions.
|
||||
* Unlike {@link compare}, this never returns `null`: different flavors are ordered alphabetically.
|
||||
*/
|
||||
compareLexicographic(other: ExtendedVersion): 'greater' | 'equal' | 'less';
|
||||
/**
|
||||
* Returns a numeric comparison result suitable for use with `Array.sort()`.
|
||||
* Uses lexicographic ordering (flavors sorted alphabetically, then by version).
|
||||
*/
|
||||
compareForSort(other: ExtendedVersion): 1 | 0 | -1;
|
||||
/** Returns `true` if this version is strictly greater than `other`. Returns `false` if flavors differ. */
|
||||
greaterThan(other: ExtendedVersion): boolean;
|
||||
/** Returns `true` if this version is greater than or equal to `other`. Returns `false` if flavors differ. */
|
||||
greaterThanOrEqual(other: ExtendedVersion): boolean;
|
||||
/** Returns `true` if this version equals `other` (same flavor, upstream, and downstream). */
|
||||
equals(other: ExtendedVersion): boolean;
|
||||
/** Returns `true` if this version is strictly less than `other`. Returns `false` if flavors differ. */
|
||||
lessThan(other: ExtendedVersion): boolean;
|
||||
/** Returns `true` if this version is less than or equal to `other`. Returns `false` if flavors differ. */
|
||||
lessThanOrEqual(other: ExtendedVersion): boolean;
|
||||
/**
|
||||
* Parses an extended version string into an `ExtendedVersion`.
|
||||
*
|
||||
* @param extendedVersion - A string like `"1.2.3:0"` or `"#bitcoin:1.0.0:0"`
|
||||
* @throws If the string is not a valid extended version
|
||||
*/
|
||||
static parse(extendedVersion: string): ExtendedVersion;
|
||||
/**
|
||||
* Parses a legacy "emver" format extended version string.
|
||||
*
|
||||
* @param extendedVersion - A version string in the legacy emver format
|
||||
* @throws If the string is not a valid emver version (error message includes the input string)
|
||||
*/
|
||||
static parseEmver(extendedVersion: string): ExtendedVersion;
|
||||
/**
|
||||
* Returns an ExtendedVersion with the Upstream major version version incremented by 1
|
||||
* and sets subsequent digits to zero.
|
||||
* If no non-zero upstream digit can be found the last upstream digit will be incremented.
|
||||
*/
|
||||
incrementMajor(): ExtendedVersion;
|
||||
/**
|
||||
* Returns an ExtendedVersion with the Upstream minor version version incremented by 1
|
||||
* also sets subsequent digits to zero.
|
||||
* If no non-zero upstream digit can be found the last digit will be incremented.
|
||||
*/
|
||||
incrementMinor(): ExtendedVersion;
|
||||
/**
|
||||
* Returns a boolean indicating whether a given version satisfies the VersionRange
|
||||
* !( >= 1:1 <= 2:2) || <=#bitcoin:1.2.0-alpha:0
|
||||
*/
|
||||
satisfies(versionRange: VersionRange): boolean;
|
||||
}
|
||||
/**
|
||||
* Compile-time type-checking helper that validates an extended version string literal.
|
||||
* If the string is invalid, TypeScript will report a type error at the call site.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* testTypeExVer("1.2.3:0") // compiles
|
||||
* testTypeExVer("#bitcoin:1.0:0") // compiles
|
||||
* testTypeExVer("invalid") // type error
|
||||
* ```
|
||||
*/
|
||||
export declare const testTypeExVer: <T extends string>(t: T & ValidateExVer<T>) => T & ValidateExVer<T>;
|
||||
/**
|
||||
* Compile-time type-checking helper that validates a version string literal.
|
||||
* If the string is invalid, TypeScript will report a type error at the call site.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* testTypeVersion("1.2.3") // compiles
|
||||
* testTypeVersion("-3") // type error
|
||||
* ```
|
||||
*/
|
||||
export declare const testTypeVersion: <T extends string>(t: T & ValidateVersion<T>) => T & ValidateVersion<T>;
|
||||
export {};
|
||||
Reference in New Issue
Block a user