@builder-builder/builder 0.0.11 → 0.0.12
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/entities/when.d.ts
CHANGED
|
@@ -112,6 +112,8 @@ export declare const BuilderWhenConfigSchema: v.SchemaWithPipe<readonly [v.Varia
|
|
|
112
112
|
id: string;
|
|
113
113
|
}>]>, v.SchemaWithPipe<readonly [v.ArraySchema<v.UnionSchema<[v.StringSchema<undefined>, v.NumberSchema<undefined>], undefined>, undefined>, v.ReadonlyAction<(string | number)[]>]>], undefined>;
|
|
114
114
|
}, undefined>], undefined>, v.ReadonlyAction<{
|
|
115
|
+
type: "enable";
|
|
116
|
+
} | {
|
|
115
117
|
type: "match";
|
|
116
118
|
matchPath: readonly (string | number)[] | Readonly<{
|
|
117
119
|
type: "parameter";
|
|
@@ -131,8 +133,6 @@ export declare const BuilderWhenConfigSchema: v.SchemaWithPipe<readonly [v.Varia
|
|
|
131
133
|
type: "ref";
|
|
132
134
|
id: string;
|
|
133
135
|
}>;
|
|
134
|
-
} | {
|
|
135
|
-
type: "enable";
|
|
136
136
|
}>]>;
|
|
137
137
|
export type BuilderWhenConfig = v.InferOutput<typeof BuilderWhenConfigSchema>;
|
|
138
138
|
export type BuilderWhenGeneric = BuilderWhen<unknown, unknown, unknown, unknown>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { BB, BBOptions } from './bb';
|
|
2
|
-
export type { BuilderBindings, BuilderBindingsSerialised, BuilderCollection, BuilderCollectionConfig, BuilderCollectionConfigSerialised, BuilderCollections, BuilderCollectionSerialised, BuilderCollectionsSerialised, BuilderCollectionWhen, BuilderCollectionWhenSerialised, BuilderComponent, BuilderComponentDetails, BuilderComponentDetailsSerialised, BuilderComponentField, BuilderComponentFields, BuilderComponentFieldSerialised, BuilderComponentFieldsSerialised, BuilderComponentFieldValueType, BuilderComponents, BuilderComponentSerialised, BuilderComponentsSerialised, BuilderComponentWhen, BuilderComponentWhenSerialised, BuilderDescription, BuilderDescriptionItem, BuilderEntityKind, BuilderEntitySerialised, BuilderExpectation, BuilderExpectationKind, BuilderExpectations, BuilderExpectationSerialised, BuilderExpectationsSerialised, BuilderInstanceOf, BuilderModel, BuilderModels, BuilderModelSerialised, BuilderModelValidated, BuilderOption, BuilderOptions, BuilderOptionSerialised, BuilderOptionsSerialised, BuilderOptionValues, BuilderOptionValuesSerialised, BuilderOptionWhen, BuilderOptionWhenSerialised, BuilderRefEntities, BuilderRefEntity, BuilderSelectType, BuilderSelectTypeLabels, BuilderSelectTypeSerialised, BuilderSelectTypeValues, BuilderSerialised, BuilderToggleType, BuilderToggleTypeSerialised, BuilderToggleValueType, BuilderUI, BuilderUIDescribe, BuilderUIDescribeSerialised, BuilderUIItem, BuilderUIItems, BuilderUIItemsSerialised, BuilderUIPage, BuilderUIPages, BuilderUIPageSerialised, BuilderUIPagesSerialised, BuilderUIs, BuilderUIsSerialised, BuilderUISerialised, BuilderUIValidated, BuilderValidated, BuilderEnableConfig, BuilderMatchConfig, BuilderMatchSelectMap, BuilderUnlessConfig, BuilderWhen, BuilderWhenConfig, BuilderWhenSerialised } from './entities/index';
|
|
2
|
+
export type { BuilderBindings, BuilderBindingsSerialised, BuilderCollection, BuilderCollectionConfig, BuilderCollectionConfigSerialised, BuilderCollections, BuilderCollectionSerialised, BuilderCollectionsSerialised, BuilderCollectionWhen, BuilderCollectionWhenSerialised, BuilderComponent, BuilderComponentDetails, BuilderComponentDetailsSerialised, BuilderComponentField, BuilderComponentFields, BuilderComponentFieldSerialised, BuilderComponentFieldsSerialised, BuilderComponentFieldValueType, BuilderComponents, BuilderComponentSerialised, BuilderComponentsSerialised, BuilderComponentWhen, BuilderComponentWhenSerialised, BuilderDescription, BuilderDescriptionItem, BuilderEntityKind, BuilderEntitySerialised, BuilderExpectation, BuilderExpectationKind, BuilderExpectations, BuilderExpectationSerialised, BuilderExpectationsSerialised, BuilderInstanceOf, BuilderModel, BuilderModels, BuilderModelSerialised, BuilderModelValidated, BuilderOption, BuilderOptions, BuilderOptionSerialised, BuilderOptionsSerialised, BuilderOptionValues, BuilderOptionValuesSerialised, BuilderOptionWhen, BuilderOptionWhenSerialised, BuilderRefEntities, BuilderRefEntity, BuilderSelectType, BuilderSelectTypeLabels, BuilderSelectTypeSerialised, BuilderSelectTypeValues, BuilderSerialised, BuilderToggleType, BuilderToggleTypeSerialised, BuilderToggleValueType, BuilderUI, BuilderUIDescribe, BuilderUIDescribeSerialised, BuilderUIItem, BuilderUIItems, BuilderUIItemsSerialised, BuilderUIPage, BuilderUIPages, BuilderUIPageSerialised, BuilderUIPagesSerialised, BuilderUIs, BuilderUIsSerialised, BuilderUISerialised, BuilderUIValidated, BuilderValidated, BuilderComponentVariantsValidated, BuilderInstanceValidated, BuilderEnableConfig, BuilderMatchConfig, BuilderMatchSelectMap, BuilderUnlessConfig, BuilderWhen, BuilderWhenConfig, BuilderWhenSerialised } from './entities/index';
|
|
3
3
|
export type { BuilderEnvironment } from './environment';
|
|
4
4
|
export type { BuilderError, BuilderErrorBase, BuilderErrorLocation, BuilderErrors } from './exception';
|
|
5
5
|
export type { BuilderComponentVariantsValidationResult, BuilderErrorDuplicateName, BuilderErrorInvalidCollection, BuilderErrorInvalidCollectionBounds, BuilderErrorInvalidDetail, BuilderErrorInvalidInput, BuilderErrorInvalidOption, BuilderErrorInvalidPath, BuilderErrorInvalidPathReason, BuilderErrorInvalidSelectMapKey, BuilderErrorInvalidVariant, BuilderErrorMissingComponent, BuilderErrorMissingDetail, BuilderErrorMissingReference, BuilderErrorMissingVariant, BuilderErrorUnboundParameter, BuilderErrorUnexpectedComponent, BuilderErrorUnexpectedDetail, BuilderErrorUnmetExpectation, BuilderErrorUnvalidated, BuilderInstanceValidationResult, BuilderModelValidationResult, BuilderOrder, BuilderRenderOption, BuilderRenderOptions, BuilderRenderPage, BuilderRenderPages, BuilderRenderResult, BuilderRenderUpdate, BuilderUIValidationResult, BuilderValidationResult, BuilderVariantsValidationOptions } from './mappers/index';
|
package/dist/mappers/instance.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { check } from '../check.js';
|
|
2
|
-
import { optionValueSchema } from '../entities/index.js';
|
|
2
|
+
import { modelsMerge, optionValueSchema } from '../entities/index.js';
|
|
3
3
|
import { resolveCollection, resolveOption } from './resolve.js';
|
|
4
4
|
export function createInstance(entity, partial = {}, refs = []) {
|
|
5
5
|
const model = 'model' in entity ? entity.model : entity;
|
|
6
6
|
return buildInstance(model, partial, refs);
|
|
7
7
|
}
|
|
8
8
|
function buildInstance(model, partial, refs) {
|
|
9
|
+
const merged = modelsMerge(model);
|
|
9
10
|
let instance = { ...partial };
|
|
10
|
-
|
|
11
|
+
merged.options.forEach((option) => {
|
|
11
12
|
const { name } = option;
|
|
12
13
|
const payload = resolveOption(option, instance, refs);
|
|
13
14
|
if (payload == null) {
|
|
@@ -19,7 +20,7 @@ function buildInstance(model, partial, refs) {
|
|
|
19
20
|
}
|
|
20
21
|
instance = { ...instance, [name]: payload.defaultValue };
|
|
21
22
|
});
|
|
22
|
-
|
|
23
|
+
merged.collections.forEach((collection) => {
|
|
23
24
|
const { name } = collection;
|
|
24
25
|
const payload = resolveCollection(collection, instance, refs);
|
|
25
26
|
if (payload == null) {
|
|
@@ -3,6 +3,7 @@ import type { BuilderPrimitive } from '../../primitive';
|
|
|
3
3
|
import type { BuilderInstance } from '../../instance';
|
|
4
4
|
export type BuilderRenderUpdate = (model: BuilderInstance, primitive: BuilderPrimitive) => BuilderInstance;
|
|
5
5
|
export type BuilderRenderOption = Readonly<{
|
|
6
|
+
name: string;
|
|
6
7
|
value: BuilderPrimitive;
|
|
7
8
|
update: BuilderRenderUpdate;
|
|
8
9
|
option: BuilderOptionValuesSerialised;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as v from 'valibot';
|
|
2
2
|
import { check } from '../../check.js';
|
|
3
|
+
import { modelsMerge } from '../../entities/model/index.js';
|
|
3
4
|
import { BuilderInstancesSchema } from '../../instance.js';
|
|
4
5
|
import { readPath } from '../../paths.js';
|
|
5
6
|
import { resolveCollection, resolveOption, resolveRef } from '../resolve.js';
|
|
@@ -29,20 +30,23 @@ export function render(builder, instance, refs = []) {
|
|
|
29
30
|
}
|
|
30
31
|
const itemInstances = currentInstance[item.name];
|
|
31
32
|
check.assert(BuilderInstancesSchema, itemInstances, 'Collection field is not an array! ❌');
|
|
33
|
+
const mergedItemModel = modelsMerge(collection.model);
|
|
32
34
|
itemInstances.forEach((itemInstance, index) => {
|
|
33
|
-
walkItems(item.items,
|
|
35
|
+
walkItems(item.items, mergedItemModel, [...collectionPath, item.name, index], [...labelContext, `${ordinal(index)} ${composeLabel(item.label)}`], itemInstance);
|
|
34
36
|
});
|
|
35
37
|
});
|
|
36
38
|
}
|
|
37
39
|
function emitPage(page, model, collectionPath, labelContext, currentInstance) {
|
|
38
40
|
const options = page.paths.flatMap((path) => {
|
|
39
|
-
const
|
|
40
|
-
if (
|
|
41
|
+
const found = findOption(model, currentInstance, path);
|
|
42
|
+
if (found == null) {
|
|
41
43
|
return [];
|
|
42
44
|
}
|
|
43
45
|
const fullPath = [...collectionPath, ...path];
|
|
46
|
+
const [name, option] = found;
|
|
44
47
|
return [
|
|
45
48
|
{
|
|
49
|
+
name,
|
|
46
50
|
option,
|
|
47
51
|
value: readPath(currentInstance, path),
|
|
48
52
|
update: (updateInstance, updateValue) => setPath(updateInstance, fullPath, updateValue)
|
|
@@ -57,8 +61,8 @@ export function render(builder, instance, refs = []) {
|
|
|
57
61
|
function emitDescribe(describe, model, labelContext, currentInstance) {
|
|
58
62
|
const composedLabel = composeLabel(describe.label, labelContext);
|
|
59
63
|
const values = describe.paths.flatMap((path) => {
|
|
60
|
-
const
|
|
61
|
-
if (
|
|
64
|
+
const found = findOption(model, currentInstance, path);
|
|
65
|
+
if (found == null) {
|
|
62
66
|
return [];
|
|
63
67
|
}
|
|
64
68
|
const value = readPath(currentInstance, path);
|
|
@@ -78,6 +82,9 @@ export function render(builder, instance, refs = []) {
|
|
|
78
82
|
if (labelContext.length === 0) {
|
|
79
83
|
return resolved;
|
|
80
84
|
}
|
|
85
|
+
if (resolved === '') {
|
|
86
|
+
return labelContext.join(', ');
|
|
87
|
+
}
|
|
81
88
|
return `${labelContext.join(', ')}, ${resolved}`;
|
|
82
89
|
}
|
|
83
90
|
function findOption(model, instance, path) {
|
|
@@ -90,7 +97,14 @@ export function render(builder, instance, refs = []) {
|
|
|
90
97
|
}
|
|
91
98
|
const [scopeModel, scopeInstance] = descended;
|
|
92
99
|
const entry = scopeModel.options.find((option) => option.name === optionName);
|
|
93
|
-
|
|
100
|
+
if (entry == null) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
const optionValues = resolveOption(entry, scopeInstance, refs);
|
|
104
|
+
if (optionValues == null) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
return [entry.name, optionValues];
|
|
94
108
|
}
|
|
95
109
|
function descendPairs(model, instance, remaining) {
|
|
96
110
|
if (remaining.length === 0) {
|
package/dist/validate/model.js
CHANGED
|
@@ -59,23 +59,52 @@ export function validateModelStructure(input, resolve, location) {
|
|
|
59
59
|
const checkPaths = (entry, entryLocation) => (skipPathValidation ? [] : checkEntryPaths(modelInput, entry, entryLocation));
|
|
60
60
|
options.forEach((entry, entryIndex) => errors.push(...checkPaths(entry, [...location, 'options', entryIndex])));
|
|
61
61
|
components.forEach((entry, entryIndex) => errors.push(...checkPaths(entry, [...location, 'components', entryIndex])));
|
|
62
|
-
collections.
|
|
62
|
+
const resolvedCollections = collections.map((entry, entryIndex) => {
|
|
63
63
|
const collectionLocation = [...location, 'collections', entryIndex];
|
|
64
64
|
errors.push(...checkPaths(entry, collectionLocation), ...checkCollectionBounds(entry, collectionLocation));
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
});
|
|
65
|
+
const [resolvedEntry, entryErrors] = resolveCollectionInnerModels(entry, resolve, [...collectionLocation, 'payload']);
|
|
66
|
+
errors.push(...entryErrors);
|
|
67
|
+
return resolvedEntry;
|
|
69
68
|
});
|
|
70
69
|
const data = {
|
|
71
70
|
...modelInput,
|
|
72
71
|
models: childModels,
|
|
73
72
|
options,
|
|
74
73
|
components,
|
|
75
|
-
collections
|
|
74
|
+
collections: resolvedCollections
|
|
76
75
|
};
|
|
77
76
|
return [data, errors];
|
|
78
77
|
}
|
|
78
|
+
function resolveCollectionInnerModels(entry, resolve, payloadLocation) {
|
|
79
|
+
const errors = [];
|
|
80
|
+
const newPayload = mapCollectionConfigs(entry.payload, payloadLocation, (config, configLocation) => {
|
|
81
|
+
if (!check.is(BuilderModelSerialisedSchema, config.model)) {
|
|
82
|
+
return config;
|
|
83
|
+
}
|
|
84
|
+
const [validated, modelErrors] = validateModelStructure(config.model, resolve, [...configLocation, 'model']);
|
|
85
|
+
errors.push(...modelErrors);
|
|
86
|
+
return { ...config, model: validated };
|
|
87
|
+
});
|
|
88
|
+
return [{ ...entry, payload: newPayload }, errors];
|
|
89
|
+
}
|
|
90
|
+
function mapCollectionConfigs(payload, location, visit) {
|
|
91
|
+
if (check.is(BuilderCollectionConfigSerialisedSchema, payload)) {
|
|
92
|
+
return visit(payload, location);
|
|
93
|
+
}
|
|
94
|
+
if (!check.is(BuilderWhenSerialisedSchema, payload)) {
|
|
95
|
+
return payload;
|
|
96
|
+
}
|
|
97
|
+
const when = payload;
|
|
98
|
+
if (when.type === 'match') {
|
|
99
|
+
const selectMap = when.selectMap;
|
|
100
|
+
const newSelectMap = Object.fromEntries(Object.entries(selectMap).map(([key, value]) => [
|
|
101
|
+
key,
|
|
102
|
+
mapCollectionConfigs(value, [...location, 'selectMap', key], visit)
|
|
103
|
+
]));
|
|
104
|
+
return { ...when, selectMap: newSelectMap };
|
|
105
|
+
}
|
|
106
|
+
return { ...when, payload: mapCollectionConfigs(when.payload, [...location, 'payload'], visit) };
|
|
107
|
+
}
|
|
79
108
|
function walkEntries(entries, entryKind, resolve, location) {
|
|
80
109
|
const seen = new Set();
|
|
81
110
|
const items = [];
|
|
@@ -130,11 +159,6 @@ function checkCollectionBounds(collection, location) {
|
|
|
130
159
|
return [];
|
|
131
160
|
});
|
|
132
161
|
}
|
|
133
|
-
function collectionNestedModels(collection, location) {
|
|
134
|
-
return collectionConfigs(collection, location).flatMap(([config, configLocation]) => check.is(BuilderModelSerialisedSchema, config.model)
|
|
135
|
-
? [[config.model, [...configLocation, 'model']]]
|
|
136
|
-
: []);
|
|
137
|
-
}
|
|
138
162
|
function collectionConfigs(collection, location) {
|
|
139
163
|
const { payload } = collection;
|
|
140
164
|
const payloadLocation = [...location, 'payload'];
|