@builder-builder/builder 0.0.9 → 0.0.11
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/bb.d.ts +28 -0
- package/dist/bb.js +49 -0
- package/dist/check.d.ts +1 -1
- package/dist/check.js +4 -2
- package/dist/entities/builder/bind.d.ts +4 -0
- package/dist/entities/builder/builder.d.ts +17 -490
- package/dist/entities/builder/builder.js +19 -76
- package/dist/entities/builder/factory.d.ts +7 -0
- package/dist/entities/builder/factory.js +4 -0
- package/dist/entities/builder/index.d.ts +3 -6
- package/dist/entities/builder/index.js +1 -2
- package/dist/entities/collection/collection.d.ts +71 -20
- package/dist/entities/collection/collection.js +10 -27
- package/dist/entities/collection/config.d.ts +40 -1049
- package/dist/entities/collection/config.js +11 -11
- package/dist/entities/collection/expectation.d.ts +8 -4
- package/dist/entities/collection/index.d.ts +3 -3
- package/dist/entities/collection/index.js +1 -1
- package/dist/entities/collection/when.d.ts +6 -5
- package/dist/entities/component/component.d.ts +272 -300
- package/dist/entities/component/component.js +9 -8
- package/dist/entities/component/details.d.ts +35 -60
- package/dist/entities/component/details.js +9 -9
- package/dist/entities/component/expectation.d.ts +7 -4
- package/dist/entities/component/expectation.js +0 -3
- package/dist/entities/component/field.d.ts +50 -0
- package/dist/entities/component/field.js +41 -0
- package/dist/entities/component/index.d.ts +5 -3
- package/dist/entities/component/index.js +3 -2
- package/dist/entities/component/when.d.ts +5 -5
- package/dist/entities/component/when.js +2 -2
- package/dist/entities/entry.d.ts +4 -0
- package/dist/entities/expectation.d.ts +10 -22
- package/dist/entities/expectation.js +2 -7
- package/dist/entities/index.d.ts +21 -16
- package/dist/entities/index.js +10 -8
- package/dist/entities/kind.d.ts +9 -0
- package/dist/entities/kind.js +5 -0
- package/dist/entities/model/bind.d.ts +83 -0
- package/dist/entities/model/expectation.d.ts +16 -0
- package/dist/entities/model/index.d.ts +7 -0
- package/dist/entities/model/index.js +2 -0
- package/dist/entities/model/methods.d.ts +57 -0
- package/dist/entities/{builder → model}/methods.js +8 -8
- package/dist/entities/model/model.d.ts +39 -0
- package/dist/entities/model/model.js +73 -0
- package/dist/entities/model/models.d.ts +39 -0
- package/dist/entities/model/models.js +14 -0
- package/dist/entities/{builder → model}/state.d.ts +10 -10
- package/dist/entities/option/index.d.ts +2 -2
- package/dist/entities/option/index.js +2 -2
- package/dist/entities/option/option.d.ts +216 -214
- package/dist/entities/option/option.js +9 -8
- package/dist/entities/option/select.d.ts +2 -12
- package/dist/entities/option/select.js +6 -3
- package/dist/entities/option/toggle.d.ts +2 -9
- package/dist/entities/option/toggle.js +3 -3
- package/dist/entities/option/values.d.ts +4 -24
- package/dist/entities/option/values.js +10 -4
- package/dist/entities/option/when.d.ts +6 -5
- package/dist/entities/refs.d.ts +6 -0
- package/dist/entities/refs.js +1 -0
- package/dist/entities/serialise.d.ts +393 -3568
- package/dist/entities/serialise.js +160 -31
- package/dist/entities/ui/describe.d.ts +23 -57
- package/dist/entities/ui/describe.js +4 -5
- package/dist/entities/ui/index.d.ts +4 -9
- package/dist/entities/ui/index.js +2 -4
- package/dist/entities/ui/page.d.ts +23 -57
- package/dist/entities/ui/page.js +4 -5
- package/dist/entities/ui/pages.d.ts +18 -403
- package/dist/entities/ui/pages.js +7 -7
- package/dist/entities/ui/ui.d.ts +22 -1575
- package/dist/entities/ui/ui.js +15 -28
- package/dist/entities/ui/uis.d.ts +5 -9
- package/dist/entities/ui/uis.js +12 -19
- package/dist/entities/validated.d.ts +35 -0
- package/dist/entities/validated.js +1 -0
- package/dist/entities/when.d.ts +79 -70
- package/dist/entities/when.js +11 -7
- package/dist/environment.d.ts +5 -0
- package/dist/environment.js +2 -0
- package/dist/exception.d.ts +8 -3
- package/dist/exception.js +3 -0
- package/dist/index.d.ts +21 -24
- package/dist/index.js +5 -10
- package/dist/instance.d.ts +56 -0
- package/dist/instance.js +10 -0
- package/dist/mappers/index.d.ts +7 -5
- package/dist/mappers/index.js +5 -3
- package/dist/mappers/instance.d.ts +3 -0
- package/dist/mappers/instance.js +35 -0
- package/dist/mappers/order.d.ts +6 -0
- package/dist/mappers/order.js +22 -0
- package/dist/mappers/render/pages.d.ts +4 -4
- package/dist/mappers/render/render.d.ts +2 -3
- package/dist/mappers/render/render.js +83 -78
- package/dist/mappers/resolve.d.ts +5 -9
- package/dist/mappers/resolve.js +25 -33
- package/dist/mappers/variants/index.d.ts +1 -0
- package/dist/mappers/variants/index.js +1 -0
- package/dist/mappers/variants/option-graph.d.ts +19 -0
- package/dist/mappers/{models → variants}/option-graph.js +33 -22
- package/dist/mappers/variants/variants.d.ts +3 -0
- package/dist/mappers/variants/variants.js +57 -0
- package/dist/private.d.ts +4 -0
- package/dist/private.js +4 -0
- package/dist/references.d.ts +27 -36
- package/dist/references.js +19 -12
- package/dist/serialisable.d.ts +1 -9
- package/dist/serialisable.js +2 -3
- package/dist/validate/brand.d.ts +14 -0
- package/dist/validate/brand.js +17 -0
- package/dist/validate/builder.d.ts +4 -0
- package/dist/validate/builder.js +27 -0
- package/dist/validate/expectations.d.ts +10 -0
- package/dist/validate/expectations.js +12 -0
- package/dist/validate/index.d.ts +18 -0
- package/dist/validate/index.js +9 -0
- package/dist/validate/instance.d.ts +19 -0
- package/dist/validate/instance.js +46 -0
- package/dist/validate/model.d.ts +36 -0
- package/dist/validate/model.js +196 -0
- package/dist/validate/resolve.d.ts +16 -0
- package/dist/validate/resolve.js +91 -0
- package/dist/validate/result.d.ts +8 -0
- package/dist/validate/result.js +4 -0
- package/dist/validate/ui.d.ts +8 -0
- package/dist/validate/ui.js +77 -0
- package/dist/validate/variants.d.ts +59 -0
- package/dist/validate/variants.js +102 -0
- package/package.json +12 -9
- package/dist/entities/builder/builders.d.ts +0 -20
- package/dist/entities/builder/builders.js +0 -18
- package/dist/entities/builder/expectation.d.ts +0 -12
- package/dist/entities/builder/methods.d.ts +0 -58
- package/dist/entities/builder/parameter.d.ts +0 -62
- package/dist/entities/builder/parameter.js +0 -18
- package/dist/entities/builder/validate.d.ts +0 -3
- package/dist/entities/builder/validate.js +0 -108
- package/dist/entities/errors.d.ts +0 -21
- package/dist/entities/ui/label.d.ts +0 -18
- package/dist/entities/ui/label.js +0 -12
- package/dist/entities/ui/parameter.d.ts +0 -7
- package/dist/entities/ui/parameter.js +0 -29
- package/dist/entities/ui/validate.d.ts +0 -8
- package/dist/entities/ui/validate.js +0 -21
- package/dist/entities/validate.d.ts +0 -28
- package/dist/mappers/assert/builder.d.ts +0 -2
- package/dist/mappers/assert/builder.js +0 -46
- package/dist/mappers/assert/expectation.d.ts +0 -2
- package/dist/mappers/assert/expectation.js +0 -23
- package/dist/mappers/assert/index.d.ts +0 -6
- package/dist/mappers/assert/index.js +0 -4
- package/dist/mappers/assert/model.d.ts +0 -13
- package/dist/mappers/assert/model.js +0 -47
- package/dist/mappers/assert/models.d.ts +0 -33
- package/dist/mappers/assert/models.js +0 -74
- package/dist/mappers/assert/ui.d.ts +0 -2
- package/dist/mappers/assert/ui.js +0 -22
- package/dist/mappers/instance/index.d.ts +0 -1
- package/dist/mappers/instance/index.js +0 -1
- package/dist/mappers/instance/instance.d.ts +0 -4
- package/dist/mappers/instance/instance.js +0 -33
- package/dist/mappers/models/component-graph.d.ts +0 -9
- package/dist/mappers/models/component-graph.js +0 -51
- package/dist/mappers/models/graph.d.ts +0 -12
- package/dist/mappers/models/graph.js +0 -17
- package/dist/mappers/models/index.d.ts +0 -1
- package/dist/mappers/models/index.js +0 -1
- package/dist/mappers/models/models.d.ts +0 -3
- package/dist/mappers/models/models.js +0 -37
- package/dist/mappers/models/option-graph.d.ts +0 -9
- package/dist/mappers/order/index.d.ts +0 -2
- package/dist/mappers/order/index.js +0 -1
- package/dist/mappers/order/order.d.ts +0 -14
- package/dist/mappers/order/order.js +0 -31
- package/dist/model.d.ts +0 -14
- package/dist/walker/index.d.ts +0 -2
- package/dist/walker/index.js +0 -1
- package/dist/walker/walkable.d.ts +0 -4
- package/dist/walker/walkable.js +0 -4
- package/dist/walker/walker.d.ts +0 -18
- package/dist/walker/walker.js +0 -103
- package/dist/walker/walkers.d.ts +0 -8
- package/dist/walker/walkers.js +0 -51
- /package/dist/entities/builder/{expectation.js → bind.js} +0 -0
- /package/dist/entities/{builder/state.js → entry.js} +0 -0
- /package/dist/entities/{errors.js → model/bind.js} +0 -0
- /package/dist/entities/{validate.js → model/expectation.js} +0 -0
- /package/dist/{model.js → entities/model/state.js} +0 -0
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { check } from '../../check.js';
|
|
2
|
-
import { BuilderComponentDetailsSchema } from '../../entities/index.js';
|
|
3
|
-
import { BuilderException } from '../../exception.js';
|
|
4
|
-
import { createModels } from '../models/index.js';
|
|
5
|
-
export function assertModels(builder, builderData) {
|
|
6
|
-
const expected = createModels(builder);
|
|
7
|
-
const errors = [];
|
|
8
|
-
Object.entries(expected).forEach(([component, expectedModels]) => {
|
|
9
|
-
const componentModels = builderData[component];
|
|
10
|
-
if (!componentModels) {
|
|
11
|
-
errors.push({ kind: 'missing-component', component });
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
const expectedKeys = new Map(expectedModels.map((variant) => [sortedKey(variant.model), variant.model]));
|
|
15
|
-
const actualKeys = new Set();
|
|
16
|
-
componentModels.forEach((variant) => {
|
|
17
|
-
const key = sortedKey(variant.model);
|
|
18
|
-
actualKeys.add(key);
|
|
19
|
-
if (!expectedKeys.has(key)) {
|
|
20
|
-
errors.push({ kind: 'invalid-variant', component, model: variant.model });
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
expectedKeys.forEach((model, key) => {
|
|
24
|
-
if (!actualKeys.has(key)) {
|
|
25
|
-
errors.push({ kind: 'missing-variant', component, model });
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
Object.keys(builderData).forEach((component) => {
|
|
30
|
-
if (!expected[component]) {
|
|
31
|
-
errors.push({ kind: 'unexpected-component', component });
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
const detailExpectations = new Map(builder.components.map((entry) => {
|
|
35
|
-
const details = componentDetailNames(entry);
|
|
36
|
-
return [entry.name, new Set(details)];
|
|
37
|
-
}));
|
|
38
|
-
Object.entries(builderData).forEach(([component, variants]) => {
|
|
39
|
-
const expectedDetails = detailExpectations.get(component);
|
|
40
|
-
if (!expectedDetails || expectedDetails.size === 0) {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
variants.forEach((variant) => {
|
|
44
|
-
const actualDetails = new Set(Object.keys(variant.details ?? {}));
|
|
45
|
-
expectedDetails.forEach((detail) => {
|
|
46
|
-
if (!actualDetails.has(detail)) {
|
|
47
|
-
errors.push({ kind: 'missing-detail', component, detail, model: variant.model });
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
actualDetails.forEach((detail) => {
|
|
51
|
-
if (!expectedDetails.has(detail)) {
|
|
52
|
-
errors.push({ kind: 'unexpected-detail', component, detail, model: variant.model });
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
if (errors.length > 0) {
|
|
58
|
-
throw new BuilderException(errors);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
function componentDetailNames(component) {
|
|
62
|
-
const { payload } = component;
|
|
63
|
-
if (check.is(BuilderComponentDetailsSchema, payload)) {
|
|
64
|
-
return payload.expectations.map((expectation) => expectation.name);
|
|
65
|
-
}
|
|
66
|
-
if (payload.type === 'match') {
|
|
67
|
-
return [];
|
|
68
|
-
}
|
|
69
|
-
return payload.payload.expectations.map((expectation) => expectation.name);
|
|
70
|
-
}
|
|
71
|
-
function sortedKey(model) {
|
|
72
|
-
const entries = Object.entries(model).filter(([, value]) => value != null);
|
|
73
|
-
return JSON.stringify(entries.sort(([keyA], [keyB]) => keyA.localeCompare(keyB)));
|
|
74
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { BuilderUISerialisedSchema } from '../../entities/index.js';
|
|
2
|
-
import { BuilderException } from '../../exception.js';
|
|
3
|
-
import { isRef } from '../../references.js';
|
|
4
|
-
import { createWalkerValidation } from '../../walker/index.js';
|
|
5
|
-
import { collectExpectationErrors } from './expectation.js';
|
|
6
|
-
export function assertUI(ui) {
|
|
7
|
-
const errors = collectUIErrors(ui);
|
|
8
|
-
if (errors.length > 0) {
|
|
9
|
-
throw new BuilderException(errors);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
function collectUIErrors(ui) {
|
|
13
|
-
const parameterErrors = [];
|
|
14
|
-
const walkValidate = createWalkerValidation((ref) => {
|
|
15
|
-
parameterErrors.push({ kind: 'unbound-parameter', name: ref.name });
|
|
16
|
-
});
|
|
17
|
-
walkValidate(BuilderUISerialisedSchema, ui);
|
|
18
|
-
const expectationErrors = isRef(ui.builder)
|
|
19
|
-
? []
|
|
20
|
-
: collectExpectationErrors(ui.builder, ui.expectations);
|
|
21
|
-
return [...parameterErrors, ...expectationErrors];
|
|
22
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { createInstance } from './instance.js';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { createInstance } from './instance.js';
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { BuilderGeneric, BuilderInstanceOf } from '../../entities/index';
|
|
2
|
-
import type { Prettify } from '../../prettify';
|
|
3
|
-
import type { BuilderModelInput } from '../../model';
|
|
4
|
-
export declare function createInstance<const Input extends BuilderGeneric>(builder: Input, partial?: BuilderModelInput): Prettify<BuilderInstanceOf<Input>>;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import * as v from 'valibot';
|
|
2
|
-
import { resolveCollection, resolveOption } from '../resolve.js';
|
|
3
|
-
import { assertBuilder } from '../assert/index.js';
|
|
4
|
-
export function createInstance(builder, partial = {}) {
|
|
5
|
-
assertBuilder(builder);
|
|
6
|
-
return createInstanceInternal(builder, partial);
|
|
7
|
-
}
|
|
8
|
-
function createInstanceInternal(builder, partial = {}) {
|
|
9
|
-
const { options, collections } = builder;
|
|
10
|
-
const withOptions = options.reduce((current, entry) => {
|
|
11
|
-
const option = resolveOption(entry, current);
|
|
12
|
-
if (!option) {
|
|
13
|
-
return current;
|
|
14
|
-
}
|
|
15
|
-
if (v.is(option.payload.valueSchema, current[option.name])) {
|
|
16
|
-
return current;
|
|
17
|
-
}
|
|
18
|
-
return { ...current, [option.name]: option.payload.defaultValue };
|
|
19
|
-
}, partial);
|
|
20
|
-
const withCollections = collections.reduce((current, entry) => {
|
|
21
|
-
const collection = resolveCollection(entry, current);
|
|
22
|
-
if (!collection) {
|
|
23
|
-
return current;
|
|
24
|
-
}
|
|
25
|
-
const existing = current[collection.name];
|
|
26
|
-
const collectionModels = Array.isArray(existing) ? existing : [];
|
|
27
|
-
const nestedBuilder = collection.payload.builder;
|
|
28
|
-
const desiredLength = Math.max(collectionModels.length, collection.payload.min);
|
|
29
|
-
const items = Array.from({ length: desiredLength }).map((_, index) => createInstanceInternal(nestedBuilder, collectionModels[index] ?? {}));
|
|
30
|
-
return { ...current, [collection.name]: items };
|
|
31
|
-
}, withOptions);
|
|
32
|
-
return withCollections;
|
|
33
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { BuilderComponentValidated } from '../../entities/index';
|
|
2
|
-
import type { GraphPaths } from './graph';
|
|
3
|
-
import type { BuilderOptionGraph } from './option-graph';
|
|
4
|
-
export declare class BuilderComponentGraph {
|
|
5
|
-
#private;
|
|
6
|
-
readonly paths: GraphPaths;
|
|
7
|
-
constructor(paths?: GraphPaths);
|
|
8
|
-
add(component: BuilderComponentValidated, options: BuilderOptionGraph): BuilderComponentGraph;
|
|
9
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { check } from '../../check.js';
|
|
2
|
-
import { crossProduct, dependencyKeys } from './graph.js';
|
|
3
|
-
export class BuilderComponentGraph {
|
|
4
|
-
paths;
|
|
5
|
-
constructor(paths = []) {
|
|
6
|
-
this.paths = paths;
|
|
7
|
-
}
|
|
8
|
-
add(component, options) {
|
|
9
|
-
check.falsy(this.#has(component.name), `Duplicate component name '${component.name}'! ❌`);
|
|
10
|
-
const { gatePaths, payload } = component;
|
|
11
|
-
const keys = new Set(dependencyKeys(payload, gatePaths));
|
|
12
|
-
const models = this.#mergeModels(keys, options);
|
|
13
|
-
const newPath = { name: component.name, keys, models };
|
|
14
|
-
return new BuilderComponentGraph([...this.paths, newPath]);
|
|
15
|
-
}
|
|
16
|
-
#has(name) {
|
|
17
|
-
return this.paths.some((graphPath) => graphPath.name === name);
|
|
18
|
-
}
|
|
19
|
-
#mergeModels(keys, options) {
|
|
20
|
-
const graphPaths = Array.from(keys)
|
|
21
|
-
.map((key) => options.get(key))
|
|
22
|
-
.sort((pathA, pathB) => pathB.keys.size - pathA.keys.size);
|
|
23
|
-
const handledKeys = new Set();
|
|
24
|
-
let models = [{}];
|
|
25
|
-
graphPaths.forEach((graphPath) => {
|
|
26
|
-
const isHandled = handledKeys.has(graphPath.name) &&
|
|
27
|
-
Array.from(graphPath.keys).every((key) => handledKeys.has(key));
|
|
28
|
-
if (!isHandled) {
|
|
29
|
-
const componentModels = this.#createModels(graphPath, keys);
|
|
30
|
-
models = crossProduct(models, componentModels);
|
|
31
|
-
handledKeys.add(graphPath.name);
|
|
32
|
-
graphPath.keys.forEach((key) => handledKeys.add(key));
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
return models;
|
|
36
|
-
}
|
|
37
|
-
#createModels(graphPath, keys) {
|
|
38
|
-
const seen = new Set();
|
|
39
|
-
const models = [];
|
|
40
|
-
graphPath.models.forEach((model) => {
|
|
41
|
-
const picked = Object.fromEntries(Object.entries(model).filter(([key, value]) => keys.has(key) && value != null));
|
|
42
|
-
const identity = JSON.stringify(picked);
|
|
43
|
-
if (identity !== EMPTY_MODEL && !seen.has(identity)) {
|
|
44
|
-
seen.add(identity);
|
|
45
|
-
models.push(picked);
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
return models;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
const EMPTY_MODEL = '{}';
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { BuilderPaths } from '../../paths';
|
|
2
|
-
import type { BuilderWhen } from '../../entities/index';
|
|
3
|
-
import type { BuilderModels } from '../../model';
|
|
4
|
-
export type GraphKeys = ReadonlySet<string>;
|
|
5
|
-
export type GraphPath = {
|
|
6
|
-
name: string;
|
|
7
|
-
keys: GraphKeys;
|
|
8
|
-
models: BuilderModels;
|
|
9
|
-
};
|
|
10
|
-
export type GraphPaths = ReadonlyArray<GraphPath>;
|
|
11
|
-
export declare function crossProduct(left: BuilderModels, right: BuilderModels): BuilderModels;
|
|
12
|
-
export declare function dependencyKeys(payload: unknown | BuilderWhen, gatePaths?: BuilderPaths): ReadonlyArray<string>;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import * as v from 'valibot';
|
|
2
|
-
import { BuilderWhenMatchSchema, BuilderWhenUnlessSchema } from '../../entities/index.js';
|
|
3
|
-
export function crossProduct(left, right) {
|
|
4
|
-
return left.flatMap((leftModel) => right.map((rightModel) => ({ ...leftModel, ...rightModel })));
|
|
5
|
-
}
|
|
6
|
-
export function dependencyKeys(payload, gatePaths = []) {
|
|
7
|
-
const keys = new Set(gatePaths.map(([first]) => String(first)));
|
|
8
|
-
if (v.is(BuilderWhenMatchSchema, payload)) {
|
|
9
|
-
const [firstMatchSegment] = payload.matchPath;
|
|
10
|
-
keys.add(String(firstMatchSegment));
|
|
11
|
-
}
|
|
12
|
-
else if (v.is(BuilderWhenUnlessSchema, payload)) {
|
|
13
|
-
const [firstUnlessSegment] = payload.unlessPath;
|
|
14
|
-
keys.add(String(firstUnlessSegment));
|
|
15
|
-
}
|
|
16
|
-
return Array.from(keys);
|
|
17
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { createModels } from './models.js';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { createModels } from './models.js';
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import * as v from 'valibot';
|
|
2
|
-
import { BuilderCollectionConfigSchema } from '../../entities/index.js';
|
|
3
|
-
import { assertBuilder } from '../assert/index.js';
|
|
4
|
-
import { BuilderComponentGraph } from './component-graph.js';
|
|
5
|
-
import { BuilderOptionGraph } from './option-graph.js';
|
|
6
|
-
export function createModels(builder) {
|
|
7
|
-
assertBuilder(builder);
|
|
8
|
-
return models(builder.options, builder.components, builder.collections);
|
|
9
|
-
}
|
|
10
|
-
function models(options, components, collections) {
|
|
11
|
-
const collectionModels = collections.flatMap((entry) => {
|
|
12
|
-
return collectionBuilders(entry).map((nestedBuilder) => models(nestedBuilder.options, nestedBuilder.components, nestedBuilder.collections));
|
|
13
|
-
});
|
|
14
|
-
return {
|
|
15
|
-
...collectionModels.reduce((merged, component) => ({ ...merged, ...component }), {}),
|
|
16
|
-
...Object.fromEntries(componentGraph(components, options).paths.map((path) => [
|
|
17
|
-
path.name,
|
|
18
|
-
path.models.map((model) => ({ model }))
|
|
19
|
-
]))
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
function optionGraph(options) {
|
|
23
|
-
return options.reduce((graph, option) => graph.add(option), new BuilderOptionGraph());
|
|
24
|
-
}
|
|
25
|
-
function componentGraph(components, options) {
|
|
26
|
-
return components.reduce((graph, component) => graph.add(component, optionGraph(options)), new BuilderComponentGraph());
|
|
27
|
-
}
|
|
28
|
-
function collectionBuilders(entry) {
|
|
29
|
-
const { payload } = entry;
|
|
30
|
-
if (v.is(BuilderCollectionConfigSchema, payload)) {
|
|
31
|
-
return [payload.builder];
|
|
32
|
-
}
|
|
33
|
-
if (payload.type === 'match') {
|
|
34
|
-
return Object.values(payload.selectMap).flatMap((value) => (value ? [value.builder] : []));
|
|
35
|
-
}
|
|
36
|
-
return [payload.payload.builder];
|
|
37
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { BuilderOptionValidated } from '../../entities/index';
|
|
2
|
-
import type { GraphPath, GraphPaths } from './graph';
|
|
3
|
-
export declare class BuilderOptionGraph {
|
|
4
|
-
#private;
|
|
5
|
-
readonly paths: GraphPaths;
|
|
6
|
-
constructor(paths?: GraphPaths);
|
|
7
|
-
get(name: string): GraphPath;
|
|
8
|
-
add(option: BuilderOptionValidated): BuilderOptionGraph;
|
|
9
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { order } from './order.js';
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { BuilderCollection, BuilderCollectionConfig, BuilderCollections, BuilderComponents, BuilderGeneric, BuilderStateOf, CollectionShape } from '../../entities/index';
|
|
2
|
-
import type { Prettify } from '../../prettify';
|
|
3
|
-
import type { BuilderData, BuilderModel, BuilderVariant } from '../../model';
|
|
4
|
-
export type BuilderOrder<Builder extends BuilderGeneric> = Prettify<ComponentsOrder<BuilderStateOf<Builder>['components']> & CollectionsOrder<BuilderStateOf<Builder>['collections']>>;
|
|
5
|
-
export declare function order<const Builder extends BuilderGeneric>(builder: Builder, model: BuilderModel, componentModels: BuilderData): BuilderOrder<Builder>;
|
|
6
|
-
type ComponentsOrder<Components extends BuilderComponents> = {
|
|
7
|
-
readonly [Name in Components[number]['name']]: BuilderVariant | null;
|
|
8
|
-
};
|
|
9
|
-
type CollectionsOrder<Collections extends BuilderCollections> = Collections extends readonly [
|
|
10
|
-
infer Head extends BuilderCollection,
|
|
11
|
-
...infer Tail extends BuilderCollections
|
|
12
|
-
] ? Record<Head['name'], CollectionOrderOf<Head>> & CollectionsOrder<Tail> : {};
|
|
13
|
-
type CollectionOrderOf<Collection extends BuilderCollection> = Collection['payload'] extends BuilderCollectionConfig ? CollectionShape<Collection, BuilderOrder<Collection['payload']['builder'] & BuilderGeneric>> : ReadonlyArray<unknown>;
|
|
14
|
-
export {};
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { assertBuilder, assertModel, assertModels } from '../assert/index.js';
|
|
2
|
-
import { resolveCollection, resolveComponent } from '../resolve.js';
|
|
3
|
-
export function order(builder, model, componentModels) {
|
|
4
|
-
assertBuilder(builder);
|
|
5
|
-
assertModel(builder, model);
|
|
6
|
-
assertModels(builder, componentModels);
|
|
7
|
-
const { collections, components } = builder;
|
|
8
|
-
return orderInternal(collections, components, model, componentModels);
|
|
9
|
-
}
|
|
10
|
-
function orderInternal(collections, components, model, componentModels) {
|
|
11
|
-
const result = {};
|
|
12
|
-
components.forEach((component) => {
|
|
13
|
-
const resolved = resolveComponent(component, model);
|
|
14
|
-
if (!resolved) {
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
const variants = componentModels[component.name] ?? [];
|
|
18
|
-
result[component.name] =
|
|
19
|
-
variants.find((variant) => Object.entries(variant.model).every(([key, value]) => model[key] === value)) ?? null;
|
|
20
|
-
});
|
|
21
|
-
collections.forEach((entry) => {
|
|
22
|
-
const collection = resolveCollection(entry, model);
|
|
23
|
-
if (!collection) {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
const itemModels = model[collection.name];
|
|
27
|
-
const { collections, components } = collection.payload.builder;
|
|
28
|
-
result[collection.name] = itemModels.map((itemModel) => orderInternal(collections, components, itemModel, componentModels));
|
|
29
|
-
});
|
|
30
|
-
return result;
|
|
31
|
-
}
|
package/dist/model.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { BuilderPrimitive } from './primitive';
|
|
2
|
-
export type BuilderModel = {
|
|
3
|
-
readonly [key: string]: BuilderPrimitive | BuilderModels;
|
|
4
|
-
};
|
|
5
|
-
export type BuilderModels = ReadonlyArray<BuilderModel>;
|
|
6
|
-
export type BuilderModelInput = Readonly<Record<string, unknown>>;
|
|
7
|
-
export type BuilderVariant = Readonly<{
|
|
8
|
-
model: BuilderModel;
|
|
9
|
-
price?: string;
|
|
10
|
-
image?: string;
|
|
11
|
-
details?: Readonly<Record<string, string>>;
|
|
12
|
-
}>;
|
|
13
|
-
export type BuilderVariants = ReadonlyArray<BuilderVariant>;
|
|
14
|
-
export type BuilderData = Readonly<Record<string, BuilderVariants>>;
|
package/dist/walker/index.d.ts
DELETED
package/dist/walker/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { createWalkerBinding, createWalkerDeserialise, createWalkerSerialise, createWalkerValidation } from './walkers.js';
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type * as v from 'valibot';
|
|
2
|
-
type WalkableSchema = v.LazySchema<v.GenericSchema> | v.OptionalSchema<v.GenericSchema, unknown> | v.NullableSchema<v.GenericSchema, unknown> | v.ArraySchema<v.GenericSchema, undefined> | v.RecordSchema<v.GenericSchema<string>, v.GenericSchema, undefined> | v.ObjectSchema<v.ObjectEntries, undefined> | v.UnionSchema<ReadonlyArray<v.GenericSchema>, undefined> | v.VariantSchema<string, v.VariantOptions<string>, undefined>;
|
|
3
|
-
export declare function isWalkable(schema: v.GenericSchema): schema is WalkableSchema;
|
|
4
|
-
export {};
|
package/dist/walker/walkable.js
DELETED
package/dist/walker/walker.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { BuilderRef, BuilderRefSerialised } from '../references';
|
|
2
|
-
import type { SerialisableClass } from '../serialisable';
|
|
3
|
-
import * as v from 'valibot';
|
|
4
|
-
export type Walker = (schema: v.GenericSchema, data: unknown) => unknown;
|
|
5
|
-
export type WalkerField = {
|
|
6
|
-
readonly name: string;
|
|
7
|
-
readonly literal: {
|
|
8
|
-
readonly value: unknown;
|
|
9
|
-
} | null;
|
|
10
|
-
};
|
|
11
|
-
export type WalkerFields = ReadonlyArray<WalkerField>;
|
|
12
|
-
export type WalkerConfig = {
|
|
13
|
-
readonly onRef?: (ref: BuilderRef) => unknown;
|
|
14
|
-
readonly onSerialisedRef?: (data: BuilderRefSerialised) => unknown;
|
|
15
|
-
readonly walkObject?: (fields: WalkerFields, walked: Record<string, unknown>, record: Record<string, unknown>) => unknown;
|
|
16
|
-
readonly walkEntity?: (serialisable: SerialisableClass, fields: WalkerFields, walked: Record<string, unknown>, record: Record<string, unknown>) => unknown;
|
|
17
|
-
};
|
|
18
|
-
export declare function walk(schema: v.GenericSchema, value: unknown, config: WalkerConfig): unknown;
|
package/dist/walker/walker.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import * as v from 'valibot';
|
|
2
|
-
import { isRef, isSerialisedRef } from '../references.js';
|
|
3
|
-
import { isWalkable } from './walkable.js';
|
|
4
|
-
export function walk(schema, value, config) {
|
|
5
|
-
const meta = v.getMetadata(schema);
|
|
6
|
-
if (meta.refable != null) {
|
|
7
|
-
return walkRefable(meta.refable, value, config);
|
|
8
|
-
}
|
|
9
|
-
const inner = unwrapPipe(schema);
|
|
10
|
-
if (!isWalkable(inner)) {
|
|
11
|
-
return value;
|
|
12
|
-
}
|
|
13
|
-
switch (inner.type) {
|
|
14
|
-
case 'lazy':
|
|
15
|
-
return walk(inner.getter(value), value, config);
|
|
16
|
-
case 'optional':
|
|
17
|
-
case 'nullable':
|
|
18
|
-
return walk(inner.wrapped, value, config);
|
|
19
|
-
case 'array':
|
|
20
|
-
return walkArray(inner.item, value, config);
|
|
21
|
-
case 'record':
|
|
22
|
-
return walkRecord(inner.value, value, config);
|
|
23
|
-
case 'object':
|
|
24
|
-
return walkObject(inner, value, meta.serialisable, config);
|
|
25
|
-
case 'union':
|
|
26
|
-
case 'variant': {
|
|
27
|
-
const matched = inner.options.find((option) => matches(option, value));
|
|
28
|
-
return matched ? walk(matched, value, config) : value;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
function isLiteral(schema) {
|
|
33
|
-
return schema.type === 'literal';
|
|
34
|
-
}
|
|
35
|
-
function walkRefable(inner, value, config) {
|
|
36
|
-
if (value == null) {
|
|
37
|
-
return value;
|
|
38
|
-
}
|
|
39
|
-
const resolved = isRef(value) && config.onRef
|
|
40
|
-
? config.onRef(value)
|
|
41
|
-
: isSerialisedRef(value) && config.onSerialisedRef
|
|
42
|
-
? config.onSerialisedRef(value)
|
|
43
|
-
: value;
|
|
44
|
-
if (isRef(resolved) || isSerialisedRef(resolved)) {
|
|
45
|
-
return resolved;
|
|
46
|
-
}
|
|
47
|
-
return walk(inner, resolved, config);
|
|
48
|
-
}
|
|
49
|
-
function walkArray(item, value, config) {
|
|
50
|
-
return value.flatMap((element) => {
|
|
51
|
-
const walked = walk(item, element, config);
|
|
52
|
-
if (!isAnyRef(element) || !Array.isArray(walked)) {
|
|
53
|
-
return [walked];
|
|
54
|
-
}
|
|
55
|
-
return walked.flatMap((nested) => {
|
|
56
|
-
const walkedNested = walk(item, nested, config);
|
|
57
|
-
if (isAnyRef(nested) && Array.isArray(walkedNested)) {
|
|
58
|
-
return walkedNested;
|
|
59
|
-
}
|
|
60
|
-
return [walkedNested];
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
function walkRecord(valueSchema, record, config) {
|
|
65
|
-
return Object.fromEntries(Object.entries(record).map(([key, entry]) => entry === null ? [key, null] : [key, walk(valueSchema, entry, config)]));
|
|
66
|
-
}
|
|
67
|
-
function walkObject(schema, record, serialisable, config) {
|
|
68
|
-
const fields = fieldsOf(schema);
|
|
69
|
-
const walked = {};
|
|
70
|
-
fields.forEach((field) => {
|
|
71
|
-
if (field.literal) {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
walked[field.name] = walk(schema.entries[field.name], record[field.name], config);
|
|
75
|
-
});
|
|
76
|
-
if (serialisable != null && config.walkEntity) {
|
|
77
|
-
return config.walkEntity(serialisable, fields, walked, record);
|
|
78
|
-
}
|
|
79
|
-
return config.walkObject ? config.walkObject(fields, walked, record) : record;
|
|
80
|
-
}
|
|
81
|
-
function fieldsOf(schema) {
|
|
82
|
-
return Object.entries(schema.entries).map(([name, fieldSchema]) => {
|
|
83
|
-
const inner = unwrapPipe(fieldSchema);
|
|
84
|
-
return isLiteral(inner) ? { name, literal: { value: inner.literal } } : { name, literal: null };
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
function matches(schema, value) {
|
|
88
|
-
const { instance } = v.getMetadata(schema);
|
|
89
|
-
if (instance != null && v.is(instance, value)) {
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
|
-
return v.is(schema, value);
|
|
93
|
-
}
|
|
94
|
-
function isAnyRef(value) {
|
|
95
|
-
return isRef(value) || isSerialisedRef(value);
|
|
96
|
-
}
|
|
97
|
-
function unwrapPipe(schema) {
|
|
98
|
-
if ('pipe' in schema && Array.isArray(schema.pipe)) {
|
|
99
|
-
const [first] = schema.pipe;
|
|
100
|
-
return first;
|
|
101
|
-
}
|
|
102
|
-
return schema;
|
|
103
|
-
}
|
package/dist/walker/walkers.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { Walker } from './walker';
|
|
2
|
-
import { BuilderRef } from '../references.js';
|
|
3
|
-
export declare function createWalkerSerialise(): Walker;
|
|
4
|
-
export declare function createWalkerDeserialise(): Walker;
|
|
5
|
-
export declare function createWalkerValidation(onUnbound: (ref: BuilderRef) => void): Walker;
|
|
6
|
-
export declare function createWalkerBinding(config: {
|
|
7
|
-
readonly lookupBinding: (ref: BuilderRef) => unknown;
|
|
8
|
-
}): Walker;
|
package/dist/walker/walkers.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { BuilderRef } from '../references.js';
|
|
2
|
-
import { walk } from './walker.js';
|
|
3
|
-
export function createWalkerSerialise() {
|
|
4
|
-
return (schema, data) => walk(schema, data, {
|
|
5
|
-
onRef: (ref) => ({ type: 'ref', id: ref.id, name: ref.name }),
|
|
6
|
-
walkObject: (fields, walked) => rebuild(fields, walked)
|
|
7
|
-
});
|
|
8
|
-
}
|
|
9
|
-
export function createWalkerDeserialise() {
|
|
10
|
-
return (schema, data) => walk(schema, data, {
|
|
11
|
-
onSerialisedRef: (serialised) => new BuilderRef(serialised.name, serialised.id),
|
|
12
|
-
walkObject: (fields, walked) => rebuild(fields, walked),
|
|
13
|
-
walkEntity: (serialisable, fields, walked) => construct(serialisable, fields, rebuild(fields, walked))
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
export function createWalkerValidation(onUnbound) {
|
|
17
|
-
return (schema, data) => walk(schema, data, {
|
|
18
|
-
onRef: (ref) => {
|
|
19
|
-
onUnbound(ref);
|
|
20
|
-
return ref;
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
export function createWalkerBinding(config) {
|
|
25
|
-
return (schema, data) => walk(schema, data, {
|
|
26
|
-
onRef: (ref) => {
|
|
27
|
-
const value = config.lookupBinding(ref);
|
|
28
|
-
return value != null ? value : ref;
|
|
29
|
-
},
|
|
30
|
-
walkObject: (_fields, walked, record) => applyPatches(record, walked),
|
|
31
|
-
walkEntity: (serialisable, fields, walked, record) => {
|
|
32
|
-
const merged = applyPatches(record, walked);
|
|
33
|
-
return merged === record ? record : construct(serialisable, fields, merged);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
function rebuild(fields, walked) {
|
|
38
|
-
return Object.fromEntries(fields.map((field) => [
|
|
39
|
-
field.name,
|
|
40
|
-
field.literal !== null ? field.literal.value : walked[field.name]
|
|
41
|
-
]));
|
|
42
|
-
}
|
|
43
|
-
function construct(serialisable, fields, entries) {
|
|
44
|
-
const args = fields.filter((field) => field.literal === null).map((field) => entries[field.name]);
|
|
45
|
-
const callable = serialisable;
|
|
46
|
-
return new callable(...args);
|
|
47
|
-
}
|
|
48
|
-
function applyPatches(record, walked) {
|
|
49
|
-
const patches = Object.entries(walked).filter(([name, value]) => value !== record[name]);
|
|
50
|
-
return patches.length === 0 ? record : { ...record, ...Object.fromEntries(patches) };
|
|
51
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|