@storyblok/schema 0.1.0-alpha.0 → 0.1.0-alpha.1
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/_virtual/_rolldown/runtime.cjs +29 -0
- package/dist/generated/capi/types.gen.d.cts +1 -126
- package/dist/generated/capi/types.gen.d.mts +1 -126
- package/dist/generated/mapi/_internal.gen.d.cts +1 -171
- package/dist/generated/mapi/_internal.gen.d.mts +1 -171
- package/dist/generated/overlay/zod.gen.cjs +409 -0
- package/dist/generated/overlay/zod.gen.cjs.map +1 -0
- package/dist/generated/overlay/zod.gen.mjs +403 -0
- package/dist/generated/overlay/zod.gen.mjs.map +1 -0
- package/dist/generated/types/block.d.cts +27 -14
- package/dist/generated/types/block.d.mts +27 -14
- package/dist/generated/types/field.d.cts +28 -13
- package/dist/generated/types/field.d.mts +28 -13
- package/dist/generated/types/mapi-story.d.cts +5 -9
- package/dist/generated/types/mapi-story.d.mts +5 -9
- package/dist/helpers/define-block.cjs +10 -28
- package/dist/helpers/define-block.cjs.map +1 -1
- package/dist/helpers/define-block.d.cts +14 -31
- package/dist/helpers/define-block.d.mts +14 -31
- package/dist/helpers/define-block.mjs +11 -27
- package/dist/helpers/define-block.mjs.map +1 -1
- package/dist/helpers/define-datasource.cjs +0 -16
- package/dist/helpers/define-datasource.cjs.map +1 -1
- package/dist/helpers/define-datasource.d.cts +14 -23
- package/dist/helpers/define-datasource.d.mts +14 -23
- package/dist/helpers/define-datasource.mjs +1 -15
- package/dist/helpers/define-datasource.mjs.map +1 -1
- package/dist/helpers/define-field.cjs +11 -11
- package/dist/helpers/define-field.cjs.map +1 -1
- package/dist/helpers/define-field.d.cts +46 -85
- package/dist/helpers/define-field.d.mts +46 -85
- package/dist/helpers/define-field.mjs +12 -11
- package/dist/helpers/define-field.mjs.map +1 -1
- package/dist/helpers/schema-type.d.cts +5 -9
- package/dist/helpers/schema-type.d.mts +5 -9
- package/dist/index.cjs +6 -47
- package/dist/index.d.cts +11 -20
- package/dist/index.d.mts +11 -20
- package/dist/index.mjs +6 -15
- package/dist/utils/is-record.cjs +10 -0
- package/dist/utils/is-record.cjs.map +1 -0
- package/dist/utils/is-record.mjs +9 -0
- package/dist/utils/is-record.mjs.map +1 -0
- package/dist/validators/create-story-validator.cjs +37 -0
- package/dist/validators/create-story-validator.cjs.map +1 -0
- package/dist/validators/create-story-validator.d.cts +18 -0
- package/dist/validators/create-story-validator.d.mts +18 -0
- package/dist/validators/create-story-validator.mjs +37 -0
- package/dist/validators/create-story-validator.mjs.map +1 -0
- package/dist/validators/internal-schemas.cjs +1 -0
- package/dist/validators/internal-schemas.mjs +3 -0
- package/dist/validators/shapes.cjs +12 -0
- package/dist/validators/shapes.cjs.map +1 -0
- package/dist/validators/shapes.d.cts +62 -0
- package/dist/validators/shapes.d.mts +62 -0
- package/dist/validators/shapes.mjs +12 -0
- package/dist/validators/shapes.mjs.map +1 -0
- package/dist/validators/types.d.cts +25 -0
- package/dist/validators/types.d.mts +25 -0
- package/dist/validators/validate-schema.cjs +125 -0
- package/dist/validators/validate-schema.cjs.map +1 -0
- package/dist/validators/validate-schema.d.cts +18 -0
- package/dist/validators/validate-schema.d.mts +18 -0
- package/dist/validators/validate-schema.mjs +125 -0
- package/dist/validators/validate-schema.mjs.map +1 -0
- package/dist/validators/validate-story.cjs +257 -0
- package/dist/validators/validate-story.cjs.map +1 -0
- package/dist/validators/validate-story.d.cts +17 -0
- package/dist/validators/validate-story.d.mts +17 -0
- package/dist/validators/validate-story.mjs +257 -0
- package/dist/validators/validate-story.mjs.map +1 -0
- package/package.json +5 -1
- package/dist/generated/mapi/types.gen.d.cts +0 -1272
- package/dist/generated/mapi/types.gen.d.mts +0 -1272
- package/dist/helpers/create-story-helpers.cjs +0 -42
- package/dist/helpers/create-story-helpers.cjs.map +0 -1
- package/dist/helpers/create-story-helpers.d.cts +0 -50
- package/dist/helpers/create-story-helpers.d.mts +0 -50
- package/dist/helpers/create-story-helpers.mjs +0 -42
- package/dist/helpers/create-story-helpers.mjs.map +0 -1
- package/dist/helpers/define-asset-folder.cjs +0 -46
- package/dist/helpers/define-asset-folder.cjs.map +0 -1
- package/dist/helpers/define-asset-folder.d.cts +0 -33
- package/dist/helpers/define-asset-folder.d.mts +0 -33
- package/dist/helpers/define-asset-folder.mjs +0 -43
- package/dist/helpers/define-asset-folder.mjs.map +0 -1
- package/dist/helpers/define-asset.cjs +0 -60
- package/dist/helpers/define-asset.cjs.map +0 -1
- package/dist/helpers/define-asset.d.cts +0 -32
- package/dist/helpers/define-asset.d.mts +0 -32
- package/dist/helpers/define-asset.mjs +0 -57
- package/dist/helpers/define-asset.mjs.map +0 -1
- package/dist/helpers/define-block-folder.cjs +0 -44
- package/dist/helpers/define-block-folder.cjs.map +0 -1
- package/dist/helpers/define-block-folder.d.cts +0 -34
- package/dist/helpers/define-block-folder.d.mts +0 -34
- package/dist/helpers/define-block-folder.mjs +0 -41
- package/dist/helpers/define-block-folder.mjs.map +0 -1
- package/dist/helpers/define-datasource-entry.cjs +0 -47
- package/dist/helpers/define-datasource-entry.cjs.map +0 -1
- package/dist/helpers/define-datasource-entry.d.cts +0 -49
- package/dist/helpers/define-datasource-entry.d.mts +0 -49
- package/dist/helpers/define-datasource-entry.mjs +0 -43
- package/dist/helpers/define-datasource-entry.mjs.map +0 -1
- package/dist/helpers/define-internal-tag.cjs +0 -41
- package/dist/helpers/define-internal-tag.cjs.map +0 -1
- package/dist/helpers/define-internal-tag.d.cts +0 -34
- package/dist/helpers/define-internal-tag.d.mts +0 -34
- package/dist/helpers/define-internal-tag.mjs +0 -38
- package/dist/helpers/define-internal-tag.mjs.map +0 -1
- package/dist/helpers/define-link.cjs +0 -23
- package/dist/helpers/define-link.cjs.map +0 -1
- package/dist/helpers/define-link.d.cts +0 -32
- package/dist/helpers/define-link.d.mts +0 -32
- package/dist/helpers/define-link.mjs +0 -22
- package/dist/helpers/define-link.mjs.map +0 -1
- package/dist/helpers/define-preset.cjs +0 -44
- package/dist/helpers/define-preset.cjs.map +0 -1
- package/dist/helpers/define-preset.d.cts +0 -35
- package/dist/helpers/define-preset.d.mts +0 -35
- package/dist/helpers/define-preset.mjs +0 -41
- package/dist/helpers/define-preset.mjs.map +0 -1
- package/dist/helpers/define-space.cjs +0 -47
- package/dist/helpers/define-space.cjs.map +0 -1
- package/dist/helpers/define-space.d.cts +0 -31
- package/dist/helpers/define-space.d.mts +0 -31
- package/dist/helpers/define-space.mjs +0 -44
- package/dist/helpers/define-space.mjs.map +0 -1
- package/dist/helpers/define-story.cjs +0 -122
- package/dist/helpers/define-story.cjs.map +0 -1
- package/dist/helpers/define-story.d.cts +0 -135
- package/dist/helpers/define-story.d.mts +0 -135
- package/dist/helpers/define-story.mjs +0 -118
- package/dist/helpers/define-story.mjs.map +0 -1
- package/dist/helpers/define-tag.cjs +0 -13
- package/dist/helpers/define-tag.cjs.map +0 -1
- package/dist/helpers/define-tag.d.cts +0 -23
- package/dist/helpers/define-tag.d.mts +0 -23
- package/dist/helpers/define-tag.mjs +0 -12
- package/dist/helpers/define-tag.mjs.map +0 -1
- package/dist/helpers/define-user.cjs +0 -50
- package/dist/helpers/define-user.cjs.map +0 -1
- package/dist/helpers/define-user.d.cts +0 -26
- package/dist/helpers/define-user.d.mts +0 -26
- package/dist/helpers/define-user.mjs +0 -48
- package/dist/helpers/define-user.mjs.map +0 -1
|
@@ -11,21 +11,7 @@ function defineDatasource(datasource) {
|
|
|
11
11
|
...datasource
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
|
-
/**
|
|
15
|
-
* Defines a datasource creation payload for the MAPI.
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* const payload = defineDatasourceCreate({ name: 'Colors', slug: 'colors' });
|
|
19
|
-
*/
|
|
20
|
-
const defineDatasourceCreate = (datasource) => datasource;
|
|
21
|
-
/**
|
|
22
|
-
* Defines a datasource update payload for the MAPI.
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* const payload = defineDatasourceUpdate({ name: 'Updated Colors' });
|
|
26
|
-
*/
|
|
27
|
-
const defineDatasourceUpdate = (datasource) => datasource;
|
|
28
14
|
|
|
29
15
|
//#endregion
|
|
30
|
-
export { defineDatasource
|
|
16
|
+
export { defineDatasource };
|
|
31
17
|
//# sourceMappingURL=define-datasource.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-datasource.mjs","names":[],"sources":["../../src/helpers/define-datasource.ts"],"sourcesContent":["import type { Datasource } from '../generated/capi/types.gen';\nimport type {
|
|
1
|
+
{"version":3,"file":"define-datasource.mjs","names":[],"sources":["../../src/helpers/define-datasource.ts"],"sourcesContent":["import type { Datasource as DatasourceGenerated } from '../generated/capi/types.gen';\nimport type { Override } from '../generated/types/_utils';\nimport type { Prettify } from '../utils/prettify';\n\nconst DATASOURCE_DEFAULTS = {\n id: 1,\n created_at: '',\n updated_at: '',\n dimensions: [],\n};\n\n/**\n * A Storyblok datasource content shape. Carries the datasource definition only\n * (`name`, `slug`, dimensions). Entry values are content authored by editors,\n * not part of the schema, so they are neither modelled nor pushed here.\n */\nexport type Datasource = Override<DatasourceGenerated, { slug: string }>;\n\n/** Fields that have safe defaults and may be omitted from datasource input. */\ntype DatasourceOptional = keyof typeof DATASOURCE_DEFAULTS;\n\ntype DatasourceInput = Prettify<Omit<Datasource, DatasourceOptional> & Partial<Pick<Datasource, DatasourceOptional>>>;\n\n/**\n * Returns a {@link Datasource} content-shape definition. A thin, strongly-typed\n * helper — it does not validate or throw.\n *\n * @example\n * const colors = defineDatasource({ name: 'Colors', slug: 'colors' });\n */\nexport function defineDatasource(datasource: DatasourceInput): Datasource;\nexport function defineDatasource(datasource: any) {\n return { ...DATASOURCE_DEFAULTS, ...datasource };\n}\n"],"mappings":";AAIA,MAAM,sBAAsB;CAC1B,IAAI;CACJ,YAAY;CACZ,YAAY;CACZ,YAAY,EAAE;CACf;AAsBD,SAAgB,iBAAiB,YAAiB;AAChD,QAAO;EAAE,GAAG;EAAqB,GAAG;EAAY"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
+
const require_is_record = require('../utils/is-record.cjs');
|
|
1
2
|
|
|
2
3
|
//#region src/helpers/define-field.ts
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
});
|
|
4
|
+
function defineField(name, field) {
|
|
5
|
+
const { allow, datasource, ...rest } = field;
|
|
6
|
+
const normalized = {
|
|
7
|
+
...rest,
|
|
8
|
+
name
|
|
9
|
+
};
|
|
10
|
+
if (allow !== void 0) normalized.allow = (Array.isArray(allow) ? allow : [allow]).map((ref) => typeof ref === "string" ? ref : require_is_record.isRecord(ref) ? ref.name : void 0);
|
|
11
|
+
if (datasource !== void 0) normalized.datasource = typeof datasource === "string" ? datasource : require_is_record.isRecord(datasource) ? datasource.slug : void 0;
|
|
12
|
+
return normalized;
|
|
13
|
+
}
|
|
14
14
|
|
|
15
15
|
//#endregion
|
|
16
16
|
exports.defineField = defineField;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-field.cjs","names":[],"sources":["../../src/helpers/define-field.ts"],"sourcesContent":["import type {\n AssetFieldValue,\n Field,\n MultilinkFieldValue,\n PluginFieldValue,\n RichtextFieldValue,\n TableFieldValue,\n} from '../generated/types/field';\nimport type {
|
|
1
|
+
{"version":3,"file":"define-field.cjs","names":["isRecord"],"sources":["../../src/helpers/define-field.ts"],"sourcesContent":["import type {\n AssetFieldValue,\n BlockContent,\n BlockContentInput,\n BlocksFieldValue,\n Field,\n FieldType,\n FieldValue,\n FieldValueInput,\n MultilinkFieldValue,\n PluginFieldValue,\n RichtextFieldValue,\n TableFieldValue,\n} from '../generated/types/field';\nimport type { Prettify } from '../utils/prettify';\nimport { isRecord } from '../utils/is-record';\n\nexport type {\n AssetFieldValue,\n BlockContent,\n BlockContentInput,\n BlocksFieldValue,\n Field,\n FieldType,\n FieldValue,\n FieldValueInput,\n MultilinkFieldValue,\n PluginFieldValue,\n RichtextFieldValue,\n TableFieldValue,\n};\n\n/** A block reference for `allow`: a defined block object or its name. */\ntype AllowRef = string | { name: string };\n/** A datasource reference for `datasource`: a defined datasource object or its slug. */\ntype DatasourceRef = string | { slug: string };\n\ntype NameOf<T> = T extends string ? T : T extends { name: infer N extends string } ? N : never;\ntype SlugOf<T> = T extends string ? T : T extends { slug: infer S extends string } ? S : never;\n\n/** Normalizes an `allow` input (ref, name, or array thereof) to a tuple of block-name strings. */\ntype NormalizeAllow<T> = T extends readonly any[]\n ? { [I in keyof T]: NameOf<T[I]> }\n : readonly [NameOf<T>];\n\n/**\n * Field config accepted by {@link defineField}: the content-shape field plus the\n * DSL reference keys. `allow` replaces the wire `component_whitelist`; `datasource`\n * holds the datasource ref/slug (the wire `source` selector still passes through).\n */\nexport type FieldInput = Field & {\n allow?: AllowRef | readonly AllowRef[];\n datasource?: DatasourceRef;\n required?: boolean;\n};\n\n/** Result of {@link defineField}: the field stamped with `name`, with refs normalized to strings. */\nexport type DefinedField<TName extends string, TField extends FieldInput> = Prettify<\n Omit<TField, 'allow' | 'datasource' | 'name'>\n & { name: TName }\n & (TField extends { allow: infer A } ? { allow: NormalizeAllow<A> } : unknown)\n & (TField extends { datasource: infer D } ? { datasource: SlugOf<D> } : unknown)\n>;\n\n/**\n * Returns a {@link Field} stamped with the given `name`, normalizing reference\n * keys to strings so everything downstream sees plain names/slugs. A thin,\n * strongly-typed identity helper — it does not validate or throw.\n *\n * Use inside a {@link defineBlock} `fields` array — `pos` is injected from the\n * array index by `defineBlock`.\n *\n * @example\n * defineField('headline', { type: 'text', max_length: 100, required: true });\n * defineField('body', { type: 'bloks', allow: [heroBlock, 'teaser'] });\n * defineField('theme', { type: 'option', source: 'internal', datasource: colors });\n */\nexport function defineField<\n const TName extends string,\n const TField extends FieldInput,\n>(name: TName, field: TField): DefinedField<TName, TField>;\nexport function defineField(name: string, field: Record<string, unknown>): Record<string, unknown> {\n const { allow, datasource, ...rest } = field;\n const normalized: Record<string, unknown> = { ...rest, name };\n if (allow !== undefined) {\n const refs = Array.isArray(allow) ? allow : [allow];\n normalized.allow = refs.map(ref => (typeof ref === 'string' ? ref : isRecord(ref) ? ref.name : undefined));\n }\n if (datasource !== undefined) {\n normalized.datasource = typeof datasource === 'string' ? datasource : isRecord(datasource) ? datasource.slug : undefined;\n }\n return normalized;\n}\n"],"mappings":";;;AAiFA,SAAgB,YAAY,MAAc,OAAyD;CACjG,MAAM,EAAE,OAAO,YAAY,GAAG,SAAS;CACvC,MAAM,aAAsC;EAAE,GAAG;EAAM;EAAM;AAC7D,KAAI,UAAU,OAEZ,YAAW,SADE,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM,EAC3B,KAAI,QAAQ,OAAO,QAAQ,WAAW,MAAMA,2BAAS,IAAI,GAAG,IAAI,OAAO,OAAW;AAE5G,KAAI,eAAe,OACjB,YAAW,aAAa,OAAO,eAAe,WAAW,aAAaA,2BAAS,WAAW,GAAG,WAAW,OAAO;AAEjH,QAAO"}
|
|
@@ -1,99 +1,60 @@
|
|
|
1
1
|
import { AssetFieldValue, Field, MultilinkFieldValue, PluginFieldValue, RichtextFieldValue, TableFieldValue } from "../generated/overlay/_internal.gen.cjs";
|
|
2
|
-
import {
|
|
2
|
+
import { BlockContent, BlockContentInput, BlocksFieldValue, FieldType, FieldValue, FieldValueInput } from "../generated/types/field.cjs";
|
|
3
3
|
import { Prettify } from "../utils/prettify.cjs";
|
|
4
4
|
|
|
5
5
|
//#region src/helpers/define-field.d.ts
|
|
6
|
-
/**
|
|
7
|
-
type
|
|
8
|
-
|
|
9
|
-
component: string;
|
|
10
|
-
_editable?: string | undefined;
|
|
11
|
-
} & {
|
|
12
|
-
[key: string]: string | number | boolean | Array<string | AssetFieldValue | BlokContentLoose> | AssetFieldValue | MultilinkFieldValue | TableFieldValue | RichtextFieldValue | PluginFieldValue | undefined;
|
|
6
|
+
/** A block reference for `allow`: a defined block object or its name. */
|
|
7
|
+
type AllowRef = string | {
|
|
8
|
+
name: string;
|
|
13
9
|
};
|
|
14
|
-
/**
|
|
15
|
-
type
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* instead, which omits `_uid` since Storyblok generates it automatically.
|
|
27
|
-
*/
|
|
28
|
-
type BlockContent<TBlock extends Block = Block, TBlocks = false> = TBlock extends any ? {
|
|
29
|
-
_uid: string;
|
|
30
|
-
component: TBlock['name'];
|
|
31
|
-
} & { [K in RequiredFieldKeys<TBlock['schema']>]: FieldValue<NonNullable<TBlock['schema'][K]>, TBlocks> } & { [K in OptionalFieldKeys<TBlock['schema']>]?: FieldValue<NonNullable<TBlock['schema'][K]>, TBlocks> | null } : never;
|
|
32
|
-
/**
|
|
33
|
-
* Input variant of {@link BlockContent} for write operations (creating/updating
|
|
34
|
-
* stories via the MAPI). `_uid` is optional — Storyblok generates it
|
|
35
|
-
* automatically when omitted. Nested bloks fields also use this input variant
|
|
36
|
-
* so that deeply nested blocks do not require `_uid` either.
|
|
37
|
-
*/
|
|
38
|
-
type BlockContentInput<TBlock extends Block = Block, TBlocks = false> = TBlock extends any ? {
|
|
39
|
-
_uid?: string;
|
|
40
|
-
component: TBlock['name'];
|
|
41
|
-
} & { [K in RequiredFieldKeys<TBlock['schema']>]: FieldValueInput<NonNullable<TBlock['schema'][K]>, TBlocks> } & { [K in OptionalFieldKeys<TBlock['schema']>]?: FieldValueInput<NonNullable<TBlock['schema'][K]>, TBlocks> | null } : never;
|
|
42
|
-
type BlocksFieldValue<TBlock extends Block = Block, TBlocks = false> = BlockContent<TBlock, TBlocks>[];
|
|
43
|
-
/** Union of all valid Storyblok field type discriminants (e.g., `text`, `bloks`). */
|
|
44
|
-
type FieldType = Field['type'];
|
|
45
|
-
/** Maps each field type discriminant to its runtime content value type. */
|
|
46
|
-
interface FieldTypeValueMap {
|
|
47
|
-
text: string;
|
|
48
|
-
textarea: string;
|
|
49
|
-
richtext: RichtextFieldValue;
|
|
50
|
-
markdown: string;
|
|
51
|
-
number: number;
|
|
52
|
-
datetime: string;
|
|
53
|
-
boolean: boolean;
|
|
54
|
-
option: string;
|
|
55
|
-
options: string[];
|
|
56
|
-
asset: AssetFieldValue;
|
|
57
|
-
multiasset: AssetFieldValue[];
|
|
58
|
-
multilink: MultilinkFieldValue;
|
|
59
|
-
bloks: BlockContent[];
|
|
60
|
-
table: TableFieldValue;
|
|
61
|
-
section: never;
|
|
62
|
-
tab: never;
|
|
63
|
-
custom: PluginFieldValue;
|
|
64
|
-
}
|
|
10
|
+
/** A datasource reference for `datasource`: a defined datasource object or its slug. */
|
|
11
|
+
type DatasourceRef = string | {
|
|
12
|
+
slug: string;
|
|
13
|
+
};
|
|
14
|
+
type NameOf<T> = T extends string ? T : T extends {
|
|
15
|
+
name: infer N extends string;
|
|
16
|
+
} ? N : never;
|
|
17
|
+
type SlugOf<T> = T extends string ? T : T extends {
|
|
18
|
+
slug: infer S extends string;
|
|
19
|
+
} ? S : never;
|
|
20
|
+
/** Normalizes an `allow` input (ref, name, or array thereof) to a tuple of block-name strings. */
|
|
21
|
+
type NormalizeAllow<T> = T extends readonly any[] ? { [I in keyof T]: NameOf<T[I]> } : readonly [NameOf<T>];
|
|
65
22
|
/**
|
|
66
|
-
*
|
|
67
|
-
* `
|
|
23
|
+
* Field config accepted by {@link defineField}: the content-shape field plus the
|
|
24
|
+
* DSL reference keys. `allow` replaces the wire `component_whitelist`; `datasource`
|
|
25
|
+
* holds the datasource ref/slug (the wire `source` selector still passes through).
|
|
68
26
|
*/
|
|
69
|
-
type
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
} ? [TBlocks] extends [never] ? BlokContentLoose[] : [TBlocks] extends [Block] ? BlockContentInput<ApplyWhitelist<TField, TBlocks>, TBlocks>[] : BlokContentLoose[] : FieldTypeValueMap[TField['type']]>;
|
|
27
|
+
type FieldInput = Field & {
|
|
28
|
+
allow?: AllowRef | readonly AllowRef[];
|
|
29
|
+
datasource?: DatasourceRef;
|
|
30
|
+
required?: boolean;
|
|
31
|
+
};
|
|
32
|
+
/** Result of {@link defineField}: the field stamped with `name`, with refs normalized to strings. */
|
|
33
|
+
type DefinedField<TName extends string, TField extends FieldInput> = Prettify<Omit<TField, 'allow' | 'datasource' | 'name'> & {
|
|
34
|
+
name: TName;
|
|
35
|
+
} & (TField extends {
|
|
36
|
+
allow: infer A;
|
|
37
|
+
} ? {
|
|
38
|
+
allow: NormalizeAllow<A>;
|
|
39
|
+
} : unknown) & (TField extends {
|
|
40
|
+
datasource: infer D;
|
|
41
|
+
} ? {
|
|
42
|
+
datasource: SlugOf<D>;
|
|
43
|
+
} : unknown)>;
|
|
87
44
|
/**
|
|
88
|
-
* Returns a {@link Field} stamped with the given `name
|
|
89
|
-
*
|
|
45
|
+
* Returns a {@link Field} stamped with the given `name`, normalizing reference
|
|
46
|
+
* keys to strings so everything downstream sees plain names/slugs. A thin,
|
|
47
|
+
* strongly-typed identity helper — it does not validate or throw.
|
|
48
|
+
*
|
|
49
|
+
* Use inside a {@link defineBlock} `fields` array — `pos` is injected from the
|
|
50
|
+
* array index by `defineBlock`.
|
|
90
51
|
*
|
|
91
52
|
* @example
|
|
92
53
|
* defineField('headline', { type: 'text', max_length: 100, required: true });
|
|
54
|
+
* defineField('body', { type: 'bloks', allow: [heroBlock, 'teaser'] });
|
|
55
|
+
* defineField('theme', { type: 'option', source: 'internal', datasource: colors });
|
|
93
56
|
*/
|
|
94
|
-
declare
|
|
95
|
-
name: TName;
|
|
96
|
-
};
|
|
57
|
+
declare function defineField<const TName extends string, const TField extends FieldInput>(name: TName, field: TField): DefinedField<TName, TField>;
|
|
97
58
|
//#endregion
|
|
98
|
-
export {
|
|
59
|
+
export { DefinedField, FieldInput, defineField };
|
|
99
60
|
//# sourceMappingURL=define-field.d.cts.map
|
|
@@ -1,99 +1,60 @@
|
|
|
1
1
|
import { AssetFieldValue, Field, MultilinkFieldValue, PluginFieldValue, RichtextFieldValue, TableFieldValue } from "../generated/overlay/_internal.gen.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { BlockContent, BlockContentInput, BlocksFieldValue, FieldType, FieldValue, FieldValueInput } from "../generated/types/field.mjs";
|
|
3
3
|
import { Prettify } from "../utils/prettify.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/helpers/define-field.d.ts
|
|
6
|
-
/**
|
|
7
|
-
type
|
|
8
|
-
|
|
9
|
-
component: string;
|
|
10
|
-
_editable?: string | undefined;
|
|
11
|
-
} & {
|
|
12
|
-
[key: string]: string | number | boolean | Array<string | AssetFieldValue | BlokContentLoose> | AssetFieldValue | MultilinkFieldValue | TableFieldValue | RichtextFieldValue | PluginFieldValue | undefined;
|
|
6
|
+
/** A block reference for `allow`: a defined block object or its name. */
|
|
7
|
+
type AllowRef = string | {
|
|
8
|
+
name: string;
|
|
13
9
|
};
|
|
14
|
-
/**
|
|
15
|
-
type
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* instead, which omits `_uid` since Storyblok generates it automatically.
|
|
27
|
-
*/
|
|
28
|
-
type BlockContent<TBlock extends Block = Block, TBlocks = false> = TBlock extends any ? {
|
|
29
|
-
_uid: string;
|
|
30
|
-
component: TBlock['name'];
|
|
31
|
-
} & { [K in RequiredFieldKeys<TBlock['schema']>]: FieldValue<NonNullable<TBlock['schema'][K]>, TBlocks> } & { [K in OptionalFieldKeys<TBlock['schema']>]?: FieldValue<NonNullable<TBlock['schema'][K]>, TBlocks> | null } : never;
|
|
32
|
-
/**
|
|
33
|
-
* Input variant of {@link BlockContent} for write operations (creating/updating
|
|
34
|
-
* stories via the MAPI). `_uid` is optional — Storyblok generates it
|
|
35
|
-
* automatically when omitted. Nested bloks fields also use this input variant
|
|
36
|
-
* so that deeply nested blocks do not require `_uid` either.
|
|
37
|
-
*/
|
|
38
|
-
type BlockContentInput<TBlock extends Block = Block, TBlocks = false> = TBlock extends any ? {
|
|
39
|
-
_uid?: string;
|
|
40
|
-
component: TBlock['name'];
|
|
41
|
-
} & { [K in RequiredFieldKeys<TBlock['schema']>]: FieldValueInput<NonNullable<TBlock['schema'][K]>, TBlocks> } & { [K in OptionalFieldKeys<TBlock['schema']>]?: FieldValueInput<NonNullable<TBlock['schema'][K]>, TBlocks> | null } : never;
|
|
42
|
-
type BlocksFieldValue<TBlock extends Block = Block, TBlocks = false> = BlockContent<TBlock, TBlocks>[];
|
|
43
|
-
/** Union of all valid Storyblok field type discriminants (e.g., `text`, `bloks`). */
|
|
44
|
-
type FieldType = Field['type'];
|
|
45
|
-
/** Maps each field type discriminant to its runtime content value type. */
|
|
46
|
-
interface FieldTypeValueMap {
|
|
47
|
-
text: string;
|
|
48
|
-
textarea: string;
|
|
49
|
-
richtext: RichtextFieldValue;
|
|
50
|
-
markdown: string;
|
|
51
|
-
number: number;
|
|
52
|
-
datetime: string;
|
|
53
|
-
boolean: boolean;
|
|
54
|
-
option: string;
|
|
55
|
-
options: string[];
|
|
56
|
-
asset: AssetFieldValue;
|
|
57
|
-
multiasset: AssetFieldValue[];
|
|
58
|
-
multilink: MultilinkFieldValue;
|
|
59
|
-
bloks: BlockContent[];
|
|
60
|
-
table: TableFieldValue;
|
|
61
|
-
section: never;
|
|
62
|
-
tab: never;
|
|
63
|
-
custom: PluginFieldValue;
|
|
64
|
-
}
|
|
10
|
+
/** A datasource reference for `datasource`: a defined datasource object or its slug. */
|
|
11
|
+
type DatasourceRef = string | {
|
|
12
|
+
slug: string;
|
|
13
|
+
};
|
|
14
|
+
type NameOf<T> = T extends string ? T : T extends {
|
|
15
|
+
name: infer N extends string;
|
|
16
|
+
} ? N : never;
|
|
17
|
+
type SlugOf<T> = T extends string ? T : T extends {
|
|
18
|
+
slug: infer S extends string;
|
|
19
|
+
} ? S : never;
|
|
20
|
+
/** Normalizes an `allow` input (ref, name, or array thereof) to a tuple of block-name strings. */
|
|
21
|
+
type NormalizeAllow<T> = T extends readonly any[] ? { [I in keyof T]: NameOf<T[I]> } : readonly [NameOf<T>];
|
|
65
22
|
/**
|
|
66
|
-
*
|
|
67
|
-
* `
|
|
23
|
+
* Field config accepted by {@link defineField}: the content-shape field plus the
|
|
24
|
+
* DSL reference keys. `allow` replaces the wire `component_whitelist`; `datasource`
|
|
25
|
+
* holds the datasource ref/slug (the wire `source` selector still passes through).
|
|
68
26
|
*/
|
|
69
|
-
type
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
} ? [TBlocks] extends [never] ? BlokContentLoose[] : [TBlocks] extends [Block] ? BlockContentInput<ApplyWhitelist<TField, TBlocks>, TBlocks>[] : BlokContentLoose[] : FieldTypeValueMap[TField['type']]>;
|
|
27
|
+
type FieldInput = Field & {
|
|
28
|
+
allow?: AllowRef | readonly AllowRef[];
|
|
29
|
+
datasource?: DatasourceRef;
|
|
30
|
+
required?: boolean;
|
|
31
|
+
};
|
|
32
|
+
/** Result of {@link defineField}: the field stamped with `name`, with refs normalized to strings. */
|
|
33
|
+
type DefinedField<TName extends string, TField extends FieldInput> = Prettify<Omit<TField, 'allow' | 'datasource' | 'name'> & {
|
|
34
|
+
name: TName;
|
|
35
|
+
} & (TField extends {
|
|
36
|
+
allow: infer A;
|
|
37
|
+
} ? {
|
|
38
|
+
allow: NormalizeAllow<A>;
|
|
39
|
+
} : unknown) & (TField extends {
|
|
40
|
+
datasource: infer D;
|
|
41
|
+
} ? {
|
|
42
|
+
datasource: SlugOf<D>;
|
|
43
|
+
} : unknown)>;
|
|
87
44
|
/**
|
|
88
|
-
* Returns a {@link Field} stamped with the given `name
|
|
89
|
-
*
|
|
45
|
+
* Returns a {@link Field} stamped with the given `name`, normalizing reference
|
|
46
|
+
* keys to strings so everything downstream sees plain names/slugs. A thin,
|
|
47
|
+
* strongly-typed identity helper — it does not validate or throw.
|
|
48
|
+
*
|
|
49
|
+
* Use inside a {@link defineBlock} `fields` array — `pos` is injected from the
|
|
50
|
+
* array index by `defineBlock`.
|
|
90
51
|
*
|
|
91
52
|
* @example
|
|
92
53
|
* defineField('headline', { type: 'text', max_length: 100, required: true });
|
|
54
|
+
* defineField('body', { type: 'bloks', allow: [heroBlock, 'teaser'] });
|
|
55
|
+
* defineField('theme', { type: 'option', source: 'internal', datasource: colors });
|
|
93
56
|
*/
|
|
94
|
-
declare
|
|
95
|
-
name: TName;
|
|
96
|
-
};
|
|
57
|
+
declare function defineField<const TName extends string, const TField extends FieldInput>(name: TName, field: TField): DefinedField<TName, TField>;
|
|
97
58
|
//#endregion
|
|
98
|
-
export {
|
|
59
|
+
export { DefinedField, FieldInput, defineField };
|
|
99
60
|
//# sourceMappingURL=define-field.d.mts.map
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
+
import { isRecord } from "../utils/is-record.mjs";
|
|
2
|
+
|
|
1
3
|
//#region src/helpers/define-field.ts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
});
|
|
4
|
+
function defineField(name, field) {
|
|
5
|
+
const { allow, datasource, ...rest } = field;
|
|
6
|
+
const normalized = {
|
|
7
|
+
...rest,
|
|
8
|
+
name
|
|
9
|
+
};
|
|
10
|
+
if (allow !== void 0) normalized.allow = (Array.isArray(allow) ? allow : [allow]).map((ref) => typeof ref === "string" ? ref : isRecord(ref) ? ref.name : void 0);
|
|
11
|
+
if (datasource !== void 0) normalized.datasource = typeof datasource === "string" ? datasource : isRecord(datasource) ? datasource.slug : void 0;
|
|
12
|
+
return normalized;
|
|
13
|
+
}
|
|
13
14
|
|
|
14
15
|
//#endregion
|
|
15
16
|
export { defineField };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-field.mjs","names":[],"sources":["../../src/helpers/define-field.ts"],"sourcesContent":["import type {\n AssetFieldValue,\n Field,\n MultilinkFieldValue,\n PluginFieldValue,\n RichtextFieldValue,\n TableFieldValue,\n} from '../generated/types/field';\nimport type {
|
|
1
|
+
{"version":3,"file":"define-field.mjs","names":[],"sources":["../../src/helpers/define-field.ts"],"sourcesContent":["import type {\n AssetFieldValue,\n BlockContent,\n BlockContentInput,\n BlocksFieldValue,\n Field,\n FieldType,\n FieldValue,\n FieldValueInput,\n MultilinkFieldValue,\n PluginFieldValue,\n RichtextFieldValue,\n TableFieldValue,\n} from '../generated/types/field';\nimport type { Prettify } from '../utils/prettify';\nimport { isRecord } from '../utils/is-record';\n\nexport type {\n AssetFieldValue,\n BlockContent,\n BlockContentInput,\n BlocksFieldValue,\n Field,\n FieldType,\n FieldValue,\n FieldValueInput,\n MultilinkFieldValue,\n PluginFieldValue,\n RichtextFieldValue,\n TableFieldValue,\n};\n\n/** A block reference for `allow`: a defined block object or its name. */\ntype AllowRef = string | { name: string };\n/** A datasource reference for `datasource`: a defined datasource object or its slug. */\ntype DatasourceRef = string | { slug: string };\n\ntype NameOf<T> = T extends string ? T : T extends { name: infer N extends string } ? N : never;\ntype SlugOf<T> = T extends string ? T : T extends { slug: infer S extends string } ? S : never;\n\n/** Normalizes an `allow` input (ref, name, or array thereof) to a tuple of block-name strings. */\ntype NormalizeAllow<T> = T extends readonly any[]\n ? { [I in keyof T]: NameOf<T[I]> }\n : readonly [NameOf<T>];\n\n/**\n * Field config accepted by {@link defineField}: the content-shape field plus the\n * DSL reference keys. `allow` replaces the wire `component_whitelist`; `datasource`\n * holds the datasource ref/slug (the wire `source` selector still passes through).\n */\nexport type FieldInput = Field & {\n allow?: AllowRef | readonly AllowRef[];\n datasource?: DatasourceRef;\n required?: boolean;\n};\n\n/** Result of {@link defineField}: the field stamped with `name`, with refs normalized to strings. */\nexport type DefinedField<TName extends string, TField extends FieldInput> = Prettify<\n Omit<TField, 'allow' | 'datasource' | 'name'>\n & { name: TName }\n & (TField extends { allow: infer A } ? { allow: NormalizeAllow<A> } : unknown)\n & (TField extends { datasource: infer D } ? { datasource: SlugOf<D> } : unknown)\n>;\n\n/**\n * Returns a {@link Field} stamped with the given `name`, normalizing reference\n * keys to strings so everything downstream sees plain names/slugs. A thin,\n * strongly-typed identity helper — it does not validate or throw.\n *\n * Use inside a {@link defineBlock} `fields` array — `pos` is injected from the\n * array index by `defineBlock`.\n *\n * @example\n * defineField('headline', { type: 'text', max_length: 100, required: true });\n * defineField('body', { type: 'bloks', allow: [heroBlock, 'teaser'] });\n * defineField('theme', { type: 'option', source: 'internal', datasource: colors });\n */\nexport function defineField<\n const TName extends string,\n const TField extends FieldInput,\n>(name: TName, field: TField): DefinedField<TName, TField>;\nexport function defineField(name: string, field: Record<string, unknown>): Record<string, unknown> {\n const { allow, datasource, ...rest } = field;\n const normalized: Record<string, unknown> = { ...rest, name };\n if (allow !== undefined) {\n const refs = Array.isArray(allow) ? allow : [allow];\n normalized.allow = refs.map(ref => (typeof ref === 'string' ? ref : isRecord(ref) ? ref.name : undefined));\n }\n if (datasource !== undefined) {\n normalized.datasource = typeof datasource === 'string' ? datasource : isRecord(datasource) ? datasource.slug : undefined;\n }\n return normalized;\n}\n"],"mappings":";;;AAiFA,SAAgB,YAAY,MAAc,OAAyD;CACjG,MAAM,EAAE,OAAO,YAAY,GAAG,SAAS;CACvC,MAAM,aAAsC;EAAE,GAAG;EAAM;EAAM;AAC7D,KAAI,UAAU,OAEZ,YAAW,SADE,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM,EAC3B,KAAI,QAAQ,OAAO,QAAQ,WAAW,MAAM,SAAS,IAAI,GAAG,IAAI,OAAO,OAAW;AAE5G,KAAI,eAAe,OACjB,YAAW,aAAa,OAAO,eAAe,WAAW,aAAa,SAAS,WAAW,GAAG,WAAW,OAAO;AAEjH,QAAO"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { Block } from "../generated/types/block.cjs";
|
|
2
|
-
import { Datasource } from "
|
|
3
|
-
import { ComponentFolder } from "../generated/mapi/types.gen.cjs";
|
|
2
|
+
import { Datasource } from "./define-datasource.cjs";
|
|
4
3
|
|
|
5
4
|
//#region src/helpers/schema-type.d.ts
|
|
6
5
|
/**
|
|
7
6
|
* Derives a schema types interface from a schema object.
|
|
8
7
|
*
|
|
9
|
-
* Accepts the `typeof` a schema object whose `blocks` property is a
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* Accepts the `typeof` a schema object whose `blocks` property is a record of
|
|
9
|
+
* `defineBlock()` results, and optionally a `datasources` record, and produces
|
|
10
|
+
* a type with unions of those types. A schema describes content shapes only;
|
|
11
|
+
* component groups are a UI concern and not part of it.
|
|
12
12
|
*
|
|
13
13
|
* @example
|
|
14
14
|
* ```ts
|
|
@@ -16,23 +16,19 @@ import { ComponentFolder } from "../generated/mapi/types.gen.cjs";
|
|
|
16
16
|
*
|
|
17
17
|
* export const schema = {
|
|
18
18
|
* blocks: { pageBlock, heroBlock },
|
|
19
|
-
* blockFolders: { layoutFolder },
|
|
20
19
|
* datasources: { colorsDatasource },
|
|
21
20
|
* };
|
|
22
21
|
*
|
|
23
22
|
* export type Schema = InferSchema<typeof schema>;
|
|
24
23
|
* export type Blocks = Schema['blocks'];
|
|
25
|
-
* export type BlockFolders = Schema['blockFolders'];
|
|
26
24
|
* export type Datasources = Schema['datasources'];
|
|
27
25
|
* ```
|
|
28
26
|
*/
|
|
29
27
|
interface Schema<T extends {
|
|
30
28
|
blocks: Record<string, Block>;
|
|
31
|
-
blockFolders?: Record<string, ComponentFolder>;
|
|
32
29
|
datasources?: Record<string, Datasource>;
|
|
33
30
|
}> {
|
|
34
31
|
blocks: T['blocks'][keyof T['blocks']];
|
|
35
|
-
blockFolders: T['blockFolders'] extends Record<string, ComponentFolder> ? T['blockFolders'][keyof T['blockFolders']] : never;
|
|
36
32
|
datasources: T['datasources'] extends Record<string, Datasource> ? T['datasources'][keyof T['datasources']] : never;
|
|
37
33
|
}
|
|
38
34
|
//#endregion
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { Block } from "../generated/types/block.mjs";
|
|
2
|
-
import { Datasource } from "
|
|
3
|
-
import { ComponentFolder } from "../generated/mapi/types.gen.mjs";
|
|
2
|
+
import { Datasource } from "./define-datasource.mjs";
|
|
4
3
|
|
|
5
4
|
//#region src/helpers/schema-type.d.ts
|
|
6
5
|
/**
|
|
7
6
|
* Derives a schema types interface from a schema object.
|
|
8
7
|
*
|
|
9
|
-
* Accepts the `typeof` a schema object whose `blocks` property is a
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* Accepts the `typeof` a schema object whose `blocks` property is a record of
|
|
9
|
+
* `defineBlock()` results, and optionally a `datasources` record, and produces
|
|
10
|
+
* a type with unions of those types. A schema describes content shapes only;
|
|
11
|
+
* component groups are a UI concern and not part of it.
|
|
12
12
|
*
|
|
13
13
|
* @example
|
|
14
14
|
* ```ts
|
|
@@ -16,23 +16,19 @@ import { ComponentFolder } from "../generated/mapi/types.gen.mjs";
|
|
|
16
16
|
*
|
|
17
17
|
* export const schema = {
|
|
18
18
|
* blocks: { pageBlock, heroBlock },
|
|
19
|
-
* blockFolders: { layoutFolder },
|
|
20
19
|
* datasources: { colorsDatasource },
|
|
21
20
|
* };
|
|
22
21
|
*
|
|
23
22
|
* export type Schema = InferSchema<typeof schema>;
|
|
24
23
|
* export type Blocks = Schema['blocks'];
|
|
25
|
-
* export type BlockFolders = Schema['blockFolders'];
|
|
26
24
|
* export type Datasources = Schema['datasources'];
|
|
27
25
|
* ```
|
|
28
26
|
*/
|
|
29
27
|
interface Schema<T extends {
|
|
30
28
|
blocks: Record<string, Block>;
|
|
31
|
-
blockFolders?: Record<string, ComponentFolder>;
|
|
32
29
|
datasources?: Record<string, Datasource>;
|
|
33
30
|
}> {
|
|
34
31
|
blocks: T['blocks'][keyof T['blocks']];
|
|
35
|
-
blockFolders: T['blockFolders'] extends Record<string, ComponentFolder> ? T['blockFolders'][keyof T['blockFolders']] : never;
|
|
36
32
|
datasources: T['datasources'] extends Record<string, Datasource> ? T['datasources'][keyof T['datasources']] : never;
|
|
37
33
|
}
|
|
38
34
|
//#endregion
|