@intlayer/core 9.4.1 → 9.4.3
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 +1 -1
- package/dist/cjs/index.cjs +8 -4
- package/dist/cjs/localization/getCanonicalPath.cjs +52 -0
- package/dist/cjs/localization/getCanonicalPath.cjs.map +1 -0
- package/dist/cjs/localization/getCanonicalPath.test-d.cjs +12 -0
- package/dist/cjs/localization/getCanonicalPath.test-d.cjs.map +1 -0
- package/dist/cjs/localization/getLocalizedPath.cjs +4 -2
- package/dist/cjs/localization/getLocalizedPath.cjs.map +1 -1
- package/dist/cjs/localization/index.cjs +4 -2
- package/dist/cjs/localization/rewriteMatch.cjs +52 -0
- package/dist/cjs/localization/rewriteMatch.cjs.map +1 -0
- package/dist/cjs/localization/rewriteUtils.cjs +6 -68
- package/dist/cjs/localization/rewriteUtils.cjs.map +1 -1
- package/dist/cjs/localization/rewriteUtils.test-d.cjs +0 -5
- package/dist/cjs/localization/rewriteUtils.test-d.cjs.map +1 -1
- package/dist/cjs/markdown/compiler.cjs +100 -75
- package/dist/cjs/markdown/compiler.cjs.map +1 -1
- package/dist/cjs/markdown/constants.cjs +14 -5
- package/dist/cjs/markdown/constants.cjs.map +1 -1
- package/dist/cjs/markdown/index.cjs +4 -2
- package/dist/cjs/markdown/parser.cjs +70 -44
- package/dist/cjs/markdown/parser.cjs.map +1 -1
- package/dist/cjs/markdown/renderer.cjs +7 -19
- package/dist/cjs/markdown/renderer.cjs.map +1 -1
- package/dist/cjs/markdown/utils.cjs +33 -37
- package/dist/cjs/markdown/utils.cjs.map +1 -1
- package/dist/esm/index.mjs +5 -3
- package/dist/esm/localization/getCanonicalPath.mjs +51 -0
- package/dist/esm/localization/getCanonicalPath.mjs.map +1 -0
- package/dist/esm/localization/getCanonicalPath.test-d.mjs +12 -0
- package/dist/esm/localization/getCanonicalPath.test-d.mjs.map +1 -0
- package/dist/esm/localization/getLocalizedPath.mjs +3 -1
- package/dist/esm/localization/getLocalizedPath.mjs.map +1 -1
- package/dist/esm/localization/index.mjs +3 -1
- package/dist/esm/localization/rewriteMatch.mjs +49 -0
- package/dist/esm/localization/rewriteMatch.mjs.map +1 -0
- package/dist/esm/localization/rewriteUtils.mjs +3 -63
- package/dist/esm/localization/rewriteUtils.mjs.map +1 -1
- package/dist/esm/localization/rewriteUtils.test-d.mjs +1 -6
- package/dist/esm/localization/rewriteUtils.test-d.mjs.map +1 -1
- package/dist/esm/markdown/compiler.mjs +101 -55
- package/dist/esm/markdown/compiler.mjs.map +1 -1
- package/dist/esm/markdown/constants.mjs +11 -4
- package/dist/esm/markdown/constants.mjs.map +1 -1
- package/dist/esm/markdown/index.mjs +2 -2
- package/dist/esm/markdown/parser.mjs +70 -44
- package/dist/esm/markdown/parser.mjs.map +1 -1
- package/dist/esm/markdown/renderer.mjs +7 -19
- package/dist/esm/markdown/renderer.mjs.map +1 -1
- package/dist/esm/markdown/utils.mjs +34 -38
- package/dist/esm/markdown/utils.mjs.map +1 -1
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/dictionaryManipulator/qualifiedDynamicLoader.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getDictionaryAsync.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getEnumeration.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getGender.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getInsertion.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getPlural.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getSelect.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/index.d.ts +7 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/interpolableNode.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/index.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/nesting.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/dictionaryManipulator/qualifiedDynamicLoader.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getDictionaryAsync.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getEnumeration.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getGender.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getInsertion.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getPlural.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getSelect.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/index.d.ts +7 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/interpolableNode.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/intlayer/dist/types/index.d.ts +6 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/index.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/nesting.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/dictionaryManipulator/qualifiedDynamicLoader.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getDictionaryAsync.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getEnumeration.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getGender.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getInsertion.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getPlural.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getSelect.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/index.d.ts +7 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/interpolableNode.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/intlayer/dist/types/index.d.ts +6 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/index.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/nesting.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/dictionaryManipulator/qualifiedDynamicLoader.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getDictionaryAsync.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getEnumeration.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getGender.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getInsertion.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getPlural.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getSelect.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/index.d.ts +7 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/interpolableNode.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/intlayer/dist/types/index.d.ts +6 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/index.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/nesting.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/dictionaryManipulator/qualifiedDynamicLoader.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getDictionaryAsync.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getEnumeration.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getGender.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getInsertion.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getPlural.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getSelect.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/index.d.ts +7 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/interpolableNode.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/intlayer/dist/types/index.d.ts +6 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/index.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/nesting.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/dictionaryManipulator/plainDynamicLoader.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/dictionaryManipulator/qualifiedDynamicLoader.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/formatters/compact.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/formatters/currency.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/formatters/date.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/formatters/index.d.ts +9 -0
- package/dist/types/@intlayer/core/dist/types/formatters/list.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/formatters/number.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/formatters/percentage.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/formatters/relativeTime.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/formatters/units.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/dictionaryTransformCache.d.ts +4 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getCondition.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getContent/deepTransform.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getContent/getContent.d.ts +3 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getContent/index.d.ts +3 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getContent/plugins.d.ts +7 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getDictionary.d.ts +4 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getDictionaryAsync.d.ts +6 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getEnumeration.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getGender.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getInsertion.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getIntlayer.d.ts +4 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getIntlayerAsync.d.ts +4 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getNesting.d.ts +6 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getPlural.d.ts +3 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getSelect.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/getTranslation.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/index.d.ts +18 -0
- package/dist/types/@intlayer/core/dist/types/interpreter/interpolableNode.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/intlayer/dist/types/index.d.ts +6 -0
- package/dist/types/@intlayer/core/dist/types/localization/comparePaths.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/localization/domainUtils.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/localization/generateSitemap.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/localization/getBrowserLocale.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/localization/getCanonicalPath.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/localization/getHTMLTextDir.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/localization/getLocale.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/localization/getLocaleFromPath.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/localization/getLocaleLang.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/localization/getLocaleName.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/localization/getLocalizedPath.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/localization/getLocalizedUrl.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/localization/getMultilingualUrls.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/localization/getPathWithoutLocale.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/localization/getPrefix.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/localization/index.d.ts +22 -0
- package/dist/types/@intlayer/core/dist/types/localization/localeDetector.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/localization/localeMapper.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/localization/localeResolver.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/localization/resolveBrowserLocale.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/localization/rewriteMatch.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/localization/rewriteUtils.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/localization/validatePrefix.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/markdown/index.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/condition/condition.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/condition/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/enumeration/enumeration.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/enumeration/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/file/file.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/file/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/gender/gender.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/gender/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/html/html.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/html/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/index.d.ts +22 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/insertion/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/insertion/insertion.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/markdown/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/markdown/markdown.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/nesting/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/nesting/nesting.d.ts +4 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/plural/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/plural/plural.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/select/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/select/select.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/translation/index.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/transpiler/translation/translation.d.ts +2 -0
- package/dist/types/@intlayer/core/dist/types/utils/index.d.ts +3 -0
- package/dist/types/@intlayer/core/dist/types/utils/intl.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/utils/isSameKeyPath.d.ts +1 -0
- package/dist/types/@intlayer/core/dist/types/utils/localeStorage.d.ts +2 -0
- package/dist/types/index.d.ts +5 -3
- package/dist/types/interpreter/getPlural.d.ts +1 -1
- package/dist/types/intlayer/dist/types/index.d.ts +14 -0
- package/dist/types/localization/getCanonicalPath.d.ts +19 -0
- package/dist/types/localization/getCanonicalPath.d.ts.map +1 -0
- package/dist/types/localization/getCanonicalPath.test-d.d.ts +1 -0
- package/dist/types/localization/getLocalizedPath.d.ts.map +1 -1
- package/dist/types/localization/index.d.ts +3 -1
- package/dist/types/localization/rewriteMatch.d.ts +20 -0
- package/dist/types/localization/rewriteMatch.d.ts.map +1 -0
- package/dist/types/localization/rewriteUtils.d.ts +2 -14
- package/dist/types/localization/rewriteUtils.d.ts.map +1 -1
- package/dist/types/markdown/compiler.d.ts.map +1 -1
- package/dist/types/markdown/constants.d.ts +11 -4
- package/dist/types/markdown/constants.d.ts.map +1 -1
- package/dist/types/markdown/index.d.ts +2 -2
- package/dist/types/markdown/parser.d.ts.map +1 -1
- package/dist/types/markdown/renderer.d.ts.map +1 -1
- package/dist/types/markdown/types.d.ts +8 -2
- package/dist/types/markdown/types.d.ts.map +1 -1
- package/dist/types/markdown/utils.d.ts +0 -4
- package/dist/types/markdown/utils.d.ts.map +1 -1
- package/package.json +7 -7
|
@@ -1,69 +1,9 @@
|
|
|
1
|
+
import { extractParams, fillPath, getRewriteRules } from "./rewriteMatch.mjs";
|
|
2
|
+
import { getCanonicalPath } from "./getCanonicalPath.mjs";
|
|
1
3
|
import { internationalization } from "@intlayer/config/built";
|
|
2
4
|
|
|
3
5
|
//#region src/localization/rewriteUtils.ts
|
|
4
6
|
/**
|
|
5
|
-
* Normalizes legacy Record format or extracts specialized rules from RewriteObject.
|
|
6
|
-
*
|
|
7
|
-
* Idempotent: already-normalized rules are handed back untouched, so a caller
|
|
8
|
-
* holding resolved rules can pass them on without re-normalizing.
|
|
9
|
-
*/
|
|
10
|
-
const getRewriteRules = (rewrite, context = "url") => {
|
|
11
|
-
if (!rewrite || process.env.INTLAYER_ROUTING_REWRITE_RULES && process.env.INTLAYER_ROUTING_REWRITE_RULES === "false") return void 0;
|
|
12
|
-
if (Array.isArray(rewrite.rules)) return rewrite;
|
|
13
|
-
if ("url" in rewrite) return rewrite[context];
|
|
14
|
-
return { rules: Object.entries(rewrite).map(([canonical, localized]) => ({
|
|
15
|
-
canonical: canonical.startsWith("/") ? canonical.replace(/\[([^\]]+)\]/g, ":$1") : `/${canonical.replace(/\[([^\]]+)\]/g, ":$1")}`,
|
|
16
|
-
localized: Object.fromEntries(Object.entries(localized).map(([locale, pattern]) => {
|
|
17
|
-
return [locale, pattern?.startsWith("/") ? pattern.replace(/\[([^\]]+)\]/g, ":$1") : `/${(pattern || "").replace(/\[([^\]]+)\]/g, ":$1")}`];
|
|
18
|
-
}))
|
|
19
|
-
})) };
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* Converts normalized pattern to Regex.
|
|
23
|
-
* Internal syntax supports:
|
|
24
|
-
* - :param -> ([^/]+) (one segment)
|
|
25
|
-
* - :param* -> (.*) (zero or more segments)
|
|
26
|
-
* - :param+ -> (.+) (one or more segments)
|
|
27
|
-
* - :param? -> ([^/]*) (zero or one segment)
|
|
28
|
-
*/
|
|
29
|
-
const patternToRegex = (pattern) => {
|
|
30
|
-
const regexString = pattern.replace(/\//g, "\\/").replace(/\\\/:(?:[^/\\*+?]+)\*/g, "(?:\\/(.*))?").replace(/\\\/:(?:[^/\\*+?]+)\?/g, "(?:\\/([^\\/]+))?").replace(/:([^/\\*+?]+)\*/g, "(.*)").replace(/:([^/\\*+?]+)\?/g, "([^\\/]*)").replace(/:([^/\\*+?]+)\+/g, "(.+)").replace(/:([^/\\*+?]+)/g, "([^\\/]+)");
|
|
31
|
-
return new RegExp(`^${regexString}$`);
|
|
32
|
-
};
|
|
33
|
-
/**
|
|
34
|
-
* Replaces route parameters in a path with provided values.
|
|
35
|
-
*/
|
|
36
|
-
const fillPath = (pattern, params) => {
|
|
37
|
-
let index = 0;
|
|
38
|
-
return pattern.replace(/:([^/\\*+?]+)[*+?]?/g, () => params[index++] ?? "").replace(/\/+/g, "/").replace(/\/$/, "") || "/";
|
|
39
|
-
};
|
|
40
|
-
/**
|
|
41
|
-
* Extract values from a URL based on a pattern.
|
|
42
|
-
*/
|
|
43
|
-
const extractParams = (url, pattern) => {
|
|
44
|
-
const regex = patternToRegex(pattern);
|
|
45
|
-
const match = url.match(regex);
|
|
46
|
-
return match ? match.slice(1) : null;
|
|
47
|
-
};
|
|
48
|
-
/**
|
|
49
|
-
* Given a localized URL (e.g., "/produits/123"), finds the canonical internal path (e.g., "/products/123").
|
|
50
|
-
* If locale is provided, only check for that locale. Otherwise, check for all locales.
|
|
51
|
-
*/
|
|
52
|
-
const getCanonicalPath = (localizedPath, locale, rewriteRules) => {
|
|
53
|
-
if (!rewriteRules || process.env.INTLAYER_ROUTING_REWRITE_RULES && process.env.INTLAYER_ROUTING_REWRITE_RULES === "false") return localizedPath;
|
|
54
|
-
for (const rule of rewriteRules.rules) {
|
|
55
|
-
const { canonical, localized } = rule;
|
|
56
|
-
const localesToCheck = locale ? [locale] : Object.keys(localized);
|
|
57
|
-
for (const loc of localesToCheck) {
|
|
58
|
-
const localizedPattern = localized[loc];
|
|
59
|
-
if (!localizedPattern) continue;
|
|
60
|
-
const params = extractParams(localizedPath, localizedPattern);
|
|
61
|
-
if (params) return fillPath(canonical, params);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return localizedPath;
|
|
65
|
-
};
|
|
66
|
-
/**
|
|
67
7
|
* Given a canonical path (e.g., "/products/123"), finds the localized URL pattern
|
|
68
8
|
* (e.g., "/produits/123") and reports whether a rule actually matched.
|
|
69
9
|
*
|
|
@@ -120,5 +60,5 @@ const getRewritePath = (pathname, locale, rewrite) => {
|
|
|
120
60
|
};
|
|
121
61
|
|
|
122
62
|
//#endregion
|
|
123
|
-
export {
|
|
63
|
+
export { getInternalPath, getRewritePath, resolveLocalizedPath };
|
|
124
64
|
//# sourceMappingURL=rewriteUtils.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rewriteUtils.mjs","names":["legacyRules"],"sources":["../../../src/localization/rewriteUtils.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type {\n RewriteObject,\n RewriteRules,\n RoutingConfig,\n} from '@intlayer/types/config';\nimport type {\n LocalesValues,\n ResolvedDefaultLocale,\n} from '@intlayer/types/module_augmentation';\n\n/**\n * Outcome of resolving a canonical path against the rewrite rules.\n *\n * Discriminated on `isRewritten`: when no rule matched, `path` is the very\n * input that was passed in, so a literal input keeps its literal type. Only a\n * rewritten path is computed at runtime and therefore widens to `string`.\n */\nexport type LocalizedPathResult<CanonicalPath extends string = string> =\n | { path: CanonicalPath; isRewritten: false }\n | { path: string; isRewritten: true };\n\n/** Adds the leading slash a path may be missing. */\ntype WithLeadingSlash<Path extends string> = Path extends `/${string}`\n ? Path\n : `/${Path}`;\n\n/**\n * Computes the locale-prefixed internal path for a path and a locale, mirroring\n * `getInternalPath`'s runtime behaviour: an already-prefixed path is returned\n * untouched, the root collapses to `/${Locale}` (never a trailing slash), and\n * anything else gets the prefix prepended.\n *\n * Falls back to `string` for a non-literal path, where the prefixed and\n * already-prefixed cases cannot be told apart.\n *\n * @example\n * type A = InternalPath<'/about', 'fr'>; // '/fr/about'\n * type B = InternalPath<'/', 'fr'>; // '/fr'\n * type C = InternalPath<'/fr/about', 'fr'>; // '/fr/about' (already prefixed)\n */\nexport type InternalPath<\n Path extends string,\n Locale extends string,\n> = string extends Path\n ? string\n : WithLeadingSlash<Path> extends infer Prefixed extends string\n ? Prefixed extends `/${Locale}` | `/${Locale}/${string}`\n ? Prefixed\n : Prefixed extends '/'\n ? `/${Locale}`\n : `/${Locale}${Prefixed}`\n : never;\n\n/**\n * Normalizes legacy Record format or extracts specialized rules from RewriteObject.\n *\n * Idempotent: already-normalized rules are handed back untouched, so a caller\n * holding resolved rules can pass them on without re-normalizing.\n */\nexport const getRewriteRules = <\n const Context extends keyof RewriteObject = 'url',\n>(\n rewrite: RoutingConfig['rewrite'] | RewriteRules,\n context: Context = 'url' as Context\n): RewriteRules | undefined => {\n if (\n !rewrite ||\n (process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false')\n )\n return undefined;\n\n if (Array.isArray((rewrite as RewriteRules).rules)) {\n return rewrite as RewriteRules;\n }\n\n if ('url' in rewrite) {\n return (rewrite as RewriteObject)[context];\n }\n\n // Normalize legacy format\n const legacyRules = rewrite as Record<string, Record<string, string>>;\n\n return {\n rules: Object.entries(legacyRules).map(([canonical, localized]) => ({\n // Normalize canonical path\n canonical: canonical.startsWith('/')\n ? canonical.replace(/\\[([^\\]]+)\\]/g, ':$1')\n : `/${canonical.replace(/\\[([^\\]]+)\\]/g, ':$1')}`,\n\n // Normalize localized path\n localized: Object.fromEntries(\n Object.entries(localized).map(([locale, pattern]) => {\n const normalizedPattern = pattern?.startsWith('/')\n ? pattern.replace(/\\[([^\\]]+)\\]/g, ':$1')\n : `/${(pattern || '').replace(/\\[([^\\]]+)\\]/g, ':$1')}`;\n return [locale, normalizedPattern];\n })\n ),\n })),\n };\n};\n\n/**\n * Converts normalized pattern to Regex.\n * Internal syntax supports:\n * - :param -> ([^/]+) (one segment)\n * - :param* -> (.*) (zero or more segments)\n * - :param+ -> (.+) (one or more segments)\n * - :param? -> ([^/]*) (zero or one segment)\n */\nconst patternToRegex = (pattern: string) => {\n const regexString = pattern\n .replace(/\\//g, '\\\\/') // Escape slashes\n .replace(/\\\\\\/:(?:[^/\\\\*+?]+)\\*/g, '(?:\\\\/(.*))?') // /:param*\n .replace(/\\\\\\/:(?:[^/\\\\*+?]+)\\?/g, '(?:\\\\/([^\\\\/]+))?') // /:param?\n .replace(/:([^/\\\\*+?]+)\\*/g, '(.*)') // :param* (if no leading slash)\n .replace(/:([^/\\\\*+?]+)\\?/g, '([^\\\\/]*)') // :param? (if no leading slash)\n .replace(/:([^/\\\\*+?]+)\\+/g, '(.+)') // :param+\n .replace(/:([^/\\\\*+?]+)/g, '([^\\\\/]+)'); // :param\n\n return new RegExp(`^${regexString}$`);\n};\n\n/**\n * Replaces route parameters in a path with provided values.\n */\nconst fillPath = (pattern: string, params: string[]) => {\n let index = 0;\n return (\n pattern\n .replace(/:([^/\\\\*+?]+)[*+?]?/g, () => params[index++] ?? '')\n .replace(/\\/+/g, '/')\n .replace(/\\/$/, '') || '/'\n );\n};\n\n/**\n * Extract values from a URL based on a pattern.\n */\nconst extractParams = (url: string, pattern: string): string[] | null => {\n const regex = patternToRegex(pattern);\n const match = url.match(regex);\n return match ? match.slice(1) : null;\n};\n\n/**\n * Given a localized URL (e.g., \"/produits/123\"), finds the canonical internal path (e.g., \"/products/123\").\n * If locale is provided, only check for that locale. Otherwise, check for all locales.\n */\nexport const getCanonicalPath = <\n const Path extends string,\n const Locale extends LocalesValues = LocalesValues,\n>(\n localizedPath: Path,\n locale?: Locale,\n rewriteRules?: RewriteRules\n): string => {\n if (\n !rewriteRules ||\n (process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false')\n )\n return localizedPath;\n\n for (const rule of rewriteRules.rules) {\n const { canonical, localized } = rule;\n const localesToCheck = locale ? [locale] : Object.keys(localized);\n\n for (const loc of localesToCheck) {\n const localizedPattern = localized[loc as keyof typeof localized];\n\n if (!localizedPattern) continue;\n\n const params = extractParams(localizedPath, localizedPattern);\n\n if (params) {\n return fillPath(canonical, params);\n }\n }\n }\n\n return localizedPath;\n};\n\n/**\n * Given a canonical path (e.g., \"/products/123\"), finds the localized URL pattern\n * (e.g., \"/produits/123\") and reports whether a rule actually matched.\n *\n * Takes already-normalized rules, so callers that resolve the rules once (proxies,\n * static emitters) can reuse them. {@link getLocalizedPath} is the user-facing\n * counterpart: it accepts the raw `routing.rewrite` configuration, defaults to the\n * project configuration, and returns the path alone.\n *\n * @param canonicalPath - The internal application path (e.g. `/product/:id`, `/about`).\n * @param locale - The target locale. Defaults to the configured default locale.\n * @param rewriteRules - Normalized rules, as returned by {@link getRewriteRules}.\n * @returns The localized path, discriminated on whether a rewrite rule matched.\n */\nexport const resolveLocalizedPath = <\n const CanonicalPath extends string,\n const Locale extends LocalesValues = ResolvedDefaultLocale,\n>(\n canonicalPath: CanonicalPath,\n locale?: Locale,\n rewriteRules?: RewriteRules\n): LocalizedPathResult<CanonicalPath> => {\n if (\n !rewriteRules ||\n (process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false')\n )\n return { path: canonicalPath, isRewritten: false };\n\n for (const rule of rewriteRules.rules) {\n const { canonical, localized } = rule;\n\n // Check if the input path matches a configured canonical pattern\n const params = extractParams(canonicalPath, canonical);\n\n if (params) {\n const targetLocale = locale ?? internationalization.defaultLocale;\n const targetPattern = localized[targetLocale as keyof typeof localized];\n\n if (targetPattern) {\n return {\n path: fillPath(targetPattern, params),\n isRewritten: true,\n };\n }\n }\n }\n\n return { path: canonicalPath, isRewritten: false };\n};\n\n/**\n * Returns the internal path for a given canonical path and locale.\n * Ensures the locale prefix is present exactly once.\n */\nexport const getInternalPath = <\n const Path extends string,\n const Locale extends LocalesValues,\n>(\n canonicalPath: Path,\n locale: Locale\n): InternalPath<Path, Locale> => {\n const pathWithLeadingSlash = canonicalPath.startsWith('/')\n ? canonicalPath\n : `/${canonicalPath}`;\n\n if (\n pathWithLeadingSlash.startsWith(`/${locale}/`) ||\n pathWithLeadingSlash === `/${locale}`\n ) {\n return pathWithLeadingSlash as InternalPath<Path, Locale>;\n }\n\n return `/${locale}${\n pathWithLeadingSlash === '/' ? '' : pathWithLeadingSlash\n }` as InternalPath<Path, Locale>;\n};\n\n/**\n * Given a current pathname and locale, returns the pretty localized path if a rewrite rule exists and the path is not already localized.\n */\nexport const getRewritePath = <\n const Path extends string,\n const Locale extends LocalesValues = ResolvedDefaultLocale,\n>(\n pathname: Path,\n locale: Locale,\n rewrite?: RoutingConfig['rewrite']\n): string | undefined => {\n if (\n process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false'\n )\n return undefined;\n const rules = getRewriteRules(rewrite, 'url');\n if (!rules) return undefined;\n\n // Identify canonical path (relative to root, no locale prefix expected in 'url' context)\n const canonicalPath = getCanonicalPath(pathname, undefined, rules);\n\n // Get the localized path for the current locale\n const { path: localizedPath, isRewritten } = resolveLocalizedPath(\n canonicalPath,\n locale,\n rules\n );\n\n if (isRewritten && localizedPath !== pathname) {\n return localizedPath;\n }\n\n return undefined;\n};\n"],"mappings":";;;;;;;;;AA4DA,MAAa,mBAGX,SACA,UAAmB,UACU;CAC7B,IACE,CAAC,WACA,QAAQ,IAAI,kCACX,QAAQ,IAAI,mCAAmC,SAEjD,OAAO;CAET,IAAI,MAAM,QAAS,QAAyB,KAAK,GAC/C,OAAO;CAGT,IAAI,SAAS,SACX,OAAQ,QAA0B;CAMpC,OAAO,EACL,OAAO,OAAO,QAAQA,OAAW,CAAC,CAAC,KAAK,CAAC,WAAW,gBAAgB;EAElE,WAAW,UAAU,WAAW,GAAG,IAC/B,UAAU,QAAQ,iBAAiB,KAAK,IACxC,IAAI,UAAU,QAAQ,iBAAiB,KAAK;EAGhD,WAAW,OAAO,YAChB,OAAO,QAAQ,SAAS,CAAC,CAAC,KAAK,CAAC,QAAQ,aAAa;GAInD,OAAO,CAAC,QAHkB,SAAS,WAAW,GAAG,IAC7C,QAAQ,QAAQ,iBAAiB,KAAK,IACtC,KAAK,WAAW,GAAE,CAAE,QAAQ,iBAAiB,KAAK,GACrB;EACnC,CAAC,CACH;CACF,EAAE,EACJ;AACF;;;;;;;;;AAUA,MAAM,kBAAkB,YAAoB;CAC1C,MAAM,cAAc,QACjB,QAAQ,OAAO,KAAK,CAAC,CACrB,QAAQ,0BAA0B,cAAc,CAAC,CACjD,QAAQ,0BAA0B,mBAAmB,CAAC,CACtD,QAAQ,oBAAoB,MAAM,CAAC,CACnC,QAAQ,oBAAoB,WAAW,CAAC,CACxC,QAAQ,oBAAoB,MAAM,CAAC,CACnC,QAAQ,kBAAkB,WAAW;CAExC,OAAO,IAAI,OAAO,IAAI,YAAY,EAAE;AACtC;;;;AAKA,MAAM,YAAY,SAAiB,WAAqB;CACtD,IAAI,QAAQ;CACZ,OACE,QACG,QAAQ,8BAA8B,OAAO,YAAY,EAAE,CAAC,CAC5D,QAAQ,QAAQ,GAAG,CAAC,CACpB,QAAQ,OAAO,EAAE,KAAK;AAE7B;;;;AAKA,MAAM,iBAAiB,KAAa,YAAqC;CACvE,MAAM,QAAQ,eAAe,OAAO;CACpC,MAAM,QAAQ,IAAI,MAAM,KAAK;CAC7B,OAAO,QAAQ,MAAM,MAAM,CAAC,IAAI;AAClC;;;;;AAMA,MAAa,oBAIX,eACA,QACA,iBACW;CACX,IACE,CAAC,gBACA,QAAQ,IAAI,kCACX,QAAQ,IAAI,mCAAmC,SAEjD,OAAO;CAET,KAAK,MAAM,QAAQ,aAAa,OAAO;EACrC,MAAM,EAAE,WAAW,cAAc;EACjC,MAAM,iBAAiB,SAAS,CAAC,MAAM,IAAI,OAAO,KAAK,SAAS;EAEhE,KAAK,MAAM,OAAO,gBAAgB;GAChC,MAAM,mBAAmB,UAAU;GAEnC,IAAI,CAAC,kBAAkB;GAEvB,MAAM,SAAS,cAAc,eAAe,gBAAgB;GAE5D,IAAI,QACF,OAAO,SAAS,WAAW,MAAM;EAErC;CACF;CAEA,OAAO;AACT;;;;;;;;;;;;;;;AAgBA,MAAa,wBAIX,eACA,QACA,iBACuC;CACvC,IACE,CAAC,gBACA,QAAQ,IAAI,kCACX,QAAQ,IAAI,mCAAmC,SAEjD,OAAO;EAAE,MAAM;EAAe,aAAa;CAAM;CAEnD,KAAK,MAAM,QAAQ,aAAa,OAAO;EACrC,MAAM,EAAE,WAAW,cAAc;EAGjC,MAAM,SAAS,cAAc,eAAe,SAAS;EAErD,IAAI,QAAQ;GAEV,MAAM,gBAAgB,UADD,UAAU,qBAAqB;GAGpD,IAAI,eACF,OAAO;IACL,MAAM,SAAS,eAAe,MAAM;IACpC,aAAa;GACf;EAEJ;CACF;CAEA,OAAO;EAAE,MAAM;EAAe,aAAa;CAAM;AACnD;;;;;AAMA,MAAa,mBAIX,eACA,WAC+B;CAC/B,MAAM,uBAAuB,cAAc,WAAW,GAAG,IACrD,gBACA,IAAI;CAER,IACE,qBAAqB,WAAW,IAAI,OAAO,EAAE,KAC7C,yBAAyB,IAAI,UAE7B,OAAO;CAGT,OAAO,IAAI,SACT,yBAAyB,MAAM,KAAK;AAExC;;;;AAKA,MAAa,kBAIX,UACA,QACA,YACuB;CACvB,IACE,QAAQ,IAAI,kCACZ,QAAQ,IAAI,mCAAmC,SAE/C,OAAO;CACT,MAAM,QAAQ,gBAAgB,SAAS,KAAK;CAC5C,IAAI,CAAC,OAAO,OAAO;CAGnB,MAAM,gBAAgB,iBAAiB,UAAU,QAAW,KAAK;CAGjE,MAAM,EAAE,MAAM,eAAe,gBAAgB,qBAC3C,eACA,QACA,KACF;CAEA,IAAI,eAAe,kBAAkB,UACnC,OAAO;AAIX"}
|
|
1
|
+
{"version":3,"file":"rewriteUtils.mjs","names":[],"sources":["../../../src/localization/rewriteUtils.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { RewriteRules, RoutingConfig } from '@intlayer/types/config';\nimport type {\n LocalesValues,\n ResolvedDefaultLocale,\n} from '@intlayer/types/module_augmentation';\nimport { getCanonicalPath } from './getCanonicalPath';\nimport { extractParams, fillPath, getRewriteRules } from './rewriteMatch';\n\n/**\n * Outcome of resolving a canonical path against the rewrite rules.\n *\n * Discriminated on `isRewritten`: when no rule matched, `path` is the very\n * input that was passed in, so a literal input keeps its literal type. Only a\n * rewritten path is computed at runtime and therefore widens to `string`.\n */\nexport type LocalizedPathResult<CanonicalPath extends string = string> =\n | { path: CanonicalPath; isRewritten: false }\n | { path: string; isRewritten: true };\n\n/** Adds the leading slash a path may be missing. */\ntype WithLeadingSlash<Path extends string> = Path extends `/${string}`\n ? Path\n : `/${Path}`;\n\n/**\n * Computes the locale-prefixed internal path for a path and a locale, mirroring\n * `getInternalPath`'s runtime behaviour: an already-prefixed path is returned\n * untouched, the root collapses to `/${Locale}` (never a trailing slash), and\n * anything else gets the prefix prepended.\n *\n * Falls back to `string` for a non-literal path, where the prefixed and\n * already-prefixed cases cannot be told apart.\n *\n * @example\n * type A = InternalPath<'/about', 'fr'>; // '/fr/about'\n * type B = InternalPath<'/', 'fr'>; // '/fr'\n * type C = InternalPath<'/fr/about', 'fr'>; // '/fr/about' (already prefixed)\n */\nexport type InternalPath<\n Path extends string,\n Locale extends string,\n> = string extends Path\n ? string\n : WithLeadingSlash<Path> extends infer Prefixed extends string\n ? Prefixed extends `/${Locale}` | `/${Locale}/${string}`\n ? Prefixed\n : Prefixed extends '/'\n ? `/${Locale}`\n : `/${Locale}${Prefixed}`\n : never;\n\n/**\n * Given a canonical path (e.g., \"/products/123\"), finds the localized URL pattern\n * (e.g., \"/produits/123\") and reports whether a rule actually matched.\n *\n * Takes already-normalized rules, so callers that resolve the rules once (proxies,\n * static emitters) can reuse them. {@link getLocalizedPath} is the user-facing\n * counterpart: it accepts the raw `routing.rewrite` configuration, defaults to the\n * project configuration, and returns the path alone.\n *\n * @param canonicalPath - The internal application path (e.g. `/product/:id`, `/about`).\n * @param locale - The target locale. Defaults to the configured default locale.\n * @param rewriteRules - Normalized rules, as returned by {@link getRewriteRules}.\n * @returns The localized path, discriminated on whether a rewrite rule matched.\n */\nexport const resolveLocalizedPath = <\n const CanonicalPath extends string,\n const Locale extends LocalesValues = ResolvedDefaultLocale,\n>(\n canonicalPath: CanonicalPath,\n locale?: Locale,\n rewriteRules?: RewriteRules\n): LocalizedPathResult<CanonicalPath> => {\n if (\n !rewriteRules ||\n (process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false')\n )\n return { path: canonicalPath, isRewritten: false };\n\n for (const rule of rewriteRules.rules) {\n const { canonical, localized } = rule;\n\n // Check if the input path matches a configured canonical pattern\n const params = extractParams(canonicalPath, canonical);\n\n if (params) {\n const targetLocale = locale ?? internationalization.defaultLocale;\n const targetPattern = localized[targetLocale as keyof typeof localized];\n\n if (targetPattern) {\n return {\n path: fillPath(targetPattern, params),\n isRewritten: true,\n };\n }\n }\n }\n\n return { path: canonicalPath, isRewritten: false };\n};\n\n/**\n * Returns the internal path for a given canonical path and locale.\n * Ensures the locale prefix is present exactly once.\n */\nexport const getInternalPath = <\n const Path extends string,\n const Locale extends LocalesValues,\n>(\n canonicalPath: Path,\n locale: Locale\n): InternalPath<Path, Locale> => {\n const pathWithLeadingSlash = canonicalPath.startsWith('/')\n ? canonicalPath\n : `/${canonicalPath}`;\n\n if (\n pathWithLeadingSlash.startsWith(`/${locale}/`) ||\n pathWithLeadingSlash === `/${locale}`\n ) {\n return pathWithLeadingSlash as InternalPath<Path, Locale>;\n }\n\n return `/${locale}${\n pathWithLeadingSlash === '/' ? '' : pathWithLeadingSlash\n }` as InternalPath<Path, Locale>;\n};\n\n/**\n * Given a current pathname and locale, returns the pretty localized path if a rewrite rule exists and the path is not already localized.\n */\nexport const getRewritePath = <\n const Path extends string,\n const Locale extends LocalesValues = ResolvedDefaultLocale,\n>(\n pathname: Path,\n locale: Locale,\n rewrite?: RoutingConfig['rewrite']\n): string | undefined => {\n if (\n process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false'\n )\n return undefined;\n const rules = getRewriteRules(rewrite, 'url');\n if (!rules) return undefined;\n\n // Identify canonical path (relative to root, no locale prefix expected in 'url' context)\n const canonicalPath = getCanonicalPath(pathname, undefined, rules);\n\n // Get the localized path for the current locale\n const { path: localizedPath, isRewritten } = resolveLocalizedPath(\n canonicalPath,\n locale,\n rules\n );\n\n if (isRewritten && localizedPath !== pathname) {\n return localizedPath;\n }\n\n return undefined;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkEA,MAAa,wBAIX,eACA,QACA,iBACuC;CACvC,IACE,CAAC,gBACA,QAAQ,IAAI,kCACX,QAAQ,IAAI,mCAAmC,SAEjD,OAAO;EAAE,MAAM;EAAe,aAAa;CAAM;CAEnD,KAAK,MAAM,QAAQ,aAAa,OAAO;EACrC,MAAM,EAAE,WAAW,cAAc;EAGjC,MAAM,SAAS,cAAc,eAAe,SAAS;EAErD,IAAI,QAAQ;GAEV,MAAM,gBAAgB,UADD,UAAU,qBAAqB;GAGpD,IAAI,eACF,OAAO;IACL,MAAM,SAAS,eAAe,MAAM;IACpC,aAAa;GACf;EAEJ;CACF;CAEA,OAAO;EAAE,MAAM;EAAe,aAAa;CAAM;AACnD;;;;;AAMA,MAAa,mBAIX,eACA,WAC+B;CAC/B,MAAM,uBAAuB,cAAc,WAAW,GAAG,IACrD,gBACA,IAAI;CAER,IACE,qBAAqB,WAAW,IAAI,OAAO,EAAE,KAC7C,yBAAyB,IAAI,UAE7B,OAAO;CAGT,OAAO,IAAI,SACT,yBAAyB,MAAM,KAAK;AAExC;;;;AAKA,MAAa,kBAIX,UACA,QACA,YACuB;CACvB,IACE,QAAQ,IAAI,kCACZ,QAAQ,IAAI,mCAAmC,SAE/C,OAAO;CACT,MAAM,QAAQ,gBAAgB,SAAS,KAAK;CAC5C,IAAI,CAAC,OAAO,OAAO;CAGnB,MAAM,gBAAgB,iBAAiB,UAAU,QAAW,KAAK;CAGjE,MAAM,EAAE,MAAM,eAAe,gBAAgB,qBAC3C,eACA,QACA,KACF;CAEA,IAAI,eAAe,kBAAkB,UACnC,OAAO;AAIX"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getInternalPath, resolveLocalizedPath } from "./rewriteUtils.mjs";
|
|
2
2
|
import { describe, expectTypeOf, it } from "vitest";
|
|
3
3
|
|
|
4
4
|
//#region src/localization/rewriteUtils.test-d.ts
|
|
@@ -38,11 +38,6 @@ describe("resolveLocalizedPath", () => {
|
|
|
38
38
|
expectTypeOf(resolveLocalizedPath("/about")).toEqualTypeOf();
|
|
39
39
|
});
|
|
40
40
|
});
|
|
41
|
-
describe("getCanonicalPath", () => {
|
|
42
|
-
it("should accept an omitted locale (checks every locale)", () => {
|
|
43
|
-
expectTypeOf(getCanonicalPath("/a-propos")).toEqualTypeOf();
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
41
|
|
|
47
42
|
//#endregion
|
|
48
43
|
//# sourceMappingURL=rewriteUtils.test-d.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rewriteUtils.test-d.mjs","names":[],"sources":["../../../src/localization/rewriteUtils.test-d.ts"],"sourcesContent":["import { describe, expectTypeOf, it } from 'vitest';\nimport {
|
|
1
|
+
{"version":3,"file":"rewriteUtils.test-d.mjs","names":[],"sources":["../../../src/localization/rewriteUtils.test-d.ts"],"sourcesContent":["import { describe, expectTypeOf, it } from 'vitest';\nimport { getInternalPath, resolveLocalizedPath } from './rewriteUtils';\n\n/**\n * `getInternalPath` is pure string surgery — no rewrite rules involved — so its\n * result is fully derivable from the arguments whenever both are literals.\n */\ndescribe('getInternalPath', () => {\n it('should prefix a literal path with the locale', () => {\n expectTypeOf(getInternalPath('/about', 'fr')).toEqualTypeOf<'/fr/about'>();\n });\n\n it('should collapse the root to a bare prefix, never a trailing slash', () => {\n expectTypeOf(getInternalPath('/', 'fr')).toEqualTypeOf<'/fr'>();\n });\n\n it('should leave an already-prefixed path untouched', () => {\n expectTypeOf(\n getInternalPath('/fr/about', 'fr')\n ).toEqualTypeOf<'/fr/about'>();\n expectTypeOf(getInternalPath('/fr', 'fr')).toEqualTypeOf<'/fr'>();\n });\n\n it('should add the leading slash a path is missing', () => {\n expectTypeOf(getInternalPath('about', 'fr')).toEqualTypeOf<'/fr/about'>();\n });\n\n it('should widen to string when the path is not a literal', () => {\n const dynamicPath = '/about' as string;\n\n expectTypeOf(getInternalPath(dynamicPath, 'fr')).toEqualTypeOf<string>();\n });\n});\n\n/**\n * `resolveLocalizedPath` only computes a new path when a rule matched, so the\n * `isRewritten: false` branch still carries the exact input it was given.\n */\ndescribe('resolveLocalizedPath', () => {\n it('should keep the input literal on the non-rewritten branch', () => {\n const result = resolveLocalizedPath('/about', 'fr');\n\n if (!result.isRewritten) {\n expectTypeOf(result.path).toEqualTypeOf<'/about'>();\n } else {\n expectTypeOf(result.path).toEqualTypeOf<string>();\n }\n });\n\n it('should discriminate on isRewritten', () => {\n expectTypeOf(resolveLocalizedPath('/about')).toEqualTypeOf<\n | { path: '/about'; isRewritten: false }\n | { path: string; isRewritten: true }\n >();\n });\n});\n"],"mappings":";;;;;;;;AAOA,SAAS,yBAAyB;CAChC,GAAG,sDAAsD;EACvD,aAAa,gBAAgB,UAAU,IAAI,CAAC,CAAC,CAAC,cAA2B;CAC3E,CAAC;CAED,GAAG,2EAA2E;EAC5E,aAAa,gBAAgB,KAAK,IAAI,CAAC,CAAC,CAAC,cAAqB;CAChE,CAAC;CAED,GAAG,yDAAyD;EAC1D,aACE,gBAAgB,aAAa,IAAI,CACnC,CAAC,CAAC,cAA2B;EAC7B,aAAa,gBAAgB,OAAO,IAAI,CAAC,CAAC,CAAC,cAAqB;CAClE,CAAC;CAED,GAAG,wDAAwD;EACzD,aAAa,gBAAgB,SAAS,IAAI,CAAC,CAAC,CAAC,cAA2B;CAC1E,CAAC;CAED,GAAG,+DAA+D;EAGhE,aAAa,gBAAgB,UAAa,IAAI,CAAC,CAAC,CAAC,cAAsB;CACzE,CAAC;AACH,CAAC;;;;;AAMD,SAAS,8BAA8B;CACrC,GAAG,mEAAmE;EACpE,MAAM,SAAS,qBAAqB,UAAU,IAAI;EAElD,IAAI,CAAC,OAAO,aACV,aAAa,OAAO,IAAI,CAAC,CAAC,cAAwB;OAElD,aAAa,OAAO,IAAI,CAAC,CAAC,cAAsB;CAEpD,CAAC;CAED,GAAG,4CAA4C;EAC7C,aAAa,qBAAqB,QAAQ,CAAC,CAAC,CAAC,cAG3C;CACJ,CAAC;AACH,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ATTRIBUTE_TO_NODE_PROP_MAP, ATTR_EXTRACTOR_R, BLOCKQUOTE_ALERT_R, BLOCKQUOTE_R, BLOCKQUOTE_TRIM_LEFT_MULTILINE_R, BLOCK_END_R, BREAK_LINE_R, BREAK_THEMATIC_R, CODE_BLOCK_FENCED_R, CODE_BLOCK_R, CODE_INLINE_R, CONSECUTIVE_NEWLINE_R, CUSTOM_COMPONENT_R, DO_NOT_PROCESS_HTML_ELEMENTS, FOOTNOTE_R, FOOTNOTE_REFERENCE_R, FRONT_MATTER_R, GFM_TASK_R, HEADING_ATX_COMPLIANT_R, HEADING_R, HEADING_SETEXT_R, HTML_BLOCK_ELEMENT_R, HTML_CHAR_CODE_R, HTML_COMMENT_R, HTML_LEFT_TRIM_AMOUNT_R, HTML_SELF_CLOSING_ELEMENT_R, LINK_AUTOLINK_BARE_URL_R, LINK_AUTOLINK_R,
|
|
1
|
+
import { ATTRIBUTE_TO_NODE_PROP_MAP, ATTR_EXTRACTOR_R, BLOCKQUOTE_ALERT_R, BLOCKQUOTE_R, BLOCKQUOTE_TRIM_LEFT_MULTILINE_R, BLOCK_END_R, BREAK_LINE_R, BREAK_THEMATIC_R, CODE_BLOCK_FENCED_R, CODE_BLOCK_R, CODE_INLINE_R, CONSECUTIVE_NEWLINE_R, CUSTOM_COMPONENT_OPENING_TAG_R, CUSTOM_COMPONENT_R, DO_NOT_PROCESS_HTML_ELEMENTS, FOOTNOTE_R, FOOTNOTE_REFERENCE_R, FRONT_MATTER_R, GFM_TASK_R, HEADING_ATX_COMPLIANT_R, HEADING_R, HEADING_SETEXT_R, HTML_BLOCK_ELEMENT_R, HTML_BLOCK_OPENING_TAG_R, HTML_CHAR_CODE_R, HTML_COMMENT_R, HTML_LEFT_TRIM_AMOUNT_R, HTML_SELF_CLOSING_ELEMENT_R, HTML_SELF_CLOSING_OPENING_TAG_R, LINK_AUTOLINK_BARE_URL_R, LINK_AUTOLINK_R, NAMED_CODES_TO_UNICODE, NP_TABLE_R, ORDERED, ORDERED_LIST_ITEM_PREFIX_R, ORDERED_LIST_ITEM_R, ORDERED_LIST_R, PARAGRAPH_R, Priority, REFERENCE_IMAGE_OR_LINK, REFERENCE_IMAGE_R, REFERENCE_LINK_R, RuleType, SHORTCODE_R, SHOULD_RENDER_AS_BLOCK_R, TEXT_BOLD_R, TEXT_EMPHASIZED_R, TEXT_ESCAPED_R, TEXT_MARKED_R, TEXT_PLAIN_R, TEXT_STRIKETHROUGHED_R, TRIM_STARTING_NEWLINES, UNORDERED, UNORDERED_LIST_ITEM_PREFIX_R, UNORDERED_LIST_ITEM_R, UNORDERED_LIST_R } from "./constants.mjs";
|
|
2
2
|
import { allowInline, anyScopeRegex, attributeValueToNodePropValue, blockRegex, captureNothing, cx, get, inlineRegex, normalizeAttributeKey, parseBlock, parseCaptureInline, parseInline, parseSimpleInline, parseTableAlign, parseTableCells, parseTableRow, renderNothing, sanitizer, simpleInlineRegex, slugify, some, startsWith, trimEnd, trimLeadingWhitespaceOutsideFences, unescapeString, unquote } from "./utils.mjs";
|
|
3
3
|
import { parserFor } from "./parser.mjs";
|
|
4
4
|
import { createRenderer, renderFor } from "./renderer.mjs";
|
|
@@ -6,19 +6,49 @@ import { createRenderer, renderFor } from "./renderer.mjs";
|
|
|
6
6
|
//#region src/markdown/compiler.ts
|
|
7
7
|
const IMAGE_R = /^!\[(.*?)\]\( *((?:\([^)]*\)|[^() ])*) *"?([^)"]*)?"?\)/;
|
|
8
8
|
const LINK_R = new RegExp(`^\\[((?:\\[[^\\[\\]]*(?:\\[[^\\[\\]]*\\][^\\[\\]]*)*\\]|[^\\[\\]])*)\\]\\(\\s*<?((?:\\([^)]*\\)|[^\\s\\\\]|\\\\.)*?)>?(?:\\s+['"]([\\s\\S]*?)['"])?\\s*\\)`);
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Case-insensitive `</tag>` probes, cached per tag name.
|
|
11
|
+
*
|
|
12
|
+
* The `htmlBlock` rule is qualified at every candidate position, and it used to
|
|
13
|
+
* lowercase the whole remaining document to look its closing tag up — copying
|
|
14
|
+
* the rest of the file on each probe.
|
|
15
|
+
*/
|
|
16
|
+
const closingTagRegexCache = /* @__PURE__ */ new Map();
|
|
17
|
+
const getClosingTagRegex = (tag) => {
|
|
18
|
+
const cached = closingTagRegexCache.get(tag);
|
|
19
|
+
if (cached) return cached;
|
|
20
|
+
const regex = new RegExp(`</${tag}>`, "i");
|
|
21
|
+
closingTagRegexCache.set(tag, regex);
|
|
22
|
+
return regex;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Builds a tag -> component resolver for one set of overrides.
|
|
26
|
+
*
|
|
27
|
+
* The case-insensitive fallback used to rescan every override key on each
|
|
28
|
+
* element created; the lowercase index is now built once per document instead.
|
|
29
|
+
*/
|
|
30
|
+
const createTagResolver = (components) => {
|
|
31
|
+
let lowercaseKeys = null;
|
|
32
|
+
return (tag) => {
|
|
33
|
+
if (typeof tag !== "string") return tag;
|
|
34
|
+
const override = get(components, tag);
|
|
35
|
+
if (override) return override;
|
|
36
|
+
if (!lowercaseKeys) {
|
|
37
|
+
lowercaseKeys = /* @__PURE__ */ new Map();
|
|
38
|
+
for (const key of Object.keys(components)) {
|
|
39
|
+
const lowercased = key.toLowerCase();
|
|
40
|
+
if (!lowercaseKeys.has(lowercased)) lowercaseKeys.set(lowercased, key);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const key = lowercaseKeys.get(tag.toLowerCase());
|
|
44
|
+
return (key ? get(components, key) : void 0) || tag;
|
|
45
|
+
};
|
|
19
46
|
};
|
|
47
|
+
/** Resolves the slugifier for a context, falling back to the built-in one. */
|
|
48
|
+
const createSlugger = (ctx) => (input) => ctx.slugify ? ctx.slugify(input, slugify) : slugify(input);
|
|
20
49
|
const createElementFactory = (ctx, options) => {
|
|
21
50
|
const { runtime, components = {} } = ctx;
|
|
51
|
+
const resolveTag = createTagResolver(components);
|
|
22
52
|
const filteredTags = options.tagfilter ? [
|
|
23
53
|
"title",
|
|
24
54
|
"textarea",
|
|
@@ -49,14 +79,12 @@ const createElementFactory = (ctx, options) => {
|
|
|
49
79
|
if (!classNameHandled && className) mergedProps.className = className;
|
|
50
80
|
let finalProps = mergedProps;
|
|
51
81
|
if (runtime.normalizeProps && isStringTag) finalProps = runtime.normalizeProps(tag, mergedProps);
|
|
52
|
-
const component =
|
|
82
|
+
const component = resolveTag(tag);
|
|
53
83
|
return runtime.createElement(component, finalProps, ...children.length === 1 ? [children[0]] : children);
|
|
54
84
|
};
|
|
55
85
|
};
|
|
56
86
|
const createRules = (createElement, ctx, options, footnotes, refs, attrStringToMap, containsBlockSyntax, nonParagraphBlockSyntaxes) => {
|
|
57
|
-
const slug = (
|
|
58
|
-
return ctx.slugify ? ctx.slugify(input, slugify) : slugify(input);
|
|
59
|
-
};
|
|
87
|
+
const slug = createSlugger(ctx);
|
|
60
88
|
const sanitize = ctx.sanitizer ?? sanitizer;
|
|
61
89
|
const namedCodesToUnicode = ctx.namedCodesToUnicode ? {
|
|
62
90
|
...NAMED_CODES_TO_UNICODE,
|
|
@@ -70,10 +98,11 @@ const createRules = (createElement, ctx, options, footnotes, refs, attrStringToM
|
|
|
70
98
|
return {
|
|
71
99
|
_qualify: (source) => LIST_ITEM_PREFIX_R.test(source),
|
|
72
100
|
_match: allowInline((source, state) => {
|
|
73
|
-
const
|
|
101
|
+
const lineIndent = state.prevCaptureIndent;
|
|
102
|
+
const isStartOfLine = lineIndent !== void 0;
|
|
74
103
|
const isListAllowed = state.list ?? (!state.inline && !state.simple);
|
|
75
104
|
if (isStartOfLine && isListAllowed) {
|
|
76
|
-
const matchSource =
|
|
105
|
+
const matchSource = lineIndent ? lineIndent + source : source;
|
|
77
106
|
return LIST_R.exec(matchSource);
|
|
78
107
|
}
|
|
79
108
|
return null;
|
|
@@ -127,7 +156,7 @@ const createRules = (createElement, ctx, options, footnotes, refs, attrStringToM
|
|
|
127
156
|
};
|
|
128
157
|
};
|
|
129
158
|
const matchParagraph = (source, state) => {
|
|
130
|
-
if (state.inline || state.simple || state.inHTML && source.indexOf("\n\n") === -1 && state.
|
|
159
|
+
if (state.inline || state.simple || state.inHTML && source.indexOf("\n\n") === -1 && !state.prevCaptureHasBlankLine) return null;
|
|
131
160
|
let start = 0;
|
|
132
161
|
while (true) {
|
|
133
162
|
const newlineIndex = source.indexOf("\n", start);
|
|
@@ -327,10 +356,9 @@ const createRules = (createElement, ctx, options, footnotes, refs, attrStringToM
|
|
|
327
356
|
[RuleType.htmlBlock]: {
|
|
328
357
|
_qualify: (source) => {
|
|
329
358
|
if (options.disableParsingRawHTML) return false;
|
|
330
|
-
const match =
|
|
359
|
+
const match = HTML_BLOCK_OPENING_TAG_R.exec(source);
|
|
331
360
|
if (!match) return false;
|
|
332
|
-
|
|
333
|
-
return source.toLowerCase().indexOf(`</${tag.toLowerCase()}>`) !== -1;
|
|
361
|
+
return getClosingTagRegex(match[1]).test(source);
|
|
334
362
|
},
|
|
335
363
|
_match: anyScopeRegex(HTML_BLOCK_ELEMENT_R),
|
|
336
364
|
_order: Priority.HIGH,
|
|
@@ -374,7 +402,7 @@ const createRules = (createElement, ctx, options, footnotes, refs, attrStringToM
|
|
|
374
402
|
[RuleType.htmlSelfClosing]: {
|
|
375
403
|
_qualify: (source) => {
|
|
376
404
|
if (options.disableParsingRawHTML) return false;
|
|
377
|
-
return
|
|
405
|
+
return HTML_SELF_CLOSING_OPENING_TAG_R.test(source);
|
|
378
406
|
},
|
|
379
407
|
_match: anyScopeRegex(HTML_SELF_CLOSING_ELEMENT_R),
|
|
380
408
|
_order: Priority.HIGH,
|
|
@@ -393,7 +421,7 @@ const createRules = (createElement, ctx, options, footnotes, refs, attrStringToM
|
|
|
393
421
|
}
|
|
394
422
|
},
|
|
395
423
|
[RuleType.customComponent]: {
|
|
396
|
-
_qualify: (source) =>
|
|
424
|
+
_qualify: (source) => CUSTOM_COMPONENT_OPENING_TAG_R.test(source),
|
|
397
425
|
_match: anyScopeRegex(CUSTOM_COMPONENT_R),
|
|
398
426
|
_order: Priority.MAX,
|
|
399
427
|
_parse(capture, parse, state) {
|
|
@@ -682,10 +710,19 @@ const createRules = (createElement, ctx, options, footnotes, refs, attrStringToM
|
|
|
682
710
|
}
|
|
683
711
|
};
|
|
684
712
|
};
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
713
|
+
/**
|
|
714
|
+
* `createElement` is only ever reached from a rule's `_render`, so a parse-only
|
|
715
|
+
* caller can hand over this stub instead of building an element factory.
|
|
716
|
+
*/
|
|
717
|
+
const noopCreateElement = () => null;
|
|
718
|
+
/**
|
|
719
|
+
* Builds the rule set backing one document.
|
|
720
|
+
*
|
|
721
|
+
* Rules close over the document's footnote and reference tables, so they cannot
|
|
722
|
+
* be shared across documents — but a single document's parse and render phases
|
|
723
|
+
* can share one set, which is what `compile` does.
|
|
724
|
+
*/
|
|
725
|
+
const createDocumentRules = (createElement, ctx, options, footnotes, refs) => {
|
|
689
726
|
const attrStringToMap = (tag, str) => {
|
|
690
727
|
if (!str?.trim()) return null;
|
|
691
728
|
const attributes = str.match(ATTR_EXTRACTOR_R);
|
|
@@ -714,29 +751,33 @@ const parseMarkdown = (markdown = "", ctx, options = {}) => {
|
|
|
714
751
|
UNORDERED_LIST_R,
|
|
715
752
|
CUSTOM_COMPONENT_R
|
|
716
753
|
];
|
|
754
|
+
const blockSyntaxes = options.disableParsingRawHTML ? nonParagraphBlockSyntaxes : [
|
|
755
|
+
...nonParagraphBlockSyntaxes,
|
|
756
|
+
PARAGRAPH_R,
|
|
757
|
+
HTML_BLOCK_ELEMENT_R,
|
|
758
|
+
HTML_COMMENT_R,
|
|
759
|
+
HTML_SELF_CLOSING_ELEMENT_R,
|
|
760
|
+
CUSTOM_COMPONENT_R
|
|
761
|
+
];
|
|
717
762
|
const containsBlockSyntax = (input) => {
|
|
718
763
|
const cleaned = input.replace(TRIM_STARTING_NEWLINES, "");
|
|
719
764
|
const slice = cleaned.length > 2048 ? cleaned.slice(0, 2048) : cleaned;
|
|
720
765
|
if (slice.indexOf("\n\n") !== -1) return true;
|
|
721
|
-
|
|
722
|
-
...nonParagraphBlockSyntaxes,
|
|
723
|
-
PARAGRAPH_R,
|
|
724
|
-
HTML_BLOCK_ELEMENT_R,
|
|
725
|
-
HTML_COMMENT_R,
|
|
726
|
-
HTML_SELF_CLOSING_ELEMENT_R,
|
|
727
|
-
CUSTOM_COMPONENT_R
|
|
728
|
-
];
|
|
729
|
-
return some(syntaxes, slice);
|
|
766
|
+
return some(blockSyntaxes, slice);
|
|
730
767
|
};
|
|
731
|
-
const baseRules = createRules(
|
|
732
|
-
|
|
768
|
+
const baseRules = createRules(createElement, ctx, options, footnotes, refs, attrStringToMap, containsBlockSyntax, nonParagraphBlockSyntaxes);
|
|
769
|
+
return options.disableParsingRawHTML ? Object.keys(baseRules).reduce((acc, key) => {
|
|
733
770
|
if (key !== RuleType.htmlBlock && key !== RuleType.htmlSelfClosing) acc[key] = baseRules[key];
|
|
734
771
|
return acc;
|
|
735
772
|
}, {}) : baseRules;
|
|
773
|
+
};
|
|
774
|
+
/** Runs the parse phase against an already-built rule set. */
|
|
775
|
+
const parseWithRules = (markdown, options, rules, footnotes, refs) => {
|
|
736
776
|
const parser = parserFor(rules);
|
|
737
777
|
const result = options.preserveFrontmatter ? markdown : markdown.replace(FRONT_MATTER_R, "");
|
|
738
|
-
const
|
|
739
|
-
const
|
|
778
|
+
const trimmedStart = result.replace(TRIM_STARTING_NEWLINES, "");
|
|
779
|
+
const inline = options.forceInline || !options.forceBlock && SHOULD_RENDER_AS_BLOCK_R.test(trimmedStart) === false;
|
|
780
|
+
const ast = parser(inline ? result : `${trimEnd(trimmedStart)}\n\n`, { inline });
|
|
740
781
|
if (footnotes.length > 0) for (const def of footnotes) def.parsedAst = parser(def.footnote, { inline: true });
|
|
741
782
|
return {
|
|
742
783
|
ast,
|
|
@@ -745,21 +786,11 @@ const parseMarkdown = (markdown = "", ctx, options = {}) => {
|
|
|
745
786
|
inline
|
|
746
787
|
};
|
|
747
788
|
};
|
|
748
|
-
|
|
789
|
+
/** Runs the render phase against an already-built rule set. */
|
|
790
|
+
const renderWithRules = (parsed, ctx, options, rules, createElement) => {
|
|
749
791
|
const components = ctx.components ?? {};
|
|
750
|
-
const slug = (
|
|
751
|
-
return ctx.slugify ? ctx.slugify(input, slugify) : slugify(input);
|
|
752
|
-
};
|
|
753
|
-
const createElement = createElementFactory(ctx, options);
|
|
792
|
+
const slug = createSlugger(ctx);
|
|
754
793
|
const footnotes = parsed.footnotes || [];
|
|
755
|
-
const refs = parsed.references ?? {};
|
|
756
|
-
const attrStringToMap = () => null;
|
|
757
|
-
const containsBlockSyntax = () => false;
|
|
758
|
-
const baseRules = createRules(createElement, ctx, options, footnotes, refs, attrStringToMap, containsBlockSyntax, []);
|
|
759
|
-
const rules = options.disableParsingRawHTML ? Object.keys(baseRules).reduce((acc, key) => {
|
|
760
|
-
if (key !== RuleType.htmlBlock && key !== RuleType.htmlSelfClosing) acc[key] = baseRules[key];
|
|
761
|
-
return acc;
|
|
762
|
-
}, {}) : baseRules;
|
|
763
794
|
const emitter = renderFor(createRenderer(rules, options.renderRule));
|
|
764
795
|
const inline = parsed.inline;
|
|
765
796
|
const arr = emitter(parsed.ast, { inline });
|
|
@@ -794,13 +825,28 @@ const renderMarkdownAst = (parsed, ctx, options = {}) => {
|
|
|
794
825
|
key: def.identifier
|
|
795
826
|
}, def.identifier, emitter(def.parsedAst || def.footnote, { inline: true }))))) : node;
|
|
796
827
|
};
|
|
828
|
+
const parseMarkdown = (markdown = "", ctx, options = {}) => {
|
|
829
|
+
const footnotes = [];
|
|
830
|
+
const refs = {};
|
|
831
|
+
const rules = createDocumentRules(noopCreateElement, ctx, options, footnotes, refs);
|
|
832
|
+
return parseWithRules(markdown, options, rules, footnotes, refs);
|
|
833
|
+
};
|
|
834
|
+
const renderMarkdownAst = (parsed, ctx, options = {}) => {
|
|
835
|
+
const createElement = createElementFactory(ctx, options);
|
|
836
|
+
const rules = createDocumentRules(createElement, ctx, options, parsed.footnotes ?? [], parsed.references ?? {});
|
|
837
|
+
return renderWithRules(parsed, ctx, options, rules, createElement);
|
|
838
|
+
};
|
|
797
839
|
const compile = (markdown = "", ctx, options = {}) => {
|
|
798
840
|
if (typeof markdown !== "string") {
|
|
799
841
|
console.error("intlayer: the first argument must be a string. Received", typeof markdown);
|
|
800
842
|
throw new Error("intlayer: the first argument must be a string");
|
|
801
843
|
}
|
|
802
|
-
const
|
|
803
|
-
|
|
844
|
+
const footnotes = [];
|
|
845
|
+
const refs = {};
|
|
846
|
+
const createElement = createElementFactory(ctx, options);
|
|
847
|
+
const rules = createDocumentRules(createElement, ctx, options, footnotes, refs);
|
|
848
|
+
const parsed = parseWithRules(markdown, options, rules, footnotes, refs);
|
|
849
|
+
return renderWithRules(parsed, ctx, options, rules, createElement);
|
|
804
850
|
};
|
|
805
851
|
const createCompiler = (ctx) => (markdown, options) => compile(markdown, ctx, options);
|
|
806
852
|
const compileWithOptions = (markdown, runtime, options = {}) => {
|