| import { parse, nodes } from '@markdoc/markdoc/dist/index.mjs'; |
| import { assertNever } from 'emery/assertions'; |
| import { assert, assertNever as assertNever$1 } from 'emery'; |
| import { b as basicFormFieldWithSimpleReaderParse, t as text, F as FieldDataError, h as DocumentFieldInput, n as normalizeDocumentFieldChildren, i as serializeMarkdoc, j as getDefaultValue, p as parseToEditorState, k as serializeFromEditorState, l as prosemirrorToYXmlFragment, m as createEditorStateFromYJS, o as parseToEditorStateMDX, q as serializeFromEditorStateMDX, r as createEditorSchema } from './index-1a9da0fb.node.js'; |
| import { jsx } from 'react/jsx-runtime'; |
| import { createHash } from 'crypto'; |
|
|
| function object(fields, opts) { |
| return { |
| ...opts, |
| kind: 'object', |
| fields |
| }; |
| } |
|
|
| function getValueAtPropPath(value, inputPath) { |
| const path = [...inputPath]; |
| while (path.length) { |
| const key = path.shift(); |
| value = value[key]; |
| } |
| return value; |
| } |
| function transformProps(schema, value, visitors, path = []) { |
| if (schema.kind === 'form' || schema.kind === 'child') { |
| if (visitors[schema.kind]) { |
| return visitors[schema.kind](schema, value, path); |
| } |
| return value; |
| } |
| if (schema.kind === 'object') { |
| const val = Object.fromEntries(Object.entries(schema.fields).map(([key, val]) => { |
| return [key, transformProps(val, value[key], visitors, [...path, key])]; |
| })); |
| if (visitors.object) { |
| return visitors[schema.kind](schema, val, path); |
| } |
| return val; |
| } |
| if (schema.kind === 'array') { |
| const val = value.map((val, idx) => transformProps(schema.element, val, visitors, path.concat(idx))); |
| if (visitors.array) { |
| return visitors[schema.kind](schema, val, path); |
| } |
| return val; |
| } |
| if (schema.kind === 'conditional') { |
| const discriminant = transformProps(schema.discriminant, value.discriminant, visitors, path.concat('discriminant')); |
| const conditionalVal = transformProps(schema.values[discriminant.toString()], value.value, visitors, path.concat('value')); |
| const val = { |
| discriminant, |
| value: conditionalVal |
| }; |
| if (visitors.conditional) { |
| return visitors[schema.kind](schema, val, path); |
| } |
| return val; |
| } |
| assertNever(schema); |
| } |
|
|
| // a v important note |
| // marks in the markdown ast/html are represented quite differently to how they are in slate |
| // if you had the markdown **something https://keystonejs.com something** |
| // the bold node is the parent of the link node |
| // but in slate, marks are only represented on text nodes |
|
|
| const currentlyActiveMarks = new Set(); |
| const currentlyDisabledMarks = new Set(); |
| let currentLink = null; |
| function addMarkToChildren(mark, cb) { |
| const wasPreviouslyActive = currentlyActiveMarks.has(mark); |
| currentlyActiveMarks.add(mark); |
| try { |
| return cb(); |
| } finally { |
| if (!wasPreviouslyActive) { |
| currentlyActiveMarks.delete(mark); |
| } |
| } |
| } |
| function setLinkForChildren(href, cb) { |
| // we'll only use the outer link |
| if (currentLink !== null) { |
| return cb(); |
| } |
| currentLink = href; |
| try { |
| return cb(); |
| } finally { |
| currentLink = null; |
| } |
| } |
|
|
| /** |
| * This type is more strict than `Element & { type: 'link'; }` because `children` |
| * is constrained to only contain Text nodes. This can't be assumed generally around the editor |
| * (because of potentially future inline components or nested links(which are normalized away but the editor needs to not break if it happens)) |
| * but where this type is used, we're only going to allow links to contain Text and that's important |
| * so that we know a block will never be inside an inline because Slate gets unhappy when that happens |
| * (really the link inline should probably be a mark rather than an inline, |
| * non-void inlines are probably always bad but that would imply changing the document |
| * structure which would be such unnecessary breakage) |
| */ |
|
|
| function getInlineNodes(text) { |
| const node = { |
| text |
| }; |
| for (const mark of currentlyActiveMarks) { |
| if (!currentlyDisabledMarks.has(mark)) { |
| node[mark] = true; |
| } |
| } |
| if (currentLink !== null) { |
| return [{ |
| text: '' |
| }, { |
| type: 'link', |
| href: currentLink, |
| children: [node] |
| }, { |
| text: '' |
| }]; |
| } |
| return [node]; |
| } |
|
|
| class VariableChildFields extends Error { |
| constructor() { |
| super('There are a variable number of child fields'); |
| } |
| } |
| function findSingleChildField(schema) { |
| try { |
| const result = _findConstantChildFields(schema, [], new Set()); |
| if (result.length === 1) { |
| return result[0]; |
| } |
| return; |
| } catch (err) { |
| if (err instanceof VariableChildFields) { |
| return; |
| } |
| throw err; |
| } |
| } |
| function _findConstantChildFields(schema, path, seenSchemas) { |
| if (seenSchemas.has(schema)) { |
| return []; |
| } |
| seenSchemas.add(schema); |
| switch (schema.kind) { |
| case 'form': |
| return []; |
| case 'child': |
| return [{ |
| relativePath: path, |
| options: schema.options, |
| kind: 'child' |
| }]; |
| case 'conditional': |
| { |
| if (couldContainChildField(schema)) { |
| throw new VariableChildFields(); |
| } |
| return []; |
| } |
| case 'array': |
| { |
| if (schema.asChildTag) { |
| const child = _findConstantChildFields(schema.element, [], seenSchemas); |
| if (child.length > 1) { |
| return []; |
| } |
| return [{ |
| kind: 'array', |
| asChildTag: schema.asChildTag, |
| field: schema, |
| relativePath: path, |
| child: child[0] |
| }]; |
| } |
| if (couldContainChildField(schema)) { |
| throw new VariableChildFields(); |
| } |
| return []; |
| } |
| case 'object': |
| { |
| const paths = []; |
| for (const [key, value] of Object.entries(schema.fields)) { |
| paths.push(..._findConstantChildFields(value, path.concat(key), seenSchemas)); |
| } |
| return paths; |
| } |
| } |
| } |
| function couldContainChildField(schema, seen = new Set()) { |
| if (seen.has(schema)) { |
| return false; |
| } |
| seen.add(schema); |
| switch (schema.kind) { |
| case 'form': |
| return false; |
| case 'child': |
| return true; |
| case 'conditional': |
| return Object.values(schema.values).some(value => couldContainChildField(value, seen)); |
| case 'object': |
| return Object.keys(schema.fields).some(key => couldContainChildField(schema.fields[key], seen)); |
| case 'array': |
| return couldContainChildField(schema.element, seen); |
| } |
| } |
|
|
| function inlineNodeFromMarkdoc(node) { |
| if (node.type === 'inline') { |
| return inlineChildrenFromMarkdoc(node.children); |
| } |
| if (node.type === 'link') { |
| return setLinkForChildren(node.attributes.href, () => inlineChildrenFromMarkdoc(node.children)); |
| } |
| if (node.type === 'text') { |
| return getInlineNodes(node.attributes.content); |
| } |
| if (node.type === 'strong') { |
| return addMarkToChildren('bold', () => inlineChildrenFromMarkdoc(node.children)); |
| } |
| if (node.type === 'code') { |
| return addMarkToChildren('code', () => getInlineNodes(node.attributes.content)); |
| } |
| if (node.type === 'em') { |
| return addMarkToChildren('italic', () => inlineChildrenFromMarkdoc(node.children)); |
| } |
| if (node.type === 's') { |
| return addMarkToChildren('strikethrough', () => inlineChildrenFromMarkdoc(node.children)); |
| } |
| if (node.type === 'tag') { |
| if (node.tag === 'u') { |
| return addMarkToChildren('underline', () => inlineChildrenFromMarkdoc(node.children)); |
| } |
| if (node.tag === 'kbd') { |
| return addMarkToChildren('keyboard', () => inlineChildrenFromMarkdoc(node.children)); |
| } |
| if (node.tag === 'sub') { |
| return addMarkToChildren('subscript', () => inlineChildrenFromMarkdoc(node.children)); |
| } |
| if (node.tag === 'sup') { |
| return addMarkToChildren('superscript', () => inlineChildrenFromMarkdoc(node.children)); |
| } |
| } |
| if (node.type === 'softbreak') { |
| return getInlineNodes(' '); |
| } |
| if (node.type === 'hardbreak') { |
| return getInlineNodes('\n'); |
| } |
| if (node.tag === 'component-inline-prop' && Array.isArray(node.attributes.propPath) && node.attributes.propPath.every(x => typeof x === 'string' || typeof x === 'number')) { |
| return { |
| type: 'component-inline-prop', |
| children: inlineFromMarkdoc(node.children), |
| propPath: node.attributes.propPath |
| }; |
| } |
| throw new Error(`Unknown inline node type: ${node.type}`); |
| } |
| function inlineChildrenFromMarkdoc(nodes) { |
| return nodes.flatMap(inlineNodeFromMarkdoc); |
| } |
| function inlineFromMarkdoc(nodes) { |
| const transformedNodes = nodes.flatMap(inlineNodeFromMarkdoc); |
| const nextNodes = []; |
| let lastNode; |
| for (const [idx, node] of transformedNodes.entries()) { |
| var _lastNode; |
| if (node.type === undefined && node.text === '' && ((_lastNode = lastNode) === null || _lastNode === void 0 ? void 0 : _lastNode.type) === undefined && idx !== transformedNodes.length - 1) { |
| continue; |
| } |
| nextNodes.push(node); |
| lastNode = node; |
| } |
| if (!nextNodes.length) { |
| nextNodes.push({ |
| text: '' |
| }); |
| } |
| return nextNodes; |
| } |
| function fromMarkdoc(node, componentBlocks) { |
| const nodes = node.children.flatMap(x => fromMarkdocNode(x, componentBlocks)); |
| if (nodes.length === 0) { |
| return [{ |
| type: 'paragraph', |
| children: [{ |
| text: '' |
| }] |
| }]; |
| } |
| if (nodes[nodes.length - 1].type !== 'paragraph') { |
| nodes.push({ |
| type: 'paragraph', |
| children: [{ |
| text: '' |
| }] |
| }); |
| } |
| return nodes; |
| } |
| function fromMarkdocNode(node, componentBlocks) { |
| if (node.type === 'blockquote') { |
| return { |
| type: 'blockquote', |
| children: node.children.flatMap(x => fromMarkdocNode(x, componentBlocks)) |
| }; |
| } |
| if (node.type === 'fence') { |
| const { |
| language, |
| content, |
| ...rest |
| } = node.attributes; |
| return { |
| type: 'code', |
| children: [{ |
| text: content.replace(/\n$/, '') |
| }], |
| ...(typeof language === 'string' ? { |
| language |
| } : {}), |
| ...rest |
| }; |
| } |
| if (node.type === 'heading') { |
| return { |
| ...node.attributes, |
| level: node.attributes.level, |
| type: 'heading', |
| children: inlineFromMarkdoc(node.children) |
| }; |
| } |
| if (node.type === 'list') { |
| return { |
| type: node.attributes.ordered ? 'ordered-list' : 'unordered-list', |
| children: node.children.flatMap(x => fromMarkdocNode(x, componentBlocks)) |
| }; |
| } |
| if (node.type === 'item') { |
| var _node$children$; |
| const children = [{ |
| type: 'list-item-content', |
| children: node.children.length ? inlineFromMarkdoc([node.children[0]]) : [{ |
| text: '' |
| }] |
| }]; |
| if (((_node$children$ = node.children[1]) === null || _node$children$ === void 0 ? void 0 : _node$children$.type) === 'list') { |
| const list = node.children[1]; |
| children.push({ |
| type: list.attributes.ordered ? 'ordered-list' : 'unordered-list', |
| children: list.children.flatMap(x => fromMarkdocNode(x, componentBlocks)) |
| }); |
| } |
| return { |
| type: 'list-item', |
| children |
| }; |
| } |
| if (node.type === 'paragraph') { |
| if (node.children.length === 1 && node.children[0].type === 'inline' && node.children[0].children.length === 1 && node.children[0].children[0].type === 'image') { |
| var _image$attributes$tit; |
| const image = node.children[0].children[0]; |
| return { |
| type: 'image', |
| src: decodeURI(image.attributes.src), |
| alt: image.attributes.alt, |
| title: (_image$attributes$tit = image.attributes.title) !== null && _image$attributes$tit !== void 0 ? _image$attributes$tit : '', |
| children: [{ |
| text: '' |
| }] |
| }; |
| } |
| const children = inlineFromMarkdoc(node.children); |
| if (children.length === 1 && children[0].type === 'component-inline-prop') { |
| return children[0]; |
| } |
| return { |
| type: 'paragraph', |
| children, |
| textAlign: node.attributes.textAlign |
| }; |
| } |
| if (node.type === 'hr') { |
| return { |
| type: 'divider', |
| children: [{ |
| text: '' |
| }] |
| }; |
| } |
| if (node.type === 'table') { |
| return { |
| type: 'table', |
| children: node.children.flatMap(x => fromMarkdocNode(x, componentBlocks)) |
| }; |
| } |
| if (node.type === 'tbody') { |
| return { |
| type: 'table-body', |
| children: node.children.flatMap(x => fromMarkdocNode(x, componentBlocks)) |
| }; |
| } |
| if (node.type === 'thead') { |
| if (!node.children.length) return []; |
| return { |
| type: 'table-head', |
| children: node.children.flatMap(x => fromMarkdocNode(x, componentBlocks)) |
| }; |
| } |
| if (node.type === 'tr') { |
| return { |
| type: 'table-row', |
| children: node.children.flatMap(x => fromMarkdocNode(x, componentBlocks)) |
| }; |
| } |
| if (node.type === 'td') { |
| return { |
| type: 'table-cell', |
| children: node.children.flatMap(x => fromMarkdocNode(x, componentBlocks)) |
| }; |
| } |
| if (node.type === 'th') { |
| return { |
| type: 'table-cell', |
| header: true, |
| children: node.children.flatMap(x => fromMarkdocNode(x, componentBlocks)) |
| }; |
| } |
| if (node.type === 'tag') { |
| if (node.tag === 'table') { |
| return fromMarkdocNode(node.children[0], componentBlocks); |
| } |
| if (node.tag === 'layout') { |
| return { |
| type: 'layout', |
| layout: node.attributes.layout, |
| children: node.children.flatMap(x => fromMarkdocNode(x, componentBlocks)) |
| }; |
| } |
| if (node.tag === 'layout-area') { |
| return { |
| type: 'layout-area', |
| children: node.children.flatMap(x => fromMarkdocNode(x, componentBlocks)) |
| }; |
| } |
| if (node.tag === 'component-block') { |
| return { |
| type: 'component-block', |
| component: node.attributes.component, |
| props: node.attributes.props, |
| children: node.children.length === 0 ? [{ |
| type: 'component-inline-prop', |
| children: [{ |
| text: '' |
| }] |
| }] : node.children.flatMap(x => fromMarkdocNode(x, componentBlocks)) |
| }; |
| } |
| if (node.tag === 'component-block-prop' && Array.isArray(node.attributes.propPath) && node.attributes.propPath.every(x => typeof x === 'string' || typeof x === 'number')) { |
| return { |
| type: 'component-block-prop', |
| children: node.children.flatMap(x => fromMarkdocNode(x, componentBlocks)), |
| propPath: node.attributes.propPath |
| }; |
| } |
| if (node.tag) { |
| const componentBlock = componentBlocks[node.tag]; |
| if (componentBlock) { |
| const singleChildField = findSingleChildField({ |
| kind: 'object', |
| fields: componentBlock.schema |
| }); |
| if (singleChildField) { |
| const newAttributes = JSON.parse(JSON.stringify(node.attributes)); |
| const children = []; |
| toChildrenAndProps(node.children, children, newAttributes, singleChildField, [], componentBlocks); |
| return { |
| type: 'component-block', |
| component: node.tag, |
| props: newAttributes, |
| children |
| }; |
| } |
| return { |
| type: 'component-block', |
| component: node.tag, |
| props: node.attributes, |
| children: node.children.length === 0 ? [{ |
| type: 'component-inline-prop', |
| children: [{ |
| text: '' |
| }] |
| }] : node.children.flatMap(x => fromMarkdocNode(x, componentBlocks)) |
| }; |
| } |
| } |
| throw new Error(`Unknown tag: ${node.tag}`); |
| } |
| return inlineNodeFromMarkdoc(node); |
| } |
| function toChildrenAndProps(fromMarkdoc, resultingChildren, value, singleChildField, parentPropPath, componentBlocks) { |
| if (singleChildField.kind === 'child') { |
| const children = fromMarkdoc.flatMap(x => fromMarkdocNode(x, componentBlocks)); |
| resultingChildren.push({ |
| type: `component-${singleChildField.options.kind}-prop`, |
| propPath: [...parentPropPath, ...singleChildField.relativePath], |
| children |
| }); |
| } |
| if (singleChildField.kind === 'array') { |
| const arr = []; |
| for (let [idx, child] of fromMarkdoc.entries()) { |
| if (child.type === 'paragraph') { |
| child = child.children[0].children[0]; |
| } |
| if (child.type !== 'tag') { |
| throw new Error(`expected tag ${singleChildField.asChildTag}, found type: ${child.type}`); |
| } |
| if (child.tag !== singleChildField.asChildTag) { |
| throw new Error(`expected tag ${singleChildField.asChildTag}, found tag: ${child.tag}`); |
| } |
| const attributes = JSON.parse(JSON.stringify(child.attributes)); |
| if (singleChildField.child) { |
| toChildrenAndProps(child.children, resultingChildren, attributes, singleChildField.child, [...parentPropPath, ...singleChildField.relativePath, idx], componentBlocks); |
| } |
| arr.push(attributes); |
| } |
| const key = singleChildField.relativePath[singleChildField.relativePath.length - 1]; |
| const parent = getValueAtPropPath(value, singleChildField.relativePath.slice(0, -1)); |
| parent[key] = arr; |
| } |
| } |
|
|
| // these are intentionally more restrictive than the types allowed by strong and weak maps |
|
|
| const emptyCacheNode = Symbol('emptyCacheNode'); |
|
|
| // weak keys should always come before strong keys in the arguments though that cannot be enforced with types |
| function memoize(func) { |
| const cacheNode = { |
| value: emptyCacheNode, |
| strong: undefined, |
| weak: undefined |
| }; |
| return (...args) => { |
| let currentCacheNode = cacheNode; |
| for (const arg of args) { |
| if (typeof arg === 'string' || typeof arg === 'number') { |
| if (currentCacheNode.strong === undefined) { |
| currentCacheNode.strong = new Map(); |
| } |
| if (!currentCacheNode.strong.has(arg)) { |
| currentCacheNode.strong.set(arg, { |
| value: emptyCacheNode, |
| strong: undefined, |
| weak: undefined |
| }); |
| } |
| currentCacheNode = currentCacheNode.strong.get(arg); |
| continue; |
| } |
| if (typeof arg === 'object') { |
| if (currentCacheNode.weak === undefined) { |
| currentCacheNode.weak = new WeakMap(); |
| } |
| if (!currentCacheNode.weak.has(arg)) { |
| currentCacheNode.weak.set(arg, { |
| value: emptyCacheNode, |
| strong: undefined, |
| weak: undefined |
| }); |
| } |
| currentCacheNode = currentCacheNode.weak.get(arg); |
| continue; |
| } |
| } |
| if (currentCacheNode.value !== emptyCacheNode) { |
| return currentCacheNode.value; |
| } |
| const result = func(...args); |
| currentCacheNode.value = result; |
| return result; |
| }; |
| } |
|
|
| function fixPath(path) { |
| return path.replace(/^\.?\/+/, '').replace(/\/*$/, ''); |
| } |
| const collectionPath = /\/\*\*?(?:$|\/)/; |
| function getConfiguredCollectionPath(config, collection) { |
| var _collectionConfig$pat; |
| const collectionConfig = config.collections[collection]; |
| const path = (_collectionConfig$pat = collectionConfig.path) !== null && _collectionConfig$pat !== void 0 ? _collectionConfig$pat : `${collection}/*/`; |
| if (!collectionPath.test(path)) { |
| throw new Error(`Collection path must end with /* or /** or include /*/ or /**/ but ${collection} has ${path}`); |
| } |
| return path; |
| } |
| function getCollectionPath(config, collection) { |
| const configuredPath = getConfiguredCollectionPath(config, collection); |
| const path = fixPath(configuredPath.replace(/\*\*?.*$/, '')); |
| return path; |
| } |
| function getCollectionFormat(config, collection) { |
| return getFormatInfo(config, 'collections', collection); |
| } |
| function getSingletonFormat(config, singleton) { |
| return getFormatInfo(config, 'singletons', singleton); |
| } |
| function getCollectionItemPath(config, collection, slug) { |
| const basePath = getCollectionPath(config, collection); |
| const suffix = getCollectionItemSlugSuffix(config, collection); |
| return `${basePath}/${slug}${suffix}`; |
| } |
| function getEntryDataFilepath(dir, formatInfo) { |
| return `${dir}${formatInfo.dataLocation === 'index' ? '/index' : ''}${getDataFileExtension(formatInfo)}`; |
| } |
| function getSlugGlobForCollection(config, collection) { |
| const collectionPath = getConfiguredCollectionPath(config, collection); |
| return collectionPath.includes('**') ? '**' : '*'; |
| } |
| function getCollectionItemSlugSuffix(config, collection) { |
| const configuredPath = getConfiguredCollectionPath(config, collection); |
| const path = fixPath(configuredPath.replace(/^[^*]+\*\*?/, '')); |
| return path ? `/${path}` : ''; |
| } |
| function getSingletonPath(config, singleton) { |
| var _singleton$path, _singleton$path2; |
| if ((_singleton$path = config.singletons[singleton].path) !== null && _singleton$path !== void 0 && _singleton$path.includes('*')) { |
| throw new Error(`Singleton paths cannot include * but ${singleton} has ${config.singletons[singleton].path}`); |
| } |
| return fixPath((_singleton$path2 = config.singletons[singleton].path) !== null && _singleton$path2 !== void 0 ? _singleton$path2 : singleton); |
| } |
| function getDataFileExtension(formatInfo) { |
| return formatInfo.contentField ? formatInfo.contentField.contentExtension : '.' + formatInfo.data; |
| } |
| const getFormatInfo = memoize(_getFormatInfo); |
| function _getFormatInfo(config, type, key) { |
| var _collectionOrSingleto, _format$data; |
| const collectionOrSingleton = type === 'collections' ? config.collections[key] : config.singletons[key]; |
| const path = type === 'collections' ? getConfiguredCollectionPath(config, key) : (_collectionOrSingleto = collectionOrSingleton.path) !== null && _collectionOrSingleto !== void 0 ? _collectionOrSingleto : `${key}/`; |
| const dataLocation = path.endsWith('/') ? 'index' : 'outer'; |
| const { |
| schema, |
| format = 'yaml' |
| } = collectionOrSingleton; |
| if (typeof format === 'string') { |
| return { |
| dataLocation, |
| contentField: undefined, |
| data: format |
| }; |
| } |
| let contentField; |
| if (format.contentField) { |
| let field = { |
| kind: 'object', |
| fields: schema |
| }; |
| let path = Array.isArray(format.contentField) ? format.contentField : [format.contentField]; |
| let contentExtension; |
| try { |
| contentExtension = getContentExtension(path, field, () => JSON.stringify(format.contentField)); |
| } catch (err) { |
| if (err instanceof ContentFieldLocationError) { |
| throw new Error(`${err.message} (${type}.${key})`); |
| } |
| throw err; |
| } |
| contentField = { |
| path, |
| contentExtension |
| }; |
| } |
| return { |
| data: (_format$data = format.data) !== null && _format$data !== void 0 ? _format$data : 'yaml', |
| contentField, |
| dataLocation |
| }; |
| } |
| class ContentFieldLocationError extends Error { |
| constructor(message) { |
| super(message); |
| } |
| } |
| function getContentExtension(path, schema, debugName) { |
| if (path.length === 0) { |
| if (schema.kind !== 'form' || schema.formKind !== 'content') { |
| throw new ContentFieldLocationError(`Content field for ${debugName()} is not a content field`); |
| } |
| return schema.contentExtension; |
| } |
| if (schema.kind === 'object') { |
| const field = schema.fields[path[0]]; |
| if (!field) { |
| throw new ContentFieldLocationError(`Field ${debugName()} specified in contentField does not exist`); |
| } |
| return getContentExtension(path.slice(1), field, debugName); |
| } |
| if (schema.kind === 'conditional') { |
| if (path[0] !== 'value') { |
| throw new ContentFieldLocationError(`Conditional fields referenced in a contentField path must only reference the value field (${debugName()})`); |
| } |
| let contentExtension; |
| const innerPath = path.slice(1); |
| for (const value of Object.values(schema.values)) { |
| const foundContentExtension = getContentExtension(innerPath, value, debugName); |
| if (!contentExtension) { |
| contentExtension = foundContentExtension; |
| continue; |
| } |
| if (contentExtension !== foundContentExtension) { |
| throw new ContentFieldLocationError(`contentField ${debugName()} has conflicting content extensions`); |
| } |
| } |
| if (!contentExtension) { |
| throw new ContentFieldLocationError(`contentField ${debugName()} does not point to a content field`); |
| } |
| return contentExtension; |
| } |
| throw new ContentFieldLocationError(`Path specified in contentField ${debugName()} does not point to a content field`); |
| } |
|
|
| function getSrcPrefix(publicPath, slug) { |
| return typeof publicPath === 'string' ? `${publicPath.replace(/\/*$/, '')}/${slug === undefined ? '' : slug + '/'}` : ''; |
| } |
|
|
| function deserializeFiles(nodes, componentBlocks, files, otherFiles, mode, documentFeatures, slug) { |
| return nodes.map(node => { |
| if (node.type === 'component-block') { |
| const componentBlock = componentBlocks[node.component]; |
| if (!componentBlock) return node; |
| const schema = object(componentBlock.schema); |
| return { |
| ...node, |
| props: deserializeProps(schema, node.props, files, otherFiles, mode, slug) |
| }; |
| } |
| if (node.type === 'image' && typeof node.src === 'string' && mode === 'edit') { |
| var _ref; |
| const prefix = getSrcPrefixForImageBlock(documentFeatures, slug); |
| const filename = node.src.slice(prefix.length); |
| const content = (_ref = typeof documentFeatures.images === 'object' && typeof documentFeatures.images.directory === 'string' ? otherFiles.get(fixPath(documentFeatures.images.directory)) : files) === null || _ref === void 0 ? void 0 : _ref.get(filename); |
| if (!content) { |
| return { |
| type: 'paragraph', |
| children: [{ |
| text: `Missing image ${filename}` |
| }] |
| }; |
| } |
| return { |
| type: 'image', |
| src: { |
| filename, |
| content |
| }, |
| alt: node.alt, |
| title: node.title, |
| children: [{ |
| text: '' |
| }] |
| }; |
| } |
| if (typeof node.type === 'string') { |
| const children = deserializeFiles(node.children, componentBlocks, files, otherFiles, mode, documentFeatures, slug); |
| return { |
| ...node, |
| children |
| }; |
| } |
| return node; |
| }); |
| } |
| function deserializeProps(schema, value, files, otherFiles, mode, slug) { |
| return transformProps(schema, value, { |
| form: (schema, value) => { |
| if (schema.formKind === 'asset') { |
| var _otherFiles$get; |
| if (mode === 'read') { |
| return schema.reader.parse(value); |
| } |
| const filename = schema.filename(value, { |
| slug, |
| suggestedFilenamePrefix: undefined |
| }); |
| return schema.parse(value, { |
| asset: filename ? schema.directory ? (_otherFiles$get = otherFiles.get(schema.directory)) === null || _otherFiles$get === void 0 ? void 0 : _otherFiles$get.get(filename) : files.get(filename) : undefined, |
| slug |
| }); |
| } |
| if (schema.formKind === 'content' || schema.formKind === 'assets') { |
| throw new Error('Not implemented'); |
| } |
| if (mode === 'read') { |
| return schema.reader.parse(value); |
| } |
| return schema.parse(value, undefined); |
| } |
| }); |
| } |
| function getSrcPrefixForImageBlock(documentFeatures, slug) { |
| return getSrcPrefix(typeof documentFeatures.images === 'object' ? documentFeatures.images.publicPath : undefined, slug); |
| } |
|
|
| async function sha1(content) { |
| return createHash('sha1').update(content).digest('hex'); |
| } |
|
|
| const textEncoder$1 = new TextEncoder(); |
| const blobShaCache = new WeakMap(); |
| async function blobSha(contents) { |
| const cached = blobShaCache.get(contents); |
| if (cached !== undefined) return cached; |
| const blobPrefix = textEncoder$1.encode('blob ' + contents.length + '\0'); |
| const array = new Uint8Array(blobPrefix.byteLength + contents.byteLength); |
| array.set(blobPrefix, 0); |
| array.set(contents, blobPrefix.byteLength); |
| const digestPromise = sha1(array); |
| blobShaCache.set(contents, digestPromise); |
| digestPromise.then(digest => blobShaCache.set(contents, digest)); |
| return digestPromise; |
| } |
| function getTreeNodeAtPath(root, path) { |
| const parts = path.split('/'); |
| let node = root.get(parts[0]); |
| for (const part of parts.slice(1)) { |
| if (!node) return undefined; |
| if (!node.children) return undefined; |
| node = node.children.get(part); |
| } |
| return node; |
| } |
| function getNodeAtPath(tree, path) { |
| if (path === '') return tree; |
| let node = tree; |
| for (const part of path.split('/')) { |
| if (!node.has(part)) { |
| node.set(part, new Map()); |
| } |
| const innerNode = node.get(part); |
| assert(innerNode instanceof Map, 'expected tree'); |
| node = innerNode; |
| } |
| return node; |
| } |
| function getFilename(path) { |
| return path.replace(/.*\//, ''); |
| } |
| function getDirname(path) { |
| if (!path.includes('/')) return ''; |
| return path.replace(/\/[^/]+$/, ''); |
| } |
| function toTreeChanges(changes) { |
| const changesRoot = new Map(); |
| for (const deletion of changes.deletions) { |
| const parentTree = getNodeAtPath(changesRoot, getDirname(deletion)); |
| parentTree.set(getFilename(deletion), 'delete'); |
| } |
| for (const addition of changes.additions) { |
| const parentTree = getNodeAtPath(changesRoot, getDirname(addition.path)); |
| parentTree.set(getFilename(addition.path), addition.contents); |
| } |
| return changesRoot; |
| } |
| const SPACE_CHAR_CODE = 32; |
| const space = new Uint8Array([SPACE_CHAR_CODE]); |
| const nullchar = new Uint8Array([0]); |
| const tree = textEncoder$1.encode('tree '); |
|
|
| // based on https://github.com/isomorphic-git/isomorphic-git/blob/c09dfa20ffe0ab9e6602e0fa172d72ba8994e443/src/models/GitTree.js#L108-L122 |
| function treeSha(children) { |
| const entries = [...children].map(([name, node]) => ({ |
| name, |
| sha: node.entry.sha, |
| mode: node.entry.mode |
| })); |
| entries.sort((a, b) => { |
| const aName = a.mode === '040000' ? a.name + '/' : a.name; |
| const bName = b.mode === '040000' ? b.name + '/' : b.name; |
| return aName === bName ? 0 : aName < bName ? -1 : 1; |
| }); |
| const treeObject = entries.flatMap(entry => { |
| const mode = textEncoder$1.encode(entry.mode.replace(/^0/, '')); |
| const name = textEncoder$1.encode(entry.name); |
| const sha = hexToBytes(entry.sha); |
| return [mode, space, name, nullchar, sha]; |
| }); |
| return sha1(concatBytes([tree, textEncoder$1.encode(treeObject.reduce((sum, val) => sum + val.byteLength, 0).toString()), nullchar, ...treeObject])); |
| } |
| function concatBytes(byteArrays) { |
| const totalLength = byteArrays.reduce((sum, arr) => sum + arr.byteLength, 0); |
| const result = new Uint8Array(totalLength); |
| let offset = 0; |
| for (const arr of byteArrays) { |
| result.set(arr, offset); |
| offset += arr.byteLength; |
| } |
| return result; |
| } |
| function hexToBytes(str) { |
| const bytes = new Uint8Array(str.length / 2); |
| for (var i = 0; i < bytes.byteLength; i += 1) { |
| const start = i * 2; |
| bytes[i] = parseInt(str.slice(start, start + 2), 16); |
| } |
| return bytes; |
| } |
| async function createTreeNodeEntry(path, children) { |
| const sha = await treeSha(children); |
| return { |
| path, |
| mode: '040000', |
| type: 'tree', |
| sha |
| }; |
| } |
| async function createBlobNodeEntry(path, contents) { |
| const sha = 'sha' in contents ? contents.sha : await blobSha(contents); |
| return { |
| path, |
| mode: '100644', |
| type: 'blob', |
| sha |
| }; |
| } |
| async function updateTreeWithChanges(tree, changes) { |
| var _await$updateTree; |
| const newTree = (_await$updateTree = await updateTree(tree, toTreeChanges(changes), [])) !== null && _await$updateTree !== void 0 ? _await$updateTree : new Map(); |
| return { |
| entries: treeToEntries(newTree), |
| sha: await treeSha(newTree !== null && newTree !== void 0 ? newTree : new Map()) |
| }; |
| } |
| function treeToEntries(tree) { |
| return [...tree.values()].flatMap(x => x.children ? [x.entry, ...treeToEntries(x.children)] : [x.entry]); |
| } |
| async function updateTree(tree, changedTree, path) { |
| const newTree = new Map(tree); |
| for (const [key, value] of changedTree) { |
| if (value === 'delete') { |
| newTree.delete(key); |
| } |
| if (value instanceof Map) { |
| var _newTree$get$children, _newTree$get; |
| const existingChildren = (_newTree$get$children = (_newTree$get = newTree.get(key)) === null || _newTree$get === void 0 ? void 0 : _newTree$get.children) !== null && _newTree$get$children !== void 0 ? _newTree$get$children : new Map(); |
| const children = await updateTree(existingChildren, value, path.concat(key)); |
| if (children === undefined) { |
| newTree.delete(key); |
| continue; |
| } |
| const entry = await createTreeNodeEntry(path.concat(key).join('/'), children); |
| newTree.set(key, { |
| entry, |
| children |
| }); |
| } |
| if (value instanceof Uint8Array || typeof value === 'object' && 'sha' in value) { |
| const entry = await createBlobNodeEntry(path.concat(key).join('/'), value); |
| newTree.set(key, { |
| entry |
| }); |
| } |
| } |
| if (newTree.size === 0) { |
| return undefined; |
| } |
| return newTree; |
| } |
| function treeEntriesToTreeNodes(entries) { |
| const root = new Map(); |
| const getChildrenAtPath = parts => { |
| var _node; |
| if (parts.length === 0) { |
| return root; |
| } |
| let node = root.get(parts[0]); |
| for (const part of parts.slice(1)) { |
| if (!node) return undefined; |
| if (!node.children) return undefined; |
| node = node.children.get(part); |
| } |
| return (_node = node) === null || _node === void 0 ? void 0 : _node.children; |
| }; |
| for (const entry of entries) { |
| const split = entry.path.split('/'); |
| const children = getChildrenAtPath(split.slice(0, -1)); |
| if (children) { |
| children.set(split[split.length - 1], { |
| entry, |
| children: entry.type === 'tree' ? new Map() : undefined |
| }); |
| } |
| } |
| return root; |
| } |
|
|
| function collectDirectoriesUsedInSchemaInner(schema, directories, seenSchemas) { |
| if (seenSchemas.has(schema)) { |
| return; |
| } |
| seenSchemas.add(schema); |
| if (schema.kind === 'array') { |
| return collectDirectoriesUsedInSchemaInner(schema.element, directories, seenSchemas); |
| } |
| if (schema.kind === 'child') { |
| return; |
| } |
| if (schema.kind === 'form') { |
| if (schema.formKind === 'asset' && schema.directory !== undefined) { |
| directories.add(fixPath(schema.directory)); |
| } |
| if ((schema.formKind === 'content' || schema.formKind === 'assets') && schema.directories !== undefined) { |
| for (const directory of schema.directories) { |
| directories.add(fixPath(directory)); |
| } |
| } |
| return; |
| } |
| if (schema.kind === 'object') { |
| for (const field of Object.values(schema.fields)) { |
| collectDirectoriesUsedInSchemaInner(field, directories, seenSchemas); |
| } |
| return; |
| } |
| if (schema.kind === 'conditional') { |
| for (const innerSchema of Object.values(schema.values)) { |
| collectDirectoriesUsedInSchemaInner(innerSchema, directories, seenSchemas); |
| } |
| return; |
| } |
| assertNever$1(schema); |
| } |
| function collectDirectoriesUsedInSchema(schema) { |
| const directories = new Set(); |
| collectDirectoriesUsedInSchemaInner(schema, directories, new Set()); |
| return directories; |
| } |
| function getDirectoriesForTreeKey(schema, directory, slug, format) { |
| const directories = [fixPath(directory)]; |
| if (format.dataLocation === 'outer') { |
| directories.push(fixPath(directory) + getDataFileExtension(format)); |
| } |
| const toAdd = slug === undefined ? '' : `/${slug}`; |
| for (const directory of collectDirectoriesUsedInSchema(schema)) { |
| directories.push(directory + toAdd); |
| } |
| return directories; |
| } |
|
|
| const textDecoder$1 = new TextDecoder(); |
| const defaultAltField$1 = text({ |
| label: 'Alt text', |
| description: 'This text will be used by screen readers and search engines.' |
| }); |
| const emptyTitleField$1 = basicFormFieldWithSimpleReaderParse({ |
| Input() { |
| return null; |
| }, |
| defaultValue() { |
| return ''; |
| }, |
| parse(value) { |
| if (value === undefined) return ''; |
| if (typeof value !== 'string') { |
| throw new FieldDataError('Must be string'); |
| } |
| return value; |
| }, |
| validate(value) { |
| return value; |
| }, |
| serialize(value) { |
| return { |
| value |
| }; |
| }, |
| label: 'Title' |
| }); |
| function normaliseDocumentFeatures(config) { |
| var _config$formatting, _formatting$alignment, _formatting$alignment2, _formatting$blockType, _formatting$inlineMar, _formatting$inlineMar2, _formatting$inlineMar3, _formatting$inlineMar4, _formatting$inlineMar5, _formatting$inlineMar6, _formatting$inlineMar7, _formatting$inlineMar8, _formatting$listTypes, _formatting$listTypes2, _imagesConfig$schema$, _imagesConfig$schema, _imagesConfig$schema$2, _imagesConfig$schema2; |
| const formatting = config.formatting === true ? { |
| // alignment: true, // not supported natively in markdown |
| blockTypes: true, |
| headingLevels: true, |
| inlineMarks: true, |
| listTypes: true, |
| softBreaks: true |
| } : (_config$formatting = config.formatting) !== null && _config$formatting !== void 0 ? _config$formatting : {}; |
| const imagesConfig = config.images === true ? {} : config.images; |
| return { |
| formatting: { |
| alignment: formatting.alignment === true ? { |
| center: true, |
| end: true |
| } : { |
| center: !!((_formatting$alignment = formatting.alignment) !== null && _formatting$alignment !== void 0 && _formatting$alignment.center), |
| end: !!((_formatting$alignment2 = formatting.alignment) !== null && _formatting$alignment2 !== void 0 && _formatting$alignment2.end) |
| }, |
| blockTypes: (formatting === null || formatting === void 0 ? void 0 : formatting.blockTypes) === true ? { |
| blockquote: true, |
| code: { |
| schema: object({}) |
| } |
| } : { |
| blockquote: !!((_formatting$blockType = formatting.blockTypes) !== null && _formatting$blockType !== void 0 && _formatting$blockType.blockquote), |
| code: (_formatting$blockType2 => { |
| if (((_formatting$blockType2 = formatting.blockTypes) === null || _formatting$blockType2 === void 0 ? void 0 : _formatting$blockType2.code) === undefined) { |
| return false; |
| } |
| if (formatting.blockTypes.code === true || !formatting.blockTypes.code.schema) { |
| return { |
| schema: object({}) |
| }; |
| } |
| for (const key of ['type', 'children', 'language']) { |
| if (key in formatting.blockTypes.code.schema) { |
| throw new Error(`"${key}" cannot be a key in the schema for code blocks`); |
| } |
| } |
| return { |
| schema: object(formatting.blockTypes.code.schema) |
| }; |
| })() |
| }, |
| headings: (_obj$schema => { |
| const opt = formatting === null || formatting === void 0 ? void 0 : formatting.headingLevels; |
| const obj = typeof opt === 'object' && 'levels' in opt ? opt : { |
| levels: opt, |
| schema: undefined |
| }; |
| if (obj.schema) { |
| for (const key of ['type', 'children', 'level', 'textAlign']) { |
| if (key in obj.schema) { |
| throw new Error(`"${key}" cannot be a key in the schema for headings`); |
| } |
| } |
| } |
| return { |
| levels: [...new Set(obj.levels === true ? [1, 2, 3, 4, 5, 6] : obj.levels)], |
| schema: object((_obj$schema = obj.schema) !== null && _obj$schema !== void 0 ? _obj$schema : {}) |
| }; |
| })(), |
| inlineMarks: formatting.inlineMarks === true ? { |
| bold: true, |
| code: true, |
| italic: true, |
| keyboard: false, |
| // not supported natively in markdown |
| strikethrough: true, |
| subscript: false, |
| // not supported natively in markdown |
| superscript: false, |
| // not supported natively in markdown |
| underline: false // not supported natively in markdown |
| } : { |
| bold: !!((_formatting$inlineMar = formatting.inlineMarks) !== null && _formatting$inlineMar !== void 0 && _formatting$inlineMar.bold), |
| code: !!((_formatting$inlineMar2 = formatting.inlineMarks) !== null && _formatting$inlineMar2 !== void 0 && _formatting$inlineMar2.code), |
| italic: !!((_formatting$inlineMar3 = formatting.inlineMarks) !== null && _formatting$inlineMar3 !== void 0 && _formatting$inlineMar3.italic), |
| strikethrough: !!((_formatting$inlineMar4 = formatting.inlineMarks) !== null && _formatting$inlineMar4 !== void 0 && _formatting$inlineMar4.strikethrough), |
| underline: !!((_formatting$inlineMar5 = formatting.inlineMarks) !== null && _formatting$inlineMar5 !== void 0 && _formatting$inlineMar5.underline), |
| keyboard: !!((_formatting$inlineMar6 = formatting.inlineMarks) !== null && _formatting$inlineMar6 !== void 0 && _formatting$inlineMar6.keyboard), |
| subscript: !!((_formatting$inlineMar7 = formatting.inlineMarks) !== null && _formatting$inlineMar7 !== void 0 && _formatting$inlineMar7.subscript), |
| superscript: !!((_formatting$inlineMar8 = formatting.inlineMarks) !== null && _formatting$inlineMar8 !== void 0 && _formatting$inlineMar8.superscript) |
| }, |
| listTypes: formatting.listTypes === true ? { |
| ordered: true, |
| unordered: true |
| } : { |
| ordered: !!((_formatting$listTypes = formatting.listTypes) !== null && _formatting$listTypes !== void 0 && _formatting$listTypes.ordered), |
| unordered: !!((_formatting$listTypes2 = formatting.listTypes) !== null && _formatting$listTypes2 !== void 0 && _formatting$listTypes2.unordered) |
| }, |
| softBreaks: !!formatting.softBreaks |
| }, |
| links: !!config.links, |
| layouts: [...new Set((config.layouts || []).map(x => JSON.stringify(x)))].map(x => JSON.parse(x)), |
| dividers: !!config.dividers, |
| images: imagesConfig === undefined ? false : { |
| ...imagesConfig, |
| schema: { |
| alt: (_imagesConfig$schema$ = (_imagesConfig$schema = imagesConfig.schema) === null || _imagesConfig$schema === void 0 ? void 0 : _imagesConfig$schema.alt) !== null && _imagesConfig$schema$ !== void 0 ? _imagesConfig$schema$ : defaultAltField$1, |
| title: (_imagesConfig$schema$2 = (_imagesConfig$schema2 = imagesConfig.schema) === null || _imagesConfig$schema2 === void 0 ? void 0 : _imagesConfig$schema2.title) !== null && _imagesConfig$schema$2 !== void 0 ? _imagesConfig$schema$2 : emptyTitleField$1 |
| } |
| }, |
| tables: !!config.tables |
| }; |
| } |
|
|
| /** |
| * @deprecated `fields.markdoc` has superseded this field. `fields.mdx` is also available if you prefer MDX. |
| */ |
| function document({ |
| label, |
| componentBlocks = {}, |
| description, |
| ...documentFeaturesConfig |
| }) { |
| const documentFeatures = normaliseDocumentFeatures(documentFeaturesConfig); |
| return { |
| kind: 'form', |
| formKind: 'content', |
| defaultValue() { |
| return [{ |
| type: 'paragraph', |
| children: [{ |
| text: '' |
| }] |
| }]; |
| }, |
| Input(props) { |
| return /*#__PURE__*/jsx(DocumentFieldInput, { |
| componentBlocks: componentBlocks, |
| description: description, |
| label: label, |
| documentFeatures: documentFeatures, |
| ...props |
| }); |
| }, |
| parse(_, data) { |
| const markdoc = textDecoder$1.decode(data.content); |
| fromMarkdoc(parse(markdoc), componentBlocks); |
| return deserializeFiles(normalizeDocumentFieldChildren(), componentBlocks, data.other, data.external, 'edit', documentFeatures, data.slug); |
| }, |
| contentExtension: '.mdoc', |
| validate(value) { |
| return value; |
| }, |
| directories: [...collectDirectoriesUsedInSchema(object(Object.fromEntries(Object.entries(componentBlocks).map(([name, block]) => [name, object(block.schema)])))), ...(typeof documentFeatures.images === 'object' && typeof documentFeatures.images.directory === 'string' ? [fixPath(documentFeatures.images.directory)] : [])], |
| serialize(value, opts) { |
| return serializeMarkdoc(); |
| }, |
| reader: { |
| parse(value, data) { |
| const markdoc = textDecoder$1.decode(data.content); |
| const document = fromMarkdoc(parse(markdoc), componentBlocks); |
| return deserializeFiles(document, componentBlocks, new Map(), new Map(), 'read', documentFeatures, undefined); |
| } |
| } |
| }; |
| } |
|
|
| const defaultAltField = text({ |
| label: 'Alt text', |
| description: 'This text will be used by screen readers and search engines.' |
| }); |
| const emptyTitleField = basicFormFieldWithSimpleReaderParse({ |
| Input() { |
| return null; |
| }, |
| defaultValue() { |
| return ''; |
| }, |
| parse(value) { |
| if (value === undefined) return ''; |
| if (typeof value !== 'string') { |
| throw new FieldDataError('Must be string'); |
| } |
| return value; |
| }, |
| validate(value) { |
| return value; |
| }, |
| serialize(value) { |
| return { |
| value |
| }; |
| }, |
| label: 'Title' |
| }); |
| function editorOptionsToConfig(options) { |
| var _options$bold, _options$italic, _options$strikethroug, _options$code, _options$blockquote, _options$orderedList, _options$unorderedLis, _options$table, _options$link, _options$divider; |
| return { |
| bold: (_options$bold = options.bold) !== null && _options$bold !== void 0 ? _options$bold : true, |
| italic: (_options$italic = options.italic) !== null && _options$italic !== void 0 ? _options$italic : true, |
| strikethrough: (_options$strikethroug = options.strikethrough) !== null && _options$strikethroug !== void 0 ? _options$strikethroug : true, |
| code: (_options$code = options.code) !== null && _options$code !== void 0 ? _options$code : true, |
| heading: (() => { |
| let levels = []; |
| let levelsOpt = typeof options.heading === 'object' && !Array.isArray(options.heading) ? options.heading.levels : options.heading; |
| if (levelsOpt === true || levelsOpt === undefined) { |
| levels = [1, 2, 3, 4, 5, 6]; |
| } |
| if (Array.isArray(levelsOpt)) { |
| levels = levelsOpt; |
| } |
| return { |
| levels, |
| schema: options.heading && typeof options.heading === 'object' && 'schema' in options.heading ? options.heading.schema : {} |
| }; |
| })(), |
| blockquote: (_options$blockquote = options.blockquote) !== null && _options$blockquote !== void 0 ? _options$blockquote : true, |
| orderedList: (_options$orderedList = options.orderedList) !== null && _options$orderedList !== void 0 ? _options$orderedList : true, |
| unorderedList: (_options$unorderedLis = options.unorderedList) !== null && _options$unorderedLis !== void 0 ? _options$unorderedLis : true, |
| table: (_options$table = options.table) !== null && _options$table !== void 0 ? _options$table : true, |
| link: (_options$link = options.link) !== null && _options$link !== void 0 ? _options$link : true, |
| image: options.image !== false ? ((_opts$transformFilena, _opts$schema$alt, _opts$schema, _opts$schema$title, _opts$schema2) => { |
| const opts = options.image === true ? undefined : options.image; |
| return { |
| directory: opts === null || opts === void 0 ? void 0 : opts.directory, |
| publicPath: opts === null || opts === void 0 ? void 0 : opts.publicPath, |
| transformFilename: (_opts$transformFilena = opts === null || opts === void 0 ? void 0 : opts.transformFilename) !== null && _opts$transformFilena !== void 0 ? _opts$transformFilena : x => x, |
| schema: { |
| alt: (_opts$schema$alt = opts === null || opts === void 0 || (_opts$schema = opts.schema) === null || _opts$schema === void 0 ? void 0 : _opts$schema.alt) !== null && _opts$schema$alt !== void 0 ? _opts$schema$alt : defaultAltField, |
| title: (_opts$schema$title = opts === null || opts === void 0 || (_opts$schema2 = opts.schema) === null || _opts$schema2 === void 0 ? void 0 : _opts$schema2.title) !== null && _opts$schema$title !== void 0 ? _opts$schema$title : emptyTitleField |
| } |
| }; |
| })() : undefined, |
| divider: (_options$divider = options.divider) !== null && _options$divider !== void 0 ? _options$divider : true, |
| codeBlock: options.codeBlock === false ? undefined : { |
| schema: typeof options.codeBlock === 'object' ? options.codeBlock.schema : {} |
| } |
| }; |
| } |
|
|
| function getTypeForField(field) { |
| if (field.kind === 'object' || field.kind === 'conditional') { |
| return { |
| type: Object, |
| required: true |
| }; |
| } |
| if (field.kind === 'array') { |
| return { |
| type: Array, |
| required: true |
| }; |
| } |
| if (field.kind === 'child') { |
| return {}; |
| } |
| if (field.formKind === undefined) { |
| if (typeof field.defaultValue === 'string' && 'options' in field && Array.isArray(field.options) && field.options.every(val => typeof val === 'object' && val !== null && 'value' in val && typeof val.value === 'string')) { |
| return { |
| type: String, |
| matches: field.options.map(x => x.value), |
| required: true |
| }; |
| } |
| if (typeof field.defaultValue === 'string') { |
| let required = false; |
| try { |
| field.parse(''); |
| } catch { |
| required = true; |
| } |
| return { |
| type: String, |
| required |
| }; |
| } |
| try { |
| field.parse(1); |
| return { |
| type: Number |
| }; |
| } catch {} |
| if (typeof field.defaultValue === 'boolean') { |
| return { |
| type: Boolean, |
| required: true |
| }; |
| } |
| return {}; |
| } |
| if (field.formKind === 'slug') { |
| let required = false; |
| try { |
| field.parse('', undefined); |
| } catch { |
| required = true; |
| } |
| return { |
| type: String, |
| required |
| }; |
| } |
| if (field.formKind === 'asset') { |
| let required = false; |
| try { |
| field.validate(null); |
| } catch { |
| required = true; |
| } |
| return { |
| type: String, |
| required |
| }; |
| } |
| return {}; |
| } |
| function fieldsToMarkdocAttributes(fields) { |
| return Object.fromEntries(Object.entries(fields).map(([name, field]) => { |
| const schema = getTypeForField(field); |
| return [name, schema]; |
| })); |
| } |
| function createMarkdocConfig(opts) { |
| const editorConfig = editorOptionsToConfig(opts.options || {}); |
| const config = { |
| nodes: { |
| ...nodes |
| }, |
| tags: {} |
| }; |
| if (editorConfig.heading.levels.length) { |
| config.nodes.heading = { |
| ...nodes.heading, |
| attributes: { |
| ...nodes.heading.attributes, |
| ...fieldsToMarkdocAttributes(editorConfig.heading.schema) |
| } |
| }; |
| } else { |
| config.nodes.heading = undefined; |
| } |
| if (!editorConfig.blockquote) { |
| config.nodes.blockquote = undefined; |
| } |
| if (editorConfig.codeBlock) { |
| config.nodes.fence = { |
| ...nodes.fence, |
| attributes: { |
| ...nodes.fence.attributes, |
| ...fieldsToMarkdocAttributes(editorConfig.codeBlock.schema) |
| } |
| }; |
| } else { |
| config.nodes.fence = undefined; |
| } |
| if (!editorConfig.orderedList && !editorConfig.unorderedList) { |
| config.nodes.list = undefined; |
| } |
| if (!editorConfig.bold) { |
| config.nodes.strong = undefined; |
| } |
| if (!editorConfig.italic) { |
| config.nodes.em = undefined; |
| } |
| if (!editorConfig.strikethrough) { |
| config.nodes.s = undefined; |
| } |
| if (!editorConfig.link) { |
| config.nodes.link = undefined; |
| } |
| if (!editorConfig.image) { |
| config.nodes.image = undefined; |
| } |
| if (!editorConfig.divider) { |
| config.nodes.hr = undefined; |
| } |
| if (!editorConfig.table) { |
| config.nodes.table = undefined; |
| } |
| for (const [name, component] of Object.entries(opts.components || {})) { |
| var _opts$render; |
| const isEmpty = component.kind === 'block' || component.kind === 'inline'; |
| config.tags[name] = { |
| render: (_opts$render = opts.render) === null || _opts$render === void 0 || (_opts$render = _opts$render.tags) === null || _opts$render === void 0 ? void 0 : _opts$render[name], |
| children: isEmpty ? [] : undefined, |
| selfClosing: isEmpty, |
| attributes: fieldsToMarkdocAttributes(component.schema), |
| description: 'description' in component ? component.description : undefined, |
| inline: component.kind === 'inline' || component.kind === 'mark' |
| }; |
| } |
| for (const [name, render] of Object.entries(((_opts$render2 = opts.render) === null || _opts$render2 === void 0 ? void 0 : _opts$render2.nodes) || {})) { |
| var _opts$render2; |
| const nodeSchema = config.nodes[name]; |
| if (nodeSchema) { |
| nodeSchema.render = render; |
| } |
| } |
| return config; |
| } |
|
|
| const textDecoder = new TextDecoder(); |
| const textEncoder = new TextEncoder(); |
| function getDirectoriesForEditorField(components, config) { |
| return [...collectDirectoriesUsedInSchema(object(Object.fromEntries(Object.entries(components).map(([name, component]) => [name, object(component.schema)])))), ...(typeof config.image === 'object' && typeof config.image.directory === 'string' ? [fixPath(config.image.directory)] : [])]; |
| } |
| function markdoc({ |
| label, |
| description, |
| options = {}, |
| components = {}, |
| extension = 'mdoc' |
| }) { |
| let schema; |
| const config = editorOptionsToConfig(options); |
| let getSchema = () => { |
| if (!schema) { |
| schema = createEditorSchema(); |
| } |
| return schema; |
| }; |
| return { |
| kind: 'form', |
| formKind: 'content', |
| defaultValue() { |
| return getDefaultValue(getSchema()); |
| }, |
| Input(props) { |
| return /*#__PURE__*/jsx(DocumentFieldInput, { |
| description: description, |
| label: label, |
| ...props |
| }); |
| }, |
| parse: (_, { |
| content, |
| other, |
| external, |
| slug |
| }) => { |
| const text = textDecoder.decode(content); |
| return parseToEditorState(text, getSchema()); |
| }, |
| contentExtension: `.${extension}`, |
| validate(value) { |
| return value; |
| }, |
| directories: getDirectoriesForEditorField(components, config), |
| serialize(value, { |
| slug |
| }) { |
| const out = serializeFromEditorState(); |
| return { |
| content: textEncoder.encode(out.content), |
| external: out.external, |
| other: out.other, |
| value: undefined |
| }; |
| }, |
| reader: { |
| parse: (_, { |
| content |
| }) => { |
| const text = textDecoder.decode(content); |
| return { |
| node: parse(text) |
| }; |
| } |
| }, |
| collaboration: { |
| toYjs(value) { |
| return prosemirrorToYXmlFragment(value.doc); |
| }, |
| fromYjs(yjsValue, awareness) { |
| return createEditorStateFromYJS(getSchema()); |
| } |
| } |
| }; |
| } |
| markdoc.createMarkdocConfig = createMarkdocConfig; |
| markdoc.inline = function inlineMarkdoc({ |
| label, |
| description, |
| options = {}, |
| components = {} |
| }) { |
| let schema; |
| const config = editorOptionsToConfig(options); |
| let getSchema = () => { |
| if (!schema) { |
| schema = createEditorSchema(); |
| } |
| return schema; |
| }; |
| return { |
| kind: 'form', |
| formKind: 'assets', |
| defaultValue() { |
| return getDefaultValue(getSchema()); |
| }, |
| Input(props) { |
| return /*#__PURE__*/jsx(DocumentFieldInput, { |
| description: description, |
| label: label, |
| ...props |
| }); |
| }, |
| parse: (value, { |
| other, |
| external, |
| slug |
| }) => { |
| if (value === undefined) { |
| value = ''; |
| } |
| if (typeof value !== 'string') { |
| throw new FieldDataError('Must be a string'); |
| } |
| return parseToEditorState(value, getSchema()); |
| }, |
| validate(value) { |
| return value; |
| }, |
| directories: getDirectoriesForEditorField(components, config), |
| serialize(value, { |
| slug |
| }) { |
| const out = serializeFromEditorState(); |
| return { |
| external: out.external, |
| other: out.other, |
| value: out.content |
| }; |
| }, |
| reader: { |
| parse: value => { |
| if (value === undefined) { |
| value = ''; |
| } |
| if (typeof value !== 'string') { |
| throw new FieldDataError('Must be a string'); |
| } |
| return { |
| node: parse(value) |
| }; |
| } |
| }, |
| collaboration: { |
| toYjs(value) { |
| return prosemirrorToYXmlFragment(value.doc); |
| }, |
| fromYjs(yjsValue, awareness) { |
| return createEditorStateFromYJS(getSchema()); |
| } |
| } |
| }; |
| }; |
| function mdx({ |
| label, |
| description, |
| options = {}, |
| components = {}, |
| extension = 'mdx' |
| }) { |
| let schema; |
| const config = editorOptionsToConfig(options); |
| let getSchema = () => { |
| if (!schema) { |
| schema = createEditorSchema(); |
| } |
| return schema; |
| }; |
| return { |
| kind: 'form', |
| formKind: 'content', |
| defaultValue() { |
| return getDefaultValue(getSchema()); |
| }, |
| Input(props) { |
| return /*#__PURE__*/jsx(DocumentFieldInput, { |
| description: description, |
| label: label, |
| ...props |
| }); |
| }, |
| parse: (_, { |
| content, |
| other, |
| external, |
| slug |
| }) => { |
| const text = textDecoder.decode(content); |
| return parseToEditorStateMDX(text, getSchema()); |
| }, |
| contentExtension: `.${extension}`, |
| validate(value) { |
| return value; |
| }, |
| directories: getDirectoriesForEditorField(components, config), |
| serialize(value, { |
| slug |
| }) { |
| const out = serializeFromEditorStateMDX(); |
| return { |
| content: textEncoder.encode(out.content), |
| external: out.external, |
| other: out.other, |
| value: undefined |
| }; |
| }, |
| reader: { |
| parse: (_, { |
| content |
| }) => { |
| const text = textDecoder.decode(content); |
| return text; |
| } |
| }, |
| collaboration: { |
| toYjs(value) { |
| return prosemirrorToYXmlFragment(value.doc); |
| }, |
| fromYjs(yjsValue, awareness) { |
| return createEditorStateFromYJS(getSchema()); |
| } |
| } |
| }; |
| } |
| mdx.inline = function mdx({ |
| label, |
| description, |
| options = {}, |
| components = {} |
| }) { |
| let schema; |
| const config = editorOptionsToConfig(options); |
| let getSchema = () => { |
| if (!schema) { |
| schema = createEditorSchema(); |
| } |
| return schema; |
| }; |
| return { |
| kind: 'form', |
| formKind: 'assets', |
| defaultValue() { |
| return getDefaultValue(getSchema()); |
| }, |
| Input(props) { |
| return /*#__PURE__*/jsx(DocumentFieldInput, { |
| description: description, |
| label: label, |
| ...props |
| }); |
| }, |
| parse: (value, { |
| other, |
| external, |
| slug |
| }) => { |
| if (value === undefined) { |
| value = ''; |
| } |
| if (typeof value !== 'string') { |
| throw new FieldDataError('Must be a string'); |
| } |
| return parseToEditorStateMDX(value, getSchema()); |
| }, |
| validate(value) { |
| return value; |
| }, |
| directories: getDirectoriesForEditorField(components, config), |
| serialize(value, { |
| slug |
| }) { |
| const out = serializeFromEditorStateMDX(); |
| return { |
| external: out.external, |
| other: out.other, |
| value: out.content |
| }; |
| }, |
| reader: { |
| parse: value => { |
| if (value === undefined) { |
| value = ''; |
| } |
| if (typeof value !== 'string') { |
| throw new FieldDataError('Must be a string'); |
| } |
| return value; |
| } |
| }, |
| collaboration: { |
| toYjs(value) { |
| return prosemirrorToYXmlFragment(value.doc); |
| }, |
| fromYjs(yjsValue, awareness) { |
| return createEditorStateFromYJS(getSchema()); |
| } |
| } |
| }; |
| }; |
|
|
| export { markdoc as a, getDirectoriesForTreeKey as b, getCollectionPath as c, document as d, getSingletonFormat as e, fixPath as f, getSrcPrefix as g, getSingletonPath as h, blobSha as i, getCollectionFormat as j, getSlugGlobForCollection as k, getDataFileExtension as l, mdx as m, getCollectionItemPath as n, object as o, getEntryDataFilepath as p, getValueAtPropPath as q, getTreeNodeAtPath as r, treeEntriesToTreeNodes as t, updateTreeWithChanges as u }; |