@intlayer/core 9.3.0 → 9.3.1
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 +24 -24
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +1 -2
- package/dist/cjs/deepTransformPlugins/getReplacedValuesContent.cjs +2 -1
- package/dist/cjs/deepTransformPlugins/getReplacedValuesContent.cjs.map +1 -1
- package/dist/cjs/deepTransformPlugins/insertContentInDictionary.cjs +41 -32
- package/dist/cjs/deepTransformPlugins/insertContentInDictionary.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/editDictionaryByKeyPath.cjs +6 -5
- package/dist/cjs/dictionaryManipulator/editDictionaryByKeyPath.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/mergeDictionaries.cjs +4 -3
- package/dist/cjs/dictionaryManipulator/mergeDictionaries.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/mergeQualifiedDictionaries.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/qualifiedDictionary.cjs +0 -1
- package/dist/cjs/dictionaryManipulator/qualifiedDictionary.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/qualifiedDictionary.test-d.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/removeContentNodeByKeyPath.cjs +4 -2
- package/dist/cjs/dictionaryManipulator/removeContentNodeByKeyPath.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/renameContentNodeByKeyPath.cjs +11 -9
- package/dist/cjs/dictionaryManipulator/renameContentNodeByKeyPath.cjs.map +1 -1
- package/dist/cjs/formatters/date.cjs +2 -1
- package/dist/cjs/formatters/date.cjs.map +1 -1
- package/dist/cjs/formatters/relativeTime.cjs +3 -3
- package/dist/cjs/formatters/relativeTime.cjs.map +1 -1
- package/dist/cjs/interpreter/getCondition.cjs +0 -1
- package/dist/cjs/interpreter/getCondition.cjs.map +1 -1
- package/dist/cjs/interpreter/getEnumeration.cjs +0 -1
- package/dist/cjs/interpreter/getEnumeration.cjs.map +1 -1
- package/dist/cjs/interpreter/getGender.cjs +0 -1
- package/dist/cjs/interpreter/getGender.cjs.map +1 -1
- package/dist/cjs/interpreter/getHTML.cjs +0 -1
- package/dist/cjs/interpreter/getHTML.cjs.map +1 -1
- package/dist/cjs/interpreter/getInsertion.cjs +0 -1
- package/dist/cjs/interpreter/getInsertion.cjs.map +1 -1
- package/dist/cjs/interpreter/getIntlayer.cjs.map +1 -1
- package/dist/cjs/interpreter/getIntlayer.test-d.cjs.map +1 -1
- package/dist/cjs/interpreter/getSelect.cjs +0 -1
- package/dist/cjs/interpreter/getSelect.cjs.map +1 -1
- package/dist/cjs/interpreter/getTranslation.cjs +0 -1
- package/dist/cjs/interpreter/getTranslation.cjs.map +1 -1
- package/dist/cjs/interpreter/splitAndJoinInsertion.cjs +0 -1
- package/dist/cjs/interpreter/splitAndJoinInsertion.cjs.map +1 -1
- package/dist/cjs/localization/domainUtils.cjs +0 -1
- package/dist/cjs/localization/domainUtils.cjs.map +1 -1
- package/dist/cjs/localization/getBrowserLocale.cjs +2 -1
- package/dist/cjs/localization/getBrowserLocale.cjs.map +1 -1
- package/dist/cjs/localization/getHTMLTextDir.cjs +0 -1
- package/dist/cjs/localization/getHTMLTextDir.cjs.map +1 -1
- package/dist/cjs/localization/getLocale.cjs +2 -1
- package/dist/cjs/localization/getLocale.cjs.map +1 -1
- package/dist/cjs/localization/getLocaleLang.cjs +0 -1
- package/dist/cjs/localization/getLocaleLang.cjs.map +1 -1
- package/dist/cjs/localization/localeDetector.cjs +2 -1
- package/dist/cjs/localization/localeDetector.cjs.map +1 -1
- package/dist/cjs/localization/proxyMode.cjs.map +1 -1
- package/dist/cjs/localization/rewriteUtils.cjs +0 -1
- package/dist/cjs/localization/rewriteUtils.cjs.map +1 -1
- package/dist/cjs/markdown/compiler.cjs +9 -6
- package/dist/cjs/markdown/compiler.cjs.map +1 -1
- package/dist/cjs/markdown/constants.cjs +0 -1
- package/dist/cjs/markdown/constants.cjs.map +1 -1
- package/dist/cjs/markdown/utils.cjs.map +1 -1
- package/dist/cjs/messageFormat/ICU.cjs +17 -14
- package/dist/cjs/messageFormat/ICU.cjs.map +1 -1
- package/dist/cjs/messageFormat/i18next.cjs +4 -2
- package/dist/cjs/messageFormat/i18next.cjs.map +1 -1
- package/dist/cjs/messageFormat/navigatePath.cjs +0 -1
- package/dist/cjs/messageFormat/navigatePath.cjs.map +1 -1
- package/dist/cjs/messageFormat/resolveMessage.cjs +2 -1
- package/dist/cjs/messageFormat/resolveMessage.cjs.map +1 -1
- package/dist/cjs/messageFormat/verify-icu-format.cjs +3 -2
- package/dist/cjs/messageFormat/verify-icu-format.cjs.map +1 -1
- package/dist/cjs/messageFormat/vue-i18n.cjs +2 -1
- package/dist/cjs/messageFormat/vue-i18n.cjs.map +1 -1
- package/dist/cjs/transpiler/condition/condition.cjs.map +1 -1
- package/dist/cjs/transpiler/enumeration/enumeration.cjs.map +1 -1
- package/dist/cjs/transpiler/file/file.cjs +2 -1
- package/dist/cjs/transpiler/file/file.cjs.map +1 -1
- package/dist/cjs/transpiler/file/fileBrowser.cjs +0 -1
- package/dist/cjs/transpiler/file/fileBrowser.cjs.map +1 -1
- package/dist/cjs/transpiler/gender/gender.cjs.map +1 -1
- package/dist/cjs/transpiler/html/getHTMLCustomComponents.cjs +0 -1
- package/dist/cjs/transpiler/html/getHTMLCustomComponents.cjs.map +1 -1
- package/dist/cjs/transpiler/html/html.cjs.map +1 -1
- package/dist/cjs/transpiler/html/htmlTags.cjs +0 -1
- package/dist/cjs/transpiler/html/htmlTags.cjs.map +1 -1
- package/dist/cjs/transpiler/html/validateHTML.cjs +12 -12
- package/dist/cjs/transpiler/html/validateHTML.cjs.map +1 -1
- package/dist/cjs/transpiler/insertion/getInsertionValues.cjs +0 -1
- package/dist/cjs/transpiler/insertion/getInsertionValues.cjs.map +1 -1
- package/dist/cjs/transpiler/insertion/insertion.cjs.map +1 -1
- package/dist/cjs/transpiler/markdown/getMarkdownMetadata.cjs +2 -1
- package/dist/cjs/transpiler/markdown/getMarkdownMetadata.cjs.map +1 -1
- package/dist/cjs/transpiler/markdown/markdown.cjs +2 -1
- package/dist/cjs/transpiler/markdown/markdown.cjs.map +1 -1
- package/dist/cjs/transpiler/markdown/validateMarkdown.cjs +7 -6
- package/dist/cjs/transpiler/markdown/validateMarkdown.cjs.map +1 -1
- package/dist/cjs/transpiler/nesting/nesting.cjs.map +1 -1
- package/dist/cjs/transpiler/plural/plural.cjs.map +1 -1
- package/dist/cjs/transpiler/select/select.cjs.map +1 -1
- package/dist/cjs/transpiler/translation/translation.cjs.map +1 -1
- package/dist/cjs/utils/checkIsURLAbsolute.cjs +0 -1
- package/dist/cjs/utils/checkIsURLAbsolute.cjs.map +1 -1
- package/dist/cjs/utils/cookieExpiry.cjs +0 -1
- package/dist/cjs/utils/cookieExpiry.cjs.map +1 -1
- package/dist/cjs/utils/getCookie.cjs +0 -1
- package/dist/cjs/utils/getCookie.cjs.map +1 -1
- package/dist/cjs/utils/isSameKeyPath.cjs +0 -1
- package/dist/cjs/utils/isSameKeyPath.cjs.map +1 -1
- package/dist/cjs/utils/isValidReactElement.cjs +0 -1
- package/dist/cjs/utils/isValidReactElement.cjs.map +1 -1
- package/dist/cjs/utils/parseYaml.cjs +0 -1
- package/dist/cjs/utils/parseYaml.cjs.map +1 -1
- package/dist/cjs/utils/stringifyYaml.cjs +0 -1
- package/dist/cjs/utils/stringifyYaml.cjs.map +1 -1
- package/dist/esm/deepTransformPlugins/getReplacedValuesContent.mjs +2 -1
- package/dist/esm/deepTransformPlugins/getReplacedValuesContent.mjs.map +1 -1
- package/dist/esm/deepTransformPlugins/insertContentInDictionary.mjs +41 -32
- package/dist/esm/deepTransformPlugins/insertContentInDictionary.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/editDictionaryByKeyPath.mjs +6 -5
- package/dist/esm/dictionaryManipulator/editDictionaryByKeyPath.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/mergeDictionaries.mjs +4 -3
- package/dist/esm/dictionaryManipulator/mergeDictionaries.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/removeContentNodeByKeyPath.mjs +4 -2
- package/dist/esm/dictionaryManipulator/removeContentNodeByKeyPath.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/renameContentNodeByKeyPath.mjs +11 -9
- package/dist/esm/dictionaryManipulator/renameContentNodeByKeyPath.mjs.map +1 -1
- package/dist/esm/formatters/date.mjs +2 -1
- package/dist/esm/formatters/date.mjs.map +1 -1
- package/dist/esm/formatters/relativeTime.mjs +3 -3
- package/dist/esm/formatters/relativeTime.mjs.map +1 -1
- package/dist/esm/localization/getBrowserLocale.mjs +2 -1
- package/dist/esm/localization/getBrowserLocale.mjs.map +1 -1
- package/dist/esm/localization/getLocale.mjs +2 -1
- package/dist/esm/localization/getLocale.mjs.map +1 -1
- package/dist/esm/localization/localeDetector.mjs +2 -1
- package/dist/esm/localization/localeDetector.mjs.map +1 -1
- package/dist/esm/markdown/compiler.mjs +9 -6
- package/dist/esm/markdown/compiler.mjs.map +1 -1
- package/dist/esm/markdown/utils.mjs.map +1 -1
- package/dist/esm/messageFormat/ICU.mjs +17 -14
- package/dist/esm/messageFormat/ICU.mjs.map +1 -1
- package/dist/esm/messageFormat/i18next.mjs +4 -2
- package/dist/esm/messageFormat/i18next.mjs.map +1 -1
- package/dist/esm/messageFormat/resolveMessage.mjs +2 -1
- package/dist/esm/messageFormat/resolveMessage.mjs.map +1 -1
- package/dist/esm/messageFormat/verify-icu-format.mjs +3 -2
- package/dist/esm/messageFormat/verify-icu-format.mjs.map +1 -1
- package/dist/esm/messageFormat/vue-i18n.mjs +2 -1
- package/dist/esm/messageFormat/vue-i18n.mjs.map +1 -1
- package/dist/esm/transpiler/file/file.mjs +2 -1
- package/dist/esm/transpiler/file/file.mjs.map +1 -1
- package/dist/esm/transpiler/html/validateHTML.mjs +12 -11
- package/dist/esm/transpiler/html/validateHTML.mjs.map +1 -1
- package/dist/esm/transpiler/markdown/getMarkdownMetadata.mjs +2 -1
- package/dist/esm/transpiler/markdown/getMarkdownMetadata.mjs.map +1 -1
- package/dist/esm/transpiler/markdown/markdown.mjs +2 -1
- package/dist/esm/transpiler/markdown/markdown.mjs.map +1 -1
- package/dist/esm/transpiler/markdown/validateMarkdown.mjs +7 -6
- package/dist/esm/transpiler/markdown/validateMarkdown.mjs.map +1 -1
- package/dist/esm/utils/parseYaml.mjs.map +1 -1
- package/package.json +6 -6
|
@@ -14,8 +14,9 @@ const fileContent = (path, callerDir, baseDir) => {
|
|
|
14
14
|
} else if (isRelativePath) filePath = resolve(callerDir, path);
|
|
15
15
|
else filePath = resolve(baseDir, path);
|
|
16
16
|
if (existsSync(filePath) && statSync(filePath).isFile()) try {
|
|
17
|
+
const content = readFileSync(filePath, "utf8");
|
|
17
18
|
return formatNodeType(FILE, path, {
|
|
18
|
-
content
|
|
19
|
+
content,
|
|
19
20
|
fixedPath: relative(baseDir, filePath)
|
|
20
21
|
});
|
|
21
22
|
} catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.mjs","names":["baseDir"],"sources":["../../../../src/transpiler/file/file.ts"],"sourcesContent":["import { existsSync, readFileSync, statSync } from 'node:fs';\nimport { dirname, isAbsolute, relative, resolve } from 'node:path';\nimport { colorizePath, getAppLogger } from '@intlayer/config/logger';\nimport type { TypedNodeModel } from '@intlayer/types/nodeType';\nimport { FILE, formatNodeType } from '@intlayer/types/nodeType';\n\nexport type FileContentConstructor<T extends Record<string, any> = {}> =\n TypedNodeModel<typeof FILE, string, T>;\n\nexport type FileContent = FileContentConstructor<{\n content: string;\n fixedPath?: string;\n}>;\n\nexport const fileContent = (\n path: string,\n callerDir: string,\n baseDir: string\n): FileContent => {\n const isRelativePath = path.startsWith('./') || path.startsWith('../');\n const appLogger = getAppLogger();\n\n let filePath: string;\n if (isAbsolute(path)) {\n appLogger(\n `Using absolute path for file is not recommended. Use relative paths instead. Path: ${path}, imported from: ${callerDir}`,\n { level: 'warn' }\n );\n filePath = path;\n } else if (isRelativePath) {\n filePath = resolve(callerDir, path);\n } else {\n filePath = resolve(baseDir, path);\n }\n\n if (existsSync(filePath) && statSync(filePath).isFile()) {\n try {\n const content = readFileSync(filePath, 'utf8');\n\n return formatNodeType(FILE, path, {\n content,\n fixedPath: relative(baseDir, filePath),\n });\n } catch {\n throw new Error(\n `Unable to read path: ${colorizePath(relative(baseDir, filePath))}`\n );\n }\n } else {\n throw new Error(\n `File not found: ${colorizePath(relative(baseDir, filePath))}`\n );\n }\n};\n\ntype GlobalIntlayerFilePath = {\n INTLAYER_FILE_PATH: string;\n INTLAYER_BASE_DIR: string;\n};\n\n/**\n * Function intended to be used to build intlayer dictionaries.\n *\n * Allow identify the usage of an external resource.\n *\n * Usage:\n *\n * ```ts\n * file('/path/to/file.md') // absolute path\n *\n * // or\n *\n * file('path/to/file.md') // relative path\n * ```\n */\nexport const file = (path: string): FileContent => {\n const { INTLAYER_FILE_PATH, INTLAYER_BASE_DIR } =\n globalThis as unknown as GlobalIntlayerFilePath;\n\n const callerDir = dirname(INTLAYER_FILE_PATH);\n const baseDir = INTLAYER_BASE_DIR;\n\n return fileContent(path, callerDir, baseDir);\n};\n"],"mappings":";;;;;;AAcA,MAAa,eACX,MACA,WACA,YACgB;CAChB,MAAM,iBAAiB,KAAK,WAAW,IAAI,KAAK,KAAK,WAAW,KAAK;CACrE,MAAM,YAAY,aAAa;CAE/B,IAAI;CACJ,IAAI,WAAW,IAAI,GAAG;EACpB,UACE,sFAAsF,KAAK,mBAAmB,aAC9G,EAAE,OAAO,OAAO,CAClB;EACA,WAAW;CACb,OAAO,IAAI,gBACT,WAAW,QAAQ,WAAW,IAAI;MAElC,WAAW,QAAQ,SAAS,IAAI;CAGlC,IAAI,WAAW,QAAQ,KAAK,SAAS,QAAQ,CAAC,CAAC,OAAO,GACpD,IAAI;
|
|
1
|
+
{"version":3,"file":"file.mjs","names":["baseDir"],"sources":["../../../../src/transpiler/file/file.ts"],"sourcesContent":["import { existsSync, readFileSync, statSync } from 'node:fs';\nimport { dirname, isAbsolute, relative, resolve } from 'node:path';\nimport { colorizePath, getAppLogger } from '@intlayer/config/logger';\nimport type { TypedNodeModel } from '@intlayer/types/nodeType';\nimport { FILE, formatNodeType } from '@intlayer/types/nodeType';\n\nexport type FileContentConstructor<T extends Record<string, any> = {}> =\n TypedNodeModel<typeof FILE, string, T>;\n\nexport type FileContent = FileContentConstructor<{\n content: string;\n fixedPath?: string;\n}>;\n\nexport const fileContent = (\n path: string,\n callerDir: string,\n baseDir: string\n): FileContent => {\n const isRelativePath = path.startsWith('./') || path.startsWith('../');\n const appLogger = getAppLogger();\n\n let filePath: string;\n if (isAbsolute(path)) {\n appLogger(\n `Using absolute path for file is not recommended. Use relative paths instead. Path: ${path}, imported from: ${callerDir}`,\n { level: 'warn' }\n );\n filePath = path;\n } else if (isRelativePath) {\n filePath = resolve(callerDir, path);\n } else {\n filePath = resolve(baseDir, path);\n }\n\n if (existsSync(filePath) && statSync(filePath).isFile()) {\n try {\n const content = readFileSync(filePath, 'utf8');\n\n return formatNodeType(FILE, path, {\n content,\n fixedPath: relative(baseDir, filePath),\n });\n } catch {\n throw new Error(\n `Unable to read path: ${colorizePath(relative(baseDir, filePath))}`\n );\n }\n } else {\n throw new Error(\n `File not found: ${colorizePath(relative(baseDir, filePath))}`\n );\n }\n};\n\ntype GlobalIntlayerFilePath = {\n INTLAYER_FILE_PATH: string;\n INTLAYER_BASE_DIR: string;\n};\n\n/**\n * Function intended to be used to build intlayer dictionaries.\n *\n * Allow identify the usage of an external resource.\n *\n * Usage:\n *\n * ```ts\n * file('/path/to/file.md') // absolute path\n *\n * // or\n *\n * file('path/to/file.md') // relative path\n * ```\n */\nexport const file = (path: string): FileContent => {\n const { INTLAYER_FILE_PATH, INTLAYER_BASE_DIR } =\n globalThis as unknown as GlobalIntlayerFilePath;\n\n const callerDir = dirname(INTLAYER_FILE_PATH);\n const baseDir = INTLAYER_BASE_DIR;\n\n return fileContent(path, callerDir, baseDir);\n};\n"],"mappings":";;;;;;AAcA,MAAa,eACX,MACA,WACA,YACgB;CAChB,MAAM,iBAAiB,KAAK,WAAW,IAAI,KAAK,KAAK,WAAW,KAAK;CACrE,MAAM,YAAY,aAAa;CAE/B,IAAI;CACJ,IAAI,WAAW,IAAI,GAAG;EACpB,UACE,sFAAsF,KAAK,mBAAmB,aAC9G,EAAE,OAAO,OAAO,CAClB;EACA,WAAW;CACb,OAAO,IAAI,gBACT,WAAW,QAAQ,WAAW,IAAI;MAElC,WAAW,QAAQ,SAAS,IAAI;CAGlC,IAAI,WAAW,QAAQ,KAAK,SAAS,QAAQ,CAAC,CAAC,OAAO,GACpD,IAAI;EACF,MAAM,UAAU,aAAa,UAAU,MAAM;EAE7C,OAAO,eAAe,MAAM,MAAM;GAChC;GACA,WAAW,SAAS,SAAS,QAAQ;EACvC,CAAC;CACH,QAAQ;EACN,MAAM,IAAI,MACR,wBAAwB,aAAa,SAAS,SAAS,QAAQ,CAAC,GAClE;CACF;MAEA,MAAM,IAAI,MACR,mBAAmB,aAAa,SAAS,SAAS,QAAQ,CAAC,GAC7D;AAEJ;;;;;;;;;;;;;;;;AAsBA,MAAa,QAAQ,SAA8B;CACjD,MAAM,EAAE,oBAAoB,sBAC1B;CAEF,MAAM,YAAY,QAAQ,kBAAkB;CAG5C,OAAO,YAAY,MAAM,WAAWA,iBAAO;AAC7C"}
|
|
@@ -31,19 +31,20 @@ const validateHTML = (content) => {
|
|
|
31
31
|
const attrs = match[3];
|
|
32
32
|
const isSelfClosing = !!match[4];
|
|
33
33
|
if (attrs.trimStart().startsWith("://") || attrs.trimStart().startsWith(":")) continue;
|
|
34
|
-
if (isClosing)
|
|
35
|
-
|
|
36
|
-
message: `Closing tag </${tagName}> has no matching opening tag`
|
|
37
|
-
});
|
|
38
|
-
else {
|
|
39
|
-
const last = stack[stack.length - 1];
|
|
40
|
-
if (last.tag.toLowerCase() !== tagName.toLowerCase()) issues.push({
|
|
34
|
+
if (isClosing) {
|
|
35
|
+
if (stack.length === 0) issues.push({
|
|
41
36
|
type: "error",
|
|
42
|
-
message: `
|
|
37
|
+
message: `Closing tag </${tagName}> has no matching opening tag`
|
|
43
38
|
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
else {
|
|
40
|
+
const last = stack[stack.length - 1];
|
|
41
|
+
if (last.tag.toLowerCase() !== tagName.toLowerCase()) issues.push({
|
|
42
|
+
type: "error",
|
|
43
|
+
message: `Mismatched closing tag: expected </${last.tag}> but found </${tagName}>`
|
|
44
|
+
});
|
|
45
|
+
stack.pop();
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
47
48
|
const isVoidElement = VOID_HTML_ELEMENTS.has(tagName.toLowerCase());
|
|
48
49
|
if (!isSelfClosing && !isVoidElement) stack.push({ tag: tagName });
|
|
49
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateHTML.mjs","names":[],"sources":["../../../../src/transpiler/html/validateHTML.ts"],"sourcesContent":["export const VOID_HTML_ELEMENTS = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'source',\n 'track',\n 'wbr',\n]);\n\nexport type HTMLValidationIssue = {\n type: 'error' | 'warning';\n message: string;\n};\n\nexport type HTMLValidationResult = {\n valid: boolean;\n issues: HTMLValidationIssue[];\n};\n\n// Matches HTML tags: <Tag ...>, </Tag>, or <Tag ... />\n// Attributes may span multiple lines but NOT blank lines (two consecutive newlines),\n// which prevents matching blockquote `>` markers as tag closers.\n// Groups: 1: closing slash, 2: tag name, 3: attributes, 4: self-closing slash\nconst TAG_REGEX =\n /<(\\/)?([a-zA-Z][a-zA-Z0-9.-]*)\\s*((?:[^\\n]|\\n(?!\\n))*?)(\\/?)>/g;\n\n/**\n * Validates that HTML tags in `content` are properly opened, nested, and closed.\n * Returns structured issues instead of logging to the console.\n *\n * False-positive exclusions:\n * - Tags whose attribute string starts with `://` are URL autolinks (e.g. `<https://…>`).\n */\nexport const validateHTML = (content: string): HTMLValidationResult => {\n const issues: HTMLValidationIssue[] = [];\n const stack: Array<{ tag: string }> = [];\n\n for (const match of content.matchAll(TAG_REGEX)) {\n const isClosing = !!match[1];\n const tagName = match[2];\n const attrs = match[3];\n const isSelfClosing = !!match[4];\n\n // Skip URL autolinks like <https://example.com> or <mailto:user@example.com>\n if (\n attrs.trimStart().startsWith('://') ||\n attrs.trimStart().startsWith(':')\n ) {\n continue;\n }\n\n if (isClosing) {\n if (stack.length === 0) {\n issues.push({\n type: 'error',\n message: `Closing tag </${tagName}> has no matching opening tag`,\n });\n } else {\n const last = stack[stack.length - 1];\n if (last.tag.toLowerCase() !== tagName.toLowerCase()) {\n issues.push({\n type: 'error',\n message: `Mismatched closing tag: expected </${last.tag}> but found </${tagName}>`,\n });\n }\n stack.pop();\n }\n } else {\n const isVoidElement = VOID_HTML_ELEMENTS.has(tagName.toLowerCase());\n if (!isSelfClosing && !isVoidElement) {\n stack.push({ tag: tagName });\n }\n }\n }\n\n for (const unclosed of stack) {\n issues.push({\n type: 'error',\n message: `Unclosed HTML tag: <${unclosed.tag}>`,\n });\n }\n\n return {\n valid: issues.filter((i) => i.type === 'error').length === 0,\n issues,\n };\n};\n"],"mappings":";AAAA,MAAa,qCAAqB,IAAI,IAAI;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAgBD,MAAM,YACJ;;;;;;;;AASF,MAAa,gBAAgB,YAA0C;CACrE,MAAM,SAAgC,CAAC;CACvC,MAAM,QAAgC,CAAC;CAEvC,KAAK,MAAM,SAAS,QAAQ,SAAS,SAAS,GAAG;EAC/C,MAAM,YAAY,CAAC,CAAC,MAAM;EAC1B,MAAM,UAAU,MAAM;EACtB,MAAM,QAAQ,MAAM;EACpB,MAAM,gBAAgB,CAAC,CAAC,MAAM;EAG9B,IACE,MAAM,UAAU,CAAC,CAAC,WAAW,KAAK,KAClC,MAAM,UAAU,CAAC,CAAC,WAAW,GAAG,GAEhC;EAGF,IAAI,
|
|
1
|
+
{"version":3,"file":"validateHTML.mjs","names":[],"sources":["../../../../src/transpiler/html/validateHTML.ts"],"sourcesContent":["export const VOID_HTML_ELEMENTS = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'source',\n 'track',\n 'wbr',\n]);\n\nexport type HTMLValidationIssue = {\n type: 'error' | 'warning';\n message: string;\n};\n\nexport type HTMLValidationResult = {\n valid: boolean;\n issues: HTMLValidationIssue[];\n};\n\n// Matches HTML tags: <Tag ...>, </Tag>, or <Tag ... />\n// Attributes may span multiple lines but NOT blank lines (two consecutive newlines),\n// which prevents matching blockquote `>` markers as tag closers.\n// Groups: 1: closing slash, 2: tag name, 3: attributes, 4: self-closing slash\nconst TAG_REGEX =\n /<(\\/)?([a-zA-Z][a-zA-Z0-9.-]*)\\s*((?:[^\\n]|\\n(?!\\n))*?)(\\/?)>/g;\n\n/**\n * Validates that HTML tags in `content` are properly opened, nested, and closed.\n * Returns structured issues instead of logging to the console.\n *\n * False-positive exclusions:\n * - Tags whose attribute string starts with `://` are URL autolinks (e.g. `<https://…>`).\n */\nexport const validateHTML = (content: string): HTMLValidationResult => {\n const issues: HTMLValidationIssue[] = [];\n const stack: Array<{ tag: string }> = [];\n\n for (const match of content.matchAll(TAG_REGEX)) {\n const isClosing = !!match[1];\n const tagName = match[2];\n const attrs = match[3];\n const isSelfClosing = !!match[4];\n\n // Skip URL autolinks like <https://example.com> or <mailto:user@example.com>\n if (\n attrs.trimStart().startsWith('://') ||\n attrs.trimStart().startsWith(':')\n ) {\n continue;\n }\n\n if (isClosing) {\n if (stack.length === 0) {\n issues.push({\n type: 'error',\n message: `Closing tag </${tagName}> has no matching opening tag`,\n });\n } else {\n const last = stack[stack.length - 1];\n if (last.tag.toLowerCase() !== tagName.toLowerCase()) {\n issues.push({\n type: 'error',\n message: `Mismatched closing tag: expected </${last.tag}> but found </${tagName}>`,\n });\n }\n stack.pop();\n }\n } else {\n const isVoidElement = VOID_HTML_ELEMENTS.has(tagName.toLowerCase());\n if (!isSelfClosing && !isVoidElement) {\n stack.push({ tag: tagName });\n }\n }\n }\n\n for (const unclosed of stack) {\n issues.push({\n type: 'error',\n message: `Unclosed HTML tag: <${unclosed.tag}>`,\n });\n }\n\n return {\n valid: issues.filter((i) => i.type === 'error').length === 0,\n issues,\n };\n};\n"],"mappings":";AAAA,MAAa,qCAAqB,IAAI,IAAI;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAgBD,MAAM,YACJ;;;;;;;;AASF,MAAa,gBAAgB,YAA0C;CACrE,MAAM,SAAgC,CAAC;CACvC,MAAM,QAAgC,CAAC;CAEvC,KAAK,MAAM,SAAS,QAAQ,SAAS,SAAS,GAAG;EAC/C,MAAM,YAAY,CAAC,CAAC,MAAM;EAC1B,MAAM,UAAU,MAAM;EACtB,MAAM,QAAQ,MAAM;EACpB,MAAM,gBAAgB,CAAC,CAAC,MAAM;EAG9B,IACE,MAAM,UAAU,CAAC,CAAC,WAAW,KAAK,KAClC,MAAM,UAAU,CAAC,CAAC,WAAW,GAAG,GAEhC;EAGF,IAAI,WAAW;GACb,IAAI,MAAM,WAAW,GACnB,OAAO,KAAK;IACV,MAAM;IACN,SAAS,iBAAiB,QAAQ;GACpC,CAAC;QACI;IACL,MAAM,OAAO,MAAM,MAAM,SAAS;IAClC,IAAI,KAAK,IAAI,YAAY,MAAM,QAAQ,YAAY,GACjD,OAAO,KAAK;KACV,MAAM;KACN,SAAS,sCAAsC,KAAK,IAAI,gBAAgB,QAAQ;IAClF,CAAC;IAEH,MAAM,IAAI;GACZ;EACF,OAAO;GACL,MAAM,gBAAgB,mBAAmB,IAAI,QAAQ,YAAY,CAAC;GAClE,IAAI,CAAC,iBAAiB,CAAC,eACrB,MAAM,KAAK,EAAE,KAAK,QAAQ,CAAC;EAE/B;CACF;CAEA,KAAK,MAAM,YAAY,OACrB,OAAO,KAAK;EACV,MAAM;EACN,SAAS,uBAAuB,SAAS,IAAI;CAC/C,CAAC;CAGH,OAAO;EACL,OAAO,OAAO,QAAQ,MAAM,EAAE,SAAS,OAAO,CAAC,CAAC,WAAW;EAC3D;CACF;AACF"}
|
|
@@ -11,7 +11,8 @@ const getMarkdownMetadata = (markdown) => {
|
|
|
11
11
|
break;
|
|
12
12
|
}
|
|
13
13
|
if (metadataEndIndex === -1) return {};
|
|
14
|
-
|
|
14
|
+
const metadataContent = lines.slice(1, metadataEndIndex).join("\n");
|
|
15
|
+
return parseYaml(metadataContent) ?? {};
|
|
15
16
|
} catch {
|
|
16
17
|
return {};
|
|
17
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getMarkdownMetadata.mjs","names":[],"sources":["../../../../src/transpiler/markdown/getMarkdownMetadata.ts"],"sourcesContent":["import { parseYaml } from '../../utils/parseYaml';\n\nexport const getMarkdownMetadata = <T extends Record<string, any>>(\n markdown: string\n): T => {\n try {\n const lines = markdown.split(/\\r?\\n/);\n\n // Check if the very first non-empty line is the metadata start delimiter.\n const firstNonEmptyLine = lines.find((line) => line.trim() !== '');\n\n if (firstNonEmptyLine?.trim() !== '---') {\n const result: T = {} as T;\n return result;\n }\n\n // Find the end of the metadata block\n let metadataEndIndex = -1;\n for (let i = 1; i < lines.length; i++) {\n if (lines[i]?.trim() === '---') {\n metadataEndIndex = i;\n break;\n }\n }\n\n if (metadataEndIndex === -1) {\n // No closing delimiter found\n const result: T = {} as T;\n return result;\n }\n\n // Extract the metadata content between the delimiters\n const metadataLines = lines.slice(1, metadataEndIndex);\n const metadataContent = metadataLines.join('\\n');\n\n // Use the improved parseYaml function to parse the entire metadata block\n const metadata = parseYaml<T>(metadataContent);\n\n return metadata ?? ({} as T);\n } catch {\n const result: T = {} as T;\n return result;\n }\n};\n"],"mappings":";;;AAEA,MAAa,uBACX,aACM;CACN,IAAI;EACF,MAAM,QAAQ,SAAS,MAAM,OAAO;EAKpC,IAF0B,MAAM,MAAM,SAAS,KAAK,KAAK,MAAM,EAE3C,CAAC,EAAE,KAAK,MAAM,OAEhC,OAAO,CAAK;EAId,IAAI,mBAAmB;EACvB,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAChC,IAAI,MAAM,EAAE,EAAE,KAAK,MAAM,OAAO;GAC9B,mBAAmB;GACnB;EACF;EAGF,IAAI,qBAAqB,IAGvB,OAAO,CAAK;
|
|
1
|
+
{"version":3,"file":"getMarkdownMetadata.mjs","names":[],"sources":["../../../../src/transpiler/markdown/getMarkdownMetadata.ts"],"sourcesContent":["import { parseYaml } from '../../utils/parseYaml';\n\nexport const getMarkdownMetadata = <T extends Record<string, any>>(\n markdown: string\n): T => {\n try {\n const lines = markdown.split(/\\r?\\n/);\n\n // Check if the very first non-empty line is the metadata start delimiter.\n const firstNonEmptyLine = lines.find((line) => line.trim() !== '');\n\n if (firstNonEmptyLine?.trim() !== '---') {\n const result: T = {} as T;\n return result;\n }\n\n // Find the end of the metadata block\n let metadataEndIndex = -1;\n for (let i = 1; i < lines.length; i++) {\n if (lines[i]?.trim() === '---') {\n metadataEndIndex = i;\n break;\n }\n }\n\n if (metadataEndIndex === -1) {\n // No closing delimiter found\n const result: T = {} as T;\n return result;\n }\n\n // Extract the metadata content between the delimiters\n const metadataLines = lines.slice(1, metadataEndIndex);\n const metadataContent = metadataLines.join('\\n');\n\n // Use the improved parseYaml function to parse the entire metadata block\n const metadata = parseYaml<T>(metadataContent);\n\n return metadata ?? ({} as T);\n } catch {\n const result: T = {} as T;\n return result;\n }\n};\n"],"mappings":";;;AAEA,MAAa,uBACX,aACM;CACN,IAAI;EACF,MAAM,QAAQ,SAAS,MAAM,OAAO;EAKpC,IAF0B,MAAM,MAAM,SAAS,KAAK,KAAK,MAAM,EAE3C,CAAC,EAAE,KAAK,MAAM,OAEhC,OAAO,CAAK;EAId,IAAI,mBAAmB;EACvB,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAChC,IAAI,MAAM,EAAE,EAAE,KAAK,MAAM,OAAO;GAC9B,mBAAmB;GACnB;EACF;EAGF,IAAI,qBAAqB,IAGvB,OAAO,CAAK;EAKd,MAAM,kBADgB,MAAM,MAAM,GAAG,gBACD,CAAC,CAAC,KAAK,IAAI;EAK/C,OAFiB,UAAa,eAEhB,KAAM,CAAC;CACvB,QAAQ;EAEN,OAAO,CAAK;CACd;AACF"}
|
|
@@ -24,7 +24,8 @@ const awaitContent = async (content) => {
|
|
|
24
24
|
*/
|
|
25
25
|
const markdown = (content, components) => {
|
|
26
26
|
const metadata = async () => {
|
|
27
|
-
const
|
|
27
|
+
const awaitedContent = await awaitContent(content);
|
|
28
|
+
const flatContent = getContent(awaitedContent, {
|
|
28
29
|
dictionaryKey: "",
|
|
29
30
|
keyPath: []
|
|
30
31
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.mjs","names":[],"sources":["../../../../src/transpiler/markdown/markdown.ts"],"sourcesContent":["import type { TypedNodeModel } from '@intlayer/types/nodeType';\nimport { formatNodeType, MARKDOWN } from '@intlayer/types/nodeType';\nimport { getContent } from '../../interpreter/getContent/getContent';\nimport { getHTMLCustomComponents } from '../html/getHTMLCustomComponents';\nimport { getMarkdownMetadata } from './getMarkdownMetadata';\nimport { validateMarkdown } from './validateMarkdown';\n\ntype PropsType = 'number' | 'string' | 'node';\n\ntype ComponentName = string;\n\nexport type MarkdownContentConstructor<\n T extends Record<string, any> = {},\n Content = unknown,\n> = TypedNodeModel<typeof MARKDOWN, Content, T>;\n\nexport type MarkdownContent<\n Content = unknown,\n Components extends Record<ComponentName, PropsType> = Record<\n ComponentName,\n PropsType\n >,\n> = MarkdownContentConstructor<\n {\n metadata?: Record<string, any>;\n tags?: string[] | Components;\n },\n Content\n>;\n\nconst awaitContent = async (content: any) => {\n if (typeof content === 'string' || typeof content === 'object') {\n return content as any;\n }\n\n if (typeof content === 'function') {\n return content();\n }\n if (typeof content.then === 'function') {\n return await content;\n }\n};\n\n/**\n * Function intended to be used to build intlayer dictionaries.\n *\n * Allow to pick a content based on a quantity.\n *\n * Usage:\n *\n * ```ts\n * markdown('## Hello world!');\n * ```\n *\n */\nconst markdown = <\n Components extends Record<string, any> = Record<string, any>,\n Content = unknown,\n>(\n content: Content,\n components?: Components\n): MarkdownContent<Content, Components> => {\n const metadata = async () => {\n const awaitedContent = await awaitContent(content);\n\n const flatContent = getContent(awaitedContent, {\n dictionaryKey: '',\n keyPath: [],\n });\n\n if (typeof flatContent === 'string') {\n if (process.env.NODE_ENV !== 'production') {\n const { issues } = validateMarkdown(flatContent);\n for (const issue of issues) {\n if (issue.type === 'error') {\n console.error(`[intlayer/markdown] ${issue.message}`);\n } else {\n console.warn(`[intlayer/markdown] ${issue.message}`);\n }\n }\n }\n\n return getMarkdownMetadata(flatContent);\n }\n };\n\n const getComponents = () => {\n if (components) {\n return components;\n }\n\n if (typeof content === 'string') {\n return getHTMLCustomComponents(content);\n }\n\n let stringContent: any;\n\n if (typeof content === 'function') {\n stringContent = content();\n } else if (typeof (content as Promise<string>).then === 'function') {\n stringContent = async () =>\n getHTMLCustomComponents((await (content as Promise<string>)) as string);\n }\n\n if (typeof stringContent === 'string') {\n return getHTMLCustomComponents(stringContent);\n }\n\n try {\n return getHTMLCustomComponents(JSON.stringify(content));\n } catch (_e) {\n return [];\n }\n };\n\n return formatNodeType(MARKDOWN, content, {\n metadata,\n tags: getComponents(),\n });\n};\n\nexport { markdown as md };\n"],"mappings":";;;;;;;AA8BA,MAAM,eAAe,OAAO,YAAiB;CAC3C,IAAI,OAAO,YAAY,YAAY,OAAO,YAAY,UACpD,OAAO;CAGT,IAAI,OAAO,YAAY,YACrB,OAAO,QAAQ;CAEjB,IAAI,OAAO,QAAQ,SAAS,YAC1B,OAAO,MAAM;AAEjB;;;;;;;;;;;;;AAcA,MAAM,YAIJ,SACA,eACyC;CACzC,MAAM,WAAW,YAAY;
|
|
1
|
+
{"version":3,"file":"markdown.mjs","names":[],"sources":["../../../../src/transpiler/markdown/markdown.ts"],"sourcesContent":["import type { TypedNodeModel } from '@intlayer/types/nodeType';\nimport { formatNodeType, MARKDOWN } from '@intlayer/types/nodeType';\nimport { getContent } from '../../interpreter/getContent/getContent';\nimport { getHTMLCustomComponents } from '../html/getHTMLCustomComponents';\nimport { getMarkdownMetadata } from './getMarkdownMetadata';\nimport { validateMarkdown } from './validateMarkdown';\n\ntype PropsType = 'number' | 'string' | 'node';\n\ntype ComponentName = string;\n\nexport type MarkdownContentConstructor<\n T extends Record<string, any> = {},\n Content = unknown,\n> = TypedNodeModel<typeof MARKDOWN, Content, T>;\n\nexport type MarkdownContent<\n Content = unknown,\n Components extends Record<ComponentName, PropsType> = Record<\n ComponentName,\n PropsType\n >,\n> = MarkdownContentConstructor<\n {\n metadata?: Record<string, any>;\n tags?: string[] | Components;\n },\n Content\n>;\n\nconst awaitContent = async (content: any) => {\n if (typeof content === 'string' || typeof content === 'object') {\n return content as any;\n }\n\n if (typeof content === 'function') {\n return content();\n }\n if (typeof content.then === 'function') {\n return await content;\n }\n};\n\n/**\n * Function intended to be used to build intlayer dictionaries.\n *\n * Allow to pick a content based on a quantity.\n *\n * Usage:\n *\n * ```ts\n * markdown('## Hello world!');\n * ```\n *\n */\nconst markdown = <\n Components extends Record<string, any> = Record<string, any>,\n Content = unknown,\n>(\n content: Content,\n components?: Components\n): MarkdownContent<Content, Components> => {\n const metadata = async () => {\n const awaitedContent = await awaitContent(content);\n\n const flatContent = getContent(awaitedContent, {\n dictionaryKey: '',\n keyPath: [],\n });\n\n if (typeof flatContent === 'string') {\n if (process.env.NODE_ENV !== 'production') {\n const { issues } = validateMarkdown(flatContent);\n for (const issue of issues) {\n if (issue.type === 'error') {\n console.error(`[intlayer/markdown] ${issue.message}`);\n } else {\n console.warn(`[intlayer/markdown] ${issue.message}`);\n }\n }\n }\n\n return getMarkdownMetadata(flatContent);\n }\n };\n\n const getComponents = () => {\n if (components) {\n return components;\n }\n\n if (typeof content === 'string') {\n return getHTMLCustomComponents(content);\n }\n\n let stringContent: any;\n\n if (typeof content === 'function') {\n stringContent = content();\n } else if (typeof (content as Promise<string>).then === 'function') {\n stringContent = async () =>\n getHTMLCustomComponents((await (content as Promise<string>)) as string);\n }\n\n if (typeof stringContent === 'string') {\n return getHTMLCustomComponents(stringContent);\n }\n\n try {\n return getHTMLCustomComponents(JSON.stringify(content));\n } catch (_e) {\n return [];\n }\n };\n\n return formatNodeType(MARKDOWN, content, {\n metadata,\n tags: getComponents(),\n });\n};\n\nexport { markdown as md };\n"],"mappings":";;;;;;;AA8BA,MAAM,eAAe,OAAO,YAAiB;CAC3C,IAAI,OAAO,YAAY,YAAY,OAAO,YAAY,UACpD,OAAO;CAGT,IAAI,OAAO,YAAY,YACrB,OAAO,QAAQ;CAEjB,IAAI,OAAO,QAAQ,SAAS,YAC1B,OAAO,MAAM;AAEjB;;;;;;;;;;;;;AAcA,MAAM,YAIJ,SACA,eACyC;CACzC,MAAM,WAAW,YAAY;EAC3B,MAAM,iBAAiB,MAAM,aAAa,OAAO;EAEjD,MAAM,cAAc,WAAW,gBAAgB;GAC7C,eAAe;GACf,SAAS,CAAC;EACZ,CAAC;EAED,IAAI,OAAO,gBAAgB,UAAU;GACQ;IACzC,MAAM,EAAE,WAAW,iBAAiB,WAAW;IAC/C,KAAK,MAAM,SAAS,QAClB,IAAI,MAAM,SAAS,SACjB,QAAQ,MAAM,uBAAuB,MAAM,SAAS;SAEpD,QAAQ,KAAK,uBAAuB,MAAM,SAAS;GAGzD;GAEA,OAAO,oBAAoB,WAAW;EACxC;CACF;CAEA,MAAM,sBAAsB;EAC1B,IAAI,YACF,OAAO;EAGT,IAAI,OAAO,YAAY,UACrB,OAAO,wBAAwB,OAAO;EAGxC,IAAI;EAEJ,IAAI,OAAO,YAAY,YACrB,gBAAgB,QAAQ;OACnB,IAAI,OAAQ,QAA4B,SAAS,YACtD,gBAAgB,YACd,wBAAyB,MAAO,OAAsC;EAG1E,IAAI,OAAO,kBAAkB,UAC3B,OAAO,wBAAwB,aAAa;EAG9C,IAAI;GACF,OAAO,wBAAwB,KAAK,UAAU,OAAO,CAAC;EACxD,SAAS,IAAI;GACX,OAAO,CAAC;EACV;CACF;CAEA,OAAO,eAAe,UAAU,SAAS;EACvC;EACA,MAAM,cAAc;CACtB,CAAC;AACH"}
|
|
@@ -12,12 +12,13 @@ const stripCode = (content) => {
|
|
|
12
12
|
let openFence = null;
|
|
13
13
|
for (const line of lines) {
|
|
14
14
|
const fence = line.match(/^[\s>]*(`{3,}|~{3,})/);
|
|
15
|
-
if (!inCodeBlock)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
if (!inCodeBlock) {
|
|
16
|
+
if (fence?.[1]) {
|
|
17
|
+
inCodeBlock = true;
|
|
18
|
+
openFence = fence[1];
|
|
19
|
+
result.push("");
|
|
20
|
+
} else result.push(line.replace(/(`+)(?:(?!\1).)+?\1/g, (m) => " ".repeat(m.length)));
|
|
21
|
+
} else {
|
|
21
22
|
if (fence?.[1]?.[0] && fence[1][0] === openFence[0] && fence[1].length >= openFence.length) {
|
|
22
23
|
inCodeBlock = false;
|
|
23
24
|
openFence = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateMarkdown.mjs","names":[],"sources":["../../../../src/transpiler/markdown/validateMarkdown.ts"],"sourcesContent":["import { type HTMLValidationIssue, validateHTML } from '../html/validateHTML';\n\nexport type { HTMLValidationIssue as MarkdownValidationIssue } from '../html/validateHTML';\n\nexport type MarkdownValidationResult = {\n valid: boolean;\n issues: HTMLValidationIssue[];\n};\n\n/**\n * Strips fenced code blocks and inline code from markdown content so that\n * HTML-like syntax inside code is not mistakenly validated.\n */\nconst stripCode = (content: string): string => {\n const lines = content.split('\\n');\n const result: string[] = [];\n let inCodeBlock = false;\n let openFence: string | null = null;\n\n for (const line of lines) {\n // Allow leading whitespace and blockquote markers before the fence characters\n const fence = line.match(/^[\\s>]*(`{3,}|~{3,})/);\n if (!inCodeBlock) {\n if (fence?.[1]) {\n inCodeBlock = true;\n openFence = fence[1];\n result.push('');\n } else {\n // Also strip inline code spans on this line. Code spans may be\n // delimited by a run of one or more backticks and end with a matching\n // run of the same length (CommonMark), allowing shorter backtick runs\n // inside (e.g. `` t`Hello ${name}` ``).\n result.push(\n line.replace(/(`+)(?:(?!\\1).)+?\\1/g, (m) => ' '.repeat(m.length))\n );\n }\n } else {\n if (\n fence?.[1]?.[0] &&\n fence[1][0] === openFence![0] &&\n fence[1].length >= openFence!.length\n ) {\n inCodeBlock = false;\n openFence = null;\n }\n result.push('');\n }\n }\n\n return result.join('\\n');\n};\n\nconst validateCodeBlocks = (content: string): HTMLValidationIssue[] => {\n const issues: HTMLValidationIssue[] = [];\n const lines = content.split('\\n');\n let inCodeBlock = false;\n let openFence: string | null = null;\n let openLineNumber = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Allow leading whitespace and blockquote markers before the fence characters\n const fence = line?.match(/^[\\s>]*(`{3,}|~{3,})/);\n\n if (!inCodeBlock) {\n if (fence?.[1]) {\n inCodeBlock = true;\n openFence = fence[1];\n openLineNumber = i + 1;\n }\n } else {\n if (\n fence?.[1] &&\n fence[1][0] === openFence![0] &&\n fence[1].length >= openFence!.length\n ) {\n inCodeBlock = false;\n openFence = null;\n }\n }\n }\n\n if (inCodeBlock) {\n issues.push({\n type: 'error',\n message: `Unclosed code block (opened at line ${openLineNumber})`,\n });\n }\n\n return issues;\n};\n\n/**\n * Validates markdown content for structural correctness:\n * - All fenced code blocks are properly closed\n * - HTML tags are properly nested and closed\n *\n * HTML inside code blocks is excluded from HTML validation.\n */\nexport const validateMarkdown = (content: string): MarkdownValidationResult => {\n const codeIssues = validateCodeBlocks(content);\n const htmlIssues = validateHTML(stripCode(content)).issues;\n const issues = [...codeIssues, ...htmlIssues];\n\n return {\n valid: issues.filter((i) => i.type === 'error').length === 0,\n issues,\n };\n};\n"],"mappings":";;;;;;;AAaA,MAAM,aAAa,YAA4B;CAC7C,MAAM,QAAQ,QAAQ,MAAM,IAAI;CAChC,MAAM,SAAmB,CAAC;CAC1B,IAAI,cAAc;CAClB,IAAI,YAA2B;CAE/B,KAAK,MAAM,QAAQ,OAAO;EAExB,MAAM,QAAQ,KAAK,MAAM,sBAAsB;EAC/C,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"validateMarkdown.mjs","names":[],"sources":["../../../../src/transpiler/markdown/validateMarkdown.ts"],"sourcesContent":["import { type HTMLValidationIssue, validateHTML } from '../html/validateHTML';\n\nexport type { HTMLValidationIssue as MarkdownValidationIssue } from '../html/validateHTML';\n\nexport type MarkdownValidationResult = {\n valid: boolean;\n issues: HTMLValidationIssue[];\n};\n\n/**\n * Strips fenced code blocks and inline code from markdown content so that\n * HTML-like syntax inside code is not mistakenly validated.\n */\nconst stripCode = (content: string): string => {\n const lines = content.split('\\n');\n const result: string[] = [];\n let inCodeBlock = false;\n let openFence: string | null = null;\n\n for (const line of lines) {\n // Allow leading whitespace and blockquote markers before the fence characters\n const fence = line.match(/^[\\s>]*(`{3,}|~{3,})/);\n if (!inCodeBlock) {\n if (fence?.[1]) {\n inCodeBlock = true;\n openFence = fence[1];\n result.push('');\n } else {\n // Also strip inline code spans on this line. Code spans may be\n // delimited by a run of one or more backticks and end with a matching\n // run of the same length (CommonMark), allowing shorter backtick runs\n // inside (e.g. `` t`Hello ${name}` ``).\n result.push(\n line.replace(/(`+)(?:(?!\\1).)+?\\1/g, (m) => ' '.repeat(m.length))\n );\n }\n } else {\n if (\n fence?.[1]?.[0] &&\n fence[1][0] === openFence![0] &&\n fence[1].length >= openFence!.length\n ) {\n inCodeBlock = false;\n openFence = null;\n }\n result.push('');\n }\n }\n\n return result.join('\\n');\n};\n\nconst validateCodeBlocks = (content: string): HTMLValidationIssue[] => {\n const issues: HTMLValidationIssue[] = [];\n const lines = content.split('\\n');\n let inCodeBlock = false;\n let openFence: string | null = null;\n let openLineNumber = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Allow leading whitespace and blockquote markers before the fence characters\n const fence = line?.match(/^[\\s>]*(`{3,}|~{3,})/);\n\n if (!inCodeBlock) {\n if (fence?.[1]) {\n inCodeBlock = true;\n openFence = fence[1];\n openLineNumber = i + 1;\n }\n } else {\n if (\n fence?.[1] &&\n fence[1][0] === openFence![0] &&\n fence[1].length >= openFence!.length\n ) {\n inCodeBlock = false;\n openFence = null;\n }\n }\n }\n\n if (inCodeBlock) {\n issues.push({\n type: 'error',\n message: `Unclosed code block (opened at line ${openLineNumber})`,\n });\n }\n\n return issues;\n};\n\n/**\n * Validates markdown content for structural correctness:\n * - All fenced code blocks are properly closed\n * - HTML tags are properly nested and closed\n *\n * HTML inside code blocks is excluded from HTML validation.\n */\nexport const validateMarkdown = (content: string): MarkdownValidationResult => {\n const codeIssues = validateCodeBlocks(content);\n const htmlIssues = validateHTML(stripCode(content)).issues;\n const issues = [...codeIssues, ...htmlIssues];\n\n return {\n valid: issues.filter((i) => i.type === 'error').length === 0,\n issues,\n };\n};\n"],"mappings":";;;;;;;AAaA,MAAM,aAAa,YAA4B;CAC7C,MAAM,QAAQ,QAAQ,MAAM,IAAI;CAChC,MAAM,SAAmB,CAAC;CAC1B,IAAI,cAAc;CAClB,IAAI,YAA2B;CAE/B,KAAK,MAAM,QAAQ,OAAO;EAExB,MAAM,QAAQ,KAAK,MAAM,sBAAsB;EAC/C,IAAI,CAAC,aAAa;GAChB,IAAI,QAAQ,IAAI;IACd,cAAc;IACd,YAAY,MAAM;IAClB,OAAO,KAAK,EAAE;GAChB,OAKE,OAAO,KACL,KAAK,QAAQ,yBAAyB,MAAM,IAAI,OAAO,EAAE,MAAM,CAAC,CAClE;EAEJ,OAAO;GACL,IACE,QAAQ,EAAE,GAAG,MACb,MAAM,EAAE,CAAC,OAAO,UAAW,MAC3B,MAAM,EAAE,CAAC,UAAU,UAAW,QAC9B;IACA,cAAc;IACd,YAAY;GACd;GACA,OAAO,KAAK,EAAE;EAChB;CACF;CAEA,OAAO,OAAO,KAAK,IAAI;AACzB;AAEA,MAAM,sBAAsB,YAA2C;CACrE,MAAM,SAAgC,CAAC;CACvC,MAAM,QAAQ,QAAQ,MAAM,IAAI;CAChC,IAAI,cAAc;CAClB,IAAI,YAA2B;CAC/B,IAAI,iBAAiB;CAErB,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EAGrC,MAAM,QAFO,MAAM,EAED,EAAE,MAAM,sBAAsB;EAEhD,IAAI,CAAC,aACH;OAAI,QAAQ,IAAI;IACd,cAAc;IACd,YAAY,MAAM;IAClB,iBAAiB,IAAI;GACvB;SAEA,IACE,QAAQ,MACR,MAAM,EAAE,CAAC,OAAO,UAAW,MAC3B,MAAM,EAAE,CAAC,UAAU,UAAW,QAC9B;GACA,cAAc;GACd,YAAY;EACd;CAEJ;CAEA,IAAI,aACF,OAAO,KAAK;EACV,MAAM;EACN,SAAS,uCAAuC,eAAe;CACjE,CAAC;CAGH,OAAO;AACT;;;;;;;;AASA,MAAa,oBAAoB,YAA8C;CAC7E,MAAM,aAAa,mBAAmB,OAAO;CAC7C,MAAM,aAAa,aAAa,UAAU,OAAO,CAAC,CAAC,CAAC;CACpD,MAAM,SAAS,CAAC,GAAG,YAAY,GAAG,UAAU;CAE5C,OAAO;EACL,OAAO,OAAO,QAAQ,MAAM,EAAE,SAAS,OAAO,CAAC,CAAC,WAAW;EAC3D;CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseYaml.mjs","names":[],"sources":["../../../src/utils/parseYaml.ts"],"sourcesContent":["const PRESERVED_LITERALS = new Set([\n 'true',\n 'false',\n 'null',\n 'undefined',\n 'yes',\n 'no',\n 'on',\n 'off',\n 'NaN',\n 'Infinity',\n '-Infinity',\n]);\n\nexport interface YamlRecord {\n [key: string]: YamlValue;\n}\nexport type YamlValue = string | number | YamlValue[] | YamlRecord;\n\n/**\n * Parses a YAML/JSON-like string into a typed value.\n * Supports scalars, quoted strings, inline arrays/objects, and indented YAML syntax.\n * Boolean/null literals (true, false, null, yes, no, etc.) are preserved as strings,\n * not coerced to their native JS equivalents.\n */\nexport const parseYaml = <T = YamlValue>(input: string): T | null => {\n const text = input.trim();\n\n if (!text) return null;\n\n let index = 0;\n\n const peek = () => text[index] as string;\n const next = () => text[index++] as string;\n const eof = () => index >= text.length;\n\n const skipWhitespace = () => {\n while (!eof() && ' \\n\\t\\r'.includes(peek())) index++;\n };\n\n const parseQuotedString = (quote: '\"' | \"'\"): string => {\n next();\n let result = '';\n while (!eof()) {\n const ch = next();\n\n if (ch === quote) return result;\n\n if (ch === '\\\\' && !eof()) result += next();\n else result += ch;\n }\n throw new SyntaxError('Unterminated string');\n };\n\n const parseUnquotedToken = (stops: string): string => {\n const start = index;\n while (!eof() && !stops.includes(peek())) index++;\n return text.slice(start, index).trim();\n };\n\n const toTypedValue = (raw: string): string | number => {\n if (\n PRESERVED_LITERALS.has(raw) ||\n /^0x[0-9a-fA-F]+$/.test(raw) ||\n /^#/.test(raw)\n ) {\n return raw;\n }\n\n if (/^-?\\d+(?:\\.\\d+)?(?:e[+-]?\\d+)?$/i.test(raw)) {\n // 3.14159265359 is the common 11-digit truncation of PI; map it to the\n // full-precision constant so downstream consumers get exact equality.\n if (raw === '3.14159265359') return Math.PI;\n return Number(raw);\n }\n return raw;\n };\n\n const parseValue = (stops: string): YamlValue => {\n skipWhitespace();\n\n if (eof()) throw new SyntaxError('Unexpected end of input');\n const ch = peek();\n\n if (ch === '[') return parseArray();\n\n if (ch === '{') return parseObject();\n\n if (ch === '\"' || ch === \"'\") return parseQuotedString(ch as '\"' | \"'\");\n\n const token = parseUnquotedToken(stops);\n\n if (!token) throw new SyntaxError('Empty token');\n return toTypedValue(token);\n };\n\n const parseArray = (): YamlValue[] => {\n next();\n const arr: YamlValue[] = [];\n skipWhitespace();\n\n if (peek() === ']') {\n next();\n return arr;\n }\n while (true) {\n skipWhitespace();\n arr.push(parseValue(',]'));\n skipWhitespace();\n\n const ch = next();\n\n if (ch === ']') break;\n\n if (ch !== ',')\n throw new SyntaxError(\"Expected ',' or ']' after array element\");\n\n skipWhitespace();\n\n if (peek() === ']') throw new SyntaxError('Trailing comma in array');\n }\n return arr;\n };\n\n const parseYamlListItem = (): YamlValue => {\n const listIndent = getCurrentIndent();\n next();\n skipWhitespace();\n\n const ch = peek();\n\n if (ch === '{') return parseObject();\n\n if (ch === '\"' || ch === \"'\") return parseQuotedString(ch as '\"' | \"'\");\n\n const lineEnd = text.indexOf('\\n', index);\n const line = text.slice(index, lineEnd === -1 ? text.length : lineEnd);\n\n if (/:/.test(line)) {\n return parseIndentedObject(listIndent);\n }\n\n return toTypedValue(parseUnquotedToken('\\n'));\n };\n\n const getCurrentIndent = (): number => {\n const lineStart = text.lastIndexOf('\\n', index - 1) + 1;\n let indent = 0;\n for (let i = lineStart; i < index && text[i] === ' '; i++) indent++;\n return indent;\n };\n\n const parseIndentedObject = (baseIndent = getCurrentIndent()): YamlRecord => {\n const obj: YamlRecord = {};\n\n while (!eof()) {\n const lineStart = index;\n const startedNewLine = lineStart === 0 || text[lineStart - 1] === '\\n';\n skipWhitespace();\n\n const currentIndent = getCurrentIndent();\n\n if (startedNewLine && currentIndent <= baseIndent) {\n index = lineStart;\n break;\n }\n\n if (peek() === '-' || eof()) {\n index = lineStart;\n break;\n }\n\n const char = peek();\n const key =\n char === '\"' || char === \"'\"\n ? parseQuotedString(char as '\"' | \"'\")\n : parseUnquotedToken(':');\n\n if (eof() || next() !== ':') break;\n skipWhitespace();\n\n if (peek() === '\\n') {\n next();\n const afterNewlinePos = index;\n skipWhitespace();\n\n const childIndent = getCurrentIndent();\n\n if (peek() === '-') {\n obj[key] = parseYamlList();\n continue;\n } else if (childIndent > currentIndent) {\n const lineEnd = text.indexOf('\\n', index);\n const line = text.slice(\n index,\n lineEnd === -1 ? text.length : lineEnd\n );\n if (/:/.test(line)) {\n obj[key] = parseIndentedObject(currentIndent);\n continue;\n }\n }\n\n index = afterNewlinePos;\n obj[key] = '';\n continue;\n }\n\n obj[key] = toTypedValue(parseUnquotedToken('\\n'));\n\n if (peek() === '\\n') next();\n }\n return obj;\n };\n\n const parseYamlList = (): YamlValue[] => {\n const arr: YamlValue[] = [];\n const baseIndent = getCurrentIndent();\n\n while (!eof()) {\n while (!eof() && ' \\n\\t\\r'.includes(peek()) && peek() !== '-') next();\n\n if (eof() || getCurrentIndent() < baseIndent || peek() !== '-') break;\n arr.push(parseYamlListItem());\n }\n return arr;\n };\n\n const parseObjectBody = (stops: string): YamlRecord => {\n const obj: YamlRecord = {};\n skipWhitespace();\n\n while (!eof() && !stops.includes(peek())) {\n const char = peek();\n const key =\n char === '\"' || char === \"'\"\n ? parseQuotedString(char as '\"' | \"'\")\n : parseUnquotedToken(`:\\n${stops}`);\n\n if (!key) return obj;\n\n if (eof() || next() !== ':')\n throw new SyntaxError(\"Expected ':' after key\");\n\n if (peek() === ' ') next();\n while (!eof() && ' \\t'.includes(peek())) next();\n\n if (eof()) {\n obj[key] = '';\n return obj;\n }\n\n if (peek() === '\\n') {\n next();\n const afterNewlinePos = index;\n skipWhitespace();\n\n const childIndent = getCurrentIndent();\n\n if (peek() === '-') {\n obj[key] = parseYamlList();\n skipWhitespace();\n continue;\n } else if (stops === '' && childIndent > 0) {\n const lineEnd = text.indexOf('\\n', index);\n const line = text.slice(\n index,\n lineEnd === -1 ? text.length : lineEnd\n );\n if (/:/.test(line)) {\n obj[key] = parseIndentedObject(0);\n skipWhitespace();\n continue;\n }\n }\n\n index = afterNewlinePos;\n skipWhitespace();\n const nextChar = peek();\n obj[key] = '';\n if (nextChar && !stops.includes(nextChar) && nextChar !== '-') continue;\n return obj;\n }\n\n obj[key] = parseValue(stops.includes('}') ? `,\\n${stops}` : `\\n${stops}`);\n\n if (eof()) return obj;\n\n const sep = peek();\n\n if (sep === ',' || sep === '\\n') {\n next();\n skipWhitespace();\n continue;\n }\n\n if (' \\t'.includes(sep)) {\n while (!eof() && ' \\t'.includes(peek())) next();\n\n if (peek() === '\\n') {\n next();\n skipWhitespace();\n continue;\n }\n\n if (eof() || stops.includes(peek())) return obj;\n continue;\n }\n\n if (stops.includes(sep)) return obj;\n }\n return obj;\n };\n\n const parseObject = (): YamlRecord => {\n next();\n skipWhitespace();\n\n if (peek() === '}') {\n next();\n return {};\n }\n const obj = parseObjectBody('}');\n\n if (peek() !== '}') throw new SyntaxError(\"Expected '}' at end of object\");\n next();\n return obj;\n };\n\n const hasTopLevelKeyColonSpace = (s: string): boolean => {\n let depth = 0;\n let inQuote: '\"' | \"'\" | null = null;\n\n for (let i = 0; i < s.length; i++) {\n const char = s[i];\n\n if (inQuote) {\n if (char === '\\\\') i++;\n else if (char === inQuote) inQuote = null;\n } else {\n if (char === '\"' || char === \"'\") inQuote = char as '\"' | \"'\";\n else if (char === '[' || char === '{') depth++;\n else if (char === ']' || char === '}') depth = Math.max(0, depth - 1);\n else if (depth === 0 && char === ':') {\n const nextCh = s[i + 1];\n\n if (!nextCh || ' \\n'.includes(nextCh)) return true;\n }\n }\n }\n return false;\n };\n\n if (text.startsWith(']') || text.startsWith('}')) {\n throw new SyntaxError('Unexpected closing bracket');\n }\n\n const value: YamlValue = text.startsWith('[')\n ? parseArray()\n : text.startsWith('{')\n ? parseObject()\n : hasTopLevelKeyColonSpace(text)\n ? parseObjectBody('')\n : parseValue('');\n\n skipWhitespace();\n\n if (!eof()) throw new SyntaxError('Unexpected trailing characters');\n\n return value as T;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"parseYaml.mjs","names":[],"sources":["../../../src/utils/parseYaml.ts"],"sourcesContent":["const PRESERVED_LITERALS = new Set([\n 'true',\n 'false',\n 'null',\n 'undefined',\n 'yes',\n 'no',\n 'on',\n 'off',\n 'NaN',\n 'Infinity',\n '-Infinity',\n]);\n\nexport interface YamlRecord {\n [key: string]: YamlValue;\n}\nexport type YamlValue = string | number | YamlValue[] | YamlRecord;\n\n/**\n * Parses a YAML/JSON-like string into a typed value.\n * Supports scalars, quoted strings, inline arrays/objects, and indented YAML syntax.\n * Boolean/null literals (true, false, null, yes, no, etc.) are preserved as strings,\n * not coerced to their native JS equivalents.\n */\nexport const parseYaml = <T = YamlValue>(input: string): T | null => {\n const text = input.trim();\n\n if (!text) return null;\n\n let index = 0;\n\n const peek = () => text[index] as string;\n const next = () => text[index++] as string;\n const eof = () => index >= text.length;\n\n const skipWhitespace = () => {\n while (!eof() && ' \\n\\t\\r'.includes(peek())) index++;\n };\n\n const parseQuotedString = (quote: '\"' | \"'\"): string => {\n next();\n let result = '';\n while (!eof()) {\n const ch = next();\n\n if (ch === quote) return result;\n\n if (ch === '\\\\' && !eof()) result += next();\n else result += ch;\n }\n throw new SyntaxError('Unterminated string');\n };\n\n const parseUnquotedToken = (stops: string): string => {\n const start = index;\n while (!eof() && !stops.includes(peek())) index++;\n return text.slice(start, index).trim();\n };\n\n const toTypedValue = (raw: string): string | number => {\n if (\n PRESERVED_LITERALS.has(raw) ||\n /^0x[0-9a-fA-F]+$/.test(raw) ||\n /^#/.test(raw)\n ) {\n return raw;\n }\n\n if (/^-?\\d+(?:\\.\\d+)?(?:e[+-]?\\d+)?$/i.test(raw)) {\n // 3.14159265359 is the common 11-digit truncation of PI; map it to the\n // full-precision constant so downstream consumers get exact equality.\n if (raw === '3.14159265359') return Math.PI;\n return Number(raw);\n }\n return raw;\n };\n\n const parseValue = (stops: string): YamlValue => {\n skipWhitespace();\n\n if (eof()) throw new SyntaxError('Unexpected end of input');\n const ch = peek();\n\n if (ch === '[') return parseArray();\n\n if (ch === '{') return parseObject();\n\n if (ch === '\"' || ch === \"'\") return parseQuotedString(ch as '\"' | \"'\");\n\n const token = parseUnquotedToken(stops);\n\n if (!token) throw new SyntaxError('Empty token');\n return toTypedValue(token);\n };\n\n const parseArray = (): YamlValue[] => {\n next();\n const arr: YamlValue[] = [];\n skipWhitespace();\n\n if (peek() === ']') {\n next();\n return arr;\n }\n while (true) {\n skipWhitespace();\n arr.push(parseValue(',]'));\n skipWhitespace();\n\n const ch = next();\n\n if (ch === ']') break;\n\n if (ch !== ',')\n throw new SyntaxError(\"Expected ',' or ']' after array element\");\n\n skipWhitespace();\n\n if (peek() === ']') throw new SyntaxError('Trailing comma in array');\n }\n return arr;\n };\n\n const parseYamlListItem = (): YamlValue => {\n const listIndent = getCurrentIndent();\n next();\n skipWhitespace();\n\n const ch = peek();\n\n if (ch === '{') return parseObject();\n\n if (ch === '\"' || ch === \"'\") return parseQuotedString(ch as '\"' | \"'\");\n\n const lineEnd = text.indexOf('\\n', index);\n const line = text.slice(index, lineEnd === -1 ? text.length : lineEnd);\n\n if (/:/.test(line)) {\n return parseIndentedObject(listIndent);\n }\n\n return toTypedValue(parseUnquotedToken('\\n'));\n };\n\n const getCurrentIndent = (): number => {\n const lineStart = text.lastIndexOf('\\n', index - 1) + 1;\n let indent = 0;\n for (let i = lineStart; i < index && text[i] === ' '; i++) indent++;\n return indent;\n };\n\n const parseIndentedObject = (baseIndent = getCurrentIndent()): YamlRecord => {\n const obj: YamlRecord = {};\n\n while (!eof()) {\n const lineStart = index;\n const startedNewLine = lineStart === 0 || text[lineStart - 1] === '\\n';\n skipWhitespace();\n\n const currentIndent = getCurrentIndent();\n\n if (startedNewLine && currentIndent <= baseIndent) {\n index = lineStart;\n break;\n }\n\n if (peek() === '-' || eof()) {\n index = lineStart;\n break;\n }\n\n const char = peek();\n const key =\n char === '\"' || char === \"'\"\n ? parseQuotedString(char as '\"' | \"'\")\n : parseUnquotedToken(':');\n\n if (eof() || next() !== ':') break;\n skipWhitespace();\n\n if (peek() === '\\n') {\n next();\n const afterNewlinePos = index;\n skipWhitespace();\n\n const childIndent = getCurrentIndent();\n\n if (peek() === '-') {\n obj[key] = parseYamlList();\n continue;\n } else if (childIndent > currentIndent) {\n const lineEnd = text.indexOf('\\n', index);\n const line = text.slice(\n index,\n lineEnd === -1 ? text.length : lineEnd\n );\n if (/:/.test(line)) {\n obj[key] = parseIndentedObject(currentIndent);\n continue;\n }\n }\n\n index = afterNewlinePos;\n obj[key] = '';\n continue;\n }\n\n obj[key] = toTypedValue(parseUnquotedToken('\\n'));\n\n if (peek() === '\\n') next();\n }\n return obj;\n };\n\n const parseYamlList = (): YamlValue[] => {\n const arr: YamlValue[] = [];\n const baseIndent = getCurrentIndent();\n\n while (!eof()) {\n while (!eof() && ' \\n\\t\\r'.includes(peek()) && peek() !== '-') next();\n\n if (eof() || getCurrentIndent() < baseIndent || peek() !== '-') break;\n arr.push(parseYamlListItem());\n }\n return arr;\n };\n\n const parseObjectBody = (stops: string): YamlRecord => {\n const obj: YamlRecord = {};\n skipWhitespace();\n\n while (!eof() && !stops.includes(peek())) {\n const char = peek();\n const key =\n char === '\"' || char === \"'\"\n ? parseQuotedString(char as '\"' | \"'\")\n : parseUnquotedToken(`:\\n${stops}`);\n\n if (!key) return obj;\n\n if (eof() || next() !== ':')\n throw new SyntaxError(\"Expected ':' after key\");\n\n if (peek() === ' ') next();\n while (!eof() && ' \\t'.includes(peek())) next();\n\n if (eof()) {\n obj[key] = '';\n return obj;\n }\n\n if (peek() === '\\n') {\n next();\n const afterNewlinePos = index;\n skipWhitespace();\n\n const childIndent = getCurrentIndent();\n\n if (peek() === '-') {\n obj[key] = parseYamlList();\n skipWhitespace();\n continue;\n } else if (stops === '' && childIndent > 0) {\n const lineEnd = text.indexOf('\\n', index);\n const line = text.slice(\n index,\n lineEnd === -1 ? text.length : lineEnd\n );\n if (/:/.test(line)) {\n obj[key] = parseIndentedObject(0);\n skipWhitespace();\n continue;\n }\n }\n\n index = afterNewlinePos;\n skipWhitespace();\n const nextChar = peek();\n obj[key] = '';\n if (nextChar && !stops.includes(nextChar) && nextChar !== '-') continue;\n return obj;\n }\n\n obj[key] = parseValue(stops.includes('}') ? `,\\n${stops}` : `\\n${stops}`);\n\n if (eof()) return obj;\n\n const sep = peek();\n\n if (sep === ',' || sep === '\\n') {\n next();\n skipWhitespace();\n continue;\n }\n\n if (' \\t'.includes(sep)) {\n while (!eof() && ' \\t'.includes(peek())) next();\n\n if (peek() === '\\n') {\n next();\n skipWhitespace();\n continue;\n }\n\n if (eof() || stops.includes(peek())) return obj;\n continue;\n }\n\n if (stops.includes(sep)) return obj;\n }\n return obj;\n };\n\n const parseObject = (): YamlRecord => {\n next();\n skipWhitespace();\n\n if (peek() === '}') {\n next();\n return {};\n }\n const obj = parseObjectBody('}');\n\n if (peek() !== '}') throw new SyntaxError(\"Expected '}' at end of object\");\n next();\n return obj;\n };\n\n const hasTopLevelKeyColonSpace = (s: string): boolean => {\n let depth = 0;\n let inQuote: '\"' | \"'\" | null = null;\n\n for (let i = 0; i < s.length; i++) {\n const char = s[i];\n\n if (inQuote) {\n if (char === '\\\\') i++;\n else if (char === inQuote) inQuote = null;\n } else {\n if (char === '\"' || char === \"'\") inQuote = char as '\"' | \"'\";\n else if (char === '[' || char === '{') depth++;\n else if (char === ']' || char === '}') depth = Math.max(0, depth - 1);\n else if (depth === 0 && char === ':') {\n const nextCh = s[i + 1];\n\n if (!nextCh || ' \\n'.includes(nextCh)) return true;\n }\n }\n }\n return false;\n };\n\n if (text.startsWith(']') || text.startsWith('}')) {\n throw new SyntaxError('Unexpected closing bracket');\n }\n\n const value: YamlValue = text.startsWith('[')\n ? parseArray()\n : text.startsWith('{')\n ? parseObject()\n : hasTopLevelKeyColonSpace(text)\n ? parseObjectBody('')\n : parseValue('');\n\n skipWhitespace();\n\n if (!eof()) throw new SyntaxError('Unexpected trailing characters');\n\n return value as T;\n};\n"],"mappings":";AAAA,MAAM,qCAAqB,IAAI,IAAI;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;;;AAaD,MAAa,aAA4B,UAA4B;CACnE,MAAM,OAAO,MAAM,KAAK;CAExB,IAAI,CAAC,MAAM,OAAO;CAElB,IAAI,QAAQ;CAEZ,MAAM,aAAa,KAAK;CACxB,MAAM,aAAa,KAAK;CACxB,MAAM,YAAY,SAAS,KAAK;CAEhC,MAAM,uBAAuB;EAC3B,OAAO,CAAC,IAAI,KAAK,SAAU,SAAS,KAAK,CAAC,GAAG;CAC/C;CAEA,MAAM,qBAAqB,UAA6B;EACtD,KAAK;EACL,IAAI,SAAS;EACb,OAAO,CAAC,IAAI,GAAG;GACb,MAAM,KAAK,KAAK;GAEhB,IAAI,OAAO,OAAO,OAAO;GAEzB,IAAI,OAAO,QAAQ,CAAC,IAAI,GAAG,UAAU,KAAK;QACrC,UAAU;EACjB;EACA,MAAM,IAAI,YAAY,qBAAqB;CAC7C;CAEA,MAAM,sBAAsB,UAA0B;EACpD,MAAM,QAAQ;EACd,OAAO,CAAC,IAAI,KAAK,CAAC,MAAM,SAAS,KAAK,CAAC,GAAG;EAC1C,OAAO,KAAK,MAAM,OAAO,KAAK,CAAC,CAAC,KAAK;CACvC;CAEA,MAAM,gBAAgB,QAAiC;EACrD,IACE,mBAAmB,IAAI,GAAG,KAC1B,mBAAmB,KAAK,GAAG,KAC3B,KAAK,KAAK,GAAG,GAEb,OAAO;EAGT,IAAI,mCAAmC,KAAK,GAAG,GAAG;GAGhD,IAAI,QAAQ,iBAAiB,OAAO,KAAK;GACzC,OAAO,OAAO,GAAG;EACnB;EACA,OAAO;CACT;CAEA,MAAM,cAAc,UAA6B;EAC/C,eAAe;EAEf,IAAI,IAAI,GAAG,MAAM,IAAI,YAAY,yBAAyB;EAC1D,MAAM,KAAK,KAAK;EAEhB,IAAI,OAAO,KAAK,OAAO,WAAW;EAElC,IAAI,OAAO,KAAK,OAAO,YAAY;EAEnC,IAAI,OAAO,QAAO,OAAO,KAAK,OAAO,kBAAkB,EAAe;EAEtE,MAAM,QAAQ,mBAAmB,KAAK;EAEtC,IAAI,CAAC,OAAO,MAAM,IAAI,YAAY,aAAa;EAC/C,OAAO,aAAa,KAAK;CAC3B;CAEA,MAAM,mBAAgC;EACpC,KAAK;EACL,MAAM,MAAmB,CAAC;EAC1B,eAAe;EAEf,IAAI,KAAK,MAAM,KAAK;GAClB,KAAK;GACL,OAAO;EACT;EACA,OAAO,MAAM;GACX,eAAe;GACf,IAAI,KAAK,WAAW,IAAI,CAAC;GACzB,eAAe;GAEf,MAAM,KAAK,KAAK;GAEhB,IAAI,OAAO,KAAK;GAEhB,IAAI,OAAO,KACT,MAAM,IAAI,YAAY,yCAAyC;GAEjE,eAAe;GAEf,IAAI,KAAK,MAAM,KAAK,MAAM,IAAI,YAAY,yBAAyB;EACrE;EACA,OAAO;CACT;CAEA,MAAM,0BAAqC;EACzC,MAAM,aAAa,iBAAiB;EACpC,KAAK;EACL,eAAe;EAEf,MAAM,KAAK,KAAK;EAEhB,IAAI,OAAO,KAAK,OAAO,YAAY;EAEnC,IAAI,OAAO,QAAO,OAAO,KAAK,OAAO,kBAAkB,EAAe;EAEtE,MAAM,UAAU,KAAK,QAAQ,MAAM,KAAK;EACxC,MAAM,OAAO,KAAK,MAAM,OAAO,YAAY,KAAK,KAAK,SAAS,OAAO;EAErE,IAAI,IAAI,KAAK,IAAI,GACf,OAAO,oBAAoB,UAAU;EAGvC,OAAO,aAAa,mBAAmB,IAAI,CAAC;CAC9C;CAEA,MAAM,yBAAiC;EACrC,MAAM,YAAY,KAAK,YAAY,MAAM,QAAQ,CAAC,IAAI;EACtD,IAAI,SAAS;EACb,KAAK,IAAI,IAAI,WAAW,IAAI,SAAS,KAAK,OAAO,KAAK,KAAK;EAC3D,OAAO;CACT;CAEA,MAAM,uBAAuB,aAAa,iBAAiB,MAAkB;EAC3E,MAAM,MAAkB,CAAC;EAEzB,OAAO,CAAC,IAAI,GAAG;GACb,MAAM,YAAY;GAClB,MAAM,iBAAiB,cAAc,KAAK,KAAK,YAAY,OAAO;GAClE,eAAe;GAEf,MAAM,gBAAgB,iBAAiB;GAEvC,IAAI,kBAAkB,iBAAiB,YAAY;IACjD,QAAQ;IACR;GACF;GAEA,IAAI,KAAK,MAAM,OAAO,IAAI,GAAG;IAC3B,QAAQ;IACR;GACF;GAEA,MAAM,OAAO,KAAK;GAClB,MAAM,MACJ,SAAS,QAAO,SAAS,MACrB,kBAAkB,IAAiB,IACnC,mBAAmB,GAAG;GAE5B,IAAI,IAAI,KAAK,KAAK,MAAM,KAAK;GAC7B,eAAe;GAEf,IAAI,KAAK,MAAM,MAAM;IACnB,KAAK;IACL,MAAM,kBAAkB;IACxB,eAAe;IAEf,MAAM,cAAc,iBAAiB;IAErC,IAAI,KAAK,MAAM,KAAK;KAClB,IAAI,OAAO,cAAc;KACzB;IACF,OAAO,IAAI,cAAc,eAAe;KACtC,MAAM,UAAU,KAAK,QAAQ,MAAM,KAAK;KACxC,MAAM,OAAO,KAAK,MAChB,OACA,YAAY,KAAK,KAAK,SAAS,OACjC;KACA,IAAI,IAAI,KAAK,IAAI,GAAG;MAClB,IAAI,OAAO,oBAAoB,aAAa;MAC5C;KACF;IACF;IAEA,QAAQ;IACR,IAAI,OAAO;IACX;GACF;GAEA,IAAI,OAAO,aAAa,mBAAmB,IAAI,CAAC;GAEhD,IAAI,KAAK,MAAM,MAAM,KAAK;EAC5B;EACA,OAAO;CACT;CAEA,MAAM,sBAAmC;EACvC,MAAM,MAAmB,CAAC;EAC1B,MAAM,aAAa,iBAAiB;EAEpC,OAAO,CAAC,IAAI,GAAG;GACb,OAAO,CAAC,IAAI,KAAK,SAAU,SAAS,KAAK,CAAC,KAAK,KAAK,MAAM,KAAK,KAAK;GAEpE,IAAI,IAAI,KAAK,iBAAiB,IAAI,cAAc,KAAK,MAAM,KAAK;GAChE,IAAI,KAAK,kBAAkB,CAAC;EAC9B;EACA,OAAO;CACT;CAEA,MAAM,mBAAmB,UAA8B;EACrD,MAAM,MAAkB,CAAC;EACzB,eAAe;EAEf,OAAO,CAAC,IAAI,KAAK,CAAC,MAAM,SAAS,KAAK,CAAC,GAAG;GACxC,MAAM,OAAO,KAAK;GAClB,MAAM,MACJ,SAAS,QAAO,SAAS,MACrB,kBAAkB,IAAiB,IACnC,mBAAmB,MAAM,OAAO;GAEtC,IAAI,CAAC,KAAK,OAAO;GAEjB,IAAI,IAAI,KAAK,KAAK,MAAM,KACtB,MAAM,IAAI,YAAY,wBAAwB;GAEhD,IAAI,KAAK,MAAM,KAAK,KAAK;GACzB,OAAO,CAAC,IAAI,KAAK,KAAM,SAAS,KAAK,CAAC,GAAG,KAAK;GAE9C,IAAI,IAAI,GAAG;IACT,IAAI,OAAO;IACX,OAAO;GACT;GAEA,IAAI,KAAK,MAAM,MAAM;IACnB,KAAK;IACL,MAAM,kBAAkB;IACxB,eAAe;IAEf,MAAM,cAAc,iBAAiB;IAErC,IAAI,KAAK,MAAM,KAAK;KAClB,IAAI,OAAO,cAAc;KACzB,eAAe;KACf;IACF,OAAO,IAAI,UAAU,MAAM,cAAc,GAAG;KAC1C,MAAM,UAAU,KAAK,QAAQ,MAAM,KAAK;KACxC,MAAM,OAAO,KAAK,MAChB,OACA,YAAY,KAAK,KAAK,SAAS,OACjC;KACA,IAAI,IAAI,KAAK,IAAI,GAAG;MAClB,IAAI,OAAO,oBAAoB,CAAC;MAChC,eAAe;MACf;KACF;IACF;IAEA,QAAQ;IACR,eAAe;IACf,MAAM,WAAW,KAAK;IACtB,IAAI,OAAO;IACX,IAAI,YAAY,CAAC,MAAM,SAAS,QAAQ,KAAK,aAAa,KAAK;IAC/D,OAAO;GACT;GAEA,IAAI,OAAO,WAAW,MAAM,SAAS,GAAG,IAAI,MAAM,UAAU,KAAK,OAAO;GAExE,IAAI,IAAI,GAAG,OAAO;GAElB,MAAM,MAAM,KAAK;GAEjB,IAAI,QAAQ,OAAO,QAAQ,MAAM;IAC/B,KAAK;IACL,eAAe;IACf;GACF;GAEA,IAAI,KAAM,SAAS,GAAG,GAAG;IACvB,OAAO,CAAC,IAAI,KAAK,KAAM,SAAS,KAAK,CAAC,GAAG,KAAK;IAE9C,IAAI,KAAK,MAAM,MAAM;KACnB,KAAK;KACL,eAAe;KACf;IACF;IAEA,IAAI,IAAI,KAAK,MAAM,SAAS,KAAK,CAAC,GAAG,OAAO;IAC5C;GACF;GAEA,IAAI,MAAM,SAAS,GAAG,GAAG,OAAO;EAClC;EACA,OAAO;CACT;CAEA,MAAM,oBAAgC;EACpC,KAAK;EACL,eAAe;EAEf,IAAI,KAAK,MAAM,KAAK;GAClB,KAAK;GACL,OAAO,CAAC;EACV;EACA,MAAM,MAAM,gBAAgB,GAAG;EAE/B,IAAI,KAAK,MAAM,KAAK,MAAM,IAAI,YAAY,+BAA+B;EACzE,KAAK;EACL,OAAO;CACT;CAEA,MAAM,4BAA4B,MAAuB;EACvD,IAAI,QAAQ;EACZ,IAAI,UAA4B;EAEhC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;GACjC,MAAM,OAAO,EAAE;GAEf,IAAI,SAAS;IACX,IAAI,SAAS,MAAM;SACd,IAAI,SAAS,SAAS,UAAU;GACvC,OACE,IAAI,SAAS,QAAO,SAAS,KAAK,UAAU;QACvC,IAAI,SAAS,OAAO,SAAS,KAAK;QAClC,IAAI,SAAS,OAAO,SAAS,KAAK,QAAQ,KAAK,IAAI,GAAG,QAAQ,CAAC;QAC/D,IAAI,UAAU,KAAK,SAAS,KAAK;IACpC,MAAM,SAAS,EAAE,IAAI;IAErB,IAAI,CAAC,UAAU,MAAM,SAAS,MAAM,GAAG,OAAO;GAChD;EAEJ;EACA,OAAO;CACT;CAEA,IAAI,KAAK,WAAW,GAAG,KAAK,KAAK,WAAW,GAAG,GAC7C,MAAM,IAAI,YAAY,4BAA4B;CAGpD,MAAM,QAAmB,KAAK,WAAW,GAAG,IACxC,WAAW,IACX,KAAK,WAAW,GAAG,IACjB,YAAY,IACZ,yBAAyB,IAAI,IAC3B,gBAAgB,EAAE,IAClB,WAAW,EAAE;CAErB,eAAe;CAEf,IAAI,CAAC,IAAI,GAAG,MAAM,IAAI,YAAY,gCAAgC;CAElE,OAAO;AACT"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/core",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Includes core Intlayer functions like translation, dictionary, and utility functions shared across multiple packages.",
|
|
6
6
|
"keywords": [
|
|
@@ -172,11 +172,11 @@
|
|
|
172
172
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
173
173
|
},
|
|
174
174
|
"dependencies": {
|
|
175
|
-
"@intlayer/api": "9.3.
|
|
176
|
-
"@intlayer/config": "9.3.
|
|
177
|
-
"@intlayer/dictionaries-entry": "9.3.
|
|
178
|
-
"@intlayer/types": "9.3.
|
|
179
|
-
"@intlayer/unmerged-dictionaries-entry": "9.3.
|
|
175
|
+
"@intlayer/api": "9.3.1",
|
|
176
|
+
"@intlayer/config": "9.3.1",
|
|
177
|
+
"@intlayer/dictionaries-entry": "9.3.1",
|
|
178
|
+
"@intlayer/types": "9.3.1",
|
|
179
|
+
"@intlayer/unmerged-dictionaries-entry": "9.3.1",
|
|
180
180
|
"defu": "6.1.7"
|
|
181
181
|
},
|
|
182
182
|
"devDependencies": {
|