docusaurus-plugin-openapi-docs 0.0.0-1092 → 0.0.0-1093
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +26 -32
- package/lib/markdown/utils.d.ts +38 -1
- package/lib/markdown/utils.js +100 -2
- package/package.json +2 -2
- package/src/index.ts +35 -47
- package/src/markdown/utils.ts +153 -3
- package/lib/markdown/externalizeJsonProps.d.ts +0 -31
- package/lib/markdown/externalizeJsonProps.js +0 -149
- package/src/markdown/externalizeJsonProps.ts +0 -201
package/lib/index.js
CHANGED
|
@@ -20,7 +20,7 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
20
20
|
const json5_1 = __importDefault(require("json5"));
|
|
21
21
|
const mustache_1 = require("mustache");
|
|
22
22
|
const markdown_1 = require("./markdown");
|
|
23
|
-
const
|
|
23
|
+
const utils_2 = require("./markdown/utils");
|
|
24
24
|
const openapi_1 = require("./openapi");
|
|
25
25
|
const options_1 = require("./options");
|
|
26
26
|
const sidebars_1 = __importDefault(require("./sidebars"));
|
|
@@ -239,8 +239,17 @@ custom_edit_url: null
|
|
|
239
239
|
if (downloadUrl) {
|
|
240
240
|
item.downloadUrl = downloadUrl;
|
|
241
241
|
}
|
|
242
|
-
|
|
243
|
-
|
|
242
|
+
// Generate markdown, with externalization for API and schema pages
|
|
243
|
+
let externalFiles = [];
|
|
244
|
+
if (options.externalJsonProps &&
|
|
245
|
+
(item.type === "api" || item.type === "schema")) {
|
|
246
|
+
const result = (0, utils_2.runWithExternalization)(item.id, () => pageGeneratorByType[item.type](item));
|
|
247
|
+
item.markdown = result.result;
|
|
248
|
+
externalFiles = result.files;
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
item.markdown = pageGeneratorByType[item.type](item);
|
|
252
|
+
}
|
|
244
253
|
if (isSchemasOnly && item.type !== "schema") {
|
|
245
254
|
return;
|
|
246
255
|
}
|
|
@@ -282,23 +291,15 @@ custom_edit_url: null
|
|
|
282
291
|
if (item.id.length === 0) {
|
|
283
292
|
throw Error("Operation must have summary or operationId defined");
|
|
284
293
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
jsonFilesToWrite = result.jsonFiles;
|
|
292
|
-
// Write JSON files
|
|
293
|
-
for (const jsonFile of jsonFilesToWrite) {
|
|
294
|
-
const jsonPath = `${outputDir}/${jsonFile.filename}`;
|
|
295
|
-
if (!fs_1.default.existsSync(jsonPath)) {
|
|
296
|
-
fs_1.default.writeFileSync(jsonPath, jsonFile.content, "utf8");
|
|
297
|
-
console.log(chalk_1.default.green(`Successfully created "${jsonPath}"`));
|
|
298
|
-
}
|
|
294
|
+
// Write externalized JSON files
|
|
295
|
+
for (const jsonFile of externalFiles) {
|
|
296
|
+
const jsonPath = `${outputDir}/${jsonFile.filename}`;
|
|
297
|
+
if (!fs_1.default.existsSync(jsonPath)) {
|
|
298
|
+
fs_1.default.writeFileSync(jsonPath, jsonFile.content, "utf8");
|
|
299
|
+
console.log(chalk_1.default.green(`Successfully created "${jsonPath}"`));
|
|
299
300
|
}
|
|
300
301
|
}
|
|
301
|
-
fs_1.default.writeFileSync(`${outputDir}/${item.id}.api.mdx`,
|
|
302
|
+
fs_1.default.writeFileSync(`${outputDir}/${item.id}.api.mdx`, view, "utf8");
|
|
302
303
|
console.log(chalk_1.default.green(`Successfully created "${outputDir}/${item.id}.api.mdx"`));
|
|
303
304
|
}
|
|
304
305
|
catch (err) {
|
|
@@ -347,20 +348,13 @@ custom_edit_url: null
|
|
|
347
348
|
throw Error("Schema must have title defined");
|
|
348
349
|
}
|
|
349
350
|
// eslint-disable-next-line testing-library/render-result-naming-convention
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
// Write JSON files in schemas directory
|
|
358
|
-
for (const jsonFile of jsonFilesToWrite) {
|
|
359
|
-
const jsonPath = `${outputDir}/schemas/${jsonFile.filename}`;
|
|
360
|
-
if (!fs_1.default.existsSync(jsonPath)) {
|
|
361
|
-
fs_1.default.writeFileSync(jsonPath, jsonFile.content, "utf8");
|
|
362
|
-
console.log(chalk_1.default.green(`Successfully created "${jsonPath}"`));
|
|
363
|
-
}
|
|
351
|
+
const schemaView = (0, mustache_1.render)(schemaMdTemplate, item);
|
|
352
|
+
// Write externalized JSON files in schemas directory
|
|
353
|
+
for (const jsonFile of externalFiles) {
|
|
354
|
+
const jsonPath = `${outputDir}/schemas/${jsonFile.filename}`;
|
|
355
|
+
if (!fs_1.default.existsSync(jsonPath)) {
|
|
356
|
+
fs_1.default.writeFileSync(jsonPath, jsonFile.content, "utf8");
|
|
357
|
+
console.log(chalk_1.default.green(`Successfully created "${jsonPath}"`));
|
|
364
358
|
}
|
|
365
359
|
}
|
|
366
360
|
fs_1.default.writeFileSync(`${outputDir}/schemas/${item.id}.schema.mdx`, schemaView, "utf8");
|
package/lib/markdown/utils.d.ts
CHANGED
|
@@ -1,6 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents an external JSON file to be written alongside the MDX.
|
|
3
|
+
*/
|
|
4
|
+
export interface ExternalFile {
|
|
5
|
+
/** The filename for the JSON file (relative to outputDir) */
|
|
6
|
+
filename: string;
|
|
7
|
+
/** The JSON content to write */
|
|
8
|
+
content: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Result of running MDX generation with externalization.
|
|
12
|
+
*/
|
|
13
|
+
export interface ExternalizationResult<T> {
|
|
14
|
+
/** The result of the generation function */
|
|
15
|
+
result: T;
|
|
16
|
+
/** External JSON files to write */
|
|
17
|
+
files: ExternalFile[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Runs a function with externalization enabled.
|
|
21
|
+
* Any calls to create() within the function will externalize eligible component props.
|
|
22
|
+
*
|
|
23
|
+
* @param baseFilename - Base filename for the MDX file (without extension)
|
|
24
|
+
* @param fn - Function to run with externalization enabled
|
|
25
|
+
* @returns The function result and any external files that were collected
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* const { result: mdx, files } = runWithExternalization("add-pet", () => {
|
|
29
|
+
* return createApiPageMD(item);
|
|
30
|
+
* });
|
|
31
|
+
*/
|
|
32
|
+
export declare function runWithExternalization<T>(baseFilename: string, fn: () => T): ExternalizationResult<T>;
|
|
1
33
|
/**
|
|
2
34
|
* Children in the plugin does not accept DOM elements, when compared with Children in the theme.
|
|
3
|
-
* It is designed for rendering HTML
|
|
35
|
+
* It is designed for rendering HTML as strings.
|
|
4
36
|
*/
|
|
5
37
|
export type Children = string | undefined | (string | string[] | undefined)[];
|
|
6
38
|
export type Props = Record<string, any> & {
|
|
@@ -9,6 +41,11 @@ export type Props = Record<string, any> & {
|
|
|
9
41
|
export type Options = {
|
|
10
42
|
inline?: boolean;
|
|
11
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* Creates a JSX component string with the given tag, props, and options.
|
|
46
|
+
* When called within runWithExternalization(), props for eligible
|
|
47
|
+
* components are externalized to a single JSON file and spread.
|
|
48
|
+
*/
|
|
12
49
|
export declare function create(tag: string, props: Props, options?: Options): string;
|
|
13
50
|
export declare function guard<T>(value: T | undefined, cb: (value: T) => Children): string;
|
|
14
51
|
export declare function render(children: Children): string;
|
package/lib/markdown/utils.js
CHANGED
|
@@ -7,15 +7,82 @@
|
|
|
7
7
|
* ========================================================================== */
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.codeBlock = exports.curlyBrackets = exports.codeFence = exports.greaterThan = exports.lessThan = void 0;
|
|
10
|
+
exports.runWithExternalization = runWithExternalization;
|
|
10
11
|
exports.create = create;
|
|
11
12
|
exports.guard = guard;
|
|
12
13
|
exports.render = render;
|
|
13
14
|
exports.clean = clean;
|
|
15
|
+
/**
|
|
16
|
+
* Module-level externalization context.
|
|
17
|
+
* Note: AsyncLocalStorage would be cleaner but isn't available in browser bundles.
|
|
18
|
+
*/
|
|
19
|
+
let externalizationContext = null;
|
|
20
|
+
/**
|
|
21
|
+
* Components whose props should be externalized to separate JSON files.
|
|
22
|
+
* These are the components that typically receive large JSON objects.
|
|
23
|
+
*/
|
|
24
|
+
const EXTERNALIZABLE_COMPONENTS = new Set([
|
|
25
|
+
"StatusCodes",
|
|
26
|
+
"ParamsDetails",
|
|
27
|
+
"RequestSchema",
|
|
28
|
+
"Schema",
|
|
29
|
+
"SchemaItem",
|
|
30
|
+
]);
|
|
31
|
+
/**
|
|
32
|
+
* Runs a function with externalization enabled.
|
|
33
|
+
* Any calls to create() within the function will externalize eligible component props.
|
|
34
|
+
*
|
|
35
|
+
* @param baseFilename - Base filename for the MDX file (without extension)
|
|
36
|
+
* @param fn - Function to run with externalization enabled
|
|
37
|
+
* @returns The function result and any external files that were collected
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* const { result: mdx, files } = runWithExternalization("add-pet", () => {
|
|
41
|
+
* return createApiPageMD(item);
|
|
42
|
+
* });
|
|
43
|
+
*/
|
|
44
|
+
function runWithExternalization(baseFilename, fn) {
|
|
45
|
+
// Set up context
|
|
46
|
+
externalizationContext = {
|
|
47
|
+
baseFilename,
|
|
48
|
+
componentCounters: {},
|
|
49
|
+
files: [],
|
|
50
|
+
};
|
|
51
|
+
try {
|
|
52
|
+
const result = fn();
|
|
53
|
+
const files = externalizationContext.files;
|
|
54
|
+
return { result, files };
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
// Always clear context
|
|
58
|
+
externalizationContext = null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Creates a JSX component string with the given tag, props, and options.
|
|
63
|
+
* When called within runWithExternalization(), props for eligible
|
|
64
|
+
* components are externalized to a single JSON file and spread.
|
|
65
|
+
*/
|
|
14
66
|
function create(tag, props, options = {}) {
|
|
15
67
|
const { children, ...rest } = props;
|
|
16
68
|
let propString = "";
|
|
17
|
-
|
|
18
|
-
|
|
69
|
+
// Check if this component's props should be externalized
|
|
70
|
+
if (shouldExternalizeComponent(tag, rest)) {
|
|
71
|
+
const filename = generateExternalFilename(tag);
|
|
72
|
+
const content = JSON.stringify(rest);
|
|
73
|
+
// Add to external files
|
|
74
|
+
externalizationContext.files.push({
|
|
75
|
+
filename,
|
|
76
|
+
content,
|
|
77
|
+
});
|
|
78
|
+
// Use spread syntax with require
|
|
79
|
+
propString = `\n {...require("./${filename}")}`;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// Inline props as usual
|
|
83
|
+
for (const [key, value] of Object.entries(rest)) {
|
|
84
|
+
propString += `\n ${key}={${JSON.stringify(value)}}`;
|
|
85
|
+
}
|
|
19
86
|
}
|
|
20
87
|
let indentedChildren = render(children).replace(/^/gm, " ");
|
|
21
88
|
if (options.inline) {
|
|
@@ -26,6 +93,37 @@ function create(tag, props, options = {}) {
|
|
|
26
93
|
indentedChildren += indentedChildren ? "\n" : "";
|
|
27
94
|
return `<${tag}${propString}>\n${indentedChildren}</${tag}>`;
|
|
28
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Determines if a component's props should be externalized.
|
|
98
|
+
*/
|
|
99
|
+
function shouldExternalizeComponent(tag, props) {
|
|
100
|
+
// No context means externalization is not enabled
|
|
101
|
+
if (!externalizationContext) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
if (!EXTERNALIZABLE_COMPONENTS.has(tag)) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
// Don't externalize if props are empty or only contain undefined/null
|
|
108
|
+
const hasContent = Object.values(props).some((v) => v !== undefined && v !== null);
|
|
109
|
+
if (!hasContent) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Generates a unique filename for an externalized component's props.
|
|
116
|
+
*/
|
|
117
|
+
function generateExternalFilename(componentName) {
|
|
118
|
+
var _a;
|
|
119
|
+
if (!externalizationContext) {
|
|
120
|
+
throw new Error("Externalization context not set");
|
|
121
|
+
}
|
|
122
|
+
const count = ((_a = externalizationContext.componentCounters[componentName]) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
123
|
+
externalizationContext.componentCounters[componentName] = count;
|
|
124
|
+
const suffix = count > 1 ? `.${count}` : "";
|
|
125
|
+
return `${externalizationContext.baseFilename}.${componentName}${suffix}.json`;
|
|
126
|
+
}
|
|
29
127
|
function guard(value, cb) {
|
|
30
128
|
if (!!value || value === 0) {
|
|
31
129
|
const children = cb(value);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docusaurus-plugin-openapi-docs",
|
|
3
3
|
"description": "OpenAPI plugin for Docusaurus.",
|
|
4
|
-
"version": "0.0.0-
|
|
4
|
+
"version": "0.0.0-1093",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"openapi",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"engines": {
|
|
66
66
|
"node": ">=14"
|
|
67
67
|
},
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "25ec109b85febce944f00689f6985a89886280ae"
|
|
69
69
|
}
|
package/src/index.ts
CHANGED
|
@@ -21,10 +21,7 @@ import {
|
|
|
21
21
|
createSchemaPageMD,
|
|
22
22
|
createTagPageMD,
|
|
23
23
|
} from "./markdown";
|
|
24
|
-
import {
|
|
25
|
-
externalizeJsonPropsSimple,
|
|
26
|
-
ExternalizedJsonFile,
|
|
27
|
-
} from "./markdown/externalizeJsonProps";
|
|
24
|
+
import { ExternalFile, runWithExternalization } from "./markdown/utils";
|
|
28
25
|
import { processOpenapiFiles, readOpenapiFiles } from "./openapi";
|
|
29
26
|
import { OptionsSchema } from "./options";
|
|
30
27
|
import generateSidebarSlice from "./sidebars";
|
|
@@ -337,8 +334,21 @@ custom_edit_url: null
|
|
|
337
334
|
if (downloadUrl) {
|
|
338
335
|
item.downloadUrl = downloadUrl;
|
|
339
336
|
}
|
|
340
|
-
|
|
341
|
-
|
|
337
|
+
|
|
338
|
+
// Generate markdown, with externalization for API and schema pages
|
|
339
|
+
let externalFiles: ExternalFile[] = [];
|
|
340
|
+
if (
|
|
341
|
+
options.externalJsonProps &&
|
|
342
|
+
(item.type === "api" || item.type === "schema")
|
|
343
|
+
) {
|
|
344
|
+
const result = runWithExternalization(item.id, () =>
|
|
345
|
+
pageGeneratorByType[item.type](item as any)
|
|
346
|
+
);
|
|
347
|
+
item.markdown = result.result;
|
|
348
|
+
externalFiles = result.files;
|
|
349
|
+
} else {
|
|
350
|
+
item.markdown = pageGeneratorByType[item.type](item as any);
|
|
351
|
+
}
|
|
342
352
|
if (isSchemasOnly && item.type !== "schema") {
|
|
343
353
|
return;
|
|
344
354
|
}
|
|
@@ -388,32 +398,18 @@ custom_edit_url: null
|
|
|
388
398
|
);
|
|
389
399
|
}
|
|
390
400
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
// Write JSON files
|
|
401
|
-
for (const jsonFile of jsonFilesToWrite) {
|
|
402
|
-
const jsonPath = `${outputDir}/${jsonFile.filename}`;
|
|
403
|
-
if (!fs.existsSync(jsonPath)) {
|
|
404
|
-
fs.writeFileSync(jsonPath, jsonFile.content, "utf8");
|
|
405
|
-
console.log(
|
|
406
|
-
chalk.green(`Successfully created "${jsonPath}"`)
|
|
407
|
-
);
|
|
408
|
-
}
|
|
401
|
+
// Write externalized JSON files
|
|
402
|
+
for (const jsonFile of externalFiles) {
|
|
403
|
+
const jsonPath = `${outputDir}/${jsonFile.filename}`;
|
|
404
|
+
if (!fs.existsSync(jsonPath)) {
|
|
405
|
+
fs.writeFileSync(jsonPath, jsonFile.content, "utf8");
|
|
406
|
+
console.log(
|
|
407
|
+
chalk.green(`Successfully created "${jsonPath}"`)
|
|
408
|
+
);
|
|
409
409
|
}
|
|
410
410
|
}
|
|
411
411
|
|
|
412
|
-
fs.writeFileSync(
|
|
413
|
-
`${outputDir}/${item.id}.api.mdx`,
|
|
414
|
-
finalView,
|
|
415
|
-
"utf8"
|
|
416
|
-
);
|
|
412
|
+
fs.writeFileSync(`${outputDir}/${item.id}.api.mdx`, view, "utf8");
|
|
417
413
|
console.log(
|
|
418
414
|
chalk.green(
|
|
419
415
|
`Successfully created "${outputDir}/${item.id}.api.mdx"`
|
|
@@ -499,24 +495,16 @@ custom_edit_url: null
|
|
|
499
495
|
throw Error("Schema must have title defined");
|
|
500
496
|
}
|
|
501
497
|
// eslint-disable-next-line testing-library/render-result-naming-convention
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
for (const jsonFile of jsonFilesToWrite) {
|
|
513
|
-
const jsonPath = `${outputDir}/schemas/${jsonFile.filename}`;
|
|
514
|
-
if (!fs.existsSync(jsonPath)) {
|
|
515
|
-
fs.writeFileSync(jsonPath, jsonFile.content, "utf8");
|
|
516
|
-
console.log(
|
|
517
|
-
chalk.green(`Successfully created "${jsonPath}"`)
|
|
518
|
-
);
|
|
519
|
-
}
|
|
498
|
+
const schemaView = render(schemaMdTemplate, item);
|
|
499
|
+
|
|
500
|
+
// Write externalized JSON files in schemas directory
|
|
501
|
+
for (const jsonFile of externalFiles) {
|
|
502
|
+
const jsonPath = `${outputDir}/schemas/${jsonFile.filename}`;
|
|
503
|
+
if (!fs.existsSync(jsonPath)) {
|
|
504
|
+
fs.writeFileSync(jsonPath, jsonFile.content, "utf8");
|
|
505
|
+
console.log(
|
|
506
|
+
chalk.green(`Successfully created "${jsonPath}"`)
|
|
507
|
+
);
|
|
520
508
|
}
|
|
521
509
|
}
|
|
522
510
|
|
package/src/markdown/utils.ts
CHANGED
|
@@ -5,9 +5,93 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
* ========================================================================== */
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Represents an external JSON file to be written alongside the MDX.
|
|
10
|
+
*/
|
|
11
|
+
export interface ExternalFile {
|
|
12
|
+
/** The filename for the JSON file (relative to outputDir) */
|
|
13
|
+
filename: string;
|
|
14
|
+
/** The JSON content to write */
|
|
15
|
+
content: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Result of running MDX generation with externalization.
|
|
20
|
+
*/
|
|
21
|
+
export interface ExternalizationResult<T> {
|
|
22
|
+
/** The result of the generation function */
|
|
23
|
+
result: T;
|
|
24
|
+
/** External JSON files to write */
|
|
25
|
+
files: ExternalFile[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Context for externalization during MDX generation.
|
|
30
|
+
*/
|
|
31
|
+
interface ExternalizationContext {
|
|
32
|
+
/** Base filename for external files (e.g., "add-pet" for "add-pet.api.mdx") */
|
|
33
|
+
baseFilename: string;
|
|
34
|
+
/** Counter for generating unique filenames per component type */
|
|
35
|
+
componentCounters: Record<string, number>;
|
|
36
|
+
/** Collected external files during generation */
|
|
37
|
+
files: ExternalFile[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Module-level externalization context.
|
|
42
|
+
* Note: AsyncLocalStorage would be cleaner but isn't available in browser bundles.
|
|
43
|
+
*/
|
|
44
|
+
let externalizationContext: ExternalizationContext | null = null;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Components whose props should be externalized to separate JSON files.
|
|
48
|
+
* These are the components that typically receive large JSON objects.
|
|
49
|
+
*/
|
|
50
|
+
const EXTERNALIZABLE_COMPONENTS = new Set([
|
|
51
|
+
"StatusCodes",
|
|
52
|
+
"ParamsDetails",
|
|
53
|
+
"RequestSchema",
|
|
54
|
+
"Schema",
|
|
55
|
+
"SchemaItem",
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Runs a function with externalization enabled.
|
|
60
|
+
* Any calls to create() within the function will externalize eligible component props.
|
|
61
|
+
*
|
|
62
|
+
* @param baseFilename - Base filename for the MDX file (without extension)
|
|
63
|
+
* @param fn - Function to run with externalization enabled
|
|
64
|
+
* @returns The function result and any external files that were collected
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* const { result: mdx, files } = runWithExternalization("add-pet", () => {
|
|
68
|
+
* return createApiPageMD(item);
|
|
69
|
+
* });
|
|
70
|
+
*/
|
|
71
|
+
export function runWithExternalization<T>(
|
|
72
|
+
baseFilename: string,
|
|
73
|
+
fn: () => T
|
|
74
|
+
): ExternalizationResult<T> {
|
|
75
|
+
// Set up context
|
|
76
|
+
externalizationContext = {
|
|
77
|
+
baseFilename,
|
|
78
|
+
componentCounters: {},
|
|
79
|
+
files: [],
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
const result = fn();
|
|
84
|
+
const files = externalizationContext.files;
|
|
85
|
+
return { result, files };
|
|
86
|
+
} finally {
|
|
87
|
+
// Always clear context
|
|
88
|
+
externalizationContext = null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
8
92
|
/**
|
|
9
93
|
* Children in the plugin does not accept DOM elements, when compared with Children in the theme.
|
|
10
|
-
* It is designed for rendering HTML
|
|
94
|
+
* It is designed for rendering HTML as strings.
|
|
11
95
|
*/
|
|
12
96
|
export type Children = string | undefined | (string | string[] | undefined)[];
|
|
13
97
|
|
|
@@ -15,6 +99,11 @@ export type Props = Record<string, any> & { children?: Children };
|
|
|
15
99
|
|
|
16
100
|
export type Options = { inline?: boolean };
|
|
17
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Creates a JSX component string with the given tag, props, and options.
|
|
104
|
+
* When called within runWithExternalization(), props for eligible
|
|
105
|
+
* components are externalized to a single JSON file and spread.
|
|
106
|
+
*/
|
|
18
107
|
export function create(
|
|
19
108
|
tag: string,
|
|
20
109
|
props: Props,
|
|
@@ -23,9 +112,27 @@ export function create(
|
|
|
23
112
|
const { children, ...rest } = props;
|
|
24
113
|
|
|
25
114
|
let propString = "";
|
|
26
|
-
|
|
27
|
-
|
|
115
|
+
|
|
116
|
+
// Check if this component's props should be externalized
|
|
117
|
+
if (shouldExternalizeComponent(tag, rest)) {
|
|
118
|
+
const filename = generateExternalFilename(tag);
|
|
119
|
+
const content = JSON.stringify(rest);
|
|
120
|
+
|
|
121
|
+
// Add to external files
|
|
122
|
+
externalizationContext!.files.push({
|
|
123
|
+
filename,
|
|
124
|
+
content,
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Use spread syntax with require
|
|
128
|
+
propString = `\n {...require("./${filename}")}`;
|
|
129
|
+
} else {
|
|
130
|
+
// Inline props as usual
|
|
131
|
+
for (const [key, value] of Object.entries(rest)) {
|
|
132
|
+
propString += `\n ${key}={${JSON.stringify(value)}}`;
|
|
133
|
+
}
|
|
28
134
|
}
|
|
135
|
+
|
|
29
136
|
let indentedChildren = render(children).replace(/^/gm, " ");
|
|
30
137
|
|
|
31
138
|
if (options.inline) {
|
|
@@ -38,6 +145,49 @@ export function create(
|
|
|
38
145
|
return `<${tag}${propString}>\n${indentedChildren}</${tag}>`;
|
|
39
146
|
}
|
|
40
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Determines if a component's props should be externalized.
|
|
150
|
+
*/
|
|
151
|
+
function shouldExternalizeComponent(
|
|
152
|
+
tag: string,
|
|
153
|
+
props: Record<string, any>
|
|
154
|
+
): boolean {
|
|
155
|
+
// No context means externalization is not enabled
|
|
156
|
+
if (!externalizationContext) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (!EXTERNALIZABLE_COMPONENTS.has(tag)) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Don't externalize if props are empty or only contain undefined/null
|
|
165
|
+
const hasContent = Object.values(props).some(
|
|
166
|
+
(v) => v !== undefined && v !== null
|
|
167
|
+
);
|
|
168
|
+
if (!hasContent) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Generates a unique filename for an externalized component's props.
|
|
177
|
+
*/
|
|
178
|
+
function generateExternalFilename(componentName: string): string {
|
|
179
|
+
if (!externalizationContext) {
|
|
180
|
+
throw new Error("Externalization context not set");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const count =
|
|
184
|
+
(externalizationContext.componentCounters[componentName] ?? 0) + 1;
|
|
185
|
+
externalizationContext.componentCounters[componentName] = count;
|
|
186
|
+
|
|
187
|
+
const suffix = count > 1 ? `.${count}` : "";
|
|
188
|
+
return `${externalizationContext.baseFilename}.${componentName}${suffix}.json`;
|
|
189
|
+
}
|
|
190
|
+
|
|
41
191
|
export function guard<T>(
|
|
42
192
|
value: T | undefined,
|
|
43
193
|
cb: (value: T) => Children
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This module provides utilities for externalizing large JSON props in MDX files.
|
|
3
|
-
*
|
|
4
|
-
* The motivation is to improve MDX compilation performance. When large JSON objects
|
|
5
|
-
* are embedded directly as JSX props, MDX needs to parse them into AST and then
|
|
6
|
-
* serialize them back. By externalizing to JSON files and using require(), the
|
|
7
|
-
* MDX compiler can skip this expensive processing.
|
|
8
|
-
*
|
|
9
|
-
* @see https://github.com/facebook/docusaurus/discussions/11664
|
|
10
|
-
*/
|
|
11
|
-
export interface ExternalizedJsonFile {
|
|
12
|
-
/** The filename for the JSON file (without path) */
|
|
13
|
-
filename: string;
|
|
14
|
-
/** The JSON content to write */
|
|
15
|
-
content: string;
|
|
16
|
-
}
|
|
17
|
-
export interface ExternalizeResult {
|
|
18
|
-
/** The transformed MDX content with require() statements */
|
|
19
|
-
mdx: string;
|
|
20
|
-
/** List of JSON files that need to be written */
|
|
21
|
-
jsonFiles: ExternalizedJsonFile[];
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Externalizes large JSON props from MDX content.
|
|
25
|
-
* Uses brace-counting to correctly handle deeply nested JSON.
|
|
26
|
-
*
|
|
27
|
-
* @param mdx - The original MDX content
|
|
28
|
-
* @param baseFilename - The base filename (without extension) for the MDX file
|
|
29
|
-
* @returns The transformed MDX and list of JSON files to write
|
|
30
|
-
*/
|
|
31
|
-
export declare function externalizeJsonPropsSimple(mdx: string, baseFilename: string): ExternalizeResult;
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/* ============================================================================
|
|
3
|
-
* Copyright (c) Palo Alto Networks
|
|
4
|
-
*
|
|
5
|
-
* This source code is licensed under the MIT license found in the
|
|
6
|
-
* LICENSE file in the root directory of this source tree.
|
|
7
|
-
* ========================================================================== */
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.externalizeJsonPropsSimple = externalizeJsonPropsSimple;
|
|
10
|
-
/**
|
|
11
|
-
* Components and their props that should be externalized.
|
|
12
|
-
* These are the components that typically receive large JSON objects.
|
|
13
|
-
*/
|
|
14
|
-
const COMPONENTS_TO_EXTERNALIZE = [
|
|
15
|
-
{ component: "StatusCodes", prop: "responses" },
|
|
16
|
-
{ component: "ParamsDetails", prop: "parameters" },
|
|
17
|
-
{ component: "RequestSchema", prop: "body" },
|
|
18
|
-
{ component: "Schema", prop: "schema" },
|
|
19
|
-
{ component: "SchemaItem", prop: "schema" },
|
|
20
|
-
];
|
|
21
|
-
/**
|
|
22
|
-
* Minimum size (in characters) for a JSON prop to be externalized.
|
|
23
|
-
* Props smaller than this threshold will remain inline.
|
|
24
|
-
*/
|
|
25
|
-
const MIN_SIZE_THRESHOLD = 500;
|
|
26
|
-
/**
|
|
27
|
-
* Extracts the content between balanced braces starting at a given position.
|
|
28
|
-
* Returns the content (without outer braces) and the end position.
|
|
29
|
-
*/
|
|
30
|
-
function extractBalancedBraces(str, startIndex) {
|
|
31
|
-
if (str[startIndex] !== "{") {
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
let depth = 0;
|
|
35
|
-
let inString = false;
|
|
36
|
-
let stringChar = "";
|
|
37
|
-
let escaped = false;
|
|
38
|
-
for (let i = startIndex; i < str.length; i++) {
|
|
39
|
-
const char = str[i];
|
|
40
|
-
if (escaped) {
|
|
41
|
-
escaped = false;
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
if (char === "\\") {
|
|
45
|
-
escaped = true;
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
if (!inString) {
|
|
49
|
-
if (char === '"' || char === "'") {
|
|
50
|
-
inString = true;
|
|
51
|
-
stringChar = char;
|
|
52
|
-
}
|
|
53
|
-
else if (char === "{") {
|
|
54
|
-
depth++;
|
|
55
|
-
}
|
|
56
|
-
else if (char === "}") {
|
|
57
|
-
depth--;
|
|
58
|
-
if (depth === 0) {
|
|
59
|
-
// Found the matching closing brace
|
|
60
|
-
return {
|
|
61
|
-
content: str.substring(startIndex + 1, i),
|
|
62
|
-
endIndex: i,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
if (char === stringChar) {
|
|
69
|
-
inString = false;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
return null; // Unbalanced braces
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Externalizes large JSON props from MDX content.
|
|
77
|
-
* Uses brace-counting to correctly handle deeply nested JSON.
|
|
78
|
-
*
|
|
79
|
-
* @param mdx - The original MDX content
|
|
80
|
-
* @param baseFilename - The base filename (without extension) for the MDX file
|
|
81
|
-
* @returns The transformed MDX and list of JSON files to write
|
|
82
|
-
*/
|
|
83
|
-
function externalizeJsonPropsSimple(mdx, baseFilename) {
|
|
84
|
-
const jsonFiles = [];
|
|
85
|
-
let transformedMdx = mdx;
|
|
86
|
-
for (const { component, prop } of COMPONENTS_TO_EXTERNALIZE) {
|
|
87
|
-
// Find pattern: prop={
|
|
88
|
-
const propPattern = new RegExp(`${prop}=\\{`, "g");
|
|
89
|
-
let match;
|
|
90
|
-
// Keep searching until no more matches (need to restart after each replacement)
|
|
91
|
-
let searchStart = 0;
|
|
92
|
-
while (true) {
|
|
93
|
-
propPattern.lastIndex = searchStart;
|
|
94
|
-
match = propPattern.exec(transformedMdx);
|
|
95
|
-
if (!match)
|
|
96
|
-
break;
|
|
97
|
-
const propStart = match.index;
|
|
98
|
-
const braceStart = propStart + prop.length + 1; // Position of '{'
|
|
99
|
-
// Extract the balanced content
|
|
100
|
-
const extracted = extractBalancedBraces(transformedMdx, braceStart);
|
|
101
|
-
if (!extracted) {
|
|
102
|
-
searchStart = braceStart + 1;
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
const jsonContent = extracted.content;
|
|
106
|
-
const propEnd = extracted.endIndex + 1; // Position after '}'
|
|
107
|
-
// Skip small or non-JSON content
|
|
108
|
-
const trimmed = jsonContent.trim();
|
|
109
|
-
if (jsonContent.length < MIN_SIZE_THRESHOLD ||
|
|
110
|
-
trimmed === "undefined" ||
|
|
111
|
-
trimmed === "null" ||
|
|
112
|
-
trimmed === "true" ||
|
|
113
|
-
trimmed === "false" ||
|
|
114
|
-
trimmed.startsWith("require(")) {
|
|
115
|
-
searchStart = propEnd;
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
// Check if this is within the target component
|
|
119
|
-
// Look backwards for the component tag
|
|
120
|
-
const beforeProp = transformedMdx.substring(0, propStart);
|
|
121
|
-
const componentTagPattern = new RegExp(`<${component}[\\s\\S]*$`);
|
|
122
|
-
if (!componentTagPattern.test(beforeProp)) {
|
|
123
|
-
searchStart = propEnd;
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
// Generate filename
|
|
127
|
-
const existingCount = jsonFiles.filter((f) => f.filename.includes(`.${prop}`)).length;
|
|
128
|
-
const suffix = existingCount > 0 ? `.${existingCount + 1}` : "";
|
|
129
|
-
const jsonFilename = `${baseFilename}.${prop}${suffix}.json`;
|
|
130
|
-
// Store the JSON file
|
|
131
|
-
jsonFiles.push({
|
|
132
|
-
filename: jsonFilename,
|
|
133
|
-
content: jsonContent.trim(),
|
|
134
|
-
});
|
|
135
|
-
// Replace the prop value with require()
|
|
136
|
-
const newProp = `${prop}={require("./${jsonFilename}")}`;
|
|
137
|
-
transformedMdx =
|
|
138
|
-
transformedMdx.substring(0, propStart) +
|
|
139
|
-
newProp +
|
|
140
|
-
transformedMdx.substring(propEnd);
|
|
141
|
-
// Continue searching after the replacement
|
|
142
|
-
searchStart = propStart + newProp.length;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
return {
|
|
146
|
-
mdx: transformedMdx,
|
|
147
|
-
jsonFiles,
|
|
148
|
-
};
|
|
149
|
-
}
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
/* ============================================================================
|
|
2
|
-
* Copyright (c) Palo Alto Networks
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
* ========================================================================== */
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* This module provides utilities for externalizing large JSON props in MDX files.
|
|
10
|
-
*
|
|
11
|
-
* The motivation is to improve MDX compilation performance. When large JSON objects
|
|
12
|
-
* are embedded directly as JSX props, MDX needs to parse them into AST and then
|
|
13
|
-
* serialize them back. By externalizing to JSON files and using require(), the
|
|
14
|
-
* MDX compiler can skip this expensive processing.
|
|
15
|
-
*
|
|
16
|
-
* @see https://github.com/facebook/docusaurus/discussions/11664
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
export interface ExternalizedJsonFile {
|
|
20
|
-
/** The filename for the JSON file (without path) */
|
|
21
|
-
filename: string;
|
|
22
|
-
/** The JSON content to write */
|
|
23
|
-
content: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface ExternalizeResult {
|
|
27
|
-
/** The transformed MDX content with require() statements */
|
|
28
|
-
mdx: string;
|
|
29
|
-
/** List of JSON files that need to be written */
|
|
30
|
-
jsonFiles: ExternalizedJsonFile[];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Components and their props that should be externalized.
|
|
35
|
-
* These are the components that typically receive large JSON objects.
|
|
36
|
-
*/
|
|
37
|
-
const COMPONENTS_TO_EXTERNALIZE = [
|
|
38
|
-
{ component: "StatusCodes", prop: "responses" },
|
|
39
|
-
{ component: "ParamsDetails", prop: "parameters" },
|
|
40
|
-
{ component: "RequestSchema", prop: "body" },
|
|
41
|
-
{ component: "Schema", prop: "schema" },
|
|
42
|
-
{ component: "SchemaItem", prop: "schema" },
|
|
43
|
-
];
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Minimum size (in characters) for a JSON prop to be externalized.
|
|
47
|
-
* Props smaller than this threshold will remain inline.
|
|
48
|
-
*/
|
|
49
|
-
const MIN_SIZE_THRESHOLD = 500;
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Extracts the content between balanced braces starting at a given position.
|
|
53
|
-
* Returns the content (without outer braces) and the end position.
|
|
54
|
-
*/
|
|
55
|
-
function extractBalancedBraces(
|
|
56
|
-
str: string,
|
|
57
|
-
startIndex: number
|
|
58
|
-
): { content: string; endIndex: number } | null {
|
|
59
|
-
if (str[startIndex] !== "{") {
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
let depth = 0;
|
|
64
|
-
let inString = false;
|
|
65
|
-
let stringChar = "";
|
|
66
|
-
let escaped = false;
|
|
67
|
-
|
|
68
|
-
for (let i = startIndex; i < str.length; i++) {
|
|
69
|
-
const char = str[i];
|
|
70
|
-
|
|
71
|
-
if (escaped) {
|
|
72
|
-
escaped = false;
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (char === "\\") {
|
|
77
|
-
escaped = true;
|
|
78
|
-
continue;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (!inString) {
|
|
82
|
-
if (char === '"' || char === "'") {
|
|
83
|
-
inString = true;
|
|
84
|
-
stringChar = char;
|
|
85
|
-
} else if (char === "{") {
|
|
86
|
-
depth++;
|
|
87
|
-
} else if (char === "}") {
|
|
88
|
-
depth--;
|
|
89
|
-
if (depth === 0) {
|
|
90
|
-
// Found the matching closing brace
|
|
91
|
-
return {
|
|
92
|
-
content: str.substring(startIndex + 1, i),
|
|
93
|
-
endIndex: i,
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
} else {
|
|
98
|
-
if (char === stringChar) {
|
|
99
|
-
inString = false;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return null; // Unbalanced braces
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Externalizes large JSON props from MDX content.
|
|
109
|
-
* Uses brace-counting to correctly handle deeply nested JSON.
|
|
110
|
-
*
|
|
111
|
-
* @param mdx - The original MDX content
|
|
112
|
-
* @param baseFilename - The base filename (without extension) for the MDX file
|
|
113
|
-
* @returns The transformed MDX and list of JSON files to write
|
|
114
|
-
*/
|
|
115
|
-
export function externalizeJsonPropsSimple(
|
|
116
|
-
mdx: string,
|
|
117
|
-
baseFilename: string
|
|
118
|
-
): ExternalizeResult {
|
|
119
|
-
const jsonFiles: ExternalizedJsonFile[] = [];
|
|
120
|
-
let transformedMdx = mdx;
|
|
121
|
-
|
|
122
|
-
for (const { component, prop } of COMPONENTS_TO_EXTERNALIZE) {
|
|
123
|
-
// Find pattern: prop={
|
|
124
|
-
const propPattern = new RegExp(`${prop}=\\{`, "g");
|
|
125
|
-
let match;
|
|
126
|
-
|
|
127
|
-
// Keep searching until no more matches (need to restart after each replacement)
|
|
128
|
-
let searchStart = 0;
|
|
129
|
-
while (true) {
|
|
130
|
-
propPattern.lastIndex = searchStart;
|
|
131
|
-
match = propPattern.exec(transformedMdx);
|
|
132
|
-
|
|
133
|
-
if (!match) break;
|
|
134
|
-
|
|
135
|
-
const propStart = match.index;
|
|
136
|
-
const braceStart = propStart + prop.length + 1; // Position of '{'
|
|
137
|
-
|
|
138
|
-
// Extract the balanced content
|
|
139
|
-
const extracted = extractBalancedBraces(transformedMdx, braceStart);
|
|
140
|
-
if (!extracted) {
|
|
141
|
-
searchStart = braceStart + 1;
|
|
142
|
-
continue;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const jsonContent = extracted.content;
|
|
146
|
-
const propEnd = extracted.endIndex + 1; // Position after '}'
|
|
147
|
-
|
|
148
|
-
// Skip small or non-JSON content
|
|
149
|
-
const trimmed = jsonContent.trim();
|
|
150
|
-
if (
|
|
151
|
-
jsonContent.length < MIN_SIZE_THRESHOLD ||
|
|
152
|
-
trimmed === "undefined" ||
|
|
153
|
-
trimmed === "null" ||
|
|
154
|
-
trimmed === "true" ||
|
|
155
|
-
trimmed === "false" ||
|
|
156
|
-
trimmed.startsWith("require(")
|
|
157
|
-
) {
|
|
158
|
-
searchStart = propEnd;
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Check if this is within the target component
|
|
163
|
-
// Look backwards for the component tag
|
|
164
|
-
const beforeProp = transformedMdx.substring(0, propStart);
|
|
165
|
-
const componentTagPattern = new RegExp(`<${component}[\\s\\S]*$`);
|
|
166
|
-
if (!componentTagPattern.test(beforeProp)) {
|
|
167
|
-
searchStart = propEnd;
|
|
168
|
-
continue;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Generate filename
|
|
172
|
-
const existingCount = jsonFiles.filter((f) =>
|
|
173
|
-
f.filename.includes(`.${prop}`)
|
|
174
|
-
).length;
|
|
175
|
-
const suffix = existingCount > 0 ? `.${existingCount + 1}` : "";
|
|
176
|
-
const jsonFilename = `${baseFilename}.${prop}${suffix}.json`;
|
|
177
|
-
|
|
178
|
-
// Store the JSON file
|
|
179
|
-
jsonFiles.push({
|
|
180
|
-
filename: jsonFilename,
|
|
181
|
-
content: jsonContent.trim(),
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
// Replace the prop value with require()
|
|
185
|
-
const newProp = `${prop}={require("./${jsonFilename}")}`;
|
|
186
|
-
|
|
187
|
-
transformedMdx =
|
|
188
|
-
transformedMdx.substring(0, propStart) +
|
|
189
|
-
newProp +
|
|
190
|
-
transformedMdx.substring(propEnd);
|
|
191
|
-
|
|
192
|
-
// Continue searching after the replacement
|
|
193
|
-
searchStart = propStart + newProp.length;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return {
|
|
198
|
-
mdx: transformedMdx,
|
|
199
|
-
jsonFiles,
|
|
200
|
-
};
|
|
201
|
-
}
|