embedex 0.1.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/README.md ADDED
@@ -0,0 +1,92 @@
1
+ <h1 align="center">embedex</h1>
2
+ <p align="center">
3
+ <img alt="embedex logo." src="./static/logo.png" width=320>
4
+ </p>
5
+
6
+ Command-line interface (CLI) to embed examples into TypeDoc comments.
7
+
8
+ While you can write code directly in TypeDoc comments using the [`@example` tag](https://typedoc.org/tags/example/), they aren't type-checked, linted, or tested, making it difficult to keep them up to date.
9
+
10
+ While [`typedoc-plugin-include-example`](https://github.com/ferdodo/typedoc-plugin-include-example) embeds code into the resulting TypeDoc, it's missing from your code so VS Code's on-hover doesn't show the examples.
11
+
12
+ Ensure your example code runs and shows up in your IDE with `embedex`.
13
+
14
+ ## Table of contents <!-- omit from toc -->
15
+
16
+ - [Install](#install)
17
+ - [Usage](#usage)
18
+ - [Reference](#reference)
19
+ - [Local development commands](#local-development-commands)
20
+
21
+ ## Install
22
+
23
+ ```sh
24
+ npm install -D embedex
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ 1. Add an example to `./examples` (configurable). The first line is a comma-separated list of paths from the current working directory to embed targets. `./examples/greeter.ts`:
30
+
31
+ ```ts
32
+ // src/greeter.ts
33
+ import { greet } from "@my-scope/greeter";
34
+
35
+ greet("world");
36
+ ```
37
+
38
+ 1. In embed target files, add an example comment with the path of the example. `./src/greeter.ts`:
39
+
40
+ ````ts
41
+ /**
42
+ * Greets a person by name.
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * // examples/greeter.ts
47
+ * ```
48
+ */
49
+ function greet(name: string) {
50
+ console.log(`Hello, ${name}!`);
51
+ }
52
+ ````
53
+
54
+ 1. Run `npx embedex`.
55
+ 1. The example is embedded! `./src/greeter.ts`:
56
+
57
+ ````ts
58
+ /**
59
+ * Greets a person by name.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * // examples/greeter.ts
64
+ * import { greet } from "@my-scope/greeter";
65
+ *
66
+ * greet("world");
67
+ * ```
68
+ */
69
+ function greet(name: string) {
70
+ console.log(`Hello, ${name}!`);
71
+ }
72
+ ````
73
+
74
+ ## Reference
75
+
76
+ ```
77
+ Usage: embedex [options]
78
+
79
+ Command-line interface (CLI) to embed example TypeScript code into TypeDoc comments.
80
+
81
+ Options:
82
+ -V, --version output the version number
83
+ -e, --examplesGlob <pattern> examples glob pattern (default: "examples/**/*.ts")
84
+ -c, --check check if examples are already embedded, useful for CI (default:
85
+ false)
86
+ -v, --verbose show verbose output (default: false)
87
+ -h, --help display help for command
88
+ ```
89
+
90
+ ## Local development commands
91
+
92
+ See [`package.json`](./package.json) `scripts` for a list of commands.
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "embedex",
3
+ "description": "Command-line interface (CLI) to embed example TypeScript code into TypeDoc comments.",
4
+ "version": "0.1.0",
5
+ "bin": {
6
+ "embedex": "./src/bin/cli.js"
7
+ },
8
+ "dependencies": {
9
+ "@commander-js/extra-typings": "12.1.0",
10
+ "glob": "11.0.0",
11
+ "tslib": "2.8.0",
12
+ "yoctocolors-cjs": "2.1.2"
13
+ },
14
+ "keywords": [],
15
+ "license": "MIT",
16
+ "main": "./src/index.js",
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "type": "commonjs",
21
+ "typings": "./src/index.d.ts",
22
+ "types": "./src/index.d.ts"
23
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/src/bin/cli.js ADDED
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const extra_typings_1 = require("@commander-js/extra-typings");
5
+ const package_json_1 = require("../../package.json");
6
+ const embed_1 = require("../lib/embed");
7
+ const processResult_1 = require("./processResult");
8
+ const program = new extra_typings_1.Command()
9
+ .name(package_json_1.name)
10
+ .description("Command-line interface (CLI) to embed example TypeScript code into TypeDoc comments.")
11
+ .version(String(package_json_1.version))
12
+ .addOption(new extra_typings_1.Option("-e, --examplesGlob <pattern>", "examples glob pattern").default("examples/**/*.ts"))
13
+ .addOption(new extra_typings_1.Option("-c, --check", "check if examples are already embedded, useful for CI").default(false))
14
+ .addOption(new extra_typings_1.Option("-v, --verbose", "show verbose output").default(false));
15
+ program.parse();
16
+ const options = program.opts();
17
+ const { check, examplesGlob, verbose } = options;
18
+ const cwd = process.cwd();
19
+ if (verbose) {
20
+ console.log((0, processResult_1.dim)("examplesGlob:\n ", examplesGlob));
21
+ console.log((0, processResult_1.dim)("cwd:\n ", cwd));
22
+ }
23
+ (0, embed_1.embed)({
24
+ examplesGlob,
25
+ cwd,
26
+ write: !check,
27
+ })
28
+ .then((result) => {
29
+ const output = (0, processResult_1.processResult)({ check, result, cwd, verbose });
30
+ if (output.some((o) => o.isError)) {
31
+ console.error(output.map((o) => o.message).join("\n"));
32
+ process.exit(1);
33
+ }
34
+ else {
35
+ console.log(output.map((o) => o.message).join("\n"));
36
+ }
37
+ })
38
+ .catch((error) => {
39
+ console.error(error.message);
40
+ process.exit(1);
41
+ });
42
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../../../packages/embedex/src/bin/cli.ts"],"names":[],"mappings":";;;AACA,+DAA8D;AAE9D,qDAAmD;AACnD,wCAAqC;AACrC,mDAAqD;AAErD,MAAM,OAAO,GAAG,IAAI,uBAAO,EAAE;KAC1B,IAAI,CAAC,mBAAI,CAAC;KACV,WAAW,CACV,sFAAsF,CACvF;KACA,OAAO,CAAC,MAAM,CAAC,sBAAO,CAAC,CAAC;KACxB,SAAS,CACR,IAAI,sBAAM,CAAC,8BAA8B,EAAE,uBAAuB,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAChG;KACA,SAAS,CACR,IAAI,sBAAM,CAAC,aAAa,EAAE,uDAAuD,CAAC,CAAC,OAAO,CACxF,KAAK,CACN,CACF;KACA,SAAS,CAAC,IAAI,sBAAM,CAAC,eAAe,EAAE,qBAAqB,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AAEhF,OAAO,CAAC,KAAK,EAAE,CAAC;AAEhB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;AAC/B,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;AACjD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAE1B,IAAI,OAAO,EAAE,CAAC;IACZ,OAAO,CAAC,GAAG,CAAC,IAAA,mBAAG,EAAC,mBAAmB,EAAE,YAAY,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,IAAA,mBAAG,EAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,IAAA,aAAK,EAAC;IACJ,YAAY;IACZ,GAAG;IACH,KAAK,EAAE,CAAC,KAAK;CACd,CAAC;KACC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;IACf,MAAM,MAAM,GAAG,IAAA,6BAAa,EAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;IAC9D,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,CAAC;AACH,CAAC,CAAC;KACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { type Embed, type EmbedResult } from "../lib/types";
2
+ interface Output {
3
+ code: Embed["code"];
4
+ isError: boolean;
5
+ message: string;
6
+ }
7
+ export declare function dim(...messages: string[]): string;
8
+ export declare function processResult(params: {
9
+ check: boolean;
10
+ result: EmbedResult;
11
+ cwd: string;
12
+ verbose: boolean;
13
+ }): Output[];
14
+ export {};
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dim = dim;
4
+ exports.processResult = processResult;
5
+ const tslib_1 = require("tslib");
6
+ const node_path_1 = require("node:path");
7
+ const yoctocolors_cjs_1 = tslib_1.__importDefault(require("yoctocolors-cjs"));
8
+ function dim(...messages) {
9
+ return yoctocolors_cjs_1.default.dim(messages.join(" "));
10
+ }
11
+ function processResult(params) {
12
+ const { check, result, cwd, verbose } = params;
13
+ const { embeds, examples, targets } = result;
14
+ function relative(path) {
15
+ return (0, node_path_1.relative)(cwd, path);
16
+ }
17
+ if (verbose) {
18
+ console.log(dim("examples:\n ", examples
19
+ .map(({ path, targets }) => `${relative(path)} -> ${targets.map(relative).join(", ")}`)
20
+ .join("\n ")));
21
+ console.log(dim("targets:\n ", targets
22
+ .map(({ path, examples }) => `${relative(path)} -> ${examples.map(relative).join(", ")}`)
23
+ .join("\n ")));
24
+ }
25
+ const output = [];
26
+ for (const embed of embeds) {
27
+ const { code, paths } = embed;
28
+ const { target, examples } = paths;
29
+ const toOutput = createToOutput({
30
+ code,
31
+ paths: { target: relative(target), examples: examples.map((path) => relative(path)) },
32
+ });
33
+ // eslint-disable-next-line default-case
34
+ switch (code) {
35
+ case "NO_CHANGE": {
36
+ output.push(toOutput());
37
+ break;
38
+ }
39
+ case "NO_MATCH": {
40
+ output.push(toOutput(true));
41
+ break;
42
+ }
43
+ case "UPDATE": {
44
+ output.push(toOutput(check));
45
+ break;
46
+ }
47
+ }
48
+ }
49
+ return output.sort((a, b) => a.code.localeCompare(b.code));
50
+ }
51
+ function createToOutput(params) {
52
+ const { code, paths } = params;
53
+ const { target, examples } = paths;
54
+ return (isError = false) => ({
55
+ code,
56
+ isError,
57
+ message: `${yoctocolors_cjs_1.default.green(code)} ${yoctocolors_cjs_1.default.gray(target)} -> ${yoctocolors_cjs_1.default.gray(examples.join(", "))}`,
58
+ });
59
+ }
60
+ //# sourceMappingURL=processResult.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processResult.js","sourceRoot":"","sources":["../../../../../packages/embedex/src/bin/processResult.ts"],"names":[],"mappings":"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"}
package/src/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./lib/embed";
2
+ export * from "./lib/types";
package/src/index.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./lib/embed"), exports);
5
+ tslib_1.__exportStar(require("./lib/types"), exports);
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/embedex/src/index.ts"],"names":[],"mappings":";;;AAAA,sDAA4B;AAC5B,sDAA4B"}
@@ -0,0 +1,5 @@
1
+ import { type EmbedParams, type EmbedResult } from "./types";
2
+ /**
3
+ * Command-line interface (CLI) to embed examples into TypeDoc comments.
4
+ */
5
+ export declare function embed(params: Readonly<EmbedParams>): Promise<EmbedResult>;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.embed = embed;
4
+ const promises_1 = require("node:fs/promises");
5
+ const createExampleMap_1 = require("./internal/createExampleMap");
6
+ const createTargetMap_1 = require("./internal/createTargetMap");
7
+ const processTargets_1 = require("./internal/processTargets");
8
+ /**
9
+ * Command-line interface (CLI) to embed examples into TypeDoc comments.
10
+ */
11
+ async function embed(params) {
12
+ const { examplesGlob: globPattern, cwd, write } = params;
13
+ const exampleMap = await (0, createExampleMap_1.createExampleMap)({ globPattern, cwd });
14
+ const targetMap = await (0, createTargetMap_1.createTargetMap)({ exampleMap });
15
+ const embeds = (0, processTargets_1.processTargets)({ exampleMap, cwd, targetMap });
16
+ await Promise.all(embeds.map(async (embed) => {
17
+ if (write && embed.code === "UPDATE") {
18
+ await (0, promises_1.writeFile)(embed.paths.target, embed.updatedContent);
19
+ }
20
+ }));
21
+ return {
22
+ embeds,
23
+ examples: [...exampleMap.entries()].map(([key, value]) => ({
24
+ path: key,
25
+ targets: value.targets,
26
+ })),
27
+ targets: [...targetMap.entries()].map(([key, value]) => ({
28
+ path: key,
29
+ examples: [...value.examples],
30
+ })),
31
+ };
32
+ }
33
+ //# sourceMappingURL=embed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embed.js","sourceRoot":"","sources":["../../../../../packages/embedex/src/lib/embed.ts"],"names":[],"mappings":";;AAUA,sBA0BC;AApCD,+CAA6C;AAE7C,kEAA+D;AAC/D,gEAA6D;AAC7D,8DAA2D;AAG3D;;GAEG;AACI,KAAK,UAAU,KAAK,CAAC,MAA6B;IACvD,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IACzD,MAAM,UAAU,GAAG,MAAM,IAAA,mCAAgB,EAAC,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;IAChE,MAAM,SAAS,GAAG,MAAM,IAAA,iCAAe,EAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IAExD,MAAM,MAAM,GAAG,IAAA,+BAAc,EAAC,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;IAE9D,MAAM,OAAO,CAAC,GAAG,CACf,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACzB,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,IAAA,oBAAS,EAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,OAAO;QACL,MAAM;QACN,QAAQ,EAAE,CAAC,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;YACzD,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CAAC;QACH,OAAO,EAAE,CAAC,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;YACvD,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;SAC9B,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { type ExampleMap } from "./types";
2
+ export declare function createExampleMap(params: {
3
+ globPattern: string;
4
+ cwd: string;
5
+ }): Promise<ExampleMap>;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createExampleMap = createExampleMap;
4
+ const promises_1 = require("node:fs/promises");
5
+ const node_path_1 = require("node:path");
6
+ const glob_1 = require("glob");
7
+ const EXAMPLE_MARKER_PREFIX = "// ";
8
+ async function createExampleMap(params) {
9
+ const { globPattern, cwd } = params;
10
+ const exampleMap = new Map();
11
+ const paths = await (0, glob_1.glob)(globPattern, { absolute: true, cwd, nodir: true });
12
+ for await (const path of paths) {
13
+ const content = await (0, promises_1.readFile)(path, "utf8");
14
+ const [first, ...rest] = content.split("\n");
15
+ if (first?.startsWith(EXAMPLE_MARKER_PREFIX)) {
16
+ exampleMap.set(path, {
17
+ content: rest.join("\n"),
18
+ targets: first
19
+ .replace(EXAMPLE_MARKER_PREFIX, "")
20
+ .split(",")
21
+ .map((t) => (0, node_path_1.join)(cwd, t.trim())),
22
+ });
23
+ }
24
+ }
25
+ return exampleMap;
26
+ }
27
+ //# sourceMappingURL=createExampleMap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createExampleMap.js","sourceRoot":"","sources":["../../../../../../packages/embedex/src/lib/internal/createExampleMap.ts"],"names":[],"mappings":";;AAUA,4CAuBC;AAjCD,+CAA4C;AAC5C,yCAAiC;AAEjC,+BAA4B;AAK5B,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAE7B,KAAK,UAAU,gBAAgB,CAAC,MAGtC;IACC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;IACpC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAwB,CAAC;IACnD,MAAM,KAAK,GAAG,MAAM,IAAA,WAAI,EAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5E,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,MAAM,IAAA,mBAAQ,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,KAAK,EAAE,UAAU,CAAC,qBAAqB,CAAC,EAAE,CAAC;YAC7C,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE;gBACnB,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;gBACxB,OAAO,EAAE,KAAK;qBACX,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC;qBAClC,KAAK,CAAC,GAAG,CAAC;qBACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,gBAAI,EAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;aACnC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type ExampleMap, type TargetMap } from "./types";
2
+ export declare function createTargetMap(params: Readonly<{
3
+ exampleMap: Readonly<ExampleMap>;
4
+ }>): Promise<TargetMap>;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTargetMap = createTargetMap;
4
+ const promises_1 = require("node:fs/promises");
5
+ async function createTargetMap(params) {
6
+ const { exampleMap } = params;
7
+ const uniqueTargetPaths = new Set([...exampleMap.values()].flatMap(({ targets }) => targets));
8
+ const targetContents = new Map();
9
+ await Promise.all([...uniqueTargetPaths].map(async (path) => {
10
+ targetContents.set(path, await (0, promises_1.readFile)(path, "utf8"));
11
+ }));
12
+ return new Map([...uniqueTargetPaths].map((targetPath) => [
13
+ targetPath,
14
+ {
15
+ content: targetContents.get(targetPath),
16
+ examples: new Set([...exampleMap.entries()]
17
+ .filter(([_, { targets }]) => targets.includes(targetPath))
18
+ .map(([examplePath]) => examplePath)),
19
+ },
20
+ ]));
21
+ }
22
+ //# sourceMappingURL=createTargetMap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTargetMap.js","sourceRoot":"","sources":["../../../../../../packages/embedex/src/lib/internal/createTargetMap.ts"],"names":[],"mappings":";;AAKA,0CA0BC;AA/BD,+CAA4C;AAKrC,KAAK,UAAU,eAAe,CACnC,MAAsD;IAEtD,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;IAE9B,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9F,MAAM,cAAc,GAAG,IAAI,GAAG,EAAsB,CAAC;IACrD,MAAM,OAAO,CAAC,GAAG,CACf,CAAC,GAAG,iBAAiB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACxC,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,IAAA,mBAAQ,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CACH,CAAC;IAEF,OAAO,IAAI,GAAG,CACZ,CAAC,GAAG,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC;QACzC,UAAU;QACV;YACE,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC,UAAU,CAAE;YACxC,QAAQ,EAAE,IAAI,GAAG,CACf,CAAC,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC;iBACtB,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;iBAC1D,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CACvC;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Embed } from "../types";
2
+ import { type ExampleMap, type TargetMap } from "./types";
3
+ export declare function processTargets(params: Readonly<{
4
+ exampleMap: ExampleMap;
5
+ cwd: string;
6
+ targetMap: TargetMap;
7
+ }>): Embed[];
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processTargets = processTargets;
4
+ const node_path_1 = require("node:path");
5
+ function processTargets(params) {
6
+ const { exampleMap, targetMap, cwd } = params;
7
+ function absolutePath(path) {
8
+ return (0, node_path_1.join)(cwd, path);
9
+ }
10
+ const result = [];
11
+ for (const [target, value] of targetMap.entries()) {
12
+ const { content, examples } = value;
13
+ const matches = matchAll({ content, exists: (example) => examples.has(absolutePath(example)) });
14
+ if (matches.length === 0) {
15
+ result.push({ code: "NO_MATCH", paths: { target, examples: [] } });
16
+ }
17
+ else {
18
+ let updatedContent = content;
19
+ for (const { fullMatch, language, indent, example } of matches) {
20
+ const exampleContent = exampleMap.get(absolutePath(example));
21
+ const replacement = `\`\`\`${language}\n${prefixLines({
22
+ content: [`// ${example}`, ...exampleContent.content.split("\n"), `\`\`\``],
23
+ indent,
24
+ })}`;
25
+ updatedContent = updatedContent.replaceAll(fullMatch, replacement);
26
+ }
27
+ const paths = { examples: matches.map((m) => absolutePath(m.example)), target };
28
+ result.push(content === updatedContent
29
+ ? { code: "NO_CHANGE", paths }
30
+ : { code: "UPDATE", paths, updatedContent });
31
+ }
32
+ }
33
+ return result;
34
+ }
35
+ function matchAll(params) {
36
+ const { content, exists } = params;
37
+ return [...content.matchAll(/```(typescript|ts)\n(\s+)\*\s+\/\/\s(.+)\n[\S\s]+?```/g)]
38
+ .map((match) => {
39
+ const [fullMatch, language, indent, example] = match;
40
+ return isDefined(fullMatch) &&
41
+ isDefined(language) &&
42
+ isDefined(indent) &&
43
+ isDefined(example) &&
44
+ exists(example)
45
+ ? { fullMatch, language, indent, example }
46
+ : undefined;
47
+ })
48
+ .filter(isDefined);
49
+ }
50
+ function prefixLines(params) {
51
+ const { content, indent } = params;
52
+ return content
53
+ .map((line) => {
54
+ const trimmed = line.trim();
55
+ return trimmed ? `${indent}* ${line}` : `${indent}*`;
56
+ })
57
+ .join("\n");
58
+ }
59
+ function isDefined(value) {
60
+ return value !== null && value !== undefined;
61
+ }
62
+ //# sourceMappingURL=processTargets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processTargets.js","sourceRoot":"","sources":["../../../../../../packages/embedex/src/lib/internal/processTargets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type ExamplePath, type TargetPath } from "../types";
2
+ export interface Example {
3
+ content: string;
4
+ targets: TargetPath[];
5
+ }
6
+ export type ExampleMap = Map<ExamplePath, Example>;
7
+ interface Target {
8
+ content: string;
9
+ examples: Set<ExamplePath>;
10
+ }
11
+ export type TargetMap = Map<TargetPath, Target>;
12
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../packages/embedex/src/lib/internal/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,37 @@
1
+ export type ExamplePath = string;
2
+ export type TargetPath = string;
3
+ export interface EmbedParams {
4
+ examplesGlob: string;
5
+ cwd: string;
6
+ write: boolean;
7
+ }
8
+ export type Code = "NO_CHANGE" | "NO_MATCH" | "UPDATE";
9
+ export interface Result {
10
+ code: Code;
11
+ paths: {
12
+ target: TargetPath;
13
+ examples: ExamplePath[];
14
+ };
15
+ }
16
+ export type NoMatch = Result & {
17
+ code: "NO_MATCH";
18
+ };
19
+ export type NoChange = Result & {
20
+ code: "NO_CHANGE";
21
+ };
22
+ export type Updated = Result & {
23
+ code: "UPDATE";
24
+ updatedContent: string;
25
+ };
26
+ export type Embed = NoMatch | Updated | NoChange;
27
+ export interface EmbedResult {
28
+ embeds: Embed[];
29
+ examples: Array<{
30
+ path: ExamplePath;
31
+ targets: TargetPath[];
32
+ }>;
33
+ targets: Array<{
34
+ path: TargetPath;
35
+ examples: ExamplePath[];
36
+ }>;
37
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../packages/embedex/src/lib/types.ts"],"names":[],"mappings":""}
Binary file