@diplodoc/transform 4.40.0 → 4.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/css/_yfm-only.css.map +1 -1
  2. package/dist/css/_yfm-only.min.css.map +1 -1
  3. package/dist/css/base.css.map +1 -1
  4. package/dist/css/base.min.css.map +1 -1
  5. package/dist/css/print.css.map +1 -1
  6. package/dist/css/yfm.css.map +1 -1
  7. package/dist/css/yfm.min.css.map +1 -1
  8. package/lib/frontmatter.d.ts +6 -0
  9. package/lib/frontmatter.js +80 -0
  10. package/lib/frontmatter.js.map +1 -0
  11. package/lib/liquid/index.d.ts +1 -1
  12. package/lib/liquid/index.js +34 -22
  13. package/lib/liquid/index.js.map +1 -1
  14. package/package.json +2 -2
  15. package/src/transform/frontmatter.ts +102 -0
  16. package/src/transform/liquid/index.ts +45 -46
  17. package/lib/frontmatter/common.d.ts +0 -21
  18. package/lib/frontmatter/common.js +0 -24
  19. package/lib/frontmatter/common.js.map +0 -1
  20. package/lib/frontmatter/emplace.d.ts +0 -4
  21. package/lib/frontmatter/emplace.js +0 -21
  22. package/lib/frontmatter/emplace.js.map +0 -1
  23. package/lib/frontmatter/extract.d.ts +0 -8
  24. package/lib/frontmatter/extract.js +0 -65
  25. package/lib/frontmatter/extract.js.map +0 -1
  26. package/lib/frontmatter/index.d.ts +0 -4
  27. package/lib/frontmatter/index.js +0 -23
  28. package/lib/frontmatter/index.js.map +0 -1
  29. package/lib/frontmatter/transformValues.d.ts +0 -2
  30. package/lib/frontmatter/transformValues.js +0 -20
  31. package/lib/frontmatter/transformValues.js.map +0 -1
  32. package/src/transform/frontmatter/common.ts +0 -27
  33. package/src/transform/frontmatter/emplace.ts +0 -24
  34. package/src/transform/frontmatter/extract.ts +0 -94
  35. package/src/transform/frontmatter/index.ts +0 -4
  36. package/src/transform/frontmatter/transformValues.ts +0 -26
@@ -0,0 +1,102 @@
1
+ import {YAMLException, dump, load} from 'js-yaml';
2
+ import {dedent} from 'ts-dedent';
3
+ import cloneDeepWith from 'lodash/cloneDeepWith';
4
+
5
+ import {log} from './log';
6
+
7
+ export type FrontMatter = {
8
+ [key: string]: unknown;
9
+ metadata?: Record<string, unknown>[];
10
+ };
11
+
12
+ const SEP = '---';
13
+
14
+ /**
15
+ * Temporary workaround to enable parsing YAML metadata from potentially
16
+ * Liquid-aware source files
17
+ * @param content Input string which could contain Liquid-style substitution syntax (which clashes with YAML
18
+ * object syntax)
19
+ * @returns String with `{}` escaped, ready to be parsed with `js-yaml`
20
+ */
21
+ const escapeLiquid = (content: string): string =>
22
+ content.replace(/{{/g, '(({{').replace(/}}/g, '}}))');
23
+
24
+ /**
25
+ * Inverse of a workaround defined above.
26
+ * @see `escapeLiquidSubstitutionSyntax`
27
+ * @param escapedContent Input string with `{}` escaped with backslashes
28
+ * @returns Unescaped string
29
+ */
30
+ const unescapeLiquid = (escapedContent: string): string =>
31
+ escapedContent.replace(/\(\({{/g, '{{').replace(/}}\)\)/g, '}}');
32
+
33
+ const matchMetadata = (fileContent: string) => {
34
+ if (!fileContent.startsWith(SEP)) {
35
+ return null;
36
+ }
37
+
38
+ const closeStart = fileContent.indexOf('\n' + SEP, SEP.length);
39
+ const closeEnd = fileContent.indexOf('\n', closeStart + 1);
40
+
41
+ if (closeStart === -1) {
42
+ return null;
43
+ }
44
+
45
+ return [fileContent.slice(SEP.length, closeStart).trim(), fileContent.slice(closeEnd + 1)];
46
+ };
47
+
48
+ const duplicateKeysCompatibleLoad = (yaml: string, filePath: string | undefined) => {
49
+ try {
50
+ return load(yaml);
51
+ } catch (e) {
52
+ if (e instanceof YAMLException) {
53
+ const duplicateKeysDeprecationWarning = dedent`
54
+ In ${filePath ?? '(unknown)'}: Encountered a YAML parsing exception when processing file metadata: ${e.reason}.
55
+ It's highly possible the input file contains duplicate mapping keys.
56
+ Will retry processing with necessary compatibility flags.
57
+ Please note that this behaviour is DEPRECATED and WILL be removed in a future version
58
+ without further notice, so the build WILL fail when supplied with YAML-incompatible meta.
59
+ `;
60
+
61
+ log.warn(duplicateKeysDeprecationWarning);
62
+
63
+ return load(yaml, {json: true});
64
+ }
65
+
66
+ throw e;
67
+ }
68
+ };
69
+
70
+ export const extractFrontMatter = (
71
+ fileContent: string,
72
+ filePath?: string,
73
+ ): [FrontMatter, string] => {
74
+ const matches = matchMetadata(fileContent);
75
+
76
+ if (matches) {
77
+ const [metadata, strippedContent] = matches;
78
+
79
+ return [
80
+ cloneDeepWith(
81
+ duplicateKeysCompatibleLoad(escapeLiquid(metadata), filePath) as FrontMatter,
82
+ (v) => (typeof v === 'string' ? unescapeLiquid(v) : undefined),
83
+ ),
84
+ strippedContent,
85
+ ];
86
+ }
87
+
88
+ return [{}, fileContent];
89
+ };
90
+
91
+ export const composeFrontMatter = (frontMatter: FrontMatter, strippedContent: string) => {
92
+ const dumped = dump(frontMatter, {lineWidth: -1}).trim();
93
+
94
+ // This empty object check is a bit naive
95
+ // The other option would be to check if all own fields are `undefined`,
96
+ // since we exploit passing in `undefined` to remove a field quite a bit
97
+ if (dumped === '{}') {
98
+ return strippedContent;
99
+ }
100
+
101
+ return `${SEP}\n${dumped}\n${SEP}\n${strippedContent}`;
102
+ };
@@ -1,12 +1,8 @@
1
1
  import type {Dictionary} from 'lodash';
2
2
 
3
- import {
4
- countLineAmount,
5
- emplaceSerializedFrontMatter,
6
- separateAndExtractFrontMatter,
7
- serializeFrontMatter,
8
- transformFrontMatterValues,
9
- } from '../frontmatter';
3
+ import {cloneDeepWith} from 'lodash';
4
+
5
+ import {composeFrontMatter, extractFrontMatter} from '../frontmatter';
10
6
 
11
7
  import applySubstitutions from './substitutions';
12
8
  import {prepareSourceMap} from './sourceMap';
@@ -149,65 +145,68 @@ function liquidSnippet<
149
145
  return output as unknown as C;
150
146
  }
151
147
 
152
- type TransformSourceMapOptions = {
153
- emplacedResultOffset: number;
154
- emplacedSourceOffset: number;
155
- };
148
+ function linesCount(content: string) {
149
+ let count = 1,
150
+ index = -1;
151
+ while ((index = content.indexOf('\n', index + 1)) > -1) {
152
+ count++;
153
+ }
156
154
 
157
- function transformSourceMap(
158
- sourceMap: Dictionary<string>,
159
- {emplacedResultOffset, emplacedSourceOffset}: TransformSourceMapOptions,
160
- ) {
161
- return Object.fromEntries(
162
- Object.entries(sourceMap).map(([lineInResult, lineInSource]) => [
163
- (Number(lineInResult) + emplacedResultOffset).toString(),
164
- (Number(lineInSource) + emplacedSourceOffset).toString(),
165
- ]),
166
- );
155
+ return count;
167
156
  }
168
157
 
169
158
  function liquidDocument<
170
159
  B extends boolean = false,
171
160
  C = B extends false ? string : {output: string; sourceMap: Dictionary<string>},
172
161
  >(
173
- originInput: string,
162
+ input: string,
174
163
  vars: Record<string, unknown>,
175
164
  path?: string,
176
165
  settings?: ArgvSettings & {withSourceMap?: B},
177
166
  ): C {
178
- const {frontMatter, frontMatterStrippedContent, frontMatterLineCount} =
179
- separateAndExtractFrontMatter(originInput, path);
167
+ const [frontMatter, strippedContent] = extractFrontMatter(input, path);
180
168
 
181
- const transformedFrontMatter = transformFrontMatterValues(frontMatter, (v) =>
182
- typeof v === 'string'
183
- ? liquidSnippet(v, vars, path, {...settings, withSourceMap: false})
184
- : v,
169
+ const liquidedFrontMatter = cloneDeepWith(frontMatter, (value: unknown) =>
170
+ typeof value === 'string'
171
+ ? liquidSnippet(value, vars, path, {...settings, withSourceMap: false})
172
+ : undefined,
185
173
  );
186
- const transformedAndSerialized = serializeFrontMatter(transformedFrontMatter);
187
174
 
188
- // -1 comes from the fact that the last line in serialized FM is the same as the first line in stripped content
189
- const resultFrontMatterOffset = Math.max(0, countLineAmount(transformedAndSerialized) - 1);
190
- const sourceFrontMatterOffset = Math.max(0, frontMatterLineCount - 1);
175
+ const liquidedResult = liquidSnippet(strippedContent, vars, path, settings);
176
+ const liquidedContent =
177
+ typeof liquidedResult === 'object' ? liquidedResult.output : liquidedResult;
191
178
 
192
- const liquidProcessedContent = liquidSnippet(frontMatterStrippedContent, vars, path, settings);
179
+ const output = composeFrontMatter(liquidedFrontMatter, liquidedContent);
180
+
181
+ if (typeof liquidedResult === 'object') {
182
+ const inputLinesCount = linesCount(input);
183
+ const outputLinesCount = linesCount(output);
184
+ const contentLinesCount = linesCount(strippedContent);
185
+ const contentLinesDiff = linesCount(liquidedContent) - contentLinesCount;
186
+
187
+ const fullLinesDiff = outputLinesCount - inputLinesCount;
188
+
189
+ // Always >= 0
190
+ const sourceOffset = inputLinesCount - contentLinesCount;
191
+ // Content lines diff already counted in source map
192
+ const resultOffset = fullLinesDiff - contentLinesDiff;
193
+
194
+ liquidedResult.sourceMap = Object.fromEntries(
195
+ Object.entries(liquidedResult.sourceMap).map(([lineInResult, lineInSource]) => [
196
+ (Number(lineInResult) + resultOffset).toString(),
197
+ (Number(lineInSource) + sourceOffset).toString(),
198
+ ]),
199
+ );
200
+ }
193
201
 
194
202
  // typeof check for better inference; the catch is that return of liquidSnippet can be an
195
203
  // object even with source maps off, see `substitutions.test.ts`
196
- return (settings?.withSourceMap && typeof liquidProcessedContent === 'object'
204
+ return (settings?.withSourceMap && typeof liquidedResult === 'object'
197
205
  ? {
198
- output: emplaceSerializedFrontMatter(
199
- liquidProcessedContent.output,
200
- transformedAndSerialized,
201
- ),
202
- sourceMap: transformSourceMap(liquidProcessedContent.sourceMap, {
203
- emplacedResultOffset: resultFrontMatterOffset,
204
- emplacedSourceOffset: sourceFrontMatterOffset,
205
- }),
206
+ output,
207
+ sourceMap: liquidedResult.sourceMap,
206
208
  }
207
- : emplaceSerializedFrontMatter(
208
- liquidProcessedContent as string,
209
- transformedAndSerialized,
210
- )) as unknown as C;
209
+ : output) as unknown as C;
211
210
  }
212
211
 
213
212
  // both default and named exports for convenience
@@ -1,21 +0,0 @@
1
- export declare type FrontMatter = {
2
- [key: string]: unknown;
3
- metadata?: Record<string, unknown>[];
4
- };
5
- export declare const frontMatterFence = "---";
6
- /**
7
- * Temporary workaround to enable parsing YAML metadata from potentially
8
- * Liquid-aware source files
9
- * @param content Input string which could contain Liquid-style substitution syntax (which clashes with YAML
10
- * object syntax)
11
- * @returns String with `{}` escaped, ready to be parsed with `js-yaml`
12
- */
13
- export declare const escapeLiquidSubstitutionSyntax: (content: string) => string;
14
- /**
15
- * Inverse of a workaround defined above.
16
- * @see `escapeLiquidSubstitutionSyntax`
17
- * @param escapedContent Input string with `{}` escaped with backslashes
18
- * @returns Unescaped string
19
- */
20
- export declare const unescapeLiquidSubstitutionSyntax: (escapedContent: string) => string;
21
- export declare const countLineAmount: (str: string) => number;
@@ -1,24 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.countLineAmount = exports.unescapeLiquidSubstitutionSyntax = exports.escapeLiquidSubstitutionSyntax = exports.frontMatterFence = void 0;
4
- exports.frontMatterFence = '---';
5
- /**
6
- * Temporary workaround to enable parsing YAML metadata from potentially
7
- * Liquid-aware source files
8
- * @param content Input string which could contain Liquid-style substitution syntax (which clashes with YAML
9
- * object syntax)
10
- * @returns String with `{}` escaped, ready to be parsed with `js-yaml`
11
- */
12
- const escapeLiquidSubstitutionSyntax = (content) => content.replace(/{{/g, '(({{').replace(/}}/g, '}}))');
13
- exports.escapeLiquidSubstitutionSyntax = escapeLiquidSubstitutionSyntax;
14
- /**
15
- * Inverse of a workaround defined above.
16
- * @see `escapeLiquidSubstitutionSyntax`
17
- * @param escapedContent Input string with `{}` escaped with backslashes
18
- * @returns Unescaped string
19
- */
20
- const unescapeLiquidSubstitutionSyntax = (escapedContent) => escapedContent.replace(/\(\({{/g, '{{').replace(/}}\)\)/g, '}}');
21
- exports.unescapeLiquidSubstitutionSyntax = unescapeLiquidSubstitutionSyntax;
22
- const countLineAmount = (str) => str.split(/\r?\n/).length;
23
- exports.countLineAmount = countLineAmount;
24
- //# sourceMappingURL=common.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/transform/frontmatter/common.ts"],"names":[],"mappings":";;;AAKa,QAAA,gBAAgB,GAAG,KAAK,CAAC;AAEtC;;;;;;GAMG;AACI,MAAM,8BAA8B,GAAG,CAAC,OAAe,EAAU,EAAE,CACtE,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAD7C,QAAA,8BAA8B,kCACe;AAE1D;;;;;GAKG;AACI,MAAM,gCAAgC,GAAG,CAAC,cAAsB,EAAU,EAAE,CAC/E,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AADxD,QAAA,gCAAgC,oCACwB;AAE9D,MAAM,eAAe,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;AAA7D,QAAA,eAAe,mBAA8C"}
@@ -1,4 +0,0 @@
1
- import { FrontMatter } from './common';
2
- export declare const serializeFrontMatter: (frontMatter: FrontMatter) => string;
3
- export declare const emplaceSerializedFrontMatter: (frontMatterStrippedContent: string, frontMatter: string) => string;
4
- export declare const emplaceFrontMatter: (frontMatterStrippedContent: string, frontMatter: FrontMatter) => string;
@@ -1,21 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.emplaceFrontMatter = exports.emplaceSerializedFrontMatter = exports.serializeFrontMatter = void 0;
4
- const js_yaml_1 = require("js-yaml");
5
- const common_1 = require("./common");
6
- const serializeFrontMatter = (frontMatter) => {
7
- const dumped = (0, js_yaml_1.dump)(frontMatter, { lineWidth: -1 }).trim();
8
- // This empty object check is a bit naive
9
- // The other option would be to check if all own fields are `undefined`,
10
- // since we exploit passing in `undefined` to remove a field quite a bit
11
- if (dumped === '{}') {
12
- return '';
13
- }
14
- return `${common_1.frontMatterFence}\n${dumped}\n${common_1.frontMatterFence}\n`;
15
- };
16
- exports.serializeFrontMatter = serializeFrontMatter;
17
- const emplaceSerializedFrontMatter = (frontMatterStrippedContent, frontMatter) => `${frontMatter}${frontMatterStrippedContent}`;
18
- exports.emplaceSerializedFrontMatter = emplaceSerializedFrontMatter;
19
- const emplaceFrontMatter = (frontMatterStrippedContent, frontMatter) => (0, exports.emplaceSerializedFrontMatter)(frontMatterStrippedContent, (0, exports.serializeFrontMatter)(frontMatter));
20
- exports.emplaceFrontMatter = emplaceFrontMatter;
21
- //# sourceMappingURL=emplace.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"emplace.js","sourceRoot":"","sources":["../../src/transform/frontmatter/emplace.ts"],"names":[],"mappings":";;;AAAA,qCAA6B;AAE7B,qCAAuD;AAEhD,MAAM,oBAAoB,GAAG,CAAC,WAAwB,EAAE,EAAE;IAC7D,MAAM,MAAM,GAAG,IAAA,cAAI,EAAC,WAAW,EAAE,EAAC,SAAS,EAAE,CAAC,CAAC,EAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAEzD,yCAAyC;IACzC,wEAAwE;IACxE,wEAAwE;IACxE,IAAI,MAAM,KAAK,IAAI,EAAE;QACjB,OAAO,EAAE,CAAC;KACb;IAED,OAAO,GAAG,yBAAgB,KAAK,MAAM,KAAK,yBAAgB,IAAI,CAAC;AACnE,CAAC,CAAC;AAXW,QAAA,oBAAoB,wBAW/B;AAEK,MAAM,4BAA4B,GAAG,CACxC,0BAAkC,EAClC,WAAmB,EACrB,EAAE,CAAC,GAAG,WAAW,GAAG,0BAA0B,EAAE,CAAC;AAHtC,QAAA,4BAA4B,gCAGU;AAE5C,MAAM,kBAAkB,GAAG,CAAC,0BAAkC,EAAE,WAAwB,EAAE,EAAE,CAC/F,IAAA,oCAA4B,EAAC,0BAA0B,EAAE,IAAA,4BAAoB,EAAC,WAAW,CAAC,CAAC,CAAC;AADnF,QAAA,kBAAkB,sBACiE"}
@@ -1,8 +0,0 @@
1
- import { FrontMatter } from './common';
2
- declare type ParseExistingMetadataReturn = {
3
- frontMatter: FrontMatter;
4
- frontMatterStrippedContent: string;
5
- frontMatterLineCount: number;
6
- };
7
- export declare const separateAndExtractFrontMatter: (fileContent: string, filePath?: string) => ParseExistingMetadataReturn;
8
- export {};
@@ -1,65 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.separateAndExtractFrontMatter = void 0;
4
- const js_yaml_1 = require("js-yaml");
5
- const log_1 = require("../log");
6
- const common_1 = require("./common");
7
- const transformValues_1 = require("./transformValues");
8
- const matchMetadata = (fileContent) => {
9
- if (!fileContent.startsWith(common_1.frontMatterFence)) {
10
- return null;
11
- }
12
- // Search by format:
13
- // ---
14
- // metaName1: metaValue1
15
- // metaName2: meta value2
16
- // incorrectMetadata
17
- // ---
18
- const regexpMetadata = '(?<=-{3}\\r?\\n)((.*\\r?\\n)*?)(?=-{3}\\r?\\n)';
19
- // Search by format:
20
- // ---
21
- // main content 123
22
- const regexpFileContent = '-{3}\\r?\\n((.*[\r?\n]*)*)';
23
- const regexpParseFileContent = new RegExp(`${regexpMetadata}${regexpFileContent}`, 'gm');
24
- return regexpParseFileContent.exec(fileContent);
25
- };
26
- const duplicateKeysCompatibleLoad = (yaml, filePath) => {
27
- try {
28
- return (0, js_yaml_1.load)(yaml);
29
- }
30
- catch (e) {
31
- if (e instanceof js_yaml_1.YAMLException) {
32
- const duplicateKeysDeprecationWarning = `
33
- In ${filePath !== null && filePath !== void 0 ? filePath : '(unknown)'}: Encountered a YAML parsing exception when processing file metadata: ${e.reason}.
34
- It's highly possible the input file contains duplicate mapping keys.
35
- Will retry processing with necessary compatibility flags.
36
- Please note that this behaviour is DEPRECATED and WILL be removed in a future version
37
- without further notice, so the build WILL fail when supplied with YAML-incompatible meta.
38
- `
39
- .replace(/^\s+/gm, '')
40
- .replace(/\n/g, ' ')
41
- .trim();
42
- log_1.log.warn(duplicateKeysDeprecationWarning);
43
- return (0, js_yaml_1.load)(yaml, { json: true });
44
- }
45
- throw e;
46
- }
47
- };
48
- const separateAndExtractFrontMatter = (fileContent, filePath) => {
49
- const matches = matchMetadata(fileContent);
50
- if (matches && matches.length > 0) {
51
- const [, metadata, , metadataStrippedContent] = matches;
52
- return {
53
- frontMatter: (0, transformValues_1.transformFrontMatterValues)(duplicateKeysCompatibleLoad((0, common_1.escapeLiquidSubstitutionSyntax)(metadata), filePath), (v) => (typeof v === 'string' ? (0, common_1.unescapeLiquidSubstitutionSyntax)(v) : v)),
54
- frontMatterStrippedContent: metadataStrippedContent,
55
- frontMatterLineCount: (0, common_1.countLineAmount)(metadata),
56
- };
57
- }
58
- return {
59
- frontMatter: {},
60
- frontMatterStrippedContent: fileContent,
61
- frontMatterLineCount: 0,
62
- };
63
- };
64
- exports.separateAndExtractFrontMatter = separateAndExtractFrontMatter;
65
- //# sourceMappingURL=extract.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/transform/frontmatter/extract.ts"],"names":[],"mappings":";;;AAAA,qCAA4C;AAE5C,gCAA2B;AAE3B,qCAMkB;AAClB,uDAA6D;AAQ7D,MAAM,aAAa,GAAG,CAAC,WAAmB,EAAE,EAAE;IAC1C,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,yBAAgB,CAAC,EAAE;QAC3C,OAAO,IAAI,CAAC;KACf;IAED,oBAAoB;IACpB,MAAM;IACN,wBAAwB;IACxB,yBAAyB;IACzB,oBAAoB;IACpB,MAAM;IACN,MAAM,cAAc,GAAG,gDAAgD,CAAC;IACxE,oBAAoB;IACpB,MAAM;IACN,mBAAmB;IACnB,MAAM,iBAAiB,GAAG,4BAA4B,CAAC;IAEvD,MAAM,sBAAsB,GAAG,IAAI,MAAM,CAAC,GAAG,cAAc,GAAG,iBAAiB,EAAE,EAAE,IAAI,CAAC,CAAC;IAEzF,OAAO,sBAAsB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AACpD,CAAC,CAAC;AAEF,MAAM,2BAA2B,GAAG,CAAC,IAAY,EAAE,QAA4B,EAAE,EAAE;IAC/E,IAAI;QACA,OAAO,IAAA,cAAI,EAAC,IAAI,CAAC,CAAC;KACrB;IAAC,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,YAAY,uBAAa,EAAE;YAC5B,MAAM,+BAA+B,GAAG;qBAC/B,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,WAAW,yEAAyE,CAAC,CAAC,MAAM;;;;;aAKhH;iBACI,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;iBACrB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;iBACnB,IAAI,EAAE,CAAC;YAEZ,SAAG,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;YAE1C,OAAO,IAAA,cAAI,EAAC,IAAI,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC;SACnC;QAED,MAAM,CAAC,CAAC;KACX;AACL,CAAC,CAAC;AAEK,MAAM,6BAA6B,GAAG,CACzC,WAAmB,EACnB,QAAiB,EACU,EAAE;IAC7B,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAE3C,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;QAC/B,MAAM,CAAC,EAAE,QAAQ,EAAE,AAAD,EAAG,uBAAuB,CAAC,GAAG,OAAO,CAAC;QAExD,OAAO;YACH,WAAW,EAAE,IAAA,4CAA0B,EACnC,2BAA2B,CACvB,IAAA,uCAA8B,EAAC,QAAQ,CAAC,EACxC,QAAQ,CACI,EAChB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAA,yCAAgC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAC3E;YACD,0BAA0B,EAAE,uBAAuB;YACnD,oBAAoB,EAAE,IAAA,wBAAe,EAAC,QAAQ,CAAC;SAClD,CAAC;KACL;IAED,OAAO;QACH,WAAW,EAAE,EAAE;QACf,0BAA0B,EAAE,WAAW;QACvC,oBAAoB,EAAE,CAAC;KAC1B,CAAC;AACN,CAAC,CAAC;AA3BW,QAAA,6BAA6B,iCA2BxC"}
@@ -1,4 +0,0 @@
1
- export * from './extract';
2
- export * from './emplace';
3
- export * from './transformValues';
4
- export { countLineAmount } from './common';
@@ -1,23 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.countLineAmount = void 0;
18
- __exportStar(require("./extract"), exports);
19
- __exportStar(require("./emplace"), exports);
20
- __exportStar(require("./transformValues"), exports);
21
- var common_1 = require("./common");
22
- Object.defineProperty(exports, "countLineAmount", { enumerable: true, get: function () { return common_1.countLineAmount; } });
23
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/transform/frontmatter/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,4CAA0B;AAC1B,4CAA0B;AAC1B,oDAAkC;AAClC,mCAAyC;AAAjC,yGAAA,eAAe,OAAA"}
@@ -1,2 +0,0 @@
1
- import { FrontMatter } from './common';
2
- export declare const transformFrontMatterValues: (frontMatter: FrontMatter, valueMapper: (v: unknown) => unknown) => FrontMatter;
@@ -1,20 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformFrontMatterValues = void 0;
4
- const transformFrontMatterValues = (frontMatter, valueMapper) => {
5
- const transformInner = (something) => {
6
- if (Array.isArray(something)) {
7
- return something.map((el) => transformInner(el));
8
- }
9
- if (typeof something === 'object' && something !== null) {
10
- return Object.fromEntries(Object.entries(something).map(([k, v]) => [k, transformInner(v)]));
11
- }
12
- if (typeof something === 'function') {
13
- return something;
14
- }
15
- return valueMapper(something);
16
- };
17
- return transformInner(frontMatter);
18
- };
19
- exports.transformFrontMatterValues = transformFrontMatterValues;
20
- //# sourceMappingURL=transformValues.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transformValues.js","sourceRoot":"","sources":["../../src/transform/frontmatter/transformValues.ts"],"names":[],"mappings":";;;AAEO,MAAM,0BAA0B,GAAG,CACtC,WAAwB,EACxB,WAAoC,EACzB,EAAE;IACb,MAAM,cAAc,GAAG,CAAC,SAAkB,EAAW,EAAE;QACnD,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;YAC1B,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC;SACpD;QAED,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,IAAI,EAAE;YACrD,OAAO,MAAM,CAAC,WAAW,CACrB,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CACpE,CAAC;SACL;QAED,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE;YACjC,OAAO,SAAS,CAAC;SACpB;QAED,OAAO,WAAW,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC,CAAC;IAEF,OAAO,cAAc,CAAC,WAAW,CAAgB,CAAC;AACtD,CAAC,CAAC;AAvBW,QAAA,0BAA0B,8BAuBrC"}
@@ -1,27 +0,0 @@
1
- export type FrontMatter = {
2
- [key: string]: unknown;
3
- metadata?: Record<string, unknown>[];
4
- };
5
-
6
- export const frontMatterFence = '---';
7
-
8
- /**
9
- * Temporary workaround to enable parsing YAML metadata from potentially
10
- * Liquid-aware source files
11
- * @param content Input string which could contain Liquid-style substitution syntax (which clashes with YAML
12
- * object syntax)
13
- * @returns String with `{}` escaped, ready to be parsed with `js-yaml`
14
- */
15
- export const escapeLiquidSubstitutionSyntax = (content: string): string =>
16
- content.replace(/{{/g, '(({{').replace(/}}/g, '}}))');
17
-
18
- /**
19
- * Inverse of a workaround defined above.
20
- * @see `escapeLiquidSubstitutionSyntax`
21
- * @param escapedContent Input string with `{}` escaped with backslashes
22
- * @returns Unescaped string
23
- */
24
- export const unescapeLiquidSubstitutionSyntax = (escapedContent: string): string =>
25
- escapedContent.replace(/\(\({{/g, '{{').replace(/}}\)\)/g, '}}');
26
-
27
- export const countLineAmount = (str: string) => str.split(/\r?\n/).length;
@@ -1,24 +0,0 @@
1
- import {dump} from 'js-yaml';
2
-
3
- import {FrontMatter, frontMatterFence} from './common';
4
-
5
- export const serializeFrontMatter = (frontMatter: FrontMatter) => {
6
- const dumped = dump(frontMatter, {lineWidth: -1}).trim();
7
-
8
- // This empty object check is a bit naive
9
- // The other option would be to check if all own fields are `undefined`,
10
- // since we exploit passing in `undefined` to remove a field quite a bit
11
- if (dumped === '{}') {
12
- return '';
13
- }
14
-
15
- return `${frontMatterFence}\n${dumped}\n${frontMatterFence}\n`;
16
- };
17
-
18
- export const emplaceSerializedFrontMatter = (
19
- frontMatterStrippedContent: string,
20
- frontMatter: string,
21
- ) => `${frontMatter}${frontMatterStrippedContent}`;
22
-
23
- export const emplaceFrontMatter = (frontMatterStrippedContent: string, frontMatter: FrontMatter) =>
24
- emplaceSerializedFrontMatter(frontMatterStrippedContent, serializeFrontMatter(frontMatter));
@@ -1,94 +0,0 @@
1
- import {YAMLException, load} from 'js-yaml';
2
-
3
- import {log} from '../log';
4
-
5
- import {
6
- FrontMatter,
7
- countLineAmount,
8
- escapeLiquidSubstitutionSyntax,
9
- frontMatterFence,
10
- unescapeLiquidSubstitutionSyntax,
11
- } from './common';
12
- import {transformFrontMatterValues} from './transformValues';
13
-
14
- type ParseExistingMetadataReturn = {
15
- frontMatter: FrontMatter;
16
- frontMatterStrippedContent: string;
17
- frontMatterLineCount: number;
18
- };
19
-
20
- const matchMetadata = (fileContent: string) => {
21
- if (!fileContent.startsWith(frontMatterFence)) {
22
- return null;
23
- }
24
-
25
- // Search by format:
26
- // ---
27
- // metaName1: metaValue1
28
- // metaName2: meta value2
29
- // incorrectMetadata
30
- // ---
31
- const regexpMetadata = '(?<=-{3}\\r?\\n)((.*\\r?\\n)*?)(?=-{3}\\r?\\n)';
32
- // Search by format:
33
- // ---
34
- // main content 123
35
- const regexpFileContent = '-{3}\\r?\\n((.*[\r?\n]*)*)';
36
-
37
- const regexpParseFileContent = new RegExp(`${regexpMetadata}${regexpFileContent}`, 'gm');
38
-
39
- return regexpParseFileContent.exec(fileContent);
40
- };
41
-
42
- const duplicateKeysCompatibleLoad = (yaml: string, filePath: string | undefined) => {
43
- try {
44
- return load(yaml);
45
- } catch (e) {
46
- if (e instanceof YAMLException) {
47
- const duplicateKeysDeprecationWarning = `
48
- In ${filePath ?? '(unknown)'}: Encountered a YAML parsing exception when processing file metadata: ${e.reason}.
49
- It's highly possible the input file contains duplicate mapping keys.
50
- Will retry processing with necessary compatibility flags.
51
- Please note that this behaviour is DEPRECATED and WILL be removed in a future version
52
- without further notice, so the build WILL fail when supplied with YAML-incompatible meta.
53
- `
54
- .replace(/^\s+/gm, '')
55
- .replace(/\n/g, ' ')
56
- .trim();
57
-
58
- log.warn(duplicateKeysDeprecationWarning);
59
-
60
- return load(yaml, {json: true});
61
- }
62
-
63
- throw e;
64
- }
65
- };
66
-
67
- export const separateAndExtractFrontMatter = (
68
- fileContent: string,
69
- filePath?: string,
70
- ): ParseExistingMetadataReturn => {
71
- const matches = matchMetadata(fileContent);
72
-
73
- if (matches && matches.length > 0) {
74
- const [, metadata, , metadataStrippedContent] = matches;
75
-
76
- return {
77
- frontMatter: transformFrontMatterValues(
78
- duplicateKeysCompatibleLoad(
79
- escapeLiquidSubstitutionSyntax(metadata),
80
- filePath,
81
- ) as FrontMatter,
82
- (v) => (typeof v === 'string' ? unescapeLiquidSubstitutionSyntax(v) : v),
83
- ),
84
- frontMatterStrippedContent: metadataStrippedContent,
85
- frontMatterLineCount: countLineAmount(metadata),
86
- };
87
- }
88
-
89
- return {
90
- frontMatter: {},
91
- frontMatterStrippedContent: fileContent,
92
- frontMatterLineCount: 0,
93
- };
94
- };
@@ -1,4 +0,0 @@
1
- export * from './extract';
2
- export * from './emplace';
3
- export * from './transformValues';
4
- export {countLineAmount} from './common';
@@ -1,26 +0,0 @@
1
- import {FrontMatter} from './common';
2
-
3
- export const transformFrontMatterValues = (
4
- frontMatter: FrontMatter,
5
- valueMapper: (v: unknown) => unknown,
6
- ): FrontMatter => {
7
- const transformInner = (something: unknown): unknown => {
8
- if (Array.isArray(something)) {
9
- return something.map((el) => transformInner(el));
10
- }
11
-
12
- if (typeof something === 'object' && something !== null) {
13
- return Object.fromEntries(
14
- Object.entries(something).map(([k, v]) => [k, transformInner(v)]),
15
- );
16
- }
17
-
18
- if (typeof something === 'function') {
19
- return something;
20
- }
21
-
22
- return valueMapper(something);
23
- };
24
-
25
- return transformInner(frontMatter) as FrontMatter;
26
- };