Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 34 additions & 33 deletions packages/capi-client/src/generated/types/block.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
// Generated by @storyblok/openapi-codegen. Do not edit by hand.
// Source template lives in tools/openapi-codegen/templates/.

import type {
Component as ComponentGenerated,
Field,
} from './_sources';
import type { Override } from './_utils';
import type { Component as ComponentGenerated, Field } from "./_sources";
import type { Override } from "./_utils";

/**
* Ordered array of named fields — the content-shape DSL form `defineBlock`
Expand All @@ -23,42 +20,46 @@ export type Block<
TFields extends BlockFields = BlockFields,
TIsRoot extends boolean = boolean,
TIsNestable extends boolean = boolean,
> = Override<Omit<ComponentGenerated, 'schema' | 'component_group_uuid'>, {
name: TName;
fields: TFields;
is_root?: TIsRoot;
is_nestable?: TIsNestable;
/**
* Escape hatch for pinning this block to a Storyblok UI-managed component
* group by UUID. Component groups are normally maintained in code via the
* schema directory layout; set this only if you intentionally manage groups
* in the Storyblok UI, and fill in the group UUID yourself. When set,
* `schema push` diffs it and sends it to the Management API; when omitted,
* the block's remote group is left untouched.
*
* @deprecated Prefer maintaining component groups in code through the
* directory layout.
*/
component_group_uuid?: string | null;
/**
* Folder membership as a display name path (e.g. `'Layout/Heros'`); `null` =
* explicitly ungrouped (push clears the group). Absent = unmanaged (push
* leaves the remote group untouched).
*/
folder?: string | null;
}>;
> = Override<
Omit<ComponentGenerated, "schema" | "component_group_uuid">,
{
name: TName;
fields: TFields;
is_root?: TIsRoot;
is_nestable?: TIsNestable;
/**
* Escape hatch for pinning this block to a Storyblok UI-managed component
* group by UUID. Component groups are normally maintained in code via the
* schema directory layout; set this only if you intentionally manage groups
* in the Storyblok UI, and fill in the group UUID yourself. When set,
* `schema push` diffs it and sends it to the Management API; when omitted,
* the block's remote group is left untouched.
*
* @deprecated Prefer maintaining component groups in code through the
* directory layout.
*/
component_group_uuid?: string | null;
/**
* Folder membership as a display name path (e.g. `'Layout/Heros'`); `null` =
* explicitly ungrouped (push clears the group). Absent = unmanaged (push
* leaves the remote group untouched).
*/
folder?: string | null;
}
>;

/**
* A root {@link Block} (`is_root: true`). Given a union of blocks, narrows to
* its root members; with no argument it is the generic root-block type.
*/
export type RootBlock<T extends Block = Block & { is_root: true }> =
Extract<T, { is_root: true }>;
export type RootBlock<T extends Block = Block & { is_root: true }> = Extract<T, { is_root: true }>;

/**
* A nestable {@link Block} (`is_nestable: true`). Given a union of blocks,
* narrows to its nestable members; with no argument it is the generic
* nestable-block type.
*/
export type NestableBlock<T extends Block = Block & { is_nestable: true }> =
Extract<T, { is_nestable: true }>;
export type NestableBlock<T extends Block = Block & { is_nestable: true }> = Extract<
T,
{ is_nestable: true }
>;
193 changes: 127 additions & 66 deletions packages/capi-client/src/generated/types/field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,18 @@ import type {
PluginFieldValue,
RichTextFieldValue,
TableFieldValue,
} from './_sources';
import type { Prettify } from './_utils';
import type { Block, BlockFields } from './block';
} from "./_sources";
import type { Prettify } from "./_utils";
import type { Block, BlockFields } from "./block";

export type { Field };
export type { AssetFieldValue, MultilinkFieldValue, PluginFieldValue, RichTextFieldValue, TableFieldValue };
export type {
AssetFieldValue,
MultilinkFieldValue,
PluginFieldValue,
RichTextFieldValue,
TableFieldValue,
};

/**
* @deprecated Use {@link RichTextFieldValue} instead. Will be removed in a future major version.
Expand All @@ -37,15 +43,45 @@ type IsBaseBlock<T> = [Block] extends [T] ? true : false;
* required (`required: true`) from optional fields. Each `F` is a member of the
* field union, so it provably satisfies `FieldValue`'s `Field` constraint.
*/
type ContentFields<TFields extends BlockFields, TBlocks extends Block | NoBlocks, TFieldPlugins = Record<never, never>> = Prettify<
{ [F in TFields[number] as F extends { required: true } ? F['name'] : never]: FieldValue<F, TBlocks, TFieldPlugins> }
& { [F in TFields[number] as F extends { required: true } ? never : F['name']]?: FieldValue<F, TBlocks, TFieldPlugins> | null }
type ContentFields<
TFields extends BlockFields,
TBlocks extends Block | NoBlocks,
TFieldPlugins = Record<never, never>,
> = Prettify<
{
[F in TFields[number] as F extends { required: true } ? F["name"] : never]: FieldValue<
F,
TBlocks,
TFieldPlugins
>;
} & {
[F in TFields[number] as F extends { required: true } ? never : F["name"]]?: FieldValue<
F,
TBlocks,
TFieldPlugins
> | null;
}
>;

/** Input (write) variant of {@link ContentFields}, resolving each field via {@link FieldValueInput}. */
type ContentFieldsInput<TFields extends BlockFields, TBlocks extends Block | NoBlocks, TFieldPlugins = Record<never, never>> = Prettify<
{ [F in TFields[number] as F extends { required: true } ? F['name'] : never]: FieldValueInput<F, TBlocks, TFieldPlugins> }
& { [F in TFields[number] as F extends { required: true } ? never : F['name']]?: FieldValueInput<F, TBlocks, TFieldPlugins> | null }
type ContentFieldsInput<
TFields extends BlockFields,
TBlocks extends Block | NoBlocks,
TFieldPlugins = Record<never, never>,
> = Prettify<
{
[F in TFields[number] as F extends { required: true } ? F["name"] : never]: FieldValueInput<
F,
TBlocks,
TFieldPlugins
>;
} & {
[F in TFields[number] as F extends { required: true } ? never : F["name"]]?: FieldValueInput<
F,
TBlocks,
TFieldPlugins
> | null;
}
>;

/**
Expand All @@ -54,27 +90,41 @@ type ContentFieldsInput<TFields extends BlockFields, TBlocks extends Block | NoB
* runtime shape (any block, `_editable` optional). With a schema-typed
* `TBlock`, fields are narrowed per the block's `fields`.
*/
export type BlockContent<TBlock extends Block = Block, TBlocks extends Block | NoBlocks = NoBlocks, TFieldPlugins = Record<never, never>> =
export type BlockContent<
TBlock extends Block = Block,
TBlocks extends Block | NoBlocks = NoBlocks,
TFieldPlugins = Record<never, never>,
> =
IsBaseBlock<TBlock> extends true
? BlockContentBase
// distribute over each member of the `TBlock` union
: TBlock extends any
: // distribute over each member of the `TBlock` union
TBlock extends any
? Prettify<
{ _uid: string; component: TBlock['name']; _editable?: string }
& ContentFields<TBlock['fields'], TBlocks, TFieldPlugins>
>
{ _uid: string; component: TBlock["name"]; _editable?: string } & ContentFields<
TBlock["fields"],
TBlocks,
TFieldPlugins
>
>
: never;

/** Input variant of {@link BlockContent} for write operations (creating/updating stories via the MAPI). `_uid` is optional. */
export type BlockContentInput<TBlock extends Block = Block, TBlocks extends Block | NoBlocks = NoBlocks, TFieldPlugins = Record<never, never>> =
export type BlockContentInput<
TBlock extends Block = Block,
TBlocks extends Block | NoBlocks = NoBlocks,
TFieldPlugins = Record<never, never>,
> =
IsBaseBlock<TBlock> extends true
? BlockContentInputBase
// distribute over each member of the `TBlock` union
: TBlock extends any
: // distribute over each member of the `TBlock` union
TBlock extends any
? Prettify<
{ _uid?: string; component: TBlock['name']; _editable?: string }
& ContentFieldsInput<TBlock['fields'], TBlocks, TFieldPlugins>
>
{ _uid?: string; component: TBlock["name"]; _editable?: string } & ContentFieldsInput<
TBlock["fields"],
TBlocks,
TFieldPlugins
>
>
: never;

export type BlocksFieldValue<
Expand All @@ -84,7 +134,7 @@ export type BlocksFieldValue<
> = BlockContent<TBlock, TBlocks, TFieldPlugins>[];

/** Union of all valid Storyblok field type discriminants (e.g., `text`, `bloks`). */
export type FieldType = Field['type'];
export type FieldType = Field["type"];

interface FieldTypeValueMap {
text: string;
Expand Down Expand Up @@ -112,10 +162,11 @@ interface FieldTypeValueMap {
custom: PluginFieldValue;
}

type IsNestable<T> =
T extends { is_nestable: false } ? false
: T extends { is_nestable: true } ? true
: true;
type IsNestable<T> = T extends { is_nestable: false }
? false
: T extends { is_nestable: true }
? true
: true;

type AllowEntry = string | { folder: string };

Expand All @@ -130,22 +181,31 @@ type AllowEntry = string | { folder: string };
* string path on both the block's `folder` and the field's `allow`: a shared ref
* carries the exact path on both sides, so no drift is possible.
*/
type MatchesFolder<TBlock, TFolder extends string> =
TBlock extends { folder: infer BF extends string }
? Lowercase<BF> extends Lowercase<TFolder> | `${Lowercase<TFolder>}/${string}` ? TBlock : never
: never;
type MatchesFolder<TBlock, TFolder extends string> = TBlock extends {
folder: infer BF extends string;
}
? Lowercase<BF> extends Lowercase<TFolder> | `${Lowercase<TFolder>}/${string}`
? TBlock
: never
: never;

type ApplyAllow<TField, TBlocks> = TField extends { allow: ReadonlyArray<infer TAllowed extends AllowEntry> }
type ApplyAllow<TField, TBlocks> = TField extends {
allow: ReadonlyArray<infer TAllowed extends AllowEntry>;
}
? TAllowed extends string
// keep only the registry blocks named in `allow`
? Extract<TBlocks, { name: TAllowed }>
? // keep only the registry blocks named in `allow`
Extract<TBlocks, { name: TAllowed }>
: TAllowed extends { folder: infer F extends string }
// keep registry blocks in the folder (or any nested folder)
? TBlocks extends any ? MatchesFolder<TBlocks, F> : never
? // keep registry blocks in the folder (or any nested folder)
TBlocks extends any
? MatchesFolder<TBlocks, F>
: never
: never
: // no `allow`: distribute over the registry, keeping nestable blocks
TBlocks extends any
? IsNestable<TBlocks> extends true
? TBlocks
: never
// no `allow`: distribute over the registry, keeping nestable blocks
: TBlocks extends any
? IsNestable<TBlocks> extends true ? TBlocks : never
: never;

/**
Expand All @@ -154,7 +214,9 @@ type ApplyAllow<TField, TBlocks> = TField extends { allow: ReadonlyArray<infer T
* so folder refs are not accepted. A `deny` entry naming no known block is
* inert: it removes nothing rather than collapsing the field.
*/
type ApplyDeny<TField, TBlocks> = TField extends { deny: ReadonlyArray<infer TDenied extends string> }
type ApplyDeny<TField, TBlocks> = TField extends {
deny: ReadonlyArray<infer TDenied extends string>;
}
? Exclude<TBlocks, { name: TDenied }>
: TBlocks;

Expand All @@ -170,30 +232,29 @@ type ApplyRestrictions<TField, TBlocks> = ApplyDeny<TField, ApplyAllow<TField, T
* the plugin envelope (`plugin`, optional `_uid`); otherwise it falls back to
* the untyped {@link PluginFieldValue}. Same shape for read and write.
*/
type ResolveCustom<TField, TFieldPlugins> =
TField extends { field_type: infer F extends string }
? F extends keyof TFieldPlugins
? Prettify<TFieldPlugins[F] & { plugin: string; _uid?: string }>
: PluginFieldValue
: PluginFieldValue;
type ResolveCustom<TField, TFieldPlugins> = TField extends { field_type: infer F extends string }
? F extends keyof TFieldPlugins
? Prettify<TFieldPlugins[F] & { plugin: string; _uid?: string }>
: PluginFieldValue
: PluginFieldValue;

/** Resolves a field definition to its runtime content value type (read). */
export type FieldValue<
TField extends Field = Field,
TBlocks extends Block | NoBlocks = NoBlocks,
TFieldPlugins = Record<never, never>,
> = Prettify<
TField extends { type: 'bloks' }
// guard `never` first: `[never] extends [Block]` is structurally true, so an
// empty registry would otherwise be mistaken for a populated one
? [TBlocks] extends [never]
? BlockContentBase[]
: [TBlocks] extends [Block]
? BlockContent<ApplyRestrictions<TField, TBlocks>, TBlocks, TFieldPlugins>[]
: BlockContentBase[]
: TField extends { type: 'custom' }
TField extends { type: "bloks" }
? // guard `never` first: `[never] extends [Block]` is structurally true, so an
// empty registry would otherwise be mistaken for a populated one
[TBlocks] extends [never]
? BlockContentBase[]
: [TBlocks] extends [Block]
? BlockContent<ApplyRestrictions<TField, TBlocks>, TBlocks, TFieldPlugins>[]
: BlockContentBase[]
: TField extends { type: "custom" }
? ResolveCustom<TField, TFieldPlugins>
: FieldTypeValueMap[TField['type']]
: FieldTypeValueMap[TField["type"]]
>;

/** Resolves a field definition to its input value type (write). */
Expand All @@ -202,15 +263,15 @@ export type FieldValueInput<
TBlocks extends Block | NoBlocks = NoBlocks,
TFieldPlugins = Record<never, never>,
> = Prettify<
TField extends { type: 'bloks' }
// guard `never` first: `[never] extends [Block]` is structurally true, so an
// empty registry would otherwise be mistaken for a populated one
? [TBlocks] extends [never]
? BlockContentInputBase[]
: [TBlocks] extends [Block]
? BlockContentInput<ApplyRestrictions<TField, TBlocks>, TBlocks, TFieldPlugins>[]
: BlockContentInputBase[]
: TField extends { type: 'custom' }
TField extends { type: "bloks" }
? // guard `never` first: `[never] extends [Block]` is structurally true, so an
// empty registry would otherwise be mistaken for a populated one
[TBlocks] extends [never]
? BlockContentInputBase[]
: [TBlocks] extends [Block]
? BlockContentInput<ApplyRestrictions<TField, TBlocks>, TBlocks, TFieldPlugins>[]
: BlockContentInputBase[]
: TField extends { type: "custom" }
? ResolveCustom<TField, TFieldPlugins>
: FieldTypeValueMap[TField['type']]
: FieldTypeValueMap[TField["type"]]
>;
Loading
Loading