@builder-builder/builder 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/check.d.ts +2 -1
- package/dist/check.js +6 -2
- package/dist/entities/builder/builder.d.ts +494 -0
- package/dist/entities/builder/builder.js +84 -0
- package/dist/entities/builder/builders.d.ts +20 -0
- package/dist/entities/builder/builders.js +18 -0
- package/dist/entities/builder/expectation.d.ts +12 -0
- package/dist/entities/builder/index.d.ts +7 -0
- package/dist/entities/builder/index.js +3 -0
- package/dist/entities/builder/methods.d.ts +58 -0
- package/dist/entities/builder/methods.js +30 -0
- package/dist/entities/builder/parameter.d.ts +62 -0
- package/dist/entities/builder/parameter.js +18 -0
- package/dist/entities/builder/state.d.ts +26 -0
- package/dist/entities/builder/validate.d.ts +3 -0
- package/dist/entities/builder/validate.js +108 -0
- package/dist/entities/collection/collection.d.ts +37 -0
- package/dist/entities/collection/collection.js +42 -0
- package/dist/entities/collection/config.d.ts +1094 -0
- package/dist/entities/collection/config.js +23 -0
- package/dist/entities/collection/expectation.d.ts +7 -0
- package/dist/entities/collection/expectation.js +4 -0
- package/dist/entities/collection/index.d.ts +8 -0
- package/dist/entities/collection/index.js +4 -0
- package/dist/entities/collection/when.d.ts +9 -0
- package/dist/entities/collection/when.js +2 -0
- package/dist/entities/component/component.d.ts +403 -0
- package/dist/entities/component/component.js +24 -0
- package/dist/entities/component/details.d.ts +82 -0
- package/dist/entities/component/details.js +17 -0
- package/dist/entities/component/expectation.d.ts +8 -0
- package/dist/entities/component/expectation.js +7 -0
- package/dist/entities/component/index.d.ts +8 -0
- package/dist/entities/component/index.js +4 -0
- package/dist/entities/component/when.d.ts +11 -0
- package/dist/entities/component/when.js +20 -0
- package/dist/entities/errors.d.ts +21 -0
- package/dist/entities/expectation.d.ts +44 -0
- package/dist/entities/expectation.js +23 -0
- package/dist/entities/index.d.ts +18 -0
- package/dist/entities/index.js +9 -0
- package/dist/entities/option/expectation.d.ts +2 -0
- package/dist/entities/option/expectation.js +4 -0
- package/dist/entities/option/index.d.ts +11 -0
- package/dist/entities/option/index.js +6 -0
- package/dist/entities/option/option.d.ts +347 -0
- package/dist/entities/option/option.js +24 -0
- package/dist/entities/option/select.d.ts +49 -0
- package/dist/entities/option/select.js +40 -0
- package/dist/entities/option/toggle.d.ts +39 -0
- package/dist/entities/option/toggle.js +42 -0
- package/dist/entities/option/values.d.ts +63 -0
- package/dist/entities/option/values.js +8 -0
- package/dist/entities/option/when.d.ts +9 -0
- package/dist/entities/option/when.js +2 -0
- package/dist/entities/serialise.d.ts +3801 -0
- package/dist/entities/serialise.js +41 -0
- package/dist/entities/ui/describe.d.ts +100 -0
- package/dist/entities/ui/describe.js +22 -0
- package/dist/entities/ui/index.d.ts +14 -0
- package/dist/entities/ui/index.js +7 -0
- package/dist/entities/ui/label.d.ts +18 -0
- package/dist/entities/ui/label.js +12 -0
- package/dist/entities/ui/page.d.ts +96 -0
- package/dist/entities/ui/page.js +20 -0
- package/dist/entities/ui/pages.d.ts +431 -0
- package/dist/entities/ui/pages.js +29 -0
- package/dist/entities/ui/parameter.d.ts +7 -0
- package/dist/entities/ui/parameter.js +29 -0
- package/dist/entities/ui/ui.d.ts +1582 -0
- package/dist/entities/ui/ui.js +53 -0
- package/dist/entities/ui/uis.d.ts +10 -0
- package/dist/entities/ui/uis.js +20 -0
- package/dist/entities/ui/validate.d.ts +8 -0
- package/dist/entities/ui/validate.js +21 -0
- package/dist/entities/validate.d.ts +28 -0
- package/dist/entities/validate.js +1 -0
- package/dist/entities/when.d.ts +176 -0
- package/dist/entities/when.js +47 -0
- package/dist/exception.d.ts +8 -0
- package/dist/exception.js +7 -0
- package/dist/index.d.ts +38 -13
- package/dist/index.js +23 -5
- package/dist/mappers/assert/builder.d.ts +2 -0
- package/dist/mappers/assert/builder.js +46 -0
- package/dist/mappers/assert/expectation.d.ts +2 -0
- package/dist/mappers/assert/expectation.js +23 -0
- package/dist/mappers/assert/index.d.ts +6 -0
- package/dist/mappers/assert/index.js +4 -0
- package/dist/mappers/assert/model.d.ts +13 -0
- package/dist/mappers/assert/model.js +47 -0
- package/dist/mappers/assert/models.d.ts +33 -0
- package/dist/mappers/assert/models.js +74 -0
- package/dist/mappers/assert/ui.d.ts +2 -0
- package/dist/mappers/assert/ui.js +22 -0
- package/dist/mappers/index.d.ts +7 -0
- package/dist/mappers/index.js +4 -0
- package/dist/mappers/instance/index.d.ts +1 -0
- package/dist/mappers/instance/index.js +1 -0
- package/dist/mappers/instance/instance.d.ts +4 -0
- package/dist/mappers/instance/instance.js +33 -0
- package/dist/mappers/models/component-graph.d.ts +9 -0
- package/dist/{core/component/graph.js → mappers/models/component-graph.js} +3 -3
- package/dist/{core → mappers/models}/graph.d.ts +4 -1
- package/dist/mappers/models/graph.js +17 -0
- package/dist/mappers/models/index.d.ts +1 -0
- package/dist/mappers/models/index.js +1 -0
- package/dist/mappers/models/models.d.ts +3 -0
- package/dist/mappers/models/models.js +37 -0
- package/dist/mappers/models/option-graph.d.ts +9 -0
- package/dist/mappers/models/option-graph.js +77 -0
- package/dist/mappers/order/index.d.ts +2 -0
- package/dist/mappers/order/index.js +1 -0
- package/dist/mappers/order/order.d.ts +14 -0
- package/dist/mappers/order/order.js +31 -0
- package/dist/mappers/render/index.d.ts +4 -0
- package/dist/mappers/render/index.js +2 -0
- package/dist/mappers/render/ordinal.d.ts +1 -0
- package/dist/mappers/render/ordinal.js +20 -0
- package/dist/mappers/render/pages.d.ts +15 -0
- package/dist/mappers/render/pages.js +1 -0
- package/dist/mappers/render/render.d.ts +8 -0
- package/dist/mappers/render/render.js +124 -0
- package/dist/mappers/resolve.d.ts +9 -0
- package/dist/mappers/resolve.js +57 -0
- package/dist/model.d.ts +8 -8
- package/dist/paths.d.ts +5 -16
- package/dist/paths.js +3 -0
- package/dist/primitive.d.ts +5 -0
- package/dist/{schemas/primitives.js → primitive.js} +0 -2
- package/dist/references.d.ts +60 -0
- package/dist/references.js +26 -0
- package/dist/serialisable.d.ts +10 -0
- package/dist/serialisable.js +5 -0
- package/dist/walker/index.d.ts +2 -0
- package/dist/walker/index.js +1 -0
- package/dist/walker/walkable.d.ts +4 -0
- package/dist/walker/walkable.js +4 -0
- package/dist/walker/walker.d.ts +18 -0
- package/dist/walker/walker.js +103 -0
- package/dist/walker/walkers.d.ts +8 -0
- package/dist/walker/walkers.js +51 -0
- package/package.json +8 -2
- package/dist/core/builder.d.ts +0 -74
- package/dist/core/builder.js +0 -109
- package/dist/core/collection/collection.d.ts +0 -32
- package/dist/core/collection/collection.js +0 -37
- package/dist/core/collection/index.d.ts +0 -4
- package/dist/core/collection/index.js +0 -2
- package/dist/core/collection/method.d.ts +0 -30
- package/dist/core/collection/method.js +0 -11
- package/dist/core/component/component.d.ts +0 -9
- package/dist/core/component/component.js +0 -10
- package/dist/core/component/graph.d.ts +0 -9
- package/dist/core/component/index.d.ts +0 -4
- package/dist/core/component/index.js +0 -2
- package/dist/core/component/method.d.ts +0 -11
- package/dist/core/expectation.d.ts +0 -42
- package/dist/core/expectation.js +0 -18
- package/dist/core/graph.js +0 -3
- package/dist/core/index.d.ts +0 -14
- package/dist/core/index.js +0 -7
- package/dist/core/option/graph.d.ts +0 -10
- package/dist/core/option/graph.js +0 -78
- package/dist/core/option/index.d.ts +0 -10
- package/dist/core/option/index.js +0 -5
- package/dist/core/option/method.d.ts +0 -70
- package/dist/core/option/method.js +0 -13
- package/dist/core/option/option.d.ts +0 -30
- package/dist/core/option/option.js +0 -42
- package/dist/core/option/select.d.ts +0 -22
- package/dist/core/option/select.js +0 -34
- package/dist/core/option/toggle.d.ts +0 -16
- package/dist/core/option/toggle.js +0 -29
- package/dist/core/parameter.d.ts +0 -48
- package/dist/core/parameter.js +0 -31
- package/dist/core/validate.d.ts +0 -26
- package/dist/core/validate.js +0 -43
- package/dist/core/when/config.d.ts +0 -20
- package/dist/core/when/config.js +0 -4
- package/dist/core/when/constrain.d.ts +0 -14
- package/dist/core/when/index.d.ts +0 -5
- package/dist/core/when/index.js +0 -2
- package/dist/core/when/nullability.d.ts +0 -18
- package/dist/core/when/resolve.d.ts +0 -18
- package/dist/core/when/resolve.js +0 -22
- package/dist/resolve/index.d.ts +0 -10
- package/dist/resolve/index.js +0 -5
- package/dist/resolve/instance.d.ts +0 -35
- package/dist/resolve/instance.js +0 -80
- package/dist/resolve/models.d.ts +0 -3
- package/dist/resolve/models.js +0 -20
- package/dist/resolve/order.d.ts +0 -21
- package/dist/resolve/order.js +0 -27
- package/dist/resolve/render.d.ts +0 -23
- package/dist/resolve/render.js +0 -171
- package/dist/resolve/validate.d.ts +0 -37
- package/dist/resolve/validate.js +0 -47
- package/dist/schemas/description.d.ts +0 -5
- package/dist/schemas/description.js +0 -3
- package/dist/schemas/index.d.ts +0 -6
- package/dist/schemas/index.js +0 -3
- package/dist/schemas/primitives.d.ts +0 -9
- package/dist/schemas/ui.d.ts +0 -96
- package/dist/schemas/ui.js +0 -23
- package/dist/serialise/deserialise.d.ts +0 -14
- package/dist/serialise/deserialise.js +0 -119
- package/dist/serialise/index.d.ts +0 -6
- package/dist/serialise/index.js +0 -4
- package/dist/serialise/schemas.d.ts +0 -1946
- package/dist/serialise/schemas.js +0 -150
- package/dist/serialise/serialise.d.ts +0 -13
- package/dist/serialise/serialise.js +0 -147
- package/dist/serialise/validate.d.ts +0 -26
- package/dist/serialise/validate.js +0 -148
- package/dist/ui.d.ts +0 -19
- package/dist/ui.js +0 -44
- /package/dist/{core/component/method.js → entities/builder/expectation.js} +0 -0
- /package/dist/{core/when/constrain.js → entities/builder/state.js} +0 -0
- /package/dist/{core/when/nullability.js → entities/errors.js} +0 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Prettify } from '../../prettify';
|
|
2
|
+
import type { CollectionsAsserted } from '../collection/index';
|
|
3
|
+
import type { ComponentAsserted } from '../component/index';
|
|
4
|
+
import type { BuilderExpectation, BuilderExpectations } from '../expectation';
|
|
5
|
+
import type { BuilderState, BuilderStateAppend } from './state';
|
|
6
|
+
export type BuilderStateAsserted<State extends BuilderState, Expectations extends BuilderExpectations> = BuilderStateAppend<State, {
|
|
7
|
+
model: ModelAsserted<State, Expectations>;
|
|
8
|
+
components: ComponentAsserted<State, Expectations>;
|
|
9
|
+
collections: CollectionsAsserted<State, Expectations>;
|
|
10
|
+
}>;
|
|
11
|
+
export type ModelExpected<Expectations extends BuilderExpectations> = Expectations extends readonly [infer Head, ...infer Tail extends BuilderExpectations] ? (Head extends BuilderExpectation<infer Name, infer Value, 'option'> ? Record<Name, Value> : Head extends BuilderExpectation<infer Name, any, 'collection'> ? Record<Name, ReadonlyArray<unknown>> : unknown) & ModelExpected<Tail> : unknown;
|
|
12
|
+
export type ModelAsserted<State extends BuilderState, Expectations extends BuilderExpectations, Current extends State['model'] = State['model'], Asserted extends ModelExpected<Expectations> = ModelExpected<Expectations>> = unknown extends Current ? Prettify<Asserted> : Prettify<Current & Asserted>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { BuilderGeneric, BuilderInstanceOf, BuilderReference, BuilderReferences, BuilderSerialised, BuilderStateOf } from './builder';
|
|
2
|
+
export type { BuilderStateAsserted, ModelAsserted, ModelExpected } from './expectation';
|
|
3
|
+
export type { BindingModelType, BuilderBindings, BuilderBoundState } from './parameter';
|
|
4
|
+
export type { BuilderState, BuilderStateAppend, BuilderStateEmpty } from './state';
|
|
5
|
+
export { Builder, BuilderSchema, BuilderSerialisedSchema } from './builder.js';
|
|
6
|
+
export { builders, mergeBuilderParts } from './builders.js';
|
|
7
|
+
export { bindBuilder } from './parameter.js';
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { BuilderPaths } from '../../paths';
|
|
2
|
+
import type { BuilderRef, Refable } from '../../references';
|
|
3
|
+
import type { WhenConfigPayload } from '../when';
|
|
4
|
+
import type { BuilderCollectionConfig, BuilderCollectionWhen } from '../collection/index';
|
|
5
|
+
import type { BuilderComponentDetails, BuilderComponentWhen } from '../component/index';
|
|
6
|
+
import type { BuilderOptionValues, BuilderOptionWhen } from '../option/index';
|
|
7
|
+
import type { BuilderValidPaths, BuilderWhenConstrained, WhenNullability } from '../when';
|
|
8
|
+
import type { Builder } from './builder';
|
|
9
|
+
import type { BuilderState, BuilderStateAppend } from './state';
|
|
10
|
+
import { BuilderCollection } from '../collection/index.js';
|
|
11
|
+
import { BuilderComponent } from '../component/index.js';
|
|
12
|
+
import { BuilderOption } from '../option/index.js';
|
|
13
|
+
export type BuilderOptionMethod<State extends BuilderState> = {
|
|
14
|
+
<const Name extends string, const Payload extends Refable<BuilderOptionValues>>(name: Name, payload: Payload): OptionStateAppend<State, BuilderOption<Name, Payload>>;
|
|
15
|
+
when: <const GatePaths extends Refable<BuilderValidPaths<State>>, const Name extends string, const Payload extends Refable<BuilderOptionWhen>>(gatePaths: GatePaths, name: Name, payload: Payload & BuilderWhenConstrained<State, Payload>) => OptionStateAppend<State, OptionWhenResolver<Name, Payload>, OptionModelOf<OptionWhenResolver<Name, Payload>> | WhenNullability<State, GatePaths, Payload>>;
|
|
16
|
+
};
|
|
17
|
+
export type BuilderComponentMethod<State extends BuilderState> = {
|
|
18
|
+
<const Name extends string, const Payload extends Refable<BuilderComponentDetails>>(name: Name, payload?: Payload): ComponentStateAppend<State, BuilderComponent<Name, Payload>>;
|
|
19
|
+
when: <const GatePaths extends Refable<BuilderValidPaths<State>>, const Name extends string, const Payload extends Refable<BuilderComponentWhen>>(gatePaths: GatePaths, name: Name, payload?: Payload & BuilderWhenConstrained<State, Payload>) => ComponentStateAppend<State, ComponentWhenResolver<Name, Payload>>;
|
|
20
|
+
};
|
|
21
|
+
export type BuilderCollectionMethod<State extends BuilderState> = {
|
|
22
|
+
<const Name extends string, const Payload extends Refable<BuilderCollectionConfig>>(name: Name, payload: Payload): CollectionStateAppend<State, BuilderCollection<Name, Payload>>;
|
|
23
|
+
when: <const GatePaths extends Refable<BuilderValidPaths<State>>, const Name extends string, const Payload extends Refable<BuilderCollectionWhen>>(gatePaths: GatePaths, name: Name, payload: Payload & BuilderWhenConstrained<State, Payload>) => CollectionStateAppend<State, CollectionWhenResolver<Name, Payload>, CollectionModelOf<CollectionWhenResolver<Name, Payload>> | WhenNullability<State, GatePaths, Payload>>;
|
|
24
|
+
};
|
|
25
|
+
type OptionWhenResolver<Name extends string, Payload extends Refable<BuilderOptionWhen>> = Payload extends BuilderOptionWhen ? BuilderOption<Name, WhenConfigPayload<Payload, BuilderOptionValues>> : BuilderOption<Name, BuilderRef>;
|
|
26
|
+
type ComponentWhenResolver<Name extends string, Payload extends Refable<BuilderComponentWhen>> = Payload extends BuilderComponentWhen ? BuilderComponent<Name, WhenConfigPayload<Payload, BuilderComponentDetails>> : BuilderComponent<Name, BuilderRef>;
|
|
27
|
+
type CollectionWhenResolver<Name extends string, Payload extends Refable<BuilderCollectionWhen>> = Payload extends BuilderCollectionWhen ? BuilderCollection<Name, WhenConfigPayload<Payload, BuilderCollectionConfig>> : BuilderCollection<Name, BuilderRef>;
|
|
28
|
+
type OptionStateAppend<State extends BuilderState, Option extends BuilderOption, ModelType = OptionModelOf<Option>> = Builder<BuilderStateAppend<State, {
|
|
29
|
+
model: State['model'] & {
|
|
30
|
+
[K in Option['name']]: ModelType;
|
|
31
|
+
};
|
|
32
|
+
options: [...State['options'], Option];
|
|
33
|
+
}>>;
|
|
34
|
+
type ComponentStateAppend<State extends BuilderState, Component extends BuilderComponent> = Builder<BuilderStateAppend<State, {
|
|
35
|
+
components: [...State['components'], Component];
|
|
36
|
+
}>>;
|
|
37
|
+
type CollectionStateAppend<State extends BuilderState, Collection extends BuilderCollection, ModelType = CollectionModelOf<Collection>> = Builder<BuilderStateAppend<State, {
|
|
38
|
+
model: State['model'] & Record<Collection['name'], ModelType>;
|
|
39
|
+
collections: [...State['collections'], Collection];
|
|
40
|
+
}>>;
|
|
41
|
+
type OptionModelOf<Option extends BuilderOption> = Option['payload'] extends BuilderRef ? string : Option['payload'] extends {
|
|
42
|
+
readonly value: infer Value;
|
|
43
|
+
} ? Value : never;
|
|
44
|
+
type CollectionModelOf<Collection extends BuilderCollection> = [Collection['payload']] extends [
|
|
45
|
+
never
|
|
46
|
+
] ? null : Collection['payload'] extends BuilderCollectionConfig ? Collection['payload']['builder'] extends Builder<infer State extends BuilderState> ? CollectionShape<Collection, State['model']> : ReadonlyArray<unknown> : ReadonlyArray<unknown>;
|
|
47
|
+
type CollectionShape<Collection extends BuilderCollection, Item> = Collection['payload'] extends BuilderCollectionConfig ? Collection['payload']['min'] extends number ? Collection['payload']['max'] extends number ? number extends Collection['payload']['min'] ? ReadonlyArray<Item> : number extends Collection['payload']['max'] ? ReadonlyArray<Item> : Collection['payload']['min'] extends Collection['payload']['max'] ? CollectionTuple<Item, Collection['payload']['min']> : ReadonlyArray<Item> : ReadonlyArray<Item> : ReadonlyArray<Item> : ReadonlyArray<Item>;
|
|
48
|
+
type CollectionTuple<Item, Length extends number, Result extends ReadonlyArray<Item> = []> = Result['length'] extends Length ? Result : CollectionTuple<Item, Length, [...Result, Item]>;
|
|
49
|
+
export declare function builderOptionMethod(): ((name: string, payload: Refable<BuilderOptionValues>) => BuilderOption<string, Refable<import("..").BuilderSelectType<readonly [string, ...string[]], import("valibot").GenericSchema<string | null>> | import("..").BuilderToggleType<import("valibot").GenericSchema<string | number | boolean | null>>>, Refable<readonly (readonly (string | number)[])[]>>) & {
|
|
50
|
+
when(gatePaths: Refable<BuilderPaths>, name: string, payload: Refable<BuilderOptionWhen>): BuilderOption<string, Refable<BuilderOptionWhen>, readonly (readonly (string | number)[])[] | BuilderRef>;
|
|
51
|
+
};
|
|
52
|
+
export declare function builderComponentMethod(): ((name: string, payload?: Refable<BuilderComponentDetails>) => BuilderComponent<string, Refable<BuilderComponentDetails<Refable<readonly import("..").BuilderExpectation<string, unknown, "option" | "component" | "collection" | "detail">[]>>> | import("../when").BuilderEnableConfig<Refable<BuilderComponentDetails<Refable<readonly import("..").BuilderExpectation<string, unknown, "option" | "component" | "collection" | "detail">[]>>>>, Refable<readonly (readonly (string | number)[])[]>>) & {
|
|
53
|
+
when(gatePaths: Refable<BuilderPaths>, name: string, payload?: Refable<BuilderComponentWhen>): BuilderComponent<string, Refable<BuilderComponentWhen>, readonly (readonly (string | number)[])[] | BuilderRef>;
|
|
54
|
+
};
|
|
55
|
+
export declare function builderCollectionMethod(): ((name: string, payload: Refable<BuilderCollectionConfig>) => BuilderCollection<string, Refable<BuilderCollectionConfig<Refable<import("./builder").BuilderGeneric>, Refable<number>, Refable<number>>>, Refable<readonly (readonly (string | number)[])[]>>) & {
|
|
56
|
+
when(gatePaths: Refable<BuilderPaths>, name: string, payload: Refable<BuilderCollectionWhen>): BuilderCollection<string, Refable<BuilderCollectionWhen>, readonly (readonly (string | number)[])[] | BuilderRef>;
|
|
57
|
+
};
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { BuilderCollection } from '../collection/index.js';
|
|
2
|
+
import { BuilderComponent, componentWhen } from '../component/index.js';
|
|
3
|
+
import { BuilderOption } from '../option/index.js';
|
|
4
|
+
export function builderOptionMethod() {
|
|
5
|
+
return Object.assign((name, payload) => {
|
|
6
|
+
return new BuilderOption(name, payload);
|
|
7
|
+
}, {
|
|
8
|
+
when(gatePaths, name, payload) {
|
|
9
|
+
return new BuilderOption(name, payload, gatePaths);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export function builderComponentMethod() {
|
|
14
|
+
return Object.assign((name, payload) => {
|
|
15
|
+
return new BuilderComponent(name, payload ?? componentWhen.enable());
|
|
16
|
+
}, {
|
|
17
|
+
when(gatePaths, name, payload) {
|
|
18
|
+
return new BuilderComponent(name, payload ?? componentWhen.enable(), gatePaths);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export function builderCollectionMethod() {
|
|
23
|
+
return Object.assign((name, payload) => {
|
|
24
|
+
return new BuilderCollection(name, payload);
|
|
25
|
+
}, {
|
|
26
|
+
when(gatePaths, name, payload) {
|
|
27
|
+
return new BuilderCollection(name, payload, gatePaths);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { BuilderPaths } from '../../paths';
|
|
2
|
+
import type { BuilderRef, Refable } from '../../references';
|
|
3
|
+
import type { BuilderCollectionPayload } from '../collection/index';
|
|
4
|
+
import type { BuilderComponentPayload } from '../component/index';
|
|
5
|
+
import type { BuilderOptionPayload } from '../option/index';
|
|
6
|
+
import type { BuilderWhenConfig, BuilderWhenConstrained, WhenConfigNullable } from '../when';
|
|
7
|
+
import type { BuilderState, BuilderStateAppend } from './state';
|
|
8
|
+
import { Builder } from './builder.js';
|
|
9
|
+
type ParameterNamesOf<Entries extends ReadonlyArray<EntryLike>> = EntryParameters<Entries>['name'];
|
|
10
|
+
type PayloadForParameter<State extends BuilderState, Name extends string> = Name extends ParameterNamesOf<State['options']> ? BuilderOptionPayload : Name extends ParameterNamesOf<State['collections']> ? BuilderCollectionPayload : Name extends ParameterNamesOf<State['components']> ? BuilderComponentPayload : never;
|
|
11
|
+
export type BuilderBindings<State extends BuilderState> = {
|
|
12
|
+
readonly [Name in ParameterNamesOf<State['options']> | ParameterNamesOf<State['collections']> | ParameterNamesOf<State['components']>]: BuilderWhenConstrained<State, PayloadForParameter<State, Name>>;
|
|
13
|
+
};
|
|
14
|
+
export declare function bindBuilder<State extends BuilderState, Bindings extends BuilderBindings<State>>(builder: Builder<State>, bindings: Bindings): Builder<BuilderBoundState<State, Bindings>>;
|
|
15
|
+
export type BuilderBoundState<State extends BuilderState, Bindings extends BuilderBindings<State>> = BuilderStateAppend<State, {
|
|
16
|
+
options: EntryBound<State['options'], Extract<keyof Bindings, string>>;
|
|
17
|
+
collections: EntryBound<State['collections'], Extract<keyof Bindings, string>>;
|
|
18
|
+
components: EntryBound<State['components'], Extract<keyof Bindings, string>>;
|
|
19
|
+
model: Omit<State['model'], keyof Bindings> & {
|
|
20
|
+
[K in Extract<keyof Bindings, string>]: BindingModelType<Bindings[K]>;
|
|
21
|
+
};
|
|
22
|
+
}>;
|
|
23
|
+
export type BindingModelType<Binding> = BindingValueType<Binding> | BindingConfigNullable<Binding>;
|
|
24
|
+
type BindingValueType<Binding> = Binding extends {
|
|
25
|
+
readonly type: 'match';
|
|
26
|
+
readonly selectMap: infer SelectMap extends Record<string, unknown>;
|
|
27
|
+
} ? NonNullable<SelectMap[keyof SelectMap]> extends {
|
|
28
|
+
readonly value: infer Value;
|
|
29
|
+
} ? Value : string : Binding extends {
|
|
30
|
+
readonly payload: {
|
|
31
|
+
readonly value: infer Value;
|
|
32
|
+
};
|
|
33
|
+
} ? Value : Binding extends {
|
|
34
|
+
readonly value: infer Value;
|
|
35
|
+
} ? Value : string;
|
|
36
|
+
type BindingConfigNullable<Binding> = Binding extends BuilderWhenConfig ? WhenConfigNullable<Binding> : never;
|
|
37
|
+
type EntryLike = {
|
|
38
|
+
readonly name: string;
|
|
39
|
+
readonly payload: unknown;
|
|
40
|
+
readonly gatePaths?: Refable<BuilderPaths>;
|
|
41
|
+
};
|
|
42
|
+
type EntryBound<Entries extends ReadonlyArray<EntryLike>, BoundNames extends string> = Entries extends readonly [
|
|
43
|
+
infer Head extends EntryLike,
|
|
44
|
+
...infer Tail extends ReadonlyArray<EntryLike>
|
|
45
|
+
] ? Head extends {
|
|
46
|
+
readonly payload: infer Payload;
|
|
47
|
+
} ? Payload extends BuilderRef ? Head['name'] extends BoundNames ? [...EntryBound<Tail, BoundNames>] : [Head, ...EntryBound<Tail, BoundNames>] : [Head, ...EntryBound<Tail, BoundNames>] : [Head, ...EntryBound<Tail, BoundNames>] : [];
|
|
48
|
+
type EntryParameters<Entries extends ReadonlyArray<EntryLike>> = Entries[number] extends infer Entry ? Entry extends {
|
|
49
|
+
readonly payload: infer Payload;
|
|
50
|
+
} ? PayloadParameters<Payload> : never : never;
|
|
51
|
+
type PayloadParameters<Payload> = ParameterOf<Payload> | (Payload extends {
|
|
52
|
+
readonly type: 'match';
|
|
53
|
+
readonly selectMap: infer SelectMap;
|
|
54
|
+
} ? ParameterOf<SelectMap[keyof SelectMap]> : never) | (Payload extends {
|
|
55
|
+
readonly type: 'enable' | 'unless';
|
|
56
|
+
readonly payload: infer Inner;
|
|
57
|
+
} ? ParameterOf<Inner> : never);
|
|
58
|
+
type ParameterOf<Value> = Extract<Value, BuilderRef> extends infer Ref extends BuilderRef ? {
|
|
59
|
+
readonly name: Ref['name'];
|
|
60
|
+
readonly payload: Ref;
|
|
61
|
+
} : never;
|
|
62
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
import { isRef } from '../../references.js';
|
|
3
|
+
import { createWalkerBinding } from '../../walker/index.js';
|
|
4
|
+
import { Builder, BuilderSchema, BuilderSerialisedSchema } from './builder.js';
|
|
5
|
+
import { mergeBuilderParts } from './builders.js';
|
|
6
|
+
export function bindBuilder(builder, bindings) {
|
|
7
|
+
const { expectations, references } = builder;
|
|
8
|
+
const bindingEntries = Object.entries(bindings);
|
|
9
|
+
const boundNames = new Set(bindingEntries.filter(([, value]) => v.is(BuilderSchema, value)).map(([name]) => name));
|
|
10
|
+
const remainingReferences = references.filter((reference) => !isRef(reference) || !boundNames.has(reference.name));
|
|
11
|
+
const bindingLookup = bindings;
|
|
12
|
+
const walkBind = createWalkerBinding({
|
|
13
|
+
lookupBinding: (ref) => bindingLookup[ref.name]
|
|
14
|
+
});
|
|
15
|
+
const walked = walkBind(BuilderSerialisedSchema, builder);
|
|
16
|
+
const merged = mergeBuilderParts(bindingEntries.map(([, value]) => value));
|
|
17
|
+
return new Builder([...remainingReferences, ...merged.references], [...walked.options, ...merged.options], [...walked.components, ...merged.components], [...walked.collections, ...merged.collections], [...expectations, ...merged.expectations]);
|
|
18
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Prettify } from '../../prettify';
|
|
2
|
+
import type { BuilderRefs } from '../../references';
|
|
3
|
+
import type { BuilderCollections } from '../collection/index';
|
|
4
|
+
import type { BuilderComponents } from '../component/index';
|
|
5
|
+
import type { BuilderOptions } from '../option/index';
|
|
6
|
+
export type BuilderState = {
|
|
7
|
+
model: unknown;
|
|
8
|
+
references: BuilderRefs;
|
|
9
|
+
options: BuilderOptions;
|
|
10
|
+
components: BuilderComponents;
|
|
11
|
+
collections: BuilderCollections;
|
|
12
|
+
};
|
|
13
|
+
export type BuilderStateEmpty = {
|
|
14
|
+
readonly model: unknown;
|
|
15
|
+
readonly references: [];
|
|
16
|
+
readonly options: [];
|
|
17
|
+
readonly components: [];
|
|
18
|
+
readonly collections: [];
|
|
19
|
+
};
|
|
20
|
+
export type BuilderStateAppend<State extends BuilderState, Patch extends Partial<BuilderState>> = {
|
|
21
|
+
model: Prettify<'model' extends keyof Patch ? Patch['model'] : State['model']>;
|
|
22
|
+
references: 'references' extends keyof Patch ? Extract<Patch['references'], BuilderRefs> : State['references'];
|
|
23
|
+
options: Extract<'options' extends keyof Patch ? Patch['options'] : State['options'], BuilderOptions>;
|
|
24
|
+
components: Extract<'components' extends keyof Patch ? Patch['components'] : State['components'], BuilderComponents>;
|
|
25
|
+
collections: Extract<'collections' extends keyof Patch ? Patch['collections'] : State['collections'], BuilderCollections>;
|
|
26
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
import { BuilderException } from '../../exception.js';
|
|
3
|
+
import { isRef } from '../../references.js';
|
|
4
|
+
import { BuilderCollectionConfigSchema } from '../collection/index.js';
|
|
5
|
+
import { BuilderWhenMatchSchema, BuilderWhenUnlessSchema } from '../when.js';
|
|
6
|
+
export function validateDuplicates(builder) {
|
|
7
|
+
const kinds = [
|
|
8
|
+
{ entryKind: 'option', entries: builder.options },
|
|
9
|
+
{ entryKind: 'component', entries: builder.components },
|
|
10
|
+
{ entryKind: 'collection', entries: builder.collections }
|
|
11
|
+
];
|
|
12
|
+
const errors = kinds.flatMap(({ entryKind, entries }) => {
|
|
13
|
+
const seen = new Set();
|
|
14
|
+
return entries.flatMap((entry) => {
|
|
15
|
+
if (seen.has(entry.name)) {
|
|
16
|
+
return [{ kind: 'duplicate-name', entryKind, name: entry.name }];
|
|
17
|
+
}
|
|
18
|
+
seen.add(entry.name);
|
|
19
|
+
return [];
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
if (errors.length > 0) {
|
|
23
|
+
throw new BuilderException(errors);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function validatePaths(builder) {
|
|
27
|
+
const errors = collectPathErrors(builder);
|
|
28
|
+
if (errors.length > 0) {
|
|
29
|
+
throw new BuilderException(errors);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function collectPathErrors(builder) {
|
|
33
|
+
if (builder.expectations.length > 0) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
const allEntries = [...builder.options, ...builder.components, ...builder.collections];
|
|
37
|
+
return allEntries.flatMap((entry) => pathsForEntry(entry).flatMap((path) => collectEntryPathErrors(builder, entry.name, path)));
|
|
38
|
+
}
|
|
39
|
+
function pathsForEntry(entry) {
|
|
40
|
+
const gatePaths = entry.gatePaths != null && !isRef(entry.gatePaths)
|
|
41
|
+
? entry.gatePaths
|
|
42
|
+
: [];
|
|
43
|
+
const configPaths = pathsFromWhen(entry.payload);
|
|
44
|
+
return [...gatePaths, ...configPaths];
|
|
45
|
+
}
|
|
46
|
+
function pathsFromWhen(payload) {
|
|
47
|
+
if (v.is(BuilderWhenMatchSchema, payload)) {
|
|
48
|
+
const matchPath = payload.matchPath;
|
|
49
|
+
return isRef(matchPath) ? [] : [matchPath];
|
|
50
|
+
}
|
|
51
|
+
if (v.is(BuilderWhenUnlessSchema, payload)) {
|
|
52
|
+
const unlessPath = payload.unlessPath;
|
|
53
|
+
return isRef(unlessPath) ? [] : [unlessPath];
|
|
54
|
+
}
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
function collectEntryPathErrors(builder, entryName, path) {
|
|
58
|
+
const collectionSegments = path.slice(0, -1);
|
|
59
|
+
const optionName = path.at(-1);
|
|
60
|
+
const reached = traverseCollections([builder], collectionSegments);
|
|
61
|
+
if (reached === null) {
|
|
62
|
+
return [{ kind: 'invalid-gate-path', name: entryName, path }];
|
|
63
|
+
}
|
|
64
|
+
const anyHasOption = reached.some((current) => current.options.some((option) => option.name === optionName));
|
|
65
|
+
return anyHasOption ? [] : [{ kind: 'invalid-gate-path', name: entryName, path }];
|
|
66
|
+
}
|
|
67
|
+
function traverseCollections(candidates, remaining) {
|
|
68
|
+
if (remaining.length === 0) {
|
|
69
|
+
return candidates;
|
|
70
|
+
}
|
|
71
|
+
const [collectionName, index, ...rest] = remaining;
|
|
72
|
+
if (!v.is(v.string(), collectionName) || !v.is(v.number(), index)) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
const descents = candidates.map((current) => descendCollection(current, collectionName, index));
|
|
76
|
+
if (descents.some((descent) => descent === null)) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
const nextCandidates = descents.flatMap((descent) => descent ?? []);
|
|
80
|
+
if (nextCandidates.length === 0) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
return traverseCollections(nextCandidates, rest);
|
|
84
|
+
}
|
|
85
|
+
function descendCollection(builder, collectionName, index) {
|
|
86
|
+
const collection = builder.collections.find((entry) => entry.name === collectionName);
|
|
87
|
+
if (!collection) {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
const configs = possibleConfigs(collection.payload);
|
|
91
|
+
const withinBounds = configs.filter((config) => isRef(config.max) || index < config.max);
|
|
92
|
+
if (withinBounds.length === 0 && configs.length > 0) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return withinBounds.flatMap((config) => (isRef(config.builder) ? [] : [config.builder]));
|
|
96
|
+
}
|
|
97
|
+
function possibleConfigs(payload) {
|
|
98
|
+
if (isRef(payload)) {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
if (v.is(BuilderCollectionConfigSchema, payload)) {
|
|
102
|
+
return [payload];
|
|
103
|
+
}
|
|
104
|
+
if (payload.type === 'match') {
|
|
105
|
+
return Object.values(payload.selectMap).flatMap((value) => v.is(BuilderCollectionConfigSchema, value) ? [value] : []);
|
|
106
|
+
}
|
|
107
|
+
return v.is(BuilderCollectionConfigSchema, payload.payload) ? [payload.payload] : [];
|
|
108
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { BuilderPaths } from '../../paths';
|
|
2
|
+
import type { Refable, RefableSerialised } from '../../references';
|
|
3
|
+
import type { BuilderState } from '../builder/index';
|
|
4
|
+
import type { BuilderWhen, WhenSerialised } from '../when';
|
|
5
|
+
import type { BuilderCollectionConfigSerialised } from './config';
|
|
6
|
+
import * as v from 'valibot';
|
|
7
|
+
import { BuilderCollectionConfig } from './config.js';
|
|
8
|
+
export type BuilderErrorInvalidCollectionBounds = {
|
|
9
|
+
readonly kind: 'invalid-collection-bounds';
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly min: number;
|
|
12
|
+
readonly max: number;
|
|
13
|
+
};
|
|
14
|
+
export type BuilderCollectionPayload = BuilderCollectionConfig | BuilderWhen<Refable<BuilderCollectionConfig>>;
|
|
15
|
+
export declare class BuilderCollection<const Name extends string = string, const Payload extends Refable<BuilderCollectionPayload> = Refable<BuilderCollectionPayload>, const GatePaths extends Refable<BuilderPaths> = Refable<BuilderPaths>> {
|
|
16
|
+
readonly type: 'collection';
|
|
17
|
+
readonly name: Name;
|
|
18
|
+
readonly payload: Payload;
|
|
19
|
+
readonly gatePaths?: GatePaths;
|
|
20
|
+
constructor(name: Name, payload: Payload, gatePaths?: GatePaths);
|
|
21
|
+
}
|
|
22
|
+
export declare const BuilderCollectionSchema: v.InstanceSchema<typeof BuilderCollection, undefined>;
|
|
23
|
+
export type BuilderCollections = ReadonlyArray<BuilderCollection>;
|
|
24
|
+
export declare const BuilderCollectionWhenSerialisedSchema: v.GenericSchema;
|
|
25
|
+
export type BuilderCollectionWhenSerialised = WhenSerialised<BuilderCollectionConfigSerialised>;
|
|
26
|
+
export type BuilderCollectionSerialised = {
|
|
27
|
+
readonly name: string;
|
|
28
|
+
readonly gatePaths?: RefableSerialised<BuilderPaths>;
|
|
29
|
+
readonly payload: RefableSerialised<BuilderCollectionConfigSerialised | BuilderCollectionWhenSerialised>;
|
|
30
|
+
};
|
|
31
|
+
export declare const BuilderCollectionSerialisedSchema: v.GenericSchema<BuilderCollectionSerialised>;
|
|
32
|
+
export declare const BuilderCollectionsSerialisedSchema: v.SchemaWithPipe<readonly [v.ArraySchema<v.GenericSchema<BuilderCollectionSerialised>, undefined>, v.ReadonlyAction<BuilderCollectionSerialised[]>]>;
|
|
33
|
+
export type BuilderCollectionsSerialised = ReadonlyArray<BuilderCollectionSerialised>;
|
|
34
|
+
export type CollectionNamesOf<State extends BuilderState | null> = [State] extends [BuilderState] ? State['collections'][number]['name'] : never;
|
|
35
|
+
export type CollectionShape<Collection extends BuilderCollection, Item> = Collection['payload'] extends BuilderCollectionConfig ? Collection['payload']['min'] extends number ? Collection['payload']['max'] extends number ? number extends Collection['payload']['min'] ? ReadonlyArray<Item> : number extends Collection['payload']['max'] ? ReadonlyArray<Item> : Collection['payload']['min'] extends Collection['payload']['max'] ? CollectionTuple<Item, Collection['payload']['min']> : ReadonlyArray<Item> : ReadonlyArray<Item> : ReadonlyArray<Item> : ReadonlyArray<Item>;
|
|
36
|
+
type CollectionTuple<Item, Length extends number, Result extends ReadonlyArray<Item> = []> = Result['length'] extends Length ? Result : CollectionTuple<Item, Length, [...Result, Item]>;
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
import { BuilderException } from '../../exception.js';
|
|
3
|
+
import { BuilderPathsSchema } from '../../paths.js';
|
|
4
|
+
import { isRef, refable } from '../../references.js';
|
|
5
|
+
import { serialisable } from '../../serialisable.js';
|
|
6
|
+
import { createWhenSerialisedSchema } from '../when.js';
|
|
7
|
+
import { BuilderCollectionConfig, BuilderCollectionConfigSerialisedSchema } from './config.js';
|
|
8
|
+
export class BuilderCollection {
|
|
9
|
+
name;
|
|
10
|
+
payload;
|
|
11
|
+
gatePaths;
|
|
12
|
+
constructor(name, payload, gatePaths) {
|
|
13
|
+
this.name = name;
|
|
14
|
+
this.payload = payload;
|
|
15
|
+
this.gatePaths = gatePaths;
|
|
16
|
+
validateCollectionBounds(name, payload);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function validateCollectionBounds(name, payload) {
|
|
20
|
+
if (!(payload instanceof BuilderCollectionConfig)) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const { min, max } = payload;
|
|
24
|
+
if (isRef(min) || isRef(max)) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const minValue = min;
|
|
28
|
+
const maxValue = max;
|
|
29
|
+
if (minValue < 0 || maxValue <= 0 || maxValue < minValue) {
|
|
30
|
+
throw new BuilderException([
|
|
31
|
+
{ kind: 'invalid-collection-bounds', name, min: minValue, max: maxValue }
|
|
32
|
+
]);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export const BuilderCollectionSchema = v.instance(BuilderCollection);
|
|
36
|
+
export const BuilderCollectionWhenSerialisedSchema = createWhenSerialisedSchema(BuilderCollectionConfigSerialisedSchema);
|
|
37
|
+
export const BuilderCollectionSerialisedSchema = serialisable(BuilderCollection, v.object({
|
|
38
|
+
name: v.string(),
|
|
39
|
+
payload: refable(v.union([BuilderCollectionConfigSerialisedSchema, BuilderCollectionWhenSerialisedSchema])),
|
|
40
|
+
gatePaths: v.optional(refable(BuilderPathsSchema))
|
|
41
|
+
}));
|
|
42
|
+
export const BuilderCollectionsSerialisedSchema = v.pipe(v.array(BuilderCollectionSerialisedSchema), v.readonly());
|