@intlayer/core 5.5.9 → 5.5.11

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.
Files changed (26) hide show
  1. package/README.md +42 -9
  2. package/dist/cjs/localization/index.cjs +2 -0
  3. package/dist/cjs/localization/index.cjs.map +1 -1
  4. package/dist/cjs/localization/localeMapper.cjs +17 -2
  5. package/dist/cjs/localization/localeMapper.cjs.map +1 -1
  6. package/dist/cjs/transpiler/markdown/getMarkdownMetadata.cjs +30 -7
  7. package/dist/cjs/transpiler/markdown/getMarkdownMetadata.cjs.map +1 -1
  8. package/dist/cjs/transpiler/markdown/getMarkdownMetadata.test.cjs +35 -0
  9. package/dist/cjs/transpiler/markdown/getMarkdownMetadata.test.cjs.map +1 -0
  10. package/dist/esm/localization/index.mjs +2 -1
  11. package/dist/esm/localization/index.mjs.map +1 -1
  12. package/dist/esm/localization/localeMapper.mjs +15 -1
  13. package/dist/esm/localization/localeMapper.mjs.map +1 -1
  14. package/dist/esm/transpiler/markdown/getMarkdownMetadata.mjs +30 -7
  15. package/dist/esm/transpiler/markdown/getMarkdownMetadata.mjs.map +1 -1
  16. package/dist/esm/transpiler/markdown/getMarkdownMetadata.test.mjs +34 -0
  17. package/dist/esm/transpiler/markdown/getMarkdownMetadata.test.mjs.map +1 -0
  18. package/dist/types/localization/index.d.ts +1 -1
  19. package/dist/types/localization/index.d.ts.map +1 -1
  20. package/dist/types/localization/localeMapper.d.ts +25 -1
  21. package/dist/types/localization/localeMapper.d.ts.map +1 -1
  22. package/dist/types/transpiler/markdown/getMarkdownMetadata.d.ts +1 -1
  23. package/dist/types/transpiler/markdown/getMarkdownMetadata.d.ts.map +1 -1
  24. package/dist/types/transpiler/markdown/getMarkdownMetadata.test.d.ts +2 -0
  25. package/dist/types/transpiler/markdown/getMarkdownMetadata.test.d.ts.map +1 -0
  26. package/package.json +14 -12
package/README.md CHANGED
@@ -5,15 +5,48 @@
5
5
  </div>
6
6
 
7
7
  <div align="center">
8
- <a href="https://www.npmjs.com/package/intlayer">
9
- <img alt="npm" src="https://img.shields.io/npm/v/intlayer.svg?labelColor=49516F&color=8994BC" />
10
- </a>
11
- <a href="https://npmjs.org/package/intlayer">
12
- <img alt="downloads" src="https://badgen.net/npm/dm/intlayer?labelColor=49516F&color=8994BC" />
13
- </a>
14
- <a href="https://npmjs.org/package/intlayer">
15
- <img alt="types included" src="https://badgen.net/npm/types/intlayer?labelColor=49516F&color=8994BC"
16
- />
8
+ <a href="https://www.npmjs.com/package/intlayer" target="blank"><img
9
+ align="center"
10
+ alt="npm"
11
+ src="https://img.shields.io/npm/v/intlayer.svg?labelColor=49516F&color=8994BC&style=for-the-badge"
12
+ height="30" /></a>
13
+ <a href="https://npmjs.org/package/intlayer" target="blank"><img
14
+ align="center"
15
+ src="https://img.shields.io/npm/dm/intlayer?labelColor=49516F&color=8994BC&style=for-the-badge"
16
+ alt="monthly downloads"
17
+ height="30"
18
+ /></a>
19
+ <a href="https://npmjs.org/package/intlayer" target="blank"><img
20
+ align="center"
21
+ src="https://img.shields.io/npm/types/intlayer?label=types%20included&labelColor=49516F&color=8994BC&style=for-the-badge"
22
+ alt="types included"
23
+ height="30"
24
+ /></a>
25
+ </div>
26
+
27
+ <div>
28
+ <br/>
29
+ <p align="center">
30
+ <a href="https://www.linkedin.com/company/intlayerorg" target="blank"><img align="center"
31
+ src="https://img.shields.io/badge/linkedin-%231DA1F2.svg?style=for-the-badge&logo=linkedin&logoColor=white"
32
+ alt="Intlayer LinkedIn" height="30"/></a>
33
+ <a href="https://www.facebook.com/intlayer" target="blank"><img align="center"
34
+ src="https://img.shields.io/badge/facebook-4267B2.svg?style=for-the-badge&logo=facebook&logoColor=white"
35
+ alt="Intlayer Facebook" height="30"/></a>
36
+ <a href="https://www.instagram.com/intlayer_org/" target="blank"><img align="center"
37
+ src="https://img.shields.io/badge/instagram-%23E4405F.svg?style=for-the-badge&logo=Instagram&logoColor=white"
38
+ alt="Intlayer Instagram" height="30"/></a>
39
+ <a href="https://x.com/Intlayer183096" target="blank"><img align="center"
40
+ src="https://img.shields.io/badge/x-1DA1F2.svg?style=for-the-badge&logo=x&logoColor=white"
41
+ alt="Intlayer X" height="30"/></a>
42
+ <a href="https://www.youtube.com/@intlayer" target="blank"><img align="center"
43
+ src="https://img.shields.io/badge/youtube-FF0000.svg?style=for-the-badge&logo=youtube&logoColor=white"
44
+ alt="Intlayer YouTube" height="30"/></a>
45
+ <a href="https://www.tiktok.com/@intlayer" target="blank"><img align="center"
46
+ src="https://img.shields.io/badge/tiktok-000000.svg?style=for-the-badge&logo=tiktok&logoColor=white"
47
+ alt="Intlayer TikTok" height="30"/></a>
48
+ <br>
49
+ </p>
17
50
  </div>
18
51
 
19
52
  # @intlayer/core: Containing Intlayer core functions
@@ -29,6 +29,7 @@ __export(localization_exports, {
29
29
  localeFlatMap: () => import_localeMapper.localeFlatMap,
30
30
  localeList: () => import_localeList.localeList,
31
31
  localeMap: () => import_localeMapper.localeMap,
32
+ localeRecord: () => import_localeMapper.localeRecord,
32
33
  localeResolver: () => import_localeResolver.localeResolver
33
34
  });
34
35
  module.exports = __toCommonJS(localization_exports);
@@ -56,6 +57,7 @@ var import_localeResolver = require('./localeResolver.cjs');
56
57
  localeFlatMap,
57
58
  localeList,
58
59
  localeMap,
60
+ localeRecord,
59
61
  localeResolver
60
62
  });
61
63
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/localization/index.ts"],"sourcesContent":["export { getHTMLTextDir } from './getHTMLTextDir';\nexport { getLocaleFromPath } from './getLocaleFromPath';\nexport { getLocaleLang } from './getLocaleLang';\nexport { getLocaleName } from './getLocaleName';\nexport { getLocalizedUrl } from './getLocalizedUrl';\nexport { getMultilingualUrls } from './getMultilingualUrls';\nexport { getPathWithoutLocale } from './getPathWithoutLocale';\nexport { localeDetector } from './localeDetector';\nexport { localeList } from './localeList';\nexport { localeFlatMap, localeMap } from './localeMapper';\nexport { localeResolver } from './localeResolver';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAA+B;AAC/B,+BAAkC;AAClC,2BAA8B;AAC9B,2BAA8B;AAC9B,6BAAgC;AAChC,iCAAoC;AACpC,kCAAqC;AACrC,4BAA+B;AAC/B,wBAA2B;AAC3B,0BAAyC;AACzC,4BAA+B;","names":[]}
1
+ {"version":3,"sources":["../../../src/localization/index.ts"],"sourcesContent":["export { getHTMLTextDir } from './getHTMLTextDir';\nexport { getLocaleFromPath } from './getLocaleFromPath';\nexport { getLocaleLang } from './getLocaleLang';\nexport { getLocaleName } from './getLocaleName';\nexport { getLocalizedUrl } from './getLocalizedUrl';\nexport { getMultilingualUrls } from './getMultilingualUrls';\nexport { getPathWithoutLocale } from './getPathWithoutLocale';\nexport { localeDetector } from './localeDetector';\nexport { localeList } from './localeList';\nexport { localeFlatMap, localeMap, localeRecord } from './localeMapper';\nexport { localeResolver } from './localeResolver';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAA+B;AAC/B,+BAAkC;AAClC,2BAA8B;AAC9B,2BAA8B;AAC9B,6BAAgC;AAChC,iCAAoC;AACpC,kCAAqC;AACrC,4BAA+B;AAC/B,wBAA2B;AAC3B,0BAAuD;AACvD,4BAA+B;","names":[]}
@@ -29,7 +29,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  var localeMapper_exports = {};
30
30
  __export(localeMapper_exports, {
31
31
  localeFlatMap: () => localeFlatMap,
32
- localeMap: () => localeMap
32
+ localeMap: () => localeMap,
33
+ localeRecord: () => localeRecord
33
34
  });
34
35
  module.exports = __toCommonJS(localeMapper_exports);
35
36
  var import_built = __toESM(require("@intlayer/config/built"));
@@ -51,9 +52,23 @@ const localeFlatMap = (mapper, locales = import_built.default.internationalizati
51
52
  urlPrefix: locale === defaultLocale && !prefixDefault ? "" : `/${locale}`
52
53
  })
53
54
  );
55
+ const localeRecord = (mapper, locales = import_built.default.internationalization.locales, defaultLocale = import_built.default.internationalization.defaultLocale, prefixDefault = import_built.default.middleware.prefixDefault) => locales.reduce(
56
+ (acc, locale) => {
57
+ acc[locale] = mapper({
58
+ locale,
59
+ defaultLocale,
60
+ locales,
61
+ isDefault: locale === defaultLocale,
62
+ urlPrefix: locale === defaultLocale && !prefixDefault ? "" : `/${locale}`
63
+ });
64
+ return acc;
65
+ },
66
+ {}
67
+ );
54
68
  // Annotate the CommonJS export names for ESM import in node:
55
69
  0 && (module.exports = {
56
70
  localeFlatMap,
57
- localeMap
71
+ localeMap,
72
+ localeRecord
58
73
  });
59
74
  //# sourceMappingURL=localeMapper.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/localization/localeMapper.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { LocalesValues } from '@intlayer/config/client';\n\nexport type LocaleData = {\n locale: LocalesValues;\n defaultLocale: LocalesValues;\n isDefault: boolean;\n locales: LocalesValues[];\n urlPrefix: string;\n};\n\n/**\n * Map the locale data to an array of objects\n *\n * @example\n * ```ts\n * const routes = localeMap((localizedData) =>\n * ({\n * path: localizedData.urlPrefix,\n * name: localizedData.locale,\n * isDefault: localizedData.isDefault,\n * locales: localizedData.locales,\n * defaultLocale: localizedData.defaultLocale,\n * }),\n * );\n *\n * // Result\n * [\n * { path: '/', name: 'en', isDefault: true, locales: ['en'], defaultLocale: 'en', urlPrefix: '' },\n * { path: '/fr', name: 'fr', isDefault: false, locales: ['fr'], defaultLocale: 'en', urlPrefix: '/fr' },\n * { path: '/es', name: 'es', isDefault: false, locales: ['es'], defaultLocale: 'en', urlPrefix: '/es' },\n * ]\n * ```\n *\n * @param mapper - The mapper function that returns an object\n * @returns An array of objects\n */\nexport const localeMap = <T extends object>(\n mapper: (locale: LocaleData) => T,\n locales: LocalesValues[] = configuration.internationalization.locales,\n defaultLocale: LocalesValues = configuration.internationalization\n .defaultLocale,\n prefixDefault: boolean = configuration.middleware.prefixDefault\n): T[] =>\n locales.map((locale) =>\n mapper({\n locale,\n defaultLocale,\n locales,\n isDefault: locale === defaultLocale,\n urlPrefix: locale === defaultLocale && !prefixDefault ? '' : `/${locale}`,\n })\n );\n\n/**\n * Flatten the locale map into a single array of objects\n *\n * @example\n * ```ts\n * const routes = localeMap((localizedData) =>\n * [{\n * path: localizedData.urlPrefix,\n * name: localizedData.locale,\n * isDefault: localizedData.isDefault,\n * locales: localizedData.locales,\n * defaultLocale: localizedData.defaultLocale,\n * }],\n * );\n *\n * // Result\n * [\n * { path: '/', name: 'en', isDefault: true, locales: ['en'], defaultLocale: 'en', urlPrefix: '' },\n * { path: '/fr', name: 'fr', isDefault: false, locales: ['fr'], defaultLocale: 'en', urlPrefix: '/fr' },\n * { path: '/es', name: 'es', isDefault: false, locales: ['es'], defaultLocale: 'en', urlPrefix: '/es' },\n * ]\n * ```\n *\n * @param mapper - The mapper function that returns an array of objects\n * @returns An array of objects\n */\nexport const localeFlatMap = <T>(\n mapper: (locale: LocaleData) => T[],\n locales: LocalesValues[] = configuration.internationalization.locales,\n defaultLocale: LocalesValues = configuration.internationalization\n .defaultLocale,\n prefixDefault: boolean = configuration.middleware.prefixDefault\n): T[] =>\n locales.flatMap((locale) =>\n mapper({\n locale,\n defaultLocale,\n locales,\n isDefault: locale === defaultLocale,\n urlPrefix: locale === defaultLocale && !prefixDefault ? '' : `/${locale}`,\n })\n );\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA0B;AAqCnB,MAAM,YAAY,CACvB,QACA,UAA2B,aAAAA,QAAc,qBAAqB,SAC9D,gBAA+B,aAAAA,QAAc,qBAC1C,eACH,gBAAyB,aAAAA,QAAc,WAAW,kBAElD,QAAQ;AAAA,EAAI,CAAC,WACX,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,WAAW;AAAA,IACtB,WAAW,WAAW,iBAAiB,CAAC,gBAAgB,KAAK,IAAI,MAAM;AAAA,EACzE,CAAC;AACH;AA4BK,MAAM,gBAAgB,CAC3B,QACA,UAA2B,aAAAA,QAAc,qBAAqB,SAC9D,gBAA+B,aAAAA,QAAc,qBAC1C,eACH,gBAAyB,aAAAA,QAAc,WAAW,kBAElD,QAAQ;AAAA,EAAQ,CAAC,WACf,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,WAAW;AAAA,IACtB,WAAW,WAAW,iBAAiB,CAAC,gBAAgB,KAAK,IAAI,MAAM;AAAA,EACzE,CAAC;AACH;","names":["configuration"]}
1
+ {"version":3,"sources":["../../../src/localization/localeMapper.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { Locales, LocalesValues } from '@intlayer/config/client';\n\nexport type LocaleData = {\n locale: LocalesValues;\n defaultLocale: LocalesValues;\n isDefault: boolean;\n locales: LocalesValues[];\n urlPrefix: string;\n};\n\n/**\n * Map the locale data to an array of objects\n *\n * @example\n * ```ts\n * const routes = localeMap((localizedData) =>\n * ({\n * path: localizedData.urlPrefix,\n * name: localizedData.locale,\n * isDefault: localizedData.isDefault,\n * locales: localizedData.locales,\n * defaultLocale: localizedData.defaultLocale,\n * }),\n * );\n *\n * // Result\n * [\n * { path: '/', name: 'en', isDefault: true, locales: ['en'], defaultLocale: 'en', urlPrefix: '' },\n * { path: '/fr', name: 'fr', isDefault: false, locales: ['fr'], defaultLocale: 'en', urlPrefix: '/fr' },\n * { path: '/es', name: 'es', isDefault: false, locales: ['es'], defaultLocale: 'en', urlPrefix: '/es' },\n * ]\n * ```\n *\n * @param mapper - The mapper function that returns an object\n * @returns An array of objects\n */\nexport const localeMap = <T extends object>(\n mapper: (locale: LocaleData) => T,\n locales: LocalesValues[] = configuration.internationalization.locales,\n defaultLocale: LocalesValues = configuration.internationalization\n .defaultLocale,\n prefixDefault: boolean = configuration.middleware.prefixDefault\n): T[] =>\n locales.map((locale) =>\n mapper({\n locale,\n defaultLocale,\n locales,\n isDefault: locale === defaultLocale,\n urlPrefix: locale === defaultLocale && !prefixDefault ? '' : `/${locale}`,\n })\n );\n\n/**\n * Flatten the locale map into a single array of objects\n *\n * @example\n * ```ts\n * const routes = localeMap((localizedData) =>\n * [{\n * path: localizedData.urlPrefix,\n * name: localizedData.locale,\n * isDefault: localizedData.isDefault,\n * locales: localizedData.locales,\n * defaultLocale: localizedData.defaultLocale,\n * }],\n * );\n *\n * // Result\n * [\n * { path: '/', name: 'en', isDefault: true, locales: ['en'], defaultLocale: 'en', urlPrefix: '' },\n * { path: '/fr', name: 'fr', isDefault: false, locales: ['fr'], defaultLocale: 'en', urlPrefix: '/fr' },\n * { path: '/es', name: 'es', isDefault: false, locales: ['es'], defaultLocale: 'en', urlPrefix: '/es' },\n * ]\n * ```\n *\n * @param mapper - The mapper function that returns an array of objects\n * @returns An array of objects\n */\nexport const localeFlatMap = <T>(\n mapper: (locale: LocaleData) => T[],\n locales: LocalesValues[] = configuration.internationalization.locales,\n defaultLocale: LocalesValues = configuration.internationalization\n .defaultLocale,\n prefixDefault: boolean = configuration.middleware.prefixDefault\n): T[] =>\n locales.flatMap((locale) =>\n mapper({\n locale,\n defaultLocale,\n locales,\n isDefault: locale === defaultLocale,\n urlPrefix: locale === defaultLocale && !prefixDefault ? '' : `/${locale}`,\n })\n );\n\n/**\n * Creates a record object mapping locales to values transformed by the mapper function\n *\n * @example\n * ```ts\n * const translations = localeRecord(({ locale }) =>\n * require(`./translations/${locale}.json`)\n * );\n *\n * // Result\n * {\n * en: { ... }, // Content of translations/en.json\n * fr: { ... }, // Content of translations/fr.json\n * es: { ... } // Content of translations/es.json\n * }\n * ```\n *\n * @param mapper - Function that takes locale data and returns a value for that locale\n * @param locales - Array of locale codes to map over (defaults to configured locales)\n * @param defaultLocale - The default locale (defaults to configured default)\n * @param prefixDefault - Whether to prefix the default locale in URLs (defaults to configured value)\n * @returns Record mapping locale codes to mapped values\n */\nexport const localeRecord = <T>(\n mapper: (locale: LocaleData) => T,\n locales: Locales[] = configuration.internationalization.locales,\n defaultLocale: Locales = configuration.internationalization.defaultLocale,\n prefixDefault: boolean = configuration.middleware.prefixDefault\n): Record<Locales, T> =>\n locales.reduce(\n (acc, locale) => {\n acc[locale] = mapper({\n locale,\n defaultLocale,\n locales,\n isDefault: locale === defaultLocale,\n urlPrefix:\n locale === defaultLocale && !prefixDefault ? '' : `/${locale}`,\n });\n return acc;\n },\n {} as Record<Locales, T>\n );\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA0B;AAqCnB,MAAM,YAAY,CACvB,QACA,UAA2B,aAAAA,QAAc,qBAAqB,SAC9D,gBAA+B,aAAAA,QAAc,qBAC1C,eACH,gBAAyB,aAAAA,QAAc,WAAW,kBAElD,QAAQ;AAAA,EAAI,CAAC,WACX,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,WAAW;AAAA,IACtB,WAAW,WAAW,iBAAiB,CAAC,gBAAgB,KAAK,IAAI,MAAM;AAAA,EACzE,CAAC;AACH;AA4BK,MAAM,gBAAgB,CAC3B,QACA,UAA2B,aAAAA,QAAc,qBAAqB,SAC9D,gBAA+B,aAAAA,QAAc,qBAC1C,eACH,gBAAyB,aAAAA,QAAc,WAAW,kBAElD,QAAQ;AAAA,EAAQ,CAAC,WACf,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,WAAW;AAAA,IACtB,WAAW,WAAW,iBAAiB,CAAC,gBAAgB,KAAK,IAAI,MAAM;AAAA,EACzE,CAAC;AACH;AAyBK,MAAM,eAAe,CAC1B,QACA,UAAqB,aAAAA,QAAc,qBAAqB,SACxD,gBAAyB,aAAAA,QAAc,qBAAqB,eAC5D,gBAAyB,aAAAA,QAAc,WAAW,kBAElD,QAAQ;AAAA,EACN,CAAC,KAAK,WAAW;AACf,QAAI,MAAM,IAAI,OAAO;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,WAAW;AAAA,MACtB,WACE,WAAW,iBAAiB,CAAC,gBAAgB,KAAK,IAAI,MAAM;AAAA,IAChE,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EACA,CAAC;AACH;","names":["configuration"]}
@@ -43,36 +43,59 @@ const getMarkdownMetadata = (markdown) => {
43
43
  const lines = markdown.split(/\r?\n/);
44
44
  const firstNonEmptyLine = lines.find((line) => line.trim() !== "");
45
45
  if (!firstNonEmptyLine || firstNonEmptyLine.trim() !== "---") {
46
- return {};
46
+ const result = {};
47
+ return result;
47
48
  }
48
49
  const metadata = {};
49
50
  let inMetadataBlock = false;
50
- for (const line of lines) {
51
+ let currentKey = null;
52
+ let currentArrayItems = [];
53
+ for (let i = 0; i < lines.length; i++) {
54
+ const line = lines[i];
51
55
  const trimmedLine = line.trim();
52
56
  if (trimmedLine === "---") {
53
57
  if (!inMetadataBlock) {
54
58
  inMetadataBlock = true;
55
59
  continue;
56
60
  } else {
61
+ if (currentKey && currentArrayItems.length > 0) {
62
+ metadata[currentKey] = currentArrayItems;
63
+ }
57
64
  break;
58
65
  }
59
66
  }
60
67
  if (inMetadataBlock) {
68
+ const arrayItemMatch = line.match(/^\s*-\s+(.+)$/);
69
+ if (arrayItemMatch && currentKey) {
70
+ currentArrayItems.push(arrayItemMatch[1].trim());
71
+ continue;
72
+ }
73
+ if (currentKey && currentArrayItems.length > 0) {
74
+ metadata[currentKey] = currentArrayItems;
75
+ currentKey = null;
76
+ currentArrayItems = [];
77
+ }
61
78
  const match = line.match(/^([^:]+)\s*:\s*(.*)$/);
62
79
  if (match) {
63
80
  const key = match[1].trim();
64
81
  const value = match[2].trim();
65
- try {
66
- metadata[key] = parseToObject(value);
67
- } catch (e) {
68
- metadata[key] = value;
82
+ if (value === "") {
83
+ currentKey = key;
84
+ currentArrayItems = [];
85
+ } else {
86
+ try {
87
+ metadata[key] = parseToObject(value);
88
+ } catch (e) {
89
+ metadata[key] = value;
90
+ }
69
91
  }
70
92
  }
71
93
  }
72
94
  }
73
95
  return metadata;
74
96
  } catch (e) {
75
- return void 0;
97
+ const result = {};
98
+ return result;
76
99
  }
77
100
  };
78
101
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/transpiler/markdown/getMarkdownMetadata.ts"],"sourcesContent":["const parseToObject = <T = any>(input: string): T | null => {\n // Normalize different bracket types and keys/values\n let normalizedInput = input\n .trim()\n .replace(/^\\[/, '[') // Keep array brackets\n .replace(/^\\{/, '{') // Keep object brackets\n .replace(/\\]$/, ']') // Keep array brackets\n .replace(/\\}$/, '}') // Keep object brackets\n .replace(/([\\w\\d_]+)\\s*:/g, '\"$1\":') // Ensure JSON-valid keys (e.g., key: -> \"key\":)\n .replace(/:\\s*([a-zA-Z_][\\w\\d_]*)/g, ': \"$1\"'); // Handle unquoted string values\n\n // Fix arrays with unquoted items (e.g., [content, anotherContent])\n normalizedInput = normalizedInput.replace(\n /\\[([^\\[\\]]+?)\\]/g,\n (_match, arrayContent) => {\n const newContent = (arrayContent as string)\n .split(',')\n .map((item) => {\n const trimmed = item.trim();\n // If already quoted or is a valid number, return as is.\n if (\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n !isNaN(Number(trimmed))\n ) {\n return trimmed;\n }\n return `\"${trimmed}\"`;\n })\n .join(', ');\n return `[${newContent}]`;\n }\n );\n\n // Parse the string into an object\n return JSON.parse(normalizedInput) as T;\n};\n\nexport const getMarkdownMetadata = (\n markdown: string\n): Record<string, any> | undefined => {\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 || firstNonEmptyLine.trim() !== '---') {\n return {};\n }\n\n const metadata: Record<string, any> = {};\n let inMetadataBlock = false;\n\n for (const line of lines) {\n const trimmedLine = line.trim();\n\n // Toggle metadata block on encountering the delimiter.\n if (trimmedLine === '---') {\n if (!inMetadataBlock) {\n // Begin metadata block.\n inMetadataBlock = true;\n continue;\n } else {\n // End of metadata block; stop processing.\n break;\n }\n }\n\n // If we're inside the metadata block, parse key: value pairs.\n if (inMetadataBlock) {\n const match = line.match(/^([^:]+)\\s*:\\s*(.*)$/);\n if (match) {\n const key = match[1].trim();\n const value = match[2].trim();\n try {\n metadata[key] = parseToObject(value);\n } catch (e) {\n metadata[key] = value;\n }\n }\n }\n }\n\n return metadata;\n } catch (e) {\n return undefined;\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAAM,gBAAgB,CAAU,UAA4B;AAE1D,MAAI,kBAAkB,MACnB,KAAK,EACL,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,mBAAmB,OAAO,EAClC,QAAQ,4BAA4B,QAAQ;AAG/C,oBAAkB,gBAAgB;AAAA,IAChC;AAAA,IACA,CAAC,QAAQ,iBAAiB;AACxB,YAAM,aAAc,aACjB,MAAM,GAAG,EACT,IAAI,CAAC,SAAS;AACb,cAAM,UAAU,KAAK,KAAK;AAE1B,YACG,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,KAChD,CAAC,MAAM,OAAO,OAAO,CAAC,GACtB;AACA,iBAAO;AAAA,QACT;AACA,eAAO,IAAI,OAAO;AAAA,MACpB,CAAC,EACA,KAAK,IAAI;AACZ,aAAO,IAAI,UAAU;AAAA,IACvB;AAAA,EACF;AAGA,SAAO,KAAK,MAAM,eAAe;AACnC;AAEO,MAAM,sBAAsB,CACjC,aACoC;AACpC,MAAI;AACF,UAAM,QAAQ,SAAS,MAAM,OAAO;AAGpC,UAAM,oBAAoB,MAAM,KAAK,CAAC,SAAS,KAAK,KAAK,MAAM,EAAE;AAEjE,QAAI,CAAC,qBAAqB,kBAAkB,KAAK,MAAM,OAAO;AAC5D,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,WAAgC,CAAC;AACvC,QAAI,kBAAkB;AAEtB,eAAW,QAAQ,OAAO;AACxB,YAAM,cAAc,KAAK,KAAK;AAG9B,UAAI,gBAAgB,OAAO;AACzB,YAAI,CAAC,iBAAiB;AAEpB,4BAAkB;AAClB;AAAA,QACF,OAAO;AAEL;AAAA,QACF;AAAA,MACF;AAGA,UAAI,iBAAiB;AACnB,cAAM,QAAQ,KAAK,MAAM,sBAAsB;AAC/C,YAAI,OAAO;AACT,gBAAM,MAAM,MAAM,CAAC,EAAE,KAAK;AAC1B,gBAAM,QAAQ,MAAM,CAAC,EAAE,KAAK;AAC5B,cAAI;AACF,qBAAS,GAAG,IAAI,cAAc,KAAK;AAAA,UACrC,SAAS,GAAG;AACV,qBAAS,GAAG,IAAI;AAAA,UAClB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT,SAAS,GAAG;AACV,WAAO;AAAA,EACT;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/transpiler/markdown/getMarkdownMetadata.ts"],"sourcesContent":["const parseToObject = <T = any>(input: string): T | null => {\n // Normalize different bracket types and keys/values\n let normalizedInput = input\n .trim()\n .replace(/^\\[/, '[') // Keep array brackets\n .replace(/^\\{/, '{') // Keep object brackets\n .replace(/\\]$/, ']') // Keep array brackets\n .replace(/\\}$/, '}') // Keep object brackets\n .replace(/([\\w\\d_]+)\\s*:/g, '\"$1\":') // Ensure JSON-valid keys (e.g., key: -> \"key\":)\n .replace(/:\\s*([a-zA-Z_][\\w\\d_]*)/g, ': \"$1\"'); // Handle unquoted string values\n\n // Fix arrays with unquoted items (e.g., [content, anotherContent])\n normalizedInput = normalizedInput.replace(\n /\\[([^\\[\\]]+?)\\]/g,\n (_match, arrayContent) => {\n const newContent = (arrayContent as string)\n .split(',')\n .map((item) => {\n const trimmed = item.trim();\n // If already quoted or is a valid number, return as is.\n if (\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n !isNaN(Number(trimmed))\n ) {\n return trimmed;\n }\n return `\"${trimmed}\"`;\n })\n .join(', ');\n return `[${newContent}]`;\n }\n );\n\n // Parse the string into an object\n return JSON.parse(normalizedInput) as T;\n};\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 || firstNonEmptyLine.trim() !== '---') {\n const result: T = {} as T;\n return result;\n }\n\n const metadata: T = {} as T;\n let inMetadataBlock = false;\n let currentKey: string | null = null;\n let currentArrayItems: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmedLine = line.trim();\n\n // Toggle metadata block on encountering the delimiter.\n if (trimmedLine === '---') {\n if (!inMetadataBlock) {\n // Begin metadata block.\n inMetadataBlock = true;\n continue;\n } else {\n // End of metadata block; finalize any pending array and stop processing.\n if (currentKey && currentArrayItems.length > 0) {\n (metadata as Record<string, any>)[currentKey] = currentArrayItems;\n }\n break;\n }\n }\n\n // If we're inside the metadata block, parse key: value pairs.\n if (inMetadataBlock) {\n // Check if this line is an array item (starts with - )\n const arrayItemMatch = line.match(/^\\s*-\\s+(.+)$/);\n if (arrayItemMatch && currentKey) {\n // This is an array item for the current key\n currentArrayItems.push(arrayItemMatch[1].trim());\n continue;\n }\n\n // If we have a pending array from a previous key, save it\n if (currentKey && currentArrayItems.length > 0) {\n (metadata as Record<string, any>)[currentKey] = currentArrayItems;\n currentKey = null;\n currentArrayItems = [];\n }\n\n // Check for key: value pairs\n const match = line.match(/^([^:]+)\\s*:\\s*(.*)$/);\n if (match) {\n const key = match[1].trim();\n const value = match[2].trim();\n\n if (value === '') {\n // This might be the start of a multi-line structure (like an array)\n currentKey = key;\n currentArrayItems = [];\n } else {\n try {\n (metadata as Record<string, any>)[key] = parseToObject(value);\n } catch (e) {\n (metadata as Record<string, any>)[key] = value;\n }\n }\n }\n }\n }\n\n return metadata;\n } catch (e) {\n const result: T = {} as T;\n return result;\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAAM,gBAAgB,CAAU,UAA4B;AAE1D,MAAI,kBAAkB,MACnB,KAAK,EACL,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,mBAAmB,OAAO,EAClC,QAAQ,4BAA4B,QAAQ;AAG/C,oBAAkB,gBAAgB;AAAA,IAChC;AAAA,IACA,CAAC,QAAQ,iBAAiB;AACxB,YAAM,aAAc,aACjB,MAAM,GAAG,EACT,IAAI,CAAC,SAAS;AACb,cAAM,UAAU,KAAK,KAAK;AAE1B,YACG,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,KAChD,CAAC,MAAM,OAAO,OAAO,CAAC,GACtB;AACA,iBAAO;AAAA,QACT;AACA,eAAO,IAAI,OAAO;AAAA,MACpB,CAAC,EACA,KAAK,IAAI;AACZ,aAAO,IAAI,UAAU;AAAA,IACvB;AAAA,EACF;AAGA,SAAO,KAAK,MAAM,eAAe;AACnC;AAEO,MAAM,sBAAsB,CACjC,aACM;AACN,MAAI;AACF,UAAM,QAAQ,SAAS,MAAM,OAAO;AAGpC,UAAM,oBAAoB,MAAM,KAAK,CAAC,SAAS,KAAK,KAAK,MAAM,EAAE;AAEjE,QAAI,CAAC,qBAAqB,kBAAkB,KAAK,MAAM,OAAO;AAC5D,YAAM,SAAY,CAAC;AACnB,aAAO;AAAA,IACT;AAEA,UAAM,WAAc,CAAC;AACrB,QAAI,kBAAkB;AACtB,QAAI,aAA4B;AAChC,QAAI,oBAA8B,CAAC;AAEnC,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,OAAO,MAAM,CAAC;AACpB,YAAM,cAAc,KAAK,KAAK;AAG9B,UAAI,gBAAgB,OAAO;AACzB,YAAI,CAAC,iBAAiB;AAEpB,4BAAkB;AAClB;AAAA,QACF,OAAO;AAEL,cAAI,cAAc,kBAAkB,SAAS,GAAG;AAC9C,YAAC,SAAiC,UAAU,IAAI;AAAA,UAClD;AACA;AAAA,QACF;AAAA,MACF;AAGA,UAAI,iBAAiB;AAEnB,cAAM,iBAAiB,KAAK,MAAM,eAAe;AACjD,YAAI,kBAAkB,YAAY;AAEhC,4BAAkB,KAAK,eAAe,CAAC,EAAE,KAAK,CAAC;AAC/C;AAAA,QACF;AAGA,YAAI,cAAc,kBAAkB,SAAS,GAAG;AAC9C,UAAC,SAAiC,UAAU,IAAI;AAChD,uBAAa;AACb,8BAAoB,CAAC;AAAA,QACvB;AAGA,cAAM,QAAQ,KAAK,MAAM,sBAAsB;AAC/C,YAAI,OAAO;AACT,gBAAM,MAAM,MAAM,CAAC,EAAE,KAAK;AAC1B,gBAAM,QAAQ,MAAM,CAAC,EAAE,KAAK;AAE5B,cAAI,UAAU,IAAI;AAEhB,yBAAa;AACb,gCAAoB,CAAC;AAAA,UACvB,OAAO;AACL,gBAAI;AACF,cAAC,SAAiC,GAAG,IAAI,cAAc,KAAK;AAAA,YAC9D,SAAS,GAAG;AACV,cAAC,SAAiC,GAAG,IAAI;AAAA,YAC3C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT,SAAS,GAAG;AACV,UAAM,SAAY,CAAC;AACnB,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var import_vitest = require("vitest");
3
+ var import__ = require('../index.cjs');
4
+ (0, import_vitest.describe)("getMarkdownMetadata", () => {
5
+ const markdown = [
6
+ "---",
7
+ "title: Mock Title",
8
+ "description: Mock Description",
9
+ "author: Mock Author",
10
+ "date: 2024-01-01",
11
+ "tags:",
12
+ " - tag1",
13
+ " - tag2",
14
+ " - tag3",
15
+ "---",
16
+ "# Mock Heading",
17
+ "This is a mock paragraph with some sample text.",
18
+ "Here is another mock paragraph.",
19
+ "## Mock Section",
20
+ "Some more mock content goes here.",
21
+ "### Mock Subsection",
22
+ "Final mock paragraph with test content."
23
+ ].join("\n");
24
+ (0, import_vitest.it)("should return the metadata from the markdown file", () => {
25
+ const metadata = (0, import__.getMarkdownMetadata)(markdown);
26
+ (0, import_vitest.expect)(metadata).toEqual({
27
+ title: "Mock Title",
28
+ description: "Mock Description",
29
+ author: "Mock Author",
30
+ date: "2024-01-01",
31
+ tags: ["tag1", "tag2", "tag3"]
32
+ });
33
+ });
34
+ });
35
+ //# sourceMappingURL=getMarkdownMetadata.test.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/transpiler/markdown/getMarkdownMetadata.test.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest';\nimport { getMarkdownMetadata } from '..';\n\ndescribe('getMarkdownMetadata', () => {\n const markdown = [\n '---',\n 'title: Mock Title',\n 'description: Mock Description',\n 'author: Mock Author',\n 'date: 2024-01-01',\n 'tags:',\n ' - tag1',\n ' - tag2',\n ' - tag3',\n '---',\n '# Mock Heading',\n 'This is a mock paragraph with some sample text.',\n 'Here is another mock paragraph.',\n '## Mock Section',\n 'Some more mock content goes here.',\n '### Mock Subsection',\n 'Final mock paragraph with test content.',\n ].join('\\n');\n\n it('should return the metadata from the markdown file', () => {\n const metadata = getMarkdownMetadata(markdown);\n expect(metadata).toEqual({\n title: 'Mock Title',\n description: 'Mock Description',\n author: 'Mock Author',\n date: '2024-01-01',\n tags: ['tag1', 'tag2', 'tag3'],\n });\n });\n});\n"],"mappings":";AAAA,oBAAqC;AACrC,eAAoC;AAAA,IAEpC,wBAAS,uBAAuB,MAAM;AACpC,QAAM,WAAW;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AAEX,wBAAG,qDAAqD,MAAM;AAC5D,UAAM,eAAW,8BAAoB,QAAQ;AAC7C,8BAAO,QAAQ,EAAE,QAAQ;AAAA,MACvB,OAAO;AAAA,MACP,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM,CAAC,QAAQ,QAAQ,MAAM;AAAA,IAC/B,CAAC;AAAA,EACH,CAAC;AACH,CAAC;","names":[]}
@@ -7,7 +7,7 @@ import { getMultilingualUrls } from "./getMultilingualUrls.mjs";
7
7
  import { getPathWithoutLocale } from "./getPathWithoutLocale.mjs";
8
8
  import { localeDetector } from "./localeDetector.mjs";
9
9
  import { localeList } from "./localeList.mjs";
10
- import { localeFlatMap, localeMap } from "./localeMapper.mjs";
10
+ import { localeFlatMap, localeMap, localeRecord } from "./localeMapper.mjs";
11
11
  import { localeResolver } from "./localeResolver.mjs";
12
12
  export {
13
13
  getHTMLTextDir,
@@ -21,6 +21,7 @@ export {
21
21
  localeFlatMap,
22
22
  localeList,
23
23
  localeMap,
24
+ localeRecord,
24
25
  localeResolver
25
26
  };
26
27
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/localization/index.ts"],"sourcesContent":["export { getHTMLTextDir } from './getHTMLTextDir';\nexport { getLocaleFromPath } from './getLocaleFromPath';\nexport { getLocaleLang } from './getLocaleLang';\nexport { getLocaleName } from './getLocaleName';\nexport { getLocalizedUrl } from './getLocalizedUrl';\nexport { getMultilingualUrls } from './getMultilingualUrls';\nexport { getPathWithoutLocale } from './getPathWithoutLocale';\nexport { localeDetector } from './localeDetector';\nexport { localeList } from './localeList';\nexport { localeFlatMap, localeMap } from './localeMapper';\nexport { localeResolver } from './localeResolver';\n"],"mappings":"AAAA,SAAS,sBAAsB;AAC/B,SAAS,yBAAyB;AAClC,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAChC,SAAS,2BAA2B;AACpC,SAAS,4BAA4B;AACrC,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAC3B,SAAS,eAAe,iBAAiB;AACzC,SAAS,sBAAsB;","names":[]}
1
+ {"version":3,"sources":["../../../src/localization/index.ts"],"sourcesContent":["export { getHTMLTextDir } from './getHTMLTextDir';\nexport { getLocaleFromPath } from './getLocaleFromPath';\nexport { getLocaleLang } from './getLocaleLang';\nexport { getLocaleName } from './getLocaleName';\nexport { getLocalizedUrl } from './getLocalizedUrl';\nexport { getMultilingualUrls } from './getMultilingualUrls';\nexport { getPathWithoutLocale } from './getPathWithoutLocale';\nexport { localeDetector } from './localeDetector';\nexport { localeList } from './localeList';\nexport { localeFlatMap, localeMap, localeRecord } from './localeMapper';\nexport { localeResolver } from './localeResolver';\n"],"mappings":"AAAA,SAAS,sBAAsB;AAC/B,SAAS,yBAAyB;AAClC,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAChC,SAAS,2BAA2B;AACpC,SAAS,4BAA4B;AACrC,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAC3B,SAAS,eAAe,WAAW,oBAAoB;AACvD,SAAS,sBAAsB;","names":[]}
@@ -17,8 +17,22 @@ const localeFlatMap = (mapper, locales = configuration.internationalization.loca
17
17
  urlPrefix: locale === defaultLocale && !prefixDefault ? "" : `/${locale}`
18
18
  })
19
19
  );
20
+ const localeRecord = (mapper, locales = configuration.internationalization.locales, defaultLocale = configuration.internationalization.defaultLocale, prefixDefault = configuration.middleware.prefixDefault) => locales.reduce(
21
+ (acc, locale) => {
22
+ acc[locale] = mapper({
23
+ locale,
24
+ defaultLocale,
25
+ locales,
26
+ isDefault: locale === defaultLocale,
27
+ urlPrefix: locale === defaultLocale && !prefixDefault ? "" : `/${locale}`
28
+ });
29
+ return acc;
30
+ },
31
+ {}
32
+ );
20
33
  export {
21
34
  localeFlatMap,
22
- localeMap
35
+ localeMap,
36
+ localeRecord
23
37
  };
24
38
  //# sourceMappingURL=localeMapper.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/localization/localeMapper.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { LocalesValues } from '@intlayer/config/client';\n\nexport type LocaleData = {\n locale: LocalesValues;\n defaultLocale: LocalesValues;\n isDefault: boolean;\n locales: LocalesValues[];\n urlPrefix: string;\n};\n\n/**\n * Map the locale data to an array of objects\n *\n * @example\n * ```ts\n * const routes = localeMap((localizedData) =>\n * ({\n * path: localizedData.urlPrefix,\n * name: localizedData.locale,\n * isDefault: localizedData.isDefault,\n * locales: localizedData.locales,\n * defaultLocale: localizedData.defaultLocale,\n * }),\n * );\n *\n * // Result\n * [\n * { path: '/', name: 'en', isDefault: true, locales: ['en'], defaultLocale: 'en', urlPrefix: '' },\n * { path: '/fr', name: 'fr', isDefault: false, locales: ['fr'], defaultLocale: 'en', urlPrefix: '/fr' },\n * { path: '/es', name: 'es', isDefault: false, locales: ['es'], defaultLocale: 'en', urlPrefix: '/es' },\n * ]\n * ```\n *\n * @param mapper - The mapper function that returns an object\n * @returns An array of objects\n */\nexport const localeMap = <T extends object>(\n mapper: (locale: LocaleData) => T,\n locales: LocalesValues[] = configuration.internationalization.locales,\n defaultLocale: LocalesValues = configuration.internationalization\n .defaultLocale,\n prefixDefault: boolean = configuration.middleware.prefixDefault\n): T[] =>\n locales.map((locale) =>\n mapper({\n locale,\n defaultLocale,\n locales,\n isDefault: locale === defaultLocale,\n urlPrefix: locale === defaultLocale && !prefixDefault ? '' : `/${locale}`,\n })\n );\n\n/**\n * Flatten the locale map into a single array of objects\n *\n * @example\n * ```ts\n * const routes = localeMap((localizedData) =>\n * [{\n * path: localizedData.urlPrefix,\n * name: localizedData.locale,\n * isDefault: localizedData.isDefault,\n * locales: localizedData.locales,\n * defaultLocale: localizedData.defaultLocale,\n * }],\n * );\n *\n * // Result\n * [\n * { path: '/', name: 'en', isDefault: true, locales: ['en'], defaultLocale: 'en', urlPrefix: '' },\n * { path: '/fr', name: 'fr', isDefault: false, locales: ['fr'], defaultLocale: 'en', urlPrefix: '/fr' },\n * { path: '/es', name: 'es', isDefault: false, locales: ['es'], defaultLocale: 'en', urlPrefix: '/es' },\n * ]\n * ```\n *\n * @param mapper - The mapper function that returns an array of objects\n * @returns An array of objects\n */\nexport const localeFlatMap = <T>(\n mapper: (locale: LocaleData) => T[],\n locales: LocalesValues[] = configuration.internationalization.locales,\n defaultLocale: LocalesValues = configuration.internationalization\n .defaultLocale,\n prefixDefault: boolean = configuration.middleware.prefixDefault\n): T[] =>\n locales.flatMap((locale) =>\n mapper({\n locale,\n defaultLocale,\n locales,\n isDefault: locale === defaultLocale,\n urlPrefix: locale === defaultLocale && !prefixDefault ? '' : `/${locale}`,\n })\n );\n"],"mappings":"AAAA,OAAO,mBAAmB;AAqCnB,MAAM,YAAY,CACvB,QACA,UAA2B,cAAc,qBAAqB,SAC9D,gBAA+B,cAAc,qBAC1C,eACH,gBAAyB,cAAc,WAAW,kBAElD,QAAQ;AAAA,EAAI,CAAC,WACX,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,WAAW;AAAA,IACtB,WAAW,WAAW,iBAAiB,CAAC,gBAAgB,KAAK,IAAI,MAAM;AAAA,EACzE,CAAC;AACH;AA4BK,MAAM,gBAAgB,CAC3B,QACA,UAA2B,cAAc,qBAAqB,SAC9D,gBAA+B,cAAc,qBAC1C,eACH,gBAAyB,cAAc,WAAW,kBAElD,QAAQ;AAAA,EAAQ,CAAC,WACf,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,WAAW;AAAA,IACtB,WAAW,WAAW,iBAAiB,CAAC,gBAAgB,KAAK,IAAI,MAAM;AAAA,EACzE,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../../../src/localization/localeMapper.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { Locales, LocalesValues } from '@intlayer/config/client';\n\nexport type LocaleData = {\n locale: LocalesValues;\n defaultLocale: LocalesValues;\n isDefault: boolean;\n locales: LocalesValues[];\n urlPrefix: string;\n};\n\n/**\n * Map the locale data to an array of objects\n *\n * @example\n * ```ts\n * const routes = localeMap((localizedData) =>\n * ({\n * path: localizedData.urlPrefix,\n * name: localizedData.locale,\n * isDefault: localizedData.isDefault,\n * locales: localizedData.locales,\n * defaultLocale: localizedData.defaultLocale,\n * }),\n * );\n *\n * // Result\n * [\n * { path: '/', name: 'en', isDefault: true, locales: ['en'], defaultLocale: 'en', urlPrefix: '' },\n * { path: '/fr', name: 'fr', isDefault: false, locales: ['fr'], defaultLocale: 'en', urlPrefix: '/fr' },\n * { path: '/es', name: 'es', isDefault: false, locales: ['es'], defaultLocale: 'en', urlPrefix: '/es' },\n * ]\n * ```\n *\n * @param mapper - The mapper function that returns an object\n * @returns An array of objects\n */\nexport const localeMap = <T extends object>(\n mapper: (locale: LocaleData) => T,\n locales: LocalesValues[] = configuration.internationalization.locales,\n defaultLocale: LocalesValues = configuration.internationalization\n .defaultLocale,\n prefixDefault: boolean = configuration.middleware.prefixDefault\n): T[] =>\n locales.map((locale) =>\n mapper({\n locale,\n defaultLocale,\n locales,\n isDefault: locale === defaultLocale,\n urlPrefix: locale === defaultLocale && !prefixDefault ? '' : `/${locale}`,\n })\n );\n\n/**\n * Flatten the locale map into a single array of objects\n *\n * @example\n * ```ts\n * const routes = localeMap((localizedData) =>\n * [{\n * path: localizedData.urlPrefix,\n * name: localizedData.locale,\n * isDefault: localizedData.isDefault,\n * locales: localizedData.locales,\n * defaultLocale: localizedData.defaultLocale,\n * }],\n * );\n *\n * // Result\n * [\n * { path: '/', name: 'en', isDefault: true, locales: ['en'], defaultLocale: 'en', urlPrefix: '' },\n * { path: '/fr', name: 'fr', isDefault: false, locales: ['fr'], defaultLocale: 'en', urlPrefix: '/fr' },\n * { path: '/es', name: 'es', isDefault: false, locales: ['es'], defaultLocale: 'en', urlPrefix: '/es' },\n * ]\n * ```\n *\n * @param mapper - The mapper function that returns an array of objects\n * @returns An array of objects\n */\nexport const localeFlatMap = <T>(\n mapper: (locale: LocaleData) => T[],\n locales: LocalesValues[] = configuration.internationalization.locales,\n defaultLocale: LocalesValues = configuration.internationalization\n .defaultLocale,\n prefixDefault: boolean = configuration.middleware.prefixDefault\n): T[] =>\n locales.flatMap((locale) =>\n mapper({\n locale,\n defaultLocale,\n locales,\n isDefault: locale === defaultLocale,\n urlPrefix: locale === defaultLocale && !prefixDefault ? '' : `/${locale}`,\n })\n );\n\n/**\n * Creates a record object mapping locales to values transformed by the mapper function\n *\n * @example\n * ```ts\n * const translations = localeRecord(({ locale }) =>\n * require(`./translations/${locale}.json`)\n * );\n *\n * // Result\n * {\n * en: { ... }, // Content of translations/en.json\n * fr: { ... }, // Content of translations/fr.json\n * es: { ... } // Content of translations/es.json\n * }\n * ```\n *\n * @param mapper - Function that takes locale data and returns a value for that locale\n * @param locales - Array of locale codes to map over (defaults to configured locales)\n * @param defaultLocale - The default locale (defaults to configured default)\n * @param prefixDefault - Whether to prefix the default locale in URLs (defaults to configured value)\n * @returns Record mapping locale codes to mapped values\n */\nexport const localeRecord = <T>(\n mapper: (locale: LocaleData) => T,\n locales: Locales[] = configuration.internationalization.locales,\n defaultLocale: Locales = configuration.internationalization.defaultLocale,\n prefixDefault: boolean = configuration.middleware.prefixDefault\n): Record<Locales, T> =>\n locales.reduce(\n (acc, locale) => {\n acc[locale] = mapper({\n locale,\n defaultLocale,\n locales,\n isDefault: locale === defaultLocale,\n urlPrefix:\n locale === defaultLocale && !prefixDefault ? '' : `/${locale}`,\n });\n return acc;\n },\n {} as Record<Locales, T>\n );\n"],"mappings":"AAAA,OAAO,mBAAmB;AAqCnB,MAAM,YAAY,CACvB,QACA,UAA2B,cAAc,qBAAqB,SAC9D,gBAA+B,cAAc,qBAC1C,eACH,gBAAyB,cAAc,WAAW,kBAElD,QAAQ;AAAA,EAAI,CAAC,WACX,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,WAAW;AAAA,IACtB,WAAW,WAAW,iBAAiB,CAAC,gBAAgB,KAAK,IAAI,MAAM;AAAA,EACzE,CAAC;AACH;AA4BK,MAAM,gBAAgB,CAC3B,QACA,UAA2B,cAAc,qBAAqB,SAC9D,gBAA+B,cAAc,qBAC1C,eACH,gBAAyB,cAAc,WAAW,kBAElD,QAAQ;AAAA,EAAQ,CAAC,WACf,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,WAAW;AAAA,IACtB,WAAW,WAAW,iBAAiB,CAAC,gBAAgB,KAAK,IAAI,MAAM;AAAA,EACzE,CAAC;AACH;AAyBK,MAAM,eAAe,CAC1B,QACA,UAAqB,cAAc,qBAAqB,SACxD,gBAAyB,cAAc,qBAAqB,eAC5D,gBAAyB,cAAc,WAAW,kBAElD,QAAQ;AAAA,EACN,CAAC,KAAK,WAAW;AACf,QAAI,MAAM,IAAI,OAAO;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,WAAW;AAAA,MACtB,WACE,WAAW,iBAAiB,CAAC,gBAAgB,KAAK,IAAI,MAAM;AAAA,IAChE,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EACA,CAAC;AACH;","names":[]}
@@ -20,36 +20,59 @@ const getMarkdownMetadata = (markdown) => {
20
20
  const lines = markdown.split(/\r?\n/);
21
21
  const firstNonEmptyLine = lines.find((line) => line.trim() !== "");
22
22
  if (!firstNonEmptyLine || firstNonEmptyLine.trim() !== "---") {
23
- return {};
23
+ const result = {};
24
+ return result;
24
25
  }
25
26
  const metadata = {};
26
27
  let inMetadataBlock = false;
27
- for (const line of lines) {
28
+ let currentKey = null;
29
+ let currentArrayItems = [];
30
+ for (let i = 0; i < lines.length; i++) {
31
+ const line = lines[i];
28
32
  const trimmedLine = line.trim();
29
33
  if (trimmedLine === "---") {
30
34
  if (!inMetadataBlock) {
31
35
  inMetadataBlock = true;
32
36
  continue;
33
37
  } else {
38
+ if (currentKey && currentArrayItems.length > 0) {
39
+ metadata[currentKey] = currentArrayItems;
40
+ }
34
41
  break;
35
42
  }
36
43
  }
37
44
  if (inMetadataBlock) {
45
+ const arrayItemMatch = line.match(/^\s*-\s+(.+)$/);
46
+ if (arrayItemMatch && currentKey) {
47
+ currentArrayItems.push(arrayItemMatch[1].trim());
48
+ continue;
49
+ }
50
+ if (currentKey && currentArrayItems.length > 0) {
51
+ metadata[currentKey] = currentArrayItems;
52
+ currentKey = null;
53
+ currentArrayItems = [];
54
+ }
38
55
  const match = line.match(/^([^:]+)\s*:\s*(.*)$/);
39
56
  if (match) {
40
57
  const key = match[1].trim();
41
58
  const value = match[2].trim();
42
- try {
43
- metadata[key] = parseToObject(value);
44
- } catch (e) {
45
- metadata[key] = value;
59
+ if (value === "") {
60
+ currentKey = key;
61
+ currentArrayItems = [];
62
+ } else {
63
+ try {
64
+ metadata[key] = parseToObject(value);
65
+ } catch (e) {
66
+ metadata[key] = value;
67
+ }
46
68
  }
47
69
  }
48
70
  }
49
71
  }
50
72
  return metadata;
51
73
  } catch (e) {
52
- return void 0;
74
+ const result = {};
75
+ return result;
53
76
  }
54
77
  };
55
78
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/transpiler/markdown/getMarkdownMetadata.ts"],"sourcesContent":["const parseToObject = <T = any>(input: string): T | null => {\n // Normalize different bracket types and keys/values\n let normalizedInput = input\n .trim()\n .replace(/^\\[/, '[') // Keep array brackets\n .replace(/^\\{/, '{') // Keep object brackets\n .replace(/\\]$/, ']') // Keep array brackets\n .replace(/\\}$/, '}') // Keep object brackets\n .replace(/([\\w\\d_]+)\\s*:/g, '\"$1\":') // Ensure JSON-valid keys (e.g., key: -> \"key\":)\n .replace(/:\\s*([a-zA-Z_][\\w\\d_]*)/g, ': \"$1\"'); // Handle unquoted string values\n\n // Fix arrays with unquoted items (e.g., [content, anotherContent])\n normalizedInput = normalizedInput.replace(\n /\\[([^\\[\\]]+?)\\]/g,\n (_match, arrayContent) => {\n const newContent = (arrayContent as string)\n .split(',')\n .map((item) => {\n const trimmed = item.trim();\n // If already quoted or is a valid number, return as is.\n if (\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n !isNaN(Number(trimmed))\n ) {\n return trimmed;\n }\n return `\"${trimmed}\"`;\n })\n .join(', ');\n return `[${newContent}]`;\n }\n );\n\n // Parse the string into an object\n return JSON.parse(normalizedInput) as T;\n};\n\nexport const getMarkdownMetadata = (\n markdown: string\n): Record<string, any> | undefined => {\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 || firstNonEmptyLine.trim() !== '---') {\n return {};\n }\n\n const metadata: Record<string, any> = {};\n let inMetadataBlock = false;\n\n for (const line of lines) {\n const trimmedLine = line.trim();\n\n // Toggle metadata block on encountering the delimiter.\n if (trimmedLine === '---') {\n if (!inMetadataBlock) {\n // Begin metadata block.\n inMetadataBlock = true;\n continue;\n } else {\n // End of metadata block; stop processing.\n break;\n }\n }\n\n // If we're inside the metadata block, parse key: value pairs.\n if (inMetadataBlock) {\n const match = line.match(/^([^:]+)\\s*:\\s*(.*)$/);\n if (match) {\n const key = match[1].trim();\n const value = match[2].trim();\n try {\n metadata[key] = parseToObject(value);\n } catch (e) {\n metadata[key] = value;\n }\n }\n }\n }\n\n return metadata;\n } catch (e) {\n return undefined;\n }\n};\n"],"mappings":"AAAA,MAAM,gBAAgB,CAAU,UAA4B;AAE1D,MAAI,kBAAkB,MACnB,KAAK,EACL,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,mBAAmB,OAAO,EAClC,QAAQ,4BAA4B,QAAQ;AAG/C,oBAAkB,gBAAgB;AAAA,IAChC;AAAA,IACA,CAAC,QAAQ,iBAAiB;AACxB,YAAM,aAAc,aACjB,MAAM,GAAG,EACT,IAAI,CAAC,SAAS;AACb,cAAM,UAAU,KAAK,KAAK;AAE1B,YACG,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,KAChD,CAAC,MAAM,OAAO,OAAO,CAAC,GACtB;AACA,iBAAO;AAAA,QACT;AACA,eAAO,IAAI,OAAO;AAAA,MACpB,CAAC,EACA,KAAK,IAAI;AACZ,aAAO,IAAI,UAAU;AAAA,IACvB;AAAA,EACF;AAGA,SAAO,KAAK,MAAM,eAAe;AACnC;AAEO,MAAM,sBAAsB,CACjC,aACoC;AACpC,MAAI;AACF,UAAM,QAAQ,SAAS,MAAM,OAAO;AAGpC,UAAM,oBAAoB,MAAM,KAAK,CAAC,SAAS,KAAK,KAAK,MAAM,EAAE;AAEjE,QAAI,CAAC,qBAAqB,kBAAkB,KAAK,MAAM,OAAO;AAC5D,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,WAAgC,CAAC;AACvC,QAAI,kBAAkB;AAEtB,eAAW,QAAQ,OAAO;AACxB,YAAM,cAAc,KAAK,KAAK;AAG9B,UAAI,gBAAgB,OAAO;AACzB,YAAI,CAAC,iBAAiB;AAEpB,4BAAkB;AAClB;AAAA,QACF,OAAO;AAEL;AAAA,QACF;AAAA,MACF;AAGA,UAAI,iBAAiB;AACnB,cAAM,QAAQ,KAAK,MAAM,sBAAsB;AAC/C,YAAI,OAAO;AACT,gBAAM,MAAM,MAAM,CAAC,EAAE,KAAK;AAC1B,gBAAM,QAAQ,MAAM,CAAC,EAAE,KAAK;AAC5B,cAAI;AACF,qBAAS,GAAG,IAAI,cAAc,KAAK;AAAA,UACrC,SAAS,GAAG;AACV,qBAAS,GAAG,IAAI;AAAA,UAClB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT,SAAS,GAAG;AACV,WAAO;AAAA,EACT;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/transpiler/markdown/getMarkdownMetadata.ts"],"sourcesContent":["const parseToObject = <T = any>(input: string): T | null => {\n // Normalize different bracket types and keys/values\n let normalizedInput = input\n .trim()\n .replace(/^\\[/, '[') // Keep array brackets\n .replace(/^\\{/, '{') // Keep object brackets\n .replace(/\\]$/, ']') // Keep array brackets\n .replace(/\\}$/, '}') // Keep object brackets\n .replace(/([\\w\\d_]+)\\s*:/g, '\"$1\":') // Ensure JSON-valid keys (e.g., key: -> \"key\":)\n .replace(/:\\s*([a-zA-Z_][\\w\\d_]*)/g, ': \"$1\"'); // Handle unquoted string values\n\n // Fix arrays with unquoted items (e.g., [content, anotherContent])\n normalizedInput = normalizedInput.replace(\n /\\[([^\\[\\]]+?)\\]/g,\n (_match, arrayContent) => {\n const newContent = (arrayContent as string)\n .split(',')\n .map((item) => {\n const trimmed = item.trim();\n // If already quoted or is a valid number, return as is.\n if (\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n !isNaN(Number(trimmed))\n ) {\n return trimmed;\n }\n return `\"${trimmed}\"`;\n })\n .join(', ');\n return `[${newContent}]`;\n }\n );\n\n // Parse the string into an object\n return JSON.parse(normalizedInput) as T;\n};\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 || firstNonEmptyLine.trim() !== '---') {\n const result: T = {} as T;\n return result;\n }\n\n const metadata: T = {} as T;\n let inMetadataBlock = false;\n let currentKey: string | null = null;\n let currentArrayItems: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmedLine = line.trim();\n\n // Toggle metadata block on encountering the delimiter.\n if (trimmedLine === '---') {\n if (!inMetadataBlock) {\n // Begin metadata block.\n inMetadataBlock = true;\n continue;\n } else {\n // End of metadata block; finalize any pending array and stop processing.\n if (currentKey && currentArrayItems.length > 0) {\n (metadata as Record<string, any>)[currentKey] = currentArrayItems;\n }\n break;\n }\n }\n\n // If we're inside the metadata block, parse key: value pairs.\n if (inMetadataBlock) {\n // Check if this line is an array item (starts with - )\n const arrayItemMatch = line.match(/^\\s*-\\s+(.+)$/);\n if (arrayItemMatch && currentKey) {\n // This is an array item for the current key\n currentArrayItems.push(arrayItemMatch[1].trim());\n continue;\n }\n\n // If we have a pending array from a previous key, save it\n if (currentKey && currentArrayItems.length > 0) {\n (metadata as Record<string, any>)[currentKey] = currentArrayItems;\n currentKey = null;\n currentArrayItems = [];\n }\n\n // Check for key: value pairs\n const match = line.match(/^([^:]+)\\s*:\\s*(.*)$/);\n if (match) {\n const key = match[1].trim();\n const value = match[2].trim();\n\n if (value === '') {\n // This might be the start of a multi-line structure (like an array)\n currentKey = key;\n currentArrayItems = [];\n } else {\n try {\n (metadata as Record<string, any>)[key] = parseToObject(value);\n } catch (e) {\n (metadata as Record<string, any>)[key] = value;\n }\n }\n }\n }\n }\n\n return metadata;\n } catch (e) {\n const result: T = {} as T;\n return result;\n }\n};\n"],"mappings":"AAAA,MAAM,gBAAgB,CAAU,UAA4B;AAE1D,MAAI,kBAAkB,MACnB,KAAK,EACL,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,mBAAmB,OAAO,EAClC,QAAQ,4BAA4B,QAAQ;AAG/C,oBAAkB,gBAAgB;AAAA,IAChC;AAAA,IACA,CAAC,QAAQ,iBAAiB;AACxB,YAAM,aAAc,aACjB,MAAM,GAAG,EACT,IAAI,CAAC,SAAS;AACb,cAAM,UAAU,KAAK,KAAK;AAE1B,YACG,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,KAChD,CAAC,MAAM,OAAO,OAAO,CAAC,GACtB;AACA,iBAAO;AAAA,QACT;AACA,eAAO,IAAI,OAAO;AAAA,MACpB,CAAC,EACA,KAAK,IAAI;AACZ,aAAO,IAAI,UAAU;AAAA,IACvB;AAAA,EACF;AAGA,SAAO,KAAK,MAAM,eAAe;AACnC;AAEO,MAAM,sBAAsB,CACjC,aACM;AACN,MAAI;AACF,UAAM,QAAQ,SAAS,MAAM,OAAO;AAGpC,UAAM,oBAAoB,MAAM,KAAK,CAAC,SAAS,KAAK,KAAK,MAAM,EAAE;AAEjE,QAAI,CAAC,qBAAqB,kBAAkB,KAAK,MAAM,OAAO;AAC5D,YAAM,SAAY,CAAC;AACnB,aAAO;AAAA,IACT;AAEA,UAAM,WAAc,CAAC;AACrB,QAAI,kBAAkB;AACtB,QAAI,aAA4B;AAChC,QAAI,oBAA8B,CAAC;AAEnC,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,OAAO,MAAM,CAAC;AACpB,YAAM,cAAc,KAAK,KAAK;AAG9B,UAAI,gBAAgB,OAAO;AACzB,YAAI,CAAC,iBAAiB;AAEpB,4BAAkB;AAClB;AAAA,QACF,OAAO;AAEL,cAAI,cAAc,kBAAkB,SAAS,GAAG;AAC9C,YAAC,SAAiC,UAAU,IAAI;AAAA,UAClD;AACA;AAAA,QACF;AAAA,MACF;AAGA,UAAI,iBAAiB;AAEnB,cAAM,iBAAiB,KAAK,MAAM,eAAe;AACjD,YAAI,kBAAkB,YAAY;AAEhC,4BAAkB,KAAK,eAAe,CAAC,EAAE,KAAK,CAAC;AAC/C;AAAA,QACF;AAGA,YAAI,cAAc,kBAAkB,SAAS,GAAG;AAC9C,UAAC,SAAiC,UAAU,IAAI;AAChD,uBAAa;AACb,8BAAoB,CAAC;AAAA,QACvB;AAGA,cAAM,QAAQ,KAAK,MAAM,sBAAsB;AAC/C,YAAI,OAAO;AACT,gBAAM,MAAM,MAAM,CAAC,EAAE,KAAK;AAC1B,gBAAM,QAAQ,MAAM,CAAC,EAAE,KAAK;AAE5B,cAAI,UAAU,IAAI;AAEhB,yBAAa;AACb,gCAAoB,CAAC;AAAA,UACvB,OAAO;AACL,gBAAI;AACF,cAAC,SAAiC,GAAG,IAAI,cAAc,KAAK;AAAA,YAC9D,SAAS,GAAG;AACV,cAAC,SAAiC,GAAG,IAAI;AAAA,YAC3C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT,SAAS,GAAG;AACV,UAAM,SAAY,CAAC;AACnB,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -0,0 +1,34 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { getMarkdownMetadata } from "../index.mjs";
3
+ describe("getMarkdownMetadata", () => {
4
+ const markdown = [
5
+ "---",
6
+ "title: Mock Title",
7
+ "description: Mock Description",
8
+ "author: Mock Author",
9
+ "date: 2024-01-01",
10
+ "tags:",
11
+ " - tag1",
12
+ " - tag2",
13
+ " - tag3",
14
+ "---",
15
+ "# Mock Heading",
16
+ "This is a mock paragraph with some sample text.",
17
+ "Here is another mock paragraph.",
18
+ "## Mock Section",
19
+ "Some more mock content goes here.",
20
+ "### Mock Subsection",
21
+ "Final mock paragraph with test content."
22
+ ].join("\n");
23
+ it("should return the metadata from the markdown file", () => {
24
+ const metadata = getMarkdownMetadata(markdown);
25
+ expect(metadata).toEqual({
26
+ title: "Mock Title",
27
+ description: "Mock Description",
28
+ author: "Mock Author",
29
+ date: "2024-01-01",
30
+ tags: ["tag1", "tag2", "tag3"]
31
+ });
32
+ });
33
+ });
34
+ //# sourceMappingURL=getMarkdownMetadata.test.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/transpiler/markdown/getMarkdownMetadata.test.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest';\nimport { getMarkdownMetadata } from '..';\n\ndescribe('getMarkdownMetadata', () => {\n const markdown = [\n '---',\n 'title: Mock Title',\n 'description: Mock Description',\n 'author: Mock Author',\n 'date: 2024-01-01',\n 'tags:',\n ' - tag1',\n ' - tag2',\n ' - tag3',\n '---',\n '# Mock Heading',\n 'This is a mock paragraph with some sample text.',\n 'Here is another mock paragraph.',\n '## Mock Section',\n 'Some more mock content goes here.',\n '### Mock Subsection',\n 'Final mock paragraph with test content.',\n ].join('\\n');\n\n it('should return the metadata from the markdown file', () => {\n const metadata = getMarkdownMetadata(markdown);\n expect(metadata).toEqual({\n title: 'Mock Title',\n description: 'Mock Description',\n author: 'Mock Author',\n date: '2024-01-01',\n tags: ['tag1', 'tag2', 'tag3'],\n });\n });\n});\n"],"mappings":"AAAA,SAAS,UAAU,QAAQ,UAAU;AACrC,SAAS,2BAA2B;AAEpC,SAAS,uBAAuB,MAAM;AACpC,QAAM,WAAW;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AAEX,KAAG,qDAAqD,MAAM;AAC5D,UAAM,WAAW,oBAAoB,QAAQ;AAC7C,WAAO,QAAQ,EAAE,QAAQ;AAAA,MACvB,OAAO;AAAA,MACP,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM,CAAC,QAAQ,QAAQ,MAAM;AAAA,IAC/B,CAAC;AAAA,EACH,CAAC;AACH,CAAC;","names":[]}
@@ -7,6 +7,6 @@ export { getMultilingualUrls } from './getMultilingualUrls';
7
7
  export { getPathWithoutLocale } from './getPathWithoutLocale';
8
8
  export { localeDetector } from './localeDetector';
9
9
  export { localeList } from './localeList';
10
- export { localeFlatMap, localeMap } from './localeMapper';
10
+ export { localeFlatMap, localeMap, localeRecord } from './localeMapper';
11
11
  export { localeResolver } from './localeResolver';
12
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/localization/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/localization/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { LocalesValues } from '@intlayer/config/client';
1
+ import { Locales, LocalesValues } from '@intlayer/config/client';
2
2
  export type LocaleData = {
3
3
  locale: LocalesValues;
4
4
  defaultLocale: LocalesValues;
@@ -60,4 +60,28 @@ export declare const localeMap: <T extends object>(mapper: (locale: LocaleData)
60
60
  * @returns An array of objects
61
61
  */
62
62
  export declare const localeFlatMap: <T>(mapper: (locale: LocaleData) => T[], locales?: LocalesValues[], defaultLocale?: LocalesValues, prefixDefault?: boolean) => T[];
63
+ /**
64
+ * Creates a record object mapping locales to values transformed by the mapper function
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * const translations = localeRecord(({ locale }) =>
69
+ * require(`./translations/${locale}.json`)
70
+ * );
71
+ *
72
+ * // Result
73
+ * {
74
+ * en: { ... }, // Content of translations/en.json
75
+ * fr: { ... }, // Content of translations/fr.json
76
+ * es: { ... } // Content of translations/es.json
77
+ * }
78
+ * ```
79
+ *
80
+ * @param mapper - Function that takes locale data and returns a value for that locale
81
+ * @param locales - Array of locale codes to map over (defaults to configured locales)
82
+ * @param defaultLocale - The default locale (defaults to configured default)
83
+ * @param prefixDefault - Whether to prefix the default locale in URLs (defaults to configured value)
84
+ * @returns Record mapping locale codes to mapped values
85
+ */
86
+ export declare const localeRecord: <T>(mapper: (locale: LocaleData) => T, locales?: Locales[], defaultLocale?: Locales, prefixDefault?: boolean) => Record<Locales, T>;
63
87
  //# sourceMappingURL=localeMapper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"localeMapper.d.ts","sourceRoot":"","sources":["../../../src/localization/localeMapper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,MAAM,EACxC,QAAQ,CAAC,MAAM,EAAE,UAAU,KAAK,CAAC,EACjC,UAAS,aAAa,EAA+C,EACrE,gBAAe,aACC,EAChB,gBAAe,OAAgD,KAC9D,CAAC,EASD,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,EAC7B,QAAQ,CAAC,MAAM,EAAE,UAAU,KAAK,CAAC,EAAE,EACnC,UAAS,aAAa,EAA+C,EACrE,gBAAe,aACC,EAChB,gBAAe,OAAgD,KAC9D,CAAC,EASD,CAAC"}
1
+ {"version":3,"file":"localeMapper.d.ts","sourceRoot":"","sources":["../../../src/localization/localeMapper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAEjE,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,MAAM,EACxC,QAAQ,CAAC,MAAM,EAAE,UAAU,KAAK,CAAC,EACjC,UAAS,aAAa,EAA+C,EACrE,gBAAe,aACC,EAChB,gBAAe,OAAgD,KAC9D,CAAC,EASD,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,EAC7B,QAAQ,CAAC,MAAM,EAAE,UAAU,KAAK,CAAC,EAAE,EACnC,UAAS,aAAa,EAA+C,EACrE,gBAAe,aACC,EAChB,gBAAe,OAAgD,KAC9D,CAAC,EASD,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,EAC5B,QAAQ,CAAC,MAAM,EAAE,UAAU,KAAK,CAAC,EACjC,UAAS,OAAO,EAA+C,EAC/D,gBAAe,OAA0D,EACzE,gBAAe,OAAgD,KAC9D,MAAM,CAAC,OAAO,EAAE,CAAC,CAcjB,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const getMarkdownMetadata: (markdown: string) => Record<string, any> | undefined;
1
+ export declare const getMarkdownMetadata: <T extends Record<string, any>>(markdown: string) => T;
2
2
  //# sourceMappingURL=getMarkdownMetadata.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getMarkdownMetadata.d.ts","sourceRoot":"","sources":["../../../../src/transpiler/markdown/getMarkdownMetadata.ts"],"names":[],"mappings":"AAqCA,eAAO,MAAM,mBAAmB,GAC9B,UAAU,MAAM,KACf,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAgDxB,CAAC"}
1
+ {"version":3,"file":"getMarkdownMetadata.d.ts","sourceRoot":"","sources":["../../../../src/transpiler/markdown/getMarkdownMetadata.ts"],"names":[],"mappings":"AAqCA,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC/D,UAAU,MAAM,KACf,CA+EF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=getMarkdownMetadata.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getMarkdownMetadata.test.d.ts","sourceRoot":"","sources":["../../../../src/transpiler/markdown/getMarkdownMetadata.test.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/core",
3
- "version": "5.5.9",
3
+ "version": "5.5.11",
4
4
  "private": false,
5
5
  "description": "Includes core Intlayer functions like translation, dictionary, and utility functions shared across multiple packages.",
6
6
  "keywords": [
@@ -75,9 +75,9 @@
75
75
  ],
76
76
  "dependencies": {
77
77
  "negotiator": "^1.0.0",
78
- "@intlayer/api": "5.5.9",
79
- "@intlayer/dictionaries-entry": "5.5.9",
80
- "@intlayer/config": "5.5.9"
78
+ "@intlayer/api": "5.5.11",
79
+ "@intlayer/dictionaries-entry": "5.5.11",
80
+ "@intlayer/config": "5.5.11"
81
81
  },
82
82
  "devDependencies": {
83
83
  "@types/negotiator": "^0.6.3",
@@ -90,16 +90,17 @@
90
90
  "tsc-alias": "^1.8.16",
91
91
  "tsup": "^8.5.0",
92
92
  "typescript": "^5.8.3",
93
- "@utils/eslint-config": "1.0.4",
94
- "@utils/ts-config-types": "1.0.4",
93
+ "vitest": "^3.2.2",
95
94
  "@utils/ts-config": "1.0.4",
96
- "@utils/tsup-config": "1.0.4"
95
+ "@utils/eslint-config": "1.0.4",
96
+ "@utils/tsup-config": "1.0.4",
97
+ "@utils/ts-config-types": "1.0.4"
97
98
  },
98
99
  "peerDependencies": {
99
- "@intlayer/config": "5.5.9",
100
- "@intlayer/dictionaries-entry": "5.5.9",
101
- "intlayer": "5.5.9",
102
- "@intlayer/api": "5.5.9"
100
+ "@intlayer/api": "5.5.11",
101
+ "intlayer": "5.5.11",
102
+ "@intlayer/config": "5.5.11",
103
+ "@intlayer/dictionaries-entry": "5.5.11"
103
104
  },
104
105
  "engines": {
105
106
  "node": ">=14.18"
@@ -122,7 +123,8 @@
122
123
  "prettier:fix": "prettier . --write",
123
124
  "process-files": "ts-node src/transpiler/processFilesCLI.ts --dir $npm_config_dir --extension $npm_config_extension --no-node-snapshot",
124
125
  "reset": "pnpm clean & pnpm build",
125
- "test": "",
126
+ "test": "vitest run",
127
+ "test:watch": "vitest",
126
128
  "typecheck": "tsup --project ./tsconfig.json --noEmit"
127
129
  }
128
130
  }