@opensyntaxhq/autodocs-plugin-examples 1.0.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.
- package/dist/index.d.mts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +254 -0
- package/dist/index.mjs +219 -0
- package/package.json +55 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Plugin } from '@opensyntaxhq/autodocs-core';
|
|
2
|
+
|
|
3
|
+
interface ExamplesPluginOptions {
|
|
4
|
+
validate?: boolean;
|
|
5
|
+
outputDir?: string;
|
|
6
|
+
}
|
|
7
|
+
declare function examplesPlugin(options?: ExamplesPluginOptions): Plugin;
|
|
8
|
+
|
|
9
|
+
export { type ExamplesPluginOptions, examplesPlugin as default, examplesPlugin };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Plugin } from '@opensyntaxhq/autodocs-core';
|
|
2
|
+
|
|
3
|
+
interface ExamplesPluginOptions {
|
|
4
|
+
validate?: boolean;
|
|
5
|
+
outputDir?: string;
|
|
6
|
+
}
|
|
7
|
+
declare function examplesPlugin(options?: ExamplesPluginOptions): Plugin;
|
|
8
|
+
|
|
9
|
+
export { type ExamplesPluginOptions, examplesPlugin as default, examplesPlugin };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
default: () => examplesPlugin,
|
|
34
|
+
examplesPlugin: () => examplesPlugin
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(index_exports);
|
|
37
|
+
var import_promises6 = __toESM(require("fs/promises"));
|
|
38
|
+
var import_os = __toESM(require("os"));
|
|
39
|
+
var import_path10 = __toESM(require("path"));
|
|
40
|
+
var import_typescript7 = __toESM(require("typescript"));
|
|
41
|
+
|
|
42
|
+
// ../../core/src/parser/index.ts
|
|
43
|
+
var import_typescript = __toESM(require("typescript"));
|
|
44
|
+
var import_path = __toESM(require("path"));
|
|
45
|
+
var import_fs = __toESM(require("fs"));
|
|
46
|
+
|
|
47
|
+
// ../../core/src/extractor/index.ts
|
|
48
|
+
var import_typescript5 = __toESM(require("typescript"));
|
|
49
|
+
var import_path3 = __toESM(require("path"));
|
|
50
|
+
|
|
51
|
+
// ../../core/src/parser/utils.ts
|
|
52
|
+
var import_typescript2 = __toESM(require("typescript"));
|
|
53
|
+
|
|
54
|
+
// ../../core/src/extractor/serializers.ts
|
|
55
|
+
var import_typescript4 = __toESM(require("typescript"));
|
|
56
|
+
var import_crypto = __toESM(require("crypto"));
|
|
57
|
+
var import_path2 = __toESM(require("path"));
|
|
58
|
+
|
|
59
|
+
// ../../core/src/extractor/utils.ts
|
|
60
|
+
var import_typescript3 = __toESM(require("typescript"));
|
|
61
|
+
|
|
62
|
+
// ../../core/src/generators/json/index.ts
|
|
63
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
64
|
+
var import_path4 = __toESM(require("path"));
|
|
65
|
+
|
|
66
|
+
// ../../core/src/version.ts
|
|
67
|
+
var VERSION = "1.0.0";
|
|
68
|
+
|
|
69
|
+
// ../../core/src/generators/markdown/index.ts
|
|
70
|
+
var import_promises2 = __toESM(require("fs/promises"));
|
|
71
|
+
var import_path5 = __toESM(require("path"));
|
|
72
|
+
|
|
73
|
+
// ../../core/src/generators/html/index.ts
|
|
74
|
+
var import_promises3 = __toESM(require("fs/promises"));
|
|
75
|
+
var import_path6 = __toESM(require("path"));
|
|
76
|
+
|
|
77
|
+
// ../../core/src/cache/FileCache.ts
|
|
78
|
+
var import_promises4 = __toESM(require("fs/promises"));
|
|
79
|
+
var import_path7 = __toESM(require("path"));
|
|
80
|
+
var import_crypto2 = __toESM(require("crypto"));
|
|
81
|
+
|
|
82
|
+
// ../../core/src/cache/incremental.ts
|
|
83
|
+
var import_typescript6 = __toESM(require("typescript"));
|
|
84
|
+
var import_path8 = __toESM(require("path"));
|
|
85
|
+
var import_fs2 = __toESM(require("fs"));
|
|
86
|
+
|
|
87
|
+
// ../../core/src/deploy/static.ts
|
|
88
|
+
var import_promises5 = __toESM(require("fs/promises"));
|
|
89
|
+
var import_path9 = __toESM(require("path"));
|
|
90
|
+
|
|
91
|
+
// src/index.ts
|
|
92
|
+
function examplesPlugin(options = {}) {
|
|
93
|
+
const records = [];
|
|
94
|
+
return {
|
|
95
|
+
name: "@opensyntaxhq/autodocs-plugin-examples",
|
|
96
|
+
version: VERSION,
|
|
97
|
+
async afterExtract(docs) {
|
|
98
|
+
for (const entry of docs) {
|
|
99
|
+
const examples = entry.documentation?.examples;
|
|
100
|
+
if (!examples || examples.length === 0) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
for (const [index, example] of examples.entries()) {
|
|
104
|
+
if (options.validate) {
|
|
105
|
+
await validateExample(example, entry);
|
|
106
|
+
}
|
|
107
|
+
records.push({
|
|
108
|
+
entryId: entry.id,
|
|
109
|
+
entryName: entry.name,
|
|
110
|
+
index,
|
|
111
|
+
language: example.language,
|
|
112
|
+
code: example.code
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return docs;
|
|
117
|
+
},
|
|
118
|
+
async afterGenerate(outputDir) {
|
|
119
|
+
if (!options.outputDir || records.length === 0) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const examplesDir = import_path10.default.isAbsolute(options.outputDir) ? options.outputDir : import_path10.default.join(outputDir, options.outputDir);
|
|
123
|
+
await import_promises6.default.mkdir(examplesDir, { recursive: true });
|
|
124
|
+
for (const record of records) {
|
|
125
|
+
const exampleNumber = record.index + 1;
|
|
126
|
+
const baseName = `${slugify(record.entryName)}__example-${exampleNumber.toString()}`;
|
|
127
|
+
const extension = languageToExtension(record.language);
|
|
128
|
+
const fileName = `${baseName}.${extension}`;
|
|
129
|
+
const filePath = import_path10.default.join(examplesDir, fileName);
|
|
130
|
+
await import_promises6.default.writeFile(filePath, record.code, "utf-8");
|
|
131
|
+
record.filePath = fileName;
|
|
132
|
+
}
|
|
133
|
+
const indexPayload = records.map((record) => ({
|
|
134
|
+
entryId: record.entryId,
|
|
135
|
+
entryName: record.entryName,
|
|
136
|
+
index: record.index,
|
|
137
|
+
language: record.language,
|
|
138
|
+
file: record.filePath
|
|
139
|
+
}));
|
|
140
|
+
await import_promises6.default.writeFile(
|
|
141
|
+
import_path10.default.join(examplesDir, "examples.json"),
|
|
142
|
+
JSON.stringify(indexPayload, null, 2),
|
|
143
|
+
"utf-8"
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
async function validateExample(example, entry) {
|
|
149
|
+
const tempDir = await import_promises6.default.mkdtemp(import_path10.default.join(import_os.default.tmpdir(), "autodocs-example-"));
|
|
150
|
+
const extension = languageToExtension(example.language);
|
|
151
|
+
const tempFile = import_path10.default.join(tempDir, `example.${extension}`);
|
|
152
|
+
try {
|
|
153
|
+
const normalized = example.code.endsWith("\n") ? example.code : `${example.code}
|
|
154
|
+
`;
|
|
155
|
+
const stub = buildEntryStub(entry, normalized);
|
|
156
|
+
const wrapped = `${stub}${normalized}export {};
|
|
157
|
+
`;
|
|
158
|
+
await import_promises6.default.writeFile(tempFile, wrapped, "utf-8");
|
|
159
|
+
const program = import_typescript7.default.createProgram([tempFile], {
|
|
160
|
+
noEmit: true,
|
|
161
|
+
skipLibCheck: true,
|
|
162
|
+
target: import_typescript7.default.ScriptTarget.ES2022
|
|
163
|
+
});
|
|
164
|
+
const diagnostics = import_typescript7.default.getPreEmitDiagnostics(program);
|
|
165
|
+
if (diagnostics.length > 0) {
|
|
166
|
+
const errors = diagnostics.map((d) => {
|
|
167
|
+
const message = typeof d.messageText === "string" ? d.messageText : d.messageText.messageText;
|
|
168
|
+
return message;
|
|
169
|
+
});
|
|
170
|
+
throw new Error(`TypeScript errors:
|
|
171
|
+
${errors.join("\n")}`);
|
|
172
|
+
}
|
|
173
|
+
} finally {
|
|
174
|
+
try {
|
|
175
|
+
await import_promises6.default.unlink(tempFile);
|
|
176
|
+
await import_promises6.default.rmdir(tempDir);
|
|
177
|
+
} catch {
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function buildEntryStub(entry, code) {
|
|
182
|
+
const name = entry.name;
|
|
183
|
+
if (!isValidIdentifier(name)) {
|
|
184
|
+
return "";
|
|
185
|
+
}
|
|
186
|
+
const escaped = escapeRegExp(name);
|
|
187
|
+
const usagePattern = new RegExp(`\\b${escaped}\\b`);
|
|
188
|
+
if (!usagePattern.test(code)) {
|
|
189
|
+
return "";
|
|
190
|
+
}
|
|
191
|
+
if (hasDeclaration(code, escaped)) {
|
|
192
|
+
return "";
|
|
193
|
+
}
|
|
194
|
+
switch (entry.kind) {
|
|
195
|
+
case "class":
|
|
196
|
+
return `declare class ${name} {}
|
|
197
|
+
`;
|
|
198
|
+
case "enum":
|
|
199
|
+
return `declare enum ${name} {}
|
|
200
|
+
`;
|
|
201
|
+
case "interface":
|
|
202
|
+
return `interface ${name} {}
|
|
203
|
+
`;
|
|
204
|
+
case "type":
|
|
205
|
+
return `type ${name} = any;
|
|
206
|
+
`;
|
|
207
|
+
case "function":
|
|
208
|
+
return `declare function ${name}(...args: any[]): any;
|
|
209
|
+
`;
|
|
210
|
+
case "variable":
|
|
211
|
+
return `declare const ${name}: any;
|
|
212
|
+
`;
|
|
213
|
+
default:
|
|
214
|
+
return `declare const ${name}: any;
|
|
215
|
+
`;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function hasDeclaration(code, escapedName) {
|
|
219
|
+
const patterns = [
|
|
220
|
+
`\\bimport\\s+[^;]*\\b${escapedName}\\b`,
|
|
221
|
+
`\\bimport\\s+\\{[^}]*\\b${escapedName}\\b[^}]*\\}\\s+from`,
|
|
222
|
+
`\\bimport\\s+${escapedName}\\s+from`,
|
|
223
|
+
`\\bfunction\\s+${escapedName}\\b`,
|
|
224
|
+
`\\bclass\\s+${escapedName}\\b`,
|
|
225
|
+
`\\binterface\\s+${escapedName}\\b`,
|
|
226
|
+
`\\btype\\s+${escapedName}\\b`,
|
|
227
|
+
`\\bconst\\s+${escapedName}\\b`,
|
|
228
|
+
`\\blet\\s+${escapedName}\\b`,
|
|
229
|
+
`\\bvar\\s+${escapedName}\\b`,
|
|
230
|
+
`\\benum\\s+${escapedName}\\b`,
|
|
231
|
+
`\\bexport\\s+(?:default\\s+)?(?:function|class|const|let|var|enum|interface|type)\\s+${escapedName}\\b`
|
|
232
|
+
];
|
|
233
|
+
return patterns.some((pattern) => new RegExp(pattern).test(code));
|
|
234
|
+
}
|
|
235
|
+
function isValidIdentifier(name) {
|
|
236
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name);
|
|
237
|
+
}
|
|
238
|
+
function escapeRegExp(value) {
|
|
239
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
240
|
+
}
|
|
241
|
+
function slugify(value) {
|
|
242
|
+
return value.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)+/g, "");
|
|
243
|
+
}
|
|
244
|
+
function languageToExtension(language) {
|
|
245
|
+
const normalized = language.toLowerCase();
|
|
246
|
+
if (normalized === "tsx") return "tsx";
|
|
247
|
+
if (normalized === "javascript" || normalized === "js") return "js";
|
|
248
|
+
if (normalized === "typescript" || normalized === "ts") return "ts";
|
|
249
|
+
return "txt";
|
|
250
|
+
}
|
|
251
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
252
|
+
0 && (module.exports = {
|
|
253
|
+
examplesPlugin
|
|
254
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import fs8 from "fs/promises";
|
|
3
|
+
import os from "os";
|
|
4
|
+
import path10 from "path";
|
|
5
|
+
import ts7 from "typescript";
|
|
6
|
+
|
|
7
|
+
// ../../core/src/parser/index.ts
|
|
8
|
+
import ts from "typescript";
|
|
9
|
+
import path from "path";
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
|
|
12
|
+
// ../../core/src/extractor/index.ts
|
|
13
|
+
import ts5 from "typescript";
|
|
14
|
+
import path3 from "path";
|
|
15
|
+
|
|
16
|
+
// ../../core/src/parser/utils.ts
|
|
17
|
+
import ts2 from "typescript";
|
|
18
|
+
|
|
19
|
+
// ../../core/src/extractor/serializers.ts
|
|
20
|
+
import ts4 from "typescript";
|
|
21
|
+
import crypto from "crypto";
|
|
22
|
+
import path2 from "path";
|
|
23
|
+
|
|
24
|
+
// ../../core/src/extractor/utils.ts
|
|
25
|
+
import ts3 from "typescript";
|
|
26
|
+
|
|
27
|
+
// ../../core/src/generators/json/index.ts
|
|
28
|
+
import fs2 from "fs/promises";
|
|
29
|
+
import path4 from "path";
|
|
30
|
+
|
|
31
|
+
// ../../core/src/version.ts
|
|
32
|
+
var VERSION = "1.0.0";
|
|
33
|
+
|
|
34
|
+
// ../../core/src/generators/markdown/index.ts
|
|
35
|
+
import fs3 from "fs/promises";
|
|
36
|
+
import path5 from "path";
|
|
37
|
+
|
|
38
|
+
// ../../core/src/generators/html/index.ts
|
|
39
|
+
import fs4 from "fs/promises";
|
|
40
|
+
import path6 from "path";
|
|
41
|
+
|
|
42
|
+
// ../../core/src/cache/FileCache.ts
|
|
43
|
+
import fs5 from "fs/promises";
|
|
44
|
+
import path7 from "path";
|
|
45
|
+
import crypto2 from "crypto";
|
|
46
|
+
|
|
47
|
+
// ../../core/src/cache/incremental.ts
|
|
48
|
+
import ts6 from "typescript";
|
|
49
|
+
import path8 from "path";
|
|
50
|
+
import fs6 from "fs";
|
|
51
|
+
|
|
52
|
+
// ../../core/src/deploy/static.ts
|
|
53
|
+
import fs7 from "fs/promises";
|
|
54
|
+
import path9 from "path";
|
|
55
|
+
|
|
56
|
+
// src/index.ts
|
|
57
|
+
function examplesPlugin(options = {}) {
|
|
58
|
+
const records = [];
|
|
59
|
+
return {
|
|
60
|
+
name: "@opensyntaxhq/autodocs-plugin-examples",
|
|
61
|
+
version: VERSION,
|
|
62
|
+
async afterExtract(docs) {
|
|
63
|
+
for (const entry of docs) {
|
|
64
|
+
const examples = entry.documentation?.examples;
|
|
65
|
+
if (!examples || examples.length === 0) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
for (const [index, example] of examples.entries()) {
|
|
69
|
+
if (options.validate) {
|
|
70
|
+
await validateExample(example, entry);
|
|
71
|
+
}
|
|
72
|
+
records.push({
|
|
73
|
+
entryId: entry.id,
|
|
74
|
+
entryName: entry.name,
|
|
75
|
+
index,
|
|
76
|
+
language: example.language,
|
|
77
|
+
code: example.code
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return docs;
|
|
82
|
+
},
|
|
83
|
+
async afterGenerate(outputDir) {
|
|
84
|
+
if (!options.outputDir || records.length === 0) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const examplesDir = path10.isAbsolute(options.outputDir) ? options.outputDir : path10.join(outputDir, options.outputDir);
|
|
88
|
+
await fs8.mkdir(examplesDir, { recursive: true });
|
|
89
|
+
for (const record of records) {
|
|
90
|
+
const exampleNumber = record.index + 1;
|
|
91
|
+
const baseName = `${slugify(record.entryName)}__example-${exampleNumber.toString()}`;
|
|
92
|
+
const extension = languageToExtension(record.language);
|
|
93
|
+
const fileName = `${baseName}.${extension}`;
|
|
94
|
+
const filePath = path10.join(examplesDir, fileName);
|
|
95
|
+
await fs8.writeFile(filePath, record.code, "utf-8");
|
|
96
|
+
record.filePath = fileName;
|
|
97
|
+
}
|
|
98
|
+
const indexPayload = records.map((record) => ({
|
|
99
|
+
entryId: record.entryId,
|
|
100
|
+
entryName: record.entryName,
|
|
101
|
+
index: record.index,
|
|
102
|
+
language: record.language,
|
|
103
|
+
file: record.filePath
|
|
104
|
+
}));
|
|
105
|
+
await fs8.writeFile(
|
|
106
|
+
path10.join(examplesDir, "examples.json"),
|
|
107
|
+
JSON.stringify(indexPayload, null, 2),
|
|
108
|
+
"utf-8"
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
async function validateExample(example, entry) {
|
|
114
|
+
const tempDir = await fs8.mkdtemp(path10.join(os.tmpdir(), "autodocs-example-"));
|
|
115
|
+
const extension = languageToExtension(example.language);
|
|
116
|
+
const tempFile = path10.join(tempDir, `example.${extension}`);
|
|
117
|
+
try {
|
|
118
|
+
const normalized = example.code.endsWith("\n") ? example.code : `${example.code}
|
|
119
|
+
`;
|
|
120
|
+
const stub = buildEntryStub(entry, normalized);
|
|
121
|
+
const wrapped = `${stub}${normalized}export {};
|
|
122
|
+
`;
|
|
123
|
+
await fs8.writeFile(tempFile, wrapped, "utf-8");
|
|
124
|
+
const program = ts7.createProgram([tempFile], {
|
|
125
|
+
noEmit: true,
|
|
126
|
+
skipLibCheck: true,
|
|
127
|
+
target: ts7.ScriptTarget.ES2022
|
|
128
|
+
});
|
|
129
|
+
const diagnostics = ts7.getPreEmitDiagnostics(program);
|
|
130
|
+
if (diagnostics.length > 0) {
|
|
131
|
+
const errors = diagnostics.map((d) => {
|
|
132
|
+
const message = typeof d.messageText === "string" ? d.messageText : d.messageText.messageText;
|
|
133
|
+
return message;
|
|
134
|
+
});
|
|
135
|
+
throw new Error(`TypeScript errors:
|
|
136
|
+
${errors.join("\n")}`);
|
|
137
|
+
}
|
|
138
|
+
} finally {
|
|
139
|
+
try {
|
|
140
|
+
await fs8.unlink(tempFile);
|
|
141
|
+
await fs8.rmdir(tempDir);
|
|
142
|
+
} catch {
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function buildEntryStub(entry, code) {
|
|
147
|
+
const name = entry.name;
|
|
148
|
+
if (!isValidIdentifier(name)) {
|
|
149
|
+
return "";
|
|
150
|
+
}
|
|
151
|
+
const escaped = escapeRegExp(name);
|
|
152
|
+
const usagePattern = new RegExp(`\\b${escaped}\\b`);
|
|
153
|
+
if (!usagePattern.test(code)) {
|
|
154
|
+
return "";
|
|
155
|
+
}
|
|
156
|
+
if (hasDeclaration(code, escaped)) {
|
|
157
|
+
return "";
|
|
158
|
+
}
|
|
159
|
+
switch (entry.kind) {
|
|
160
|
+
case "class":
|
|
161
|
+
return `declare class ${name} {}
|
|
162
|
+
`;
|
|
163
|
+
case "enum":
|
|
164
|
+
return `declare enum ${name} {}
|
|
165
|
+
`;
|
|
166
|
+
case "interface":
|
|
167
|
+
return `interface ${name} {}
|
|
168
|
+
`;
|
|
169
|
+
case "type":
|
|
170
|
+
return `type ${name} = any;
|
|
171
|
+
`;
|
|
172
|
+
case "function":
|
|
173
|
+
return `declare function ${name}(...args: any[]): any;
|
|
174
|
+
`;
|
|
175
|
+
case "variable":
|
|
176
|
+
return `declare const ${name}: any;
|
|
177
|
+
`;
|
|
178
|
+
default:
|
|
179
|
+
return `declare const ${name}: any;
|
|
180
|
+
`;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function hasDeclaration(code, escapedName) {
|
|
184
|
+
const patterns = [
|
|
185
|
+
`\\bimport\\s+[^;]*\\b${escapedName}\\b`,
|
|
186
|
+
`\\bimport\\s+\\{[^}]*\\b${escapedName}\\b[^}]*\\}\\s+from`,
|
|
187
|
+
`\\bimport\\s+${escapedName}\\s+from`,
|
|
188
|
+
`\\bfunction\\s+${escapedName}\\b`,
|
|
189
|
+
`\\bclass\\s+${escapedName}\\b`,
|
|
190
|
+
`\\binterface\\s+${escapedName}\\b`,
|
|
191
|
+
`\\btype\\s+${escapedName}\\b`,
|
|
192
|
+
`\\bconst\\s+${escapedName}\\b`,
|
|
193
|
+
`\\blet\\s+${escapedName}\\b`,
|
|
194
|
+
`\\bvar\\s+${escapedName}\\b`,
|
|
195
|
+
`\\benum\\s+${escapedName}\\b`,
|
|
196
|
+
`\\bexport\\s+(?:default\\s+)?(?:function|class|const|let|var|enum|interface|type)\\s+${escapedName}\\b`
|
|
197
|
+
];
|
|
198
|
+
return patterns.some((pattern) => new RegExp(pattern).test(code));
|
|
199
|
+
}
|
|
200
|
+
function isValidIdentifier(name) {
|
|
201
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name);
|
|
202
|
+
}
|
|
203
|
+
function escapeRegExp(value) {
|
|
204
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
205
|
+
}
|
|
206
|
+
function slugify(value) {
|
|
207
|
+
return value.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)+/g, "");
|
|
208
|
+
}
|
|
209
|
+
function languageToExtension(language) {
|
|
210
|
+
const normalized = language.toLowerCase();
|
|
211
|
+
if (normalized === "tsx") return "tsx";
|
|
212
|
+
if (normalized === "javascript" || normalized === "js") return "js";
|
|
213
|
+
if (normalized === "typescript" || normalized === "ts") return "ts";
|
|
214
|
+
return "txt";
|
|
215
|
+
}
|
|
216
|
+
export {
|
|
217
|
+
examplesPlugin as default,
|
|
218
|
+
examplesPlugin
|
|
219
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@opensyntaxhq/autodocs-plugin-examples",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"description": "Code example validation and extraction plugin for Autodocs",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/OpenSyntaxHQ/autodocs.git",
|
|
9
|
+
"directory": "packages/plugins/examples"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/OpenSyntaxHQ/autodocs/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/OpenSyntaxHQ/autodocs",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"autodocs",
|
|
17
|
+
"plugin",
|
|
18
|
+
"examples",
|
|
19
|
+
"documentation"
|
|
20
|
+
],
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"module": "./dist/index.mjs",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"import": "./dist/index.mjs",
|
|
34
|
+
"require": "./dist/index.js"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsup",
|
|
39
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
40
|
+
"lint": "eslint .",
|
|
41
|
+
"type-check": "tsc --noEmit",
|
|
42
|
+
"clean": "rm -rf dist"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"typescript": "^5.9.0"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@opensyntaxhq/autodocs-core": "^1.0.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@opensyntaxhq/autodocs-core": "^1.0.0",
|
|
52
|
+
"@types/node": "^22.0.0",
|
|
53
|
+
"tsup": "^8.3.0"
|
|
54
|
+
}
|
|
55
|
+
}
|