@portabletext/schema 1.0.1 → 1.1.0

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/index.cjs CHANGED
@@ -4,10 +4,21 @@ function compileSchema(definition) {
4
4
  const styles = (definition.styles ?? []).map((style) => ({
5
5
  ...style,
6
6
  value: style.name
7
- }));
7
+ })), blockFields = [];
8
+ if (definition.block?.fields)
9
+ for (const field of definition.block.fields) {
10
+ if (field.name === "_type" || field.name === "_key" || field.name === "children" || field.name === "markDefs" || field.name === "style" || field.name === "listItem" || field.name === "level") {
11
+ console.warn(
12
+ `"${field.name}" is a reserved field name on Portable Text blocks`
13
+ );
14
+ continue;
15
+ }
16
+ blockFields.push(field);
17
+ }
8
18
  return {
9
19
  block: {
10
- name: definition.block?.name ?? "block"
20
+ name: definition.block?.name ?? "block",
21
+ ...blockFields.length > 0 ? { fields: blockFields } : {}
11
22
  },
12
23
  span: {
13
24
  name: "span"
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/compile-schema.ts","../src/define-schema.ts"],"sourcesContent":["import type {SchemaDefinition} from './define-schema'\nimport type {Schema} from './schema'\n\n/**\n * @public\n */\nexport function compileSchema(definition: SchemaDefinition): Schema {\n const styles = (definition.styles ?? []).map((style) => ({\n ...style,\n value: style.name,\n }))\n\n return {\n block: {\n name: definition.block?.name ?? 'block',\n },\n span: {\n name: 'span',\n },\n styles: !styles.some((style) => style.value === 'normal')\n ? [{value: 'normal', name: 'normal', title: 'Normal'}, ...styles]\n : styles,\n lists: (definition.lists ?? []).map((list) => ({\n ...list,\n value: list.name,\n })),\n decorators: (definition.decorators ?? []).map((decorator) => ({\n ...decorator,\n value: decorator.name,\n })),\n annotations: (definition.annotations ?? []).map((annotation) => ({\n ...annotation,\n fields: annotation.fields ?? [],\n })),\n blockObjects: (definition.blockObjects ?? []).map((blockObject) => ({\n ...blockObject,\n fields: blockObject.fields ?? [],\n })),\n inlineObjects: (definition.inlineObjects ?? []).map((inlineObject) => ({\n ...inlineObject,\n fields: inlineObject.fields ?? [],\n })),\n }\n}\n","import type {BaseDefinition, FieldDefinition} from './schema'\n\n/**\n * @public\n */\nexport type SchemaDefinition = {\n block?: {\n name: string\n }\n styles?: ReadonlyArray<StyleDefinition>\n lists?: ReadonlyArray<ListDefinition>\n decorators?: ReadonlyArray<DecoratorDefinition>\n annotations?: ReadonlyArray<AnnotationDefinition>\n blockObjects?: ReadonlyArray<BlockObjectDefinition>\n inlineObjects?: ReadonlyArray<InlineObjectDefinition>\n}\n\n/**\n * @public\n * A helper wrapper that adds editor support, such as autocomplete and type checking, for a schema definition.\n * @example\n * ```ts\n * import { defineSchema } from '@portabletext/editor'\n *\n * const schemaDefinition = defineSchema({\n * decorators: [{name: 'strong'}, {name: 'em'}, {name: 'underline'}],\n * annotations: [{name: 'link'}],\n * styles: [\n * {name: 'normal'},\n * {name: 'h1'},\n * {name: 'h2'},\n * {name: 'h3'},\n * {name: 'blockquote'},\n * ],\n * lists: [],\n * inlineObjects: [],\n * blockObjects: [],\n * }\n * ```\n */\nexport function defineSchema<const TSchemaDefinition extends SchemaDefinition>(\n definition: TSchemaDefinition,\n): TSchemaDefinition {\n return definition\n}\n\n/**\n * @public\n */\nexport type StyleDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition\n\n/**\n * @public\n */\nexport type ListDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition\n\n/**\n * @public\n */\nexport type DecoratorDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition\n\n/**\n * @public\n */\nexport type AnnotationDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition & {\n fields?: ReadonlyArray<FieldDefinition>\n}\n\n/**\n * @public\n */\nexport type BlockObjectDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition & {\n fields?: ReadonlyArray<FieldDefinition>\n}\n\n/**\n * @public\n */\nexport type InlineObjectDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition & {\n fields?: ReadonlyArray<FieldDefinition>\n}\n"],"names":[],"mappings":";;AAMO,SAAS,cAAc,YAAsC;AAClE,QAAM,UAAU,WAAW,UAAU,CAAA,GAAI,IAAI,CAAC,WAAW;AAAA,IACvD,GAAG;AAAA,IACH,OAAO,MAAM;AAAA,EAAA,EACb;AAEF,SAAO;AAAA,IACL,OAAO;AAAA,MACL,MAAM,WAAW,OAAO,QAAQ;AAAA,IAAA;AAAA,IAElC,MAAM;AAAA,MACJ,MAAM;AAAA,IAAA;AAAA,IAER,QAAS,OAAO,KAAK,CAAC,UAAU,MAAM,UAAU,QAAQ,IAEpD,SADA,CAAC,EAAC,OAAO,UAAU,MAAM,UAAU,OAAO,SAAA,GAAW,GAAG,MAAM;AAAA,IAElE,QAAQ,WAAW,SAAS,CAAA,GAAI,IAAI,CAAC,UAAU;AAAA,MAC7C,GAAG;AAAA,MACH,OAAO,KAAK;AAAA,IAAA,EACZ;AAAA,IACF,aAAa,WAAW,cAAc,CAAA,GAAI,IAAI,CAAC,eAAe;AAAA,MAC5D,GAAG;AAAA,MACH,OAAO,UAAU;AAAA,IAAA,EACjB;AAAA,IACF,cAAc,WAAW,eAAe,CAAA,GAAI,IAAI,CAAC,gBAAgB;AAAA,MAC/D,GAAG;AAAA,MACH,QAAQ,WAAW,UAAU,CAAA;AAAA,IAAC,EAC9B;AAAA,IACF,eAAe,WAAW,gBAAgB,CAAA,GAAI,IAAI,CAAC,iBAAiB;AAAA,MAClE,GAAG;AAAA,MACH,QAAQ,YAAY,UAAU,CAAA;AAAA,IAAC,EAC/B;AAAA,IACF,gBAAgB,WAAW,iBAAiB,CAAA,GAAI,IAAI,CAAC,kBAAkB;AAAA,MACrE,GAAG;AAAA,MACH,QAAQ,aAAa,UAAU,CAAA;AAAA,IAAC,EAChC;AAAA,EAAA;AAEN;ACHO,SAAS,aACd,YACmB;AACnB,SAAO;AACT;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/compile-schema.ts","../src/define-schema.ts"],"sourcesContent":["import type {SchemaDefinition} from './define-schema'\nimport type {FieldDefinition, Schema} from './schema'\n\n/**\n * @public\n */\nexport function compileSchema(definition: SchemaDefinition): Schema {\n const styles = (definition.styles ?? []).map((style) => ({\n ...style,\n value: style.name,\n }))\n\n const blockFields: Array<FieldDefinition> = []\n\n if (definition.block?.fields) {\n for (const field of definition.block.fields) {\n if (\n field.name === '_type' ||\n field.name === '_key' ||\n field.name === 'children' ||\n field.name === 'markDefs' ||\n field.name === 'style' ||\n field.name === 'listItem' ||\n field.name === 'level'\n ) {\n console.warn(\n `\"${field.name}\" is a reserved field name on Portable Text blocks`,\n )\n continue\n }\n\n blockFields.push(field)\n }\n }\n\n return {\n block: {\n name: definition.block?.name ?? 'block',\n ...(blockFields.length > 0 ? {fields: blockFields} : {}),\n },\n span: {\n name: 'span',\n },\n styles: !styles.some((style) => style.value === 'normal')\n ? [{value: 'normal', name: 'normal', title: 'Normal'}, ...styles]\n : styles,\n lists: (definition.lists ?? []).map((list) => ({\n ...list,\n value: list.name,\n })),\n decorators: (definition.decorators ?? []).map((decorator) => ({\n ...decorator,\n value: decorator.name,\n })),\n annotations: (definition.annotations ?? []).map((annotation) => ({\n ...annotation,\n fields: annotation.fields ?? [],\n })),\n blockObjects: (definition.blockObjects ?? []).map((blockObject) => ({\n ...blockObject,\n fields: blockObject.fields ?? [],\n })),\n inlineObjects: (definition.inlineObjects ?? []).map((inlineObject) => ({\n ...inlineObject,\n fields: inlineObject.fields ?? [],\n })),\n }\n}\n","import type {BaseDefinition, FieldDefinition} from './schema'\n\n/**\n * @public\n */\nexport type SchemaDefinition = {\n block?: {\n name?: string\n fields?: ReadonlyArray<FieldDefinition>\n }\n styles?: ReadonlyArray<StyleDefinition>\n lists?: ReadonlyArray<ListDefinition>\n decorators?: ReadonlyArray<DecoratorDefinition>\n annotations?: ReadonlyArray<AnnotationDefinition>\n blockObjects?: ReadonlyArray<BlockObjectDefinition>\n inlineObjects?: ReadonlyArray<InlineObjectDefinition>\n}\n\n/**\n * @public\n * A helper wrapper that adds editor support, such as autocomplete and type checking, for a schema definition.\n * @example\n * ```ts\n * import { defineSchema } from '@portabletext/editor'\n *\n * const schemaDefinition = defineSchema({\n * decorators: [{name: 'strong'}, {name: 'em'}, {name: 'underline'}],\n * annotations: [{name: 'link'}],\n * styles: [\n * {name: 'normal'},\n * {name: 'h1'},\n * {name: 'h2'},\n * {name: 'h3'},\n * {name: 'blockquote'},\n * ],\n * lists: [],\n * inlineObjects: [],\n * blockObjects: [],\n * }\n * ```\n */\nexport function defineSchema<const TSchemaDefinition extends SchemaDefinition>(\n definition: TSchemaDefinition,\n): TSchemaDefinition {\n return definition\n}\n\n/**\n * @public\n */\nexport type StyleDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition\n\n/**\n * @public\n */\nexport type ListDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition\n\n/**\n * @public\n */\nexport type DecoratorDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition\n\n/**\n * @public\n */\nexport type AnnotationDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition & {\n fields?: ReadonlyArray<FieldDefinition>\n}\n\n/**\n * @public\n */\nexport type BlockObjectDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition & {\n fields?: ReadonlyArray<FieldDefinition>\n}\n\n/**\n * @public\n */\nexport type InlineObjectDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition & {\n fields?: ReadonlyArray<FieldDefinition>\n}\n"],"names":[],"mappings":";;AAMO,SAAS,cAAc,YAAsC;AAClE,QAAM,UAAU,WAAW,UAAU,CAAA,GAAI,IAAI,CAAC,WAAW;AAAA,IACvD,GAAG;AAAA,IACH,OAAO,MAAM;AAAA,EAAA,EACb,GAEI,cAAsC,CAAA;AAE5C,MAAI,WAAW,OAAO;AACpB,eAAW,SAAS,WAAW,MAAM,QAAQ;AAC3C,UACE,MAAM,SAAS,WACf,MAAM,SAAS,UACf,MAAM,SAAS,cACf,MAAM,SAAS,cACf,MAAM,SAAS,WACf,MAAM,SAAS,cACf,MAAM,SAAS,SACf;AACA,gBAAQ;AAAA,UACN,IAAI,MAAM,IAAI;AAAA,QAAA;AAEhB;AAAA,MACF;AAEA,kBAAY,KAAK,KAAK;AAAA,IACxB;AAGF,SAAO;AAAA,IACL,OAAO;AAAA,MACL,MAAM,WAAW,OAAO,QAAQ;AAAA,MAChC,GAAI,YAAY,SAAS,IAAI,EAAC,QAAQ,YAAA,IAAe,CAAA;AAAA,IAAC;AAAA,IAExD,MAAM;AAAA,MACJ,MAAM;AAAA,IAAA;AAAA,IAER,QAAS,OAAO,KAAK,CAAC,UAAU,MAAM,UAAU,QAAQ,IAEpD,SADA,CAAC,EAAC,OAAO,UAAU,MAAM,UAAU,OAAO,SAAA,GAAW,GAAG,MAAM;AAAA,IAElE,QAAQ,WAAW,SAAS,CAAA,GAAI,IAAI,CAAC,UAAU;AAAA,MAC7C,GAAG;AAAA,MACH,OAAO,KAAK;AAAA,IAAA,EACZ;AAAA,IACF,aAAa,WAAW,cAAc,CAAA,GAAI,IAAI,CAAC,eAAe;AAAA,MAC5D,GAAG;AAAA,MACH,OAAO,UAAU;AAAA,IAAA,EACjB;AAAA,IACF,cAAc,WAAW,eAAe,CAAA,GAAI,IAAI,CAAC,gBAAgB;AAAA,MAC/D,GAAG;AAAA,MACH,QAAQ,WAAW,UAAU,CAAA;AAAA,IAAC,EAC9B;AAAA,IACF,eAAe,WAAW,gBAAgB,CAAA,GAAI,IAAI,CAAC,iBAAiB;AAAA,MAClE,GAAG;AAAA,MACH,QAAQ,YAAY,UAAU,CAAA;AAAA,IAAC,EAC/B;AAAA,IACF,gBAAgB,WAAW,iBAAiB,CAAA,GAAI,IAAI,CAAC,kBAAkB;AAAA,MACrE,GAAG;AAAA,MACH,QAAQ,aAAa,UAAU,CAAA;AAAA,IAAC,EAChC;AAAA,EAAA;AAEN;AC1BO,SAAS,aACd,YACmB;AACnB,SAAO;AACT;;;"}
package/dist/index.d.cts CHANGED
@@ -4,6 +4,7 @@
4
4
  type Schema = {
5
5
  block: {
6
6
  name: string;
7
+ fields?: ReadonlyArray<FieldDefinition>;
7
8
  };
8
9
  span: {
9
10
  name: string;
@@ -81,7 +82,8 @@ type BaseDefinition = {
81
82
  */
82
83
  type SchemaDefinition = {
83
84
  block?: {
84
- name: string;
85
+ name?: string;
86
+ fields?: ReadonlyArray<FieldDefinition>;
85
87
  };
86
88
  styles?: ReadonlyArray<StyleDefinition>;
87
89
  lists?: ReadonlyArray<ListDefinition>;
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  type Schema = {
5
5
  block: {
6
6
  name: string;
7
+ fields?: ReadonlyArray<FieldDefinition>;
7
8
  };
8
9
  span: {
9
10
  name: string;
@@ -81,7 +82,8 @@ type BaseDefinition = {
81
82
  */
82
83
  type SchemaDefinition = {
83
84
  block?: {
84
- name: string;
85
+ name?: string;
86
+ fields?: ReadonlyArray<FieldDefinition>;
85
87
  };
86
88
  styles?: ReadonlyArray<StyleDefinition>;
87
89
  lists?: ReadonlyArray<ListDefinition>;
package/dist/index.js CHANGED
@@ -2,10 +2,21 @@ function compileSchema(definition) {
2
2
  const styles = (definition.styles ?? []).map((style) => ({
3
3
  ...style,
4
4
  value: style.name
5
- }));
5
+ })), blockFields = [];
6
+ if (definition.block?.fields)
7
+ for (const field of definition.block.fields) {
8
+ if (field.name === "_type" || field.name === "_key" || field.name === "children" || field.name === "markDefs" || field.name === "style" || field.name === "listItem" || field.name === "level") {
9
+ console.warn(
10
+ `"${field.name}" is a reserved field name on Portable Text blocks`
11
+ );
12
+ continue;
13
+ }
14
+ blockFields.push(field);
15
+ }
6
16
  return {
7
17
  block: {
8
- name: definition.block?.name ?? "block"
18
+ name: definition.block?.name ?? "block",
19
+ ...blockFields.length > 0 ? { fields: blockFields } : {}
9
20
  },
10
21
  span: {
11
22
  name: "span"
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/compile-schema.ts","../src/define-schema.ts"],"sourcesContent":["import type {SchemaDefinition} from './define-schema'\nimport type {Schema} from './schema'\n\n/**\n * @public\n */\nexport function compileSchema(definition: SchemaDefinition): Schema {\n const styles = (definition.styles ?? []).map((style) => ({\n ...style,\n value: style.name,\n }))\n\n return {\n block: {\n name: definition.block?.name ?? 'block',\n },\n span: {\n name: 'span',\n },\n styles: !styles.some((style) => style.value === 'normal')\n ? [{value: 'normal', name: 'normal', title: 'Normal'}, ...styles]\n : styles,\n lists: (definition.lists ?? []).map((list) => ({\n ...list,\n value: list.name,\n })),\n decorators: (definition.decorators ?? []).map((decorator) => ({\n ...decorator,\n value: decorator.name,\n })),\n annotations: (definition.annotations ?? []).map((annotation) => ({\n ...annotation,\n fields: annotation.fields ?? [],\n })),\n blockObjects: (definition.blockObjects ?? []).map((blockObject) => ({\n ...blockObject,\n fields: blockObject.fields ?? [],\n })),\n inlineObjects: (definition.inlineObjects ?? []).map((inlineObject) => ({\n ...inlineObject,\n fields: inlineObject.fields ?? [],\n })),\n }\n}\n","import type {BaseDefinition, FieldDefinition} from './schema'\n\n/**\n * @public\n */\nexport type SchemaDefinition = {\n block?: {\n name: string\n }\n styles?: ReadonlyArray<StyleDefinition>\n lists?: ReadonlyArray<ListDefinition>\n decorators?: ReadonlyArray<DecoratorDefinition>\n annotations?: ReadonlyArray<AnnotationDefinition>\n blockObjects?: ReadonlyArray<BlockObjectDefinition>\n inlineObjects?: ReadonlyArray<InlineObjectDefinition>\n}\n\n/**\n * @public\n * A helper wrapper that adds editor support, such as autocomplete and type checking, for a schema definition.\n * @example\n * ```ts\n * import { defineSchema } from '@portabletext/editor'\n *\n * const schemaDefinition = defineSchema({\n * decorators: [{name: 'strong'}, {name: 'em'}, {name: 'underline'}],\n * annotations: [{name: 'link'}],\n * styles: [\n * {name: 'normal'},\n * {name: 'h1'},\n * {name: 'h2'},\n * {name: 'h3'},\n * {name: 'blockquote'},\n * ],\n * lists: [],\n * inlineObjects: [],\n * blockObjects: [],\n * }\n * ```\n */\nexport function defineSchema<const TSchemaDefinition extends SchemaDefinition>(\n definition: TSchemaDefinition,\n): TSchemaDefinition {\n return definition\n}\n\n/**\n * @public\n */\nexport type StyleDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition\n\n/**\n * @public\n */\nexport type ListDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition\n\n/**\n * @public\n */\nexport type DecoratorDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition\n\n/**\n * @public\n */\nexport type AnnotationDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition & {\n fields?: ReadonlyArray<FieldDefinition>\n}\n\n/**\n * @public\n */\nexport type BlockObjectDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition & {\n fields?: ReadonlyArray<FieldDefinition>\n}\n\n/**\n * @public\n */\nexport type InlineObjectDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition & {\n fields?: ReadonlyArray<FieldDefinition>\n}\n"],"names":[],"mappings":"AAMO,SAAS,cAAc,YAAsC;AAClE,QAAM,UAAU,WAAW,UAAU,CAAA,GAAI,IAAI,CAAC,WAAW;AAAA,IACvD,GAAG;AAAA,IACH,OAAO,MAAM;AAAA,EAAA,EACb;AAEF,SAAO;AAAA,IACL,OAAO;AAAA,MACL,MAAM,WAAW,OAAO,QAAQ;AAAA,IAAA;AAAA,IAElC,MAAM;AAAA,MACJ,MAAM;AAAA,IAAA;AAAA,IAER,QAAS,OAAO,KAAK,CAAC,UAAU,MAAM,UAAU,QAAQ,IAEpD,SADA,CAAC,EAAC,OAAO,UAAU,MAAM,UAAU,OAAO,SAAA,GAAW,GAAG,MAAM;AAAA,IAElE,QAAQ,WAAW,SAAS,CAAA,GAAI,IAAI,CAAC,UAAU;AAAA,MAC7C,GAAG;AAAA,MACH,OAAO,KAAK;AAAA,IAAA,EACZ;AAAA,IACF,aAAa,WAAW,cAAc,CAAA,GAAI,IAAI,CAAC,eAAe;AAAA,MAC5D,GAAG;AAAA,MACH,OAAO,UAAU;AAAA,IAAA,EACjB;AAAA,IACF,cAAc,WAAW,eAAe,CAAA,GAAI,IAAI,CAAC,gBAAgB;AAAA,MAC/D,GAAG;AAAA,MACH,QAAQ,WAAW,UAAU,CAAA;AAAA,IAAC,EAC9B;AAAA,IACF,eAAe,WAAW,gBAAgB,CAAA,GAAI,IAAI,CAAC,iBAAiB;AAAA,MAClE,GAAG;AAAA,MACH,QAAQ,YAAY,UAAU,CAAA;AAAA,IAAC,EAC/B;AAAA,IACF,gBAAgB,WAAW,iBAAiB,CAAA,GAAI,IAAI,CAAC,kBAAkB;AAAA,MACrE,GAAG;AAAA,MACH,QAAQ,aAAa,UAAU,CAAA;AAAA,IAAC,EAChC;AAAA,EAAA;AAEN;ACHO,SAAS,aACd,YACmB;AACnB,SAAO;AACT;"}
1
+ {"version":3,"file":"index.js","sources":["../src/compile-schema.ts","../src/define-schema.ts"],"sourcesContent":["import type {SchemaDefinition} from './define-schema'\nimport type {FieldDefinition, Schema} from './schema'\n\n/**\n * @public\n */\nexport function compileSchema(definition: SchemaDefinition): Schema {\n const styles = (definition.styles ?? []).map((style) => ({\n ...style,\n value: style.name,\n }))\n\n const blockFields: Array<FieldDefinition> = []\n\n if (definition.block?.fields) {\n for (const field of definition.block.fields) {\n if (\n field.name === '_type' ||\n field.name === '_key' ||\n field.name === 'children' ||\n field.name === 'markDefs' ||\n field.name === 'style' ||\n field.name === 'listItem' ||\n field.name === 'level'\n ) {\n console.warn(\n `\"${field.name}\" is a reserved field name on Portable Text blocks`,\n )\n continue\n }\n\n blockFields.push(field)\n }\n }\n\n return {\n block: {\n name: definition.block?.name ?? 'block',\n ...(blockFields.length > 0 ? {fields: blockFields} : {}),\n },\n span: {\n name: 'span',\n },\n styles: !styles.some((style) => style.value === 'normal')\n ? [{value: 'normal', name: 'normal', title: 'Normal'}, ...styles]\n : styles,\n lists: (definition.lists ?? []).map((list) => ({\n ...list,\n value: list.name,\n })),\n decorators: (definition.decorators ?? []).map((decorator) => ({\n ...decorator,\n value: decorator.name,\n })),\n annotations: (definition.annotations ?? []).map((annotation) => ({\n ...annotation,\n fields: annotation.fields ?? [],\n })),\n blockObjects: (definition.blockObjects ?? []).map((blockObject) => ({\n ...blockObject,\n fields: blockObject.fields ?? [],\n })),\n inlineObjects: (definition.inlineObjects ?? []).map((inlineObject) => ({\n ...inlineObject,\n fields: inlineObject.fields ?? [],\n })),\n }\n}\n","import type {BaseDefinition, FieldDefinition} from './schema'\n\n/**\n * @public\n */\nexport type SchemaDefinition = {\n block?: {\n name?: string\n fields?: ReadonlyArray<FieldDefinition>\n }\n styles?: ReadonlyArray<StyleDefinition>\n lists?: ReadonlyArray<ListDefinition>\n decorators?: ReadonlyArray<DecoratorDefinition>\n annotations?: ReadonlyArray<AnnotationDefinition>\n blockObjects?: ReadonlyArray<BlockObjectDefinition>\n inlineObjects?: ReadonlyArray<InlineObjectDefinition>\n}\n\n/**\n * @public\n * A helper wrapper that adds editor support, such as autocomplete and type checking, for a schema definition.\n * @example\n * ```ts\n * import { defineSchema } from '@portabletext/editor'\n *\n * const schemaDefinition = defineSchema({\n * decorators: [{name: 'strong'}, {name: 'em'}, {name: 'underline'}],\n * annotations: [{name: 'link'}],\n * styles: [\n * {name: 'normal'},\n * {name: 'h1'},\n * {name: 'h2'},\n * {name: 'h3'},\n * {name: 'blockquote'},\n * ],\n * lists: [],\n * inlineObjects: [],\n * blockObjects: [],\n * }\n * ```\n */\nexport function defineSchema<const TSchemaDefinition extends SchemaDefinition>(\n definition: TSchemaDefinition,\n): TSchemaDefinition {\n return definition\n}\n\n/**\n * @public\n */\nexport type StyleDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition\n\n/**\n * @public\n */\nexport type ListDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition\n\n/**\n * @public\n */\nexport type DecoratorDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition\n\n/**\n * @public\n */\nexport type AnnotationDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition & {\n fields?: ReadonlyArray<FieldDefinition>\n}\n\n/**\n * @public\n */\nexport type BlockObjectDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition & {\n fields?: ReadonlyArray<FieldDefinition>\n}\n\n/**\n * @public\n */\nexport type InlineObjectDefinition<\n TBaseDefinition extends BaseDefinition = BaseDefinition,\n> = TBaseDefinition & {\n fields?: ReadonlyArray<FieldDefinition>\n}\n"],"names":[],"mappings":"AAMO,SAAS,cAAc,YAAsC;AAClE,QAAM,UAAU,WAAW,UAAU,CAAA,GAAI,IAAI,CAAC,WAAW;AAAA,IACvD,GAAG;AAAA,IACH,OAAO,MAAM;AAAA,EAAA,EACb,GAEI,cAAsC,CAAA;AAE5C,MAAI,WAAW,OAAO;AACpB,eAAW,SAAS,WAAW,MAAM,QAAQ;AAC3C,UACE,MAAM,SAAS,WACf,MAAM,SAAS,UACf,MAAM,SAAS,cACf,MAAM,SAAS,cACf,MAAM,SAAS,WACf,MAAM,SAAS,cACf,MAAM,SAAS,SACf;AACA,gBAAQ;AAAA,UACN,IAAI,MAAM,IAAI;AAAA,QAAA;AAEhB;AAAA,MACF;AAEA,kBAAY,KAAK,KAAK;AAAA,IACxB;AAGF,SAAO;AAAA,IACL,OAAO;AAAA,MACL,MAAM,WAAW,OAAO,QAAQ;AAAA,MAChC,GAAI,YAAY,SAAS,IAAI,EAAC,QAAQ,YAAA,IAAe,CAAA;AAAA,IAAC;AAAA,IAExD,MAAM;AAAA,MACJ,MAAM;AAAA,IAAA;AAAA,IAER,QAAS,OAAO,KAAK,CAAC,UAAU,MAAM,UAAU,QAAQ,IAEpD,SADA,CAAC,EAAC,OAAO,UAAU,MAAM,UAAU,OAAO,SAAA,GAAW,GAAG,MAAM;AAAA,IAElE,QAAQ,WAAW,SAAS,CAAA,GAAI,IAAI,CAAC,UAAU;AAAA,MAC7C,GAAG;AAAA,MACH,OAAO,KAAK;AAAA,IAAA,EACZ;AAAA,IACF,aAAa,WAAW,cAAc,CAAA,GAAI,IAAI,CAAC,eAAe;AAAA,MAC5D,GAAG;AAAA,MACH,OAAO,UAAU;AAAA,IAAA,EACjB;AAAA,IACF,cAAc,WAAW,eAAe,CAAA,GAAI,IAAI,CAAC,gBAAgB;AAAA,MAC/D,GAAG;AAAA,MACH,QAAQ,WAAW,UAAU,CAAA;AAAA,IAAC,EAC9B;AAAA,IACF,eAAe,WAAW,gBAAgB,CAAA,GAAI,IAAI,CAAC,iBAAiB;AAAA,MAClE,GAAG;AAAA,MACH,QAAQ,YAAY,UAAU,CAAA;AAAA,IAAC,EAC/B;AAAA,IACF,gBAAgB,WAAW,iBAAiB,CAAA,GAAI,IAAI,CAAC,kBAAkB;AAAA,MACrE,GAAG;AAAA,MACH,QAAQ,aAAa,UAAU,CAAA;AAAA,IAAC,EAChC;AAAA,EAAA;AAEN;AC1BO,SAAS,aACd,YACmB;AACnB,SAAO;AACT;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/schema",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Portable Text Schema",
5
5
  "keywords": [
6
6
  "portabletext",
@@ -36,8 +36,9 @@
36
36
  "src"
37
37
  ],
38
38
  "devDependencies": {
39
- "@sanity/pkg-utils": "^7.11.1",
40
- "typescript": "^5.9.2"
39
+ "@sanity/pkg-utils": "^7.11.9",
40
+ "typescript": "^5.9.2",
41
+ "vitest": "^3.2.4"
41
42
  },
42
43
  "scripts": {
43
44
  "build": "pkg-utils build --strict --check --clean",
@@ -46,6 +47,8 @@
46
47
  "check:types:watch": "tsc --watch",
47
48
  "clean": "del .turbo && del lib && del node_modules",
48
49
  "dev": "pkg-utils watch",
49
- "lint:fix": "biome lint --write ."
50
+ "lint:fix": "biome lint --write .",
51
+ "test:unit": "vitest run",
52
+ "test:unit:watch": "vitest watch"
50
53
  }
51
54
  }
@@ -0,0 +1,46 @@
1
+ import {describe, expect, test, vi} from 'vitest'
2
+ import {compileSchema} from './compile-schema'
3
+
4
+ describe(compileSchema.name, () => {
5
+ describe('block fields', () => {
6
+ test('reserved fields are ignored and warned about', () => {
7
+ const consoleWarnSpy = vi
8
+ .spyOn(console, 'warn')
9
+ .mockImplementation(() => {})
10
+
11
+ expect(
12
+ compileSchema({block: {fields: [{name: '_type', type: 'string'}]}}),
13
+ ).toEqual({
14
+ block: {name: 'block'},
15
+ span: {name: 'span'},
16
+ styles: [{value: 'normal', name: 'normal', title: 'Normal'}],
17
+ lists: [],
18
+ decorators: [],
19
+ annotations: [],
20
+ blockObjects: [],
21
+ inlineObjects: [],
22
+ })
23
+
24
+ expect(consoleWarnSpy).toHaveBeenCalledWith(
25
+ '"_type" is a reserved field name on Portable Text blocks',
26
+ )
27
+
28
+ consoleWarnSpy.mockRestore()
29
+ })
30
+
31
+ test('custom fields are included', () => {
32
+ expect(
33
+ compileSchema({block: {fields: [{name: 'foo', type: 'string'}]}}),
34
+ ).toEqual({
35
+ block: {name: 'block', fields: [{name: 'foo', type: 'string'}]},
36
+ span: {name: 'span'},
37
+ styles: [{value: 'normal', name: 'normal', title: 'Normal'}],
38
+ lists: [],
39
+ decorators: [],
40
+ annotations: [],
41
+ blockObjects: [],
42
+ inlineObjects: [],
43
+ })
44
+ })
45
+ })
46
+ })
@@ -1,5 +1,5 @@
1
1
  import type {SchemaDefinition} from './define-schema'
2
- import type {Schema} from './schema'
2
+ import type {FieldDefinition, Schema} from './schema'
3
3
 
4
4
  /**
5
5
  * @public
@@ -10,9 +10,33 @@ export function compileSchema(definition: SchemaDefinition): Schema {
10
10
  value: style.name,
11
11
  }))
12
12
 
13
+ const blockFields: Array<FieldDefinition> = []
14
+
15
+ if (definition.block?.fields) {
16
+ for (const field of definition.block.fields) {
17
+ if (
18
+ field.name === '_type' ||
19
+ field.name === '_key' ||
20
+ field.name === 'children' ||
21
+ field.name === 'markDefs' ||
22
+ field.name === 'style' ||
23
+ field.name === 'listItem' ||
24
+ field.name === 'level'
25
+ ) {
26
+ console.warn(
27
+ `"${field.name}" is a reserved field name on Portable Text blocks`,
28
+ )
29
+ continue
30
+ }
31
+
32
+ blockFields.push(field)
33
+ }
34
+ }
35
+
13
36
  return {
14
37
  block: {
15
38
  name: definition.block?.name ?? 'block',
39
+ ...(blockFields.length > 0 ? {fields: blockFields} : {}),
16
40
  },
17
41
  span: {
18
42
  name: 'span',
@@ -5,7 +5,8 @@ import type {BaseDefinition, FieldDefinition} from './schema'
5
5
  */
6
6
  export type SchemaDefinition = {
7
7
  block?: {
8
- name: string
8
+ name?: string
9
+ fields?: ReadonlyArray<FieldDefinition>
9
10
  }
10
11
  styles?: ReadonlyArray<StyleDefinition>
11
12
  lists?: ReadonlyArray<ListDefinition>
package/src/schema.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  export type Schema = {
5
5
  block: {
6
6
  name: string
7
+ fields?: ReadonlyArray<FieldDefinition>
7
8
  }
8
9
  span: {
9
10
  name: string