diff --git a/config/config.ts b/config/config.ts
index 6b0a060..bdfccd5 100644
--- a/config/config.ts
+++ b/config/config.ts
@@ -1,17 +1,18 @@
+import { ConfigSpec, ValueSpecAny } from "../types.ts";
import { BuilderExtract, IBuilder } from "./builder.ts";
import { Value } from "./value.ts";
-export class Config extends IBuilder {
+export class Config extends IBuilder {
static empty() {
return new Config({});
}
- static withValue(key: K, value: Value) {
+ static withValue(key: K, value: Value) {
return new Config({
[key]: value.build(),
} as { [key in K]: B });
}
- static of }>(spec: B) {
+ static of }, C extends ValueSpecAny>(spec: B) {
// deno-lint-ignore no-explicit-any
const answer: { [K in keyof B]: BuilderExtract } = {} as any;
for (const key in spec) {
@@ -20,7 +21,7 @@ export class Config extends IBuilder {
}
return new Config(answer);
}
- addValue(key: K, value: Value) {
+ addValue(key: K, value: Value) {
return new Config({
...this.a,
[key]: value.build(),
diff --git a/config/list.ts b/config/list.ts
index 4971222..b54ec10 100644
--- a/config/list.ts
+++ b/config/list.ts
@@ -1,28 +1,32 @@
-import { UniqueBy } from "../types.ts";
+import { ConfigSpec, Tag, UniqueBy, ValueSpecList } from "../types.ts";
import { BuilderExtract, IBuilder } from "./builder.ts";
import { Config } from "./config.ts";
import { Default, NullableDefault, NumberSpec, StringSpec } from "./value.ts";
import { Description } from "./value.ts";
+import * as T from "../types.ts";
-export class List extends IBuilder {
+export class List> extends IBuilder {
// deno-lint-ignore ban-types
static boolean & { range: string; spec: {} }>(a: A) {
return new List({
+ type: "list" as const,
subtype: "boolean" as const,
...a,
});
}
static string<
- A extends Description & Default
+ A extends Description & Default & { range: string; spec: { range: string; spec: StringSpec } }
>(a: A) {
return new List({
+ type: "list" as const,
subtype: "string" as const,
...a,
- });
+ } as T.Tag<"list", T.Subtype<"string", T.WithDescription, string[]>>>>);
}
static number & { range: string; spec: NumberSpec }>(a: A) {
return new List({
+ type: "list" as const,
subtype: "number" as const,
...a,
});
@@ -40,6 +44,7 @@ export class List extends IBuilder {
}
>(a: A) {
return new List({
+ type: "list" as const,
subtype: "enum" as const,
...a,
});
@@ -54,7 +59,7 @@ export class List extends IBuilder {
"unique-by": null | UniqueBy;
};
},
- B
+ B extends ConfigSpec
>(a: A) {
const { spec: previousSpec, ...rest } = a;
const { spec: previousSpecSpec, ...restSpec } = previousSpec;
@@ -68,9 +73,10 @@ export class List extends IBuilder {
...rest,
};
return new List({
+ type: "list" as const,
subtype: "object" as const,
...value,
- });
+ } as T.Tag<"list", T.Subtype<"object", T.WithDescription, Record[]>>>>);
}
static union<
A extends Description &
@@ -90,7 +96,8 @@ export class List extends IBuilder {
"unique-by": null | UniqueBy | undefined;
};
},
- Variants extends { [key: string]: Config }
+ Variants extends { [key: string]: Config },
+ B extends ConfigSpec
>(a: A) {
const { spec: previousSpec, ...rest } = a;
const { variants: previousVariants, ...restSpec } = previousSpec;
@@ -109,6 +116,7 @@ export class List extends IBuilder {
...rest,
};
return new List({
+ type: "list" as const,
subtype: "union" as const,
...value,
});
diff --git a/config/pointer.ts b/config/pointer.ts
index 26ae61e..efd4ae2 100644
--- a/config/pointer.ts
+++ b/config/pointer.ts
@@ -1,7 +1,8 @@
+import { ValueSpecAny } from "../types.ts";
import { IBuilder } from "./builder.ts";
import { Description } from "./value.ts";
-export class Pointer extends IBuilder {
+export class Pointer extends IBuilder {
static packageTorKey(a: A) {
return new Pointer({
type: "pointer" as const,
diff --git a/config/value.ts b/config/value.ts
index c656a8d..95788dc 100644
--- a/config/value.ts
+++ b/config/value.ts
@@ -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 { Config } from "./config.ts";
import { List } from "./list.ts";
import { Pointer } from "./pointer.ts";
+export type DefaultString =
+ | string
+ | {
+ charset: string | null | undefined;
+ len: number;
+ };
export type Description = {
name: string;
description: string | null;
@@ -12,7 +20,7 @@ export type Default = {
default: A;
};
export type NullableDefault = {
- default: A | null;
+ default?: A;
};
export type StringSpec = {
@@ -38,30 +46,29 @@ export type Nullable = {
};
type _UniqueBy =
- | null
| string
| {
- any: string;
+ any: _UniqueBy[];
};
-export class Value extends IBuilder {
+export class Value extends IBuilder {
static boolean>(a: A) {
return new Value({
type: "boolean" as const,
...a,
});
}
- static string & Nullable & StringSpec>(a: A) {
+ static string & Nullable & StringSpec>(a: A) {
return new Value({
type: "string" as const,
...a,
- });
+ } as Tag<"string", T.WithDescription, DefaultString>>>);
}
static number & Nullable & NumberSpec>(a: A) {
return new Value({
type: "number" as const,
...a,
- });
+ } as Tag<"number", T.WithDescription, number>>>);
}
static enum<
A extends Description &
@@ -74,20 +81,20 @@ export class Value extends IBuilder {
}
static object<
A extends Description &
- NullableDefault> & { values: readonly string[] | string[]; "value-names": Record },
- B
+ NullableDefault<{ [k: string]: unknown }> & {
+ "display-as": null | string;
+ "unique-by": null | string;
+ spec: Config;
+ "value-names": Record;
+ },
+ B extends ConfigSpec
>(a: A) {
- const { default: previousDefault, ...rest } = a;
- if (previousDefault == null) {
- return new Value({
- type: "object" as const,
- ...rest,
- });
- }
+ const { spec: previousSpec, ...rest } = a;
+ const spec = previousSpec.build();
return new Value({
type: "object" as const,
...rest,
- default: previousDefault.build(),
+ spec,
});
}
static union<
@@ -106,8 +113,9 @@ export class Value extends IBuilder {
"unique-by": _UniqueBy | null;
},
Variants extends {
- [key: string]: Config;
- }
+ [key: string]: Config;
+ },
+ B extends ConfigSpec
>(a: A) {
const { variants: previousVariants, ...rest } = a;
// deno-lint-ignore no-explicit-any
@@ -123,13 +131,10 @@ export class Value extends IBuilder {
});
}
- static pointer(a: Pointer) {
+ static pointer(a: Pointer) {
return new Value(a.build());
}
- static list, B>(a: A) {
- return new Value({
- type: "list" as const,
- ...a.build(),
- });
+ static list, B extends Tag<"list", ValueSpecList>>(a: A) {
+ return new Value(a.build());
}
}
diff --git a/types.ts b/types.ts
index d24698f..d5329b7 100644
--- a/types.ts
+++ b/types.ts
@@ -176,9 +176,9 @@ export type WithNullableDefault = T & {
};
export type WithDescription = T & {
- description?: string;
+ description?: null | string;
name: string;
- warning?: string;
+ warning?: null | string;
};
export type ListSpec = {
@@ -212,7 +212,7 @@ export type DefaultString =
| string
| {
/** The chars available for the randome generation */
- charset?: string;
+ charset?: null | string;
/** Length that we generate to */
len: number;
};
@@ -225,17 +225,17 @@ export type ValueSpecString = (
"pattern-description": string;
}
) & {
- copyable?: boolean;
- masked?: boolean;
- placeholder?: string;
+ copyable?: null | boolean;
+ masked?: null | boolean;
+ placeholder?: null | string;
};
export type ValueSpecNumber = {
/** Something like [3,6] or [0, *) */
- range?: string;
- integral?: boolean;
+ range?: null | string;
+ integral?: null | boolean;
/** Used a description of the units */
- units?: string;
- placeholder?: number;
+ units?: null | string;
+ placeholder?: null | number;
};
export type ValueSpecBoolean = Record;
export type ValueSpecAny =
@@ -301,8 +301,8 @@ export type ValueSpecUnion = {
/** What tag for the specification, for tag unions */
tag: {
id: string;
- name?: string;
- description?: string;
+ name?: null | string;
+ description?: null | string;
"variant-names": {
[key: string]: string;
};
@@ -311,13 +311,13 @@ export type ValueSpecUnion = {
variants: {
[key: string]: ConfigSpec;
};
- "display-as"?: string;
- "unique-by"?: UniqueBy;
+ "display-as"?: null | string;
+ "unique-by"?: null | UniqueBy;
};
export type ValueSpecObject = {
spec: ConfigSpec;
- "display-as"?: string;
- "unique-by"?: UniqueBy;
+ "display-as"?: null | string;
+ "unique-by"?: null | UniqueBy;
};
export type ValueSpecList =
| Subtype<"boolean", WithDescription, boolean[]>>>