mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-30 12:21:57 +00:00
chore: Make the expanded types extended, so that way we know we are outputing the correct type.
This commit is contained in:
@@ -1,17 +1,18 @@
|
|||||||
|
import { ConfigSpec, ValueSpecAny } from "../types.ts";
|
||||||
import { BuilderExtract, IBuilder } from "./builder.ts";
|
import { BuilderExtract, IBuilder } from "./builder.ts";
|
||||||
import { Value } from "./value.ts";
|
import { Value } from "./value.ts";
|
||||||
|
|
||||||
export class Config<A> extends IBuilder<A> {
|
export class Config<A extends ConfigSpec> extends IBuilder<A> {
|
||||||
static empty() {
|
static empty() {
|
||||||
return new Config({});
|
return new Config({});
|
||||||
}
|
}
|
||||||
static withValue<K extends string, B>(key: K, value: Value<B>) {
|
static withValue<K extends string, B extends ValueSpecAny>(key: K, value: Value<B>) {
|
||||||
return new Config({
|
return new Config({
|
||||||
[key]: value.build(),
|
[key]: value.build(),
|
||||||
} as { [key in K]: B });
|
} as { [key in K]: B });
|
||||||
}
|
}
|
||||||
|
|
||||||
static of<B extends { [key: string]: Value<unknown> }>(spec: B) {
|
static of<B extends { [key: string]: Value<C> }, C extends ValueSpecAny>(spec: B) {
|
||||||
// deno-lint-ignore no-explicit-any
|
// deno-lint-ignore no-explicit-any
|
||||||
const answer: { [K in keyof B]: BuilderExtract<B[K]> } = {} as any;
|
const answer: { [K in keyof B]: BuilderExtract<B[K]> } = {} as any;
|
||||||
for (const key in spec) {
|
for (const key in spec) {
|
||||||
@@ -20,7 +21,7 @@ export class Config<A> extends IBuilder<A> {
|
|||||||
}
|
}
|
||||||
return new Config(answer);
|
return new Config(answer);
|
||||||
}
|
}
|
||||||
addValue<K extends string, B>(key: K, value: Value<B>) {
|
addValue<K extends string, B extends ValueSpecAny>(key: K, value: Value<B>) {
|
||||||
return new Config({
|
return new Config({
|
||||||
...this.a,
|
...this.a,
|
||||||
[key]: value.build(),
|
[key]: value.build(),
|
||||||
|
|||||||
@@ -1,28 +1,32 @@
|
|||||||
import { UniqueBy } from "../types.ts";
|
import { ConfigSpec, Tag, UniqueBy, ValueSpecList } from "../types.ts";
|
||||||
import { BuilderExtract, IBuilder } from "./builder.ts";
|
import { BuilderExtract, IBuilder } from "./builder.ts";
|
||||||
import { Config } from "./config.ts";
|
import { Config } from "./config.ts";
|
||||||
import { Default, NullableDefault, NumberSpec, StringSpec } from "./value.ts";
|
import { Default, NullableDefault, NumberSpec, StringSpec } from "./value.ts";
|
||||||
import { Description } from "./value.ts";
|
import { Description } from "./value.ts";
|
||||||
|
import * as T from "../types.ts";
|
||||||
|
|
||||||
export class List<A> extends IBuilder<A> {
|
export class List<A extends Tag<"list", ValueSpecList>> extends IBuilder<A> {
|
||||||
// deno-lint-ignore ban-types
|
// deno-lint-ignore ban-types
|
||||||
static boolean<A extends Description & Default<boolean[]> & { range: string; spec: {} }>(a: A) {
|
static boolean<A extends Description & Default<boolean[]> & { range: string; spec: {} }>(a: A) {
|
||||||
return new List({
|
return new List({
|
||||||
|
type: "list" as const,
|
||||||
subtype: "boolean" as const,
|
subtype: "boolean" as const,
|
||||||
...a,
|
...a,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static string<
|
static string<
|
||||||
A extends Description & Default<string[] & { range: string; spec: null | { range: string; spec: StringSpec } }>
|
A extends Description & Default<string[]> & { range: string; spec: { range: string; spec: StringSpec } }
|
||||||
>(a: A) {
|
>(a: A) {
|
||||||
return new List({
|
return new List({
|
||||||
|
type: "list" as const,
|
||||||
subtype: "string" as const,
|
subtype: "string" as const,
|
||||||
...a,
|
...a,
|
||||||
});
|
} as T.Tag<"list", T.Subtype<"string", T.WithDescription<T.WithDefault<T.ListSpec<T.ValueSpecString>, string[]>>>>);
|
||||||
}
|
}
|
||||||
static number<A extends Description & Default<number[]> & { range: string; spec: NumberSpec }>(a: A) {
|
static number<A extends Description & Default<number[]> & { range: string; spec: NumberSpec }>(a: A) {
|
||||||
return new List({
|
return new List({
|
||||||
|
type: "list" as const,
|
||||||
subtype: "number" as const,
|
subtype: "number" as const,
|
||||||
...a,
|
...a,
|
||||||
});
|
});
|
||||||
@@ -40,6 +44,7 @@ export class List<A> extends IBuilder<A> {
|
|||||||
}
|
}
|
||||||
>(a: A) {
|
>(a: A) {
|
||||||
return new List({
|
return new List({
|
||||||
|
type: "list" as const,
|
||||||
subtype: "enum" as const,
|
subtype: "enum" as const,
|
||||||
...a,
|
...a,
|
||||||
});
|
});
|
||||||
@@ -54,7 +59,7 @@ export class List<A> extends IBuilder<A> {
|
|||||||
"unique-by": null | UniqueBy;
|
"unique-by": null | UniqueBy;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
B
|
B extends ConfigSpec
|
||||||
>(a: A) {
|
>(a: A) {
|
||||||
const { spec: previousSpec, ...rest } = a;
|
const { spec: previousSpec, ...rest } = a;
|
||||||
const { spec: previousSpecSpec, ...restSpec } = previousSpec;
|
const { spec: previousSpecSpec, ...restSpec } = previousSpec;
|
||||||
@@ -68,9 +73,10 @@ export class List<A> extends IBuilder<A> {
|
|||||||
...rest,
|
...rest,
|
||||||
};
|
};
|
||||||
return new List({
|
return new List({
|
||||||
|
type: "list" as const,
|
||||||
subtype: "object" as const,
|
subtype: "object" as const,
|
||||||
...value,
|
...value,
|
||||||
});
|
} as T.Tag<"list", T.Subtype<"object", T.WithDescription<T.WithNullableDefault<T.ListSpec<T.ValueSpecObject>, Record<string, unknown>[]>>>>);
|
||||||
}
|
}
|
||||||
static union<
|
static union<
|
||||||
A extends Description &
|
A extends Description &
|
||||||
@@ -90,7 +96,8 @@ export class List<A> extends IBuilder<A> {
|
|||||||
"unique-by": null | UniqueBy | undefined;
|
"unique-by": null | UniqueBy | undefined;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
Variants extends { [key: string]: Config<unknown> }
|
Variants extends { [key: string]: Config<ConfigSpec> },
|
||||||
|
B extends ConfigSpec
|
||||||
>(a: A) {
|
>(a: A) {
|
||||||
const { spec: previousSpec, ...rest } = a;
|
const { spec: previousSpec, ...rest } = a;
|
||||||
const { variants: previousVariants, ...restSpec } = previousSpec;
|
const { variants: previousVariants, ...restSpec } = previousSpec;
|
||||||
@@ -109,6 +116,7 @@ export class List<A> extends IBuilder<A> {
|
|||||||
...rest,
|
...rest,
|
||||||
};
|
};
|
||||||
return new List({
|
return new List({
|
||||||
|
type: "list" as const,
|
||||||
subtype: "union" as const,
|
subtype: "union" as const,
|
||||||
...value,
|
...value,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
import { ValueSpecAny } from "../types.ts";
|
||||||
import { IBuilder } from "./builder.ts";
|
import { IBuilder } from "./builder.ts";
|
||||||
import { Description } from "./value.ts";
|
import { Description } from "./value.ts";
|
||||||
|
|
||||||
export class Pointer<A> extends IBuilder<A> {
|
export class Pointer<A extends ValueSpecAny> extends IBuilder<A> {
|
||||||
static packageTorKey<A extends Description & { "package-id": string; interface: string }>(a: A) {
|
static packageTorKey<A extends Description & { "package-id": string; interface: string }>(a: A) {
|
||||||
return new Pointer({
|
return new Pointer({
|
||||||
type: "pointer" as const,
|
type: "pointer" as const,
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
|
import { ConfigSpec, Tag, ValueSpecAny, ValueSpecList } from "../types.ts";
|
||||||
|
import * as T from "../types.ts";
|
||||||
import { BuilderExtract, IBuilder } from "./builder.ts";
|
import { BuilderExtract, IBuilder } from "./builder.ts";
|
||||||
import { Config } from "./config.ts";
|
import { Config } from "./config.ts";
|
||||||
import { List } from "./list.ts";
|
import { List } from "./list.ts";
|
||||||
import { Pointer } from "./pointer.ts";
|
import { Pointer } from "./pointer.ts";
|
||||||
|
|
||||||
|
export type DefaultString =
|
||||||
|
| string
|
||||||
|
| {
|
||||||
|
charset: string | null | undefined;
|
||||||
|
len: number;
|
||||||
|
};
|
||||||
export type Description = {
|
export type Description = {
|
||||||
name: string;
|
name: string;
|
||||||
description: string | null;
|
description: string | null;
|
||||||
@@ -12,7 +20,7 @@ export type Default<A> = {
|
|||||||
default: A;
|
default: A;
|
||||||
};
|
};
|
||||||
export type NullableDefault<A> = {
|
export type NullableDefault<A> = {
|
||||||
default: A | null;
|
default?: A;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type StringSpec = {
|
export type StringSpec = {
|
||||||
@@ -38,30 +46,29 @@ export type Nullable = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type _UniqueBy =
|
type _UniqueBy =
|
||||||
| null
|
|
||||||
| string
|
| string
|
||||||
| {
|
| {
|
||||||
any: string;
|
any: _UniqueBy[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Value<A> extends IBuilder<A> {
|
export class Value<A extends ValueSpecAny> extends IBuilder<A> {
|
||||||
static boolean<A extends Description & Default<boolean>>(a: A) {
|
static boolean<A extends Description & Default<boolean>>(a: A) {
|
||||||
return new Value({
|
return new Value({
|
||||||
type: "boolean" as const,
|
type: "boolean" as const,
|
||||||
...a,
|
...a,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static string<A extends Description & NullableDefault<string> & Nullable & StringSpec>(a: A) {
|
static string<A extends Description & NullableDefault<DefaultString> & Nullable & StringSpec>(a: A) {
|
||||||
return new Value({
|
return new Value({
|
||||||
type: "string" as const,
|
type: "string" as const,
|
||||||
...a,
|
...a,
|
||||||
});
|
} as Tag<"string", T.WithDescription<T.WithNullableDefault<T.WithNullable<T.ValueSpecString>, DefaultString>>>);
|
||||||
}
|
}
|
||||||
static number<A extends Description & NullableDefault<number> & Nullable & NumberSpec>(a: A) {
|
static number<A extends Description & NullableDefault<number> & Nullable & NumberSpec>(a: A) {
|
||||||
return new Value({
|
return new Value({
|
||||||
type: "number" as const,
|
type: "number" as const,
|
||||||
...a,
|
...a,
|
||||||
});
|
} as Tag<"number", T.WithDescription<T.WithNullableDefault<T.WithNullable<T.ValueSpecNumber>, number>>>);
|
||||||
}
|
}
|
||||||
static enum<
|
static enum<
|
||||||
A extends Description &
|
A extends Description &
|
||||||
@@ -74,20 +81,20 @@ export class Value<A> extends IBuilder<A> {
|
|||||||
}
|
}
|
||||||
static object<
|
static object<
|
||||||
A extends Description &
|
A extends Description &
|
||||||
NullableDefault<Config<B>> & { values: readonly string[] | string[]; "value-names": Record<string, string> },
|
NullableDefault<{ [k: string]: unknown }> & {
|
||||||
B
|
"display-as": null | string;
|
||||||
|
"unique-by": null | string;
|
||||||
|
spec: Config<B>;
|
||||||
|
"value-names": Record<string, string>;
|
||||||
|
},
|
||||||
|
B extends ConfigSpec
|
||||||
>(a: A) {
|
>(a: A) {
|
||||||
const { default: previousDefault, ...rest } = a;
|
const { spec: previousSpec, ...rest } = a;
|
||||||
if (previousDefault == null) {
|
const spec = previousSpec.build();
|
||||||
return new Value({
|
|
||||||
type: "object" as const,
|
|
||||||
...rest,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return new Value({
|
return new Value({
|
||||||
type: "object" as const,
|
type: "object" as const,
|
||||||
...rest,
|
...rest,
|
||||||
default: previousDefault.build(),
|
spec,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static union<
|
static union<
|
||||||
@@ -106,8 +113,9 @@ export class Value<A> extends IBuilder<A> {
|
|||||||
"unique-by": _UniqueBy | null;
|
"unique-by": _UniqueBy | null;
|
||||||
},
|
},
|
||||||
Variants extends {
|
Variants extends {
|
||||||
[key: string]: Config<unknown>;
|
[key: string]: Config<B>;
|
||||||
}
|
},
|
||||||
|
B extends ConfigSpec
|
||||||
>(a: A) {
|
>(a: A) {
|
||||||
const { variants: previousVariants, ...rest } = a;
|
const { variants: previousVariants, ...rest } = a;
|
||||||
// deno-lint-ignore no-explicit-any
|
// deno-lint-ignore no-explicit-any
|
||||||
@@ -123,13 +131,10 @@ export class Value<A> extends IBuilder<A> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static pointer<A>(a: Pointer<A>) {
|
static pointer<A extends ValueSpecAny>(a: Pointer<A>) {
|
||||||
return new Value(a.build());
|
return new Value(a.build());
|
||||||
}
|
}
|
||||||
static list<A extends List<B>, B>(a: A) {
|
static list<A extends List<B>, B extends Tag<"list", ValueSpecList>>(a: A) {
|
||||||
return new Value({
|
return new Value(a.build());
|
||||||
type: "list" as const,
|
|
||||||
...a.build(),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
types.ts
32
types.ts
@@ -176,9 +176,9 @@ export type WithNullableDefault<T, Default> = T & {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type WithDescription<T> = T & {
|
export type WithDescription<T> = T & {
|
||||||
description?: string;
|
description?: null | string;
|
||||||
name: string;
|
name: string;
|
||||||
warning?: string;
|
warning?: null | string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ListSpec<T> = {
|
export type ListSpec<T> = {
|
||||||
@@ -212,7 +212,7 @@ export type DefaultString =
|
|||||||
| string
|
| string
|
||||||
| {
|
| {
|
||||||
/** The chars available for the randome generation */
|
/** The chars available for the randome generation */
|
||||||
charset?: string;
|
charset?: null | string;
|
||||||
/** Length that we generate to */
|
/** Length that we generate to */
|
||||||
len: number;
|
len: number;
|
||||||
};
|
};
|
||||||
@@ -225,17 +225,17 @@ export type ValueSpecString = (
|
|||||||
"pattern-description": string;
|
"pattern-description": string;
|
||||||
}
|
}
|
||||||
) & {
|
) & {
|
||||||
copyable?: boolean;
|
copyable?: null | boolean;
|
||||||
masked?: boolean;
|
masked?: null | boolean;
|
||||||
placeholder?: string;
|
placeholder?: null | string;
|
||||||
};
|
};
|
||||||
export type ValueSpecNumber = {
|
export type ValueSpecNumber = {
|
||||||
/** Something like [3,6] or [0, *) */
|
/** Something like [3,6] or [0, *) */
|
||||||
range?: string;
|
range?: null | string;
|
||||||
integral?: boolean;
|
integral?: null | boolean;
|
||||||
/** Used a description of the units */
|
/** Used a description of the units */
|
||||||
units?: string;
|
units?: null | string;
|
||||||
placeholder?: number;
|
placeholder?: null | number;
|
||||||
};
|
};
|
||||||
export type ValueSpecBoolean = Record<string, unknown>;
|
export type ValueSpecBoolean = Record<string, unknown>;
|
||||||
export type ValueSpecAny =
|
export type ValueSpecAny =
|
||||||
@@ -301,8 +301,8 @@ export type ValueSpecUnion = {
|
|||||||
/** What tag for the specification, for tag unions */
|
/** What tag for the specification, for tag unions */
|
||||||
tag: {
|
tag: {
|
||||||
id: string;
|
id: string;
|
||||||
name?: string;
|
name?: null | string;
|
||||||
description?: string;
|
description?: null | string;
|
||||||
"variant-names": {
|
"variant-names": {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
};
|
};
|
||||||
@@ -311,13 +311,13 @@ export type ValueSpecUnion = {
|
|||||||
variants: {
|
variants: {
|
||||||
[key: string]: ConfigSpec;
|
[key: string]: ConfigSpec;
|
||||||
};
|
};
|
||||||
"display-as"?: string;
|
"display-as"?: null | string;
|
||||||
"unique-by"?: UniqueBy;
|
"unique-by"?: null | UniqueBy;
|
||||||
};
|
};
|
||||||
export type ValueSpecObject = {
|
export type ValueSpecObject = {
|
||||||
spec: ConfigSpec;
|
spec: ConfigSpec;
|
||||||
"display-as"?: string;
|
"display-as"?: null | string;
|
||||||
"unique-by"?: UniqueBy;
|
"unique-by"?: null | UniqueBy;
|
||||||
};
|
};
|
||||||
export type ValueSpecList =
|
export type ValueSpecList =
|
||||||
| Subtype<"boolean", WithDescription<WithDefault<ListSpec<ValueSpecBoolean>, boolean[]>>>
|
| Subtype<"boolean", WithDescription<WithDefault<ListSpec<ValueSpecBoolean>, boolean[]>>>
|
||||||
|
|||||||
Reference in New Issue
Block a user