@storyblok/schema 0.1.0-alpha.0 → 0.1.0-alpha.2

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 (170) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +29 -0
  2. package/dist/field-plugins/index.cjs +4 -0
  3. package/dist/field-plugins/index.d.cts +2 -0
  4. package/dist/field-plugins/index.d.mts +2 -0
  5. package/dist/field-plugins/index.mjs +3 -0
  6. package/dist/field-plugins/storyblok-color-field.cjs +32 -0
  7. package/dist/field-plugins/storyblok-color-field.cjs.map +1 -0
  8. package/dist/field-plugins/storyblok-color-field.d.cts +16 -0
  9. package/dist/field-plugins/storyblok-color-field.d.mts +16 -0
  10. package/dist/field-plugins/storyblok-color-field.mjs +32 -0
  11. package/dist/field-plugins/storyblok-color-field.mjs.map +1 -0
  12. package/dist/generated/capi/types.gen.d.cts +1 -126
  13. package/dist/generated/capi/types.gen.d.mts +1 -126
  14. package/dist/generated/mapi/_internal.gen.d.cts +1 -171
  15. package/dist/generated/mapi/_internal.gen.d.mts +1 -171
  16. package/dist/generated/overlay/zod.gen.cjs +407 -0
  17. package/dist/generated/overlay/zod.gen.cjs.map +1 -0
  18. package/dist/generated/overlay/zod.gen.mjs +402 -0
  19. package/dist/generated/overlay/zod.gen.mjs.map +1 -0
  20. package/dist/generated/types/block.d.cts +27 -14
  21. package/dist/generated/types/block.d.mts +27 -14
  22. package/dist/generated/types/field.d.cts +48 -17
  23. package/dist/generated/types/field.d.mts +48 -17
  24. package/dist/generated/types/mapi-story.d.cts +6 -10
  25. package/dist/generated/types/mapi-story.d.mts +6 -10
  26. package/dist/generated/types/story.d.cts +3 -3
  27. package/dist/generated/types/story.d.mts +3 -3
  28. package/dist/helpers/define-block.cjs +10 -28
  29. package/dist/helpers/define-block.cjs.map +1 -1
  30. package/dist/helpers/define-block.d.cts +14 -31
  31. package/dist/helpers/define-block.d.mts +14 -31
  32. package/dist/helpers/define-block.mjs +11 -27
  33. package/dist/helpers/define-block.mjs.map +1 -1
  34. package/dist/helpers/define-datasource.cjs +0 -16
  35. package/dist/helpers/define-datasource.cjs.map +1 -1
  36. package/dist/helpers/define-datasource.d.cts +14 -23
  37. package/dist/helpers/define-datasource.d.mts +14 -23
  38. package/dist/helpers/define-datasource.mjs +1 -15
  39. package/dist/helpers/define-datasource.mjs.map +1 -1
  40. package/dist/helpers/define-field-plugin.cjs +21 -0
  41. package/dist/helpers/define-field-plugin.cjs.map +1 -0
  42. package/dist/helpers/define-field-plugin.d.cts +33 -0
  43. package/dist/helpers/define-field-plugin.d.mts +33 -0
  44. package/dist/helpers/define-field-plugin.mjs +20 -0
  45. package/dist/helpers/define-field-plugin.mjs.map +1 -0
  46. package/dist/helpers/define-field.cjs +11 -11
  47. package/dist/helpers/define-field.cjs.map +1 -1
  48. package/dist/helpers/define-field.d.cts +46 -85
  49. package/dist/helpers/define-field.d.mts +46 -85
  50. package/dist/helpers/define-field.mjs +12 -11
  51. package/dist/helpers/define-field.mjs.map +1 -1
  52. package/dist/helpers/define-schema.cjs +22 -0
  53. package/dist/helpers/define-schema.cjs.map +1 -0
  54. package/dist/helpers/define-schema.d.cts +28 -0
  55. package/dist/helpers/define-schema.d.mts +28 -0
  56. package/dist/helpers/define-schema.mjs +21 -0
  57. package/dist/helpers/define-schema.mjs.map +1 -0
  58. package/dist/helpers/schema-type.d.cts +21 -17
  59. package/dist/helpers/schema-type.d.mts +21 -17
  60. package/dist/index.cjs +10 -47
  61. package/dist/index.d.cts +13 -20
  62. package/dist/index.d.mts +13 -20
  63. package/dist/index.mjs +8 -15
  64. package/dist/utils/is-record.cjs +10 -0
  65. package/dist/utils/is-record.cjs.map +1 -0
  66. package/dist/utils/is-record.mjs +9 -0
  67. package/dist/utils/is-record.mjs.map +1 -0
  68. package/dist/validators/create-story-validator.cjs +37 -0
  69. package/dist/validators/create-story-validator.cjs.map +1 -0
  70. package/dist/validators/create-story-validator.d.cts +18 -0
  71. package/dist/validators/create-story-validator.d.mts +18 -0
  72. package/dist/validators/create-story-validator.mjs +37 -0
  73. package/dist/validators/create-story-validator.mjs.map +1 -0
  74. package/dist/validators/internal-schemas.cjs +1 -0
  75. package/dist/validators/internal-schemas.mjs +3 -0
  76. package/dist/validators/shapes.cjs +12 -0
  77. package/dist/validators/shapes.cjs.map +1 -0
  78. package/dist/validators/shapes.d.cts +71 -0
  79. package/dist/validators/shapes.d.mts +71 -0
  80. package/dist/validators/shapes.mjs +12 -0
  81. package/dist/validators/shapes.mjs.map +1 -0
  82. package/dist/validators/types.d.cts +25 -0
  83. package/dist/validators/types.d.mts +25 -0
  84. package/dist/validators/validate-schema.cjs +145 -0
  85. package/dist/validators/validate-schema.cjs.map +1 -0
  86. package/dist/validators/validate-schema.d.cts +19 -0
  87. package/dist/validators/validate-schema.d.mts +19 -0
  88. package/dist/validators/validate-schema.mjs +145 -0
  89. package/dist/validators/validate-schema.mjs.map +1 -0
  90. package/dist/validators/validate-story.cjs +285 -0
  91. package/dist/validators/validate-story.cjs.map +1 -0
  92. package/dist/validators/validate-story.d.cts +17 -0
  93. package/dist/validators/validate-story.d.mts +17 -0
  94. package/dist/validators/validate-story.mjs +284 -0
  95. package/dist/validators/validate-story.mjs.map +1 -0
  96. package/package.json +17 -2
  97. package/dist/generated/mapi/types.gen.d.cts +0 -1272
  98. package/dist/generated/mapi/types.gen.d.mts +0 -1272
  99. package/dist/helpers/create-story-helpers.cjs +0 -42
  100. package/dist/helpers/create-story-helpers.cjs.map +0 -1
  101. package/dist/helpers/create-story-helpers.d.cts +0 -50
  102. package/dist/helpers/create-story-helpers.d.mts +0 -50
  103. package/dist/helpers/create-story-helpers.mjs +0 -42
  104. package/dist/helpers/create-story-helpers.mjs.map +0 -1
  105. package/dist/helpers/define-asset-folder.cjs +0 -46
  106. package/dist/helpers/define-asset-folder.cjs.map +0 -1
  107. package/dist/helpers/define-asset-folder.d.cts +0 -33
  108. package/dist/helpers/define-asset-folder.d.mts +0 -33
  109. package/dist/helpers/define-asset-folder.mjs +0 -43
  110. package/dist/helpers/define-asset-folder.mjs.map +0 -1
  111. package/dist/helpers/define-asset.cjs +0 -60
  112. package/dist/helpers/define-asset.cjs.map +0 -1
  113. package/dist/helpers/define-asset.d.cts +0 -32
  114. package/dist/helpers/define-asset.d.mts +0 -32
  115. package/dist/helpers/define-asset.mjs +0 -57
  116. package/dist/helpers/define-asset.mjs.map +0 -1
  117. package/dist/helpers/define-block-folder.cjs +0 -44
  118. package/dist/helpers/define-block-folder.cjs.map +0 -1
  119. package/dist/helpers/define-block-folder.d.cts +0 -34
  120. package/dist/helpers/define-block-folder.d.mts +0 -34
  121. package/dist/helpers/define-block-folder.mjs +0 -41
  122. package/dist/helpers/define-block-folder.mjs.map +0 -1
  123. package/dist/helpers/define-datasource-entry.cjs +0 -47
  124. package/dist/helpers/define-datasource-entry.cjs.map +0 -1
  125. package/dist/helpers/define-datasource-entry.d.cts +0 -49
  126. package/dist/helpers/define-datasource-entry.d.mts +0 -49
  127. package/dist/helpers/define-datasource-entry.mjs +0 -43
  128. package/dist/helpers/define-datasource-entry.mjs.map +0 -1
  129. package/dist/helpers/define-internal-tag.cjs +0 -41
  130. package/dist/helpers/define-internal-tag.cjs.map +0 -1
  131. package/dist/helpers/define-internal-tag.d.cts +0 -34
  132. package/dist/helpers/define-internal-tag.d.mts +0 -34
  133. package/dist/helpers/define-internal-tag.mjs +0 -38
  134. package/dist/helpers/define-internal-tag.mjs.map +0 -1
  135. package/dist/helpers/define-link.cjs +0 -23
  136. package/dist/helpers/define-link.cjs.map +0 -1
  137. package/dist/helpers/define-link.d.cts +0 -32
  138. package/dist/helpers/define-link.d.mts +0 -32
  139. package/dist/helpers/define-link.mjs +0 -22
  140. package/dist/helpers/define-link.mjs.map +0 -1
  141. package/dist/helpers/define-preset.cjs +0 -44
  142. package/dist/helpers/define-preset.cjs.map +0 -1
  143. package/dist/helpers/define-preset.d.cts +0 -35
  144. package/dist/helpers/define-preset.d.mts +0 -35
  145. package/dist/helpers/define-preset.mjs +0 -41
  146. package/dist/helpers/define-preset.mjs.map +0 -1
  147. package/dist/helpers/define-space.cjs +0 -47
  148. package/dist/helpers/define-space.cjs.map +0 -1
  149. package/dist/helpers/define-space.d.cts +0 -31
  150. package/dist/helpers/define-space.d.mts +0 -31
  151. package/dist/helpers/define-space.mjs +0 -44
  152. package/dist/helpers/define-space.mjs.map +0 -1
  153. package/dist/helpers/define-story.cjs +0 -122
  154. package/dist/helpers/define-story.cjs.map +0 -1
  155. package/dist/helpers/define-story.d.cts +0 -135
  156. package/dist/helpers/define-story.d.mts +0 -135
  157. package/dist/helpers/define-story.mjs +0 -118
  158. package/dist/helpers/define-story.mjs.map +0 -1
  159. package/dist/helpers/define-tag.cjs +0 -13
  160. package/dist/helpers/define-tag.cjs.map +0 -1
  161. package/dist/helpers/define-tag.d.cts +0 -23
  162. package/dist/helpers/define-tag.d.mts +0 -23
  163. package/dist/helpers/define-tag.mjs +0 -12
  164. package/dist/helpers/define-tag.mjs.map +0 -1
  165. package/dist/helpers/define-user.cjs +0 -50
  166. package/dist/helpers/define-user.cjs.map +0 -1
  167. package/dist/helpers/define-user.d.cts +0 -26
  168. package/dist/helpers/define-user.d.mts +0 -26
  169. package/dist/helpers/define-user.mjs +0 -48
  170. package/dist/helpers/define-user.mjs.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { AssetFieldValue, BlockContentBase, BlockContentInputBase, Field, MultilinkFieldValue, PluginFieldValue, RichtextFieldValue, TableFieldValue } from "../overlay/_internal.gen.cjs";
2
2
  import { Prettify } from "./_utils.cjs";
3
- import { Block } from "./block.cjs";
3
+ import { Block, BlockFields } from "./block.cjs";
4
4
 
5
5
  //#region src/generated/types/field.d.ts
6
6
  /**
@@ -11,27 +11,42 @@ import { Block } from "./block.cjs";
11
11
  type NoBlocks = false;
12
12
  /** True when `T` is the un-narrowed base `Block` (i.e. no specific block was supplied). */
13
13
  type IsBaseBlock<T> = [Block] extends [T] ? true : false;
14
- type RequiredFieldKeys<T> = { [K in keyof T]: T[K] extends {
14
+ /**
15
+ * Maps a block's ordered `fields` array to its read content object, splitting
16
+ * required (`required: true`) from optional fields. Each `F` is a member of the
17
+ * field union, so it provably satisfies `FieldValue`'s `Field` constraint.
18
+ */
19
+ type ContentFields<TFields extends BlockFields, TBlocks, TFieldPlugins = Record<never, never>> = Prettify<{ [F in TFields[number] as F extends {
20
+ required: true;
21
+ } ? F['name'] : never]: FieldValue<F, TBlocks, TFieldPlugins> } & { [F in TFields[number] as F extends {
22
+ required: true;
23
+ } ? never : F['name']]?: FieldValue<F, TBlocks, TFieldPlugins> | null }>;
24
+ /** Input (write) variant of {@link ContentFields}, resolving each field via {@link FieldValueInput}. */
25
+ type ContentFieldsInput<TFields extends BlockFields, TBlocks, TFieldPlugins = Record<never, never>> = Prettify<{ [F in TFields[number] as F extends {
15
26
  required: true;
16
- } ? K : never }[keyof T];
17
- type OptionalFieldKeys<T> = Exclude<keyof T, RequiredFieldKeys<T>>;
27
+ } ? F['name'] : never]: FieldValueInput<F, TBlocks, TFieldPlugins> } & { [F in TFields[number] as F extends {
28
+ required: true;
29
+ } ? never : F['name']]?: FieldValueInput<F, TBlocks, TFieldPlugins> | null }>;
18
30
  /**
19
31
  * Content object for a single block instance as returned by the Storyblok
20
32
  * Content Delivery API. Without a `TBlock` argument, this is the loose
21
33
  * runtime shape (any block, `_editable` optional). With a schema-typed
22
- * `TBlock`, fields are narrowed per the block's schema.
34
+ * `TBlock`, fields are narrowed per the block's `fields`.
23
35
  */
24
- type BlockContent<TBlock extends Block = Block, TBlocks = NoBlocks> = IsBaseBlock<TBlock> extends true ? BlockContentBase : TBlock extends any ? Prettify<{
36
+ type BlockContent<TBlock extends Block = Block, TBlocks = NoBlocks, TFieldPlugins = Record<never, never>> = IsBaseBlock<TBlock> extends true ? BlockContentBase : TBlock extends any ? Prettify<{
25
37
  _uid: string;
26
38
  component: TBlock['name'];
27
39
  _editable?: string;
28
- } & { [K in RequiredFieldKeys<TBlock['schema']>]: FieldValue<NonNullable<TBlock['schema'][K]>, TBlocks> } & { [K in OptionalFieldKeys<TBlock['schema']>]?: FieldValue<NonNullable<TBlock['schema'][K]>, TBlocks> | null }> : never;
40
+ } & ContentFields<TBlock['fields'], TBlocks, TFieldPlugins>> : never;
29
41
  /** Input variant of {@link BlockContent} for write operations (creating/updating stories via the MAPI). `_uid` is optional. */
30
- type BlockContentInput<TBlock extends Block = Block, TBlocks = NoBlocks> = IsBaseBlock<TBlock> extends true ? BlockContentInputBase : TBlock extends any ? Prettify<{
42
+ type BlockContentInput<TBlock extends Block = Block, TBlocks = NoBlocks, TFieldPlugins = Record<never, never>> = IsBaseBlock<TBlock> extends true ? BlockContentInputBase : TBlock extends any ? Prettify<{
31
43
  _uid?: string;
32
44
  component: TBlock['name'];
33
45
  _editable?: string;
34
- } & { [K in RequiredFieldKeys<TBlock['schema']>]: FieldValueInput<NonNullable<TBlock['schema'][K]>, TBlocks> } & { [K in OptionalFieldKeys<TBlock['schema']>]?: FieldValueInput<NonNullable<TBlock['schema'][K]>, TBlocks> | null }> : never;
46
+ } & ContentFieldsInput<TBlock['fields'], TBlocks, TFieldPlugins>> : never;
47
+ type BlocksFieldValue<TBlock extends Block = Block, TBlocks = NoBlocks, TFieldPlugins = Record<never, never>> = BlockContent<TBlock, TBlocks, TFieldPlugins>[];
48
+ /** Union of all valid Storyblok field type discriminants (e.g., `text`, `bloks`). */
49
+ type FieldType = Field['type'];
35
50
  interface FieldTypeValueMap {
36
51
  text: string;
37
52
  textarea: string;
@@ -56,19 +71,35 @@ type IsNestable<T> = T extends {
56
71
  } ? false : T extends {
57
72
  is_nestable: true;
58
73
  } ? true : true;
59
- type ApplyWhitelist<TField, TBlocks> = TField extends {
60
- component_whitelist: ReadonlyArray<infer TWhitelisted extends string>;
74
+ type ApplyAllow<TField, TBlocks> = TField extends {
75
+ allow: ReadonlyArray<infer TAllowed extends string>;
61
76
  } ? Extract<TBlocks, {
62
- name: TWhitelisted;
77
+ name: TAllowed;
63
78
  }> : TBlocks extends any ? IsNestable<TBlocks> extends true ? TBlocks : never : never;
79
+ /**
80
+ * Resolves a `custom` field to its registered plugin value. When the field's
81
+ * `field_type` is a key of `TFieldPlugins`, the validator output is merged with
82
+ * the plugin envelope (`plugin`, optional `_uid`); otherwise it falls back to
83
+ * the untyped {@link PluginFieldValue}. Same shape for read and write.
84
+ */
85
+ type ResolveCustom<TField, TFieldPlugins> = TField extends {
86
+ field_type: infer F extends string;
87
+ } ? F extends keyof TFieldPlugins ? Prettify<TFieldPlugins[F] & {
88
+ plugin: string;
89
+ _uid?: string;
90
+ }> : PluginFieldValue : PluginFieldValue;
64
91
  /** Resolves a field definition to its runtime content value type (read). */
65
- type FieldValue<TField extends Field = Field, TBlocks = NoBlocks> = Prettify<TField extends {
92
+ type FieldValue<TField extends Field = Field, TBlocks = NoBlocks, TFieldPlugins = Record<never, never>> = Prettify<TField extends {
66
93
  type: 'bloks';
67
- } ? [TBlocks] extends [never] ? BlockContentBase[] : [TBlocks] extends [Block] ? BlockContent<ApplyWhitelist<TField, TBlocks>, TBlocks>[] : BlockContentBase[] : FieldTypeValueMap[TField['type']]>;
94
+ } ? [TBlocks] extends [never] ? BlockContentBase[] : [TBlocks] extends [Block] ? BlockContent<ApplyAllow<TField, TBlocks>, TBlocks, TFieldPlugins>[] : BlockContentBase[] : TField extends {
95
+ type: 'custom';
96
+ } ? ResolveCustom<TField, TFieldPlugins> : FieldTypeValueMap[TField['type']]>;
68
97
  /** Resolves a field definition to its input value type (write). */
69
- type FieldValueInput<TField extends Field = Field, TBlocks = NoBlocks> = Prettify<TField extends {
98
+ type FieldValueInput<TField extends Field = Field, TBlocks = NoBlocks, TFieldPlugins = Record<never, never>> = Prettify<TField extends {
70
99
  type: 'bloks';
71
- } ? [TBlocks] extends [never] ? BlockContentInputBase[] : [TBlocks] extends [Block] ? BlockContentInput<ApplyWhitelist<TField, TBlocks>, TBlocks>[] : BlockContentInputBase[] : FieldTypeValueMap[TField['type']]>;
100
+ } ? [TBlocks] extends [never] ? BlockContentInputBase[] : [TBlocks] extends [Block] ? BlockContentInput<ApplyAllow<TField, TBlocks>, TBlocks, TFieldPlugins>[] : BlockContentInputBase[] : TField extends {
101
+ type: 'custom';
102
+ } ? ResolveCustom<TField, TFieldPlugins> : FieldTypeValueMap[TField['type']]>;
72
103
  //#endregion
73
- export { BlockContent, BlockContentInput };
104
+ export { BlockContent, BlockContentInput, BlocksFieldValue, FieldType, FieldValue, FieldValueInput };
74
105
  //# sourceMappingURL=field.d.cts.map
@@ -1,6 +1,6 @@
1
1
  import { AssetFieldValue, BlockContentBase, BlockContentInputBase, Field, MultilinkFieldValue, PluginFieldValue, RichtextFieldValue, TableFieldValue } from "../overlay/_internal.gen.mjs";
2
2
  import { Prettify } from "./_utils.mjs";
3
- import { Block } from "./block.mjs";
3
+ import { Block, BlockFields } from "./block.mjs";
4
4
 
5
5
  //#region src/generated/types/field.d.ts
6
6
  /**
@@ -11,27 +11,42 @@ import { Block } from "./block.mjs";
11
11
  type NoBlocks = false;
12
12
  /** True when `T` is the un-narrowed base `Block` (i.e. no specific block was supplied). */
13
13
  type IsBaseBlock<T> = [Block] extends [T] ? true : false;
14
- type RequiredFieldKeys<T> = { [K in keyof T]: T[K] extends {
14
+ /**
15
+ * Maps a block's ordered `fields` array to its read content object, splitting
16
+ * required (`required: true`) from optional fields. Each `F` is a member of the
17
+ * field union, so it provably satisfies `FieldValue`'s `Field` constraint.
18
+ */
19
+ type ContentFields<TFields extends BlockFields, TBlocks, TFieldPlugins = Record<never, never>> = Prettify<{ [F in TFields[number] as F extends {
20
+ required: true;
21
+ } ? F['name'] : never]: FieldValue<F, TBlocks, TFieldPlugins> } & { [F in TFields[number] as F extends {
22
+ required: true;
23
+ } ? never : F['name']]?: FieldValue<F, TBlocks, TFieldPlugins> | null }>;
24
+ /** Input (write) variant of {@link ContentFields}, resolving each field via {@link FieldValueInput}. */
25
+ type ContentFieldsInput<TFields extends BlockFields, TBlocks, TFieldPlugins = Record<never, never>> = Prettify<{ [F in TFields[number] as F extends {
15
26
  required: true;
16
- } ? K : never }[keyof T];
17
- type OptionalFieldKeys<T> = Exclude<keyof T, RequiredFieldKeys<T>>;
27
+ } ? F['name'] : never]: FieldValueInput<F, TBlocks, TFieldPlugins> } & { [F in TFields[number] as F extends {
28
+ required: true;
29
+ } ? never : F['name']]?: FieldValueInput<F, TBlocks, TFieldPlugins> | null }>;
18
30
  /**
19
31
  * Content object for a single block instance as returned by the Storyblok
20
32
  * Content Delivery API. Without a `TBlock` argument, this is the loose
21
33
  * runtime shape (any block, `_editable` optional). With a schema-typed
22
- * `TBlock`, fields are narrowed per the block's schema.
34
+ * `TBlock`, fields are narrowed per the block's `fields`.
23
35
  */
24
- type BlockContent<TBlock extends Block = Block, TBlocks = NoBlocks> = IsBaseBlock<TBlock> extends true ? BlockContentBase : TBlock extends any ? Prettify<{
36
+ type BlockContent<TBlock extends Block = Block, TBlocks = NoBlocks, TFieldPlugins = Record<never, never>> = IsBaseBlock<TBlock> extends true ? BlockContentBase : TBlock extends any ? Prettify<{
25
37
  _uid: string;
26
38
  component: TBlock['name'];
27
39
  _editable?: string;
28
- } & { [K in RequiredFieldKeys<TBlock['schema']>]: FieldValue<NonNullable<TBlock['schema'][K]>, TBlocks> } & { [K in OptionalFieldKeys<TBlock['schema']>]?: FieldValue<NonNullable<TBlock['schema'][K]>, TBlocks> | null }> : never;
40
+ } & ContentFields<TBlock['fields'], TBlocks, TFieldPlugins>> : never;
29
41
  /** Input variant of {@link BlockContent} for write operations (creating/updating stories via the MAPI). `_uid` is optional. */
30
- type BlockContentInput<TBlock extends Block = Block, TBlocks = NoBlocks> = IsBaseBlock<TBlock> extends true ? BlockContentInputBase : TBlock extends any ? Prettify<{
42
+ type BlockContentInput<TBlock extends Block = Block, TBlocks = NoBlocks, TFieldPlugins = Record<never, never>> = IsBaseBlock<TBlock> extends true ? BlockContentInputBase : TBlock extends any ? Prettify<{
31
43
  _uid?: string;
32
44
  component: TBlock['name'];
33
45
  _editable?: string;
34
- } & { [K in RequiredFieldKeys<TBlock['schema']>]: FieldValueInput<NonNullable<TBlock['schema'][K]>, TBlocks> } & { [K in OptionalFieldKeys<TBlock['schema']>]?: FieldValueInput<NonNullable<TBlock['schema'][K]>, TBlocks> | null }> : never;
46
+ } & ContentFieldsInput<TBlock['fields'], TBlocks, TFieldPlugins>> : never;
47
+ type BlocksFieldValue<TBlock extends Block = Block, TBlocks = NoBlocks, TFieldPlugins = Record<never, never>> = BlockContent<TBlock, TBlocks, TFieldPlugins>[];
48
+ /** Union of all valid Storyblok field type discriminants (e.g., `text`, `bloks`). */
49
+ type FieldType = Field['type'];
35
50
  interface FieldTypeValueMap {
36
51
  text: string;
37
52
  textarea: string;
@@ -56,19 +71,35 @@ type IsNestable<T> = T extends {
56
71
  } ? false : T extends {
57
72
  is_nestable: true;
58
73
  } ? true : true;
59
- type ApplyWhitelist<TField, TBlocks> = TField extends {
60
- component_whitelist: ReadonlyArray<infer TWhitelisted extends string>;
74
+ type ApplyAllow<TField, TBlocks> = TField extends {
75
+ allow: ReadonlyArray<infer TAllowed extends string>;
61
76
  } ? Extract<TBlocks, {
62
- name: TWhitelisted;
77
+ name: TAllowed;
63
78
  }> : TBlocks extends any ? IsNestable<TBlocks> extends true ? TBlocks : never : never;
79
+ /**
80
+ * Resolves a `custom` field to its registered plugin value. When the field's
81
+ * `field_type` is a key of `TFieldPlugins`, the validator output is merged with
82
+ * the plugin envelope (`plugin`, optional `_uid`); otherwise it falls back to
83
+ * the untyped {@link PluginFieldValue}. Same shape for read and write.
84
+ */
85
+ type ResolveCustom<TField, TFieldPlugins> = TField extends {
86
+ field_type: infer F extends string;
87
+ } ? F extends keyof TFieldPlugins ? Prettify<TFieldPlugins[F] & {
88
+ plugin: string;
89
+ _uid?: string;
90
+ }> : PluginFieldValue : PluginFieldValue;
64
91
  /** Resolves a field definition to its runtime content value type (read). */
65
- type FieldValue<TField extends Field = Field, TBlocks = NoBlocks> = Prettify<TField extends {
92
+ type FieldValue<TField extends Field = Field, TBlocks = NoBlocks, TFieldPlugins = Record<never, never>> = Prettify<TField extends {
66
93
  type: 'bloks';
67
- } ? [TBlocks] extends [never] ? BlockContentBase[] : [TBlocks] extends [Block] ? BlockContent<ApplyWhitelist<TField, TBlocks>, TBlocks>[] : BlockContentBase[] : FieldTypeValueMap[TField['type']]>;
94
+ } ? [TBlocks] extends [never] ? BlockContentBase[] : [TBlocks] extends [Block] ? BlockContent<ApplyAllow<TField, TBlocks>, TBlocks, TFieldPlugins>[] : BlockContentBase[] : TField extends {
95
+ type: 'custom';
96
+ } ? ResolveCustom<TField, TFieldPlugins> : FieldTypeValueMap[TField['type']]>;
68
97
  /** Resolves a field definition to its input value type (write). */
69
- type FieldValueInput<TField extends Field = Field, TBlocks = NoBlocks> = Prettify<TField extends {
98
+ type FieldValueInput<TField extends Field = Field, TBlocks = NoBlocks, TFieldPlugins = Record<never, never>> = Prettify<TField extends {
70
99
  type: 'bloks';
71
- } ? [TBlocks] extends [never] ? BlockContentInputBase[] : [TBlocks] extends [Block] ? BlockContentInput<ApplyWhitelist<TField, TBlocks>, TBlocks>[] : BlockContentInputBase[] : FieldTypeValueMap[TField['type']]>;
100
+ } ? [TBlocks] extends [never] ? BlockContentInputBase[] : [TBlocks] extends [Block] ? BlockContentInput<ApplyAllow<TField, TBlocks>, TBlocks, TFieldPlugins>[] : BlockContentInputBase[] : TField extends {
101
+ type: 'custom';
102
+ } ? ResolveCustom<TField, TFieldPlugins> : FieldTypeValueMap[TField['type']]>;
72
103
  //#endregion
73
- export { BlockContent, BlockContentInput };
104
+ export { BlockContent, BlockContentInput, BlocksFieldValue, FieldType, FieldValue, FieldValueInput };
74
105
  //# sourceMappingURL=field.d.mts.map
@@ -1,4 +1,4 @@
1
- import { MapiStory as MapiStory$1, StoryCreate as StoryCreate$1, StoryUpdate as StoryUpdate$1 } from "../mapi/_internal.gen.cjs";
1
+ import { MapiStory as MapiStory$1, StoryCreate, StoryUpdate } from "../mapi/_internal.gen.cjs";
2
2
  import { Override, Prettify } from "./_utils.cjs";
3
3
  import { Block, RootBlock } from "./block.cjs";
4
4
  import { BlockContent, BlockContentInput } from "./field.cjs";
@@ -14,16 +14,12 @@ type NoBlocks = false;
14
14
  * Base (un-narrowed) `RootBlock` means no schema was supplied, so the generated
15
15
  * story passes through unchanged.
16
16
  */
17
- type MapiStoryWithSchemaContent<TStory extends MapiStory$1 | StoryCreate$1 | StoryUpdate$1, TBlock extends RootBlock = RootBlock, TBlocks = NoBlocks> = RootBlock extends TBlock ? TStory : Override<TStory, {
18
- content: TStory extends StoryCreate$1 | StoryUpdate$1 ? BlockContentInput<TBlock, TBlocks> : BlockContent<TBlock, TBlocks>;
17
+ type MapiStoryWithSchemaContent<TStory extends MapiStory$1 | StoryCreate | StoryUpdate, TBlock extends RootBlock = RootBlock, TBlocks = NoBlocks, TFieldPlugins = Record<never, never>> = RootBlock extends TBlock ? TStory : Override<TStory, {
18
+ content: TStory extends StoryCreate | StoryUpdate ? BlockContentInput<TBlock, TBlocks, TFieldPlugins> : BlockContent<TBlock, TBlocks, TFieldPlugins>;
19
19
  }>;
20
- type MakeMapiStory<TStory extends MapiStory$1 | StoryCreate$1 | StoryUpdate$1, TBlockOrBlocks extends RootBlock | Block = RootBlock, TBlocks = NoBlocks> = Prettify<[TBlockOrBlocks] extends [RootBlock] ? MapiStoryWithSchemaContent<TStory, TBlockOrBlocks, TBlocks> : TBlocks extends NoBlocks ? MapiStoryWithSchemaContent<TStory, Extract<TBlockOrBlocks, RootBlock>, TBlockOrBlocks> : never>;
20
+ type MakeMapiStory<TStory extends MapiStory$1 | StoryCreate | StoryUpdate, TBlockOrBlocks extends RootBlock | Block = RootBlock, TFieldPlugins = Record<never, never>, TBlocks = NoBlocks> = Prettify<[TBlockOrBlocks] extends [RootBlock] ? MapiStoryWithSchemaContent<TStory, TBlockOrBlocks, TBlocks, TFieldPlugins> : TBlocks extends NoBlocks ? MapiStoryWithSchemaContent<TStory, Extract<TBlockOrBlocks, RootBlock>, TBlockOrBlocks, TFieldPlugins> : never>;
21
21
  /** A Storyblok MAPI story. */
22
- type MapiStory<TBlockOrBlocks extends RootBlock | Block = RootBlock, TBlocks = NoBlocks> = MakeMapiStory<MapiStory$1, TBlockOrBlocks, TBlocks>;
23
- /** Payload for creating a story via the MAPI. */
24
- type StoryCreate<TBlockOrBlocks extends RootBlock | Block = RootBlock, TBlocks = NoBlocks> = MakeMapiStory<StoryCreate$1, TBlockOrBlocks, TBlocks>;
25
- /** Payload for updating a story via the MAPI. */
26
- type StoryUpdate<TBlockOrBlocks extends RootBlock | Block = RootBlock, TBlocks = NoBlocks> = MakeMapiStory<StoryUpdate$1, TBlockOrBlocks, TBlocks>;
22
+ type MapiStory<TBlockOrBlocks extends RootBlock | Block = RootBlock, TFieldPlugins = Record<never, never>, TBlocks = NoBlocks> = MakeMapiStory<MapiStory$1, TBlockOrBlocks, TFieldPlugins, TBlocks>;
27
23
  //#endregion
28
- export { MapiStory, StoryCreate, StoryUpdate };
24
+ export { MapiStory };
29
25
  //# sourceMappingURL=mapi-story.d.cts.map
@@ -1,4 +1,4 @@
1
- import { MapiStory as MapiStory$1, StoryCreate as StoryCreate$1, StoryUpdate as StoryUpdate$1 } from "../mapi/_internal.gen.mjs";
1
+ import { MapiStory as MapiStory$1, StoryCreate, StoryUpdate } from "../mapi/_internal.gen.mjs";
2
2
  import { Override, Prettify } from "./_utils.mjs";
3
3
  import { Block, RootBlock } from "./block.mjs";
4
4
  import { BlockContent, BlockContentInput } from "./field.mjs";
@@ -14,16 +14,12 @@ type NoBlocks = false;
14
14
  * Base (un-narrowed) `RootBlock` means no schema was supplied, so the generated
15
15
  * story passes through unchanged.
16
16
  */
17
- type MapiStoryWithSchemaContent<TStory extends MapiStory$1 | StoryCreate$1 | StoryUpdate$1, TBlock extends RootBlock = RootBlock, TBlocks = NoBlocks> = RootBlock extends TBlock ? TStory : Override<TStory, {
18
- content: TStory extends StoryCreate$1 | StoryUpdate$1 ? BlockContentInput<TBlock, TBlocks> : BlockContent<TBlock, TBlocks>;
17
+ type MapiStoryWithSchemaContent<TStory extends MapiStory$1 | StoryCreate | StoryUpdate, TBlock extends RootBlock = RootBlock, TBlocks = NoBlocks, TFieldPlugins = Record<never, never>> = RootBlock extends TBlock ? TStory : Override<TStory, {
18
+ content: TStory extends StoryCreate | StoryUpdate ? BlockContentInput<TBlock, TBlocks, TFieldPlugins> : BlockContent<TBlock, TBlocks, TFieldPlugins>;
19
19
  }>;
20
- type MakeMapiStory<TStory extends MapiStory$1 | StoryCreate$1 | StoryUpdate$1, TBlockOrBlocks extends RootBlock | Block = RootBlock, TBlocks = NoBlocks> = Prettify<[TBlockOrBlocks] extends [RootBlock] ? MapiStoryWithSchemaContent<TStory, TBlockOrBlocks, TBlocks> : TBlocks extends NoBlocks ? MapiStoryWithSchemaContent<TStory, Extract<TBlockOrBlocks, RootBlock>, TBlockOrBlocks> : never>;
20
+ type MakeMapiStory<TStory extends MapiStory$1 | StoryCreate | StoryUpdate, TBlockOrBlocks extends RootBlock | Block = RootBlock, TFieldPlugins = Record<never, never>, TBlocks = NoBlocks> = Prettify<[TBlockOrBlocks] extends [RootBlock] ? MapiStoryWithSchemaContent<TStory, TBlockOrBlocks, TBlocks, TFieldPlugins> : TBlocks extends NoBlocks ? MapiStoryWithSchemaContent<TStory, Extract<TBlockOrBlocks, RootBlock>, TBlockOrBlocks, TFieldPlugins> : never>;
21
21
  /** A Storyblok MAPI story. */
22
- type MapiStory<TBlockOrBlocks extends RootBlock | Block = RootBlock, TBlocks = NoBlocks> = MakeMapiStory<MapiStory$1, TBlockOrBlocks, TBlocks>;
23
- /** Payload for creating a story via the MAPI. */
24
- type StoryCreate<TBlockOrBlocks extends RootBlock | Block = RootBlock, TBlocks = NoBlocks> = MakeMapiStory<StoryCreate$1, TBlockOrBlocks, TBlocks>;
25
- /** Payload for updating a story via the MAPI. */
26
- type StoryUpdate<TBlockOrBlocks extends RootBlock | Block = RootBlock, TBlocks = NoBlocks> = MakeMapiStory<StoryUpdate$1, TBlockOrBlocks, TBlocks>;
22
+ type MapiStory<TBlockOrBlocks extends RootBlock | Block = RootBlock, TFieldPlugins = Record<never, never>, TBlocks = NoBlocks> = MakeMapiStory<MapiStory$1, TBlockOrBlocks, TFieldPlugins, TBlocks>;
27
23
  //#endregion
28
- export { MapiStory, StoryCreate, StoryUpdate };
24
+ export { MapiStory };
29
25
  //# sourceMappingURL=mapi-story.d.mts.map
@@ -9,11 +9,11 @@ import { BlockContent } from "./field.cjs";
9
9
  * `NoBlocks` (the default) leaves nested content loose (`BlockContentBase`).
10
10
  */
11
11
  type NoBlocks = false;
12
- type CapiStoryWithSchemaContent<TBlock extends RootBlock = RootBlock, TBlocks = NoBlocks> = Override<CapiStory, {
13
- content: BlockContent<TBlock, TBlocks>;
12
+ type CapiStoryWithSchemaContent<TBlock extends RootBlock = RootBlock, TBlocks = NoBlocks, TFieldPlugins = Record<never, never>> = Override<CapiStory, {
13
+ content: BlockContent<TBlock, TBlocks, TFieldPlugins>;
14
14
  }>;
15
15
  /** A Storyblok CDN (CAPI) story. */
16
- type Story<TBlockOrBlocks extends RootBlock | Block = RootBlock, TBlocks = NoBlocks> = Prettify<[TBlockOrBlocks] extends [RootBlock] ? CapiStoryWithSchemaContent<TBlockOrBlocks, TBlocks> : TBlocks extends NoBlocks ? CapiStoryWithSchemaContent<Extract<TBlockOrBlocks, RootBlock>, TBlockOrBlocks> : never>;
16
+ type Story<TBlockOrBlocks extends RootBlock | Block = RootBlock, TFieldPlugins = Record<never, never>, TBlocks = NoBlocks> = Prettify<[TBlockOrBlocks] extends [RootBlock] ? CapiStoryWithSchemaContent<TBlockOrBlocks, TBlocks, TFieldPlugins> : TBlocks extends NoBlocks ? CapiStoryWithSchemaContent<Extract<TBlockOrBlocks, RootBlock>, TBlockOrBlocks, TFieldPlugins> : never>;
17
17
  //#endregion
18
18
  export { Story };
19
19
  //# sourceMappingURL=story.d.cts.map
@@ -9,11 +9,11 @@ import { BlockContent } from "./field.mjs";
9
9
  * `NoBlocks` (the default) leaves nested content loose (`BlockContentBase`).
10
10
  */
11
11
  type NoBlocks = false;
12
- type CapiStoryWithSchemaContent<TBlock extends RootBlock = RootBlock, TBlocks = NoBlocks> = Override<CapiStory, {
13
- content: BlockContent<TBlock, TBlocks>;
12
+ type CapiStoryWithSchemaContent<TBlock extends RootBlock = RootBlock, TBlocks = NoBlocks, TFieldPlugins = Record<never, never>> = Override<CapiStory, {
13
+ content: BlockContent<TBlock, TBlocks, TFieldPlugins>;
14
14
  }>;
15
15
  /** A Storyblok CDN (CAPI) story. */
16
- type Story<TBlockOrBlocks extends RootBlock | Block = RootBlock, TBlocks = NoBlocks> = Prettify<[TBlockOrBlocks] extends [RootBlock] ? CapiStoryWithSchemaContent<TBlockOrBlocks, TBlocks> : TBlocks extends NoBlocks ? CapiStoryWithSchemaContent<Extract<TBlockOrBlocks, RootBlock>, TBlockOrBlocks> : never>;
16
+ type Story<TBlockOrBlocks extends RootBlock | Block = RootBlock, TFieldPlugins = Record<never, never>, TBlocks = NoBlocks> = Prettify<[TBlockOrBlocks] extends [RootBlock] ? CapiStoryWithSchemaContent<TBlockOrBlocks, TBlocks, TFieldPlugins> : TBlocks extends NoBlocks ? CapiStoryWithSchemaContent<Extract<TBlockOrBlocks, RootBlock>, TBlockOrBlocks, TFieldPlugins> : never>;
17
17
  //#endregion
18
18
  export { Story };
19
19
  //# sourceMappingURL=story.d.mts.map
@@ -5,47 +5,29 @@ const BLOCK_DEFAULTS = {
5
5
  created_at: "",
6
6
  updated_at: "",
7
7
  is_root: false,
8
- is_nestable: true,
9
- component_group_uuid: null
8
+ is_nestable: true
10
9
  };
11
10
  function defineBlock(block) {
12
- const inputSchema = Array.isArray(block?.schema) ? block.schema : [];
11
+ const inputFields = Array.isArray(block?.fields) ? block.fields : [];
13
12
  const seen = /* @__PURE__ */ new Set();
14
- const schemaRecord = {};
15
- inputSchema.forEach((field, index) => {
13
+ const fields = inputFields.map((field, index) => {
16
14
  const name = field?.name;
17
- if (typeof name !== "string") return;
18
- if (seen.has(name)) throw new Error(`defineBlock: duplicate field name "${name}" in block "${block?.name ?? ""}"`);
19
- seen.add(name);
20
- const { name: _name, ...rest } = field;
21
- schemaRecord[name] = {
22
- ...rest,
15
+ if (typeof name === "string") {
16
+ if (seen.has(name)) throw new Error(`defineBlock: duplicate field name "${name}" in block "${block?.name ?? ""}"`);
17
+ seen.add(name);
18
+ }
19
+ return {
20
+ ...field,
23
21
  pos: index
24
22
  };
25
23
  });
26
24
  return {
27
25
  ...BLOCK_DEFAULTS,
28
26
  ...block,
29
- schema: schemaRecord
27
+ fields
30
28
  };
31
29
  }
32
- /**
33
- * Defines a block creation payload for the MAPI.
34
- *
35
- * @example
36
- * const payload = defineBlockCreate({ name: 'page', schema: { ... } });
37
- */
38
- const defineBlockCreate = (block) => block;
39
- /**
40
- * Defines a block update payload for the MAPI.
41
- *
42
- * @example
43
- * const payload = defineBlockUpdate({ display_name: 'Page' });
44
- */
45
- const defineBlockUpdate = (block) => block;
46
30
 
47
31
  //#endregion
48
32
  exports.defineBlock = defineBlock;
49
- exports.defineBlockCreate = defineBlockCreate;
50
- exports.defineBlockUpdate = defineBlockUpdate;
51
33
  //# sourceMappingURL=define-block.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"define-block.cjs","names":[],"sources":["../../src/helpers/define-block.ts"],"sourcesContent":["import type {\n Block,\n BlockSchema,\n BlockSchemaInput,\n ComponentCreate,\n ComponentUpdate,\n NestableBlock,\n RootBlock,\n SchemaArrayToRecord,\n} from '../generated/types/block';\nimport type { Prettify } from '../utils/prettify';\n\nexport type { Block, BlockSchema, BlockSchemaInput, NestableBlock, RootBlock, SchemaArrayToRecord };\n\nconst BLOCK_DEFAULTS = {\n id: 1,\n created_at: '',\n updated_at: '',\n is_root: false,\n is_nestable: true,\n component_group_uuid: null,\n};\n\n/** Fields that have safe defaults and may be omitted from block input. */\ntype BlockOptional = keyof typeof BLOCK_DEFAULTS;\n\ntype BlockInput<\n TName extends string = string,\n TInputSchema extends BlockSchemaInput = BlockSchemaInput,\n TIsRoot extends boolean = false,\n TIsNestable extends boolean = true,\n TComponentGroupUuid extends string | null = null,\n> = Prettify<\n Omit<Block, 'name' | 'schema' | 'is_root' | 'is_nestable' | 'component_group_uuid' | BlockOptional> & {\n name: TName;\n schema: TInputSchema;\n is_root?: TIsRoot;\n is_nestable?: TIsNestable;\n component_group_uuid?: TComponentGroupUuid;\n } & Partial<Pick<Block, Exclude<BlockOptional, 'is_root' | 'is_nestable' | 'component_group_uuid'>>>\n>;\n\ntype DefinedBlock<\n TName extends string,\n TBlockSchema,\n TIsRoot extends boolean,\n TIsNestable extends boolean,\n TComponentGroupUuid extends string | null,\n> = Prettify<\n Omit<Block, 'name' | 'schema' | 'is_root' | 'is_nestable' | 'component_group_uuid'> & {\n name: TName;\n schema: TBlockSchema;\n is_root: TIsRoot;\n is_nestable: TIsNestable;\n component_group_uuid: TComponentGroupUuid;\n }\n>;\n\n/**\n * Returns a {@link Block} with object-shape `schema` (matches the MAPI wire\n * shape). The user-facing input is an ordered array of `defineField` calls;\n * the array index becomes the field's `pos` in the returned map. Throws if\n * two fields share the same `name`.\n *\n * @example\n * const pageBlock = defineBlock({\n * name: 'page',\n * is_root: true,\n * schema: [\n * defineField('headline', { type: 'text', required: true }),\n * ],\n * });\n */\nexport function defineBlock<\n TName extends string,\n const TInputSchema extends BlockSchemaInput,\n TIsRoot extends boolean = false,\n TIsNestable extends boolean = true,\n TComponentGroupUuid extends string | null = null,\n>(\n block: BlockInput<TName, TInputSchema, TIsRoot, TIsNestable, TComponentGroupUuid>,\n): DefinedBlock<TName, SchemaArrayToRecord<TInputSchema>, TIsRoot, TIsNestable, TComponentGroupUuid>;\n\nexport function defineBlock(block: any) {\n const inputSchema = Array.isArray(block?.schema) ? block.schema : [];\n const seen = new Set<string>();\n const schemaRecord: Record<string, unknown> = {};\n inputSchema.forEach((field: any, index: number) => {\n const name = field?.name;\n if (typeof name !== 'string') {\n return;\n }\n if (seen.has(name)) {\n throw new Error(`defineBlock: duplicate field name \"${name}\" in block \"${block?.name ?? ''}\"`);\n }\n seen.add(name);\n const { name: _name, ...rest } = field;\n schemaRecord[name] = { ...rest, pos: index };\n });\n return { ...BLOCK_DEFAULTS, ...block, schema: schemaRecord };\n}\n\n/**\n * Defines a block creation payload for the MAPI.\n *\n * @example\n * const payload = defineBlockCreate({ name: 'page', schema: { ... } });\n */\nexport const defineBlockCreate = (block: ComponentCreate): ComponentCreate => block;\n\n/**\n * Defines a block update payload for the MAPI.\n *\n * @example\n * const payload = defineBlockUpdate({ display_name: 'Page' });\n */\nexport const defineBlockUpdate = (block: ComponentUpdate): ComponentUpdate => block;\n"],"mappings":";;AAcA,MAAM,iBAAiB;CACrB,IAAI;CACJ,YAAY;CACZ,YAAY;CACZ,SAAS;CACT,aAAa;CACb,sBAAsB;CACvB;AA8DD,SAAgB,YAAY,OAAY;CACtC,MAAM,cAAc,MAAM,QAAQ,OAAO,OAAO,GAAG,MAAM,SAAS,EAAE;CACpE,MAAM,uBAAO,IAAI,KAAa;CAC9B,MAAM,eAAwC,EAAE;AAChD,aAAY,SAAS,OAAY,UAAkB;EACjD,MAAM,OAAO,OAAO;AACpB,MAAI,OAAO,SAAS,SAClB;AAEF,MAAI,KAAK,IAAI,KAAK,CAChB,OAAM,IAAI,MAAM,sCAAsC,KAAK,cAAc,OAAO,QAAQ,GAAG,GAAG;AAEhG,OAAK,IAAI,KAAK;EACd,MAAM,EAAE,MAAM,OAAO,GAAG,SAAS;AACjC,eAAa,QAAQ;GAAE,GAAG;GAAM,KAAK;GAAO;GAC5C;AACF,QAAO;EAAE,GAAG;EAAgB,GAAG;EAAO,QAAQ;EAAc;;;;;;;;AAS9D,MAAa,qBAAqB,UAA4C;;;;;;;AAQ9E,MAAa,qBAAqB,UAA4C"}
1
+ {"version":3,"file":"define-block.cjs","names":[],"sources":["../../src/helpers/define-block.ts"],"sourcesContent":["import type {\n Block,\n BlockFields,\n NestableBlock,\n RootBlock,\n} from '../generated/types/block';\nimport type { Prettify } from '../utils/prettify';\n\nexport type { Block, BlockFields, NestableBlock, RootBlock };\n\nconst BLOCK_DEFAULTS = {\n id: 1,\n created_at: '',\n updated_at: '',\n is_root: false,\n is_nestable: true,\n};\n\n/** Fields that have safe defaults and may be omitted from block input. */\ntype BlockOptional = keyof typeof BLOCK_DEFAULTS;\n\ntype BlockInput<\n TName extends string = string,\n TFields extends BlockFields = BlockFields,\n TIsRoot extends boolean = false,\n TIsNestable extends boolean = true,\n> = Prettify<\n Omit<Block, 'name' | 'fields' | 'is_root' | 'is_nestable' | BlockOptional> & {\n name: TName;\n fields: TFields;\n is_root?: TIsRoot;\n is_nestable?: TIsNestable;\n } & Partial<Pick<Block, Exclude<BlockOptional, 'is_root' | 'is_nestable'>>>\n>;\n\ntype DefinedBlock<\n TName extends string,\n TFields extends BlockFields,\n TIsRoot extends boolean,\n TIsNestable extends boolean,\n> = Prettify<\n Omit<Block, 'name' | 'fields' | 'is_root' | 'is_nestable'> & {\n name: TName;\n fields: TFields;\n is_root: TIsRoot;\n is_nestable: TIsNestable;\n }\n>;\n\n/**\n * Returns a {@link Block} content-shape definition. The user-facing input is an\n * ordered array of `defineField` calls under `fields`; the array index becomes\n * each field's `pos`. A thin, strongly-typed helper — it does not map to the\n * MAPI wire shape (the CLI owns the DSL→wire mapping). Throws only on duplicate\n * field names (a programming error).\n *\n * @example\n * const pageBlock = defineBlock({\n * name: 'page',\n * is_root: true,\n * fields: [\n * defineField('headline', { type: 'text', required: true }),\n * ],\n * });\n */\nexport function defineBlock<\n TName extends string,\n const TFields extends BlockFields,\n TIsRoot extends boolean = false,\n TIsNestable extends boolean = true,\n>(\n block: BlockInput<TName, TFields, TIsRoot, TIsNestable>,\n): DefinedBlock<TName, TFields, TIsRoot, TIsNestable>;\n\nexport function defineBlock(block: any) {\n const inputFields = Array.isArray(block?.fields) ? block.fields : [];\n const seen = new Set<string>();\n const fields = inputFields.map((field: any, index: number) => {\n const name = field?.name;\n if (typeof name === 'string') {\n if (seen.has(name)) {\n throw new Error(`defineBlock: duplicate field name \"${name}\" in block \"${block?.name ?? ''}\"`);\n }\n seen.add(name);\n }\n return { ...field, pos: index };\n });\n return { ...BLOCK_DEFAULTS, ...block, fields };\n}\n"],"mappings":";;AAUA,MAAM,iBAAiB;CACrB,IAAI;CACJ,YAAY;CACZ,YAAY;CACZ,SAAS;CACT,aAAa;CACd;AA0DD,SAAgB,YAAY,OAAY;CACtC,MAAM,cAAc,MAAM,QAAQ,OAAO,OAAO,GAAG,MAAM,SAAS,EAAE;CACpE,MAAM,uBAAO,IAAI,KAAa;CAC9B,MAAM,SAAS,YAAY,KAAK,OAAY,UAAkB;EAC5D,MAAM,OAAO,OAAO;AACpB,MAAI,OAAO,SAAS,UAAU;AAC5B,OAAI,KAAK,IAAI,KAAK,CAChB,OAAM,IAAI,MAAM,sCAAsC,KAAK,cAAc,OAAO,QAAQ,GAAG,GAAG;AAEhG,QAAK,IAAI,KAAK;;AAEhB,SAAO;GAAE,GAAG;GAAO,KAAK;GAAO;GAC/B;AACF,QAAO;EAAE,GAAG;EAAgB,GAAG;EAAO;EAAQ"}
@@ -1,5 +1,4 @@
1
- import { ComponentCreate, ComponentUpdate } from "../generated/mapi/_internal.gen.cjs";
2
- import { Block, BlockSchema, BlockSchemaInput, NestableBlock, RootBlock, SchemaArrayToRecord } from "../generated/types/block.cjs";
1
+ import { Block, BlockFields, NestableBlock, RootBlock } from "../generated/types/block.cjs";
3
2
  import { Prettify } from "../utils/prettify.cjs";
4
3
 
5
4
  //#region src/helpers/define-block.d.ts
@@ -9,54 +8,38 @@ declare const BLOCK_DEFAULTS: {
9
8
  updated_at: string;
10
9
  is_root: boolean;
11
10
  is_nestable: boolean;
12
- component_group_uuid: null;
13
11
  };
14
12
  /** Fields that have safe defaults and may be omitted from block input. */
15
13
  type BlockOptional = keyof typeof BLOCK_DEFAULTS;
16
- type BlockInput<TName extends string = string, TInputSchema extends BlockSchemaInput = BlockSchemaInput, TIsRoot extends boolean = false, TIsNestable extends boolean = true, TComponentGroupUuid extends string | null = null> = Prettify<Omit<Block, 'name' | 'schema' | 'is_root' | 'is_nestable' | 'component_group_uuid' | BlockOptional> & {
14
+ type BlockInput<TName extends string = string, TFields extends BlockFields = BlockFields, TIsRoot extends boolean = false, TIsNestable extends boolean = true> = Prettify<Omit<Block, 'name' | 'fields' | 'is_root' | 'is_nestable' | BlockOptional> & {
17
15
  name: TName;
18
- schema: TInputSchema;
16
+ fields: TFields;
19
17
  is_root?: TIsRoot;
20
18
  is_nestable?: TIsNestable;
21
- component_group_uuid?: TComponentGroupUuid;
22
- } & Partial<Pick<Block, Exclude<BlockOptional, 'is_root' | 'is_nestable' | 'component_group_uuid'>>>>;
23
- type DefinedBlock<TName extends string, TBlockSchema, TIsRoot extends boolean, TIsNestable extends boolean, TComponentGroupUuid extends string | null> = Prettify<Omit<Block, 'name' | 'schema' | 'is_root' | 'is_nestable' | 'component_group_uuid'> & {
19
+ } & Partial<Pick<Block, Exclude<BlockOptional, 'is_root' | 'is_nestable'>>>>;
20
+ type DefinedBlock<TName extends string, TFields extends BlockFields, TIsRoot extends boolean, TIsNestable extends boolean> = Prettify<Omit<Block, 'name' | 'fields' | 'is_root' | 'is_nestable'> & {
24
21
  name: TName;
25
- schema: TBlockSchema;
22
+ fields: TFields;
26
23
  is_root: TIsRoot;
27
24
  is_nestable: TIsNestable;
28
- component_group_uuid: TComponentGroupUuid;
29
25
  }>;
30
26
  /**
31
- * Returns a {@link Block} with object-shape `schema` (matches the MAPI wire
32
- * shape). The user-facing input is an ordered array of `defineField` calls;
33
- * the array index becomes the field's `pos` in the returned map. Throws if
34
- * two fields share the same `name`.
27
+ * Returns a {@link Block} content-shape definition. The user-facing input is an
28
+ * ordered array of `defineField` calls under `fields`; the array index becomes
29
+ * each field's `pos`. A thin, strongly-typed helper — it does not map to the
30
+ * MAPI wire shape (the CLI owns the DSL→wire mapping). Throws only on duplicate
31
+ * field names (a programming error).
35
32
  *
36
33
  * @example
37
34
  * const pageBlock = defineBlock({
38
35
  * name: 'page',
39
36
  * is_root: true,
40
- * schema: [
37
+ * fields: [
41
38
  * defineField('headline', { type: 'text', required: true }),
42
39
  * ],
43
40
  * });
44
41
  */
45
- declare function defineBlock<TName extends string, const TInputSchema extends BlockSchemaInput, TIsRoot extends boolean = false, TIsNestable extends boolean = true, TComponentGroupUuid extends string | null = null>(block: BlockInput<TName, TInputSchema, TIsRoot, TIsNestable, TComponentGroupUuid>): DefinedBlock<TName, SchemaArrayToRecord<TInputSchema>, TIsRoot, TIsNestable, TComponentGroupUuid>;
46
- /**
47
- * Defines a block creation payload for the MAPI.
48
- *
49
- * @example
50
- * const payload = defineBlockCreate({ name: 'page', schema: { ... } });
51
- */
52
- declare const defineBlockCreate: (block: ComponentCreate) => ComponentCreate;
53
- /**
54
- * Defines a block update payload for the MAPI.
55
- *
56
- * @example
57
- * const payload = defineBlockUpdate({ display_name: 'Page' });
58
- */
59
- declare const defineBlockUpdate: (block: ComponentUpdate) => ComponentUpdate;
42
+ declare function defineBlock<TName extends string, const TFields extends BlockFields, TIsRoot extends boolean = false, TIsNestable extends boolean = true>(block: BlockInput<TName, TFields, TIsRoot, TIsNestable>): DefinedBlock<TName, TFields, TIsRoot, TIsNestable>;
60
43
  //#endregion
61
- export { defineBlock, defineBlockCreate, defineBlockUpdate };
44
+ export { defineBlock };
62
45
  //# sourceMappingURL=define-block.d.cts.map
@@ -1,5 +1,4 @@
1
- import { ComponentCreate, ComponentUpdate } from "../generated/mapi/_internal.gen.mjs";
2
- import { Block, BlockSchema, BlockSchemaInput, NestableBlock, RootBlock, SchemaArrayToRecord } from "../generated/types/block.mjs";
1
+ import { Block, BlockFields, NestableBlock, RootBlock } from "../generated/types/block.mjs";
3
2
  import { Prettify } from "../utils/prettify.mjs";
4
3
 
5
4
  //#region src/helpers/define-block.d.ts
@@ -9,54 +8,38 @@ declare const BLOCK_DEFAULTS: {
9
8
  updated_at: string;
10
9
  is_root: boolean;
11
10
  is_nestable: boolean;
12
- component_group_uuid: null;
13
11
  };
14
12
  /** Fields that have safe defaults and may be omitted from block input. */
15
13
  type BlockOptional = keyof typeof BLOCK_DEFAULTS;
16
- type BlockInput<TName extends string = string, TInputSchema extends BlockSchemaInput = BlockSchemaInput, TIsRoot extends boolean = false, TIsNestable extends boolean = true, TComponentGroupUuid extends string | null = null> = Prettify<Omit<Block, 'name' | 'schema' | 'is_root' | 'is_nestable' | 'component_group_uuid' | BlockOptional> & {
14
+ type BlockInput<TName extends string = string, TFields extends BlockFields = BlockFields, TIsRoot extends boolean = false, TIsNestable extends boolean = true> = Prettify<Omit<Block, 'name' | 'fields' | 'is_root' | 'is_nestable' | BlockOptional> & {
17
15
  name: TName;
18
- schema: TInputSchema;
16
+ fields: TFields;
19
17
  is_root?: TIsRoot;
20
18
  is_nestable?: TIsNestable;
21
- component_group_uuid?: TComponentGroupUuid;
22
- } & Partial<Pick<Block, Exclude<BlockOptional, 'is_root' | 'is_nestable' | 'component_group_uuid'>>>>;
23
- type DefinedBlock<TName extends string, TBlockSchema, TIsRoot extends boolean, TIsNestable extends boolean, TComponentGroupUuid extends string | null> = Prettify<Omit<Block, 'name' | 'schema' | 'is_root' | 'is_nestable' | 'component_group_uuid'> & {
19
+ } & Partial<Pick<Block, Exclude<BlockOptional, 'is_root' | 'is_nestable'>>>>;
20
+ type DefinedBlock<TName extends string, TFields extends BlockFields, TIsRoot extends boolean, TIsNestable extends boolean> = Prettify<Omit<Block, 'name' | 'fields' | 'is_root' | 'is_nestable'> & {
24
21
  name: TName;
25
- schema: TBlockSchema;
22
+ fields: TFields;
26
23
  is_root: TIsRoot;
27
24
  is_nestable: TIsNestable;
28
- component_group_uuid: TComponentGroupUuid;
29
25
  }>;
30
26
  /**
31
- * Returns a {@link Block} with object-shape `schema` (matches the MAPI wire
32
- * shape). The user-facing input is an ordered array of `defineField` calls;
33
- * the array index becomes the field's `pos` in the returned map. Throws if
34
- * two fields share the same `name`.
27
+ * Returns a {@link Block} content-shape definition. The user-facing input is an
28
+ * ordered array of `defineField` calls under `fields`; the array index becomes
29
+ * each field's `pos`. A thin, strongly-typed helper — it does not map to the
30
+ * MAPI wire shape (the CLI owns the DSL→wire mapping). Throws only on duplicate
31
+ * field names (a programming error).
35
32
  *
36
33
  * @example
37
34
  * const pageBlock = defineBlock({
38
35
  * name: 'page',
39
36
  * is_root: true,
40
- * schema: [
37
+ * fields: [
41
38
  * defineField('headline', { type: 'text', required: true }),
42
39
  * ],
43
40
  * });
44
41
  */
45
- declare function defineBlock<TName extends string, const TInputSchema extends BlockSchemaInput, TIsRoot extends boolean = false, TIsNestable extends boolean = true, TComponentGroupUuid extends string | null = null>(block: BlockInput<TName, TInputSchema, TIsRoot, TIsNestable, TComponentGroupUuid>): DefinedBlock<TName, SchemaArrayToRecord<TInputSchema>, TIsRoot, TIsNestable, TComponentGroupUuid>;
46
- /**
47
- * Defines a block creation payload for the MAPI.
48
- *
49
- * @example
50
- * const payload = defineBlockCreate({ name: 'page', schema: { ... } });
51
- */
52
- declare const defineBlockCreate: (block: ComponentCreate) => ComponentCreate;
53
- /**
54
- * Defines a block update payload for the MAPI.
55
- *
56
- * @example
57
- * const payload = defineBlockUpdate({ display_name: 'Page' });
58
- */
59
- declare const defineBlockUpdate: (block: ComponentUpdate) => ComponentUpdate;
42
+ declare function defineBlock<TName extends string, const TFields extends BlockFields, TIsRoot extends boolean = false, TIsNestable extends boolean = true>(block: BlockInput<TName, TFields, TIsRoot, TIsNestable>): DefinedBlock<TName, TFields, TIsRoot, TIsNestable>;
60
43
  //#endregion
61
- export { defineBlock, defineBlockCreate, defineBlockUpdate };
44
+ export { defineBlock };
62
45
  //# sourceMappingURL=define-block.d.mts.map
@@ -4,45 +4,29 @@ const BLOCK_DEFAULTS = {
4
4
  created_at: "",
5
5
  updated_at: "",
6
6
  is_root: false,
7
- is_nestable: true,
8
- component_group_uuid: null
7
+ is_nestable: true
9
8
  };
10
9
  function defineBlock(block) {
11
- const inputSchema = Array.isArray(block?.schema) ? block.schema : [];
10
+ const inputFields = Array.isArray(block?.fields) ? block.fields : [];
12
11
  const seen = /* @__PURE__ */ new Set();
13
- const schemaRecord = {};
14
- inputSchema.forEach((field, index) => {
12
+ const fields = inputFields.map((field, index) => {
15
13
  const name = field?.name;
16
- if (typeof name !== "string") return;
17
- if (seen.has(name)) throw new Error(`defineBlock: duplicate field name "${name}" in block "${block?.name ?? ""}"`);
18
- seen.add(name);
19
- const { name: _name, ...rest } = field;
20
- schemaRecord[name] = {
21
- ...rest,
14
+ if (typeof name === "string") {
15
+ if (seen.has(name)) throw new Error(`defineBlock: duplicate field name "${name}" in block "${block?.name ?? ""}"`);
16
+ seen.add(name);
17
+ }
18
+ return {
19
+ ...field,
22
20
  pos: index
23
21
  };
24
22
  });
25
23
  return {
26
24
  ...BLOCK_DEFAULTS,
27
25
  ...block,
28
- schema: schemaRecord
26
+ fields
29
27
  };
30
28
  }
31
- /**
32
- * Defines a block creation payload for the MAPI.
33
- *
34
- * @example
35
- * const payload = defineBlockCreate({ name: 'page', schema: { ... } });
36
- */
37
- const defineBlockCreate = (block) => block;
38
- /**
39
- * Defines a block update payload for the MAPI.
40
- *
41
- * @example
42
- * const payload = defineBlockUpdate({ display_name: 'Page' });
43
- */
44
- const defineBlockUpdate = (block) => block;
45
29
 
46
30
  //#endregion
47
- export { defineBlock, defineBlockCreate, defineBlockUpdate };
31
+ export { defineBlock };
48
32
  //# sourceMappingURL=define-block.mjs.map