diff --git a/examples/archive/playground-azimuth/contentlayer.config.ts b/examples/archive/playground-azimuth/contentlayer.config.ts index e68ffd17..a3573cac 100644 --- a/examples/archive/playground-azimuth/contentlayer.config.ts +++ b/examples/archive/playground-azimuth/contentlayer.config.ts @@ -1,14 +1,13 @@ import { makeSource } from 'contentlayer/source-files' +import 'contentlayer-stackbit-yaml-generator/types' import * as documentTypes from './src/contentlayer' export default makeSource({ contentDirPath: 'content', documentTypes, - extensions: { - stackbit: { - pagesDir: 'content/pages', - dataDir: 'content/data', - }, + stackbit: { + pagesDir: 'content/pages', + dataDir: 'content/data', }, }) diff --git a/examples/archive/playground-azimuth/src/contentlayer/documents/Blog.ts b/examples/archive/playground-azimuth/src/contentlayer/documents/Blog.ts index ce6a08e5..e20d055f 100644 --- a/examples/archive/playground-azimuth/src/contentlayer/documents/Blog.ts +++ b/examples/archive/playground-azimuth/src/contentlayer/documents/Blog.ts @@ -23,12 +23,10 @@ export const Blog = defineDocumentType(() => ({ resolve: urlFromFilePath, }, }, - extensions: { - stackbit: { - fields: { - title: { label: 'Title' }, - }, - file: 'blog.md', + stackbit: { + fields: { + title: { label: 'Title' }, }, + file: 'blog.md', }, })) diff --git a/examples/archive/playground-azimuth/src/contentlayer/documents/Config.ts b/examples/archive/playground-azimuth/src/contentlayer/documents/Config.ts index 502b5333..e9557d10 100644 --- a/examples/archive/playground-azimuth/src/contentlayer/documents/Config.ts +++ b/examples/archive/playground-azimuth/src/contentlayer/documents/Config.ts @@ -45,21 +45,19 @@ export const Config = defineDocumentType(() => ({ // header: { type: 'embedded', model: Header, required: true }, footer: { type: 'nested', of: Footer, required: true }, }, - extensions: { - stackbit: { - label: 'Site Configuration', - fields: { - title: { label: 'Title' }, - path_prefix: { label: 'Base URL', hidden: true }, - domain: { label: 'Domain' }, - favicon: { label: 'Favicon' }, - palette: { label: 'Color Palette' }, - base_font: { label: 'Font' }, - header: { label: 'Header Configuration' }, - footer: { label: 'Footer Configuration' }, - }, - file: 'config.json', - }, + stackbit: { + label: 'Site Configuration', + fields: { + title: { label: 'Title' }, + path_prefix: { label: 'Base URL', hidden: true }, + domain: { label: 'Domain' }, + favicon: { label: 'Favicon' }, + palette: { label: 'Color Palette' }, + base_font: { label: 'Font' }, + header: { label: 'Header Configuration' }, + footer: { label: 'Footer Configuration' }, + }, + file: 'config.json', }, })) @@ -85,15 +83,13 @@ const Header = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Header Configuration', - fields: { - logo_img: { label: 'Logo' }, - logo_img_alt: { label: 'Logo Alt Text' }, - has_nav: { label: 'Enable Navigation' }, - nav_links: { label: 'Navigation Links' }, - }, + stackbit: { + label: 'Header Configuration', + fields: { + logo_img: { label: 'Logo' }, + logo_img_alt: { label: 'Logo Alt Text' }, + has_nav: { label: 'Enable Navigation' }, + nav_links: { label: 'Navigation Links' }, }, }, })) @@ -127,17 +123,15 @@ const Footer = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Footer Configuration', - labelField: 'content', - fields: { - sections: { label: 'Sections' }, - has_nav: { label: 'Enable Horizontal Navigation' }, - nav_links: { label: 'Horizontal Navigation Links' }, - content: { label: 'Footer Content' }, - links: { label: 'Links' }, - }, + stackbit: { + label: 'Footer Configuration', + labelField: 'content', + fields: { + sections: { label: 'Sections' }, + has_nav: { label: 'Enable Horizontal Navigation' }, + nav_links: { label: 'Horizontal Navigation Links' }, + content: { label: 'Footer Content' }, + links: { label: 'Links' }, }, }, })) @@ -196,19 +190,17 @@ const FooterForm = defineNestedType(() => ({ required: true, }, }, - extensions: { - stackbit: { - label: 'Footer Form', - labelField: 'title', - fields: { - ...footerSectionBaseFieldsExtension, - content: { label: 'Content' }, - form_id: { label: 'Form ID' }, - form_action: { label: 'Form Action' }, - hide_labels: { label: 'Hide Labels' }, - form_fields: { label: 'Form Fields' }, - submit_label: { label: 'Submit Button Label' }, - }, + stackbit: { + label: 'Footer Form', + labelField: 'title', + fields: { + ...footerSectionBaseFieldsExtension, + content: { label: 'Content' }, + form_id: { label: 'Form ID' }, + form_action: { label: 'Form Action' }, + hide_labels: { label: 'Hide Labels' }, + form_fields: { label: 'Form Fields' }, + submit_label: { label: 'Submit Button Label' }, }, }, })) @@ -223,14 +215,12 @@ const FooterNav = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Vertical Navigation', - labelField: 'title', - fields: { - ...footerSectionBaseFieldsExtension, - nav_links: { label: 'Vertical Navigation Links' }, - }, + stackbit: { + label: 'Vertical Navigation', + labelField: 'title', + fields: { + ...footerSectionBaseFieldsExtension, + nav_links: { label: 'Vertical Navigation Links' }, }, }, })) @@ -256,17 +246,15 @@ const FooterText = defineNestedType(() => ({ description: 'The text content of the section', }, }, - extensions: { - stackbit: { - label: 'Text', - labelField: 'title', - fields: { - ...footerSectionBaseFieldsExtension, - image: { label: 'Image' }, - image_alt: { label: 'Image Alt Text' }, - image_url: { label: 'Image URL' }, - content: { label: 'Content' }, - }, + stackbit: { + label: 'Text', + labelField: 'title', + fields: { + ...footerSectionBaseFieldsExtension, + image: { label: 'Image' }, + image_alt: { label: 'Image Alt Text' }, + image_url: { label: 'Image URL' }, + content: { label: 'Content' }, }, }, })) diff --git a/examples/archive/playground-azimuth/src/contentlayer/documents/Landing.ts b/examples/archive/playground-azimuth/src/contentlayer/documents/Landing.ts index dd12ef32..7e5a326e 100644 --- a/examples/archive/playground-azimuth/src/contentlayer/documents/Landing.ts +++ b/examples/archive/playground-azimuth/src/contentlayer/documents/Landing.ts @@ -40,15 +40,13 @@ export const Landing = defineDocumentType(() => ({ resolve: urlFromFilePath, }, }, - extensions: { - stackbit: { - label: 'Landing Page', - fields: { - title: { label: 'Title' }, - sections: { label: 'Sections' }, - }, - match: ['contact.md', 'features.md', 'index.md', 'pricing.md'], + stackbit: { + label: 'Landing Page', + fields: { + title: { label: 'Title' }, + sections: { label: 'Sections' }, }, + match: ['contact.md', 'features.md', 'index.md', 'pricing.md'], }, })) @@ -95,22 +93,20 @@ const SectionContent = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Content Section', - labelField: 'title', - fieldGroups: [ - { name: 'content', label: 'Content' }, - { name: 'design', label: 'Design' }, - ], - fields: { - ...sectionBaseFieldsExtension, - content: { label: 'Content', group: 'content' }, - image: { label: 'Image', group: 'content', control: { type: 'image-gallery', options: {} } }, - image_alt: { label: 'Image Alt Text', group: 'content' }, - background: { label: 'Background', group: 'design', control: { type: 'image-gallery', options: {} } }, - actions: { label: 'Action Buttons' }, - }, + stackbit: { + label: 'Content Section', + labelField: 'title', + fieldGroups: [ + { name: 'content', label: 'Content' }, + { name: 'design', label: 'Design' }, + ], + fields: { + ...sectionBaseFieldsExtension, + content: { label: 'Content', group: 'content' }, + image: { label: 'Image', group: 'content', control: { type: 'image-gallery', options: {} } }, + image_alt: { label: 'Image Alt Text', group: 'content' }, + background: { label: 'Background', group: 'design', control: { type: 'image-gallery', options: {} } }, + actions: { label: 'Action Buttons' }, }, }, })) @@ -128,15 +124,13 @@ const SectionCta = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Call to Action Section', - labelField: 'title', - fields: { - ...sectionBaseFieldsExtension, - subtitle: { label: 'Subtitle' }, - actions: { label: 'Action Buttons' }, - }, + stackbit: { + label: 'Call to Action Section', + labelField: 'title', + fields: { + ...sectionBaseFieldsExtension, + subtitle: { label: 'Subtitle' }, + actions: { label: 'Action Buttons' }, }, }, })) @@ -162,17 +156,15 @@ const SectionHero = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Hero Section', - labelField: 'title', - fields: { - ...sectionBaseFieldsExtension, - content: { label: 'Content' }, - image: { label: 'Image', control: { type: 'image-gallery', options: {} } }, - image_alt: { label: 'Image Alt Text' }, - actions: { label: 'Action Buttons' }, - }, + stackbit: { + label: 'Hero Section', + labelField: 'title', + fields: { + ...sectionBaseFieldsExtension, + content: { label: 'Content' }, + image: { label: 'Image', control: { type: 'image-gallery', options: {} } }, + image_alt: { label: 'Image Alt Text' }, + actions: { label: 'Action Buttons' }, }, }, })) @@ -196,16 +188,14 @@ const SectionFeatures = defineNestedType(() => ({ of: FeatureItem, }, }, - extensions: { - stackbit: { - label: 'Features Section', - labelField: 'title', - fields: { - ...sectionBaseFieldsExtension, - subtitle: { label: 'Subtitle' }, - background: { label: 'Background' }, - features: { label: 'Features' }, - }, + stackbit: { + label: 'Features Section', + labelField: 'title', + fields: { + ...sectionBaseFieldsExtension, + subtitle: { label: 'Subtitle' }, + background: { label: 'Background' }, + features: { label: 'Features' }, }, }, })) @@ -231,17 +221,15 @@ const FeatureItem = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Feature Item', - labelField: 'title', - fields: { - title: { label: 'Title' }, - content: { label: 'Content' }, - image: { label: 'Image', control: { type: 'image-gallery', options: {} } }, - image_alt: { label: 'Image Alt Text' }, - actions: { label: 'Action Buttons' }, - }, + stackbit: { + label: 'Feature Item', + labelField: 'title', + fields: { + title: { label: 'Title' }, + content: { label: 'Content' }, + image: { label: 'Image', control: { type: 'image-gallery', options: {} } }, + image_alt: { label: 'Image Alt Text' }, + actions: { label: 'Action Buttons' }, }, }, })) @@ -286,21 +274,19 @@ const SectionContact = defineNestedType(() => ({ required: true, }, }, - extensions: { - stackbit: { - label: 'Contact Section', - labelField: 'title', - fields: { - ...sectionBaseFieldsExtension, - subtitle: { label: 'Subtitle' }, - content: { label: 'Content' }, - background: { label: 'Background' }, - form_id: { label: 'Form ID' }, - form_action: { label: 'Form Action' }, - hide_labels: { label: 'Hide labels of the form fields?' }, - form_fields: { label: 'Form Fields' }, - submit_label: { label: 'Submit Button Label' }, - }, + stackbit: { + label: 'Contact Section', + labelField: 'title', + fields: { + ...sectionBaseFieldsExtension, + subtitle: { label: 'Subtitle' }, + content: { label: 'Content' }, + background: { label: 'Background' }, + form_id: { label: 'Form ID' }, + form_action: { label: 'Form Action' }, + hide_labels: { label: 'Hide labels of the form fields?' }, + form_fields: { label: 'Form Fields' }, + submit_label: { label: 'Submit Button Label' }, }, }, })) @@ -326,16 +312,14 @@ const SectionFaq = defineNestedType(() => ({ of: FaqItem, }, }, - extensions: { - stackbit: { - label: 'Contact Section', - labelField: 'title', - fields: { - ...sectionBaseFieldsExtension, - subtitle: { label: 'Subtitle' }, - background: { label: 'Background' }, - faq_items: { label: 'FAQ Items' }, - }, + stackbit: { + label: 'Contact Section', + labelField: 'title', + fields: { + ...sectionBaseFieldsExtension, + subtitle: { label: 'Subtitle' }, + background: { label: 'Background' }, + faq_items: { label: 'FAQ Items' }, }, }, })) @@ -346,13 +330,11 @@ const FaqItem = defineNestedType(() => ({ question: { type: 'string' }, answer: { type: 'markdown' }, }, - extensions: { - stackbit: { - label: 'FAQ Item', - fields: { - question: { label: 'Question' }, - answer: { label: 'Answer' }, - }, + stackbit: { + label: 'FAQ Item', + fields: { + question: { label: 'Question' }, + answer: { label: 'Answer' }, }, }, })) @@ -372,14 +354,12 @@ const SectionPosts = defineNestedType(() => ({ default: 'gray', }, }, - extensions: { - stackbit: { - label: 'Posts List', - fields: { - ...sectionBaseFieldsExtension, - subtitle: { label: 'Subtitle' }, - background: { label: 'Background' }, - }, + stackbit: { + label: 'Posts List', + fields: { + ...sectionBaseFieldsExtension, + subtitle: { label: 'Subtitle' }, + background: { label: 'Background' }, }, }, })) @@ -403,15 +383,13 @@ const SectionPricing = defineNestedType(() => ({ of: PricingPlan, }, }, - extensions: { - stackbit: { - label: 'Pricing Section', - fields: { - ...sectionBaseFieldsExtension, - subtitle: { label: 'Subtitle' }, - background: { label: 'Background' }, - pricing_plans: { label: 'Pricing Plans' }, - }, + stackbit: { + label: 'Pricing Section', + fields: { + ...sectionBaseFieldsExtension, + subtitle: { label: 'Subtitle' }, + background: { label: 'Background' }, + pricing_plans: { label: 'Pricing Plans' }, }, }, })) @@ -441,18 +419,16 @@ const PricingPlan = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Pricing Plan', - labelField: 'title', - fields: { - title: { label: 'Title' }, - subtitle: { label: 'Subtitle' }, - price: { label: 'Price' }, - details: { label: 'Details' }, - highlight: { label: 'Highlight' }, - actions: { label: 'Action Buttons' }, - }, + stackbit: { + label: 'Pricing Plan', + labelField: 'title', + fields: { + title: { label: 'Title' }, + subtitle: { label: 'Subtitle' }, + price: { label: 'Price' }, + details: { label: 'Details' }, + highlight: { label: 'Highlight' }, + actions: { label: 'Action Buttons' }, }, }, })) @@ -476,15 +452,13 @@ const SectionReviews = defineNestedType(() => ({ of: ReviewItem, }, }, - extensions: { - stackbit: { - label: 'Reviews Section', - fields: { - ...sectionBaseFieldsExtension, - subtitle: { label: 'Subtitle' }, - background: { label: 'Background' }, - reviews: { label: 'Reviews' }, - }, + stackbit: { + label: 'Reviews Section', + fields: { + ...sectionBaseFieldsExtension, + subtitle: { label: 'Subtitle' }, + background: { label: 'Background' }, + reviews: { label: 'Reviews' }, }, }, })) @@ -497,15 +471,13 @@ const ReviewItem = defineNestedType(() => ({ avatar_alt: { type: 'string' }, content: { type: 'string' }, }, - extensions: { - stackbit: { - label: 'Review Item', - fields: { - author: { label: 'Author' }, - avatar: { label: 'Author Image' }, - avatar_alt: { label: 'Author Image Alt Text' }, - content: { label: 'Content' }, - }, + stackbit: { + label: 'Review Item', + fields: { + author: { label: 'Author' }, + avatar: { label: 'Author Image' }, + avatar_alt: { label: 'Author Image Alt Text' }, + content: { label: 'Content' }, }, }, })) diff --git a/examples/archive/playground-azimuth/src/contentlayer/documents/Page.ts b/examples/archive/playground-azimuth/src/contentlayer/documents/Page.ts index 0336ce67..cff1f821 100644 --- a/examples/archive/playground-azimuth/src/contentlayer/documents/Page.ts +++ b/examples/archive/playground-azimuth/src/contentlayer/documents/Page.ts @@ -38,7 +38,5 @@ export const Page = defineDocumentType(() => ({ resolve: urlFromFilePath, }, }, - extensions: { - stackbit: { match: ['about.md', 'privacy-policy.md', 'signup.md', 'style-guide.md', 'terms-of-service.md'] }, - }, + stackbit: { match: ['about.md', 'privacy-policy.md', 'signup.md', 'style-guide.md', 'terms-of-service.md'] }, })) diff --git a/examples/archive/playground-azimuth/src/contentlayer/documents/Person.ts b/examples/archive/playground-azimuth/src/contentlayer/documents/Person.ts index f0e230a6..1b7331ff 100644 --- a/examples/archive/playground-azimuth/src/contentlayer/documents/Person.ts +++ b/examples/archive/playground-azimuth/src/contentlayer/documents/Person.ts @@ -9,7 +9,5 @@ export const Person = defineDocumentType(() => ({ bio: { type: 'markdown' }, photo: { type: 'string' }, }, - extensions: { - stackbit: { folder: 'authors' }, - }, + stackbit: { folder: 'authors' }, })) diff --git a/examples/archive/playground-azimuth/src/contentlayer/documents/Post.ts b/examples/archive/playground-azimuth/src/contentlayer/documents/Post.ts index 2de7a144..0d3db72b 100644 --- a/examples/archive/playground-azimuth/src/contentlayer/documents/Post.ts +++ b/examples/archive/playground-azimuth/src/contentlayer/documents/Post.ts @@ -56,19 +56,17 @@ export const Post = defineDocumentType(() => ({ resolve: urlFromFilePath, }, }, - extensions: { - stackbit: { - fields: { - title: { label: 'Title' }, - subtitle: { label: 'Subtitle' }, - date: { label: 'Date' }, - excerpt: { label: 'Excerpt' }, - image: { label: 'Image' }, - image_alt: { label: 'Image alt text (single post)' }, - thumb_image: { label: 'Image (blog feed)' }, - thumb_image_alt: { label: 'Image alt text (blog feed)' }, - }, - match: 'blog/**.md', + stackbit: { + fields: { + title: { label: 'Title' }, + subtitle: { label: 'Subtitle' }, + date: { label: 'Date' }, + excerpt: { label: 'Excerpt' }, + image: { label: 'Image' }, + image_alt: { label: 'Image alt text (single post)' }, + thumb_image: { label: 'Image (blog feed)' }, + thumb_image_alt: { label: 'Image alt text (blog feed)' }, }, + match: 'blog/**.md', }, })) diff --git a/examples/archive/playground-azimuth/src/contentlayer/nested/Action.ts b/examples/archive/playground-azimuth/src/contentlayer/nested/Action.ts index 8ab9864b..bb1caad3 100644 --- a/examples/archive/playground-azimuth/src/contentlayer/nested/Action.ts +++ b/examples/archive/playground-azimuth/src/contentlayer/nested/Action.ts @@ -52,19 +52,17 @@ export const Action = defineNestedType(() => ({ description: 'Add rel="nofollow" attribute to the link', }, }, - extensions: { - stackbit: { - labelField: 'label', - fields: { - label: { label: 'Label' }, - url: { label: 'URL' }, - style: { label: 'Style' }, - has_icon: { label: 'Show icon' }, - icon: { label: 'Icon' }, - icon_position: { label: 'Icon position' }, - new_window: { label: 'Open in new window' }, - no_follow: { label: 'No follow' }, - }, + stackbit: { + labelField: 'label', + fields: { + label: { label: 'Label' }, + url: { label: 'URL' }, + style: { label: 'Style' }, + has_icon: { label: 'Show icon' }, + icon: { label: 'Icon' }, + icon_position: { label: 'Icon position' }, + new_window: { label: 'Open in new window' }, + no_follow: { label: 'No follow' }, }, }, })) diff --git a/examples/archive/playground-azimuth/src/contentlayer/nested/FormField.ts b/examples/archive/playground-azimuth/src/contentlayer/nested/FormField.ts index 32d2508e..dd3e0fb1 100644 --- a/examples/archive/playground-azimuth/src/contentlayer/nested/FormField.ts +++ b/examples/archive/playground-azimuth/src/contentlayer/nested/FormField.ts @@ -32,18 +32,16 @@ export const FormField = defineNestedType(() => ({ default: false, }, }, - extensions: { - stackbit: { - label: 'Form Field', - labelField: 'name', - fields: { - input_type: { label: 'Type' }, - name: { label: 'Name' }, - label: { label: 'Label' }, - default_value: { label: 'Placeholder text or default value' }, - options: { label: 'Options' }, - is_required: { label: 'Is the field required?' }, - }, + stackbit: { + label: 'Form Field', + labelField: 'name', + fields: { + input_type: { label: 'Type' }, + name: { label: 'Name' }, + label: { label: 'Label' }, + default_value: { label: 'Placeholder text or default value' }, + options: { label: 'Options' }, + is_required: { label: 'Is the field required?' }, }, }, })) diff --git a/examples/archive/playground-azimuth/src/contentlayer/nested/SEO.ts b/examples/archive/playground-azimuth/src/contentlayer/nested/SEO.ts index 2e686411..4ac8af8a 100644 --- a/examples/archive/playground-azimuth/src/contentlayer/nested/SEO.ts +++ b/examples/archive/playground-azimuth/src/contentlayer/nested/SEO.ts @@ -25,15 +25,13 @@ export const SEO = defineNestedType(() => ({ of: Extra, }, }, - extensions: { - stackbit: { - label: 'Page meta data', - fields: { - title: { label: 'Title' }, - description: { label: 'Description' }, - robots: { label: 'Robots' }, - extra: { label: 'Extra' }, - }, + stackbit: { + label: 'Page meta data', + fields: { + title: { label: 'Title' }, + description: { label: 'Description' }, + robots: { label: 'Robots' }, + extra: { label: 'Extra' }, }, }, })) diff --git a/packages/@contentlayer/cli/package.json b/packages/@contentlayer/cli/package.json index de2a1e5c..78988889 100644 --- a/packages/@contentlayer/cli/package.json +++ b/packages/@contentlayer/cli/package.json @@ -1,6 +1,6 @@ { "name": "@contentlayer/cli", - "version": "0.2.5", + "version": "0.2.6-dev.8", "type": "module", "exports": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/packages/@contentlayer/cli/src/commands/PostInstallCommand.ts b/packages/@contentlayer/cli/src/commands/PostInstallCommand.ts index 4317a10c..1a703203 100644 --- a/packages/@contentlayer/cli/src/commands/PostInstallCommand.ts +++ b/packages/@contentlayer/cli/src/commands/PostInstallCommand.ts @@ -59,7 +59,7 @@ const generateTypes = ({ } const { source, esbuildHash } = sourceEither.right - const schemaDef = yield* $(source.provideSchema(esbuildHash)) + const schemaDef = yield* $(source.provideSchema({ esbuildHash })) if (!indexDtsFileExists) { yield* $(fs.writeFile(indexDtsFilePath, core.makeDataTypes({ schemaDef }))) diff --git a/packages/@contentlayer/client/package.json b/packages/@contentlayer/client/package.json index 3ed72abf..23974dca 100644 --- a/packages/@contentlayer/client/package.json +++ b/packages/@contentlayer/client/package.json @@ -1,6 +1,6 @@ { "name": "@contentlayer/client", - "version": "0.2.5", + "version": "0.2.6-dev.8", "type": "module", "exports": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/packages/@contentlayer/core/package.json b/packages/@contentlayer/core/package.json index 301ec983..da4a2526 100644 --- a/packages/@contentlayer/core/package.json +++ b/packages/@contentlayer/core/package.json @@ -1,6 +1,6 @@ { "name": "@contentlayer/core", - "version": "0.2.5", + "version": "0.2.6-dev.8", "type": "module", "exports": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/packages/@contentlayer/core/src/extensions.ts b/packages/@contentlayer/core/src/extensions.ts new file mode 100644 index 00000000..f459fae3 --- /dev/null +++ b/packages/@contentlayer/core/src/extensions.ts @@ -0,0 +1,16 @@ +declare global { + // TODO docs + interface ContentlayerExtensions { + // [extensionName: string]: { + // root: never + // documentType: never + // nestedType: never + // field: never + // } + } +} + +export type ExtensionsRoot = { [K in keyof ContentlayerExtensions]: ContentlayerExtensions[K]['root'] } +export type ExtensionsDocumentType = { [K in keyof ContentlayerExtensions]: ContentlayerExtensions[K]['documentType'] } +export type ExtensionsNestedType = { [K in keyof ContentlayerExtensions]: ContentlayerExtensions[K]['nestedType'] } +export type ExtensionsField = { [K in keyof ContentlayerExtensions]: ContentlayerExtensions[K]['field'] } diff --git a/packages/@contentlayer/core/src/generation/generate-dotpkg.ts b/packages/@contentlayer/core/src/generation/generate-dotpkg.ts index df3c0d9f..fc437ecb 100644 --- a/packages/@contentlayer/core/src/generation/generate-dotpkg.ts +++ b/packages/@contentlayer/core/src/generation/generate-dotpkg.ts @@ -76,7 +76,7 @@ export const generateDotpkgStream = ({ const generationOptions = { sourcePluginType: config.source.type, options: config.source.options } const resolveParams = pipe( T.structPar({ - schemaDef: config.source.provideSchema(config.esbuildHash), + schemaDef: config.source.provideSchema({ esbuildHash: config.esbuildHash }), targetPath: ArtifactsDir.mkdir, }), T.either, diff --git a/packages/@contentlayer/core/src/generation/generate-types.ts b/packages/@contentlayer/core/src/generation/generate-types.ts index 5a355d40..d91e3ed1 100644 --- a/packages/@contentlayer/core/src/generation/generate-types.ts +++ b/packages/@contentlayer/core/src/generation/generate-types.ts @@ -119,7 +119,7 @@ export const renderDocumentTypeDefOrNestedTypeDef = ({ const computedFields = (def._tag === 'DocumentTypeDef' ? def.computedFields : []) .map((field) => `${field.description ? ` /** ${field.description} */\n` : ''} ${field.name}: ${field.type}`) .join('\n') - const description = def.description ?? def.extensions.stackbit?.fields?.[def.name]?.label + const description = def.description const rawType = renderRawType({ sourcePluginType }) const idJsdoc = renderIdJsdoc({ sourcePluginType }) diff --git a/packages/@contentlayer/core/src/index.ts b/packages/@contentlayer/core/src/index.ts index 4c60b80b..400fb64f 100644 --- a/packages/@contentlayer/core/src/index.ts +++ b/packages/@contentlayer/core/src/index.ts @@ -3,6 +3,7 @@ export * from './generation/generate-types.js' export * from './DataCache.js' export * from './data-types.js' export * from './cwd.js' +export * from './extensions.js' export * from './gen.js' export * from './errors.js' export * from './getConfig/index.js' diff --git a/packages/@contentlayer/core/src/plugin.ts b/packages/@contentlayer/core/src/plugin.ts index a52c2c30..9aadd7fa 100644 --- a/packages/@contentlayer/core/src/plugin.ts +++ b/packages/@contentlayer/core/src/plugin.ts @@ -7,15 +7,11 @@ import type * as unified from 'unified' import type { HasCwd } from './cwd.js' import type { DataCache } from './DataCache.js' import type { SourceFetchDataError, SourceProvideSchemaError } from './errors.js' -import type { SchemaDef, StackbitExtension } from './schema/index.js' +import type { ExtensionsRoot } from './extensions.js' +import type { SchemaDef } from './schema/index.js' export type SourcePluginType = LiteralUnion<'local' | 'contentful' | 'sanity', string> -export type PluginExtensions = { - // TODO decentralized extension definitions + logic - stackbit?: StackbitExtension.Config -} - export type PluginOptions = { markdown: MarkdownOptions | MarkdownUnifiedBuilderCallback | undefined mdx: MDXOptions | undefined @@ -99,12 +95,13 @@ export type SourcePlugin = { fetchData: FetchData } & { options: PluginOptions - extensions: PluginExtensions + extensions: Partial } -export type ProvideSchema = ( - esbuildHash: string, -) => T.Effect +export type ProvideSchema = (_: { + esbuildHash: string + extensionProperties?: string[] +}) => T.Effect export type FetchData = (_: { schemaDef: SchemaDef verbose: boolean @@ -127,7 +124,6 @@ export type PartialArgs = { mdx?: MarkdownOptions | undefined date?: DateOptions | undefined fieldOptions?: Partial - extensions?: PluginExtensions disableImportAliasWarning?: boolean } @@ -139,11 +135,10 @@ export const defaultFieldOptions: FieldOptions = { export const processArgs = async ( argsOrArgsThunk: TArgs | Thunk | Thunk>, ): Promise<{ - extensions: PluginExtensions options: PluginOptions - restArgs: Omit + restArgs: Omit }> => { - const { extensions, fieldOptions, markdown, mdx, date, disableImportAliasWarning, ...restArgs } = + const { fieldOptions, markdown, mdx, date, disableImportAliasWarning, ...restArgs } = typeof argsOrArgsThunk === 'function' ? await argsOrArgsThunk() : argsOrArgsThunk const options: PluginOptions = { @@ -157,5 +152,5 @@ export const processArgs = async ( disableImportAliasWarning: disableImportAliasWarning ?? false, } - return { extensions: extensions ?? {}, options, restArgs } + return { options, restArgs } } diff --git a/packages/@contentlayer/core/src/schema/field.ts b/packages/@contentlayer/core/src/schema/field.ts index 60d9ec5a..6d6c5bac 100644 --- a/packages/@contentlayer/core/src/schema/field.ts +++ b/packages/@contentlayer/core/src/schema/field.ts @@ -1,3 +1,4 @@ +import type { ExtensionsField } from '../extensions.js' import type { NestedUnnamedTypeDef } from './index.js' export type FieldDefType = FieldDef['type'] @@ -36,6 +37,7 @@ export interface FieldDefBase { isRequired: boolean isSystemField: boolean + extensions: Partial } export interface ListFieldDef extends FieldDefBase { diff --git a/packages/@contentlayer/core/src/schema/index.ts b/packages/@contentlayer/core/src/schema/index.ts index 8ce85575..59ccad9a 100644 --- a/packages/@contentlayer/core/src/schema/index.ts +++ b/packages/@contentlayer/core/src/schema/index.ts @@ -1,13 +1,8 @@ import type { Document } from '../data-types.js' +import type { ExtensionsDocumentType, ExtensionsNestedType } from '../extensions.js' import type { FieldDef, FieldDefType } from './field.js' -import type { StackbitExtension } from './stackbit-extension.js' export * from './field.js' export * from './validate.js' -export * from './stackbit-extension.js' - -export type TypeDefExtensions = { - stackbit?: StackbitExtension.TypeExtension -} export type DocumentTypeDefMap = Record export type NestedTypeDefMap = Record @@ -27,7 +22,7 @@ export type DocumentTypeDef = { isSingleton: boolean fieldDefs: FieldDef[] computedFields: ComputedField[] - extensions: TypeDefExtensions + extensions: Partial } export type NestedTypeDef = { @@ -35,13 +30,13 @@ export type NestedTypeDef = { name: string description: string | undefined fieldDefs: FieldDef[] - extensions: TypeDefExtensions + extensions: Partial } export type NestedUnnamedTypeDef = { readonly _tag: 'NestedUnnamedTypeDef' fieldDefs: FieldDef[] - extensions: TypeDefExtensions + extensions: Partial } export type ComputedField = { diff --git a/packages/@contentlayer/core/src/schema/validate.ts b/packages/@contentlayer/core/src/schema/validate.ts index 06fe739a..a1ffdf83 100644 --- a/packages/@contentlayer/core/src/schema/validate.ts +++ b/packages/@contentlayer/core/src/schema/validate.ts @@ -5,15 +5,15 @@ export const validateSchema = (schema: SchemaDef): void => { Object.values(schema.nestedTypeDefMap).forEach((def) => validateDocumentOrObjectDef({ def })) } -const validateDocumentOrObjectDef = ({ def }: { def: DocumentTypeDef | NestedTypeDef }): void => { +const validateDocumentOrObjectDef = ({}: { def: DocumentTypeDef | NestedTypeDef }): void => { // TODO move out this code to a new stackbit extension package - const stackbitExt = def.extensions.stackbit - if (stackbitExt?.labelField) { - const noFieldFoundForLabelField = !def.fieldDefs.some((_) => _.name === stackbitExt.labelField) - if (noFieldFoundForLabelField) { - throw new Error( - `There is no field with the name "${stackbitExt.labelField}" as specified for "labelField" in ${def._tag} with the name "${def.name}"`, - ) - } - } + // const stackbitExt = def.extensions.stackbit + // if (stackbitExt?.labelField) { + // const noFieldFoundForLabelField = !def.fieldDefs.some((_) => _.name === stackbitExt.labelField) + // if (noFieldFoundForLabelField) { + // throw new Error( + // `There is no field with the name "${stackbitExt.labelField}" as specified for "labelField" in ${def._tag} with the name "${def.name}"`, + // ) + // } + // } } diff --git a/packages/@contentlayer/source-contentful/package.json b/packages/@contentlayer/source-contentful/package.json index 464d642d..47a4b9f6 100644 --- a/packages/@contentlayer/source-contentful/package.json +++ b/packages/@contentlayer/source-contentful/package.json @@ -1,6 +1,6 @@ { "name": "@contentlayer/source-contentful", - "version": "0.2.5", + "version": "0.2.6-dev.8", "type": "module", "exports": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/packages/@contentlayer/source-contentful/src/index.ts b/packages/@contentlayer/source-contentful/src/index.ts index c57cd1cb..f0cfef66 100644 --- a/packages/@contentlayer/source-contentful/src/index.ts +++ b/packages/@contentlayer/source-contentful/src/index.ts @@ -26,13 +26,12 @@ export type Args = { export const makeSourcePlugin: core.MakeSourcePlugin = async (args) => { const { options, - extensions, restArgs: { accessToken, spaceId, environmentId = 'master', schemaOverrides = {} }, } = await processArgs(args) return { type: 'contentful', - extensions, + extensions: {}, options, provideSchema: () => provideSchema({ accessToken, spaceId, environmentId, options, schemaOverrides }), fetchData: ({ schemaDef }) => diff --git a/packages/@contentlayer/source-contentful/src/provideSchema.ts b/packages/@contentlayer/source-contentful/src/provideSchema.ts index 33f5cc28..34ee54ee 100644 --- a/packages/@contentlayer/source-contentful/src/provideSchema.ts +++ b/packages/@contentlayer/source-contentful/src/provideSchema.ts @@ -146,6 +146,7 @@ const toFieldDef = ({ default: undefined, description: undefined, isSystemField: false, + extensions: {}, } if (fieldOverrides?.type) { diff --git a/packages/@contentlayer/source-files/package.json b/packages/@contentlayer/source-files/package.json index 1ff6c8a2..8a9e0e4c 100644 --- a/packages/@contentlayer/source-files/package.json +++ b/packages/@contentlayer/source-files/package.json @@ -1,6 +1,6 @@ { "name": "@contentlayer/source-files", - "version": "0.2.5", + "version": "0.2.6-dev.8", "type": "module", "exports": { ".": { @@ -45,7 +45,7 @@ "micromatch": "^4.0.5", "ts-pattern": "^4.0.2", "unified": "^10.1.2", - "yaml": "^1.10.2" + "yaml": "^2.1.0" }, "devDependencies": { "@types/faker": "^5.5.8", diff --git a/packages/@contentlayer/source-files/src/__test__/errors/utils.ts b/packages/@contentlayer/source-files/src/__test__/errors/utils.ts index b8cb69bc..b4049ac9 100644 --- a/packages/@contentlayer/source-files/src/__test__/errors/utils.ts +++ b/packages/@contentlayer/source-files/src/__test__/errors/utils.ts @@ -88,6 +88,7 @@ export const makeErrors = ( description: undefined, isRequired: true, isSystemField: false, + extensions: {}, } errors.push( new FetchDataError.MissingRequiredFieldsError({ diff --git a/packages/@contentlayer/source-files/src/__test__/fetchData/utils.ts b/packages/@contentlayer/source-files/src/__test__/fetchData/utils.ts index ef5530e5..ca6f5953 100644 --- a/packages/@contentlayer/source-files/src/__test__/fetchData/utils.ts +++ b/packages/@contentlayer/source-files/src/__test__/fetchData/utils.ts @@ -27,7 +27,7 @@ export const runTest = async ({ const esbuildHash = 'not-important-for-this-test' const source = yield* $(T.tryPromise(() => makeSource({ contentDirPath, documentTypes }))) - const coreSchemaDef = yield* $(source.provideSchema(esbuildHash)) + const coreSchemaDef = yield* $(source.provideSchema({ esbuildHash })) const documentTypeDefs = (Array.isArray(documentTypes) ? documentTypes : Object.values(documentTypes)).map((_) => _.def(), diff --git a/packages/@contentlayer/source-files/src/__test__/mapping.spec.ts b/packages/@contentlayer/source-files/src/__test__/mapping.spec.ts index 01da433f..494ca798 100644 --- a/packages/@contentlayer/source-files/src/__test__/mapping.spec.ts +++ b/packages/@contentlayer/source-files/src/__test__/mapping.spec.ts @@ -43,6 +43,7 @@ test('getDataForFieldDef', async () => { isRequired: false, default: undefined, description: undefined, + extensions: {}, }, relativeFilePath: __unusedValue, options: { @@ -94,6 +95,7 @@ test('getDataForFieldDef error', async () => { isRequired: false, default: undefined, description: undefined, + extensions: {}, }, relativeFilePath: unknownToPosixFilePath('some/path/doc.md'), options: { diff --git a/packages/@contentlayer/source-files/src/__test__/type-generation/basic.spec.ts b/packages/@contentlayer/source-files/src/__test__/type-generation/basic.spec.ts index c71ed7ea..57caadca 100644 --- a/packages/@contentlayer/source-files/src/__test__/type-generation/basic.spec.ts +++ b/packages/@contentlayer/source-files/src/__test__/type-generation/basic.spec.ts @@ -11,7 +11,7 @@ const renderTypeSource = async (documentTypes: DocumentTypes) => { const esbuildHash = 'not-important-for-this-test' const schemaDef = await pipe( T.tryPromise(() => makeSource({ documentTypes, contentDirPath: '' })), - T.chain((source) => source.provideSchema(esbuildHash)), + T.chain((source) => source.provideSchema({ esbuildHash })), provideJaegerTracing('contentlayer-cli'), provideConsole, T.runPromise, diff --git a/packages/@contentlayer/source-files/src/index.ts b/packages/@contentlayer/source-files/src/index.ts index 3e65b67a..4349c857 100644 --- a/packages/@contentlayer/source-files/src/index.ts +++ b/packages/@contentlayer/source-files/src/index.ts @@ -63,20 +63,15 @@ export type Args = { */ contentDirExclude?: string[] // NOTE https://github.com/parcel-bundler/watcher/issues/64 - +} & PluginOptions & + Partial & /** * This is an experimental feature and should be ignored for now. - */ - extensions?: { - stackbit?: core.StackbitExtension.Config - } -} & PluginOptions & - Partial + */ Partial export const makeSource: core.MakeSourcePlugin = async (args) => { const { options, - extensions, restArgs: { documentTypes, contentDirPath, @@ -85,6 +80,7 @@ export const makeSource: core.MakeSourcePlugin = async (args) => { onUnknownDocuments = 'skip-warn', onMissingOrIncompatibleData = 'skip-warn', onExtraFieldData = 'warn', + ...restArgs }, } = await processArgs(args) @@ -96,11 +92,12 @@ export const makeSource: core.MakeSourcePlugin = async (args) => { return { type: 'local', - extensions: extensions ?? {}, + // NOTE this is a pretty hacky solution that doesn't use the `extensionProperties` concept. We should revisit this. + extensions: { ...restArgs }, options, - provideSchema: (esbuildHash) => + provideSchema: ({ esbuildHash, extensionProperties = [] }) => pipe( - makeCoreSchema({ documentTypeDefs, options, esbuildHash }), + makeCoreSchema({ documentTypeDefs, options, esbuildHash, extensionProperties }), T.mapError((error) => new SourceProvideSchemaError({ error })), ), fetchData: ({ schemaDef, verbose }) => diff --git a/packages/@contentlayer/source-files/src/schema/defs/field.ts b/packages/@contentlayer/source-files/src/schema/defs/field.ts index fa044002..a6f3c17c 100644 --- a/packages/@contentlayer/source-files/src/schema/defs/field.ts +++ b/packages/@contentlayer/source-files/src/schema/defs/field.ts @@ -1,3 +1,5 @@ +import type { ExtensionsField } from '@contentlayer/core' + import type { DocumentType, NestedType } from './index.js' export type FieldDefType = FieldDef['type'] @@ -25,7 +27,7 @@ export type FieldDef = * Field name should contain only alphanumeric characters, underscore and a hyphen [A-Za-z0-9_]. * Must start with a letter. Must not end with an underscore or a hyphen. */ -interface FieldDefBase { +interface FieldDefBase extends Partial { /** Short description to editors how the field is to be used */ description?: string diff --git a/packages/@contentlayer/source-files/src/schema/defs/index.ts b/packages/@contentlayer/source-files/src/schema/defs/index.ts index e19ecca1..7f731c9c 100644 --- a/packages/@contentlayer/source-files/src/schema/defs/index.ts +++ b/packages/@contentlayer/source-files/src/schema/defs/index.ts @@ -1,4 +1,4 @@ -import type * as core from '@contentlayer/core' +import type { ExtensionsDocumentType, ExtensionsNestedType } from '@contentlayer/core' import type { Thunk } from '@contentlayer/utils' import type { ComputedField } from './computed-field.js' @@ -12,9 +12,9 @@ export type SchemaDef = { export type DocumentContentType = 'markdown' | 'mdx' | 'data' -export type TypeExtensions = { - stackbit?: core.StackbitExtension.TypeExtension -} +// export type TypeExtensions = { +// stackbit?: core.StackbitExtension.TypeExtension +// } export type FieldDefs = Record | FieldDefWithName[] @@ -43,8 +43,8 @@ export type DocumentTypeDef = { isSingleton?: boolean - extensions?: TypeExtensions -} + // extensions?: TypeExtensions +} & Partial export type ComputedFields = Record> @@ -53,16 +53,16 @@ export type NestedTypeDef = { name: DefName description?: string fields: FieldDefs - extensions?: TypeExtensions -} + // extensions?: TypeExtensions +} & Partial export const isNestedTypeDef = (_: NestedTypeDef | NestedUnnamedTypeDef): _ is NestedTypeDef => _.hasOwnProperty('name') export type NestedUnnamedTypeDef = { // type: 'NestedUnnamedTypeDef' fields: FieldDefs - extensions?: TypeExtensions -} + // extensions?: TypeExtensions +} & Partial export const isNestedUnnamedTypeDef = (_: NestedTypeDef | NestedUnnamedTypeDef): _ is NestedUnnamedTypeDef => !_.hasOwnProperty('name') diff --git a/packages/@contentlayer/source-files/src/schema/provideSchema.ts b/packages/@contentlayer/source-files/src/schema/provideSchema.ts index bf57c77e..020b1f9a 100644 --- a/packages/@contentlayer/source-files/src/schema/provideSchema.ts +++ b/packages/@contentlayer/source-files/src/schema/provideSchema.ts @@ -1,5 +1,6 @@ import * as core from '@contentlayer/core' import * as utils from '@contentlayer/utils' +import { pick } from '@contentlayer/utils' import { identity, T } from '@contentlayer/utils/effect' import type { SchemaError } from '../errors/index.js' @@ -10,10 +11,12 @@ export const makeCoreSchema = ({ documentTypeDefs, options, esbuildHash, + extensionProperties, }: { documentTypeDefs: LocalSchema.DocumentTypeDef[] options: core.PluginOptions esbuildHash: string + extensionProperties: string[] }): T.Effect => T.gen(function* ($) { const coreDocumentTypeDefMap: core.DocumentTypeDefMap = {} @@ -23,7 +26,7 @@ export const makeCoreSchema = ({ validateDefName({ defName: documentDef.name }) const fieldDefs = getFieldDefEntries(documentDef.fields).map((_) => - fieldDefEntryToCoreFieldDef(_, options.fieldOptions), + fieldDefEntryToCoreFieldDef(_, options.fieldOptions, extensionProperties), ) if (fieldDefs.some((_) => _.name === options.fieldOptions.bodyFieldName)) { @@ -39,6 +42,7 @@ export const makeCoreSchema = ({ default: undefined, isRequired: true, isSystemField: true, + extensions: {}, // NOTE extensions are not yet supported for body field }) } @@ -51,6 +55,7 @@ export const makeCoreSchema = ({ default: undefined, isRequired: true, isSystemField: true, + extensions: {}, // NOTE extensions are not yet supported for body field }) } @@ -69,7 +74,7 @@ export const makeCoreSchema = ({ isSingleton: documentDef.isSingleton ?? false, fieldDefs, computedFields, - extensions: documentDef.extensions ?? {}, + extensions: pick(documentDef, extensionProperties as any), } coreDocumentTypeDefMap[documentDef.name] = coreDocumentDef } @@ -83,9 +88,9 @@ export const makeCoreSchema = ({ ...utils.pick(nestedDef, ['description']), name: nestedDef.name, fieldDefs: getFieldDefEntries(nestedDef.fields).map((_) => - fieldDefEntryToCoreFieldDef(_, options.fieldOptions), + fieldDefEntryToCoreFieldDef(_, options.fieldOptions, extensionProperties), ), - extensions: nestedDef.extensions ?? {}, + extensions: pick(nestedDef, extensionProperties as any), } coreNestedTypeDefMap[coreNestedTypeDef.name] = coreNestedTypeDef } @@ -133,12 +138,14 @@ type FieldDefEntry = [fieldName: string, fieldDef: LocalSchema.FieldDef] const fieldDefEntryToCoreFieldDef = ( [name, fieldDef]: FieldDefEntry, fieldOptions: core.FieldOptions, + extensionProperties: string[], ): core.FieldDef => { const baseFields: core.FieldDefBase = { ...utils.pick(fieldDef, ['type', 'default', 'description']), name, isRequired: fieldDef.required ?? false, isSystemField: false, + extensions: pick(fieldDef, extensionProperties as any), } switch (fieldDef.type) { case 'list': @@ -148,7 +155,7 @@ const fieldDefEntryToCoreFieldDef = ( type: 'list_polymorphic', default: fieldDef.default, typeField: fieldDef.typeField ?? fieldOptions.typeFieldName, - of: fieldDef.of.map((_) => fieldListItemsToCoreFieldListDefItems(_, fieldOptions)), + of: fieldDef.of.map((_) => fieldListItemsToCoreFieldListDefItems(_, fieldOptions, extensionProperties)), }) } @@ -156,7 +163,7 @@ const fieldDefEntryToCoreFieldDef = ( ...baseFields, type: 'list', default: fieldDef.default, - of: fieldListItemsToCoreFieldListDefItems(fieldDef.of, fieldOptions), + of: fieldListItemsToCoreFieldListDefItems(fieldDef.of, fieldOptions, extensionProperties), }) case 'nested': if (LocalSchema.isNestedPolymorphicFieldDef(fieldDef)) { @@ -186,9 +193,9 @@ const fieldDefEntryToCoreFieldDef = ( } const fieldDefs = getFieldDefEntries(nestedTypeDef.fields).map((_) => - fieldDefEntryToCoreFieldDef(_, fieldOptions), + fieldDefEntryToCoreFieldDef(_, fieldOptions, extensionProperties), ) - const extensions = nestedTypeDef.extensions ?? {} + const extensions = pick(nestedTypeDef, extensionProperties as any) const typeDef: core.NestedUnnamedTypeDef = { _tag: 'NestedUnnamedTypeDef', fieldDefs, extensions } return identity({ ...baseFields, @@ -223,22 +230,27 @@ const fieldDefEntryToCoreFieldDef = ( }) case 'boolean': case 'date': - // case 'image': case 'json': case 'markdown': case 'mdx': case 'number': - // case 'slug': case 'string': - // case 'text': - // case 'url': - return { - // needs to pick again since fieldDef.type has been + return identity< + | core.BooleanFieldDef + | core.DateFieldDef + | core.JSONFieldDef + | core.MarkdownFieldDef + | core.MDXFieldDef + | core.NumberFieldDef + | core.StringFieldDef + >({ + // NOTE need to pick again since `fieldDef.type` is polymorphic (TS limitation?) ...utils.pick(fieldDef, ['type', 'default', 'description']), isRequired: fieldDef.required ?? false, name, isSystemField: false, - } + extensions: pick(fieldDef, extensionProperties as any), + }) default: utils.casesHandled(fieldDef) } @@ -247,6 +259,7 @@ const fieldDefEntryToCoreFieldDef = ( const fieldListItemsToCoreFieldListDefItems = ( listFieldDefItem: LocalSchema.ListFieldDefItem.Item, fieldOptions: core.FieldOptions, + extensionProperties: string[], ): core.ListFieldDefItem.Item => { switch (listFieldDefItem.type) { case 'boolean': @@ -264,9 +277,9 @@ const fieldListItemsToCoreFieldListDefItems = ( } const fieldDefs = getFieldDefEntries(nestedTypeDef.fields).map((_) => - fieldDefEntryToCoreFieldDef(_, fieldOptions), + fieldDefEntryToCoreFieldDef(_, fieldOptions, extensionProperties), ) - const extensions = nestedTypeDef.extensions ?? {} + const extensions = pick(nestedTypeDef, extensionProperties as any) const typeDef: core.NestedUnnamedTypeDef = { _tag: 'NestedUnnamedTypeDef', fieldDefs, extensions } return { type: 'nested_unnamed', typeDef } case 'document': diff --git a/packages/@contentlayer/source-sanity/package.json b/packages/@contentlayer/source-sanity/package.json index 4790c8c2..ecae3441 100644 --- a/packages/@contentlayer/source-sanity/package.json +++ b/packages/@contentlayer/source-sanity/package.json @@ -1,6 +1,6 @@ { "name": "@contentlayer/source-sanity", - "version": "0.2.5", + "version": "0.2.6-dev.8", "type": "module", "exports": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/packages/@contentlayer/source-sanity/src/index.ts b/packages/@contentlayer/source-sanity/src/index.ts index 456de0d5..287f1279 100644 --- a/packages/@contentlayer/source-sanity/src/index.ts +++ b/packages/@contentlayer/source-sanity/src/index.ts @@ -15,14 +15,13 @@ type Args = { export const makeSourcePlugin: core.MakeSourcePlugin = async (args) => { const { - extensions, options, restArgs: { studioDirPath }, } = await core.processArgs(args) return { type: 'sanity', - extensions, + extensions: {}, options, provideSchema: provideSchema({ studioDirPath, options }) as any, fetchData: ({ watch }: any) => { diff --git a/packages/@contentlayer/source-sanity/src/provideSchema.ts b/packages/@contentlayer/source-sanity/src/provideSchema.ts index b61db382..544b31db 100644 --- a/packages/@contentlayer/source-sanity/src/provideSchema.ts +++ b/packages/@contentlayer/source-sanity/src/provideSchema.ts @@ -177,6 +177,7 @@ const sanityFieldToCoreFieldDef = of: field.of.map(sanityArrayOfToCoreFieldListDefItem(objectTypeNames)), typeField: '_type', default: undefined, + extensions: {}, } case 'object': return { @@ -207,6 +208,7 @@ const sanityFieldToCoreFieldDef = default: undefined, // label: field.title, // hidden: field.hidden, + extensions: {}, } } } diff --git a/packages/@contentlayer/utils/package.json b/packages/@contentlayer/utils/package.json index 6fd0ce3d..d573e56c 100644 --- a/packages/@contentlayer/utils/package.json +++ b/packages/@contentlayer/utils/package.json @@ -1,6 +1,6 @@ { "name": "@contentlayer/utils", - "version": "0.2.5", + "version": "0.2.6-dev.8", "type": "module", "exports": { "./package.json": { diff --git a/packages/@contentlayer/utils/src/index.ts b/packages/@contentlayer/utils/src/index.ts index b31e98ec..a8bae68a 100644 --- a/packages/@contentlayer/utils/src/index.ts +++ b/packages/@contentlayer/utils/src/index.ts @@ -8,6 +8,16 @@ export * from './single-item.js' export * from './file-paths.js' export * from './tracing-effect/index.js' +declare global { + type TODO = any +} + +export type DeepPartial = T extends object + ? { + [P in keyof T]?: DeepPartial + } + : T + export { AsciiTree } from 'oo-ascii-tree' export * as pattern from 'ts-pattern' import { Tagged } from '@effect-ts/core/Case' diff --git a/packages/contentlayer-stackbit-yaml-generator/bin/cli.cjs b/packages/contentlayer-stackbit-yaml-generator/bin/cli.cjs index 3d89c188..5daf76cf 100755 --- a/packages/contentlayer-stackbit-yaml-generator/bin/cli.cjs +++ b/packages/contentlayer-stackbit-yaml-generator/bin/cli.cjs @@ -1,7 +1,7 @@ #!/usr/bin/env node const main = async () => { - const { run } = await import('../dist/cli') + const { run } = await import('../dist/cli/index.js') await run() } diff --git a/packages/contentlayer-stackbit-yaml-generator/package.json b/packages/contentlayer-stackbit-yaml-generator/package.json index a8aa9e54..182b101e 100644 --- a/packages/contentlayer-stackbit-yaml-generator/package.json +++ b/packages/contentlayer-stackbit-yaml-generator/package.json @@ -1,10 +1,20 @@ { "name": "contentlayer-stackbit-yaml-generator", - "version": "0.2.5", + "version": "0.2.6-dev.8", "type": "module", - "bin": "./dist/cli/index.js", - "exports": "./dist/lib/index.js", + "bin": "./bin/cli.cjs", + "exports": { + ".": "./dist/lib/index.js", + "./types": "./dist/types/index.js" + }, "types": "./dist/lib/index.d.ts", + "typesVersions": { + "*": { + "types": [ + "./dist/types" + ] + } + }, "files": [ "./dist/*.{js,ts,map}", "./dist/!(__test__)/**/*.{js,ts,map}", @@ -20,7 +30,7 @@ "@stackbit/sdk": "^0.2.32", "clipanion": "^3.2.0-rc.11", "typanion": "3.8.0", - "yaml": "^1.10.2" + "yaml": "^2.1.0" }, "devDependencies": { "contentlayer": "workspace:*", diff --git a/packages/contentlayer-stackbit-yaml-generator/src/__test__/__snapshots__/convert.spec.ts.snap b/packages/contentlayer-stackbit-yaml-generator/src/__test__/__snapshots__/convert.spec.ts.snap index dc2294c5..e56cf41a 100644 --- a/packages/contentlayer-stackbit-yaml-generator/src/__test__/__snapshots__/convert.spec.ts.snap +++ b/packages/contentlayer-stackbit-yaml-generator/src/__test__/__snapshots__/convert.spec.ts.snap @@ -14,20 +14,12 @@ exports[`azimuth schema 1`] = ` }, ], "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "title": { - "label": "Title", - }, - }, - "file": "blog.md", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "The title of the page", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "title", @@ -36,6 +28,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "seo", @@ -45,6 +38,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "Markdown file body", + "extensions": {}, "isRequired": true, "isSystemField": true, "name": "body", @@ -58,43 +52,12 @@ exports[`azimuth schema 1`] = ` "_tag": "DocumentTypeDef", "computedFields": [], "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "base_font": { - "label": "Font", - }, - "domain": { - "label": "Domain", - }, - "favicon": { - "label": "Favicon", - }, - "footer": { - "label": "Footer Configuration", - }, - "header": { - "label": "Header Configuration", - }, - "palette": { - "label": "Color Palette", - }, - "path_prefix": { - "hidden": true, - "label": "Base URL", - }, - "title": { - "label": "Title", - }, - }, - "file": "config.json", - "label": "Site Configuration", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "Site title", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "title", @@ -103,6 +66,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The base URL of this site. Useful for sites hosted under specific path, e.g.: https://www.example.com/my-site/", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "path_prefix", @@ -111,6 +75,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The domain of your site, including the protocol, e.g. https://mysite.com/", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "domain", @@ -119,6 +84,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "A square icon that represents your website", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "favicon", @@ -127,6 +93,7 @@ exports[`azimuth schema 1`] = ` { "default": "blue", "description": "The color palette of the site", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "palette", @@ -142,6 +109,7 @@ exports[`azimuth schema 1`] = ` { "default": "nunito-sans", "description": undefined, + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "base_font", @@ -155,6 +123,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "header", @@ -164,6 +133,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "footer", @@ -173,6 +143,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "Markdown file body", + "extensions": {}, "isRequired": true, "isSystemField": true, "name": "body", @@ -193,29 +164,12 @@ exports[`azimuth schema 1`] = ` }, ], "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "sections": { - "label": "Sections", - }, - "title": { - "label": "Title", - }, - }, - "label": "Landing Page", - "match": [ - "contact.md", - "features.md", - "index.md", - "pricing.md", - ], - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "The title of the page", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "title", @@ -224,6 +178,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "Page sections", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "sections", @@ -271,6 +226,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "seo", @@ -280,6 +236,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "Markdown file body", + "extensions": {}, "isRequired": true, "isSystemField": true, "name": "body", @@ -300,21 +257,12 @@ exports[`azimuth schema 1`] = ` }, ], "description": undefined, - "extensions": { - "stackbit": { - "match": [ - "about.md", - "privacy-policy.md", - "signup.md", - "style-guide.md", - "terms-of-service.md", - ], - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "The title of the page", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "title", @@ -323,6 +271,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The text shown below the page title", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "subtitle", @@ -331,6 +280,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The image shown below the page title", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "image", @@ -339,6 +289,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The alt text of the image", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "image_alt", @@ -347,6 +298,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "seo", @@ -356,6 +308,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "Markdown file body", + "extensions": {}, "isRequired": true, "isSystemField": true, "name": "body", @@ -369,15 +322,12 @@ exports[`azimuth schema 1`] = ` "_tag": "DocumentTypeDef", "computedFields": [], "description": undefined, - "extensions": { - "stackbit": { - "folder": "authors", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "first_name", @@ -386,6 +336,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "last_name", @@ -394,6 +345,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "bio", @@ -402,6 +354,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "photo", @@ -410,6 +363,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "Markdown file body", + "extensions": {}, "isRequired": true, "isSystemField": true, "name": "body", @@ -430,41 +384,12 @@ exports[`azimuth schema 1`] = ` }, ], "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "date": { - "label": "Date", - }, - "excerpt": { - "label": "Excerpt", - }, - "image": { - "label": "Image", - }, - "image_alt": { - "label": "Image alt text (single post)", - }, - "subtitle": { - "label": "Subtitle", - }, - "thumb_image": { - "label": "Image (blog feed)", - }, - "thumb_image_alt": { - "label": "Image alt text (blog feed)", - }, - "title": { - "label": "Title", - }, - }, - "match": "blog/**.md", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "The title of the post", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "title", @@ -473,6 +398,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The text shown just below the title or the featured image", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "subtitle", @@ -481,6 +407,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "date", @@ -491,6 +418,7 @@ exports[`azimuth schema 1`] = ` "description": "Post author", "documentTypeName": "Person", "embedDocument": false, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "author", @@ -499,6 +427,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The excerpt of the post displayed in the blog feed", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "excerpt", @@ -507,6 +436,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The image shown below the title", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "image", @@ -515,6 +445,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The alt text of the featured image", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "image_alt", @@ -523,6 +454,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The image shown in the blog feed", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "thumb_image", @@ -531,6 +463,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The alt text of the blog feed image", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "thumb_image_alt", @@ -539,6 +472,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "seo", @@ -548,6 +482,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "Markdown file body", + "extensions": {}, "isRequired": true, "isSystemField": true, "name": "body", @@ -563,41 +498,12 @@ exports[`azimuth schema 1`] = ` "Action": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "has_icon": { - "label": "Show icon", - }, - "icon": { - "label": "Icon", - }, - "icon_position": { - "label": "Icon position", - }, - "label": { - "label": "Label", - }, - "new_window": { - "label": "Open in new window", - }, - "no_follow": { - "label": "No follow", - }, - "style": { - "label": "Style", - }, - "url": { - "label": "URL", - }, - }, - "labelField": "label", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "label", @@ -606,6 +512,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "url", @@ -614,6 +521,7 @@ exports[`azimuth schema 1`] = ` { "default": "link", "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "style", @@ -627,6 +535,7 @@ exports[`azimuth schema 1`] = ` { "default": false, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "has_icon", @@ -635,6 +544,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "icon", @@ -655,6 +565,7 @@ exports[`azimuth schema 1`] = ` { "default": "left", "description": "The position of the icon relative to text", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "icon_position", @@ -667,6 +578,7 @@ exports[`azimuth schema 1`] = ` { "default": false, "description": "Should the link open a new tab", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "new_window", @@ -675,6 +587,7 @@ exports[`azimuth schema 1`] = ` { "default": false, "description": "Add rel=\\"nofollow\\" attribute to the link", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "no_follow", @@ -686,23 +599,12 @@ exports[`azimuth schema 1`] = ` "FaqItem": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "answer": { - "label": "Answer", - }, - "question": { - "label": "Question", - }, - }, - "label": "FAQ Item", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "question", @@ -711,6 +613,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "answer", @@ -722,37 +625,12 @@ exports[`azimuth schema 1`] = ` "FeatureItem": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "actions": { - "label": "Action Buttons", - }, - "content": { - "label": "Content", - }, - "image": { - "control": { - "options": {}, - "type": "image-gallery", - }, - "label": "Image", - }, - "image_alt": { - "label": "Image Alt Text", - }, - "title": { - "label": "Title", - }, - }, - "label": "Feature Item", - "labelField": "title", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "title", @@ -761,6 +639,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "Feature description", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "content", @@ -769,6 +648,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "Feature image", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "image", @@ -777,6 +657,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The alt text of the feature image", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "image_alt", @@ -785,6 +666,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "actions", @@ -800,33 +682,12 @@ exports[`azimuth schema 1`] = ` "Footer": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "content": { - "label": "Footer Content", - }, - "has_nav": { - "label": "Enable Horizontal Navigation", - }, - "links": { - "label": "Links", - }, - "nav_links": { - "label": "Horizontal Navigation Links", - }, - "sections": { - "label": "Sections", - }, - }, - "label": "Footer Configuration", - "labelField": "content", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "Footer sections", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "sections", @@ -850,6 +711,7 @@ exports[`azimuth schema 1`] = ` { "default": true, "description": "Display the horizontal navigation menu bar in the footer", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "has_nav", @@ -858,6 +720,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "List of horizontal navigation links", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "nav_links", @@ -870,6 +733,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The copyright text displayed in the footer", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "content", @@ -878,6 +742,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "A list of links displayed in the footer", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "links", @@ -893,42 +758,12 @@ exports[`azimuth schema 1`] = ` "FooterForm": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "content": { - "label": "Content", - }, - "form_action": { - "label": "Form Action", - }, - "form_fields": { - "label": "Form Fields", - }, - "form_id": { - "label": "Form ID", - }, - "hide_labels": { - "label": "Hide Labels", - }, - "submit_label": { - "label": "Submit Button Label", - }, - "title": { - "label": "Title", - }, - "type": { - "label": "Section type", - }, - }, - "label": "Footer Form", - "labelField": "title", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "The title of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "title", @@ -937,6 +772,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "Needed for contentlayer for polymorphic list types", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "type", @@ -945,6 +781,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The content of the section, appears above the form", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "content", @@ -953,6 +790,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "A unique identifier of the form, must not contain whitespace", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "form_id", @@ -961,6 +799,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The path of your custom \\"success\\" page, if you want to replace the default success message./index.js", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "form_action", @@ -969,6 +808,7 @@ exports[`azimuth schema 1`] = ` { "default": false, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "hide_labels", @@ -977,6 +817,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "form_fields", @@ -989,6 +830,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "submit_label", @@ -1000,27 +842,12 @@ exports[`azimuth schema 1`] = ` "FooterNav": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "nav_links": { - "label": "Vertical Navigation Links", - }, - "title": { - "label": "Title", - }, - "type": { - "label": "Section type", - }, - }, - "label": "Vertical Navigation", - "labelField": "title", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "The title of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "title", @@ -1029,6 +856,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "Needed for contentlayer for polymorphic list types", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "type", @@ -1037,6 +865,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "List of vertical navigation links", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "nav_links", @@ -1052,36 +881,12 @@ exports[`azimuth schema 1`] = ` "FooterText": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "content": { - "label": "Content", - }, - "image": { - "label": "Image", - }, - "image_alt": { - "label": "Image Alt Text", - }, - "image_url": { - "label": "Image URL", - }, - "title": { - "label": "Title", - }, - "type": { - "label": "Section type", - }, - }, - "label": "Text", - "labelField": "title", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "The title of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "title", @@ -1090,6 +895,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "Needed for contentlayer for polymorphic list types", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "type", @@ -1098,6 +904,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The image displayed in the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "image", @@ -1106,6 +913,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The alt text of the image", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "image_alt", @@ -1114,6 +922,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The url of the image", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "image_url", @@ -1122,6 +931,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The text content of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "content", @@ -1133,36 +943,12 @@ exports[`azimuth schema 1`] = ` "FormField": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "default_value": { - "label": "Placeholder text or default value", - }, - "input_type": { - "label": "Type", - }, - "is_required": { - "label": "Is the field required?", - }, - "label": { - "label": "Label", - }, - "name": { - "label": "Name", - }, - "options": { - "label": "Options", - }, - }, - "label": "Form Field", - "labelField": "name", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "Type of the form field", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "input_type", @@ -1180,6 +966,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The name of the field, submitted with the form", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "name", @@ -1188,6 +975,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The caption of the field, shown above the field input", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "label", @@ -1196,6 +984,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The placeholder for textual field types or default option for select field", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "default_value", @@ -1204,6 +993,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The list of options for select field", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "options", @@ -1215,6 +1005,7 @@ exports[`azimuth schema 1`] = ` { "default": false, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "is_required", @@ -1226,29 +1017,12 @@ exports[`azimuth schema 1`] = ` "Header": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "has_nav": { - "label": "Enable Navigation", - }, - "logo_img": { - "label": "Logo", - }, - "logo_img_alt": { - "label": "Logo Alt Text", - }, - "nav_links": { - "label": "Navigation Links", - }, - }, - "label": "Header Configuration", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "The logo image displayed in the header (if no logo added, the site title is displayed instead)", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "logo_img", @@ -1257,6 +1031,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The alt text of the logo image", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "logo_img_alt", @@ -1265,6 +1040,7 @@ exports[`azimuth schema 1`] = ` { "default": true, "description": "Display the navigation menu bar in the header", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "has_nav", @@ -1273,6 +1049,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "List of navigation links", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "nav_links", @@ -1288,36 +1065,12 @@ exports[`azimuth schema 1`] = ` "PricingPlan": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "actions": { - "label": "Action Buttons", - }, - "details": { - "label": "Details", - }, - "highlight": { - "label": "Highlight", - }, - "price": { - "label": "Price", - }, - "subtitle": { - "label": "Subtitle", - }, - "title": { - "label": "Title", - }, - }, - "label": "Pricing Plan", - "labelField": "title", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "title", @@ -1326,6 +1079,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "subtitle", @@ -1334,6 +1088,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "price", @@ -1342,6 +1097,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "details", @@ -1350,6 +1106,7 @@ exports[`azimuth schema 1`] = ` { "default": false, "description": "Make the plan stand out by adding a distinctive style", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "highlight", @@ -1358,6 +1115,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "actions", @@ -1373,29 +1131,12 @@ exports[`azimuth schema 1`] = ` "ReviewItem": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "author": { - "label": "Author", - }, - "avatar": { - "label": "Author Image", - }, - "avatar_alt": { - "label": "Author Image Alt Text", - }, - "content": { - "label": "Content", - }, - }, - "label": "Review Item", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "author", @@ -1404,6 +1145,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "avatar", @@ -1412,6 +1154,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "avatar_alt", @@ -1420,6 +1163,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "content", @@ -1431,29 +1175,12 @@ exports[`azimuth schema 1`] = ` "SEO": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "description": { - "label": "Description", - }, - "extra": { - "label": "Extra", - }, - "robots": { - "label": "Robots", - }, - "title": { - "label": "Title", - }, - }, - "label": "Page meta data", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "The page title that goes into the tag", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "title", @@ -1462,6 +1189,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The page description that goes into the <meta name=\\"description\\"> tag", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "description", @@ -1470,6 +1198,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The items that go into the <meta name=\\"robots\\"> tag", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "robots", @@ -1491,6 +1220,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "Additional definition for specific meta tags such as open-graph, twitter, etc.", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "extra", @@ -1503,6 +1233,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "name", @@ -1511,6 +1242,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "value", @@ -1519,6 +1251,7 @@ exports[`azimuth schema 1`] = ` { "default": "name", "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "keyName", @@ -1527,6 +1260,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "relativeUrl", @@ -1543,51 +1277,12 @@ exports[`azimuth schema 1`] = ` "SectionContact": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "background": { - "label": "Background", - }, - "content": { - "label": "Content", - }, - "form_action": { - "label": "Form Action", - }, - "form_fields": { - "label": "Form Fields", - }, - "form_id": { - "label": "Form ID", - }, - "hide_labels": { - "label": "Hide labels of the form fields?", - }, - "section_id": { - "label": "Section ID", - }, - "submit_label": { - "label": "Submit Button Label", - }, - "subtitle": { - "label": "Subtitle", - }, - "title": { - "label": "Title", - }, - "type": { - "label": "Section type", - }, - }, - "label": "Contact Section", - "labelField": "title", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "A unique identifier of the section, must not contain whitespace", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "section_id", @@ -1596,22 +1291,16 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The title of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "title", "type": "string", }, - { - "default": undefined, - "description": "Needed for contentlayer for polymorphic list types", - "isRequired": true, - "isSystemField": false, - "name": "type", - "type": "string", - }, { "default": undefined, "description": "The text shown below the title", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "subtitle", @@ -1620,6 +1309,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "the content of the section, appears above the form", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "content", @@ -1628,6 +1318,7 @@ exports[`azimuth schema 1`] = ` { "default": "gray", "description": "The background of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "background", @@ -1640,6 +1331,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "A unique identifier of the form, must not contain whitespace", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "form_id", @@ -1647,7 +1339,8 @@ exports[`azimuth schema 1`] = ` }, { "default": undefined, - "description": "The path of your custom \\"success\\" page, if you want to replace the default success message./index.js", + "description": "The path of your custom \\"success\\" page, if you want to replace the default success message.", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "form_action", @@ -1656,6 +1349,7 @@ exports[`azimuth schema 1`] = ` { "default": false, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "hide_labels", @@ -1664,6 +1358,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "form_fields", @@ -1676,6 +1371,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "submit_label", @@ -1687,64 +1383,12 @@ exports[`azimuth schema 1`] = ` "SectionContent": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fieldGroups": [ - { - "label": "Content", - "name": "content", - }, - { - "label": "Design", - "name": "design", - }, - ], - "fields": { - "actions": { - "label": "Action Buttons", - }, - "background": { - "control": { - "options": {}, - "type": "image-gallery", - }, - "group": "design", - "label": "Background", - }, - "content": { - "group": "content", - "label": "Content", - }, - "image": { - "control": { - "options": {}, - "type": "image-gallery", - }, - "group": "content", - "label": "Image", - }, - "image_alt": { - "group": "content", - "label": "Image Alt Text", - }, - "section_id": { - "label": "Section ID", - }, - "title": { - "label": "Title", - }, - "type": { - "label": "Section type", - }, - }, - "label": "Content Section", - "labelField": "title", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "A unique identifier of the section, must not contain whitespace", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "section_id", @@ -1753,22 +1397,16 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The title of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "title", "type": "string", }, - { - "default": undefined, - "description": "Needed for contentlayer for polymorphic list types", - "isRequired": true, - "isSystemField": false, - "name": "type", - "type": "string", - }, { "default": undefined, "description": "The text content of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "content", @@ -1777,6 +1415,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The image of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "image", @@ -1785,6 +1424,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The alt text of the section image", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "image_alt", @@ -1793,6 +1433,7 @@ exports[`azimuth schema 1`] = ` { "default": "gray", "description": "The background of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "background", @@ -1805,6 +1446,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "actions", @@ -1820,33 +1462,12 @@ exports[`azimuth schema 1`] = ` "SectionCta": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "actions": { - "label": "Action Buttons", - }, - "section_id": { - "label": "Section ID", - }, - "subtitle": { - "label": "Subtitle", - }, - "title": { - "label": "Title", - }, - "type": { - "label": "Section type", - }, - }, - "label": "Call to Action Section", - "labelField": "title", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "A unique identifier of the section, must not contain whitespace", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "section_id", @@ -1855,22 +1476,16 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The title of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "title", "type": "string", }, - { - "default": undefined, - "description": "Needed for contentlayer for polymorphic list types", - "isRequired": true, - "isSystemField": false, - "name": "type", - "type": "string", - }, { "default": undefined, "description": "The subtitle of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "subtitle", @@ -1879,6 +1494,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "actions", @@ -1894,36 +1510,12 @@ exports[`azimuth schema 1`] = ` "SectionFaq": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "background": { - "label": "Background", - }, - "faq_items": { - "label": "FAQ Items", - }, - "section_id": { - "label": "Section ID", - }, - "subtitle": { - "label": "Subtitle", - }, - "title": { - "label": "Title", - }, - "type": { - "label": "Section type", - }, - }, - "label": "Contact Section", - "labelField": "title", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "A unique identifier of the section, must not contain whitespace", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "section_id", @@ -1932,22 +1524,16 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The title of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "title", "type": "string", }, - { - "default": undefined, - "description": "Needed for contentlayer for polymorphic list types", - "isRequired": true, - "isSystemField": false, - "name": "type", - "type": "string", - }, { "default": undefined, "description": "The subtitle of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "subtitle", @@ -1956,6 +1542,7 @@ exports[`azimuth schema 1`] = ` { "default": "gray", "description": "The background of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "background", @@ -1968,6 +1555,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "faq_items", @@ -1983,36 +1571,12 @@ exports[`azimuth schema 1`] = ` "SectionFeatures": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "background": { - "label": "Background", - }, - "features": { - "label": "Features", - }, - "section_id": { - "label": "Section ID", - }, - "subtitle": { - "label": "Subtitle", - }, - "title": { - "label": "Title", - }, - "type": { - "label": "Section type", - }, - }, - "label": "Features Section", - "labelField": "title", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "A unique identifier of the section, must not contain whitespace", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "section_id", @@ -2021,22 +1585,16 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The title of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "title", "type": "string", }, - { - "default": undefined, - "description": "Needed for contentlayer for polymorphic list types", - "isRequired": true, - "isSystemField": false, - "name": "type", - "type": "string", - }, { "default": undefined, "description": "The subtitle of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "subtitle", @@ -2045,6 +1603,7 @@ exports[`azimuth schema 1`] = ` { "default": "gray", "description": "The background of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "background", @@ -2057,6 +1616,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "features", @@ -2072,43 +1632,12 @@ exports[`azimuth schema 1`] = ` "SectionHero": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "actions": { - "label": "Action Buttons", - }, - "content": { - "label": "Content", - }, - "image": { - "control": { - "options": {}, - "type": "image-gallery", - }, - "label": "Image", - }, - "image_alt": { - "label": "Image Alt Text", - }, - "section_id": { - "label": "Section ID", - }, - "title": { - "label": "Title", - }, - "type": { - "label": "Section type", - }, - }, - "label": "Hero Section", - "labelField": "title", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "A unique identifier of the section, must not contain whitespace", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "section_id", @@ -2117,22 +1646,16 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The title of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "title", "type": "string", }, - { - "default": undefined, - "description": "Needed for contentlayer for polymorphic list types", - "isRequired": true, - "isSystemField": false, - "name": "type", - "type": "string", - }, { "default": undefined, "description": "The text content of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "content", @@ -2141,6 +1664,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The image of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "image", @@ -2149,6 +1673,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The alt text of the section image", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "image_alt", @@ -2157,6 +1682,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "actions", @@ -2172,32 +1698,12 @@ exports[`azimuth schema 1`] = ` "SectionPosts": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "background": { - "label": "Background", - }, - "section_id": { - "label": "Section ID", - }, - "subtitle": { - "label": "Subtitle", - }, - "title": { - "label": "Title", - }, - "type": { - "label": "Section type", - }, - }, - "label": "Posts List", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "A unique identifier of the section, must not contain whitespace", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "section_id", @@ -2206,22 +1712,16 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The title of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "title", "type": "string", }, - { - "default": undefined, - "description": "Needed for contentlayer for polymorphic list types", - "isRequired": true, - "isSystemField": false, - "name": "type", - "type": "string", - }, { "default": undefined, "description": "The subtitle of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "subtitle", @@ -2230,6 +1730,7 @@ exports[`azimuth schema 1`] = ` { "default": "gray", "description": "The background of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "background", @@ -2245,35 +1746,12 @@ exports[`azimuth schema 1`] = ` "SectionPricing": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "background": { - "label": "Background", - }, - "pricing_plans": { - "label": "Pricing Plans", - }, - "section_id": { - "label": "Section ID", - }, - "subtitle": { - "label": "Subtitle", - }, - "title": { - "label": "Title", - }, - "type": { - "label": "Section type", - }, - }, - "label": "Pricing Section", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "A unique identifier of the section, must not contain whitespace", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "section_id", @@ -2282,22 +1760,16 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The title of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "title", "type": "string", }, - { - "default": undefined, - "description": "Needed for contentlayer for polymorphic list types", - "isRequired": true, - "isSystemField": false, - "name": "type", - "type": "string", - }, { "default": undefined, "description": "The subtitle of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "subtitle", @@ -2306,6 +1778,7 @@ exports[`azimuth schema 1`] = ` { "default": "gray", "description": "The background of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "background", @@ -2318,6 +1791,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "pricing_plans", @@ -2333,35 +1807,12 @@ exports[`azimuth schema 1`] = ` "SectionReviews": { "_tag": "NestedTypeDef", "description": undefined, - "extensions": { - "stackbit": { - "fields": { - "background": { - "label": "Background", - }, - "reviews": { - "label": "Reviews", - }, - "section_id": { - "label": "Section ID", - }, - "subtitle": { - "label": "Subtitle", - }, - "title": { - "label": "Title", - }, - "type": { - "label": "Section type", - }, - }, - "label": "Reviews Section", - }, - }, + "extensions": {}, "fieldDefs": [ { "default": undefined, "description": "A unique identifier of the section, must not contain whitespace", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "section_id", @@ -2370,22 +1821,16 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": "The title of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "title", "type": "string", }, - { - "default": undefined, - "description": "Needed for contentlayer for polymorphic list types", - "isRequired": true, - "isSystemField": false, - "name": "type", - "type": "string", - }, { "default": undefined, "description": "The subtitle of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "subtitle", @@ -2394,6 +1839,7 @@ exports[`azimuth schema 1`] = ` { "default": "gray", "description": "The background of the section", + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "background", @@ -2406,6 +1852,7 @@ exports[`azimuth schema 1`] = ` { "default": undefined, "description": undefined, + "extensions": {}, "isRequired": false, "isSystemField": false, "name": "reviews", @@ -2423,65 +1870,87 @@ exports[`azimuth schema 1`] = ` `; exports[`azimuth schema 2`] = ` -"stackbitVersion: ~0.3.0 -nodeVersion: \\">=12\\" +"stackbitVersion: ~0.4.0 +nodeVersion: \\">=14\\" +cmsName: git +ssgName: nextjs +objectTypeKey: type +pageLayoutKey: type models: Blog: label: Blog - labelField: null - description: null fields: - name: title required: true - const: null - default: null description: The title of the page - hidden: null - label: Title type: string - name: seo required: false - const: null - default: null - description: null - hidden: null - label: null type: model models: - SEO - - name: body + singleInstance: true + type: data + Config: + label: Config + fields: + - name: title required: true - const: null - default: null - description: Markdown file body - hidden: null - label: null - type: markdown - match: null - folder: null - file: blog.md - type: page + description: Site title + type: string + - name: path_prefix + required: true + description: \\"The base URL of this site. Useful for sites hosted under specific + path, e.g.: https://www.example.com/my-site/\\" + type: string + - name: domain + required: false + description: The domain of your site, including the protocol, e.g. + https://mysite.com/ + type: string + - name: favicon + required: false + description: A square icon that represents your website + type: string + - name: palette + required: true + description: The color palette of the site + type: enum + options: + - blue + - cyan + - green + - orange + - purple + - name: base_font + required: true + type: enum + options: + - fira-sans + - nunito-sans + - system-sans + - name: header + required: true + type: model + models: + - Header + - name: footer + required: true + type: model + models: + - Footer singleInstance: true + type: data Landing: - label: Landing Page - labelField: null - description: null + label: Landing fields: - name: title required: true - const: null - default: null description: The title of the page - hidden: null - label: Title type: string - name: sections required: false - const: null - default: null description: Page sections - hidden: null - label: Sections type: list items: type: model @@ -2497,374 +1966,111 @@ models: - SectionContact - name: seo required: false - const: null - default: null - description: null - hidden: null - label: null type: model models: - SEO - - name: body - required: true - const: null - default: null - description: Markdown file body - hidden: null - label: null - type: markdown - match: - - contact.md - - features.md - - index.md - - pricing.md - folder: null - file: null - type: page - singleInstance: false + type: data Page: label: Page - labelField: null - description: null fields: - name: title required: true - const: null - default: null description: The title of the page - hidden: null - label: null type: string - name: subtitle required: false - const: null - default: null description: The text shown below the page title - hidden: null - label: null type: string - name: image required: false - const: null - default: null description: The image shown below the page title - hidden: null - label: null type: string - name: image_alt required: false - const: null - default: null description: The alt text of the image - hidden: null - label: null type: string - name: seo required: false - const: null - default: null - description: null - hidden: null - label: null type: model models: - SEO - - name: body - required: true - const: null - default: null - description: Markdown file body - hidden: null - label: null + type: data + Person: + label: Person + fields: + - name: first_name + required: false + type: string + - name: last_name + required: false + type: string + - name: bio + required: false type: markdown - match: - - about.md - - privacy-policy.md - - signup.md - - style-guide.md - - terms-of-service.md - folder: null - file: null - type: page - singleInstance: false + - name: photo + required: false + type: string + type: data Post: label: Post - labelField: null - description: null fields: - name: title required: true - const: null - default: null description: The title of the post - hidden: null - label: Title type: string - name: subtitle required: false - const: null - default: null description: The text shown just below the title or the featured image - hidden: null - label: Subtitle type: string - name: date required: true - const: null - default: null - description: null - hidden: null - label: Date type: date - name: author required: false - const: null - default: null description: Post author - hidden: null - label: null type: reference models: - Person - name: excerpt required: false - const: null - default: null description: The excerpt of the post displayed in the blog feed - hidden: null - label: Excerpt type: string - name: image required: false - const: null - default: null description: The image shown below the title - hidden: null - label: Image type: string - name: image_alt required: false - const: null - default: null description: The alt text of the featured image - hidden: null - label: Image alt text (single post) type: string - name: thumb_image required: false - const: null - default: null description: The image shown in the blog feed - hidden: null - label: Image (blog feed) type: string - name: thumb_image_alt required: false - const: null - default: null description: The alt text of the blog feed image - hidden: null - label: Image alt text (blog feed) type: string - name: seo required: false - const: null - default: null - description: null - hidden: null - label: null type: model models: - SEO - - name: body - required: true - const: null - default: null - description: Markdown file body - hidden: null - label: null - type: markdown - match: blog/**.md - folder: null - file: null - type: page - singleInstance: false - Config: - label: Site Configuration - labelField: null - description: null - fields: - - name: title - required: true - const: null - default: null - description: Site title - hidden: null - label: Title - type: string - - name: path_prefix - required: true - const: null - default: null - description: \\"The base URL of this site. Useful for sites hosted under specific - path, e.g.: https://www.example.com/my-site/\\" - hidden: true - label: Base URL - type: string - - name: domain - required: false - const: null - default: null - description: The domain of your site, including the protocol, e.g. - https://mysite.com/ - hidden: null - label: Domain - type: string - - name: favicon - required: false - const: null - default: null - description: A square icon that represents your website - hidden: null - label: Favicon - type: string - - name: palette - required: true - const: null - default: blue - description: The color palette of the site - hidden: null - label: Color Palette - type: enum - options: - - blue - - cyan - - green - - orange - - purple - - name: base_font - required: true - const: null - default: nunito-sans - description: null - hidden: null - label: Font - type: enum - options: - - fira-sans - - nunito-sans - - system-sans - - name: header - required: true - const: null - default: null - description: null - hidden: null - label: Header Configuration - type: model - models: - - Header - - name: footer - required: true - const: null - default: null - description: null - hidden: null - label: Footer Configuration - type: model - models: - - Footer - - name: body - required: true - const: null - default: null - description: Markdown file body - hidden: null - label: null - type: markdown - match: null - folder: null - file: config.json - type: data - singleInstance: true - Person: - label: Person - labelField: null - description: null - fields: - - name: first_name - required: false - const: null - default: null - description: null - hidden: null - label: null - type: string - - name: last_name - required: false - const: null - default: null - description: null - hidden: null - label: null - type: string - - name: bio - required: false - const: null - default: null - description: null - hidden: null - label: null - type: markdown - - name: photo - required: false - const: null - default: null - description: null - hidden: null - label: null - type: string - - name: body - required: true - const: null - default: null - description: Markdown file body - hidden: null - label: null - type: markdown - match: null - folder: authors - file: null type: data - singleInstance: false SEO: - label: Page meta data - labelField: null - description: null + label: SEO fields: - name: title required: false - const: null - default: null description: The page title that goes into the <title> tag - hidden: null - label: Title type: string - name: description required: false - const: null - default: null description: The page description that goes into the <meta name=\\"description\\"> tag - hidden: null - label: Description type: string - name: robots required: false - const: null - default: null description: The items that go into the <meta name=\\"robots\\"> tag - hidden: null - label: Robots type: list items: type: enum @@ -2879,126 +2085,61 @@ models: - none - name: extra required: false - const: null - default: null description: Additional definition for specific meta tags such as open-graph, twitter, etc. - hidden: null - label: Extra type: list items: type: object fields: - name: name required: false - const: null - default: null - description: null - hidden: null - label: null type: string - name: value required: false - const: null - default: null - description: null - hidden: null - label: null type: string - name: keyName required: false - const: null - default: name - description: null - hidden: null - label: null type: string - name: relativeUrl required: false - const: null - default: null - description: null - hidden: null - label: null type: boolean - match: null - folder: null - file: null type: object Header: - label: Header Configuration - labelField: null - description: null + label: Header fields: - name: logo_img required: false - const: null - default: null description: The logo image displayed in the header (if no logo added, the site title is displayed instead) - hidden: null - label: Logo type: string - name: logo_img_alt required: false - const: null - default: null description: The alt text of the logo image - hidden: null - label: Logo Alt Text type: string - name: has_nav required: false - const: null - default: true description: Display the navigation menu bar in the header - hidden: null - label: Enable Navigation type: boolean - name: nav_links required: false - const: null - default: null description: List of navigation links - hidden: null - label: Navigation Links type: list items: type: model models: - Action - match: null - folder: null - file: null type: object Action: label: Action - labelField: label - description: null fields: - name: label required: true - const: null - default: null - description: null - hidden: null - label: Label type: string - name: url required: true - const: null - default: null - description: null - hidden: null - label: URL type: string - name: style required: false - const: null - default: link - description: null - hidden: null - label: Style type: enum options: - link @@ -3006,19 +2147,9 @@ models: - secondary - name: has_icon required: false - const: null - default: false - description: null - hidden: null - label: Show icon type: boolean - name: icon required: false - const: null - default: null - description: null - hidden: null - label: Icon type: enum options: - arrow-left @@ -3033,47 +2164,26 @@ models: - youtube - name: icon_position required: false - const: null - default: left description: The position of the icon relative to text - hidden: null - label: Icon position type: enum options: - left - right - name: new_window required: false - const: null - default: false description: Should the link open a new tab - hidden: null - label: Open in new window type: boolean - name: no_follow required: false - const: null - default: false description: Add rel=\\"nofollow\\" attribute to the link - hidden: null - label: No follow type: boolean - match: null - folder: null - file: null type: object Footer: - label: Footer Configuration - labelField: content - description: null + label: Footer fields: - name: sections required: false - const: null - default: null description: Footer sections - hidden: null - label: Sections type: list items: type: model @@ -3083,19 +2193,11 @@ models: - FooterText - name: has_nav required: false - const: null - default: true description: Display the horizontal navigation menu bar in the footer - hidden: null - label: Enable Horizontal Navigation type: boolean - name: nav_links required: false - const: null - default: null description: List of horizontal navigation links - hidden: null - label: Horizontal Navigation Links type: list items: type: model @@ -3103,89 +2205,46 @@ models: - Action - name: content required: false - const: null - default: null description: The copyright text displayed in the footer - hidden: null - label: Footer Content type: string - name: links required: false - const: null - default: null description: A list of links displayed in the footer - hidden: null - label: Links type: list items: type: model models: - Action - match: null - folder: null - file: null type: object FooterForm: - label: Footer Form - labelField: title - description: null + label: FooterForm fields: - name: title required: false - const: null - default: null description: The title of the section - hidden: null - label: Title type: string - name: type required: true - const: null - default: null description: Needed for contentlayer for polymorphic list types - hidden: null - label: Section type type: string - name: content required: false - const: null - default: null description: The content of the section, appears above the form - hidden: null - label: Content type: markdown - name: form_id required: true - const: null - default: null description: A unique identifier of the form, must not contain whitespace - hidden: null - label: Form ID type: string - name: form_action required: false - const: null - default: null description: The path of your custom \\"success\\" page, if you want to replace the default success message./index.js - hidden: null - label: Form Action type: string - name: hide_labels required: false - const: null - default: false - description: null - hidden: null - label: Hide Labels type: boolean - name: form_fields required: false - const: null - default: null - description: null - hidden: null - label: Form Fields type: list items: type: model @@ -3193,28 +2252,14 @@ models: - FormField - name: submit_label required: true - const: null - default: null - description: null - hidden: null - label: Submit Button Label type: string - match: null - folder: null - file: null type: object FormField: - label: Form Field - labelField: name - description: null + label: FormField fields: - name: input_type required: true - const: null - default: null description: Type of the form field - hidden: null - label: Type type: enum options: - text @@ -3226,923 +2271,429 @@ models: - select - name: name required: true - const: null - default: null description: The name of the field, submitted with the form - hidden: null - label: Name type: string - name: label required: false - const: null - default: null description: The caption of the field, shown above the field input - hidden: null - label: Label type: string - name: default_value required: false - const: null - default: null description: The placeholder for textual field types or default option for select field - hidden: null - label: Placeholder text or default value type: string - name: options required: false - const: null - default: null description: The list of options for select field - hidden: null - label: Options type: list items: type: string - name: is_required required: false - const: null - default: false - description: null - hidden: null - label: Is the field required? type: boolean - match: null - folder: null - file: null type: object FooterNav: - label: Vertical Navigation - labelField: title - description: null + label: FooterNav fields: - name: title required: false - const: null - default: null description: The title of the section - hidden: null - label: Title type: string - name: type required: true - const: null - default: null description: Needed for contentlayer for polymorphic list types - hidden: null - label: Section type type: string - name: nav_links required: false - const: null - default: null description: List of vertical navigation links - hidden: null - label: Vertical Navigation Links type: list items: type: model models: - Action - match: null - folder: null - file: null type: object FooterText: - label: Text - labelField: title - description: null + label: FooterText fields: - name: title required: false - const: null - default: null description: The title of the section - hidden: null - label: Title type: string - name: type required: true - const: null - default: null description: Needed for contentlayer for polymorphic list types - hidden: null - label: Section type type: string - name: image required: false - const: null - default: null description: The image displayed in the section - hidden: null - label: Image type: string - name: image_alt required: false - const: null - default: null description: The alt text of the image - hidden: null - label: Image Alt Text type: string - name: image_url required: false - const: null - default: null description: The url of the image - hidden: null - label: Image URL type: string - name: content required: false - const: null - default: null description: The text content of the section - hidden: null - label: Content type: markdown - match: null - folder: null - file: null type: object SectionContent: - label: Content Section - labelField: title - description: null + label: SectionContent fields: - name: section_id required: false - const: null - default: null description: A unique identifier of the section, must not contain whitespace - hidden: null - label: Section ID type: string - name: title required: false - const: null - default: null description: The title of the section - hidden: null - label: Title - type: string - - name: type - required: true - const: null - default: null - description: Needed for contentlayer for polymorphic list types - hidden: null - label: Section type type: string - name: content required: false - const: null - default: null description: The text content of the section - hidden: null - label: Content type: markdown - name: image required: false - const: null - default: null description: The image of the section - hidden: null - label: Image type: string - name: image_alt required: false - const: null - default: null description: The alt text of the section image - hidden: null - label: Image Alt Text type: string - name: background required: false - const: null - default: gray description: The background of the section - hidden: null - label: Background type: enum options: - gray - white - name: actions required: false - const: null - default: null - description: null - hidden: null - label: Action Buttons type: list items: type: model models: - Action - match: null - folder: null - file: null type: object SectionCta: - label: Call to Action Section - labelField: title - description: null + label: SectionCta fields: - name: section_id required: false - const: null - default: null description: A unique identifier of the section, must not contain whitespace - hidden: null - label: Section ID type: string - name: title required: false - const: null - default: null description: The title of the section - hidden: null - label: Title - type: string - - name: type - required: true - const: null - default: null - description: Needed for contentlayer for polymorphic list types - hidden: null - label: Section type type: string - name: subtitle required: false - const: null - default: null description: The subtitle of the section - hidden: null - label: Subtitle type: string - name: actions required: false - const: null - default: null - description: null - hidden: null - label: Action Buttons type: list items: type: model models: - Action - match: null - folder: null - file: null type: object SectionFaq: - label: Contact Section - labelField: title - description: null + label: SectionFaq fields: - name: section_id required: false - const: null - default: null description: A unique identifier of the section, must not contain whitespace - hidden: null - label: Section ID type: string - name: title required: false - const: null - default: null description: The title of the section - hidden: null - label: Title - type: string - - name: type - required: true - const: null - default: null - description: Needed for contentlayer for polymorphic list types - hidden: null - label: Section type type: string - name: subtitle required: false - const: null - default: null description: The subtitle of the section - hidden: null - label: Subtitle type: string - name: background required: false - const: null - default: gray description: The background of the section - hidden: null - label: Background type: enum options: - gray - white - name: faq_items required: false - const: null - default: null - description: null - hidden: null - label: FAQ Items type: list items: type: model models: - FaqItem - match: null - folder: null - file: null type: object FaqItem: - label: FAQ Item - labelField: null - description: null + label: FaqItem fields: - name: question required: false - const: null - default: null - description: null - hidden: null - label: Question type: string - name: answer required: false - const: null - default: null - description: null - hidden: null - label: Answer type: markdown - match: null - folder: null - file: null type: object SectionFeatures: - label: Features Section - labelField: title - description: null + label: SectionFeatures fields: - name: section_id required: false - const: null - default: null description: A unique identifier of the section, must not contain whitespace - hidden: null - label: Section ID type: string - name: title required: false - const: null - default: null description: The title of the section - hidden: null - label: Title - type: string - - name: type - required: true - const: null - default: null - description: Needed for contentlayer for polymorphic list types - hidden: null - label: Section type type: string - name: subtitle required: false - const: null - default: null description: The subtitle of the section - hidden: null - label: Subtitle type: string - name: background required: false - const: null - default: gray description: The background of the section - hidden: null - label: Background type: enum options: - gray - white - name: features required: false - const: null - default: null - description: null - hidden: null - label: Features type: list items: type: model models: - FeatureItem - match: null - folder: null - file: null type: object FeatureItem: - label: Feature Item - labelField: title - description: null + label: FeatureItem fields: - name: title required: false - const: null - default: null - description: null - hidden: null - label: Title type: string - name: content required: false - const: null - default: null description: Feature description - hidden: null - label: Content type: markdown - name: image required: false - const: null - default: null description: Feature image - hidden: null - label: Image type: string - name: image_alt required: false - const: null - default: null description: The alt text of the feature image - hidden: null - label: Image Alt Text type: string - name: actions required: false - const: null - default: null - description: null - hidden: null - label: Action Buttons type: list items: type: model models: - Action - match: null - folder: null - file: null type: object SectionHero: - label: Hero Section - labelField: title - description: null + label: SectionHero fields: - name: section_id required: false - const: null - default: null description: A unique identifier of the section, must not contain whitespace - hidden: null - label: Section ID type: string - name: title required: false - const: null - default: null description: The title of the section - hidden: null - label: Title - type: string - - name: type - required: true - const: null - default: null - description: Needed for contentlayer for polymorphic list types - hidden: null - label: Section type type: string - name: content required: false - const: null - default: null description: The text content of the section - hidden: null - label: Content type: markdown - name: image required: false - const: null - default: null description: The image of the section - hidden: null - label: Image type: string - name: image_alt required: false - const: null - default: null description: The alt text of the section image - hidden: null - label: Image Alt Text type: string - name: actions required: false - const: null - default: null - description: null - hidden: null - label: Action Buttons type: list items: type: model models: - Action - match: null - folder: null - file: null type: object SectionPosts: - label: Posts List - labelField: null - description: null + label: SectionPosts fields: - name: section_id required: false - const: null - default: null description: A unique identifier of the section, must not contain whitespace - hidden: null - label: Section ID type: string - name: title required: false - const: null - default: null description: The title of the section - hidden: null - label: Title - type: string - - name: type - required: true - const: null - default: null - description: Needed for contentlayer for polymorphic list types - hidden: null - label: Section type type: string - name: subtitle required: false - const: null - default: null description: The subtitle of the section - hidden: null - label: Subtitle type: string - name: background required: false - const: null - default: gray description: The background of the section - hidden: null - label: Background type: enum options: - gray - white - match: null - folder: null - file: null type: object SectionPricing: - label: Pricing Section - labelField: null - description: null + label: SectionPricing fields: - name: section_id required: false - const: null - default: null description: A unique identifier of the section, must not contain whitespace - hidden: null - label: Section ID type: string - name: title required: false - const: null - default: null description: The title of the section - hidden: null - label: Title - type: string - - name: type - required: true - const: null - default: null - description: Needed for contentlayer for polymorphic list types - hidden: null - label: Section type type: string - name: subtitle required: false - const: null - default: null description: The subtitle of the section - hidden: null - label: Subtitle type: string - name: background required: false - const: null - default: gray description: The background of the section - hidden: null - label: Background type: enum options: - gray - white - name: pricing_plans required: false - const: null - default: null - description: null - hidden: null - label: Pricing Plans type: list items: type: model models: - PricingPlan - match: null - folder: null - file: null type: object PricingPlan: - label: Pricing Plan - labelField: title - description: null + label: PricingPlan fields: - name: title required: false - const: null - default: null - description: null - hidden: null - label: Title type: string - name: subtitle required: false - const: null - default: null - description: null - hidden: null - label: Subtitle type: string - name: price required: false - const: null - default: null - description: null - hidden: null - label: Price type: string - name: details required: false - const: null - default: null - description: null - hidden: null - label: Details type: markdown - name: highlight required: false - const: null - default: false description: Make the plan stand out by adding a distinctive style - hidden: null - label: Highlight type: boolean - name: actions required: false - const: null - default: null - description: null - hidden: null - label: Action Buttons type: list items: type: model models: - Action - match: null - folder: null - file: null type: object SectionReviews: - label: Reviews Section - labelField: null - description: null + label: SectionReviews fields: - name: section_id required: false - const: null - default: null description: A unique identifier of the section, must not contain whitespace - hidden: null - label: Section ID type: string - name: title required: false - const: null - default: null description: The title of the section - hidden: null - label: Title - type: string - - name: type - required: true - const: null - default: null - description: Needed for contentlayer for polymorphic list types - hidden: null - label: Section type type: string - name: subtitle required: false - const: null - default: null description: The subtitle of the section - hidden: null - label: Subtitle type: string - name: background required: false - const: null - default: gray description: The background of the section - hidden: null - label: Background type: enum options: - gray - white - name: reviews required: false - const: null - default: null - description: null - hidden: null - label: Reviews type: list items: type: model models: - ReviewItem - match: null - folder: null - file: null type: object ReviewItem: - label: Review Item - labelField: null - description: null + label: ReviewItem fields: - name: author required: false - const: null - default: null - description: null - hidden: null - label: Author type: string - name: avatar required: false - const: null - default: null - description: null - hidden: null - label: Author Image type: string - name: avatar_alt required: false - const: null - default: null - description: null - hidden: null - label: Author Image Alt Text type: string - name: content required: false - const: null - default: null - description: null - hidden: null - label: Content type: string - match: null - folder: null - file: null type: object SectionContact: - label: Contact Section - labelField: title - description: null + label: SectionContact fields: - name: section_id required: false - const: null - default: null description: A unique identifier of the section, must not contain whitespace - hidden: null - label: Section ID type: string - name: title required: false - const: null - default: null description: The title of the section - hidden: null - label: Title - type: string - - name: type - required: true - const: null - default: null - description: Needed for contentlayer for polymorphic list types - hidden: null - label: Section type type: string - name: subtitle required: false - const: null - default: null description: The text shown below the title - hidden: null - label: Subtitle type: string - name: content required: false - const: null - default: null description: the content of the section, appears above the form - hidden: null - label: Content type: markdown - name: background required: false - const: null - default: gray description: The background of the section - hidden: null - label: Background type: enum options: - gray - white - name: form_id required: true - const: null - default: null description: A unique identifier of the form, must not contain whitespace - hidden: null - label: Form ID type: string - name: form_action required: false - const: null - default: null description: The path of your custom \\"success\\" page, if you want to replace the - default success message./index.js - hidden: null - label: Form Action + default success message. type: string - name: hide_labels required: false - const: null - default: false - description: null - hidden: null - label: Hide labels of the form fields? type: boolean - name: form_fields required: false - const: null - default: null - description: null - hidden: null - label: Form Fields type: list items: type: model @@ -4150,18 +2701,9 @@ models: - FormField - name: submit_label required: true - const: null - default: null - description: null - hidden: null - label: Submit Button Label type: string - match: null - folder: null - file: null type: object -pagesDir: null -dataDir: null +contentModels: {} " `; @@ -4184,6 +2726,7 @@ exports[`blog schema 1`] = ` { "default": undefined, "description": "The title of the post", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "title", @@ -4192,6 +2735,7 @@ exports[`blog schema 1`] = ` { "default": undefined, "description": "The date of the post", + "extensions": {}, "isRequired": true, "isSystemField": false, "name": "date", @@ -4200,6 +2744,7 @@ exports[`blog schema 1`] = ` { "default": undefined, "description": "Markdown file body", + "extensions": {}, "isRequired": true, "isSystemField": true, "name": "body", @@ -4216,44 +2761,25 @@ exports[`blog schema 1`] = ` `; exports[`blog schema 2`] = ` -"stackbitVersion: ~0.3.0 -nodeVersion: \\">=12\\" +"stackbitVersion: ~0.4.0 +nodeVersion: \\">=14\\" +cmsName: git +ssgName: nextjs +objectTypeKey: type +pageLayoutKey: type models: Post: label: Post - labelField: null - description: null fields: - name: title required: true - const: null - default: null description: The title of the post - hidden: null - label: null type: string - name: date required: true - const: null - default: null description: The date of the post - hidden: null - label: null type: date - - name: body - required: true - const: null - default: null - description: Markdown file body - hidden: null - label: null - type: markdown - match: null - folder: null - file: null type: data - singleInstance: false -pagesDir: null -dataDir: null +contentModels: {} " `; diff --git a/packages/contentlayer-stackbit-yaml-generator/src/__test__/convert.spec.ts b/packages/contentlayer-stackbit-yaml-generator/src/__test__/convert.spec.ts index a87c943c..7841b288 100644 --- a/packages/contentlayer-stackbit-yaml-generator/src/__test__/convert.spec.ts +++ b/packages/contentlayer-stackbit-yaml-generator/src/__test__/convert.spec.ts @@ -1,3 +1,4 @@ +import { defaultFieldOptions } from '@contentlayer/core' import { expect, test } from 'vitest' import { convertSchema } from '../cli/convert.js' @@ -7,13 +8,17 @@ import * as fixtures from './fixtures/index.js' test('azimuth schema', async () => { const coreSchema = await fixtures.makeAzimuthSchema() expect(coreSchema).toMatchSnapshot() - const stackbitConfig = toYamlString(convertSchema(coreSchema, {})) + const stackbitConfig = toYamlString( + convertSchema({ schema: coreSchema, extensions: {}, fieldOptions: defaultFieldOptions }), + ) expect(stackbitConfig).toMatchSnapshot() }) test('blog schema', async () => { const coreSchema = await fixtures.makeBlogSchema() expect(coreSchema).toMatchSnapshot() - const stackbitConfig = toYamlString(convertSchema(coreSchema, {})) + const stackbitConfig = toYamlString( + convertSchema({ schema: coreSchema, extensions: {}, fieldOptions: defaultFieldOptions }), + ) expect(stackbitConfig).toMatchSnapshot() }) diff --git a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Blog.ts b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Blog.ts index a38a2007..e20d055f 100644 --- a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Blog.ts +++ b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Blog.ts @@ -1,7 +1,7 @@ import { defineDocumentType } from 'contentlayer/source-files' -import { SEO } from '../nested/SEO.js' -import { urlFromFilePath } from '../utils.js' +import { SEO } from '../nested/SEO' +import { urlFromFilePath } from '../utils' export const Blog = defineDocumentType(() => ({ name: 'Blog', @@ -23,12 +23,10 @@ export const Blog = defineDocumentType(() => ({ resolve: urlFromFilePath, }, }, - extensions: { - stackbit: { - fields: { - title: { label: 'Title' }, - }, - file: 'blog.md', + stackbit: { + fields: { + title: { label: 'Title' }, }, + file: 'blog.md', }, })) diff --git a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Config.ts b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Config.ts index 3f3b50e6..e9557d10 100644 --- a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Config.ts +++ b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Config.ts @@ -1,11 +1,11 @@ import { defineDocumentType, defineNestedType } from 'contentlayer/source-files' -import { Action } from '../nested/Action.js' -import { FormField } from '../nested/FormField.js' +import { Action } from '../nested/Action' +import { FormField } from '../nested/FormField' export const Config = defineDocumentType(() => ({ name: 'Config', - filePathPattern: 'data/config.json', + // filePathPattern: 'data/config.json', isSingleton: true, fields: { title: { @@ -45,21 +45,19 @@ export const Config = defineDocumentType(() => ({ // header: { type: 'embedded', model: Header, required: true }, footer: { type: 'nested', of: Footer, required: true }, }, - extensions: { - stackbit: { - label: 'Site Configuration', - fields: { - title: { label: 'Title' }, - path_prefix: { label: 'Base URL', hidden: true }, - domain: { label: 'Domain' }, - favicon: { label: 'Favicon' }, - palette: { label: 'Color Palette' }, - base_font: { label: 'Font' }, - header: { label: 'Header Configuration' }, - footer: { label: 'Footer Configuration' }, - }, - file: 'config.json', - }, + stackbit: { + label: 'Site Configuration', + fields: { + title: { label: 'Title' }, + path_prefix: { label: 'Base URL', hidden: true }, + domain: { label: 'Domain' }, + favicon: { label: 'Favicon' }, + palette: { label: 'Color Palette' }, + base_font: { label: 'Font' }, + header: { label: 'Header Configuration' }, + footer: { label: 'Footer Configuration' }, + }, + file: 'config.json', }, })) @@ -85,15 +83,13 @@ const Header = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Header Configuration', - fields: { - logo_img: { label: 'Logo' }, - logo_img_alt: { label: 'Logo Alt Text' }, - has_nav: { label: 'Enable Navigation' }, - nav_links: { label: 'Navigation Links' }, - }, + stackbit: { + label: 'Header Configuration', + fields: { + logo_img: { label: 'Logo' }, + logo_img_alt: { label: 'Logo Alt Text' }, + has_nav: { label: 'Enable Navigation' }, + nav_links: { label: 'Navigation Links' }, }, }, })) @@ -127,17 +123,15 @@ const Footer = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Footer Configuration', - labelField: 'content', - fields: { - sections: { label: 'Sections' }, - has_nav: { label: 'Enable Horizontal Navigation' }, - nav_links: { label: 'Horizontal Navigation Links' }, - content: { label: 'Footer Content' }, - links: { label: 'Links' }, - }, + stackbit: { + label: 'Footer Configuration', + labelField: 'content', + fields: { + sections: { label: 'Sections' }, + has_nav: { label: 'Enable Horizontal Navigation' }, + nav_links: { label: 'Horizontal Navigation Links' }, + content: { label: 'Footer Content' }, + links: { label: 'Links' }, }, }, })) @@ -196,19 +190,17 @@ const FooterForm = defineNestedType(() => ({ required: true, }, }, - extensions: { - stackbit: { - label: 'Footer Form', - labelField: 'title', - fields: { - ...footerSectionBaseFieldsExtension, - content: { label: 'Content' }, - form_id: { label: 'Form ID' }, - form_action: { label: 'Form Action' }, - hide_labels: { label: 'Hide Labels' }, - form_fields: { label: 'Form Fields' }, - submit_label: { label: 'Submit Button Label' }, - }, + stackbit: { + label: 'Footer Form', + labelField: 'title', + fields: { + ...footerSectionBaseFieldsExtension, + content: { label: 'Content' }, + form_id: { label: 'Form ID' }, + form_action: { label: 'Form Action' }, + hide_labels: { label: 'Hide Labels' }, + form_fields: { label: 'Form Fields' }, + submit_label: { label: 'Submit Button Label' }, }, }, })) @@ -223,14 +215,12 @@ const FooterNav = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Vertical Navigation', - labelField: 'title', - fields: { - ...footerSectionBaseFieldsExtension, - nav_links: { label: 'Vertical Navigation Links' }, - }, + stackbit: { + label: 'Vertical Navigation', + labelField: 'title', + fields: { + ...footerSectionBaseFieldsExtension, + nav_links: { label: 'Vertical Navigation Links' }, }, }, })) @@ -256,17 +246,15 @@ const FooterText = defineNestedType(() => ({ description: 'The text content of the section', }, }, - extensions: { - stackbit: { - label: 'Text', - labelField: 'title', - fields: { - ...footerSectionBaseFieldsExtension, - image: { label: 'Image' }, - image_alt: { label: 'Image Alt Text' }, - image_url: { label: 'Image URL' }, - content: { label: 'Content' }, - }, + stackbit: { + label: 'Text', + labelField: 'title', + fields: { + ...footerSectionBaseFieldsExtension, + image: { label: 'Image' }, + image_alt: { label: 'Image Alt Text' }, + image_url: { label: 'Image URL' }, + content: { label: 'Content' }, }, }, })) diff --git a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Landing.ts b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Landing.ts index 316130d9..7e5a326e 100644 --- a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Landing.ts +++ b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Landing.ts @@ -1,13 +1,13 @@ import { defineDocumentType, defineNestedType } from 'contentlayer/source-files' -import { Action } from '../nested/Action.js' -import { FormField } from '../nested/FormField.js' -import { SEO } from '../nested/SEO.js' -import { urlFromFilePath } from '../utils.js' +import { Action } from '../nested/Action' +import { FormField } from '../nested/FormField' +import { SEO } from '../nested/SEO' +import { urlFromFilePath } from '../utils' export const Landing = defineDocumentType(() => ({ name: 'Landing', - filePathPattern: 'pages/{contact,features,index,pricing}.md', + // filePathPattern: 'pages/{contact,features,index,pricing}.md', fields: { title: { type: 'string', @@ -40,15 +40,13 @@ export const Landing = defineDocumentType(() => ({ resolve: urlFromFilePath, }, }, - extensions: { - stackbit: { - label: 'Landing Page', - fields: { - title: { label: 'Title' }, - sections: { label: 'Sections' }, - }, - match: ['contact.md', 'features.md', 'index.md', 'pricing.md'], + stackbit: { + label: 'Landing Page', + fields: { + title: { label: 'Title' }, + sections: { label: 'Sections' }, }, + match: ['contact.md', 'features.md', 'index.md', 'pricing.md'], }, })) @@ -61,17 +59,11 @@ const sectionBaseFields = { type: 'string', description: 'The title of the section', }, - type: { - type: 'string', - required: true, - description: 'Needed for contentlayer for polymorphic list types', - }, } as const const sectionBaseFieldsExtension = { section_id: { label: 'Section ID' }, title: { label: 'Title' }, - type: { label: 'Section type' }, } as const const SectionContent = defineNestedType(() => ({ @@ -101,22 +93,20 @@ const SectionContent = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Content Section', - labelField: 'title', - fieldGroups: [ - { name: 'content', label: 'Content' }, - { name: 'design', label: 'Design' }, - ], - fields: { - ...sectionBaseFieldsExtension, - content: { label: 'Content', group: 'content' }, - image: { label: 'Image', group: 'content', control: { type: 'image-gallery', options: {} } }, - image_alt: { label: 'Image Alt Text', group: 'content' }, - background: { label: 'Background', group: 'design', control: { type: 'image-gallery', options: {} } }, - actions: { label: 'Action Buttons' }, - }, + stackbit: { + label: 'Content Section', + labelField: 'title', + fieldGroups: [ + { name: 'content', label: 'Content' }, + { name: 'design', label: 'Design' }, + ], + fields: { + ...sectionBaseFieldsExtension, + content: { label: 'Content', group: 'content' }, + image: { label: 'Image', group: 'content', control: { type: 'image-gallery', options: {} } }, + image_alt: { label: 'Image Alt Text', group: 'content' }, + background: { label: 'Background', group: 'design', control: { type: 'image-gallery', options: {} } }, + actions: { label: 'Action Buttons' }, }, }, })) @@ -134,15 +124,13 @@ const SectionCta = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Call to Action Section', - labelField: 'title', - fields: { - ...sectionBaseFieldsExtension, - subtitle: { label: 'Subtitle' }, - actions: { label: 'Action Buttons' }, - }, + stackbit: { + label: 'Call to Action Section', + labelField: 'title', + fields: { + ...sectionBaseFieldsExtension, + subtitle: { label: 'Subtitle' }, + actions: { label: 'Action Buttons' }, }, }, })) @@ -168,17 +156,15 @@ const SectionHero = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Hero Section', - labelField: 'title', - fields: { - ...sectionBaseFieldsExtension, - content: { label: 'Content' }, - image: { label: 'Image', control: { type: 'image-gallery', options: {} } }, - image_alt: { label: 'Image Alt Text' }, - actions: { label: 'Action Buttons' }, - }, + stackbit: { + label: 'Hero Section', + labelField: 'title', + fields: { + ...sectionBaseFieldsExtension, + content: { label: 'Content' }, + image: { label: 'Image', control: { type: 'image-gallery', options: {} } }, + image_alt: { label: 'Image Alt Text' }, + actions: { label: 'Action Buttons' }, }, }, })) @@ -202,16 +188,14 @@ const SectionFeatures = defineNestedType(() => ({ of: FeatureItem, }, }, - extensions: { - stackbit: { - label: 'Features Section', - labelField: 'title', - fields: { - ...sectionBaseFieldsExtension, - subtitle: { label: 'Subtitle' }, - background: { label: 'Background' }, - features: { label: 'Features' }, - }, + stackbit: { + label: 'Features Section', + labelField: 'title', + fields: { + ...sectionBaseFieldsExtension, + subtitle: { label: 'Subtitle' }, + background: { label: 'Background' }, + features: { label: 'Features' }, }, }, })) @@ -237,17 +221,15 @@ const FeatureItem = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Feature Item', - labelField: 'title', - fields: { - title: { label: 'Title' }, - content: { label: 'Content' }, - image: { label: 'Image', control: { type: 'image-gallery', options: {} } }, - image_alt: { label: 'Image Alt Text' }, - actions: { label: 'Action Buttons' }, - }, + stackbit: { + label: 'Feature Item', + labelField: 'title', + fields: { + title: { label: 'Title' }, + content: { label: 'Content' }, + image: { label: 'Image', control: { type: 'image-gallery', options: {} } }, + image_alt: { label: 'Image Alt Text' }, + actions: { label: 'Action Buttons' }, }, }, })) @@ -277,8 +259,7 @@ const SectionContact = defineNestedType(() => ({ }, form_action: { type: 'string', - description: - 'The path of your custom "success" page, if you want to replace the default success message./index.js', + description: 'The path of your custom "success" page, if you want to replace the default success message.', }, hide_labels: { type: 'boolean', @@ -293,21 +274,19 @@ const SectionContact = defineNestedType(() => ({ required: true, }, }, - extensions: { - stackbit: { - label: 'Contact Section', - labelField: 'title', - fields: { - ...sectionBaseFieldsExtension, - subtitle: { label: 'Subtitle' }, - content: { label: 'Content' }, - background: { label: 'Background' }, - form_id: { label: 'Form ID' }, - form_action: { label: 'Form Action' }, - hide_labels: { label: 'Hide labels of the form fields?' }, - form_fields: { label: 'Form Fields' }, - submit_label: { label: 'Submit Button Label' }, - }, + stackbit: { + label: 'Contact Section', + labelField: 'title', + fields: { + ...sectionBaseFieldsExtension, + subtitle: { label: 'Subtitle' }, + content: { label: 'Content' }, + background: { label: 'Background' }, + form_id: { label: 'Form ID' }, + form_action: { label: 'Form Action' }, + hide_labels: { label: 'Hide labels of the form fields?' }, + form_fields: { label: 'Form Fields' }, + submit_label: { label: 'Submit Button Label' }, }, }, })) @@ -333,16 +312,14 @@ const SectionFaq = defineNestedType(() => ({ of: FaqItem, }, }, - extensions: { - stackbit: { - label: 'Contact Section', - labelField: 'title', - fields: { - ...sectionBaseFieldsExtension, - subtitle: { label: 'Subtitle' }, - background: { label: 'Background' }, - faq_items: { label: 'FAQ Items' }, - }, + stackbit: { + label: 'Contact Section', + labelField: 'title', + fields: { + ...sectionBaseFieldsExtension, + subtitle: { label: 'Subtitle' }, + background: { label: 'Background' }, + faq_items: { label: 'FAQ Items' }, }, }, })) @@ -353,13 +330,11 @@ const FaqItem = defineNestedType(() => ({ question: { type: 'string' }, answer: { type: 'markdown' }, }, - extensions: { - stackbit: { - label: 'FAQ Item', - fields: { - question: { label: 'Question' }, - answer: { label: 'Answer' }, - }, + stackbit: { + label: 'FAQ Item', + fields: { + question: { label: 'Question' }, + answer: { label: 'Answer' }, }, }, })) @@ -379,14 +354,12 @@ const SectionPosts = defineNestedType(() => ({ default: 'gray', }, }, - extensions: { - stackbit: { - label: 'Posts List', - fields: { - ...sectionBaseFieldsExtension, - subtitle: { label: 'Subtitle' }, - background: { label: 'Background' }, - }, + stackbit: { + label: 'Posts List', + fields: { + ...sectionBaseFieldsExtension, + subtitle: { label: 'Subtitle' }, + background: { label: 'Background' }, }, }, })) @@ -410,15 +383,13 @@ const SectionPricing = defineNestedType(() => ({ of: PricingPlan, }, }, - extensions: { - stackbit: { - label: 'Pricing Section', - fields: { - ...sectionBaseFieldsExtension, - subtitle: { label: 'Subtitle' }, - background: { label: 'Background' }, - pricing_plans: { label: 'Pricing Plans' }, - }, + stackbit: { + label: 'Pricing Section', + fields: { + ...sectionBaseFieldsExtension, + subtitle: { label: 'Subtitle' }, + background: { label: 'Background' }, + pricing_plans: { label: 'Pricing Plans' }, }, }, })) @@ -448,18 +419,16 @@ const PricingPlan = defineNestedType(() => ({ of: Action, }, }, - extensions: { - stackbit: { - label: 'Pricing Plan', - labelField: 'title', - fields: { - title: { label: 'Title' }, - subtitle: { label: 'Subtitle' }, - price: { label: 'Price' }, - details: { label: 'Details' }, - highlight: { label: 'Highlight' }, - actions: { label: 'Action Buttons' }, - }, + stackbit: { + label: 'Pricing Plan', + labelField: 'title', + fields: { + title: { label: 'Title' }, + subtitle: { label: 'Subtitle' }, + price: { label: 'Price' }, + details: { label: 'Details' }, + highlight: { label: 'Highlight' }, + actions: { label: 'Action Buttons' }, }, }, })) @@ -483,15 +452,13 @@ const SectionReviews = defineNestedType(() => ({ of: ReviewItem, }, }, - extensions: { - stackbit: { - label: 'Reviews Section', - fields: { - ...sectionBaseFieldsExtension, - subtitle: { label: 'Subtitle' }, - background: { label: 'Background' }, - reviews: { label: 'Reviews' }, - }, + stackbit: { + label: 'Reviews Section', + fields: { + ...sectionBaseFieldsExtension, + subtitle: { label: 'Subtitle' }, + background: { label: 'Background' }, + reviews: { label: 'Reviews' }, }, }, })) @@ -504,15 +471,13 @@ const ReviewItem = defineNestedType(() => ({ avatar_alt: { type: 'string' }, content: { type: 'string' }, }, - extensions: { - stackbit: { - label: 'Review Item', - fields: { - author: { label: 'Author' }, - avatar: { label: 'Author Image' }, - avatar_alt: { label: 'Author Image Alt Text' }, - content: { label: 'Content' }, - }, + stackbit: { + label: 'Review Item', + fields: { + author: { label: 'Author' }, + avatar: { label: 'Author Image' }, + avatar_alt: { label: 'Author Image Alt Text' }, + content: { label: 'Content' }, }, }, })) diff --git a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Page.ts b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Page.ts index 111dfd5a..cff1f821 100644 --- a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Page.ts +++ b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Page.ts @@ -1,7 +1,7 @@ import { defineDocumentType } from 'contentlayer/source-files' -import { SEO } from '../nested/SEO.js' -import { urlFromFilePath } from '../utils.js' +import { SEO } from '../nested/SEO' +import { urlFromFilePath } from '../utils' export const Page = defineDocumentType(() => ({ name: 'Page', @@ -38,7 +38,5 @@ export const Page = defineDocumentType(() => ({ resolve: urlFromFilePath, }, }, - extensions: { - stackbit: { match: ['about.md', 'privacy-policy.md', 'signup.md', 'style-guide.md', 'terms-of-service.md'] }, - }, + stackbit: { match: ['about.md', 'privacy-policy.md', 'signup.md', 'style-guide.md', 'terms-of-service.md'] }, })) diff --git a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Person.ts b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Person.ts index f0e230a6..1b7331ff 100644 --- a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Person.ts +++ b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Person.ts @@ -9,7 +9,5 @@ export const Person = defineDocumentType(() => ({ bio: { type: 'markdown' }, photo: { type: 'string' }, }, - extensions: { - stackbit: { folder: 'authors' }, - }, + stackbit: { folder: 'authors' }, })) diff --git a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Post.ts b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Post.ts index 030ecf60..0d3db72b 100644 --- a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Post.ts +++ b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Post.ts @@ -1,8 +1,8 @@ import { defineDocumentType } from 'contentlayer/source-files' -import { SEO } from '../nested/SEO.js' -import { urlFromFilePath } from '../utils.js' -import { Person } from './Person.js' +import { SEO } from '../nested/SEO' +import { urlFromFilePath } from '../utils' +import { Person } from './Person' export const Post = defineDocumentType(() => ({ name: 'Post', @@ -56,19 +56,17 @@ export const Post = defineDocumentType(() => ({ resolve: urlFromFilePath, }, }, - extensions: { - stackbit: { - fields: { - title: { label: 'Title' }, - subtitle: { label: 'Subtitle' }, - date: { label: 'Date' }, - excerpt: { label: 'Excerpt' }, - image: { label: 'Image' }, - image_alt: { label: 'Image alt text (single post)' }, - thumb_image: { label: 'Image (blog feed)' }, - thumb_image_alt: { label: 'Image alt text (blog feed)' }, - }, - match: 'blog/**.md', + stackbit: { + fields: { + title: { label: 'Title' }, + subtitle: { label: 'Subtitle' }, + date: { label: 'Date' }, + excerpt: { label: 'Excerpt' }, + image: { label: 'Image' }, + image_alt: { label: 'Image alt text (single post)' }, + thumb_image: { label: 'Image (blog feed)' }, + thumb_image_alt: { label: 'Image alt text (blog feed)' }, }, + match: 'blog/**.md', }, })) diff --git a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/nested/Action.ts b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/nested/Action.ts index 8ab9864b..bb1caad3 100644 --- a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/nested/Action.ts +++ b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/nested/Action.ts @@ -52,19 +52,17 @@ export const Action = defineNestedType(() => ({ description: 'Add rel="nofollow" attribute to the link', }, }, - extensions: { - stackbit: { - labelField: 'label', - fields: { - label: { label: 'Label' }, - url: { label: 'URL' }, - style: { label: 'Style' }, - has_icon: { label: 'Show icon' }, - icon: { label: 'Icon' }, - icon_position: { label: 'Icon position' }, - new_window: { label: 'Open in new window' }, - no_follow: { label: 'No follow' }, - }, + stackbit: { + labelField: 'label', + fields: { + label: { label: 'Label' }, + url: { label: 'URL' }, + style: { label: 'Style' }, + has_icon: { label: 'Show icon' }, + icon: { label: 'Icon' }, + icon_position: { label: 'Icon position' }, + new_window: { label: 'Open in new window' }, + no_follow: { label: 'No follow' }, }, }, })) diff --git a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/nested/FormField.ts b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/nested/FormField.ts index 32d2508e..dd3e0fb1 100644 --- a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/nested/FormField.ts +++ b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/nested/FormField.ts @@ -32,18 +32,16 @@ export const FormField = defineNestedType(() => ({ default: false, }, }, - extensions: { - stackbit: { - label: 'Form Field', - labelField: 'name', - fields: { - input_type: { label: 'Type' }, - name: { label: 'Name' }, - label: { label: 'Label' }, - default_value: { label: 'Placeholder text or default value' }, - options: { label: 'Options' }, - is_required: { label: 'Is the field required?' }, - }, + stackbit: { + label: 'Form Field', + labelField: 'name', + fields: { + input_type: { label: 'Type' }, + name: { label: 'Name' }, + label: { label: 'Label' }, + default_value: { label: 'Placeholder text or default value' }, + options: { label: 'Options' }, + is_required: { label: 'Is the field required?' }, }, }, })) diff --git a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/nested/SEO.ts b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/nested/SEO.ts index 2e686411..4ac8af8a 100644 --- a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/nested/SEO.ts +++ b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/nested/SEO.ts @@ -25,15 +25,13 @@ export const SEO = defineNestedType(() => ({ of: Extra, }, }, - extensions: { - stackbit: { - label: 'Page meta data', - fields: { - title: { label: 'Title' }, - description: { label: 'Description' }, - robots: { label: 'Robots' }, - extra: { label: 'Extra' }, - }, + stackbit: { + label: 'Page meta data', + fields: { + title: { label: 'Title' }, + description: { label: 'Description' }, + robots: { label: 'Robots' }, + extra: { label: 'Extra' }, }, }, })) diff --git a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/index.ts b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/index.ts index 0acc0342..732fb0db 100644 --- a/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/index.ts +++ b/packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/index.ts @@ -14,7 +14,7 @@ const esbuildHash = 'not-important-for-this-test' const makeSchema = (documentTypes: Record<string, DocumentType<any>>) => pipe( T.tryPromise(() => makeSource({ documentTypes, contentDirPath: '' })), - T.chain((source) => source.provideSchema(esbuildHash)), + T.chain((source) => source.provideSchema({ esbuildHash })), provideJaegerTracing('contentlayer-cli'), provideConsole, T.runPromise, diff --git a/packages/contentlayer-stackbit-yaml-generator/src/cli/DefaultCommand.ts b/packages/contentlayer-stackbit-yaml-generator/src/cli/DefaultCommand.ts index cdda51eb..0756f430 100644 --- a/packages/contentlayer-stackbit-yaml-generator/src/cli/DefaultCommand.ts +++ b/packages/contentlayer-stackbit-yaml-generator/src/cli/DefaultCommand.ts @@ -1,8 +1,8 @@ import type { HasCwd } from '@contentlayer/core' -import { getConfig, provideCwd } from '@contentlayer/core' +import * as core from '@contentlayer/core' import { provideJaegerTracing, recRemoveUndefinedValues } from '@contentlayer/utils' import type { HasConsole } from '@contentlayer/utils/effect' -import { OT, pipe, pretty, provideConsole, T } from '@contentlayer/utils/effect' +import { OT, pipe, pretty, provideConsole, S, T } from '@contentlayer/utils/effect' import { Command, Option } from 'clipanion' import { promises as fs } from 'node:fs' import * as path from 'node:path' @@ -32,6 +32,10 @@ export class DefaultCommand extends Command { validator: t.isString(), }) + watch = Option.Boolean('-w,--watch', false, { + description: 'Watch the config file for changes and regenerate the output file', + }) + // TODO refactor similar to `@contentlayer/cli` async execute() { try { @@ -39,7 +43,7 @@ export class DefaultCommand extends Command { this.executeSafe(), provideJaegerTracing('contentlayer-stackbit-yaml-generator'), T.tapCause((cause) => T.die(pretty(cause))), - provideCwd, + core.provideCwd, provideConsole, T.runPromise, ) @@ -50,37 +54,54 @@ export class DefaultCommand extends Command { } executeSafe = (): T.Effect<OT.HasTracer & HasCwd & HasConsole, unknown, void> => - pipe( - getConfig({ configPath: this.configPath }), - T.chain((config) => - T.struct({ source: T.succeed(config.source), schema: config.source.provideSchema(config.esbuildHash) }), - ), - T.chain(({ schema, source }) => - T.tryCatchPromise( - async () => { - let stackbitConfig = convertSchema(schema, source.extensions) - recRemoveUndefinedValues(stackbitConfig) - - const transform = await getTransform(this.transformPath) - if (transform) { - stackbitConfig = transform(stackbitConfig) - } - - const yamlContent = `\ + this.watch + ? pipe( + core.getConfigWatch({ configPath: this.configPath }), + S.mapEffectEitherRight((config) => pipe(transformAndGenerateStackbitYaml({ config, self: this }), T.either)), + S.runDrain, + ) + : pipe( + core.getConfig({ configPath: this.configPath }), + T.chain((config) => transformAndGenerateStackbitYaml({ config, self: this })), + OT.withSpan('DefaultCommand:executeSafe'), + ) +} + +const transformAndGenerateStackbitYaml = ({ config, self }: { config: core.Config; self: DefaultCommand }) => + pipe( + T.struct({ + source: T.succeed(config.source), + schema: config.source.provideSchema({ esbuildHash: config.esbuildHash, extensionProperties: ['stackbit'] }), + }), + + T.chain(({ schema, source }) => + T.tryCatchPromise( + async () => { + let stackbitConfig = convertSchema({ + schema, + extensions: source.extensions.stackbit ?? {}, + fieldOptions: source.options.fieldOptions, + }) + recRemoveUndefinedValues(stackbitConfig) + + const transform = await getTransform(self.transformPath) + if (transform) { + stackbitConfig = transform(stackbitConfig) + } + + const yamlContent = `\ # This file is generated by Contentlayer ${toYamlString(stackbitConfig)} ` - await fs.writeFile(this.stackbitYamlPath, yamlContent) - console.log(`Stackbit config generated to ${this.stackbitYamlPath}`) - }, - (error) => error, - ), + await fs.writeFile(self.stackbitYamlPath, yamlContent) + console.log(`Stackbit config generated to ${self.stackbitYamlPath}`) + }, + (error) => error, ), - OT.withSpan('DefaultCommand:executeSafe'), - ) -} + ), + ) const getTransform = async (transformPath: string): Promise<undefined | Transform> => { const transformFileExists = await fileOrDirExists(transformPath) diff --git a/packages/contentlayer-stackbit-yaml-generator/src/cli/convert.ts b/packages/contentlayer-stackbit-yaml-generator/src/cli/convert.ts index 45a43ccd..f20f72f5 100644 --- a/packages/contentlayer-stackbit-yaml-generator/src/cli/convert.ts +++ b/packages/contentlayer-stackbit-yaml-generator/src/cli/convert.ts @@ -1,51 +1,112 @@ import type * as core from '@contentlayer/core' import * as utils from '@contentlayer/utils' +import { identity } from '@contentlayer/utils/effect' import type * as Stackbit from '@stackbit/sdk' -export const convertSchema = ( - { documentTypeDefMap, nestedTypeDefMap }: core.SchemaDef, - extensions: core.PluginExtensions, -): Stackbit.YamlConfig => { - // TODO this needs to be more dynamic/configurable - const urlPathFieldName = 'url_path' +import type { StackbitExtension, StackbitExtensionField } from '../types/index.js' + +export const convertSchema = ({ + schema, + fieldOptions, + extensions, +}: { + schema: core.SchemaDef + fieldOptions: core.FieldOptions + extensions: StackbitExtension['root'] +}): Stackbit.YamlConfig => { + const { documentTypeDefMap, nestedTypeDefMap } = schema const documentTypeDefs = Object.values(documentTypeDefMap) const [pageDocumentDefs, dataDocumentDefs] = utils.partition( documentTypeDefs, - (_) => - _.fieldDefs.some((_) => _.name === urlPathFieldName) || _.computedFields.some((_) => _.name === urlPathFieldName), + (_) => _.extensions.stackbit?.isPage ?? false, + ) + + const pageModels = pageDocumentDefs.map((def) => + documentOrObjectDefToStackbitYamlModel({ def, type: 'page', fieldOptions }), + ) + const dataModels = dataDocumentDefs.map((def) => + documentOrObjectDefToStackbitYamlModel({ def, type: 'data', fieldOptions }), + ) + const objectModels = Object.values(nestedTypeDefMap).map((def) => + documentOrObjectDefToStackbitYamlModel({ def, type: 'object', fieldOptions }), ) - const pagesDir = extensions.stackbit?.pagesDir - const dataDir = extensions.stackbit?.dataDir const models = Object.fromEntries( - [ - ...pageDocumentDefs.map((def) => documentOrObjectDefToStackbitYamlModel({ def, type: 'page', urlPathFieldName })), - ...dataDocumentDefs.map((def) => documentOrObjectDefToStackbitYamlModel({ def, type: 'data', urlPathFieldName })), - ...Object.values(nestedTypeDefMap).map((def) => - documentOrObjectDefToStackbitYamlModel({ def, type: 'object', urlPathFieldName }), - ), - ].map(({ model, name }) => [name, model]), + [...pageModels, ...dataModels, ...objectModels].map(({ model, name }) => [name, model]), + ) + + const contentModels = Object.fromEntries( + pageDocumentDefs.flatMap((def) => { + const ext = def.extensions.stackbit + + if (ext?.isPage === true) { + const contentModel = identity<Stackbit.ContentModel>({ + isPage: true, + newFilePath: ext?.newFilePath, + urlPath: ext?.urlPath, + exclude: ext?.exclude, + file: ext?.file, + folder: ext?.folder, + hideContent: ext?.hideContent, + match: ext?.match, + singleInstance: ext?.singleInstance, + }) + + return [[def.name, contentModel]] + } + + return [] + }), ) - return { stackbitVersion: '~0.3.0', nodeVersion: '>=12', models, pagesDir, dataDir } + const { pageLayoutKey, ...restExtensions } = extensions + + return identity<Stackbit.YamlConfig>({ + stackbitVersion: '~0.4.0', + nodeVersion: '>=14', + cmsName: 'git', + ssgName: 'nextjs', + objectTypeKey: 'type', + ...restExtensions, + pageLayoutKey: pageLayoutKey ?? fieldOptions.typeFieldName, + models, + contentModels, + }) } -const documentOrObjectDefToStackbitYamlModel = ({ +type GetStackbitYamlModel<TType> = TType extends 'page' + ? Stackbit.YamlPageModel + : TType extends 'object' + ? Stackbit.ObjectModel + : TType extends 'data' + ? Stackbit.DataModel + : never + +const documentOrObjectDefToStackbitYamlModel = <TType extends Exclude<Stackbit.YamlModel['type'], 'config'>>({ def, type, + fieldOptions, }: { def: core.DocumentTypeDef | core.NestedTypeDef - type: Stackbit.YamlModel['type'] - urlPathFieldName: string -}): { model: Stackbit.YamlModel; name: string } => { + type: TType + fieldOptions: core.FieldOptions +}): { model: GetStackbitYamlModel<TType>; name: string } => { const ext = def.extensions.stackbit const fields = def._tag === 'DocumentTypeDef' - ? def.fieldDefs - .filter(not(isContentMarkdownFieldDef)) - .map((fieldDef) => fieldDefToStackbitField({ fieldDef, fieldExtension: ext?.fields?.[fieldDef.name] })) + ? def.fieldDefs.filter(not(isContentMarkdownFieldDef(fieldOptions.bodyFieldName))).map((fieldDef) => + fieldDefToStackbitField({ + fieldDef, + fieldExtension: fieldDef.extensions.stackbit ?? ext?.fields?.[fieldDef.name], + fieldOptions, + }), + ) : def.fieldDefs.map((fieldDef) => - fieldDefToStackbitField({ fieldDef, fieldExtension: ext?.fields?.[fieldDef.name] }), + fieldDefToStackbitField({ + fieldDef, + fieldExtension: fieldDef.extensions.stackbit ?? ext?.fields?.[fieldDef.name], + fieldOptions, + }), ) const options = { @@ -62,35 +123,51 @@ const documentOrObjectDefToStackbitYamlModel = ({ } const name = def.name - const singleInstance: any = def._tag === 'DocumentTypeDef' && def.isSingleton + const isSingleInstance = + ext?.singleInstance !== undefined ? ext.singleInstance : def._tag === 'DocumentTypeDef' && def.isSingleton + + const singleInstance = isSingleInstance ? { singleInstance: true } : {} switch (type) { case 'data': - return { name, model: { ...modelCommon, type: 'data', singleInstance } } - case 'config': - return { name, model: { ...modelCommon, type: 'config', singleInstance } } + return { name, model: identity<Stackbit.YamlDataModel>({ ...modelCommon, ...singleInstance, type: 'data' }) } as { + model: GetStackbitYamlModel<TType> + name: string + } case 'object': - return { name, model: { ...modelCommon, type: 'object' } } + return { name, model: identity<Stackbit.YamlObjectModel>({ ...modelCommon, type: 'object' }) } as { + model: GetStackbitYamlModel<TType> + name: string + } case 'page': - return { name, model: { ...modelCommon, type: 'page', singleInstance } } + return { name, model: identity<Stackbit.YamlPageModel>({ ...modelCommon, ...singleInstance, type: 'page' }) } as { + model: GetStackbitYamlModel<TType> + name: string + } + default: + utils.casesHandled(type) } } const fieldDefToStackbitField = ({ fieldDef, fieldExtension, + fieldOptions, }: { fieldDef: core.FieldDef - fieldExtension: core.StackbitExtension.FieldExtension | undefined + fieldExtension: StackbitExtensionField | undefined + fieldOptions: core.FieldOptions }): Stackbit.Field => { const commonField: Omit<Stackbit.FieldCommonProps, 'type'> = { name: fieldDef.name, required: fieldDef.isRequired, const: fieldExtension?.const, - default: fieldDef.default, + default: fieldExtension?.initialValue, description: fieldDef.description, hidden: fieldExtension?.hidden, label: fieldExtension?.label, + group: fieldExtension?.group, + readOnly: fieldExtension?.readOnly, } switch (fieldDef.type) { case 'enum': @@ -108,22 +185,18 @@ const fieldDefToStackbitField = ({ ...commonField, type: 'object', fields: fieldDef.typeDef.fieldDefs - .filter(not(isContentMarkdownFieldDef)) - .map((fieldDef) => fieldDefToStackbitField({ fieldDef, fieldExtension: undefined })), + .filter(not(isContentMarkdownFieldDef(fieldOptions.bodyFieldName))) + .map((fieldDef) => fieldDefToStackbitField({ fieldDef, fieldExtension: undefined, fieldOptions })), } case 'json': return { ...commonField, type: 'object', fields: [] } case 'list': case 'list_polymorphic': - return { ...commonField, type: 'list', items: listFieldDefToStackbitFieldListItems(fieldDef) } + return { ...commonField, type: 'list', items: listFieldDefToStackbitFieldListItems(fieldDef, fieldOptions) } case 'date': case 'number': case 'string': case 'markdown': - // case 'text': - // case 'slug': - // case 'image': - // case 'url': case 'boolean': return { ...commonField, type: fieldDef.type } case 'mdx': @@ -135,6 +208,7 @@ const fieldDefToStackbitField = ({ const listFieldDefToStackbitFieldListItems = ( fieldDef: core.ListFieldDef | core.ListPolymorphicFieldDef, + fieldOptions: core.FieldOptions, ): Stackbit.FieldListItems => { const getModelName = (item: core.ListFieldDefItem.ItemNested | core.ListFieldDefItem.ItemReference) => item.type === 'reference' ? item.documentTypeName : item.nestedTypeName @@ -150,7 +224,7 @@ const listFieldDefToStackbitFieldListItems = ( // TODO make more configurable via global `objectTypeKey` option // https://www.stackbit.com/docs/stackbit-yaml/properties/#objecttypekey throw new Error( - `typeField needs to be called "type" in order to be supported by Stackbit. typeField found: "${fieldDef.typeField}"`, + `typeField needs to be called "type" in order to be supported by Stackbit. Stackbit config option "objectTypeKey" isn't supported yet. typeField found: "${fieldDef.typeField}"`, ) } @@ -176,8 +250,8 @@ const listFieldDefToStackbitFieldListItems = ( return { type: 'object', fields: fieldDef.of.typeDef.fieldDefs - .filter(not(isContentMarkdownFieldDef)) - .map((fieldDef) => fieldDefToStackbitField({ fieldDef, fieldExtension: undefined })), + .filter(not(isContentMarkdownFieldDef(fieldOptions.bodyFieldName))) + .map((fieldDef) => fieldDefToStackbitField({ fieldDef, fieldExtension: undefined, fieldOptions })), } case 'enum': return { type: 'enum', options: fieldDef.of.options as string[] } @@ -197,5 +271,5 @@ const not = (...args: Parameters<Fn>) => !fn(...args) -const isContentMarkdownFieldDef = (fieldDef: core.FieldDef) => - fieldDef.name === 'content' && fieldDef.type === 'markdown' +const isContentMarkdownFieldDef = (bodyFieldName: string) => (fieldDef: core.FieldDef) => + fieldDef.name === bodyFieldName && (fieldDef.type === 'markdown' || fieldDef.type === 'mdx') diff --git a/packages/contentlayer-stackbit-yaml-generator/src/cli/utils.ts b/packages/contentlayer-stackbit-yaml-generator/src/cli/utils.ts index 9e6088f1..d69ef07a 100644 --- a/packages/contentlayer-stackbit-yaml-generator/src/cli/utils.ts +++ b/packages/contentlayer-stackbit-yaml-generator/src/cli/utils.ts @@ -1,3 +1,3 @@ import YAML from 'yaml' -export const toYamlString = (json: any): string => YAML.stringify(json) +export const toYamlString = (json: any): string => YAML.stringify(json, { aliasDuplicateObjects: false }) diff --git a/packages/contentlayer-stackbit-yaml-generator/src/types/index.ts b/packages/contentlayer-stackbit-yaml-generator/src/types/index.ts new file mode 100644 index 00000000..6389736b --- /dev/null +++ b/packages/contentlayer-stackbit-yaml-generator/src/types/index.ts @@ -0,0 +1,104 @@ +import type * as Stackbit from '@stackbit/sdk' + +export type StackbitExtensionRoot = Partial<Omit<Stackbit.YamlConfig, 'models' | 'contentModels'>> + +export type StackbitExtensionDocumentType = Omit< + Stackbit.DataModel | Stackbit.PageModel, + 'fields' | 'name' | 'type' +> & { + fields?: Record<string, StackbitExtensionField> +} & StackbitContentModelProps + +type StackbitContentModelProps = + | { + isPage?: false | undefined + } + | { + isPage: true + urlPath?: string + newFilePath?: string + hideContent?: boolean + singleInstance?: boolean + file?: string + folder?: string + match?: string | string[] + exclude?: string | string[] + } +// { +// fieldGroups?: FieldGroup[] +// fields?: Record<string, StackbitExtensionField> +// // fields?: Partial<Record<KnownFieldNames<DefName>, FieldExtension>> | Record<string, FieldExtension> +// /** the name of the field that will be used as a title of an object */ +// labelField?: string +// label?: string +// folder?: string +// file?: string +// match?: string | string[] + +// groups?: string[] +// } + +export type StackbitExtensionNestedType = Stackbit.ObjectModel + +export type FieldGroup = { + name: string + label: string +} + +// type KnownFieldNames<DefName extends string> = GetFieldNamesForDefinitionGen<DefName> + +export type StackbitExtensionField = Omit<Stackbit.Field, 'type' | 'name' | 'default'> & { + initialValue?: any + /** Note only valid for type: string */ + isImage?: boolean +} + +// & { +// label?: string +// const?: any +// /** Users will not be able to edit hidden fields, therefore when hiding a field you should specify the default or const properties to populate these fields when new objects are created. */ +// hidden?: boolean +// group?: string +// /** @default "content" */ +// control?: Control +// } + +export type Control = ControlImageGallery | ControlColorPallete + +export type ControlImageGallery = { + type: 'image-gallery' + options: ControlImageGalleryOption +} + +export type ControlImageGalleryOption = {} + +export type ControlColorPallete = { + type: 'color-pallete' + options: ControlColorPalleteOption[] +} + +export type ControlColorPalleteOption = { + value: string + backgroundColor: string + textColor?: string + borderColor?: string + borderRadius?: number +} + +// export type ControlType = 'control-pallete' | 'dropdown' | 'horizontal-switch' | 'image-gallery' +export type ControlType = Control['type'] + +export type StackbitExtension = { + root: StackbitExtensionRoot + documentType: StackbitExtensionDocumentType + nestedType: StackbitExtensionDocumentType + field: StackbitExtensionField +} + +interface ContentlayerExtensionsStackbit { + stackbit: StackbitExtension +} + +declare global { + interface ContentlayerExtensions extends ContentlayerExtensionsStackbit {} +} diff --git a/packages/contentlayer/package.json b/packages/contentlayer/package.json index d779af80..456aa843 100644 --- a/packages/contentlayer/package.json +++ b/packages/contentlayer/package.json @@ -1,6 +1,6 @@ { "name": "contentlayer", - "version": "0.2.5", + "version": "0.2.6-dev.8", "bin": "./bin/cli.cjs", "type": "module", "engines": { diff --git a/packages/next-contentlayer/package.json b/packages/next-contentlayer/package.json index 7887027d..d1737c96 100644 --- a/packages/next-contentlayer/package.json +++ b/packages/next-contentlayer/package.json @@ -1,6 +1,6 @@ { "name": "next-contentlayer", - "version": "0.2.5", + "version": "0.2.6-dev.8", "type": "module", "main": "./dist/index-cjs.cjs", "sideEffects": false, diff --git a/yarn.lock b/yarn.lock index d680ebe3..bbcbb072 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1662,7 +1662,7 @@ __metadata: unified: ^10.1.2 vite: ^2.9.8 vitest: ^0.12.4 - yaml: ^1.10.2 + yaml: ^2.1.0 peerDependencies: date-fns: 2.x peerDependenciesMeta: @@ -6392,9 +6392,9 @@ __metadata: typescript: ^4.6.4 vite: ^2.9.8 vitest: ^0.12.4 - yaml: ^1.10.2 + yaml: ^2.1.0 bin: - contentlayer-stackbit-yaml-generator: ./dist/cli/index.js + contentlayer-stackbit-yaml-generator: ./bin/cli.cjs languageName: unknown linkType: soft @@ -20277,6 +20277,13 @@ fsevents@~2.3.2: languageName: node linkType: hard +"yaml@npm:^2.1.0": + version: 2.1.0 + resolution: "yaml@npm:2.1.0" + checksum: 59323a8b51b10d9ad0eab951e7a1f315f1076c123b08ffe60441add1df4fa3433b1d5783b21c50a65536e9d853b23fa567921dbd4bc0d711be2dbf14a06be03b + languageName: node + linkType: hard + "yargs-parser@npm:^18.1.2, yargs-parser@npm:^18.1.3": version: 18.1.3 resolution: "yargs-parser@npm:18.1.3"