@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.
Files changed (96) hide show
  1. package/dist/bb.d.ts +3 -1
  2. package/dist/bb.js +6 -1
  3. package/dist/check.d.ts +2 -2
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.js +53 -0
  6. package/dist/codegen/index.d.ts +7 -0
  7. package/dist/codegen/index.js +212 -0
  8. package/dist/codegen/template.d.ts +5 -0
  9. package/dist/codegen/template.js +17 -0
  10. package/dist/entities/builder/builder.d.ts +11 -1
  11. package/dist/entities/builder/builder.js +22 -6
  12. package/dist/entities/collection/collection.d.ts +7 -1
  13. package/dist/entities/collection/collection.js +9 -2
  14. package/dist/entities/collection/config.d.ts +6 -1
  15. package/dist/entities/collection/config.js +9 -2
  16. package/dist/entities/component/component.d.ts +41 -1
  17. package/dist/entities/component/component.js +9 -2
  18. package/dist/entities/component/details.d.ts +11 -2
  19. package/dist/entities/component/details.js +9 -2
  20. package/dist/entities/component/field.d.ts +10 -1
  21. package/dist/entities/component/field.js +13 -3
  22. package/dist/entities/index.d.ts +7 -3
  23. package/dist/entities/index.js +3 -1
  24. package/dist/entities/kind.d.ts +1 -1
  25. package/dist/entities/model/model.d.ts +5 -1
  26. package/dist/entities/model/model.js +10 -3
  27. package/dist/entities/model/models.js +9 -5
  28. package/dist/entities/option/option.d.ts +41 -1
  29. package/dist/entities/option/option.js +9 -2
  30. package/dist/entities/option/select.d.ts +7 -1
  31. package/dist/entities/option/select.js +17 -6
  32. package/dist/entities/option/toggle.d.ts +7 -1
  33. package/dist/entities/option/toggle.js +16 -4
  34. package/dist/entities/option/values.d.ts +6 -0
  35. package/dist/entities/pricing.d.ts +64 -0
  36. package/dist/entities/pricing.js +48 -0
  37. package/dist/entities/serialise.d.ts +632 -8
  38. package/dist/entities/serialise.js +33 -12
  39. package/dist/entities/tags.d.ts +3 -0
  40. package/dist/entities/tags.js +2 -0
  41. package/dist/entities/ui/describe.d.ts +231 -8
  42. package/dist/entities/ui/describe.js +12 -5
  43. package/dist/entities/ui/index.d.ts +2 -0
  44. package/dist/entities/ui/index.js +1 -0
  45. package/dist/entities/ui/input.d.ts +343 -0
  46. package/dist/entities/ui/input.js +51 -0
  47. package/dist/entities/ui/page.d.ts +231 -8
  48. package/dist/entities/ui/page.js +12 -5
  49. package/dist/entities/ui/pages.d.ts +5 -1
  50. package/dist/entities/ui/pages.js +9 -2
  51. package/dist/entities/ui/ui.d.ts +9 -4
  52. package/dist/entities/ui/ui.js +29 -11
  53. package/dist/entities/validated.d.ts +7 -3
  54. package/dist/exception.d.ts +2 -2
  55. package/dist/index.d.ts +3 -3
  56. package/dist/index.js +1 -1
  57. package/dist/instance.d.ts +9 -0
  58. package/dist/instance.js +3 -1
  59. package/dist/mappers/index.d.ts +6 -4
  60. package/dist/mappers/index.js +3 -2
  61. package/dist/mappers/pricing.d.ts +3 -0
  62. package/dist/mappers/pricing.js +101 -0
  63. package/dist/mappers/render/index.d.ts +1 -1
  64. package/dist/mappers/render/pages.d.ts +8 -0
  65. package/dist/mappers/render/pages.js +2 -1
  66. package/dist/mappers/render/render.js +19 -3
  67. package/dist/mappers/resolve.d.ts +4 -4
  68. package/dist/mappers/variants/index.d.ts +2 -1
  69. package/dist/mappers/variants/index.js +2 -1
  70. package/dist/mappers/variants/variants.d.ts +5 -2
  71. package/dist/mappers/variants/variants.js +2 -2
  72. package/dist/validate/brand.d.ts +0 -7
  73. package/dist/validate/brand.js +5 -5
  74. package/dist/validate/builder.d.ts +2 -1
  75. package/dist/validate/builder.js +19 -13
  76. package/dist/validate/errors.d.ts +138 -0
  77. package/dist/validate/errors.js +148 -0
  78. package/dist/validate/expectations.d.ts +3 -10
  79. package/dist/validate/expectations.js +8 -10
  80. package/dist/validate/index.d.ts +10 -14
  81. package/dist/validate/index.js +5 -7
  82. package/dist/validate/instance.d.ts +2 -15
  83. package/dist/validate/instance.js +41 -40
  84. package/dist/validate/model.d.ts +4 -31
  85. package/dist/validate/model.js +157 -176
  86. package/dist/validate/pricing.d.ts +6 -0
  87. package/dist/validate/pricing.js +71 -0
  88. package/dist/validate/resolve.d.ts +3 -15
  89. package/dist/validate/resolve.js +66 -69
  90. package/dist/validate/result.d.ts +1 -7
  91. package/dist/validate/result.js +1 -4
  92. package/dist/validate/ui.d.ts +4 -4
  93. package/dist/validate/ui.js +80 -62
  94. package/dist/validate/variants.d.ts +2 -53
  95. package/dist/validate/variants.js +83 -86
  96. package/package.json +12 -3
@@ -1,4 +1 @@
1
- import { builderError } from '../exception.js';
2
- export function builderErrorInvalidInput(target, location = []) {
3
- return { ...builderError('invalid-input', location), target };
4
- }
1
+ export {};
@@ -1,8 +1,8 @@
1
1
  import type { BuilderModelSerialised, BuilderRefEntities, BuilderUISerialised, BuilderUIValidated } from '../entities/index';
2
- import type { BuilderErrorLocation, BuilderErrors } from '../exception';
3
2
  import type { BuilderResolve } from './resolve';
4
3
  import type { ValidationResult } from './result';
4
+ import { BuilderValidateErrors } from './errors.js';
5
5
  export type BuilderUIValidationResult = ValidationResult<BuilderUIValidated>;
6
- export declare function validateUI(input: unknown, references?: BuilderRefEntities): BuilderUIValidationResult;
7
- export declare function validateUIStructure(ui: BuilderUISerialised, resolve: BuilderResolve, location: BuilderErrorLocation): readonly [BuilderUIValidated, BuilderErrors];
8
- export declare function checkUIExpectations(mergedModel: BuilderModelSerialised, ui: BuilderUIValidated, location: BuilderErrorLocation): BuilderErrors;
6
+ export declare function validateUI(input: unknown, references?: BuilderRefEntities, errors?: BuilderValidateErrors): BuilderUIValidationResult;
7
+ export declare function validateUIStructure(ui: BuilderUISerialised, resolve: BuilderResolve, errors: BuilderValidateErrors): BuilderUIValidated;
8
+ export declare function checkUIExpectations(mergedModel: BuilderModelSerialised, ui: BuilderUIValidated, errors: BuilderValidateErrors): void;
@@ -1,77 +1,95 @@
1
1
  import { check } from '../check.js';
2
- import { BuilderUISerialisedSchema, serialise, uis } from '../entities/index.js';
2
+ import { BuilderUIInputMetadataSchema, BuilderUISerialisedSchema, serialise, uis } from '../entities/index.js';
3
3
  import { validate } from './brand.js';
4
+ import { BuilderValidateErrors } from './errors.js';
4
5
  import { checkExpectations } from './expectations.js';
5
6
  import { resolver } from './resolve.js';
6
- import { builderErrorInvalidInput } from './result.js';
7
- export function validateUI(input, references = []) {
7
+ export function validateUI(input, references = [], errors = new BuilderValidateErrors()) {
8
8
  if (!check.is(BuilderUISerialisedSchema, input)) {
9
- const errors = [builderErrorInvalidInput('ui')];
10
- return [validate(serialise.ui(uis())), errors];
9
+ errors.invalidInput('ui');
10
+ return [validate(serialise.ui(uis())), errors.errors];
11
11
  }
12
- const resolve = resolver(references);
13
- const [structure, errors] = validateUIStructure(input, resolve, []);
14
- return [validate(structure), errors];
12
+ const resolve = resolver(errors, references);
13
+ const structure = validateUIStructure(input, resolve, errors);
14
+ return [validate(structure), errors.errors];
15
15
  }
16
- export function validateUIStructure(ui, resolve, location) {
17
- const errors = [];
18
- const childUIs = ui.uis.flatMap((part, partIndex) => {
19
- const partLocation = [...location, 'uis', partIndex];
20
- const [resolved, partErrors] = resolve(part, partLocation);
21
- errors.push(...partErrors);
22
- if (resolved == null || !check.is(BuilderUISerialisedSchema, resolved)) {
23
- return [];
24
- }
25
- const [child, childErrors] = validateUIStructure(resolved, resolve, partLocation);
26
- errors.push(...childErrors);
27
- return [child];
28
- });
29
- const [items, itemErrors] = walkItems(ui.items, resolve, [...location, 'items']);
30
- errors.push(...itemErrors);
16
+ export function validateUIStructure(ui, resolve, errors) {
17
+ const childUIs = walkChildUIs();
18
+ const items = errors.scope('items', () => walkItems(ui.items));
31
19
  const data = {
32
20
  ...ui,
33
21
  uis: childUIs,
34
22
  items
35
23
  };
36
- return [data, errors];
37
- }
38
- export function checkUIExpectations(mergedModel, ui, location) {
39
- return [
40
- ...checkExpectations(mergedModel, ui.expectations, [...location, 'expectations']),
41
- ...ui.uis.flatMap((nested, nestedIndex) => checkUIExpectations(mergedModel, nested, [
42
- ...location,
43
- 'uis',
44
- nestedIndex
45
- ]))
46
- ];
24
+ return data;
25
+ function walkChildUIs() {
26
+ return errors.scope('uis', () => ui.uis.flatMap((part, partIndex) => errors.scope(partIndex, () => {
27
+ const resolved = resolve(part);
28
+ if (resolved == null || !check.is(BuilderUISerialisedSchema, resolved)) {
29
+ return [];
30
+ }
31
+ return [validateUIStructure(resolved, resolve, errors)];
32
+ })));
33
+ }
34
+ function walkItems(parts) {
35
+ return parts.map((item, itemIndex) => errors.scope(itemIndex, () => {
36
+ const resolved = resolve(item);
37
+ return walkUIItem((resolved ?? item));
38
+ }));
39
+ }
40
+ function walkUIItem(item) {
41
+ const label = errors.scope('label', () => resolve(item.label) ?? item.label);
42
+ if (item.type === 'pages') {
43
+ const innerItems = errors.scope('items', () => {
44
+ const resolved = resolve(item.items);
45
+ const resolvedItems = (Array.isArray(resolved) ? resolved : item.items);
46
+ return walkItems(resolvedItems);
47
+ });
48
+ return { ...item, label, items: innerItems };
49
+ }
50
+ const inputs = errors.scope('inputs', () => {
51
+ const resolved = resolve(item.inputs);
52
+ if (!Array.isArray(resolved)) {
53
+ return resolved ?? item.inputs;
54
+ }
55
+ return walkInputs(resolved);
56
+ });
57
+ return { ...item, label, inputs };
58
+ }
59
+ function walkInputs(inputs) {
60
+ return inputs.map((entry, entryIndex) => errors.scope(entryIndex, () => {
61
+ const resolvedEntry = resolve(entry);
62
+ return walkInput((resolvedEntry ?? entry));
63
+ }));
64
+ }
65
+ function walkInput(value) {
66
+ const path = errors.scope('path', () => resolve(value.path) ?? value.path);
67
+ const displayName = value.displayName &&
68
+ errors.scope('displayName', () => resolve(value.displayName) ?? value.displayName);
69
+ const kind = value.kind && errors.scope('kind', () => resolve(value.kind) ?? value.kind);
70
+ const metadata = value.metadata && errors.scope('metadata', () => walkMetadata(value.metadata));
71
+ return { ...value, path, displayName, kind, metadata };
72
+ }
73
+ function walkMetadata(rawMetadata) {
74
+ const resolved = resolve(rawMetadata);
75
+ if (!check.is(BuilderUIInputMetadataSchema, resolved)) {
76
+ return rawMetadata;
77
+ }
78
+ return Object.entries(resolved).reduce((entries, [key, entryValue]) => {
79
+ const resolvedValue = errors.scope(key, () => resolve(entryValue));
80
+ return { ...entries, [key]: resolvedValue ?? entryValue };
81
+ }, {});
82
+ }
47
83
  }
48
- function walkItems(items, resolve, location) {
49
- const errors = [];
50
- const result = items.map((item, itemIndex) => {
51
- const itemLocation = [...location, itemIndex];
52
- const [resolved, resolveErrors] = resolve(item, itemLocation);
53
- errors.push(...resolveErrors);
54
- const [walked, walkErrors] = walkUIItem((resolved ?? item), resolve, itemLocation);
55
- errors.push(...walkErrors);
56
- return walked;
84
+ export function checkUIExpectations(mergedModel, ui, errors) {
85
+ errors.scope('expectations', () => {
86
+ checkExpectations(mergedModel, ui.expectations, errors);
87
+ });
88
+ errors.scope('uis', () => {
89
+ ui.uis.forEach((nested, nestedIndex) => {
90
+ errors.scope(nestedIndex, () => {
91
+ checkUIExpectations(mergedModel, nested, errors);
92
+ });
93
+ });
57
94
  });
58
- return [result, errors];
59
- }
60
- function walkUIItem(item, resolve, location) {
61
- const errors = [];
62
- const [labelValue, labelErrors] = resolve(item.label, [...location, 'label']);
63
- errors.push(...labelErrors);
64
- const label = labelValue ?? item.label;
65
- if (item.type === 'pages') {
66
- const [itemsResolved, itemsErrors] = resolve(item.items, [...location, 'items']);
67
- errors.push(...itemsErrors);
68
- const resolvedItems = (Array.isArray(itemsResolved) ? itemsResolved : item.items);
69
- const [innerItems, innerErrors] = walkItems(resolvedItems, resolve, [...location, 'items']);
70
- errors.push(...innerErrors);
71
- return [{ ...item, label, items: innerItems }, errors];
72
- }
73
- const [pathsValue, pathsErrors] = resolve(item.paths, [...location, 'paths']);
74
- errors.push(...pathsErrors);
75
- const paths = pathsValue ?? item.paths;
76
- return [{ ...item, label, paths }, errors];
77
95
  }
@@ -1,59 +1,8 @@
1
1
  import type { BuilderComponentVariantsValidated, BuilderModelValidated } from '../entities/index';
2
- import type { BuilderErrorLocation } from '../exception';
3
- import type { BuilderInstance } from '../instance';
4
2
  import type { ValidationResult } from './result';
5
- export declare function builderErrorMissingComponent(component: string, location?: BuilderErrorLocation): {
6
- component: string;
7
- kind: "missing-component";
8
- location: BuilderErrorLocation;
9
- };
10
- export type BuilderErrorMissingComponent = ReturnType<typeof builderErrorMissingComponent>;
11
- export declare function builderErrorUnexpectedComponent(component: string, location?: BuilderErrorLocation): {
12
- component: string;
13
- kind: "unexpected-component";
14
- location: BuilderErrorLocation;
15
- };
16
- export type BuilderErrorUnexpectedComponent = ReturnType<typeof builderErrorUnexpectedComponent>;
17
- export declare function builderErrorMissingVariant(component: string, instance: BuilderInstance, location?: BuilderErrorLocation): {
18
- component: string;
19
- instance: BuilderInstance;
20
- kind: "missing-variant";
21
- location: BuilderErrorLocation;
22
- };
23
- export type BuilderErrorMissingVariant = ReturnType<typeof builderErrorMissingVariant>;
24
- export declare function builderErrorInvalidVariant(component: string, instance: BuilderInstance, location?: BuilderErrorLocation): {
25
- component: string;
26
- instance: BuilderInstance;
27
- kind: "invalid-variant";
28
- location: BuilderErrorLocation;
29
- };
30
- export type BuilderErrorInvalidVariant = ReturnType<typeof builderErrorInvalidVariant>;
31
- export declare function builderErrorMissingDetail(component: string, detail: string, instance: BuilderInstance, location?: BuilderErrorLocation): {
32
- component: string;
33
- detail: string;
34
- instance: BuilderInstance;
35
- kind: "missing-detail";
36
- location: BuilderErrorLocation;
37
- };
38
- export type BuilderErrorMissingDetail = ReturnType<typeof builderErrorMissingDetail>;
39
- export declare function builderErrorUnexpectedDetail(component: string, detail: string, instance: BuilderInstance, location?: BuilderErrorLocation): {
40
- component: string;
41
- detail: string;
42
- instance: BuilderInstance;
43
- kind: "unexpected-detail";
44
- location: BuilderErrorLocation;
45
- };
46
- export type BuilderErrorUnexpectedDetail = ReturnType<typeof builderErrorUnexpectedDetail>;
47
- export declare function builderErrorInvalidDetail(component: string, detail: string, instance: BuilderInstance, location?: BuilderErrorLocation): {
48
- component: string;
49
- detail: string;
50
- instance: BuilderInstance;
51
- kind: "invalid-detail";
52
- location: BuilderErrorLocation;
53
- };
54
- export type BuilderErrorInvalidDetail = ReturnType<typeof builderErrorInvalidDetail>;
3
+ import { BuilderValidateErrors } from './errors.js';
55
4
  export type BuilderVariantsValidationOptions = {
56
5
  readonly partial?: boolean;
57
6
  };
58
7
  export type BuilderComponentVariantsValidationResult = ValidationResult<BuilderComponentVariantsValidated>;
59
- export declare function validateVariants(model: BuilderModelValidated, input: unknown, options?: BuilderVariantsValidationOptions): BuilderComponentVariantsValidationResult;
8
+ export declare function validateVariants(model: BuilderModelValidated, input: unknown, options?: BuilderVariantsValidationOptions, errors?: BuilderValidateErrors): BuilderComponentVariantsValidationResult;
@@ -1,100 +1,97 @@
1
1
  import { check } from '../check.js';
2
2
  import { detailValueSchema } from '../entities/index.js';
3
- import { builderError } from '../exception.js';
4
- import { createVariants, resolveComponent } from '../mappers/index.js';
5
3
  import { BuilderComponentVariantsSchema } from '../instance.js';
4
+ import { createVariants, resolveComponent } from '../mappers/index.js';
6
5
  import { validate } from './brand.js';
7
- import { builderErrorInvalidInput } from './result.js';
8
- export function builderErrorMissingComponent(component, location = []) {
9
- return { ...builderError('missing-component', location), component };
10
- }
11
- export function builderErrorUnexpectedComponent(component, location = []) {
12
- return { ...builderError('unexpected-component', location), component };
13
- }
14
- export function builderErrorMissingVariant(component, instance, location = []) {
15
- return { ...builderError('missing-variant', location), component, instance };
16
- }
17
- export function builderErrorInvalidVariant(component, instance, location = []) {
18
- return { ...builderError('invalid-variant', location), component, instance };
19
- }
20
- export function builderErrorMissingDetail(component, detail, instance, location = []) {
21
- return { ...builderError('missing-detail', location), component, detail, instance };
22
- }
23
- export function builderErrorUnexpectedDetail(component, detail, instance, location = []) {
24
- return { ...builderError('unexpected-detail', location), component, detail, instance };
25
- }
26
- export function builderErrorInvalidDetail(component, detail, instance, location = []) {
27
- return { ...builderError('invalid-detail', location), component, detail, instance };
28
- }
29
- export function validateVariants(model, input, options = {}) {
6
+ import { BuilderValidateErrors } from './errors.js';
7
+ export function validateVariants(model, input, options = {}, errors = new BuilderValidateErrors()) {
30
8
  if (!check.is(BuilderComponentVariantsSchema, input)) {
31
- const errors = [builderErrorInvalidInput('variants')];
32
- return [validate({}), errors];
9
+ errors.invalidInput('variants');
10
+ return [validate({}), errors.errors];
33
11
  }
12
+ const variants = input;
34
13
  const expected = createVariants(model);
35
- const errors = [
36
- ...checkVariants(expected, input, options.partial ?? false),
37
- ...checkUnexpectedComponents(expected, input),
38
- ...checkInvalidDetails(input, model)
39
- ];
40
- return [validate(input), errors];
41
- }
42
- function checkVariants(expected, variants, partial) {
43
- return Object.entries(expected).flatMap(([component, expectedVariants]) => {
44
- const componentVariants = variants[component];
45
- if (componentVariants == null) {
46
- return partial ? [] : [builderErrorMissingComponent(component, ['variants'])];
14
+ errors.scope('variants', () => {
15
+ checkVariants();
16
+ checkComponents();
17
+ checkDetails();
18
+ function checkVariants() {
19
+ Object.entries(expected).forEach(([component, expectedVariants]) => {
20
+ const componentVariants = variants[component];
21
+ if (componentVariants == null) {
22
+ if (options.partial !== false) {
23
+ errors.missingComponent(component);
24
+ }
25
+ return;
26
+ }
27
+ errors.scope(component, () => {
28
+ const expectedKeys = new Map(expectedVariants.map(({ instance }) => [sortedKey(instance), instance]));
29
+ const actualKeys = new Set(componentVariants.map(({ instance }) => sortedKey(instance)));
30
+ componentVariants.forEach((variant, index) => {
31
+ errors.scope(index, () => {
32
+ const { instance } = variant;
33
+ if (!expectedKeys.has(sortedKey(instance))) {
34
+ errors.invalidVariant(component, instance);
35
+ }
36
+ });
37
+ });
38
+ Array.from(expectedKeys).forEach(([key, instance]) => {
39
+ if (!actualKeys.has(key)) {
40
+ errors.missingVariant(component, instance);
41
+ }
42
+ });
43
+ });
44
+ });
47
45
  }
48
- const expectedKeys = new Map(expectedVariants.map(({ instance }) => [sortedKey(instance), instance]));
49
- const actualKeys = new Set(componentVariants.map(({ instance }) => sortedKey(instance)));
50
- return [
51
- ...componentVariants
52
- .filter(({ instance }) => !expectedKeys.has(sortedKey(instance)))
53
- .map((variant) => builderErrorInvalidVariant(component, variant.instance, [
54
- 'variants',
55
- component,
56
- componentVariants.indexOf(variant)
57
- ])),
58
- ...[...expectedKeys]
59
- .filter(([key]) => !actualKeys.has(key))
60
- .map(([, instance]) => builderErrorMissingVariant(component, instance, ['variants', component]))
61
- ];
62
- });
63
- }
64
- function checkUnexpectedComponents(expected, variants) {
65
- return Object.keys(variants)
66
- .filter((component) => expected[component] == null)
67
- .map((component) => builderErrorUnexpectedComponent(component, ['variants', component]));
68
- }
69
- function checkInvalidDetails(variants, model) {
70
- const componentByName = new Map(model.components.map((entry) => [entry.name, entry]));
71
- return Object.entries(variants).flatMap(([component, componentVariants]) => {
72
- const entry = componentByName.get(component);
73
- if (entry == null) {
74
- return [];
46
+ function checkComponents() {
47
+ Object.keys(variants).forEach((component) => {
48
+ errors.scope(component, () => {
49
+ if (expected[component] == null) {
50
+ errors.unexpectedComponent(component);
51
+ }
52
+ });
53
+ });
75
54
  }
76
- return componentVariants.flatMap(({ instance, details }, index) => {
77
- const resolved = resolveComponent(entry, model, instance);
78
- const fields = (resolved?.fields ?? []);
79
- const expectedNames = new Set(fields.map(({ name }) => name));
80
- const actualDetails = details ?? {};
81
- const detailsLocation = ['variants', component, index, 'details'];
82
- const missingOrInvalid = fields.flatMap(({ name, valueType, isOptional }) => {
83
- const detailLocation = [...detailsLocation, name];
84
- if (!(name in actualDetails)) {
85
- return [builderErrorMissingDetail(component, name, instance, detailLocation)];
86
- }
87
- if (!check.is(detailValueSchema(valueType, isOptional), actualDetails[name])) {
88
- return [builderErrorInvalidDetail(component, name, instance, detailLocation)];
89
- }
90
- return [];
55
+ function checkDetails() {
56
+ const componentByName = new Map(model.components.map((entry) => [entry.name, entry]));
57
+ Object.entries(variants).forEach(([component, componentVariants]) => {
58
+ errors.scope(component, () => {
59
+ const entry = componentByName.get(component);
60
+ if (entry == null) {
61
+ return;
62
+ }
63
+ componentVariants.forEach(({ instance, details = {} }, index) => {
64
+ errors.scope(index, () => {
65
+ const resolved = resolveComponent(entry, model, instance);
66
+ const fields = resolved?.fields ?? [];
67
+ const expectedNames = new Set(fields.map(({ name }) => name));
68
+ errors.scope('details', () => {
69
+ fields.forEach(({ name, valueType, isOptional }) => {
70
+ errors.scope(name, () => {
71
+ if (!(name in details)) {
72
+ errors.missingDetail(component, name, instance);
73
+ return;
74
+ }
75
+ if (!check.is(detailValueSchema(valueType, isOptional), details[name])) {
76
+ errors.invalidDetail(component, name, instance);
77
+ }
78
+ });
79
+ });
80
+ Object.keys(details).forEach((detail) => {
81
+ if (!expectedNames.has(detail)) {
82
+ errors.scope(detail, () => {
83
+ errors.unexpectedDetail(component, detail, instance);
84
+ });
85
+ }
86
+ });
87
+ });
88
+ });
89
+ });
90
+ });
91
91
  });
92
- const unexpected = Object.keys(actualDetails)
93
- .filter((detail) => !expectedNames.has(detail))
94
- .map((detail) => builderErrorUnexpectedDetail(component, detail, instance, [...detailsLocation, detail]));
95
- return [...missingOrInvalid, ...unexpected];
96
- });
92
+ }
97
93
  });
94
+ return [validate(variants), errors.errors];
98
95
  }
99
96
  function sortedKey(instance) {
100
97
  const entries = Object.entries(instance).filter(([, value]) => value != null);
package/package.json CHANGED
@@ -1,16 +1,23 @@
1
1
  {
2
2
  "name": "@builder-builder/builder",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
8
8
  "default": "./dist/index.js"
9
+ },
10
+ "./codegen": {
11
+ "types": "./dist/codegen/index.d.ts",
12
+ "default": "./dist/codegen/index.js"
9
13
  }
10
14
  },
11
15
  "files": [
12
16
  "dist"
13
17
  ],
18
+ "bin": {
19
+ "bb": "./dist/cli.js"
20
+ },
14
21
  "svelte": "./dist/index.js",
15
22
  "types": "./dist/index.d.ts",
16
23
  "publishConfig": {
@@ -33,7 +40,7 @@
33
40
  "test": "npm run test:unit -- --run",
34
41
  "test:unit": "npm run messages && vitest --project client --project server",
35
42
  "test:integration": "npm run messages && vitest run --project integration",
36
- "verify": "npm run test && npm run check && npm run format && npm run lint",
43
+ "verify": "npm run test && npm run check && npm run lint",
37
44
  "types:db": "dotenv -e .env.development.local -- supabase gen types typescript --project-id \"$SUPABASE_PROJECT_ID\" --schema public > ./src/lib/db/database.types.ts"
38
45
  },
39
46
  "devDependencies": {
@@ -62,7 +69,6 @@
62
69
  "supabase": "^2.93.0",
63
70
  "svelte": "^5.0.0",
64
71
  "svelte-check": "^4.0.0",
65
- "typescript": "^5.0.0",
66
72
  "typescript-eslint": "^8.58.2",
67
73
  "vite": "^6.2.6",
68
74
  "vitest": "^4.1.5"
@@ -70,6 +76,8 @@
70
76
  "dependencies": {
71
77
  "@floating-ui/dom": "^1.7.2",
72
78
  "@lucide/svelte": "^0.525.0",
79
+ "@phenomnomnominal/tsquery": "^6.2.0",
80
+ "@phenomnomnominal/tstemplate": "^0.1.0",
73
81
  "@supabase/supabase-js": "^2.104.0",
74
82
  "@upstash/ratelimit": "^2.0.5",
75
83
  "@upstash/redis": "^1.35.0",
@@ -77,6 +85,7 @@
77
85
  "comlink": "^4.4.2",
78
86
  "fast-deep-equal": "^3.1.3",
79
87
  "svelte-clerk": "^1.1.1",
88
+ "typescript": "^5.0.0",
80
89
  "valibot": "^1.1.0"
81
90
  }
82
91
  }