@temelj/mdx 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/compiler.mjs +2 -22
- package/dist/compiler.mjs.map +1 -1
- package/dist/frontmatter-decode.d.mts +15 -0
- package/dist/frontmatter-decode.d.mts.map +1 -0
- package/dist/frontmatter-decode.mjs +187 -0
- package/dist/frontmatter-decode.mjs.map +1 -0
- package/dist/frontmatter-schema.d.mts +8 -0
- package/dist/frontmatter-schema.d.mts.map +1 -0
- package/dist/frontmatter-schema.mjs +28 -0
- package/dist/frontmatter-schema.mjs.map +1 -0
- package/dist/frontmatter.d.mts +35 -10
- package/dist/frontmatter.d.mts.map +1 -1
- package/dist/frontmatter.mjs +97 -175
- package/dist/frontmatter.mjs.map +1 -1
- package/dist/mod.d.mts +2 -1
- package/dist/mod.mjs +3 -2
- package/dist/parser/materialize.mjs +1 -1
- package/dist/parser/materialize.mjs.map +1 -1
- package/dist/source-text.d.mts +2 -2
- package/dist/source-text.d.mts.map +1 -1
- package/dist/source-text.mjs +9 -5
- package/dist/source-text.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -105,6 +105,8 @@ console.log(result.diagnostics); // Warnings; syntax errors throw ParseError.
|
|
|
105
105
|
console.log(result.file.location(2)); // { offset: 2, line: 1, column: 3 }
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
+
You can choose to parse only the frontmatter with `parseFrontmatter`.
|
|
109
|
+
|
|
108
110
|
## Parse into AST
|
|
109
111
|
|
|
110
112
|
```ts
|
package/dist/compiler.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { createDiagnostic } from "./diagnostics.mjs";
|
|
2
1
|
import { CompileError, ConfigurationError, FrontmatterError, LimitError, MdxError } from "./errors.mjs";
|
|
3
2
|
import { javascriptPropertyName } from "./javascript-ast.mjs";
|
|
4
3
|
import { parseJavaScriptProgram } from "./javascript.mjs";
|
|
5
4
|
import { analyzeDocument } from "./compile-analysis.mjs";
|
|
6
5
|
import { contentUsesAwait, emitContent } from "./compile-emit.mjs";
|
|
6
|
+
import { frontmatterSchemaValue } from "./frontmatter-schema.mjs";
|
|
7
7
|
import { documentFrontmatter } from "./model.mjs";
|
|
8
8
|
import { lowerHtml } from "./html-lower.mjs";
|
|
9
9
|
import { CodeWriter } from "./source-map.mjs";
|
|
@@ -57,16 +57,7 @@ async function compile(input, options = {}) {
|
|
|
57
57
|
let frontmatter = frontmatterNode?.data ?? Object.freeze({});
|
|
58
58
|
if (options.frontmatterSchema !== void 0) {
|
|
59
59
|
const validated = await options.frontmatterSchema["~standard"].validate(frontmatter);
|
|
60
|
-
|
|
61
|
-
const diagnostics = validated.issues.map((issue) => createDiagnostic({
|
|
62
|
-
severity: "error",
|
|
63
|
-
code: "mdx.frontmatter.schema",
|
|
64
|
-
message: formatSchemaIssue(issue),
|
|
65
|
-
span: fileSpan(input.file, frontmatterNode?.origin)
|
|
66
|
-
}));
|
|
67
|
-
throw FrontmatterError.schemaValidationFailed(input.file, diagnostics, validated.issues);
|
|
68
|
-
}
|
|
69
|
-
frontmatter = validated.value;
|
|
60
|
+
frontmatter = frontmatterSchemaValue(validated, input.file, frontmatterNode?.origin);
|
|
70
61
|
}
|
|
71
62
|
const transported = copyTransportValue(frontmatter, "frontmatter", {
|
|
72
63
|
file: input.file,
|
|
@@ -85,10 +76,6 @@ async function compile(input, options = {}) {
|
|
|
85
76
|
frontmatter
|
|
86
77
|
});
|
|
87
78
|
}
|
|
88
|
-
function formatSchemaIssue(issue) {
|
|
89
|
-
const path = issue.path?.map((part) => String(isObject(part) ? part.key : part)).join(".");
|
|
90
|
-
return path === void 0 || path.length === 0 ? issue.message : `${path}: ${issue.message}`;
|
|
91
|
-
}
|
|
92
79
|
function copyTransportValue(value, path, context) {
|
|
93
80
|
const { ancestors } = context;
|
|
94
81
|
if (value === null || isBoolean(value) || isNumber(value) || isBigInt(value) || isString(value)) return value;
|
|
@@ -120,13 +107,6 @@ function copyTransportValue(value, path, context) {
|
|
|
120
107
|
ancestors.delete(value);
|
|
121
108
|
return Object.freeze(output);
|
|
122
109
|
}
|
|
123
|
-
function fileSpan(file, range) {
|
|
124
|
-
return range === void 0 ? void 0 : {
|
|
125
|
-
file,
|
|
126
|
-
start: range.start,
|
|
127
|
-
end: range.end
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
110
|
/**
|
|
131
111
|
* Authored ESM, the JSX runtime, and the optional provider. A function body
|
|
132
112
|
* receives the runtime as `__mdxRuntime` and resolves imports through
|
package/dist/compiler.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.mjs","names":[],"sources":["../src/compiler.ts"],"sourcesContent":["import type { Schema, SchemaIssue, SchemaOutput } from \"@temelj/standard-schema\";\n\nimport { isObject, isBoolean, isNumber, isBigInt, isString } from \"@temelj/value\";\n\nimport type { HtmlRenderOptions } from \"./html-lower.ts\";\nimport type { HtmlRootNode } from \"./html.ts\";\nimport type { DocumentNode, FrontmatterObject } from \"./model.ts\";\nimport type { ParseResult } from \"./parser.ts\";\nimport type { SourceRange } from \"./ranges.ts\";\nimport type { SourceFile } from \"./source.ts\";\n\nimport { analyzeDocument, type CompileAnalysis } from \"./compile-analysis.ts\";\nimport { contentUsesAwait, emitContent } from \"./compile-emit.ts\";\nimport { createDiagnostic } from \"./diagnostics.ts\";\nimport {\n CompileError,\n ConfigurationError,\n FrontmatterError,\n LimitError,\n MdxError,\n} from \"./errors.ts\";\nimport { lowerHtml } from \"./html-lower.ts\";\nimport { javascriptPropertyName } from \"./javascript-ast.ts\";\nimport { parseJavaScriptProgram } from \"./javascript.ts\";\nimport { documentFrontmatter } from \"./model.ts\";\nimport { CodeWriter, type SourceMap } from \"./source-map.ts\";\n\nconst DEFAULT_MAXIMUM_GENERATED_CODE_BYTES = 10 * 1024 * 1024;\n\nconst DEFAULT_MAXIMUM_SOURCE_MAP_BYTES = 5 * 1024 * 1024;\n\n/** Compiled content renders the same elements as `lowerHtml` with these options. */\nexport interface CompileOptions extends HtmlRenderOptions {\n /** Emit `jsxDEV` calls with authored source locations. */\n readonly development?: boolean;\n /** Package providing `jsx-runtime`. */\n readonly jsxImportSource?: string;\n /** Maximum UTF-8 size of generated JavaScript. */\n readonly maximumGeneratedCodeBytes?: number;\n /** Maximum UTF-8 size of the serialized source map. */\n readonly maximumSourceMapBytes?: number;\n /** Optional generated filename written into the source map. */\n readonly outputName?: string;\n /** Optional package providing a `useMDXComponents` export. */\n readonly providerImportSource?: string;\n /** Original MDX filename written into the source map. */\n readonly sourceName?: string;\n /** JavaScript shape emitted by the compiler. */\n readonly outputFormat?: CompileOutputFormat;\n}\n\nexport type CompileOutputFormat = \"functionBody\" | \"program\";\n\n/**\n * The components compiled content reads from `props.components`: element\n * overrides by tag name, authored JSX components by name, and three reserved\n * entries whose names cannot collide with either.\n */\nexport interface CompiledComponents<TComponent = unknown> {\n readonly [name: string]: TComponent | undefined;\n /** Receives `code`, `language`, `meta`, `node`, and `status`. Defaults to `<pre><code>`. */\n readonly codeBlock?: TComponent;\n /** Receives `source`, `style`, and `meta`. Defaults to a readable code fallback. */\n readonly mathFormula?: TComponent;\n /** Wraps the whole document and receives its props plus `children`. */\n readonly wrapper?: TComponent;\n}\n\nexport type MdxTransportValue =\n | null\n | boolean\n | number\n | bigint\n | string\n | readonly MdxTransportValue[]\n | Readonly<{ [key: string]: MdxTransportValue }>;\n\ninterface CompileArtifactBase {\n readonly code: string;\n readonly frontmatter: MdxTransportValue;\n readonly map: SourceMap;\n}\n\nexport interface ProgramCompileArtifact extends CompileArtifactBase {\n readonly format: \"program\";\n}\n\nexport interface FunctionBodyCompileArtifact extends CompileArtifactBase {\n readonly format: \"functionBody\";\n readonly imports: readonly string[];\n}\n\nexport type CompileArtifact = ProgramCompileArtifact | FunctionBodyCompileArtifact;\n\nexport interface CompileSchemaOptions<TSchema extends Schema> extends CompileOptions {\n /** Standard Schema validation for decoded frontmatter. */\n readonly frontmatterSchema: TSchema;\n}\n\nexport interface CompileResult<\n TFrontmatter = FrontmatterObject,\n TFormat extends CompileOutputFormat = CompileOutputFormat,\n> extends ParseResult {\n readonly artifact: Extract<CompileArtifact, { readonly format: TFormat }>;\n readonly frontmatter: TFrontmatter;\n}\n\n/** Emits JavaScript for a strict document. Throws for configuration errors and compiler limits. */\nfunction emitArtifact(\n document: DocumentNode,\n options: Readonly<CompileOptions & { readonly source: SourceFile }>,\n frontmatter: MdxTransportValue,\n): CompileArtifact {\n try {\n if (\n options.maximumGeneratedCodeBytes !== undefined &&\n (!Number.isSafeInteger(options.maximumGeneratedCodeBytes) ||\n options.maximumGeneratedCodeBytes < 0)\n ) {\n throw ConfigurationError.invalidCompilerLimit(\n \"maximumGeneratedCodeBytes\",\n options.maximumGeneratedCodeBytes,\n );\n }\n\n if (\n options.maximumSourceMapBytes !== undefined &&\n (!Number.isSafeInteger(options.maximumSourceMapBytes) || options.maximumSourceMapBytes < 0)\n ) {\n throw ConfigurationError.invalidCompilerLimit(\n \"maximumSourceMapBytes\",\n options.maximumSourceMapBytes,\n );\n }\n\n const content = lowerHtml(document, options);\n const analysis = analyzeDocument(document, content, options);\n const usesAwait = contentUsesAwait(content);\n\n const format = options.outputFormat ?? \"functionBody\";\n const writer = new CodeWriter(options.source);\n emitModulePreamble(writer, analysis, options, format);\n emitContentFunction(writer, content, analysis, options, usesAwait);\n emitPublicComponent(writer, analysis, options, usesAwait, format);\n\n if (analysis.scope.missingReferences.size > 0) {\n emitMissingReferenceHelper(writer, analysis);\n }\n\n if (format === \"functionBody\") {\n writer.write(\n `return {${[...analysis.esm.exports, `default: ${analysis.scope.names.get(\"Content\")}`].join(\", \")}};\\n}\\n`,\n );\n }\n\n const code = writer.toString();\n enforceGeneratedCodeLimit(options.source, code, options.maximumGeneratedCodeBytes);\n\n try {\n // The output is valid by construction; parsing it once guards that invariant.\n parseJavaScriptProgram(\n format === \"program\" ? code : `async function __evaluateMdx(){\\n${code}\\n}`,\n );\n } catch (cause) {\n throw CompileError.generatedProgramInvalid(cause);\n }\n\n const map = writer.sourceMap(analysis.scope.sourceName, options.outputName);\n enforceSourceMapLimit(options.source, map, options.maximumSourceMapBytes);\n\n return format === \"program\"\n ? Object.freeze({ format, code, map, frontmatter })\n : Object.freeze({\n format,\n code,\n map,\n imports: Object.freeze(\n options.providerImportSource === undefined ||\n analysis.esm.imports.includes(options.providerImportSource)\n ? [...analysis.esm.imports]\n : [...analysis.esm.imports, options.providerImportSource],\n ),\n frontmatter,\n });\n } catch (cause) {\n if (cause instanceof MdxError) {\n throw cause;\n }\n\n throw CompileError.generationFailed(cause);\n }\n}\n\n/**\n * Validates frontmatter and compiles a parsed or transformed document without executing it.\n * @throws {FrontmatterError} Invalid schema output or unsupported transport data.\n * @throws {LimitError} Generated code or its source map exceeds a configured limit.\n * @throws {CompileError} JavaScript generation fails.\n * @throws {ConfigurationError} Invalid compiler options.\n */\nexport function compile<\n TSchema extends Schema,\n TFormat extends CompileOutputFormat = \"functionBody\",\n>(\n input: ParseResult,\n options: Readonly<CompileSchemaOptions<TSchema> & { readonly outputFormat?: TFormat }>,\n): Promise<CompileResult<SchemaOutput<TSchema>, TFormat>>;\nexport function compile<TFormat extends CompileOutputFormat = \"functionBody\">(\n input: ParseResult,\n options?: Readonly<CompileOptions & { readonly outputFormat?: TFormat }>,\n): Promise<CompileResult<FrontmatterObject, TFormat>>;\nexport async function compile(\n input: ParseResult,\n options: Readonly<CompileOptions & { readonly frontmatterSchema?: Schema }> = {},\n): Promise<CompileResult<unknown>> {\n const frontmatterNode = documentFrontmatter(input.document);\n let frontmatter: unknown = frontmatterNode?.data ?? Object.freeze({});\n\n if (options.frontmatterSchema !== undefined) {\n const validated = await options.frontmatterSchema[\"~standard\"].validate(frontmatter);\n\n if (validated.issues !== undefined) {\n const diagnostics = validated.issues.map((issue) =>\n createDiagnostic({\n severity: \"error\",\n code: \"mdx.frontmatter.schema\",\n message: formatSchemaIssue(issue),\n span: fileSpan(input.file, frontmatterNode?.origin),\n }),\n );\n\n throw FrontmatterError.schemaValidationFailed(input.file, diagnostics, validated.issues);\n }\n\n frontmatter = validated.value;\n }\n\n const transported = copyTransportValue(frontmatter, \"frontmatter\", {\n file: input.file,\n origin: frontmatterNode?.origin,\n ancestors: new WeakSet(),\n });\n\n const artifact = emitArtifact(input.document, { ...options, source: input.file }, transported);\n\n return Object.freeze({\n file: input.file,\n document: input.document,\n diagnostics: input.diagnostics,\n artifact,\n frontmatter,\n });\n}\n\nfunction formatSchemaIssue(issue: SchemaIssue): string {\n const path = issue.path?.map((part) => String(isObject(part) ? part.key : part)).join(\".\");\n\n return path === undefined || path.length === 0 ? issue.message : `${path}: ${issue.message}`;\n}\n\ninterface FrontmatterTransportContext {\n readonly file: SourceFile;\n readonly origin: SourceRange | undefined;\n readonly ancestors: WeakSet<object>;\n}\n\nfunction copyTransportValue(\n // oxlint-disable-next-line anti-slop/no-unknown-parameters -- Recursively validates external schema output against the MDX transport contract.\n value: unknown,\n path: string,\n context: FrontmatterTransportContext,\n): MdxTransportValue {\n const { ancestors } = context;\n\n if (value === null || isBoolean(value) || isNumber(value) || isBigInt(value) || isString(value)) {\n return value;\n }\n\n if (!isObject(value)) {\n throw FrontmatterError.nonTransportableValue(\n context.file,\n context.origin,\n `${path} contains unsupported ${Object.prototype.toString.call(value)}`,\n );\n }\n\n if (ancestors.has(value)) {\n throw FrontmatterError.nonTransportableValue(\n context.file,\n context.origin,\n `${path} contains a cycle`,\n );\n }\n\n ancestors.add(value);\n\n if (Array.isArray(value)) {\n const output: MdxTransportValue[] = [];\n\n for (let index = 0; index < value.length; index++) {\n const item = copyTransportValue(value[index], `${path}[${index}]`, context);\n\n output.push(item);\n }\n\n ancestors.delete(value);\n\n return Object.freeze(output);\n }\n\n const prototype: unknown = Object.getPrototypeOf(value);\n\n if (prototype !== Object.prototype && prototype !== null) {\n throw FrontmatterError.nonTransportableValue(\n context.file,\n context.origin,\n `${path} contains a non-plain object`,\n );\n }\n\n if (Object.getOwnPropertySymbols(value).length > 0) {\n throw FrontmatterError.nonTransportableValue(\n context.file,\n context.origin,\n `${path} contains a symbol property`,\n );\n }\n\n const output: Record<string, MdxTransportValue> = {};\n\n for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(value))) {\n if (!descriptor.enumerable) {\n continue;\n }\n\n if (!(\"value\" in descriptor)) {\n throw FrontmatterError.nonTransportableValue(\n context.file,\n context.origin,\n `${path}.${key} is an accessor property`,\n );\n }\n\n const item = copyTransportValue(descriptor.value, `${path}.${key}`, context);\n\n Object.defineProperty(output, key, {\n enumerable: true,\n value: item,\n });\n }\n\n ancestors.delete(value);\n\n return Object.freeze(output);\n}\n\nfunction fileSpan(\n file: SourceFile,\n range: SourceRange | undefined,\n): Readonly<{ file: SourceFile; start: number; end: number }> | undefined {\n return range === undefined ? undefined : { file, start: range.start, end: range.end };\n}\n\n/**\n * Authored ESM, the JSX runtime, and the optional provider. A function body\n * receives the runtime as `__mdxRuntime` and resolves imports through\n * `__resolveMdxImport` instead of importing.\n */\nfunction emitModulePreamble(\n writer: CodeWriter,\n analysis: CompileAnalysis,\n options: Readonly<CompileOptions>,\n format: CompileOutputFormat,\n): void {\n const names = analysis.scope.names;\n\n const runtime = analysis.scope.development\n ? `{Fragment: ${names.get(\"_Fragment\")}, jsxDEV: ${names.get(\"_jsxDEV\")}}`\n : `{Fragment: ${names.get(\"_Fragment\")}, jsx: ${names.get(\"_jsx\")}, jsxs: ${names.get(\"_jsxs\")}}`;\n\n const importSource = `${options.jsxImportSource ?? \"react\"}/${\n analysis.scope.development ? \"jsx-dev-runtime\" : \"jsx-runtime\"\n }`;\n\n writer.write(\n format === \"program\"\n ? `import ${runtime.replaceAll(\": \", \" as \")} from ${JSON.stringify(importSource)};\\n`\n : `const ${runtime} = __mdxRuntime;\\n`,\n );\n\n if (format === \"functionBody\") {\n if (analysis.esm.imports.length > 0 || options.providerImportSource !== undefined) {\n writer.write(`const ${names.get(\"_resolveMdxImport\")} = __resolveMdxImport;\\n`);\n }\n\n // Authored lexical bindings may use the evaluator's parameter names.\n writer.write(\"{\\n\");\n }\n\n for (const entry of analysis.esm.blocks) {\n writer.write(`${entry.code.trimEnd()}\\n`, entry.origin);\n }\n\n if (options.providerImportSource !== undefined) {\n writer.write(\n format === \"program\"\n ? `import {useMDXComponents as ${names.get(\"_provideComponents\")}} from ${JSON.stringify(options.providerImportSource)};\\n`\n : `const {useMDXComponents: ${names.get(\"_provideComponents\")}} = await ${names.get(\"_resolveMdxImport\")}(${JSON.stringify(options.providerImportSource)});\\n`,\n );\n }\n}\n\nfunction emitContentFunction(\n writer: CodeWriter,\n content: HtmlRootNode,\n analysis: CompileAnalysis,\n options: Readonly<CompileOptions>,\n usesAwait: boolean,\n): void {\n const names = analysis.scope.names;\n const props = analysis.propsName;\n const componentsName = names.get(\"_components\");\n writer.write(`${usesAwait ? \"async \" : \"\"}function ${names.get(\"_createContent\")}(${props}) {\\n`);\n writer.write(` const ${componentsName} = {`);\n const tags = [...analysis.intrinsicTags].sort();\n tags.forEach((tag, index) => {\n if (index > 0) {\n writer.write(\", \");\n }\n\n writer.write(`${javascriptPropertyName(tag)}:${JSON.stringify(tag)}`);\n });\n\n if (options.providerImportSource !== undefined) {\n writer.write(`${tags.length === 0 ? \"\" : \", \"}...${names.get(\"_provideComponents\")}()`);\n }\n\n writer.write(\n `${tags.length === 0 && options.providerImportSource === undefined ? \"\" : \", \"}...${props}.components};\\n`,\n );\n\n const components = [...analysis.scope.referencedComponents].sort();\n\n for (const component of components) {\n writer.write(` const ${component} = ${componentsName}[${JSON.stringify(component)}];\\n`);\n }\n\n for (const [reference, component] of analysis.scope.missingReferences) {\n writer.write(\n ` if (!${reference}) ${names.get(\"_missingReference\")}(${JSON.stringify(reference)}, ${component});\\n`,\n );\n }\n\n writer.write(\" return \");\n emitContent(writer, content, analysis);\n writer.write(\";\\n}\\n\");\n}\n\nfunction emitPublicComponent(\n writer: CodeWriter,\n analysis: CompileAnalysis,\n options: Readonly<CompileOptions>,\n usesAwait: boolean,\n format: CompileOutputFormat,\n): void {\n const names = analysis.scope.names;\n const props = analysis.propsName;\n const layout = names.get(\"Layout\");\n writer.write(\n `${format === \"program\" ? \"export default \" : \"\"}${usesAwait ? \"async \" : \"\"}function ${names.get(\"Content\")}(${props} = {}) {\\n`,\n );\n const content = `${usesAwait ? \"await \" : \"\"}${names.get(\"_createContent\")}(${props})`;\n\n if (analysis.esm.hasLayout) {\n writer.write(\n ` return ${runtimeCall(analysis, layout, `{...${props}, children: ${content}}`)};\\n`,\n );\n } else {\n writer.write(` const {wrapper: ${layout}} = {`);\n\n if (options.providerImportSource !== undefined) {\n writer.write(`...${names.get(\"_provideComponents\")}(), `);\n }\n\n writer.write(`...${props}.components};\\n`);\n writer.write(\n ` return ${layout} ? ${runtimeCall(analysis, layout, `{...${props}, children: ${content}}`)} : ${content};\\n`,\n );\n }\n\n writer.write(\"}\\n\");\n}\n\nfunction emitMissingReferenceHelper(writer: CodeWriter, analysis: CompileAnalysis): void {\n const names = analysis.scope.names;\n writer.write(\n `class ${names.get(\"ReferenceError\")} extends Error {\\n` +\n \" constructor(id, component) {\\n\" +\n ' super(`Expected ${component ? \"component\" : \"object\"} ${id} to be defined: you likely forgot to import, pass, or provide it.`);\\n' +\n ' this.name = \"ReferenceError\";\\n' +\n \" }\\n\" +\n \"}\\n\" +\n `function ${names.get(\"_missingReference\")}(id, component) {\\n` +\n ` throw new ${names.get(\"ReferenceError\")}(id, component);\\n` +\n \"}\\n\",\n );\n}\n\nfunction enforceGeneratedCodeLimit(\n file: SourceFile,\n code: string,\n configuredMaximum: number | undefined,\n): void {\n const maximum = configuredMaximum ?? DEFAULT_MAXIMUM_GENERATED_CODE_BYTES;\n const actual = new TextEncoder().encode(code).byteLength;\n\n if (actual > maximum) {\n throw LimitError.exceeded(file, \"maximumGeneratedCodeBytes\", maximum, undefined, actual);\n }\n}\n\nfunction enforceSourceMapLimit(\n file: SourceFile,\n map: SourceMap,\n configuredMaximum: number | undefined,\n): void {\n const maximum = configuredMaximum ?? DEFAULT_MAXIMUM_SOURCE_MAP_BYTES;\n const actual = new TextEncoder().encode(JSON.stringify(map)).byteLength;\n\n if (actual > maximum) {\n throw LimitError.exceeded(file, \"maximumSourceMapBytes\", maximum, undefined, actual);\n }\n}\n\nfunction runtimeCall(analysis: CompileAnalysis, tag: string, properties: string): string {\n return analysis.scope.development\n ? `${analysis.scope.names.get(\"_jsxDEV\")}(${tag}, ${properties}, undefined, false, undefined, undefined)`\n : `${analysis.scope.names.get(\"_jsx\")}(${tag}, ${properties})`;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"compiler.mjs","names":[],"sources":["../src/compiler.ts"],"sourcesContent":["import type { Schema, SchemaOutput } from \"@temelj/standard-schema\";\n\nimport { isObject, isBoolean, isNumber, isBigInt, isString } from \"@temelj/value\";\n\nimport type { HtmlRenderOptions } from \"./html-lower.ts\";\nimport type { HtmlRootNode } from \"./html.ts\";\nimport type { DocumentNode, FrontmatterObject } from \"./model.ts\";\nimport type { ParseResult } from \"./parser.ts\";\nimport type { SourceRange } from \"./ranges.ts\";\nimport type { SourceFile } from \"./source.ts\";\n\nimport { analyzeDocument, type CompileAnalysis } from \"./compile-analysis.ts\";\nimport { contentUsesAwait, emitContent } from \"./compile-emit.ts\";\nimport {\n CompileError,\n ConfigurationError,\n FrontmatterError,\n LimitError,\n MdxError,\n} from \"./errors.ts\";\nimport { frontmatterSchemaValue } from \"./frontmatter-schema.ts\";\nimport { lowerHtml } from \"./html-lower.ts\";\nimport { javascriptPropertyName } from \"./javascript-ast.ts\";\nimport { parseJavaScriptProgram } from \"./javascript.ts\";\nimport { documentFrontmatter } from \"./model.ts\";\nimport { CodeWriter, type SourceMap } from \"./source-map.ts\";\n\nconst DEFAULT_MAXIMUM_GENERATED_CODE_BYTES = 10 * 1024 * 1024;\n\nconst DEFAULT_MAXIMUM_SOURCE_MAP_BYTES = 5 * 1024 * 1024;\n\n/** Compiled content renders the same elements as `lowerHtml` with these options. */\nexport interface CompileOptions extends HtmlRenderOptions {\n /** Emit `jsxDEV` calls with authored source locations. */\n readonly development?: boolean;\n /** Package providing `jsx-runtime`. */\n readonly jsxImportSource?: string;\n /** Maximum UTF-8 size of generated JavaScript. */\n readonly maximumGeneratedCodeBytes?: number;\n /** Maximum UTF-8 size of the serialized source map. */\n readonly maximumSourceMapBytes?: number;\n /** Optional generated filename written into the source map. */\n readonly outputName?: string;\n /** Optional package providing a `useMDXComponents` export. */\n readonly providerImportSource?: string;\n /** Original MDX filename written into the source map. */\n readonly sourceName?: string;\n /** JavaScript shape emitted by the compiler. */\n readonly outputFormat?: CompileOutputFormat;\n}\n\nexport type CompileOutputFormat = \"functionBody\" | \"program\";\n\n/**\n * The components compiled content reads from `props.components`: element\n * overrides by tag name, authored JSX components by name, and three reserved\n * entries whose names cannot collide with either.\n */\nexport interface CompiledComponents<TComponent = unknown> {\n readonly [name: string]: TComponent | undefined;\n /** Receives `code`, `language`, `meta`, `node`, and `status`. Defaults to `<pre><code>`. */\n readonly codeBlock?: TComponent;\n /** Receives `source`, `style`, and `meta`. Defaults to a readable code fallback. */\n readonly mathFormula?: TComponent;\n /** Wraps the whole document and receives its props plus `children`. */\n readonly wrapper?: TComponent;\n}\n\nexport type MdxTransportValue =\n | null\n | boolean\n | number\n | bigint\n | string\n | readonly MdxTransportValue[]\n | Readonly<{ [key: string]: MdxTransportValue }>;\n\ninterface CompileArtifactBase {\n readonly code: string;\n readonly frontmatter: MdxTransportValue;\n readonly map: SourceMap;\n}\n\nexport interface ProgramCompileArtifact extends CompileArtifactBase {\n readonly format: \"program\";\n}\n\nexport interface FunctionBodyCompileArtifact extends CompileArtifactBase {\n readonly format: \"functionBody\";\n readonly imports: readonly string[];\n}\n\nexport type CompileArtifact = ProgramCompileArtifact | FunctionBodyCompileArtifact;\n\nexport interface CompileSchemaOptions<TSchema extends Schema> extends CompileOptions {\n /** Standard Schema validation for decoded frontmatter. */\n readonly frontmatterSchema: TSchema;\n}\n\nexport interface CompileResult<\n TFrontmatter = FrontmatterObject,\n TFormat extends CompileOutputFormat = CompileOutputFormat,\n> extends ParseResult {\n readonly artifact: Extract<CompileArtifact, { readonly format: TFormat }>;\n readonly frontmatter: TFrontmatter;\n}\n\n/** Emits JavaScript for a strict document. Throws for configuration errors and compiler limits. */\nfunction emitArtifact(\n document: DocumentNode,\n options: Readonly<CompileOptions & { readonly source: SourceFile }>,\n frontmatter: MdxTransportValue,\n): CompileArtifact {\n try {\n if (\n options.maximumGeneratedCodeBytes !== undefined &&\n (!Number.isSafeInteger(options.maximumGeneratedCodeBytes) ||\n options.maximumGeneratedCodeBytes < 0)\n ) {\n throw ConfigurationError.invalidCompilerLimit(\n \"maximumGeneratedCodeBytes\",\n options.maximumGeneratedCodeBytes,\n );\n }\n\n if (\n options.maximumSourceMapBytes !== undefined &&\n (!Number.isSafeInteger(options.maximumSourceMapBytes) || options.maximumSourceMapBytes < 0)\n ) {\n throw ConfigurationError.invalidCompilerLimit(\n \"maximumSourceMapBytes\",\n options.maximumSourceMapBytes,\n );\n }\n\n const content = lowerHtml(document, options);\n const analysis = analyzeDocument(document, content, options);\n const usesAwait = contentUsesAwait(content);\n\n const format = options.outputFormat ?? \"functionBody\";\n const writer = new CodeWriter(options.source);\n emitModulePreamble(writer, analysis, options, format);\n emitContentFunction(writer, content, analysis, options, usesAwait);\n emitPublicComponent(writer, analysis, options, usesAwait, format);\n\n if (analysis.scope.missingReferences.size > 0) {\n emitMissingReferenceHelper(writer, analysis);\n }\n\n if (format === \"functionBody\") {\n writer.write(\n `return {${[...analysis.esm.exports, `default: ${analysis.scope.names.get(\"Content\")}`].join(\", \")}};\\n}\\n`,\n );\n }\n\n const code = writer.toString();\n enforceGeneratedCodeLimit(options.source, code, options.maximumGeneratedCodeBytes);\n\n try {\n // The output is valid by construction; parsing it once guards that invariant.\n parseJavaScriptProgram(\n format === \"program\" ? code : `async function __evaluateMdx(){\\n${code}\\n}`,\n );\n } catch (cause) {\n throw CompileError.generatedProgramInvalid(cause);\n }\n\n const map = writer.sourceMap(analysis.scope.sourceName, options.outputName);\n enforceSourceMapLimit(options.source, map, options.maximumSourceMapBytes);\n\n return format === \"program\"\n ? Object.freeze({ format, code, map, frontmatter })\n : Object.freeze({\n format,\n code,\n map,\n imports: Object.freeze(\n options.providerImportSource === undefined ||\n analysis.esm.imports.includes(options.providerImportSource)\n ? [...analysis.esm.imports]\n : [...analysis.esm.imports, options.providerImportSource],\n ),\n frontmatter,\n });\n } catch (cause) {\n if (cause instanceof MdxError) {\n throw cause;\n }\n\n throw CompileError.generationFailed(cause);\n }\n}\n\n/**\n * Validates frontmatter and compiles a parsed or transformed document without executing it.\n * @throws {FrontmatterError} Invalid schema output or unsupported transport data.\n * @throws {LimitError} Generated code or its source map exceeds a configured limit.\n * @throws {CompileError} JavaScript generation fails.\n * @throws {ConfigurationError} Invalid compiler options.\n */\nexport function compile<\n TSchema extends Schema,\n TFormat extends CompileOutputFormat = \"functionBody\",\n>(\n input: ParseResult,\n options: Readonly<CompileSchemaOptions<TSchema> & { readonly outputFormat?: TFormat }>,\n): Promise<CompileResult<SchemaOutput<TSchema>, TFormat>>;\nexport function compile<TFormat extends CompileOutputFormat = \"functionBody\">(\n input: ParseResult,\n options?: Readonly<CompileOptions & { readonly outputFormat?: TFormat }>,\n): Promise<CompileResult<FrontmatterObject, TFormat>>;\nexport async function compile(\n input: ParseResult,\n options: Readonly<CompileOptions & { readonly frontmatterSchema?: Schema }> = {},\n): Promise<CompileResult<unknown>> {\n const frontmatterNode = documentFrontmatter(input.document);\n let frontmatter: unknown = frontmatterNode?.data ?? Object.freeze({});\n\n if (options.frontmatterSchema !== undefined) {\n const validated = await options.frontmatterSchema[\"~standard\"].validate(frontmatter);\n\n frontmatter = frontmatterSchemaValue(validated, input.file, frontmatterNode?.origin);\n }\n\n const transported = copyTransportValue(frontmatter, \"frontmatter\", {\n file: input.file,\n origin: frontmatterNode?.origin,\n ancestors: new WeakSet(),\n });\n\n const artifact = emitArtifact(input.document, { ...options, source: input.file }, transported);\n\n return Object.freeze({\n file: input.file,\n document: input.document,\n diagnostics: input.diagnostics,\n artifact,\n frontmatter,\n });\n}\n\ninterface FrontmatterTransportContext {\n readonly file: SourceFile;\n readonly origin: SourceRange | undefined;\n readonly ancestors: WeakSet<object>;\n}\n\nfunction copyTransportValue(\n // oxlint-disable-next-line anti-slop/no-unknown-parameters -- Recursively validates external schema output against the MDX transport contract.\n value: unknown,\n path: string,\n context: FrontmatterTransportContext,\n): MdxTransportValue {\n const { ancestors } = context;\n\n if (value === null || isBoolean(value) || isNumber(value) || isBigInt(value) || isString(value)) {\n return value;\n }\n\n if (!isObject(value)) {\n throw FrontmatterError.nonTransportableValue(\n context.file,\n context.origin,\n `${path} contains unsupported ${Object.prototype.toString.call(value)}`,\n );\n }\n\n if (ancestors.has(value)) {\n throw FrontmatterError.nonTransportableValue(\n context.file,\n context.origin,\n `${path} contains a cycle`,\n );\n }\n\n ancestors.add(value);\n\n if (Array.isArray(value)) {\n const output: MdxTransportValue[] = [];\n\n for (let index = 0; index < value.length; index++) {\n const item = copyTransportValue(value[index], `${path}[${index}]`, context);\n\n output.push(item);\n }\n\n ancestors.delete(value);\n\n return Object.freeze(output);\n }\n\n const prototype: unknown = Object.getPrototypeOf(value);\n\n if (prototype !== Object.prototype && prototype !== null) {\n throw FrontmatterError.nonTransportableValue(\n context.file,\n context.origin,\n `${path} contains a non-plain object`,\n );\n }\n\n if (Object.getOwnPropertySymbols(value).length > 0) {\n throw FrontmatterError.nonTransportableValue(\n context.file,\n context.origin,\n `${path} contains a symbol property`,\n );\n }\n\n const output: Record<string, MdxTransportValue> = {};\n\n for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(value))) {\n if (!descriptor.enumerable) {\n continue;\n }\n\n if (!(\"value\" in descriptor)) {\n throw FrontmatterError.nonTransportableValue(\n context.file,\n context.origin,\n `${path}.${key} is an accessor property`,\n );\n }\n\n const item = copyTransportValue(descriptor.value, `${path}.${key}`, context);\n\n Object.defineProperty(output, key, {\n enumerable: true,\n value: item,\n });\n }\n\n ancestors.delete(value);\n\n return Object.freeze(output);\n}\n\n/**\n * Authored ESM, the JSX runtime, and the optional provider. A function body\n * receives the runtime as `__mdxRuntime` and resolves imports through\n * `__resolveMdxImport` instead of importing.\n */\nfunction emitModulePreamble(\n writer: CodeWriter,\n analysis: CompileAnalysis,\n options: Readonly<CompileOptions>,\n format: CompileOutputFormat,\n): void {\n const names = analysis.scope.names;\n\n const runtime = analysis.scope.development\n ? `{Fragment: ${names.get(\"_Fragment\")}, jsxDEV: ${names.get(\"_jsxDEV\")}}`\n : `{Fragment: ${names.get(\"_Fragment\")}, jsx: ${names.get(\"_jsx\")}, jsxs: ${names.get(\"_jsxs\")}}`;\n\n const importSource = `${options.jsxImportSource ?? \"react\"}/${\n analysis.scope.development ? \"jsx-dev-runtime\" : \"jsx-runtime\"\n }`;\n\n writer.write(\n format === \"program\"\n ? `import ${runtime.replaceAll(\": \", \" as \")} from ${JSON.stringify(importSource)};\\n`\n : `const ${runtime} = __mdxRuntime;\\n`,\n );\n\n if (format === \"functionBody\") {\n if (analysis.esm.imports.length > 0 || options.providerImportSource !== undefined) {\n writer.write(`const ${names.get(\"_resolveMdxImport\")} = __resolveMdxImport;\\n`);\n }\n\n // Authored lexical bindings may use the evaluator's parameter names.\n writer.write(\"{\\n\");\n }\n\n for (const entry of analysis.esm.blocks) {\n writer.write(`${entry.code.trimEnd()}\\n`, entry.origin);\n }\n\n if (options.providerImportSource !== undefined) {\n writer.write(\n format === \"program\"\n ? `import {useMDXComponents as ${names.get(\"_provideComponents\")}} from ${JSON.stringify(options.providerImportSource)};\\n`\n : `const {useMDXComponents: ${names.get(\"_provideComponents\")}} = await ${names.get(\"_resolveMdxImport\")}(${JSON.stringify(options.providerImportSource)});\\n`,\n );\n }\n}\n\nfunction emitContentFunction(\n writer: CodeWriter,\n content: HtmlRootNode,\n analysis: CompileAnalysis,\n options: Readonly<CompileOptions>,\n usesAwait: boolean,\n): void {\n const names = analysis.scope.names;\n const props = analysis.propsName;\n const componentsName = names.get(\"_components\");\n writer.write(`${usesAwait ? \"async \" : \"\"}function ${names.get(\"_createContent\")}(${props}) {\\n`);\n writer.write(` const ${componentsName} = {`);\n const tags = [...analysis.intrinsicTags].sort();\n tags.forEach((tag, index) => {\n if (index > 0) {\n writer.write(\", \");\n }\n\n writer.write(`${javascriptPropertyName(tag)}:${JSON.stringify(tag)}`);\n });\n\n if (options.providerImportSource !== undefined) {\n writer.write(`${tags.length === 0 ? \"\" : \", \"}...${names.get(\"_provideComponents\")}()`);\n }\n\n writer.write(\n `${tags.length === 0 && options.providerImportSource === undefined ? \"\" : \", \"}...${props}.components};\\n`,\n );\n\n const components = [...analysis.scope.referencedComponents].sort();\n\n for (const component of components) {\n writer.write(` const ${component} = ${componentsName}[${JSON.stringify(component)}];\\n`);\n }\n\n for (const [reference, component] of analysis.scope.missingReferences) {\n writer.write(\n ` if (!${reference}) ${names.get(\"_missingReference\")}(${JSON.stringify(reference)}, ${component});\\n`,\n );\n }\n\n writer.write(\" return \");\n emitContent(writer, content, analysis);\n writer.write(\";\\n}\\n\");\n}\n\nfunction emitPublicComponent(\n writer: CodeWriter,\n analysis: CompileAnalysis,\n options: Readonly<CompileOptions>,\n usesAwait: boolean,\n format: CompileOutputFormat,\n): void {\n const names = analysis.scope.names;\n const props = analysis.propsName;\n const layout = names.get(\"Layout\");\n writer.write(\n `${format === \"program\" ? \"export default \" : \"\"}${usesAwait ? \"async \" : \"\"}function ${names.get(\"Content\")}(${props} = {}) {\\n`,\n );\n const content = `${usesAwait ? \"await \" : \"\"}${names.get(\"_createContent\")}(${props})`;\n\n if (analysis.esm.hasLayout) {\n writer.write(\n ` return ${runtimeCall(analysis, layout, `{...${props}, children: ${content}}`)};\\n`,\n );\n } else {\n writer.write(` const {wrapper: ${layout}} = {`);\n\n if (options.providerImportSource !== undefined) {\n writer.write(`...${names.get(\"_provideComponents\")}(), `);\n }\n\n writer.write(`...${props}.components};\\n`);\n writer.write(\n ` return ${layout} ? ${runtimeCall(analysis, layout, `{...${props}, children: ${content}}`)} : ${content};\\n`,\n );\n }\n\n writer.write(\"}\\n\");\n}\n\nfunction emitMissingReferenceHelper(writer: CodeWriter, analysis: CompileAnalysis): void {\n const names = analysis.scope.names;\n writer.write(\n `class ${names.get(\"ReferenceError\")} extends Error {\\n` +\n \" constructor(id, component) {\\n\" +\n ' super(`Expected ${component ? \"component\" : \"object\"} ${id} to be defined: you likely forgot to import, pass, or provide it.`);\\n' +\n ' this.name = \"ReferenceError\";\\n' +\n \" }\\n\" +\n \"}\\n\" +\n `function ${names.get(\"_missingReference\")}(id, component) {\\n` +\n ` throw new ${names.get(\"ReferenceError\")}(id, component);\\n` +\n \"}\\n\",\n );\n}\n\nfunction enforceGeneratedCodeLimit(\n file: SourceFile,\n code: string,\n configuredMaximum: number | undefined,\n): void {\n const maximum = configuredMaximum ?? DEFAULT_MAXIMUM_GENERATED_CODE_BYTES;\n const actual = new TextEncoder().encode(code).byteLength;\n\n if (actual > maximum) {\n throw LimitError.exceeded(file, \"maximumGeneratedCodeBytes\", maximum, undefined, actual);\n }\n}\n\nfunction enforceSourceMapLimit(\n file: SourceFile,\n map: SourceMap,\n configuredMaximum: number | undefined,\n): void {\n const maximum = configuredMaximum ?? DEFAULT_MAXIMUM_SOURCE_MAP_BYTES;\n const actual = new TextEncoder().encode(JSON.stringify(map)).byteLength;\n\n if (actual > maximum) {\n throw LimitError.exceeded(file, \"maximumSourceMapBytes\", maximum, undefined, actual);\n }\n}\n\nfunction runtimeCall(analysis: CompileAnalysis, tag: string, properties: string): string {\n return analysis.scope.development\n ? `${analysis.scope.names.get(\"_jsxDEV\")}(${tag}, ${properties}, undefined, false, undefined, undefined)`\n : `${analysis.scope.names.get(\"_jsx\")}(${tag}, ${properties})`;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FrontmatterFormat } from "./syntax-options.mjs";
|
|
2
|
+
import { FrontmatterObject } from "./model.mjs";
|
|
3
|
+
import { SourceSpan } from "./source.mjs";
|
|
4
|
+
import { DiagnosticReporter } from "./diagnostics.mjs";
|
|
5
|
+
//#region src/frontmatter-decode.d.ts
|
|
6
|
+
interface DecodeOptions {
|
|
7
|
+
readonly diagnostics: DiagnosticReporter;
|
|
8
|
+
readonly format: FrontmatterFormat;
|
|
9
|
+
readonly source: string;
|
|
10
|
+
readonly span: SourceSpan;
|
|
11
|
+
}
|
|
12
|
+
export declare function decodeFrontmatter(options: DecodeOptions): FrontmatterObject | undefined;
|
|
13
|
+
//#endregion
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=frontmatter-decode.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter-decode.d.mts","names":[],"sources":["../src/frontmatter-decode.ts"],"mappings":";;;;;UAkBU;WACC,aAAa;WACb,QAAQ;WACR;WACA,MAAM;;wBAOD,kBAAkB,SAAS,gBAAgB"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { isBigInt, isBoolean, isFunction, isNumber, isObject, isPlainObject, isString, isSymbol } from "@temelj/value";
|
|
2
|
+
import { TomlDate, TomlError, parse } from "smol-toml";
|
|
3
|
+
import { parseDocument } from "yaml";
|
|
4
|
+
//#region src/frontmatter-decode.ts
|
|
5
|
+
const maximumYamlAliases = 100;
|
|
6
|
+
const maximumTomlDepth = 256;
|
|
7
|
+
function decodeFrontmatter(options) {
|
|
8
|
+
return options.format === "yaml" ? decodeYaml(options) : decodeToml(options);
|
|
9
|
+
}
|
|
10
|
+
function decodeYaml(options) {
|
|
11
|
+
let document;
|
|
12
|
+
try {
|
|
13
|
+
document = parseDocument(options.source, {
|
|
14
|
+
customTags: [],
|
|
15
|
+
intAsBigInt: true,
|
|
16
|
+
logLevel: "silent",
|
|
17
|
+
prettyErrors: false,
|
|
18
|
+
resolveKnownTags: false,
|
|
19
|
+
schema: "core",
|
|
20
|
+
strict: true,
|
|
21
|
+
stringKeys: true,
|
|
22
|
+
uniqueKeys: true,
|
|
23
|
+
version: "1.2"
|
|
24
|
+
});
|
|
25
|
+
} catch (cause) {
|
|
26
|
+
addParserFailure(options, cause);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
for (const warning of document.warnings) options.diagnostics.add({
|
|
30
|
+
code: yamlCode(warning.code),
|
|
31
|
+
message: warning.message,
|
|
32
|
+
severity: "warning",
|
|
33
|
+
span: relativeSpan(options.span, warning.pos[0], warning.pos[1])
|
|
34
|
+
});
|
|
35
|
+
for (const error of document.errors) options.diagnostics.add({
|
|
36
|
+
code: yamlCode(error.code),
|
|
37
|
+
message: error.message,
|
|
38
|
+
severity: "error",
|
|
39
|
+
span: relativeSpan(options.span, error.pos[0], error.pos[1])
|
|
40
|
+
});
|
|
41
|
+
if (document.errors.length > 0) return;
|
|
42
|
+
let parsed;
|
|
43
|
+
try {
|
|
44
|
+
parsed = document.contents === null ? {} : document.toJS({ maxAliasCount: maximumYamlAliases });
|
|
45
|
+
} catch (cause) {
|
|
46
|
+
addParserFailure(options, cause);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
return convertRoot(parsed, options);
|
|
50
|
+
}
|
|
51
|
+
function decodeToml(options) {
|
|
52
|
+
let parsed;
|
|
53
|
+
try {
|
|
54
|
+
parsed = parse(options.source, {
|
|
55
|
+
integersAsBigInt: "asNeeded",
|
|
56
|
+
maxDepth: maximumTomlDepth
|
|
57
|
+
});
|
|
58
|
+
} catch (cause) {
|
|
59
|
+
if (cause instanceof TomlError) {
|
|
60
|
+
const offset = lineColumnOffset(options.source, cause.line, cause.column);
|
|
61
|
+
options.diagnostics.add({
|
|
62
|
+
code: "mdx.frontmatter.toml",
|
|
63
|
+
message: cause.message,
|
|
64
|
+
severity: "error",
|
|
65
|
+
span: relativeSpan(options.span, offset, offset + 1)
|
|
66
|
+
});
|
|
67
|
+
} else addParserFailure(options, cause);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
return convertRoot(parsed, options);
|
|
71
|
+
}
|
|
72
|
+
function convertRoot(value, options) {
|
|
73
|
+
if (!isPlainObject(value)) {
|
|
74
|
+
options.diagnostics.add({
|
|
75
|
+
code: "mdx.frontmatter.root",
|
|
76
|
+
message: "FrontmatterNode must contain a mapping at its root",
|
|
77
|
+
severity: "error",
|
|
78
|
+
span: options.span
|
|
79
|
+
});
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
return convertObject(value, options, "$", /* @__PURE__ */ new WeakSet());
|
|
83
|
+
}
|
|
84
|
+
function convertValue(value, options, path, active) {
|
|
85
|
+
if (value === null || isBoolean(value) || isNumber(value) || isString(value)) return value;
|
|
86
|
+
if (isBigInt(value)) return value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(value) : value;
|
|
87
|
+
if (value instanceof TomlDate) return convertTemporal(value);
|
|
88
|
+
if (Array.isArray(value)) {
|
|
89
|
+
if (active.has(value)) return invalidValue(options, path, "cyclic alias");
|
|
90
|
+
active.add(value);
|
|
91
|
+
const converted = [];
|
|
92
|
+
for (const [index, item] of value.entries()) {
|
|
93
|
+
const result = convertValue(item, options, `${path}[${index}]`, active);
|
|
94
|
+
if (result === void 0) return;
|
|
95
|
+
converted.push(result);
|
|
96
|
+
}
|
|
97
|
+
active.delete(value);
|
|
98
|
+
Object.freeze(converted);
|
|
99
|
+
return converted;
|
|
100
|
+
}
|
|
101
|
+
if (isPlainObject(value)) return convertObject(value, options, path, active);
|
|
102
|
+
return invalidValue(options, path, describeValue(value));
|
|
103
|
+
}
|
|
104
|
+
function convertObject(value, options, path, active) {
|
|
105
|
+
if (active.has(value)) return invalidValue(options, path, "cyclic alias");
|
|
106
|
+
active.add(value);
|
|
107
|
+
const converted = {};
|
|
108
|
+
for (const [key, item] of Object.entries(value)) {
|
|
109
|
+
const result = convertValue(item, options, propertyPath(path, key), active);
|
|
110
|
+
if (result === void 0) return;
|
|
111
|
+
Object.defineProperty(converted, key, {
|
|
112
|
+
configurable: false,
|
|
113
|
+
enumerable: true,
|
|
114
|
+
value: result,
|
|
115
|
+
writable: false
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
active.delete(value);
|
|
119
|
+
Object.freeze(converted);
|
|
120
|
+
return converted;
|
|
121
|
+
}
|
|
122
|
+
function convertTemporal(value) {
|
|
123
|
+
const type = value.isDateTime() ? value.isLocal() ? "local-date-time" : "offset-date-time" : value.isDate() ? "local-date" : "local-time";
|
|
124
|
+
return Object.freeze({
|
|
125
|
+
kind: "temporal",
|
|
126
|
+
type,
|
|
127
|
+
value: value.toISOString()
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function invalidValue(options, path, description) {
|
|
131
|
+
options.diagnostics.add({
|
|
132
|
+
code: "mdx.frontmatter.value",
|
|
133
|
+
message: `Unsupported frontmatter value at ${path}: ${description}`,
|
|
134
|
+
severity: "error",
|
|
135
|
+
span: options.span
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
function addParserFailure(options, cause) {
|
|
139
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
140
|
+
options.diagnostics.add({
|
|
141
|
+
code: `mdx.frontmatter.${options.format}`,
|
|
142
|
+
message,
|
|
143
|
+
severity: "error",
|
|
144
|
+
span: options.span
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function yamlCode(code) {
|
|
148
|
+
return code === "RESOURCE_EXHAUSTION" ? "mdx.frontmatter.resource" : "mdx.frontmatter.yaml";
|
|
149
|
+
}
|
|
150
|
+
function relativeSpan(span, start, end) {
|
|
151
|
+
const length = span.end - span.start;
|
|
152
|
+
const relativeStart = Math.max(0, Math.min(start, length));
|
|
153
|
+
const relativeEnd = Math.max(relativeStart, Math.min(end, length));
|
|
154
|
+
return Object.freeze({
|
|
155
|
+
file: span.file,
|
|
156
|
+
start: span.start + relativeStart,
|
|
157
|
+
end: span.start + relativeEnd
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
function lineColumnOffset(source, line, column) {
|
|
161
|
+
const lineStart = lineStartOffsets(source)[Math.max(0, line - 1)] ?? source.length;
|
|
162
|
+
return Math.min(source.length, lineStart + Math.max(0, column - 1));
|
|
163
|
+
}
|
|
164
|
+
function propertyPath(path, key) {
|
|
165
|
+
return /^[A-Za-z_$][\w$]*$/u.test(key) ? `${path}.${key}` : `${path}[${JSON.stringify(key)}]`;
|
|
166
|
+
}
|
|
167
|
+
function describeValue(value) {
|
|
168
|
+
if (value === void 0) return "undefined";
|
|
169
|
+
if (isFunction(value)) return "function";
|
|
170
|
+
if (isSymbol(value)) return "symbol";
|
|
171
|
+
if (value instanceof Map) return "Map";
|
|
172
|
+
if (value instanceof Set) return "Set";
|
|
173
|
+
if (value instanceof Date) return "Date";
|
|
174
|
+
return isObject(value) ? value.constructor?.name ?? "object" : String(value);
|
|
175
|
+
}
|
|
176
|
+
function lineStartOffsets(source) {
|
|
177
|
+
const offsets = [0];
|
|
178
|
+
for (let index = 0; index < source.length; index++) if (source[index] === "\r") {
|
|
179
|
+
if (source[index + 1] === "\n") index++;
|
|
180
|
+
offsets.push(index + 1);
|
|
181
|
+
} else if (source[index] === "\n") offsets.push(index + 1);
|
|
182
|
+
return offsets;
|
|
183
|
+
}
|
|
184
|
+
//#endregion
|
|
185
|
+
export { decodeFrontmatter };
|
|
186
|
+
|
|
187
|
+
//# sourceMappingURL=frontmatter-decode.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter-decode.mjs","names":["parseToml"],"sources":["../src/frontmatter-decode.ts"],"sourcesContent":["import {\n isBoolean,\n isNumber,\n isString,\n isBigInt,\n isFunction,\n isSymbol,\n isObject,\n isPlainObject,\n} from \"@temelj/value\";\nimport { parse as parseToml, TomlDate, TomlError } from \"smol-toml\";\nimport { parseDocument } from \"yaml\";\n\nimport type { DiagnosticReporter } from \"./diagnostics.ts\";\nimport type { FrontmatterObject, FrontmatterTemporal, FrontmatterValue } from \"./model.ts\";\nimport type { SourceSpan } from \"./source.ts\";\nimport type { FrontmatterFormat } from \"./syntax-options.ts\";\n\ninterface DecodeOptions {\n readonly diagnostics: DiagnosticReporter;\n readonly format: FrontmatterFormat;\n readonly source: string;\n readonly span: SourceSpan;\n}\n\nconst maximumYamlAliases = 100;\n\nconst maximumTomlDepth = 256;\n\nexport function decodeFrontmatter(options: DecodeOptions): FrontmatterObject | undefined {\n return options.format === \"yaml\" ? decodeYaml(options) : decodeToml(options);\n}\n\nfunction decodeYaml(options: DecodeOptions): FrontmatterObject | undefined {\n let document: ReturnType<typeof parseDocument>;\n\n try {\n document = parseDocument(options.source, {\n customTags: [],\n intAsBigInt: true,\n logLevel: \"silent\",\n prettyErrors: false,\n resolveKnownTags: false,\n schema: \"core\",\n strict: true,\n stringKeys: true,\n uniqueKeys: true,\n version: \"1.2\",\n });\n } catch (cause) {\n addParserFailure(options, cause);\n\n return undefined;\n }\n\n for (const warning of document.warnings) {\n options.diagnostics.add({\n code: yamlCode(warning.code),\n message: warning.message,\n severity: \"warning\",\n span: relativeSpan(options.span, warning.pos[0], warning.pos[1]),\n });\n }\n\n for (const error of document.errors) {\n options.diagnostics.add({\n code: yamlCode(error.code),\n message: error.message,\n severity: \"error\",\n span: relativeSpan(options.span, error.pos[0], error.pos[1]),\n });\n }\n\n if (document.errors.length > 0) {\n return undefined;\n }\n\n let parsed: unknown;\n\n try {\n parsed = document.contents === null ? {} : document.toJS({ maxAliasCount: maximumYamlAliases });\n } catch (cause) {\n addParserFailure(options, cause);\n\n return undefined;\n }\n\n return convertRoot(parsed, options);\n}\n\nfunction decodeToml(options: DecodeOptions): FrontmatterObject | undefined {\n let parsed: unknown;\n\n try {\n parsed = parseToml(options.source, {\n integersAsBigInt: \"asNeeded\",\n maxDepth: maximumTomlDepth,\n });\n } catch (cause) {\n if (cause instanceof TomlError) {\n const offset = lineColumnOffset(options.source, cause.line, cause.column);\n options.diagnostics.add({\n code: \"mdx.frontmatter.toml\",\n message: cause.message,\n severity: \"error\",\n span: relativeSpan(options.span, offset, offset + 1),\n });\n } else {\n addParserFailure(options, cause);\n }\n\n return undefined;\n }\n\n return convertRoot(parsed, options);\n}\n\n// oxlint-disable-next-line anti-slop/no-unknown-parameters -- YAML/TOML root input is validated here.\nfunction convertRoot(value: unknown, options: DecodeOptions): FrontmatterObject | undefined {\n if (!isPlainObject(value)) {\n options.diagnostics.add({\n code: \"mdx.frontmatter.root\",\n message: \"FrontmatterNode must contain a mapping at its root\",\n severity: \"error\",\n span: options.span,\n });\n\n return undefined;\n }\n\n return convertObject(value, options, \"$\", new WeakSet<object>());\n}\n\nfunction convertValue(\n // oxlint-disable-next-line anti-slop/no-unknown-parameters -- Recursively validates parser values before producing FrontmatterValue.\n value: unknown,\n options: DecodeOptions,\n path: string,\n active: WeakSet<object>,\n): FrontmatterValue | undefined {\n if (value === null || isBoolean(value) || isNumber(value) || isString(value)) {\n return value;\n }\n\n if (isBigInt(value)) {\n return value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER)\n ? Number(value)\n : value;\n }\n\n if (value instanceof TomlDate) {\n return convertTemporal(value);\n }\n\n if (Array.isArray(value)) {\n if (active.has(value)) {\n return invalidValue(options, path, \"cyclic alias\");\n }\n\n active.add(value);\n const converted: FrontmatterValue[] = [];\n\n for (const [index, item] of value.entries()) {\n const result = convertValue(item, options, `${path}[${index}]`, active);\n\n if (result === undefined) {\n return undefined;\n }\n\n converted.push(result);\n }\n\n active.delete(value);\n Object.freeze(converted);\n\n return converted;\n }\n\n if (isPlainObject(value)) {\n return convertObject(value, options, path, active);\n }\n\n return invalidValue(options, path, describeValue(value));\n}\n\nfunction convertObject(\n // oxlint-disable-next-line anti-slop/no-object-parameters -- YAML/TOML mapping boundary; every entry is converted to FrontmatterValue below.\n value: object,\n options: DecodeOptions,\n path: string,\n active: WeakSet<object>,\n): FrontmatterObject | undefined {\n if (active.has(value)) {\n return invalidValue(options, path, \"cyclic alias\");\n }\n\n active.add(value);\n const converted: Record<string, FrontmatterValue> = {};\n\n for (const [key, item] of Object.entries(value)) {\n const itemPath = propertyPath(path, key);\n const result = convertValue(item, options, itemPath, active);\n\n if (result === undefined) {\n return undefined;\n }\n\n Object.defineProperty(converted, key, {\n configurable: false,\n enumerable: true,\n value: result,\n writable: false,\n });\n }\n\n active.delete(value);\n Object.freeze(converted);\n\n return converted;\n}\n\nfunction convertTemporal(value: TomlDate): FrontmatterTemporal {\n const type = value.isDateTime()\n ? value.isLocal()\n ? \"local-date-time\"\n : \"offset-date-time\"\n : value.isDate()\n ? \"local-date\"\n : \"local-time\";\n\n return Object.freeze({ kind: \"temporal\", type, value: value.toISOString() });\n}\n\nfunction invalidValue(options: DecodeOptions, path: string, description: string): undefined {\n options.diagnostics.add({\n code: \"mdx.frontmatter.value\",\n message: `Unsupported frontmatter value at ${path}: ${description}`,\n severity: \"error\",\n span: options.span,\n });\n\n return undefined;\n}\n\nfunction addParserFailure(options: DecodeOptions, cause: unknown): void {\n const message = cause instanceof Error ? cause.message : String(cause);\n options.diagnostics.add({\n code: `mdx.frontmatter.${options.format}`,\n message,\n severity: \"error\",\n span: options.span,\n });\n}\n\nfunction yamlCode(code: string): string {\n return code === \"RESOURCE_EXHAUSTION\" ? \"mdx.frontmatter.resource\" : \"mdx.frontmatter.yaml\";\n}\n\nfunction relativeSpan(span: SourceSpan, start: number, end: number): SourceSpan {\n const length = span.end - span.start;\n const relativeStart = Math.max(0, Math.min(start, length));\n const relativeEnd = Math.max(relativeStart, Math.min(end, length));\n\n return Object.freeze({\n file: span.file,\n start: span.start + relativeStart,\n end: span.start + relativeEnd,\n });\n}\n\nfunction lineColumnOffset(source: string, line: number, column: number): number {\n const lineStart = lineStartOffsets(source)[Math.max(0, line - 1)] ?? source.length;\n\n return Math.min(source.length, lineStart + Math.max(0, column - 1));\n}\n\nfunction propertyPath(path: string, key: string): string {\n return /^[A-Za-z_$][\\w$]*$/u.test(key) ? `${path}.${key}` : `${path}[${JSON.stringify(key)}]`;\n}\n\n// oxlint-disable-next-line anti-slop/no-unknown-parameters -- Describes a rejected value at the YAML/TOML validation boundary.\nfunction describeValue(value: unknown): string {\n if (value === undefined) {\n return \"undefined\";\n }\n\n if (isFunction(value)) {\n return \"function\";\n }\n\n if (isSymbol(value)) {\n return \"symbol\";\n }\n\n if (value instanceof Map) {\n return \"Map\";\n }\n\n if (value instanceof Set) {\n return \"Set\";\n }\n\n if (value instanceof Date) {\n return \"Date\";\n }\n\n return isObject(value) ? (value.constructor?.name ?? \"object\") : String(value);\n}\n\nfunction lineStartOffsets(source: string): readonly number[] {\n const offsets = [0];\n\n for (let index = 0; index < source.length; index++) {\n if (source[index] === \"\\r\") {\n if (source[index + 1] === \"\\n\") {\n index++;\n }\n\n offsets.push(index + 1);\n } else if (source[index] === \"\\n\") {\n offsets.push(index + 1);\n }\n }\n\n return offsets;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SourceRange } from "./ranges.mjs";
|
|
2
|
+
import { SourceFile } from "./source.mjs";
|
|
3
|
+
import { SchemaResult } from "@temelj/standard-schema";
|
|
4
|
+
//#region src/frontmatter-schema.d.ts
|
|
5
|
+
/** Converts Standard Schema failures to the shared frontmatter diagnostics. */
|
|
6
|
+
export declare function frontmatterSchemaValue<T>(result: SchemaResult<T>, file: SourceFile, origin: SourceRange | undefined): T;
|
|
7
|
+
//#endregion
|
|
8
|
+
//# sourceMappingURL=frontmatter-schema.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter-schema.d.mts","names":[],"sources":["../src/frontmatter-schema.ts"],"mappings":";;;;;wBAWgB,uBAAuB,GACrC,QAAQ,aAAa,IACrB,MAAM,YACN,QAAQ,0BACP"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createDiagnostic } from "./diagnostics.mjs";
|
|
2
|
+
import { FrontmatterError } from "./errors.mjs";
|
|
3
|
+
import { isObject } from "@temelj/value";
|
|
4
|
+
//#region src/frontmatter-schema.ts
|
|
5
|
+
/** Converts Standard Schema failures to the shared frontmatter diagnostics. */
|
|
6
|
+
function frontmatterSchemaValue(result, file, origin) {
|
|
7
|
+
if (result.issues !== void 0) {
|
|
8
|
+
const diagnostics = result.issues.map((issue) => createDiagnostic({
|
|
9
|
+
severity: "error",
|
|
10
|
+
code: "mdx.frontmatter.schema",
|
|
11
|
+
message: formatSchemaIssue(issue),
|
|
12
|
+
span: origin === void 0 ? void 0 : {
|
|
13
|
+
file,
|
|
14
|
+
...origin
|
|
15
|
+
}
|
|
16
|
+
}));
|
|
17
|
+
throw FrontmatterError.schemaValidationFailed(file, diagnostics, result.issues);
|
|
18
|
+
}
|
|
19
|
+
return result.value;
|
|
20
|
+
}
|
|
21
|
+
function formatSchemaIssue(issue) {
|
|
22
|
+
const path = issue.path?.map((part) => String(isObject(part) ? part.key : part)).join(".");
|
|
23
|
+
return path === void 0 || path.length === 0 ? issue.message : `${path}: ${issue.message}`;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { frontmatterSchemaValue };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=frontmatter-schema.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter-schema.mjs","names":[],"sources":["../src/frontmatter-schema.ts"],"sourcesContent":["import type { SchemaIssue, SchemaResult } from \"@temelj/standard-schema\";\n\nimport { isObject } from \"@temelj/value\";\n\nimport type { SourceRange } from \"./ranges.ts\";\nimport type { SourceFile } from \"./source.ts\";\n\nimport { createDiagnostic } from \"./diagnostics.ts\";\nimport { FrontmatterError } from \"./errors.ts\";\n\n/** Converts Standard Schema failures to the shared frontmatter diagnostics. */\nexport function frontmatterSchemaValue<T>(\n result: SchemaResult<T>,\n file: SourceFile,\n origin: SourceRange | undefined,\n): T {\n if (result.issues !== undefined) {\n const diagnostics = result.issues.map((issue) =>\n createDiagnostic({\n severity: \"error\",\n code: \"mdx.frontmatter.schema\",\n message: formatSchemaIssue(issue),\n span: origin === undefined ? undefined : { file, ...origin },\n }),\n );\n\n throw FrontmatterError.schemaValidationFailed(file, diagnostics, result.issues);\n }\n\n return result.value;\n}\n\nfunction formatSchemaIssue(issue: SchemaIssue): string {\n const path = issue.path?.map((part) => String(isObject(part) ? part.key : part)).join(\".\");\n\n return path === undefined || path.length === 0 ? issue.message : `${path}: ${issue.message}`;\n}\n"],"mappings":";;;;;AAWA,SAAgB,uBACd,QACA,MACA,QACG;CACH,IAAI,OAAO,WAAW,KAAA,GAAW;EAC/B,MAAM,cAAc,OAAO,OAAO,KAAK,UACrC,iBAAiB;GACf,UAAU;GACV,MAAM;GACN,SAAS,kBAAkB,KAAK;GAChC,MAAM,WAAW,KAAA,IAAY,KAAA,IAAY;IAAE;IAAM,GAAG;GAAO;EAC7D,CAAC,CACH;EAEA,MAAM,iBAAiB,uBAAuB,MAAM,aAAa,OAAO,MAAM;CAChF;CAEA,OAAO,OAAO;AAChB;AAEA,SAAS,kBAAkB,OAA4B;CACrD,MAAM,OAAO,MAAM,MAAM,KAAK,SAAS,OAAO,SAAS,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG;CAEzF,OAAO,SAAS,KAAA,KAAa,KAAK,WAAW,IAAI,MAAM,UAAU,GAAG,KAAK,IAAI,MAAM;AACrF"}
|
package/dist/frontmatter.d.mts
CHANGED
|
@@ -1,15 +1,40 @@
|
|
|
1
|
-
import { FrontmatterFormat } from "./syntax-options.mjs";
|
|
1
|
+
import { FrontmatterFormat, FrontmatterMode } from "./syntax-options.mjs";
|
|
2
2
|
import { FrontmatterObject } from "./model.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { SourceFile } from "./source.mjs";
|
|
4
|
+
import { Diagnostic } from "./diagnostics.mjs";
|
|
5
|
+
import { ParserLimits } from "./parser/config.mjs";
|
|
6
|
+
import { Schema, SchemaOutput } from "@temelj/standard-schema";
|
|
5
7
|
//#region src/frontmatter.d.ts
|
|
6
|
-
interface
|
|
7
|
-
|
|
8
|
-
readonly format
|
|
9
|
-
|
|
10
|
-
readonly
|
|
8
|
+
export interface FrontmatterParseOptions {
|
|
9
|
+
/** Formats to recognize. Defaults to both YAML and TOML. */
|
|
10
|
+
readonly format?: FrontmatterMode;
|
|
11
|
+
/** Limits the entire input length in UTF-16 code units, without scanning its body. */
|
|
12
|
+
readonly limits?: Pick<ParserLimits, "maximumSourceLength">;
|
|
11
13
|
}
|
|
12
|
-
export
|
|
14
|
+
export interface FrontmatterParseSchemaOptions<TSchema extends Schema> extends FrontmatterParseOptions {
|
|
15
|
+
readonly frontmatterSchema: TSchema;
|
|
16
|
+
}
|
|
17
|
+
export interface FrontmatterParseResult<T = FrontmatterObject> {
|
|
18
|
+
readonly file: SourceFile;
|
|
19
|
+
readonly frontmatter: T;
|
|
20
|
+
/** Undefined when no complete, enabled frontmatter block was found. */
|
|
21
|
+
readonly format: FrontmatterFormat | undefined;
|
|
22
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Reads only the opening frontmatter block and optionally validates its metadata.
|
|
26
|
+
* @throws {ParseError} Invalid YAML or TOML.
|
|
27
|
+
* @throws {FrontmatterError} Schema validation fails.
|
|
28
|
+
* @throws {LimitError | ConfigurationError} Invalid or exceeded source-length limit.
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseFrontmatter<TSchema extends Schema>(input: string | SourceFile, options: FrontmatterParseSchemaOptions<TSchema>): Promise<FrontmatterParseResult<SchemaOutput<TSchema>>>;
|
|
31
|
+
export declare function parseFrontmatter(input: string | SourceFile, options?: FrontmatterParseOptions): Promise<FrontmatterParseResult>;
|
|
32
|
+
/**
|
|
33
|
+
* Reads frontmatter synchronously, including synchronous schema validation.
|
|
34
|
+
* @throws {StandardSchemaAsyncValidationError} The schema returns a promise.
|
|
35
|
+
* @throws {ParseError | FrontmatterError | LimitError | ConfigurationError} Parsing fails.
|
|
36
|
+
*/
|
|
37
|
+
export declare function parseFrontmatterSync<TSchema extends Schema>(input: string | SourceFile, options: FrontmatterParseSchemaOptions<TSchema>): FrontmatterParseResult<SchemaOutput<TSchema>>;
|
|
38
|
+
export declare function parseFrontmatterSync(input: string | SourceFile, options?: FrontmatterParseOptions): FrontmatterParseResult;
|
|
13
39
|
//#endregion
|
|
14
|
-
export {};
|
|
15
40
|
//# sourceMappingURL=frontmatter.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frontmatter.d.mts","names":[],"sources":["../src/frontmatter.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"frontmatter.d.mts","names":[],"sources":["../src/frontmatter.ts"],"mappings":";;;;;;;iBAmBiB;;WAEN,SAAS;;WAET,SAAS,KAAK;;iBAGR,8BACf,gBAAgB,gBACR;WACC,mBAAmB;;iBAGb,uBAAuB,IAAI;WACjC,MAAM;WACN,aAAa;;WAEb,QAAQ;WACR,sBAAsB;;;;;;;;wBASjB,iBAAiB,gBAAgB,QAC/C,gBAAgB,YAChB,SAAS,8BAA8B,WACtC,QAAQ,uBAAuB,aAAa;wBAC/B,iBACd,gBAAgB,YAChB,UAAU,0BACT,QAAQ;;;;;;wBAwBK,qBAAqB,gBAAgB,QACnD,gBAAgB,YAChB,SAAS,8BAA8B,WACtC,uBAAuB,aAAa;wBACvB,qBACd,gBAAgB,YAChB,UAAU,0BACT"}
|