@builder-builder/builder 0.0.13 → 0.0.15
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 +3 -1
- package/dist/bb.js +6 -1
- package/dist/check.d.ts +2 -2
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +53 -0
- package/dist/codegen/index.d.ts +7 -0
- package/dist/codegen/index.js +212 -0
- package/dist/codegen/template.d.ts +5 -0
- package/dist/codegen/template.js +17 -0
- package/dist/entities/builder/builder.d.ts +11 -1
- package/dist/entities/builder/builder.js +22 -6
- package/dist/entities/collection/collection.d.ts +7 -1
- package/dist/entities/collection/collection.js +9 -2
- package/dist/entities/collection/config.d.ts +6 -1
- package/dist/entities/collection/config.js +9 -2
- package/dist/entities/component/component.d.ts +41 -1
- package/dist/entities/component/component.js +9 -2
- package/dist/entities/component/details.d.ts +11 -2
- package/dist/entities/component/details.js +9 -2
- package/dist/entities/component/field.d.ts +10 -1
- package/dist/entities/component/field.js +13 -3
- package/dist/entities/index.d.ts +7 -3
- package/dist/entities/index.js +3 -1
- package/dist/entities/kind.d.ts +1 -1
- package/dist/entities/model/model.d.ts +5 -1
- package/dist/entities/model/model.js +10 -3
- package/dist/entities/model/models.js +9 -5
- package/dist/entities/option/option.d.ts +41 -1
- package/dist/entities/option/option.js +9 -2
- package/dist/entities/option/select.d.ts +7 -1
- package/dist/entities/option/select.js +17 -6
- package/dist/entities/option/toggle.d.ts +7 -1
- package/dist/entities/option/toggle.js +16 -4
- package/dist/entities/option/values.d.ts +6 -0
- package/dist/entities/pricing.d.ts +64 -0
- package/dist/entities/pricing.js +48 -0
- package/dist/entities/serialise.d.ts +632 -8
- package/dist/entities/serialise.js +33 -12
- package/dist/entities/tags.d.ts +3 -0
- package/dist/entities/tags.js +2 -0
- package/dist/entities/ui/describe.d.ts +231 -8
- package/dist/entities/ui/describe.js +12 -5
- package/dist/entities/ui/index.d.ts +2 -0
- package/dist/entities/ui/index.js +1 -0
- package/dist/entities/ui/input.d.ts +343 -0
- package/dist/entities/ui/input.js +51 -0
- package/dist/entities/ui/page.d.ts +231 -8
- package/dist/entities/ui/page.js +12 -5
- package/dist/entities/ui/pages.d.ts +5 -1
- package/dist/entities/ui/pages.js +9 -2
- package/dist/entities/ui/ui.d.ts +9 -4
- package/dist/entities/ui/ui.js +29 -11
- package/dist/entities/validated.d.ts +7 -3
- package/dist/exception.d.ts +2 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/instance.d.ts +9 -0
- package/dist/instance.js +3 -1
- package/dist/mappers/index.d.ts +6 -4
- package/dist/mappers/index.js +3 -2
- package/dist/mappers/pricing.d.ts +3 -0
- package/dist/mappers/pricing.js +101 -0
- package/dist/mappers/render/index.d.ts +1 -1
- package/dist/mappers/render/pages.d.ts +8 -0
- package/dist/mappers/render/pages.js +2 -1
- package/dist/mappers/render/render.js +19 -3
- package/dist/mappers/resolve.d.ts +4 -4
- package/dist/mappers/variants/index.d.ts +2 -1
- package/dist/mappers/variants/index.js +2 -1
- package/dist/mappers/variants/variants.d.ts +5 -2
- package/dist/mappers/variants/variants.js +2 -2
- package/dist/validate/brand.d.ts +0 -7
- package/dist/validate/brand.js +5 -5
- package/dist/validate/builder.d.ts +2 -1
- package/dist/validate/builder.js +19 -13
- package/dist/validate/errors.d.ts +138 -0
- package/dist/validate/errors.js +148 -0
- package/dist/validate/expectations.d.ts +3 -10
- package/dist/validate/expectations.js +8 -10
- package/dist/validate/index.d.ts +10 -14
- package/dist/validate/index.js +5 -7
- package/dist/validate/instance.d.ts +2 -15
- package/dist/validate/instance.js +41 -40
- package/dist/validate/model.d.ts +4 -31
- package/dist/validate/model.js +157 -176
- package/dist/validate/pricing.d.ts +6 -0
- package/dist/validate/pricing.js +71 -0
- package/dist/validate/resolve.d.ts +3 -15
- package/dist/validate/resolve.js +66 -69
- package/dist/validate/result.d.ts +1 -7
- package/dist/validate/result.js +1 -4
- package/dist/validate/ui.d.ts +4 -4
- package/dist/validate/ui.js +80 -62
- package/dist/validate/variants.d.ts +2 -53
- package/dist/validate/variants.js +83 -86
- package/package.json +12 -3
package/dist/entities/ui/page.js
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import * as v from 'valibot';
|
|
2
|
-
import { BuilderPathsSchema } from '../../paths.js';
|
|
3
2
|
import { paramable } from '../../references.js';
|
|
4
3
|
import { serialisable } from '../../serialisable.js';
|
|
4
|
+
import { BuilderTagsSchema } from '../tags.js';
|
|
5
|
+
import { BuilderUIInputsSerialisedSchema } from './input.js';
|
|
5
6
|
export class BuilderUIPage {
|
|
6
7
|
type = 'page';
|
|
7
8
|
label;
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
inputs;
|
|
10
|
+
tags;
|
|
11
|
+
constructor(label, inputs, tags) {
|
|
10
12
|
this.label = label;
|
|
11
|
-
this.
|
|
13
|
+
this.inputs = inputs;
|
|
14
|
+
this.tags = tags;
|
|
15
|
+
}
|
|
16
|
+
tag(...tags) {
|
|
17
|
+
return new BuilderUIPage(this.label, this.inputs, tags);
|
|
12
18
|
}
|
|
13
19
|
}
|
|
14
20
|
export const BuilderUIPageSchema = v.instance(BuilderUIPage);
|
|
15
21
|
export const BuilderUIPageSerialisedSchema = serialisable(v.object({
|
|
16
22
|
type: v.literal('page'),
|
|
17
23
|
label: paramable(v.string()),
|
|
18
|
-
|
|
24
|
+
inputs: paramable(BuilderUIInputsSerialisedSchema),
|
|
25
|
+
tags: v.optional(BuilderTagsSchema)
|
|
19
26
|
}));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Paramable, ParamableSerialised } from '../../references';
|
|
2
|
+
import type { BuilderTags } from '../tags';
|
|
2
3
|
import type { BuilderUIDescribe, BuilderUIDescribeSerialised } from './describe';
|
|
3
4
|
import type { BuilderUIPage, BuilderUIPageSerialised } from './page';
|
|
4
5
|
import * as v from 'valibot';
|
|
@@ -9,7 +10,9 @@ export declare class BuilderUIPages<const Name extends string = string, const La
|
|
|
9
10
|
readonly name: Name;
|
|
10
11
|
readonly label: Label;
|
|
11
12
|
readonly items: Items;
|
|
12
|
-
|
|
13
|
+
readonly tags?: BuilderTags;
|
|
14
|
+
constructor(name: Name, label: Label, items: Items, tags?: BuilderTags);
|
|
15
|
+
tag(...tags: Array<string>): BuilderUIPages<Name, Label, Items>;
|
|
13
16
|
}
|
|
14
17
|
export declare const BuilderUIPagesSchema: v.InstanceSchema<typeof BuilderUIPages, undefined>;
|
|
15
18
|
export type BuilderUIPagesSerialised = {
|
|
@@ -17,6 +20,7 @@ export type BuilderUIPagesSerialised = {
|
|
|
17
20
|
readonly name: string;
|
|
18
21
|
readonly label: ParamableSerialised<string>;
|
|
19
22
|
readonly items: ParamableSerialised<BuilderUIItemsSerialised>;
|
|
23
|
+
readonly tags?: BuilderTags;
|
|
20
24
|
};
|
|
21
25
|
export type BuilderUIItemSerialised = BuilderUIPageSerialised | BuilderUIDescribeSerialised | BuilderUIPagesSerialised;
|
|
22
26
|
export type BuilderUIItemsSerialised = ReadonlyArray<ParamableSerialised<BuilderUIItemSerialised>>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as v from 'valibot';
|
|
2
2
|
import { paramable } from '../../references.js';
|
|
3
3
|
import { serialisable } from '../../serialisable.js';
|
|
4
|
+
import { BuilderTagsSchema } from '../tags.js';
|
|
4
5
|
import { BuilderUIDescribeSerialisedSchema } from './describe.js';
|
|
5
6
|
import { BuilderUIPageSerialisedSchema } from './page.js';
|
|
6
7
|
export class BuilderUIPages {
|
|
@@ -8,10 +9,15 @@ export class BuilderUIPages {
|
|
|
8
9
|
name;
|
|
9
10
|
label;
|
|
10
11
|
items;
|
|
11
|
-
|
|
12
|
+
tags;
|
|
13
|
+
constructor(name, label, items, tags) {
|
|
12
14
|
this.name = name;
|
|
13
15
|
this.label = label;
|
|
14
16
|
this.items = items;
|
|
17
|
+
this.tags = tags;
|
|
18
|
+
}
|
|
19
|
+
tag(...tags) {
|
|
20
|
+
return new BuilderUIPages(this.name, this.label, this.items, tags);
|
|
15
21
|
}
|
|
16
22
|
}
|
|
17
23
|
export const BuilderUIPagesSchema = v.instance(BuilderUIPages);
|
|
@@ -19,7 +25,8 @@ export const BuilderUIPagesSerialisedSchema = serialisable(v.object({
|
|
|
19
25
|
type: v.literal('pages'),
|
|
20
26
|
name: v.string(),
|
|
21
27
|
label: paramable(v.string()),
|
|
22
|
-
items: paramable(v.lazy(() => BuilderUIItemsSerialisedSchema))
|
|
28
|
+
items: paramable(v.lazy(() => BuilderUIItemsSerialisedSchema)),
|
|
29
|
+
tags: v.optional(BuilderTagsSchema)
|
|
23
30
|
}));
|
|
24
31
|
export const BuilderUIItemSerialisedSchema = v.union([
|
|
25
32
|
BuilderUIPageSerialisedSchema,
|
package/dist/entities/ui/ui.d.ts
CHANGED
|
@@ -3,27 +3,32 @@ import type { BuilderExpectation, BuilderExpectations, BuilderExpectationsSerial
|
|
|
3
3
|
import type { CollectionNamesOf } from '../collection/index';
|
|
4
4
|
import type { BuilderModel, BuilderModelGeneric, BuilderModelStateOf } from '../model/model';
|
|
5
5
|
import type { BuilderModelStateAsserted } from '../model/expectation';
|
|
6
|
-
import type {
|
|
6
|
+
import type { BuilderTags } from '../tags';
|
|
7
|
+
import type { BuilderUIValidInputsOf } from './input';
|
|
7
8
|
import type { BuilderUIItems, BuilderUIItemsSerialised } from './pages';
|
|
8
9
|
import * as v from 'valibot';
|
|
9
10
|
export type BuilderUIs = ReadonlyArray<Paramable<BuilderUI>>;
|
|
10
11
|
export type BuilderUIsSerialised = ReadonlyArray<ParamableSerialised<BuilderUISerialised>>;
|
|
11
12
|
export declare class BuilderUI<Model extends BuilderModelGeneric = BuilderModelGeneric> {
|
|
13
|
+
#private;
|
|
12
14
|
readonly type: 'ui';
|
|
13
15
|
readonly model: Model;
|
|
14
16
|
readonly uis: BuilderUIs;
|
|
15
17
|
readonly items: BuilderUIItems;
|
|
16
18
|
readonly expectations: BuilderExpectations;
|
|
17
|
-
|
|
19
|
+
readonly tags?: BuilderTags;
|
|
20
|
+
constructor(uis: BuilderUIs, items: BuilderUIItems, expectations: BuilderExpectations, tags?: BuilderTags);
|
|
18
21
|
expect<const Exps extends readonly [BuilderExpectation, ...ReadonlyArray<BuilderExpectation>]>(...expectations: Exps): BuilderUI<BuilderModel<BuilderModelStateAsserted<BuilderModelStateOf<Model>, Exps>>>;
|
|
19
|
-
page(label: Paramable<string>,
|
|
20
|
-
describe(label: Paramable<string>,
|
|
22
|
+
page(label: Paramable<string>, inputs: Paramable<BuilderUIValidInputsOf<Model>>): BuilderUI<Model>;
|
|
23
|
+
describe(label: Paramable<string>, inputs: Paramable<BuilderUIValidInputsOf<Model>>): BuilderUI<Model>;
|
|
21
24
|
pages<const Name extends CollectionNamesOf<BuilderModelStateOf<Model>>>(name: Name, label: Paramable<string>, itemUI: Paramable<BuilderUI<BuilderModelGeneric>>): BuilderUI<Model>;
|
|
25
|
+
tag(...tags: Array<string>): BuilderUI<Model>;
|
|
22
26
|
}
|
|
23
27
|
export declare const BuilderUISchema: v.InstanceSchema<typeof BuilderUI, undefined>;
|
|
24
28
|
export interface BuilderUISerialised {
|
|
25
29
|
readonly uis: BuilderUIsSerialised;
|
|
26
30
|
readonly items: BuilderUIItemsSerialised;
|
|
27
31
|
readonly expectations: BuilderExpectationsSerialised;
|
|
32
|
+
readonly tags?: BuilderTags;
|
|
28
33
|
}
|
|
29
34
|
export declare const BuilderUISerialisedSchema: v.GenericSchema<BuilderUISerialised>;
|
package/dist/entities/ui/ui.js
CHANGED
|
@@ -3,6 +3,7 @@ import { check } from '../../check.js';
|
|
|
3
3
|
import { paramable } from '../../references.js';
|
|
4
4
|
import { serialisable } from '../../serialisable.js';
|
|
5
5
|
import { BuilderExpectationsSerialisedSchema } from '../expectation.js';
|
|
6
|
+
import { BuilderTagsSchema } from '../tags.js';
|
|
6
7
|
import { BuilderUIDescribe } from './describe.js';
|
|
7
8
|
import { BuilderUIPage } from './page.js';
|
|
8
9
|
import { BuilderUIItemsSerialisedSchema, BuilderUIPages } from './pages.js';
|
|
@@ -10,31 +11,48 @@ export class BuilderUI {
|
|
|
10
11
|
uis;
|
|
11
12
|
items;
|
|
12
13
|
expectations;
|
|
13
|
-
|
|
14
|
+
tags;
|
|
15
|
+
constructor(uis, items, expectations, tags) {
|
|
14
16
|
this.uis = uis;
|
|
15
17
|
this.items = items;
|
|
16
18
|
this.expectations = expectations;
|
|
19
|
+
this.tags = tags;
|
|
20
|
+
}
|
|
21
|
+
#next(patch) {
|
|
22
|
+
return new BuilderUI(this.uis, patch.items ?? this.items, patch.expectations ?? this.expectations, patch.tags ?? this.tags);
|
|
17
23
|
}
|
|
18
24
|
expect(...expectations) {
|
|
19
|
-
return
|
|
20
|
-
...this.expectations,
|
|
21
|
-
|
|
22
|
-
]);
|
|
25
|
+
return this.#next({
|
|
26
|
+
expectations: [...this.expectations, ...expectations]
|
|
27
|
+
});
|
|
23
28
|
}
|
|
24
|
-
page(label,
|
|
25
|
-
return
|
|
29
|
+
page(label, inputs) {
|
|
30
|
+
return this.#next({
|
|
31
|
+
items: [...this.items, new BuilderUIPage(label, inputs)]
|
|
32
|
+
});
|
|
26
33
|
}
|
|
27
|
-
describe(label,
|
|
28
|
-
return
|
|
34
|
+
describe(label, inputs) {
|
|
35
|
+
return this.#next({
|
|
36
|
+
items: [
|
|
37
|
+
...this.items,
|
|
38
|
+
new BuilderUIDescribe(label, inputs)
|
|
39
|
+
]
|
|
40
|
+
});
|
|
29
41
|
}
|
|
30
42
|
pages(name, label, itemUI) {
|
|
31
43
|
const items = check.is(BuilderUISchema, itemUI) ? itemUI.items : itemUI;
|
|
32
|
-
return
|
|
44
|
+
return this.#next({
|
|
45
|
+
items: [...this.items, new BuilderUIPages(name, label, items)]
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
tag(...tags) {
|
|
49
|
+
return this.#next({ tags });
|
|
33
50
|
}
|
|
34
51
|
}
|
|
35
52
|
export const BuilderUISchema = v.instance(BuilderUI);
|
|
36
53
|
export const BuilderUISerialisedSchema = serialisable(v.object({
|
|
37
54
|
uis: v.pipe(v.array(paramable(v.lazy(() => BuilderUISerialisedSchema))), v.readonly()),
|
|
38
55
|
items: BuilderUIItemsSerialisedSchema,
|
|
39
|
-
expectations: BuilderExpectationsSerialisedSchema
|
|
56
|
+
expectations: BuilderExpectationsSerialisedSchema,
|
|
57
|
+
tags: v.optional(BuilderTagsSchema)
|
|
40
58
|
}));
|
|
@@ -4,11 +4,12 @@ import type { Prettify } from '../prettify';
|
|
|
4
4
|
import type { BuilderParameter, BuilderParameterSerialised, BuilderRef, BuilderRefSerialised } from '../references';
|
|
5
5
|
import type { BuilderSerialised } from './builder/index';
|
|
6
6
|
import type { BuilderCollectionConfigSerialised, BuilderCollectionSerialised, BuilderCollectionsSerialised } from './collection/index';
|
|
7
|
-
import type { BuilderComponentSerialised, BuilderComponentsSerialised } from './component/index';
|
|
7
|
+
import type { BuilderComponentDetailsSerialised, BuilderComponentSerialised, BuilderComponentsSerialised } from './component/index';
|
|
8
8
|
import type { BuilderModelSerialised } from './model/index';
|
|
9
|
-
import type { BuilderOptionSerialised, BuilderOptionsSerialised } from './option/index';
|
|
9
|
+
import type { BuilderOptionSerialised, BuilderOptionsSerialised, BuilderOptionValuesSerialised } from './option/index';
|
|
10
|
+
import type { BuilderPricing } from './pricing';
|
|
10
11
|
import type { BuilderUIDescribeSerialised, BuilderUIItemsSerialised, BuilderUIPageSerialised, BuilderUISerialised } from './ui/index';
|
|
11
|
-
export type Validated<Input> = Input extends BuilderComponentVariants | BuilderInstance | BuilderModelSerialised | BuilderSerialised | BuilderUISerialised ? Validate<Input> & BuilderValidatedBrand : Validate<Input>;
|
|
12
|
+
export type Validated<Input> = Input extends BuilderComponentVariants | BuilderInstance | BuilderModelSerialised | BuilderPricing | BuilderSerialised | BuilderUISerialised ? Validate<Input> & BuilderValidatedBrand : Validate<Input>;
|
|
12
13
|
type Validate<Input> = Input extends BuilderParameter<string> | BuilderParameterSerialised | BuilderRef | BuilderRefSerialised ? never : Input extends ReadonlyArray<unknown> ? ValidatedTuple<Input> : Input extends object ? {
|
|
13
14
|
readonly [Key in keyof Input]: Validated<Input[Key]>;
|
|
14
15
|
} : Input;
|
|
@@ -24,11 +25,14 @@ export type BuilderInstancesValidated = Prettify<Validated<BuilderInstances>>;
|
|
|
24
25
|
export type BuilderComponentVariantsValidated = Prettify<Validated<BuilderComponentVariants>>;
|
|
25
26
|
export type BuilderOptionValidated = Prettify<Validated<BuilderOptionSerialised>>;
|
|
26
27
|
export type BuilderOptionsValidated = Prettify<Validated<BuilderOptionsSerialised>>;
|
|
28
|
+
export type BuilderOptionValuesValidated = Prettify<Validated<BuilderOptionValuesSerialised>>;
|
|
27
29
|
export type BuilderComponentValidated = Prettify<Validated<BuilderComponentSerialised>>;
|
|
28
30
|
export type BuilderComponentsValidated = Prettify<Validated<BuilderComponentsSerialised>>;
|
|
31
|
+
export type BuilderComponentDetailsValidated = Prettify<Validated<BuilderComponentDetailsSerialised>>;
|
|
29
32
|
export type BuilderCollectionValidated = Prettify<Validated<BuilderCollectionSerialised>>;
|
|
30
33
|
export type BuilderCollectionsValidated = Prettify<Validated<BuilderCollectionsSerialised>>;
|
|
31
34
|
export type BuilderCollectionConfigValidated = Prettify<Validated<BuilderCollectionConfigSerialised>>;
|
|
35
|
+
export type BuilderPricingValidated = Prettify<Validated<BuilderPricing>>;
|
|
32
36
|
export type BuilderUIItemsValidated = Prettify<Validated<BuilderUIItemsSerialised>>;
|
|
33
37
|
export type BuilderUIPageValidated = Prettify<Validated<BuilderUIPageSerialised>>;
|
|
34
38
|
export type BuilderUIDescribeValidated = Prettify<Validated<BuilderUIDescribeSerialised>>;
|
package/dist/exception.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { BuilderErrorDuplicateName, BuilderErrorInvalidCollection, BuilderErrorInvalidCollectionBounds, BuilderErrorInvalidDetail, BuilderErrorInvalidInput, BuilderErrorInvalidOption, BuilderErrorInvalidPath, BuilderErrorInvalidSelectMapKey, BuilderErrorInvalidVariant, BuilderErrorMissingComponent, BuilderErrorMissingDetail, BuilderErrorMissingReference, BuilderErrorMissingVariant, BuilderErrorUnboundParameter, BuilderErrorUnexpectedComponent, BuilderErrorUnexpectedDetail, BuilderErrorUnmetExpectation, BuilderErrorUnvalidated } from './validate/index';
|
|
1
|
+
import type { BuilderErrorDuplicateName, BuilderErrorInvalidCollection, BuilderErrorInvalidCollectionBounds, BuilderErrorInvalidDetail, BuilderErrorInvalidInput, BuilderErrorInvalidOption, BuilderErrorInvalidPath, BuilderErrorInvalidPricing, BuilderErrorInvalidSelectMapKey, BuilderErrorInvalidVariant, BuilderErrorMissingComponent, BuilderErrorMissingDetail, BuilderErrorMissingReference, BuilderErrorMissingVariant, BuilderErrorUnboundParameter, BuilderErrorUnexpectedComponent, BuilderErrorUnexpectedDetail, BuilderErrorUnmetExpectation, BuilderErrorUnvalidated } from './validate/index';
|
|
2
2
|
export type BuilderErrorLocation = ReadonlyArray<string | number>;
|
|
3
3
|
export declare function builderError<Kind extends string>(kind: Kind, location: BuilderErrorLocation): {
|
|
4
4
|
kind: Kind;
|
|
5
5
|
location: BuilderErrorLocation;
|
|
6
6
|
};
|
|
7
7
|
export type BuilderErrorBase = ReturnType<typeof builderError>;
|
|
8
|
-
export type BuilderError = BuilderErrorUnmetExpectation | BuilderErrorUnboundParameter | BuilderErrorMissingReference | BuilderErrorInvalidPath | BuilderErrorInvalidSelectMapKey | BuilderErrorDuplicateName | BuilderErrorInvalidCollectionBounds | BuilderErrorInvalidOption | BuilderErrorInvalidCollection | BuilderErrorMissingComponent | BuilderErrorUnexpectedComponent | BuilderErrorMissingVariant | BuilderErrorInvalidVariant | BuilderErrorMissingDetail | BuilderErrorUnexpectedDetail | BuilderErrorInvalidDetail | BuilderErrorInvalidInput | BuilderErrorUnvalidated;
|
|
8
|
+
export type BuilderError = BuilderErrorUnmetExpectation | BuilderErrorUnboundParameter | BuilderErrorMissingReference | BuilderErrorInvalidPath | BuilderErrorInvalidPricing | BuilderErrorInvalidSelectMapKey | BuilderErrorDuplicateName | BuilderErrorInvalidCollectionBounds | BuilderErrorInvalidOption | BuilderErrorInvalidCollection | BuilderErrorMissingComponent | BuilderErrorUnexpectedComponent | BuilderErrorMissingVariant | BuilderErrorInvalidVariant | BuilderErrorMissingDetail | BuilderErrorUnexpectedDetail | BuilderErrorInvalidDetail | BuilderErrorInvalidInput | BuilderErrorUnvalidated;
|
|
9
9
|
export type BuilderErrors = ReadonlyArray<BuilderError>;
|
|
10
10
|
export declare class BuilderException extends globalThis.Error {
|
|
11
11
|
readonly errors: BuilderErrors;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
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, BuilderComponentVariantsValidated, BuilderInstanceValidated, 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, BuilderPricing, BuilderPricingExpression, BuilderPricingReduce, BuilderPricingTagExpression, BuilderSerialised, BuilderTags, BuilderToggleType, BuilderToggleTypeSerialised, BuilderToggleValueType, BuilderUI, BuilderUIDescribe, BuilderUIDescribeSerialised, BuilderUIInput, BuilderUIInputMetadata, BuilderUIInputMetadataSerialised, BuilderUIInputs, BuilderUIInputsSerialised, BuilderUIInputSerialised, 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
|
-
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';
|
|
5
|
+
export type { BuilderComponentVariantsValidationResult, BuilderErrorDuplicateName, BuilderErrorInvalidCollection, BuilderErrorInvalidCollectionBounds, BuilderErrorInvalidDetail, BuilderErrorInvalidInput, BuilderErrorInvalidOption, BuilderErrorInvalidPath, BuilderErrorInvalidPathReason, BuilderErrorInvalidPricing, BuilderErrorInvalidPricingReason, BuilderErrorInvalidSelectMapKey, BuilderErrorInvalidVariant, BuilderErrorMissingComponent, BuilderErrorMissingDetail, BuilderErrorMissingReference, BuilderErrorMissingVariant, BuilderErrorUnboundParameter, BuilderErrorUnexpectedComponent, BuilderErrorUnexpectedDetail, BuilderErrorUnmetExpectation, BuilderErrorUnvalidated, BuilderInstanceValidationResult, BuilderModelValidationResult, BuilderOrder, BuilderRenderMetadata, BuilderRenderOption, BuilderRenderOptions, BuilderRenderPage, BuilderRenderPages, BuilderRenderResult, BuilderRenderUpdate, BuilderUIValidationResult, BuilderValidationResult, BuilderVariantsValidationOptions } from './mappers/index';
|
|
6
6
|
export type { BuilderComponentVariants, BuilderInstance, BuilderInstanceInput, BuilderInstances, BuilderVariant, BuilderVariants } from './instance';
|
|
7
7
|
export type { BuilderPath, BuilderPaths } from './paths';
|
|
8
8
|
export type { BuilderPrimitive, BuilderPrimitives } from './primitive';
|
|
9
9
|
export type { BuilderParameter, BuilderParameterSerialised, BuilderRef, Paramable, ParamableSerialised } from './references';
|
|
10
10
|
export { bb } from './bb.js';
|
|
11
|
-
export { Builder, builder, detailBoolean, detailNumber, detailString, model, parameter, ref, select, serialise, toggleBoolean, toggleNumber, toggleString } from './entities/index.js';
|
|
11
|
+
export { Builder, builder, detailBoolean, detailNumber, detailString, input, model, parameter, ref, select, serialise, toggleBoolean, toggleNumber, toggleString } from './entities/index.js';
|
|
12
12
|
export { BuilderException } from './exception.js';
|
|
13
13
|
export { ordinal } from './mappers/index.js';
|
|
14
14
|
import { collectionConfig, collectionExpectation, componentDetails, componentExpectation, optionExpectation, uis } from './entities/index.js';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { bb } from './bb.js';
|
|
2
|
-
export { Builder, builder, detailBoolean, detailNumber, detailString, model, parameter, ref, select, serialise, toggleBoolean, toggleNumber, toggleString } from './entities/index.js';
|
|
2
|
+
export { Builder, builder, detailBoolean, detailNumber, detailString, input, model, parameter, ref, select, serialise, toggleBoolean, toggleNumber, toggleString } from './entities/index.js';
|
|
3
3
|
export { BuilderException } from './exception.js';
|
|
4
4
|
export { ordinal } from './mappers/index.js';
|
|
5
5
|
import { collectionConfig, collectionExpectation, collectionWhen, componentDetails, componentExpectation, componentWhen, optionExpectation, optionWhen, uis } from './entities/index.js';
|
package/dist/instance.d.ts
CHANGED
|
@@ -10,47 +10,56 @@ export type BuilderInstanceInput = Readonly<Record<string, unknown>>;
|
|
|
10
10
|
export declare const BuilderVariantSchema: v.SchemaWithPipe<readonly [v.ObjectSchema<{
|
|
11
11
|
readonly instance: v.GenericSchema<BuilderInstance>;
|
|
12
12
|
readonly details: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.NullableSchema<v.UnionSchema<[v.StringSchema<undefined>, v.BooleanSchema<undefined>, v.NumberSchema<undefined>], undefined>, undefined>, undefined>, undefined>;
|
|
13
|
+
readonly tags: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.ReadonlyAction<string[]>]>, undefined>;
|
|
13
14
|
}, undefined>, v.ReadonlyAction<{
|
|
14
15
|
instance: BuilderInstance;
|
|
15
16
|
details?: {
|
|
16
17
|
[x: string]: string | number | boolean | null;
|
|
17
18
|
} | undefined;
|
|
19
|
+
tags?: readonly string[] | undefined;
|
|
18
20
|
}>]>;
|
|
19
21
|
export type BuilderVariant = v.InferOutput<typeof BuilderVariantSchema>;
|
|
20
22
|
export declare const BuilderVariantsSchema: v.SchemaWithPipe<readonly [v.ArraySchema<v.SchemaWithPipe<readonly [v.ObjectSchema<{
|
|
21
23
|
readonly instance: v.GenericSchema<BuilderInstance>;
|
|
22
24
|
readonly details: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.NullableSchema<v.UnionSchema<[v.StringSchema<undefined>, v.BooleanSchema<undefined>, v.NumberSchema<undefined>], undefined>, undefined>, undefined>, undefined>;
|
|
25
|
+
readonly tags: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.ReadonlyAction<string[]>]>, undefined>;
|
|
23
26
|
}, undefined>, v.ReadonlyAction<{
|
|
24
27
|
instance: BuilderInstance;
|
|
25
28
|
details?: {
|
|
26
29
|
[x: string]: string | number | boolean | null;
|
|
27
30
|
} | undefined;
|
|
31
|
+
tags?: readonly string[] | undefined;
|
|
28
32
|
}>]>, undefined>, v.ReadonlyAction<Readonly<{
|
|
29
33
|
instance: BuilderInstance;
|
|
30
34
|
details?: {
|
|
31
35
|
[x: string]: string | number | boolean | null;
|
|
32
36
|
} | undefined;
|
|
37
|
+
tags?: readonly string[] | undefined;
|
|
33
38
|
}>[]>]>;
|
|
34
39
|
export type BuilderVariants = v.InferOutput<typeof BuilderVariantsSchema>;
|
|
35
40
|
export declare const BuilderComponentVariantsSchema: v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.SchemaWithPipe<readonly [v.ArraySchema<v.SchemaWithPipe<readonly [v.ObjectSchema<{
|
|
36
41
|
readonly instance: v.GenericSchema<BuilderInstance>;
|
|
37
42
|
readonly details: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.NullableSchema<v.UnionSchema<[v.StringSchema<undefined>, v.BooleanSchema<undefined>, v.NumberSchema<undefined>], undefined>, undefined>, undefined>, undefined>;
|
|
43
|
+
readonly tags: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.ReadonlyAction<string[]>]>, undefined>;
|
|
38
44
|
}, undefined>, v.ReadonlyAction<{
|
|
39
45
|
instance: BuilderInstance;
|
|
40
46
|
details?: {
|
|
41
47
|
[x: string]: string | number | boolean | null;
|
|
42
48
|
} | undefined;
|
|
49
|
+
tags?: readonly string[] | undefined;
|
|
43
50
|
}>]>, undefined>, v.ReadonlyAction<Readonly<{
|
|
44
51
|
instance: BuilderInstance;
|
|
45
52
|
details?: {
|
|
46
53
|
[x: string]: string | number | boolean | null;
|
|
47
54
|
} | undefined;
|
|
55
|
+
tags?: readonly string[] | undefined;
|
|
48
56
|
}>[]>]>, undefined>, v.ReadonlyAction<{
|
|
49
57
|
readonly [x: string]: readonly Readonly<{
|
|
50
58
|
instance: BuilderInstance;
|
|
51
59
|
details?: {
|
|
52
60
|
[x: string]: string | number | boolean | null;
|
|
53
61
|
} | undefined;
|
|
62
|
+
tags?: readonly string[] | undefined;
|
|
54
63
|
}>[];
|
|
55
64
|
}>]>;
|
|
56
65
|
export type BuilderComponentVariants = v.InferOutput<typeof BuilderComponentVariantsSchema>;
|
package/dist/instance.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import * as v from 'valibot';
|
|
2
2
|
import { BuilderPrimitiveSchema } from './primitive.js';
|
|
3
|
+
import { BuilderTagsSchema } from './entities/tags.js';
|
|
3
4
|
export const BuilderInstanceSchema = v.pipe(v.record(v.string(), v.union([BuilderPrimitiveSchema, v.lazy(() => BuilderInstancesSchema)])), v.readonly());
|
|
4
5
|
export const BuilderInstancesSchema = v.pipe(v.array(BuilderInstanceSchema), v.readonly());
|
|
5
6
|
export const BuilderVariantSchema = v.pipe(v.object({
|
|
6
7
|
instance: BuilderInstanceSchema,
|
|
7
|
-
details: v.optional(v.record(v.string(), BuilderPrimitiveSchema))
|
|
8
|
+
details: v.optional(v.record(v.string(), BuilderPrimitiveSchema)),
|
|
9
|
+
tags: v.optional(BuilderTagsSchema)
|
|
8
10
|
}), v.readonly());
|
|
9
11
|
export const BuilderVariantsSchema = v.pipe(v.array(BuilderVariantSchema), v.readonly());
|
|
10
12
|
export const BuilderComponentVariantsSchema = v.pipe(v.record(v.string(), BuilderVariantsSchema), v.readonly());
|
package/dist/mappers/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
export type { BuilderComponentVariantsValidationResult, BuilderErrorDuplicateName, BuilderErrorInvalidCollection, BuilderErrorInvalidCollectionBounds, BuilderErrorInvalidDetail, BuilderErrorInvalidInput, BuilderErrorInvalidOption, BuilderErrorInvalidPath, BuilderErrorInvalidPathReason, BuilderErrorInvalidSelectMapKey, BuilderErrorInvalidVariant, BuilderErrorMissingComponent, BuilderErrorMissingDetail, BuilderErrorMissingReference, BuilderErrorMissingVariant, BuilderErrorUnboundParameter, BuilderErrorUnexpectedComponent, BuilderErrorUnexpectedDetail, BuilderErrorUnmetExpectation, BuilderErrorUnvalidated, BuilderInstanceValidationResult, BuilderModelValidationResult, BuilderUIValidationResult, BuilderValidationResult, BuilderVariantsValidationOptions } from '../validate/index';
|
|
1
|
+
export type { BuilderComponentVariantsValidationResult, BuilderErrorDuplicateName, BuilderErrorInvalidCollection, BuilderErrorInvalidCollectionBounds, BuilderErrorInvalidDetail, BuilderErrorInvalidInput, BuilderErrorInvalidOption, BuilderErrorInvalidPath, BuilderErrorInvalidPathReason, BuilderErrorInvalidPricing, BuilderErrorInvalidPricingReason, BuilderErrorInvalidSelectMapKey, BuilderErrorInvalidVariant, BuilderErrorMissingComponent, BuilderErrorMissingDetail, BuilderErrorMissingReference, BuilderErrorMissingVariant, BuilderErrorUnboundParameter, BuilderErrorUnexpectedComponent, BuilderErrorUnexpectedDetail, BuilderErrorUnmetExpectation, BuilderErrorUnvalidated, BuilderInstanceValidationResult, BuilderModelValidationResult, BuilderPricingValidationResult, BuilderUIValidationResult, BuilderValidationResult, BuilderVariantsValidationOptions } from '../validate/index';
|
|
2
2
|
export type { BuilderOrder } from './order';
|
|
3
|
-
export type { BuilderRenderOption, BuilderRenderOptions, BuilderRenderPage, BuilderRenderPages, BuilderRenderResult, BuilderRenderUpdate } from './render/index';
|
|
4
|
-
export { assertValidated, validateBuilder, validateInstance, validateModel, validateUI, validateVariants } from '../validate/index.js';
|
|
3
|
+
export type { BuilderRenderMetadata, BuilderRenderOption, BuilderRenderOptions, BuilderRenderPage, BuilderRenderPages, BuilderRenderResult, BuilderRenderUpdate } from './render/index';
|
|
4
|
+
export { assertValidated, validateBuilder, validateInstance, validateModel, validatePricing, validateUI, validateVariants } from '../validate/index.js';
|
|
5
|
+
export type { BuilderOptionGraph } from './variants/index.js';
|
|
5
6
|
export { createInstance } from './instance.js';
|
|
6
|
-
export { createVariants } from './variants/index.js';
|
|
7
|
+
export { createVariants, optionGraph, variantsFor } from './variants/index.js';
|
|
7
8
|
export { order } from './order.js';
|
|
9
|
+
export { pricing } from './pricing.js';
|
|
8
10
|
export { ordinal, render } from './render/index.js';
|
|
9
11
|
export { resolveCollection, resolveComponent, resolveOption } from './resolve.js';
|
package/dist/mappers/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export { assertValidated, validateBuilder, validateInstance, validateModel, validateUI, validateVariants } from '../validate/index.js';
|
|
1
|
+
export { assertValidated, validateBuilder, validateInstance, validateModel, validatePricing, validateUI, validateVariants } from '../validate/index.js';
|
|
2
2
|
export { createInstance } from './instance.js';
|
|
3
|
-
export { createVariants } from './variants/index.js';
|
|
3
|
+
export { createVariants, optionGraph, variantsFor } from './variants/index.js';
|
|
4
4
|
export { order } from './order.js';
|
|
5
|
+
export { pricing } from './pricing.js';
|
|
5
6
|
export { ordinal, render } from './render/index.js';
|
|
6
7
|
export { resolveCollection, resolveComponent, resolveOption } from './resolve.js';
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
import { check } from '../check.js';
|
|
3
|
+
import { BuilderPricingSchema } from '../entities/index.js';
|
|
4
|
+
import { BuilderVariantSchema } from '../instance.js';
|
|
5
|
+
import { resolveRef } from './resolve.js';
|
|
6
|
+
export function pricing(model, pricingInput, order, refs = []) {
|
|
7
|
+
const resolved = resolveRef(pricingInput, refs);
|
|
8
|
+
check.assert(BuilderPricingSchema, resolved, 'Pricing did not resolve to a pricing entity! ❌');
|
|
9
|
+
const { rates, formula } = resolved;
|
|
10
|
+
const modelTags = model.tags ?? [];
|
|
11
|
+
const variants = collectVariants(order);
|
|
12
|
+
return evaluate(formula);
|
|
13
|
+
function evaluate(expression, currentVariant = null) {
|
|
14
|
+
switch (expression.kind) {
|
|
15
|
+
case 'num':
|
|
16
|
+
return expression.value;
|
|
17
|
+
case 'variantPrice':
|
|
18
|
+
return variantPrice(currentVariant);
|
|
19
|
+
case 'rate':
|
|
20
|
+
return evaluateRate(expression, currentVariant);
|
|
21
|
+
case 'variants':
|
|
22
|
+
return evaluateVariants(expression);
|
|
23
|
+
case 'add':
|
|
24
|
+
return (evaluate(expression.left, currentVariant) + evaluate(expression.right, currentVariant));
|
|
25
|
+
case 'sub':
|
|
26
|
+
return (evaluate(expression.left, currentVariant) - evaluate(expression.right, currentVariant));
|
|
27
|
+
case 'mul':
|
|
28
|
+
return (evaluate(expression.left, currentVariant) * evaluate(expression.right, currentVariant));
|
|
29
|
+
case 'div':
|
|
30
|
+
return (evaluate(expression.left, currentVariant) / evaluate(expression.right, currentVariant));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function evaluateRate(expression, currentVariant) {
|
|
34
|
+
const table = rates[expression.rate];
|
|
35
|
+
check.truthy(table, `Pricing: rate '${expression.rate}' not found! ❌`);
|
|
36
|
+
const tagOrTags = resolveTagExpression(expression.tag, currentVariant);
|
|
37
|
+
const keys = Array.isArray(tagOrTags) ? tagOrTags : [tagOrTags];
|
|
38
|
+
const matches = keys
|
|
39
|
+
.map((key) => table[key])
|
|
40
|
+
.filter((value) => typeof value === 'number');
|
|
41
|
+
check.truthy(matches.length > 0, `Pricing: rate '${expression.rate}' has no entry for keys [${keys.join(', ')}]! ❌`);
|
|
42
|
+
return reduceValues(matches, expression.reduce ?? 'product');
|
|
43
|
+
}
|
|
44
|
+
function evaluateVariants(expression) {
|
|
45
|
+
const { tag } = expression;
|
|
46
|
+
const candidates = tag ? variants.filter((variant) => matchesFilter(variant, tag)) : variants;
|
|
47
|
+
const results = candidates.map((variant) => evaluate(expression.expression, variant));
|
|
48
|
+
return reduceValues(results, expression.reduce ?? 'sum');
|
|
49
|
+
}
|
|
50
|
+
function resolveTagExpression(tag, currentVariant) {
|
|
51
|
+
switch (tag.kind) {
|
|
52
|
+
case 'tag':
|
|
53
|
+
return tag.value;
|
|
54
|
+
case 'modelTags':
|
|
55
|
+
return modelTags;
|
|
56
|
+
case 'variantTags':
|
|
57
|
+
check.truthy(currentVariant, 'Pricing: variantTags used outside variants iteration! ❌');
|
|
58
|
+
return currentVariant.tags ?? [];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function matchesFilter(variant, filter) {
|
|
62
|
+
if (filter.kind === 'tag') {
|
|
63
|
+
return (variant.tags ?? []).includes(filter.value);
|
|
64
|
+
}
|
|
65
|
+
if (filter.kind === 'modelTags') {
|
|
66
|
+
return (variant.tags ?? []).some((tag) => modelTags.includes(tag));
|
|
67
|
+
}
|
|
68
|
+
check.falsy(true, 'Pricing: variantTags is not a valid variants.tag filter! ❌');
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function reduceValues(values, mode) {
|
|
73
|
+
if (mode === 'product') {
|
|
74
|
+
return values.reduce((accumulator, value) => accumulator * value, 1);
|
|
75
|
+
}
|
|
76
|
+
if (mode === 'sum') {
|
|
77
|
+
return values.reduce((accumulator, value) => accumulator + value, 0);
|
|
78
|
+
}
|
|
79
|
+
check.truthy(values.length > 0, 'Pricing: cannot reduce empty set with "first"! ❌');
|
|
80
|
+
return values[0];
|
|
81
|
+
}
|
|
82
|
+
function variantPrice(variant) {
|
|
83
|
+
check.truthy(variant, 'Pricing: variantPrice used outside variants iteration! ❌');
|
|
84
|
+
const price = variant.details?.price;
|
|
85
|
+
check.assert(v.number(), price, 'Pricing: variant missing numeric price detail! ❌');
|
|
86
|
+
return price;
|
|
87
|
+
}
|
|
88
|
+
function collectVariants(order) {
|
|
89
|
+
return Object.values(order).flatMap((value) => {
|
|
90
|
+
if (value == null) {
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
if (check.is(BuilderVariantSchema, value)) {
|
|
94
|
+
return [value];
|
|
95
|
+
}
|
|
96
|
+
if (Array.isArray(value)) {
|
|
97
|
+
return value.flatMap(collectVariants);
|
|
98
|
+
}
|
|
99
|
+
return collectVariants(value);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { BuilderRenderOption, BuilderRenderOptions, BuilderRenderPage, BuilderRenderPages, BuilderRenderUpdate } from './pages';
|
|
1
|
+
export type { BuilderRenderMetadata, BuilderRenderOption, BuilderRenderOptions, BuilderRenderPage, BuilderRenderPages, BuilderRenderUpdate } from './pages';
|
|
2
2
|
export type { BuilderRenderResult } from './render';
|
|
3
3
|
export { render } from './render.js';
|
|
4
4
|
export { ordinal } from './ordinal.js';
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import type { BuilderOptionValuesSerialised } from '../../entities/index';
|
|
2
2
|
import type { BuilderPrimitive } from '../../primitive';
|
|
3
3
|
import type { BuilderInstance } from '../../instance';
|
|
4
|
+
import * as v from 'valibot';
|
|
4
5
|
export type BuilderRenderUpdate = (model: BuilderInstance, primitive: BuilderPrimitive) => BuilderInstance;
|
|
6
|
+
export declare const BuilderRenderMetadataSchema: v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, v.ReadonlyAction<{
|
|
7
|
+
[x: string]: unknown;
|
|
8
|
+
}>]>;
|
|
9
|
+
export type BuilderRenderMetadata = v.InferOutput<typeof BuilderRenderMetadataSchema>;
|
|
5
10
|
export type BuilderRenderOption = Readonly<{
|
|
6
11
|
name: string;
|
|
7
12
|
value: BuilderPrimitive;
|
|
8
13
|
update: BuilderRenderUpdate;
|
|
9
14
|
option: BuilderOptionValuesSerialised;
|
|
15
|
+
displayName?: string;
|
|
16
|
+
kind?: string;
|
|
17
|
+
metadata?: BuilderRenderMetadata;
|
|
10
18
|
}>;
|
|
11
19
|
export type BuilderRenderOptions = ReadonlyArray<BuilderRenderOption>;
|
|
12
20
|
export type BuilderRenderPage = Readonly<{
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
export const BuilderRenderMetadataSchema = v.pipe(v.record(v.string(), v.unknown()), v.readonly());
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BuilderRenderMetadataSchema } from './pages.js';
|
|
1
2
|
import * as v from 'valibot';
|
|
2
3
|
import { check } from '../../check.js';
|
|
3
4
|
import { BuilderInstancesSchema } from '../../instance.js';
|
|
@@ -37,7 +38,8 @@ export function render(builder, instance, refs = []) {
|
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
40
|
function emitPage(page, model, collectionPath, labelContext, currentInstance) {
|
|
40
|
-
const options = page.
|
|
41
|
+
const options = page.inputs.flatMap((input) => {
|
|
42
|
+
const { path } = input;
|
|
41
43
|
const found = resolvePath(model, currentInstance, path, refs);
|
|
42
44
|
if (found == null) {
|
|
43
45
|
return [];
|
|
@@ -49,7 +51,10 @@ export function render(builder, instance, refs = []) {
|
|
|
49
51
|
name: found.name,
|
|
50
52
|
option: found.payload,
|
|
51
53
|
value: found.value,
|
|
52
|
-
update: (updateInstance, updateValue) => createInstance(builder, setPath(updateInstance, fullPath, updateValue), refs)
|
|
54
|
+
update: (updateInstance, updateValue) => createInstance(builder, setPath(updateInstance, fullPath, updateValue), refs),
|
|
55
|
+
displayName: input.displayName && composeString(input.displayName, 'displayName'),
|
|
56
|
+
kind: input.kind && composeString(input.kind, 'kind'),
|
|
57
|
+
metadata: input.metadata && composeMetadata(input.metadata)
|
|
53
58
|
}
|
|
54
59
|
];
|
|
55
60
|
});
|
|
@@ -60,7 +65,8 @@ export function render(builder, instance, refs = []) {
|
|
|
60
65
|
}
|
|
61
66
|
function emitDescribe(describe, model, labelContext, currentInstance) {
|
|
62
67
|
const composedLabel = composeLabel(describe.label, labelContext);
|
|
63
|
-
const values = describe.
|
|
68
|
+
const values = describe.inputs.flatMap((input) => {
|
|
69
|
+
const { path } = input;
|
|
64
70
|
const found = resolvePath(model, currentInstance, path, refs);
|
|
65
71
|
if (found?.value == null) {
|
|
66
72
|
return [];
|
|
@@ -84,6 +90,16 @@ export function render(builder, instance, refs = []) {
|
|
|
84
90
|
}
|
|
85
91
|
return `${labelContext.join(', ')}, ${resolved}`;
|
|
86
92
|
}
|
|
93
|
+
function composeString(value, fieldLabel) {
|
|
94
|
+
const resolved = resolveRef(value, refs);
|
|
95
|
+
check.assert(v.string(), resolved, `Input ${fieldLabel} did not resolve to a string! ❌`);
|
|
96
|
+
return resolved;
|
|
97
|
+
}
|
|
98
|
+
function composeMetadata(value) {
|
|
99
|
+
const resolved = resolveRef(value, refs);
|
|
100
|
+
check.assert(BuilderRenderMetadataSchema, resolved, 'Input metadata did not resolve to an object! ❌');
|
|
101
|
+
return Object.fromEntries(Object.entries(resolved).map(([key, entry]) => [key, resolveRef(entry, refs)]));
|
|
102
|
+
}
|
|
87
103
|
function findCollection(model, instance, collectionName) {
|
|
88
104
|
const entry = model.collections.find((candidate) => candidate.name === collectionName);
|
|
89
105
|
return entry == null ? null : resolveCollection(entry, model, instance, refs);
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import type { BuilderCollectionConfigValidated, BuilderCollectionValidated,
|
|
1
|
+
import type { BuilderCollectionConfigValidated, BuilderCollectionValidated, BuilderComponentDetailsValidated, BuilderComponentValidated, BuilderModelValidated, BuilderOptionValidated, BuilderOptionValuesValidated, BuilderRefEntities } from '../entities/index';
|
|
2
2
|
import type { BuilderInstance } from '../instance';
|
|
3
3
|
import type { BuilderPath } from '../paths';
|
|
4
|
-
export declare function resolveOption(option: BuilderOptionValidated, model: BuilderModelValidated, instance: unknown, refs?: BuilderRefEntities):
|
|
5
|
-
export declare function resolveComponent(component: BuilderComponentValidated, model: BuilderModelValidated, instance: unknown, refs?: BuilderRefEntities):
|
|
4
|
+
export declare function resolveOption(option: BuilderOptionValidated, model: BuilderModelValidated, instance: unknown, refs?: BuilderRefEntities): BuilderOptionValuesValidated | null;
|
|
5
|
+
export declare function resolveComponent(component: BuilderComponentValidated, model: BuilderModelValidated, instance: unknown, refs?: BuilderRefEntities): BuilderComponentDetailsValidated | null;
|
|
6
6
|
export declare function resolveCollection(collection: BuilderCollectionValidated, model: BuilderModelValidated, instance: unknown, refs?: BuilderRefEntities): BuilderCollectionConfigValidated | null;
|
|
7
7
|
export declare function resolveRef(value: unknown, refs: BuilderRefEntities): unknown;
|
|
8
8
|
export type ResolvedPath = {
|
|
9
9
|
readonly name: string;
|
|
10
|
-
readonly payload:
|
|
10
|
+
readonly payload: BuilderOptionValuesValidated;
|
|
11
11
|
readonly value: unknown;
|
|
12
12
|
};
|
|
13
13
|
export declare function resolvePath(model: BuilderModelValidated, instance: unknown, path: BuilderPath, refs?: BuilderRefEntities): ResolvedPath | null;
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { BuilderOptionGraph } from './option-graph.js';
|
|
2
|
+
export { createVariants, optionGraph, variantsFor } from './variants.js';
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { BuilderOptionGraph } from './option-graph.js';
|
|
2
|
+
export { createVariants, optionGraph, variantsFor } from './variants.js';
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import type { BuilderModelValidated, BuilderValidated } from '../../entities/index';
|
|
2
|
-
import type { BuilderComponentVariants } from '../../instance';
|
|
1
|
+
import type { BuilderCollectionValidated, BuilderComponentValidated, BuilderModelValidated, BuilderValidated } from '../../entities/index';
|
|
2
|
+
import type { BuilderComponentVariants, BuilderInstances } from '../../instance';
|
|
3
|
+
import { BuilderOptionGraph } from './option-graph.js';
|
|
3
4
|
export declare function createVariants(entity: BuilderValidated | BuilderModelValidated): BuilderComponentVariants;
|
|
5
|
+
export declare function optionGraph(model: BuilderModelValidated): BuilderOptionGraph;
|
|
6
|
+
export declare function variantsFor(entity: BuilderComponentValidated | BuilderCollectionValidated, options: BuilderOptionGraph): BuilderInstances;
|