@builder-builder/builder 0.0.5 → 0.0.7
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/core/builder.d.ts +6 -2
- package/dist/core/builder.js +20 -29
- package/dist/core/collection/collection.d.ts +3 -1
- package/dist/core/component/component.d.ts +0 -2
- package/dist/core/component/component.js +0 -7
- package/dist/core/component/graph.d.ts +0 -1
- package/dist/core/component/graph.js +5 -5
- package/dist/core/component/index.d.ts +1 -1
- package/dist/core/expectation.d.ts +22 -19
- package/dist/core/expectation.js +5 -9
- package/dist/core/index.d.ts +4 -2
- package/dist/core/index.js +2 -1
- package/dist/core/option/graph.d.ts +1 -2
- package/dist/core/option/graph.js +4 -6
- package/dist/core/option/index.d.ts +1 -0
- package/dist/core/option/option.js +5 -4
- package/dist/core/option/toggle.d.ts +3 -1
- package/dist/core/option/toggle.js +9 -7
- package/dist/core/validate.d.ts +26 -0
- package/dist/core/validate.js +43 -0
- package/dist/index.d.ts +7 -7
- package/dist/index.js +3 -3
- package/dist/paths.d.ts +3 -1
- package/dist/resolve/index.d.ts +4 -3
- package/dist/resolve/index.js +2 -2
- package/dist/resolve/instance.d.ts +34 -2
- package/dist/resolve/instance.js +56 -2
- package/dist/resolve/models.d.ts +2 -2
- package/dist/resolve/models.js +11 -1
- package/dist/resolve/order.d.ts +4 -2
- package/dist/resolve/order.js +13 -10
- package/dist/resolve/render.d.ts +4 -2
- package/dist/resolve/validate.d.ts +20 -16
- package/dist/resolve/validate.js +18 -22
- package/dist/serialise/deserialise.d.ts +6 -1
- package/dist/serialise/deserialise.js +40 -34
- package/dist/serialise/index.d.ts +3 -1
- package/dist/serialise/index.js +2 -1
- package/dist/serialise/schemas.d.ts +153 -92
- package/dist/serialise/schemas.js +19 -10
- package/dist/serialise/serialise.d.ts +4 -1
- package/dist/serialise/serialise.js +16 -9
- package/dist/serialise/validate.d.ts +26 -0
- package/dist/serialise/validate.js +148 -0
- package/dist/ui.d.ts +7 -6
- package/dist/ui.js +17 -15
- package/package.json +3 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as v from 'valibot';
|
|
2
2
|
import { BuilderParameterSchema } from '../core/parameter.js';
|
|
3
3
|
import { BuilderOptionValuesMapSchema, BuilderOptionValuesSchema } from '../core/option/option.js';
|
|
4
|
-
import { BuilderPathSchema, BuilderPathsSchema,
|
|
4
|
+
import { BuilderPathSchema, BuilderPathsSchema, BuilderPrimitivesSchema } from '../schemas/primitives.js';
|
|
5
5
|
export { BuilderOptionValuesMapSchema, BuilderOptionValuesSchema, BuilderParameterSchema };
|
|
6
6
|
export const BuilderSelectTypeSerialisedSchema = v.pipe(v.object({
|
|
7
7
|
type: v.literal('select'),
|
|
@@ -12,7 +12,7 @@ export const BuilderSelectTypeSerialisedSchema = v.pipe(v.object({
|
|
|
12
12
|
}), v.readonly());
|
|
13
13
|
export const BuilderToggleTypeSerialisedSchema = v.pipe(v.object({
|
|
14
14
|
type: v.literal('toggle'),
|
|
15
|
-
valueType: v.string
|
|
15
|
+
valueType: v.picklist(['string', 'boolean', 'number']),
|
|
16
16
|
defaultValue: v.nullable(v.union([v.boolean(), v.string(), v.number()])),
|
|
17
17
|
optional: v.boolean()
|
|
18
18
|
}), v.readonly());
|
|
@@ -33,7 +33,7 @@ export const BuilderOptionMatchConfigSerialisedSchema = v.pipe(v.object({
|
|
|
33
33
|
export const BuilderOptionUnlessConfigSerialisedSchema = v.pipe(v.object({
|
|
34
34
|
type: v.literal('unless'),
|
|
35
35
|
unlessPath: BuilderPathSchema,
|
|
36
|
-
disabledValues:
|
|
36
|
+
disabledValues: BuilderPrimitivesSchema,
|
|
37
37
|
values: v.union([BuilderValuesSerialisedSchema, BuilderParameterSerialisedSchema])
|
|
38
38
|
}), v.readonly());
|
|
39
39
|
export const BuilderOptionWhenConfigSerialisedSchema = v.pipe(v.variant('type', [
|
|
@@ -47,10 +47,11 @@ export const BuilderOptionSerialisedSchema = v.pipe(v.object({
|
|
|
47
47
|
gatePaths: BuilderPathsSchema,
|
|
48
48
|
config: v.nullable(BuilderOptionWhenConfigSerialisedSchema)
|
|
49
49
|
}), v.readonly());
|
|
50
|
+
const BuilderDependenciesSerialisedSchema = v.pipe(v.array(v.string()), v.readonly());
|
|
50
51
|
export const BuilderComponentSerialisedSchema = v.pipe(v.object({
|
|
51
52
|
name: v.string(),
|
|
52
53
|
paths: BuilderPathsSchema,
|
|
53
|
-
dependencies:
|
|
54
|
+
dependencies: BuilderDependenciesSerialisedSchema
|
|
54
55
|
}), v.readonly());
|
|
55
56
|
const lazyBuilder = () => v.lazy(() => BuilderSerialisedSchema);
|
|
56
57
|
const BuilderSerialisedCollectionConfigObject = v.object({
|
|
@@ -72,7 +73,7 @@ const BuilderSerialisedCollectionMatchConfigObject = v.object({
|
|
|
72
73
|
const BuilderSerialisedCollectionUnlessConfigObject = v.object({
|
|
73
74
|
type: v.literal('unless'),
|
|
74
75
|
unlessPath: BuilderPathSchema,
|
|
75
|
-
disabledValues:
|
|
76
|
+
disabledValues: BuilderPrimitivesSchema,
|
|
76
77
|
builder: lazyBuilder(),
|
|
77
78
|
min: v.number(),
|
|
78
79
|
max: v.number()
|
|
@@ -118,13 +119,17 @@ export const BuilderCollectionWhenConfigSerialisedSchema = v.pipe(v.variant('typ
|
|
|
118
119
|
export const BuilderCollectionSerialisedSchema = v.pipe(BuilderSerialisedCollectionObject, v.readonly());
|
|
119
120
|
export const BuilderExpectationSerialisedSchema = v.pipe(v.object({
|
|
120
121
|
name: v.string(),
|
|
121
|
-
kind: v.picklist(['option', 'component'])
|
|
122
|
+
kind: v.picklist(['option', 'component', 'collection'])
|
|
122
123
|
}), v.readonly());
|
|
124
|
+
const BuilderOptionsSerialisedSchema = v.pipe(v.array(BuilderOptionSerialisedSchema), v.readonly());
|
|
125
|
+
const BuilderComponentsSerialisedSchema = v.pipe(v.array(BuilderComponentSerialisedSchema), v.readonly());
|
|
126
|
+
const BuilderCollectionsSerialisedSchema = v.pipe(v.array(BuilderSerialisedCollectionObject), v.readonly());
|
|
127
|
+
const BuilderExpectationsSerialisedSchema = v.pipe(v.array(BuilderExpectationSerialisedSchema), v.readonly());
|
|
123
128
|
export const BuilderSerialisedSchema = v.pipe(v.object({
|
|
124
|
-
options:
|
|
125
|
-
components:
|
|
126
|
-
collections:
|
|
127
|
-
expectations:
|
|
129
|
+
options: BuilderOptionsSerialisedSchema,
|
|
130
|
+
components: BuilderComponentsSerialisedSchema,
|
|
131
|
+
collections: BuilderCollectionsSerialisedSchema,
|
|
132
|
+
expectations: BuilderExpectationsSerialisedSchema
|
|
128
133
|
}), v.readonly());
|
|
129
134
|
export const BuilderUIPageSerialisedSchema = v.pipe(BuilderSerialisedUIPageObject, v.readonly());
|
|
130
135
|
export const BuilderUIDescribeSerialisedSchema = v.pipe(BuilderSerialisedUIDescribeObject, v.readonly());
|
|
@@ -139,3 +144,7 @@ export const BuilderUIItemsSerialisedSchema = v.pipe(v.array(v.variant('type', [
|
|
|
139
144
|
BuilderSerialisedUIDescribeObject,
|
|
140
145
|
BuilderSerialisedUICollectionObject
|
|
141
146
|
])), v.readonly());
|
|
147
|
+
export const BuilderUISerialisedSchema = v.pipe(v.object({
|
|
148
|
+
items: BuilderUIItemsSerialisedSchema,
|
|
149
|
+
expectations: BuilderExpectationsSerialisedSchema
|
|
150
|
+
}), v.readonly());
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { BuilderGeneric } from '../core/index';
|
|
2
|
-
import type { BuilderSerialised, BuilderUISerialised } from './schemas';
|
|
2
|
+
import type { BuilderSelectTypeSerialised, BuilderSerialised, BuilderUISerialised } from './schemas';
|
|
3
3
|
import type { BuilderUIGeneric } from '../ui';
|
|
4
|
+
import { BuilderSelectType } from '../core/index.js';
|
|
4
5
|
export declare const serialise: {
|
|
5
6
|
builder: typeof serialiseBuilder;
|
|
7
|
+
select: typeof serialiseSelect;
|
|
6
8
|
ui: typeof serialiseUI;
|
|
7
9
|
};
|
|
8
10
|
declare function serialiseBuilder(builder: BuilderGeneric): BuilderSerialised;
|
|
9
11
|
declare function serialiseUI(input: BuilderUIGeneric): BuilderUISerialised;
|
|
12
|
+
declare function serialiseSelect(selectType: BuilderSelectType): BuilderSelectTypeSerialised;
|
|
10
13
|
export {};
|
|
@@ -2,6 +2,7 @@ import * as v from 'valibot';
|
|
|
2
2
|
import { BuilderCollection, BuilderComponent, BuilderOption, BuilderParameter, BuilderParameterSchema, BuilderSelectType } from '../core/index.js';
|
|
3
3
|
export const serialise = {
|
|
4
4
|
builder: serialiseBuilder,
|
|
5
|
+
select: serialiseSelect,
|
|
5
6
|
ui: serialiseUI
|
|
6
7
|
};
|
|
7
8
|
function serialiseBuilder(builder) {
|
|
@@ -13,7 +14,10 @@ function serialiseBuilder(builder) {
|
|
|
13
14
|
};
|
|
14
15
|
}
|
|
15
16
|
function serialiseUI(input) {
|
|
16
|
-
return
|
|
17
|
+
return {
|
|
18
|
+
items: input.items,
|
|
19
|
+
expectations: input.expectations.map(serialiseExpectation)
|
|
20
|
+
};
|
|
17
21
|
}
|
|
18
22
|
function serialiseOption(option) {
|
|
19
23
|
return {
|
|
@@ -46,22 +50,25 @@ function serialiseCollection(collection) {
|
|
|
46
50
|
config: serialiseCollectionWhenConfig(collection.config)
|
|
47
51
|
};
|
|
48
52
|
}
|
|
53
|
+
function serialiseSelect(selectType) {
|
|
54
|
+
return {
|
|
55
|
+
type: 'select',
|
|
56
|
+
options: selectType.options,
|
|
57
|
+
defaultValue: selectType.defaultValue,
|
|
58
|
+
optional: selectType.isOptional,
|
|
59
|
+
labels: selectType.optionLabels
|
|
60
|
+
};
|
|
61
|
+
}
|
|
49
62
|
function serialiseValues(optionValues) {
|
|
50
63
|
if (v.is(BuilderParameterSchema, optionValues)) {
|
|
51
64
|
return { type: 'parameter' };
|
|
52
65
|
}
|
|
53
66
|
if (v.is(v.instance(BuilderSelectType), optionValues)) {
|
|
54
|
-
return
|
|
55
|
-
type: 'select',
|
|
56
|
-
options: optionValues.options,
|
|
57
|
-
defaultValue: optionValues.defaultValue,
|
|
58
|
-
optional: optionValues.isOptional,
|
|
59
|
-
labels: optionValues.optionLabels
|
|
60
|
-
};
|
|
67
|
+
return serialiseSelect(optionValues);
|
|
61
68
|
}
|
|
62
69
|
return {
|
|
63
70
|
type: 'toggle',
|
|
64
|
-
valueType: optionValues.
|
|
71
|
+
valueType: optionValues.valueType,
|
|
65
72
|
defaultValue: optionValues.defaultValue,
|
|
66
73
|
optional: optionValues.isOptional
|
|
67
74
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { BuilderSerialised } from './schemas';
|
|
2
|
+
declare const validated: unique symbol;
|
|
3
|
+
export type BuilderSerialisedValidated = BuilderSerialised & {
|
|
4
|
+
readonly [validated]: true;
|
|
5
|
+
};
|
|
6
|
+
export type BuilderSerialisedErrorKind = 'duplicate-option' | 'duplicate-component' | 'duplicate-collection' | 'invalid-gate-path' | 'invalid-component-path' | 'invalid-component-dependency' | 'invalid-config-path';
|
|
7
|
+
export type BuilderSerialisedError = {
|
|
8
|
+
readonly kind: BuilderSerialisedErrorKind;
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly detail: string;
|
|
11
|
+
};
|
|
12
|
+
export type BuilderSerialisedErrors = ReadonlyArray<BuilderSerialisedError>;
|
|
13
|
+
export type BuilderSerialisedValidateResult = readonly [
|
|
14
|
+
BuilderSerialisedValidated,
|
|
15
|
+
BuilderSerialisedErrors
|
|
16
|
+
];
|
|
17
|
+
export type BuilderSerialisedValidateOptions = {
|
|
18
|
+
readonly strict: true;
|
|
19
|
+
};
|
|
20
|
+
export declare class BuilderSerialisedValidateError extends Error {
|
|
21
|
+
readonly errors: BuilderSerialisedErrors;
|
|
22
|
+
constructor(errors: BuilderSerialisedErrors);
|
|
23
|
+
}
|
|
24
|
+
export declare const validate: typeof validateSerialised;
|
|
25
|
+
declare function validateSerialised(data: unknown, options?: BuilderSerialisedValidateOptions): BuilderSerialisedValidateResult;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
import { BuilderSerialisedSchema } from './schemas.js';
|
|
3
|
+
export class BuilderSerialisedValidateError extends Error {
|
|
4
|
+
errors;
|
|
5
|
+
constructor(errors) {
|
|
6
|
+
super('serialised validation failed');
|
|
7
|
+
this.errors = errors;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export const validate = validateSerialised;
|
|
11
|
+
function validateSerialised(data, options) {
|
|
12
|
+
const serialised = v.parse(BuilderSerialisedSchema, data);
|
|
13
|
+
let errors = [];
|
|
14
|
+
const optionNames = new Set();
|
|
15
|
+
const componentNames = new Set();
|
|
16
|
+
const collectionNames = new Set();
|
|
17
|
+
const optionExpectationNames = new Set(serialised.expectations
|
|
18
|
+
.filter((expectation) => expectation.kind === 'option')
|
|
19
|
+
.map((expectation) => expectation.name));
|
|
20
|
+
const componentExpectationNames = new Set(serialised.expectations
|
|
21
|
+
.filter((expectation) => expectation.kind === 'component')
|
|
22
|
+
.map((expectation) => expectation.name));
|
|
23
|
+
const validOptionPaths = () => {
|
|
24
|
+
const names = new Set(optionNames);
|
|
25
|
+
optionExpectationNames.forEach((name) => names.add(name));
|
|
26
|
+
return names;
|
|
27
|
+
};
|
|
28
|
+
const validComponentNames = () => {
|
|
29
|
+
const names = new Set(componentNames);
|
|
30
|
+
componentExpectationNames.forEach((name) => names.add(name));
|
|
31
|
+
return names;
|
|
32
|
+
};
|
|
33
|
+
serialised.options.forEach((option) => {
|
|
34
|
+
if (optionNames.has(option.name)) {
|
|
35
|
+
errors = [
|
|
36
|
+
...errors,
|
|
37
|
+
{
|
|
38
|
+
kind: 'duplicate-option',
|
|
39
|
+
name: option.name,
|
|
40
|
+
detail: `Duplicate option '${option.name}'`
|
|
41
|
+
}
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
optionNames.add(option.name);
|
|
45
|
+
const validPaths = validOptionPaths();
|
|
46
|
+
option.gatePaths.forEach((gatePath) => {
|
|
47
|
+
const [pathName] = gatePath;
|
|
48
|
+
if (typeof pathName === 'string' && !validPaths.has(pathName)) {
|
|
49
|
+
errors = [
|
|
50
|
+
...errors,
|
|
51
|
+
{
|
|
52
|
+
kind: 'invalid-gate-path',
|
|
53
|
+
name: option.name,
|
|
54
|
+
detail: `Option '${option.name}' has gate path '${String(pathName)}' which does not reference a known option or expectation`
|
|
55
|
+
}
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
if (option.config !== null) {
|
|
60
|
+
if (option.config.type === 'match' && 'matchPath' in option.config) {
|
|
61
|
+
const [matchPathName] = option.config.matchPath;
|
|
62
|
+
if (typeof matchPathName === 'string' && !validPaths.has(matchPathName)) {
|
|
63
|
+
errors = [
|
|
64
|
+
...errors,
|
|
65
|
+
{
|
|
66
|
+
kind: 'invalid-config-path',
|
|
67
|
+
name: option.name,
|
|
68
|
+
detail: `Option '${option.name}' has match path '${String(matchPathName)}' which does not reference a known option or expectation`
|
|
69
|
+
}
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (option.config.type === 'unless' && 'unlessPath' in option.config) {
|
|
74
|
+
const [unlessPathName] = option.config.unlessPath;
|
|
75
|
+
if (typeof unlessPathName === 'string' && !validPaths.has(unlessPathName)) {
|
|
76
|
+
errors = [
|
|
77
|
+
...errors,
|
|
78
|
+
{
|
|
79
|
+
kind: 'invalid-config-path',
|
|
80
|
+
name: option.name,
|
|
81
|
+
detail: `Option '${option.name}' has unless path '${String(unlessPathName)}' which does not reference a known option or expectation`
|
|
82
|
+
}
|
|
83
|
+
];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
const validPaths = validOptionPaths();
|
|
89
|
+
serialised.components.forEach((component) => {
|
|
90
|
+
if (componentNames.has(component.name)) {
|
|
91
|
+
errors = [
|
|
92
|
+
...errors,
|
|
93
|
+
{
|
|
94
|
+
kind: 'duplicate-component',
|
|
95
|
+
name: component.name,
|
|
96
|
+
detail: `Duplicate component '${component.name}'`
|
|
97
|
+
}
|
|
98
|
+
];
|
|
99
|
+
}
|
|
100
|
+
componentNames.add(component.name);
|
|
101
|
+
component.paths.forEach((path) => {
|
|
102
|
+
const [pathName] = path;
|
|
103
|
+
if (typeof pathName === 'string' && !validPaths.has(pathName)) {
|
|
104
|
+
errors = [
|
|
105
|
+
...errors,
|
|
106
|
+
{
|
|
107
|
+
kind: 'invalid-component-path',
|
|
108
|
+
name: component.name,
|
|
109
|
+
detail: `Component '${component.name}' references path '${String(pathName)}' which does not reference a known option or expectation`
|
|
110
|
+
}
|
|
111
|
+
];
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
component.dependencies.forEach((dependency) => {
|
|
115
|
+
if (!validComponentNames().has(dependency)) {
|
|
116
|
+
errors = [
|
|
117
|
+
...errors,
|
|
118
|
+
{
|
|
119
|
+
kind: 'invalid-component-dependency',
|
|
120
|
+
name: component.name,
|
|
121
|
+
detail: `Component '${component.name}' depends on '${dependency}' which does not reference a known component or expectation`
|
|
122
|
+
}
|
|
123
|
+
];
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
serialised.collections.forEach((collection) => {
|
|
128
|
+
if (collectionNames.has(collection.name)) {
|
|
129
|
+
errors = [
|
|
130
|
+
...errors,
|
|
131
|
+
{
|
|
132
|
+
kind: 'duplicate-collection',
|
|
133
|
+
name: collection.name,
|
|
134
|
+
detail: `Duplicate collection '${collection.name}'`
|
|
135
|
+
}
|
|
136
|
+
];
|
|
137
|
+
}
|
|
138
|
+
collectionNames.add(collection.name);
|
|
139
|
+
});
|
|
140
|
+
serialised.collections.forEach((collection) => {
|
|
141
|
+
const [, nestedErrors] = validateSerialised(collection.builder);
|
|
142
|
+
errors = [...errors, ...nestedErrors];
|
|
143
|
+
});
|
|
144
|
+
if (options?.strict && errors.length > 0) {
|
|
145
|
+
throw new BuilderSerialisedValidateError(errors);
|
|
146
|
+
}
|
|
147
|
+
return [serialised, errors];
|
|
148
|
+
}
|
package/dist/ui.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { BuilderModelPaths } from './paths';
|
|
2
|
-
import type { BuilderCollectionNamesOf,
|
|
2
|
+
import type { BuilderCollectionNamesOf, BuilderGeneric } from './core/index';
|
|
3
3
|
import type { BuilderExpectationEntries, BuilderExpectations, BuilderModelAsserted } from './core/expectation';
|
|
4
|
+
import type { BuilderValidated } from './core/validate';
|
|
4
5
|
import type { BuilderUIItems } from './schemas/index';
|
|
5
6
|
export type BuilderUIGeneric = BuilderUI<BuilderGeneric>;
|
|
6
|
-
export type
|
|
7
|
-
export
|
|
8
|
-
export declare class BuilderUI<Builder extends BuilderGeneric = BuilderGeneric> {
|
|
7
|
+
export type BuilderUIs = ReadonlyArray<BuilderUI<BuilderGeneric | null>>;
|
|
8
|
+
export declare class BuilderUI<Builder extends BuilderGeneric | null = BuilderGeneric> {
|
|
9
9
|
readonly builder: Builder;
|
|
10
10
|
readonly items: BuilderUIItems;
|
|
11
11
|
readonly expectations: BuilderExpectationEntries;
|
|
@@ -13,6 +13,7 @@ export declare class BuilderUI<Builder extends BuilderGeneric = BuilderGeneric>
|
|
|
13
13
|
expect<const Expectations extends BuilderExpectations>(...expectations: Expectations): BuilderUI<BuilderModelAsserted<Builder, Expectations>>;
|
|
14
14
|
page(label: string | null, paths: BuilderModelPaths<Builder>): BuilderUI<Builder>;
|
|
15
15
|
describe(label: string | null, paths: BuilderModelPaths<Builder>): BuilderUI<Builder>;
|
|
16
|
-
collection<const Name extends BuilderCollectionNamesOf<Builder>>(name: Name, label: string,
|
|
16
|
+
collection<const Name extends BuilderCollectionNamesOf<Builder>>(name: Name, label: string, itemUI: BuilderUI<BuilderGeneric | null>): BuilderUI<Builder>;
|
|
17
17
|
}
|
|
18
|
-
export declare function ui
|
|
18
|
+
export declare function ui(): BuilderUI<null>;
|
|
19
|
+
export declare function ui<const Builder extends BuilderValidated>(builder: Builder, ...uis: BuilderUIs): BuilderUI<Builder>;
|
package/dist/ui.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { BuilderExpectation } from './core/expectation.js';
|
|
1
|
+
import { Builder } from './core/builder.js';
|
|
3
2
|
import { check } from './check.js';
|
|
3
|
+
import { validateBuilder } from './core/validate.js';
|
|
4
4
|
export class BuilderUI {
|
|
5
5
|
builder;
|
|
6
6
|
items;
|
|
@@ -21,22 +21,24 @@ export class BuilderUI {
|
|
|
21
21
|
describe(label, paths) {
|
|
22
22
|
return new BuilderUI(this.builder, [...this.items, { type: 'describe', label, paths }], this.expectations);
|
|
23
23
|
}
|
|
24
|
-
collection(name, label,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return new BuilderUI(this.builder, [...this.items, { type: 'collection', name, label, items:
|
|
24
|
+
collection(name, label, itemUI) {
|
|
25
|
+
if (this.builder) {
|
|
26
|
+
const foundCollection = this.builder.collections.find((entry) => entry.name === name);
|
|
27
|
+
check.truthy(foundCollection, `Collection '${name}' not found! ❌`);
|
|
28
|
+
}
|
|
29
|
+
return new BuilderUI(this.builder, [...this.items, { type: 'collection', name, label, items: itemUI.items }], this.expectations);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
export function ui(builder, ...uis) {
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
if (!builder) {
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- null builder for partial UIs, typed as BuilderUI<null>
|
|
35
|
+
return new BuilderUI(null);
|
|
36
|
+
}
|
|
37
|
+
const merged = uis.reduce((accumulated, currentUI) => {
|
|
38
|
+
return new BuilderUI(
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accumulated.builder is always the real builder from the first argument
|
|
40
|
+
accumulated.builder, [...accumulated.items, ...currentUI.items], [...accumulated.expectations, ...currentUI.expectations]);
|
|
35
41
|
}, new BuilderUI(builder));
|
|
36
|
-
merged.expectations
|
|
37
|
-
if (v.is(v.instance(BuilderExpectation), expectation) && expectation.kind === 'option') {
|
|
38
|
-
expectation.validate(merged.builder.options);
|
|
39
|
-
}
|
|
40
|
-
});
|
|
42
|
+
validateBuilder(new Builder(merged.builder.options, merged.builder.components, merged.builder.collections, merged.expectations), { strict: true });
|
|
41
43
|
return merged;
|
|
42
44
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@builder-builder/builder",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
|
40
40
|
"@testing-library/jest-dom": "^6.6.3",
|
|
41
41
|
"@testing-library/svelte": "^5.2.4",
|
|
42
|
+
"@vitest/coverage-v8": "^3.1.4",
|
|
42
43
|
"dotenv-cli": "^8.0.0",
|
|
43
44
|
"eslint": "^9.18.0",
|
|
44
45
|
"eslint-config-prettier": "^10.0.1",
|
|
@@ -64,7 +65,7 @@
|
|
|
64
65
|
"@vercel/kv": "^3.0.0",
|
|
65
66
|
"comlink": "^4.4.2",
|
|
66
67
|
"fast-deep-equal": "^3.1.3",
|
|
67
|
-
"svelte-clerk": "^
|
|
68
|
+
"svelte-clerk": "^1.1.1",
|
|
68
69
|
"valibot": "^1.1.0"
|
|
69
70
|
}
|
|
70
71
|
}
|