@borrowdev/docval 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.
Files changed (35) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/dist/adapters/index.mjs +21 -0
  4. package/dist/adapters/index.mjs.map +1 -0
  5. package/dist/adapters/javascript/constants.mjs +10 -0
  6. package/dist/adapters/javascript/constants.mjs.map +1 -0
  7. package/dist/adapters/javascript/index.mjs +31 -0
  8. package/dist/adapters/javascript/index.mjs.map +1 -0
  9. package/dist/adapters/javascript/utils.mjs +59 -0
  10. package/dist/adapters/javascript/utils.mjs.map +1 -0
  11. package/dist/adapters/jsx/index.mjs +8 -0
  12. package/dist/adapters/jsx/index.mjs.map +1 -0
  13. package/dist/adapters/rust/constants.mjs +6 -0
  14. package/dist/adapters/rust/constants.mjs.map +1 -0
  15. package/dist/adapters/rust/index.mjs +19 -0
  16. package/dist/adapters/rust/index.mjs.map +1 -0
  17. package/dist/adapters/rust/utils.mjs +69 -0
  18. package/dist/adapters/rust/utils.mjs.map +1 -0
  19. package/dist/adapters/tsx/index.mjs +8 -0
  20. package/dist/adapters/tsx/index.mjs.map +1 -0
  21. package/dist/adapters/typescript/index.mjs +8 -0
  22. package/dist/adapters/typescript/index.mjs.map +1 -0
  23. package/dist/assets/package.mjs +11 -0
  24. package/dist/assets/package.mjs.map +1 -0
  25. package/dist/main.d.mts +2 -0
  26. package/dist/main.mjs +3 -0
  27. package/dist/remark/plugin.d.mts +12 -0
  28. package/dist/remark/plugin.d.mts.map +1 -0
  29. package/dist/remark/plugin.mjs +25 -0
  30. package/dist/remark/plugin.mjs.map +1 -0
  31. package/dist/remark/utils.mjs +26 -0
  32. package/dist/remark/utils.mjs.map +1 -0
  33. package/dist/utils.mjs +31 -0
  34. package/dist/utils.mjs.map +1 -0
  35. package/package.json +50 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Lorenzo Bloedow
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # Borrow DocVal
2
+
3
+ **Validate your documentation codeblocks at build-time.**
4
+
5
+ DocVal creates an environment and executes the code in your codeblocks to make sure it works as expected.
@@ -0,0 +1,21 @@
1
+ import javascript_default from "./javascript/index.mjs";
2
+ import jsx_default from "./jsx/index.mjs";
3
+ import rust_default from "./rust/index.mjs";
4
+ import tsx_default from "./tsx/index.mjs";
5
+ import typescript_default from "./typescript/index.mjs";
6
+
7
+ //#region src/adapters/index.ts
8
+ const map = {
9
+ javascript: javascript_default,
10
+ js: javascript_default,
11
+ typescript: typescript_default,
12
+ ts: typescript_default,
13
+ jsx: jsx_default,
14
+ tsx: tsx_default,
15
+ rust: rust_default,
16
+ rs: rust_default
17
+ };
18
+
19
+ //#endregion
20
+ export { map as default };
21
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["adapterJavaScript","adapterTypeScript","adapterJSX","adapterTSX","adapterRust"],"sources":["../../src/adapters/index.ts"],"sourcesContent":["import adapterJavaScript from \"./javascript\";\nimport adapterJSX from \"./jsx\";\nimport adapterRust from \"./rust\";\nimport adapterTSX from \"./tsx\";\nimport adapterTypeScript from \"./typescript\";\n\nconst map: { [key: string]: (code: string, metadata: string[]) => Promise<void> } = {\n javascript: adapterJavaScript,\n js: adapterJavaScript,\n typescript: adapterTypeScript,\n ts: adapterTypeScript,\n jsx: adapterJSX,\n tsx: adapterTSX,\n rust: adapterRust,\n rs: adapterRust,\n};\n\nexport default map;\n"],"mappings":";;;;;;;AAMA,MAAM,MAA8E;CAClF,YAAYA;CACZ,IAAIA;CACJ,YAAYC;CACZ,IAAIA;CACJ,KAAKC;CACL,KAAKC;CACL,MAAMC;CACN,IAAIA;CACL"}
@@ -0,0 +1,10 @@
1
+ //#region src/adapters/javascript/constants.ts
2
+ const ADAPTER_OPTIONS = {
3
+ env: ".env.docs",
4
+ installCommand: ["npm", "install"],
5
+ environment: void 0
6
+ };
7
+
8
+ //#endregion
9
+ export { ADAPTER_OPTIONS };
10
+ //# sourceMappingURL=constants.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.mjs","names":[],"sources":["../../../src/adapters/javascript/constants.ts"],"sourcesContent":["export const ADAPTER_OPTIONS = {\n env: \".env.docs\",\n installCommand: [\"npm\", \"install\"],\n environment: undefined,\n};\n"],"mappings":";AAAA,MAAa,kBAAkB;CAC7B,KAAK;CACL,gBAAgB,CAAC,OAAO,UAAU;CAClC,aAAa;CACd"}
@@ -0,0 +1,31 @@
1
+ import { getFilename, getOptions } from "../../remark/utils.mjs";
2
+ import { cleanupEnvironment, execUntilExit } from "../../utils.mjs";
3
+ import { createEnvironment, getEntryPath, getImports } from "./utils.mjs";
4
+ import { ADAPTER_OPTIONS } from "./constants.mjs";
5
+ import { readFile } from "fs/promises";
6
+ import { existsSync } from "fs";
7
+ import { JsxEmit, transpileModule } from "typescript";
8
+
9
+ //#region src/adapters/javascript/index.ts
10
+ async function adapterJavaScript(code, filename, options, type) {
11
+ const dotenv = existsSync(options.env) ? await readFile(options.env, { encoding: "utf-8" }) : void 0;
12
+ const imports = await getImports(code, filename, type);
13
+ const environmentPath = await createEnvironment(type !== "js" ? transpileModule(code, {
14
+ fileName: filename + `.${type}`,
15
+ compilerOptions: { jsx: JsxEmit.React }
16
+ }).outputText : code, imports, dotenv, {
17
+ environmentPath: options.environment,
18
+ installCommand: options.installCommand
19
+ });
20
+ try {
21
+ await execUntilExit(`node ${dotenv ? `--env-file=${environmentPath}/.env` : ""} ${getEntryPath(environmentPath)}`, process.cwd());
22
+ } finally {
23
+ if (!options.environment) await cleanupEnvironment(environmentPath);
24
+ }
25
+ }
26
+ const adapterWrapperJavaScript = (code, metadata, type) => adapterJavaScript(code, getFilename(metadata, code), getOptions(metadata, ADAPTER_OPTIONS), type);
27
+ var javascript_default = (code, metadata) => adapterWrapperJavaScript(code, metadata, "js");
28
+
29
+ //#endregion
30
+ export { adapterWrapperJavaScript, javascript_default as default };
31
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/adapters/javascript/index.ts"],"sourcesContent":["import { getFilename, getOptions } from \"@/remark/utils\";\nimport {\n cleanupEnvironment,\n createEnvironment,\n execUntilExit,\n getEntryPath,\n getImports,\n JavaScriptType,\n} from \"./utils\";\nimport { readFile } from \"fs/promises\";\nimport { ADAPTER_OPTIONS } from \"./constants\";\nimport { existsSync } from \"fs\";\nimport { JsxEmit, transpileModule } from \"typescript\";\n\ntype AdapterOptions = {\n env: string;\n installCommand: string[];\n environment?: string;\n};\n\nasync function adapterJavaScript(\n code: string,\n filename: string,\n options: AdapterOptions,\n type: JavaScriptType,\n): Promise<void> {\n const dotenv = existsSync(options.env)\n ? await readFile(options.env, { encoding: \"utf-8\" })\n : undefined;\n const imports = await getImports(code, filename, type);\n const parsedCode =\n type !== \"js\"\n ? transpileModule(code, {\n fileName: filename + `.${type}`,\n compilerOptions: {\n jsx: JsxEmit.React,\n },\n }).outputText\n : code;\n const environmentPath = await createEnvironment(parsedCode, imports, dotenv, {\n environmentPath: options.environment,\n installCommand: options.installCommand,\n });\n\n try {\n const envFlag = dotenv ? `--env-file=${environmentPath}/.env` : \"\";\n await execUntilExit(`node ${envFlag} ${getEntryPath(environmentPath)}`, process.cwd());\n } finally {\n if (!options.environment) {\n await cleanupEnvironment(environmentPath);\n }\n }\n}\n\nexport const adapterWrapperJavaScript = (\n code: string,\n metadata: string[],\n type: JavaScriptType,\n): Promise<void> =>\n adapterJavaScript(code, getFilename(metadata, code), getOptions(metadata, ADAPTER_OPTIONS), type);\nexport default (code: string, metadata: string[]) => adapterWrapperJavaScript(code, metadata, \"js\");\n"],"mappings":";;;;;;;;;AAoBA,eAAe,kBACb,MACA,UACA,SACA,MACe;CACf,MAAM,SAAS,WAAW,QAAQ,IAAI,GAClC,MAAM,SAAS,QAAQ,KAAK,EAAE,UAAU,SAAS,CAAC,GAClD;CACJ,MAAM,UAAU,MAAM,WAAW,MAAM,UAAU,KAAK;CAUtD,MAAM,kBAAkB,MAAM,kBAR5B,SAAS,OACL,gBAAgB,MAAM;EACpB,UAAU,WAAW,IAAI;EACzB,iBAAiB,EACf,KAAK,QAAQ,OACd;EACF,CAAC,CAAC,aACH,MACsD,SAAS,QAAQ;EAC3E,iBAAiB,QAAQ;EACzB,gBAAgB,QAAQ;EACzB,CAAC;AAEF,KAAI;AAEF,QAAM,cAAc,QADJ,SAAS,cAAc,gBAAgB,SAAS,GAC5B,GAAG,aAAa,gBAAgB,IAAI,QAAQ,KAAK,CAAC;WAC9E;AACR,MAAI,CAAC,QAAQ,YACX,OAAM,mBAAmB,gBAAgB;;;AAK/C,MAAa,4BACX,MACA,UACA,SAEA,kBAAkB,MAAM,YAAY,UAAU,KAAK,EAAE,WAAW,UAAU,gBAAgB,EAAE,KAAK;AACnG,0BAAgB,MAAc,aAAuB,yBAAyB,MAAM,UAAU,KAAK"}
@@ -0,0 +1,59 @@
1
+ import package_default from "../../assets/package.mjs";
2
+ import { cleanupEnvironment, execUntilExit, logger } from "../../utils.mjs";
3
+ import { randomUUID } from "crypto";
4
+ import { parse } from "oxc-parser";
5
+ import { tmpdir } from "os";
6
+ import { mkdir, writeFile } from "fs/promises";
7
+ import { join } from "path";
8
+ import { isBuiltin } from "module";
9
+
10
+ //#region src/adapters/javascript/utils.ts
11
+ function getPackage(importSpec) {
12
+ let packageSpec = importSpec;
13
+ if (packageSpec.startsWith("npm:")) packageSpec = packageSpec.slice(4);
14
+ if (packageSpec.startsWith("@")) return packageSpec.split("/").slice(0, 2).join("/");
15
+ return packageSpec.split("/")[0];
16
+ }
17
+ async function getImports(code, filename, type) {
18
+ const ast = await parse(filename, code, { lang: type });
19
+ return [...ast.module.dynamicImports.map((d) => {
20
+ const packageSpec = getPackage(code.slice(d.moduleRequest.start, d.moduleRequest.end).replaceAll(/['"]/g, ""));
21
+ return {
22
+ package: packageSpec,
23
+ isExternal: !isBuiltin(packageSpec)
24
+ };
25
+ }), ...ast.module.staticImports.map((s) => ({
26
+ package: getPackage(s.moduleRequest.value),
27
+ isExternal: !isBuiltin(s.moduleRequest.value)
28
+ }))];
29
+ }
30
+ function getEntryPath(environmentPath) {
31
+ return `${environmentPath}/dist/index.js`;
32
+ }
33
+ async function createEnvironment(code, imports, env, options = { installCommand: ["npm", "install"] }) {
34
+ logger.info("Creating environment with imports", imports.map((i) => i.package));
35
+ if (options.environmentPath) {
36
+ logger.info("Using explicit environment at", options.environmentPath);
37
+ await mkdir(`${options.environmentPath}/dist`, { recursive: true });
38
+ await writeFile(`${options.environmentPath}/dist/index.js`, code);
39
+ return options.environmentPath;
40
+ }
41
+ const path = join(tmpdir(), "docval", randomUUID());
42
+ await mkdir(`${path}/dist`, { recursive: true });
43
+ await Promise.all([
44
+ writeFile(`${path}/package.json`, JSON.stringify(package_default)),
45
+ writeFile(`${path}/dist/index.js`, code),
46
+ env ? writeFile(`${path}/.env`, env) : Promise.resolve()
47
+ ]);
48
+ logger.info("Created environment at", path);
49
+ const cmd = options.installCommand.concat(imports.filter((i) => i.isExternal).map((i) => i.package)).join(" ");
50
+ if (imports.length > 0) {
51
+ logger.info("Installing dependencies with command:", cmd);
52
+ await execUntilExit(cmd, path);
53
+ }
54
+ return path;
55
+ }
56
+
57
+ //#endregion
58
+ export { createEnvironment, getEntryPath, getImports };
59
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.mjs","names":["manifest"],"sources":["../../../src/adapters/javascript/utils.ts"],"sourcesContent":["import { parse } from \"oxc-parser\";\nimport { tmpdir } from \"os\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport manifest from \"~/assets/package.json\";\nimport { join } from \"path\";\nimport { randomUUID } from \"crypto\";\nimport { isBuiltin } from \"module\";\nimport { cleanupEnvironment, execUntilExit, logger } from \"@/utils\";\n\ntype Import = {\n isExternal: boolean;\n package: string;\n};\n\nfunction getPackage(importSpec: string): string {\n let packageSpec = importSpec;\n // Deno environment\n if (packageSpec.startsWith(\"npm:\")) {\n packageSpec = packageSpec.slice(4);\n }\n if (packageSpec.startsWith(\"@\")) {\n return packageSpec.split(\"/\").slice(0, 2).join(\"/\");\n }\n return packageSpec.split(\"/\")[0];\n}\n\nasync function getImports(code: string, filename: string, type: JavaScriptType): Promise<Import[]> {\n const ast = await parse(filename, code, {\n lang: type,\n });\n return [\n ...ast.module.dynamicImports.map((d) => {\n const packageSpec = getPackage(\n code.slice(d.moduleRequest.start, d.moduleRequest.end).replaceAll(/['\"]/g, \"\"),\n );\n return { package: packageSpec, isExternal: !isBuiltin(packageSpec) };\n }),\n ...ast.module.staticImports.map((s) => ({\n package: getPackage(s.moduleRequest.value),\n isExternal: !isBuiltin(s.moduleRequest.value),\n })),\n ];\n}\n\ntype EnvironmentOptions = {\n environmentPath?: string;\n installCommand: string[];\n};\n\nfunction getEntryPath(environmentPath: string) {\n return `${environmentPath}/dist/index.js`;\n}\n\nasync function createEnvironment(\n code: string,\n imports: Import[],\n env: string | undefined,\n options: EnvironmentOptions = {\n installCommand: [\"npm\", \"install\"],\n },\n) {\n logger.info(\n \"Creating environment with imports\",\n imports.map((i) => i.package),\n );\n if (options.environmentPath) {\n logger.info(\"Using explicit environment at\", options.environmentPath);\n await mkdir(`${options.environmentPath}/dist`, { recursive: true });\n await writeFile(`${options.environmentPath}/dist/index.js`, code);\n return options.environmentPath;\n }\n\n const path = join(tmpdir(), \"docval\", randomUUID());\n await mkdir(`${path}/dist`, { recursive: true });\n await Promise.all([\n writeFile(`${path}/package.json`, JSON.stringify(manifest)),\n writeFile(`${path}/dist/index.js`, code),\n env ? writeFile(`${path}/.env`, env) : Promise.resolve(),\n ]);\n logger.info(\"Created environment at\", path);\n const cmd = options.installCommand\n .concat(imports.filter((i) => i.isExternal).map((i) => i.package))\n .join(\" \");\n if (imports.length > 0) {\n logger.info(\"Installing dependencies with command:\", cmd);\n await execUntilExit(cmd, path);\n }\n return path;\n}\n\ntype JavaScriptType = \"js\" | \"ts\" | \"tsx\" | \"jsx\";\n\nexport type { JavaScriptType };\nexport { getImports, createEnvironment, cleanupEnvironment, execUntilExit, getEntryPath };\n"],"mappings":";;;;;;;;;;AAcA,SAAS,WAAW,YAA4B;CAC9C,IAAI,cAAc;AAElB,KAAI,YAAY,WAAW,OAAO,CAChC,eAAc,YAAY,MAAM,EAAE;AAEpC,KAAI,YAAY,WAAW,IAAI,CAC7B,QAAO,YAAY,MAAM,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI;AAErD,QAAO,YAAY,MAAM,IAAI,CAAC;;AAGhC,eAAe,WAAW,MAAc,UAAkB,MAAyC;CACjG,MAAM,MAAM,MAAM,MAAM,UAAU,MAAM,EACtC,MAAM,MACP,CAAC;AACF,QAAO,CACL,GAAG,IAAI,OAAO,eAAe,KAAK,MAAM;EACtC,MAAM,cAAc,WAClB,KAAK,MAAM,EAAE,cAAc,OAAO,EAAE,cAAc,IAAI,CAAC,WAAW,SAAS,GAAG,CAC/E;AACD,SAAO;GAAE,SAAS;GAAa,YAAY,CAAC,UAAU,YAAY;GAAE;GACpE,EACF,GAAG,IAAI,OAAO,cAAc,KAAK,OAAO;EACtC,SAAS,WAAW,EAAE,cAAc,MAAM;EAC1C,YAAY,CAAC,UAAU,EAAE,cAAc,MAAM;EAC9C,EAAE,CACJ;;AAQH,SAAS,aAAa,iBAAyB;AAC7C,QAAO,GAAG,gBAAgB;;AAG5B,eAAe,kBACb,MACA,SACA,KACA,UAA8B,EAC5B,gBAAgB,CAAC,OAAO,UAAU,EACnC,EACD;AACA,QAAO,KACL,qCACA,QAAQ,KAAK,MAAM,EAAE,QAAQ,CAC9B;AACD,KAAI,QAAQ,iBAAiB;AAC3B,SAAO,KAAK,iCAAiC,QAAQ,gBAAgB;AACrE,QAAM,MAAM,GAAG,QAAQ,gBAAgB,QAAQ,EAAE,WAAW,MAAM,CAAC;AACnE,QAAM,UAAU,GAAG,QAAQ,gBAAgB,iBAAiB,KAAK;AACjE,SAAO,QAAQ;;CAGjB,MAAM,OAAO,KAAK,QAAQ,EAAE,UAAU,YAAY,CAAC;AACnD,OAAM,MAAM,GAAG,KAAK,QAAQ,EAAE,WAAW,MAAM,CAAC;AAChD,OAAM,QAAQ,IAAI;EAChB,UAAU,GAAG,KAAK,gBAAgB,KAAK,UAAUA,gBAAS,CAAC;EAC3D,UAAU,GAAG,KAAK,iBAAiB,KAAK;EACxC,MAAM,UAAU,GAAG,KAAK,QAAQ,IAAI,GAAG,QAAQ,SAAS;EACzD,CAAC;AACF,QAAO,KAAK,0BAA0B,KAAK;CAC3C,MAAM,MAAM,QAAQ,eACjB,OAAO,QAAQ,QAAQ,MAAM,EAAE,WAAW,CAAC,KAAK,MAAM,EAAE,QAAQ,CAAC,CACjE,KAAK,IAAI;AACZ,KAAI,QAAQ,SAAS,GAAG;AACtB,SAAO,KAAK,yCAAyC,IAAI;AACzD,QAAM,cAAc,KAAK,KAAK;;AAEhC,QAAO"}
@@ -0,0 +1,8 @@
1
+ import { adapterWrapperJavaScript } from "../javascript/index.mjs";
2
+
3
+ //#region src/adapters/jsx/index.ts
4
+ var jsx_default = (code, metadata) => adapterWrapperJavaScript(code, metadata, "jsx");
5
+
6
+ //#endregion
7
+ export { jsx_default as default };
8
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/adapters/jsx/index.ts"],"sourcesContent":["import { adapterWrapperJavaScript } from \"../javascript\";\n\nexport default (code: string, metadata: string[]) =>\n adapterWrapperJavaScript(code, metadata, \"jsx\");\n"],"mappings":";;;AAEA,mBAAgB,MAAc,aAC5B,yBAAyB,MAAM,UAAU,MAAM"}
@@ -0,0 +1,6 @@
1
+ //#region src/adapters/rust/constants.ts
2
+ const ADAPTER_OPTIONS = { environment: void 0 };
3
+
4
+ //#endregion
5
+ export { ADAPTER_OPTIONS };
6
+ //# sourceMappingURL=constants.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.mjs","names":[],"sources":["../../../src/adapters/rust/constants.ts"],"sourcesContent":["export const ADAPTER_OPTIONS = {\n environment: undefined,\n};\n"],"mappings":";AAAA,MAAa,kBAAkB,EAC7B,aAAa,QACd"}
@@ -0,0 +1,19 @@
1
+ import { getOptions } from "../../remark/utils.mjs";
2
+ import { cleanupEnvironment, execUntilExit } from "../../utils.mjs";
3
+ import { createEnvironment, getImports } from "./utils.mjs";
4
+ import { ADAPTER_OPTIONS } from "./constants.mjs";
5
+
6
+ //#region src/adapters/rust/index.ts
7
+ async function adapterRust(code, options) {
8
+ const environmentPath = await createEnvironment(code, getImports(code), { environmentPath: options.environment });
9
+ try {
10
+ await execUntilExit("cargo run", environmentPath);
11
+ } finally {
12
+ if (!options.environment) await cleanupEnvironment(environmentPath);
13
+ }
14
+ }
15
+ var rust_default = (code, metadata) => adapterRust(code, getOptions(metadata, ADAPTER_OPTIONS));
16
+
17
+ //#endregion
18
+ export { rust_default as default };
19
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/adapters/rust/index.ts"],"sourcesContent":["import { getOptions } from \"@/remark/utils\";\nimport { createEnvironment, getImports } from \"./utils\";\nimport { ADAPTER_OPTIONS } from \"./constants\";\nimport { cleanupEnvironment, execUntilExit } from \"@/utils\";\n\ntype AdapterOptions = {\n environment?: string;\n};\n\nasync function adapterRust(code: string, options: AdapterOptions): Promise<void> {\n const imports = getImports(code);\n const environmentPath = await createEnvironment(code, imports, {\n environmentPath: options.environment,\n });\n\n try {\n await execUntilExit(\"cargo run\", environmentPath);\n } finally {\n if (!options.environment) {\n await cleanupEnvironment(environmentPath);\n }\n }\n}\n\nexport default (code: string, metadata: string[]) =>\n adapterRust(code, getOptions(metadata, ADAPTER_OPTIONS));\n"],"mappings":";;;;;;AASA,eAAe,YAAY,MAAc,SAAwC;CAE/E,MAAM,kBAAkB,MAAM,kBAAkB,MADhC,WAAW,KAAK,EAC+B,EAC7D,iBAAiB,QAAQ,aAC1B,CAAC;AAEF,KAAI;AACF,QAAM,cAAc,aAAa,gBAAgB;WACzC;AACR,MAAI,CAAC,QAAQ,YACX,OAAM,mBAAmB,gBAAgB;;;AAK/C,oBAAgB,MAAc,aAC5B,YAAY,MAAM,WAAW,UAAU,gBAAgB,CAAC"}
@@ -0,0 +1,69 @@
1
+ import { execUntilExit, logger } from "../../utils.mjs";
2
+ import { randomUUID } from "crypto";
3
+ import { tmpdir } from "os";
4
+ import { mkdir, readFile, writeFile } from "fs/promises";
5
+ import { join } from "path";
6
+ import Parser from "tree-sitter";
7
+ import Rust from "tree-sitter-rust";
8
+
9
+ //#region src/adapters/rust/utils.ts
10
+ const BUILTIN_CRATES = new Set([
11
+ "std",
12
+ "core",
13
+ "alloc",
14
+ "crate"
15
+ ]);
16
+ const ERROR_CRATES = new Set([
17
+ "crate",
18
+ "super",
19
+ "self"
20
+ ]);
21
+ function getImports(code) {
22
+ const parser = new Parser();
23
+ parser.setLanguage(Rust);
24
+ const tree = parser.parse(code);
25
+ const imports = [];
26
+ for (const node of tree.rootNode.children) {
27
+ let crateName;
28
+ if (node.type === "use_declaration") {
29
+ const arg = node.child(1);
30
+ if (!arg) continue;
31
+ if (arg.type === "identifier" || arg.type === "scoped_identifier") crateName = arg.text.split("::")[0];
32
+ }
33
+ if (crateName) {
34
+ if (ERROR_CRATES.has(crateName)) throw new Error(`Unsupported import of "${crateName}". Imports of ${Array.from(ERROR_CRATES).map((c) => `"${c}"`).join(", ")} are not supported.`);
35
+ imports.push({
36
+ package: crateName,
37
+ isExternal: !BUILTIN_CRATES.has(crateName)
38
+ });
39
+ }
40
+ }
41
+ return imports;
42
+ }
43
+ function getEntryPath(environmentPath) {
44
+ return `${environmentPath}/src/main.rs`;
45
+ }
46
+ async function createEnvironment(code, imports, options = {}) {
47
+ logger.info("Creating Rust environment with crates", imports.map((i) => i.package));
48
+ if (options.environmentPath) {
49
+ logger.info("Using explicit environment at", options.environmentPath);
50
+ await mkdir(`${options.environmentPath}/src`, { recursive: true });
51
+ await writeFile(getEntryPath(options.environmentPath), code);
52
+ return options.environmentPath;
53
+ }
54
+ const manifest = await readFile(new URL("../../../assets/Cargo.toml", import.meta.url), "utf-8");
55
+ const path = join(tmpdir(), "docval", randomUUID());
56
+ await mkdir(`${path}/src`, { recursive: true });
57
+ await Promise.all([writeFile(`${path}/Cargo.toml`, manifest), writeFile(`${path}/src/main.rs`, code)]);
58
+ if (imports.length > 0) {
59
+ const crates = imports.filter((i) => i.isExternal).map((i) => i.package);
60
+ logger.info("Installing crates", crates);
61
+ await execUntilExit(`cargo add ${crates.join(" ")}`, path);
62
+ }
63
+ logger.info("Created Rust environment at", path);
64
+ return path;
65
+ }
66
+
67
+ //#endregion
68
+ export { createEnvironment, getImports };
69
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/adapters/rust/utils.ts"],"sourcesContent":["import Parser from \"tree-sitter\";\nimport Rust from \"tree-sitter-rust\";\nimport { tmpdir } from \"os\";\nimport { mkdir, readFile, writeFile } from \"fs/promises\";\nimport { join } from \"path\";\nimport { randomUUID } from \"crypto\";\nimport { execUntilExit, logger } from \"@/utils\";\n\nconst BUILTIN_CRATES = new Set([\"std\", \"core\", \"alloc\", \"crate\"]);\nconst ERROR_CRATES = new Set([\"crate\", \"super\", \"self\"]);\n\ntype Import = {\n isExternal: boolean;\n package: string;\n};\n\nfunction getImports(code: string): Import[] {\n const parser = new Parser();\n parser.setLanguage(Rust as unknown as Parser.Language);\n const tree = parser.parse(code);\n const imports: Import[] = [];\n\n for (const node of tree.rootNode.children) {\n let crateName: string | undefined;\n\n if (node.type === \"use_declaration\") {\n const arg = node.child(1);\n if (!arg) continue;\n if (arg.type === \"identifier\" || arg.type === \"scoped_identifier\") {\n crateName = arg.text.split(\"::\")[0];\n }\n }\n\n if (crateName) {\n if (ERROR_CRATES.has(crateName)) {\n throw new Error(\n `Unsupported import of \"${crateName}\". ` +\n `Imports of ${Array.from(ERROR_CRATES)\n .map((c) => `\"${c}\"`)\n .join(\", \")} are not supported.`,\n );\n }\n\n imports.push({\n package: crateName,\n isExternal: !BUILTIN_CRATES.has(crateName),\n });\n }\n }\n\n return imports;\n}\n\ntype EnvironmentOptions = {\n environmentPath?: string;\n};\n\nfunction getEntryPath(environmentPath: string) {\n return `${environmentPath}/src/main.rs`;\n}\n\nasync function createEnvironment(\n code: string,\n imports: Import[],\n options: EnvironmentOptions = {},\n) {\n logger.info(\n \"Creating Rust environment with crates\",\n imports.map((i) => i.package),\n );\n\n if (options.environmentPath) {\n logger.info(\"Using explicit environment at\", options.environmentPath);\n await mkdir(`${options.environmentPath}/src`, { recursive: true });\n await writeFile(getEntryPath(options.environmentPath), code);\n return options.environmentPath;\n }\n\n const manifest = await readFile(new URL(\"../../../assets/Cargo.toml\", import.meta.url), \"utf-8\");\n const path = join(tmpdir(), \"docval\", randomUUID());\n await mkdir(`${path}/src`, { recursive: true });\n await Promise.all([\n writeFile(`${path}/Cargo.toml`, manifest),\n writeFile(`${path}/src/main.rs`, code),\n ]);\n if (imports.length > 0) {\n const crates = imports.filter((i) => i.isExternal).map((i) => i.package);\n logger.info(\"Installing crates\", crates);\n await execUntilExit(`cargo add ${crates.join(\" \")}`, path);\n }\n logger.info(\"Created Rust environment at\", path);\n return path;\n}\n\nexport { getImports, createEnvironment, getEntryPath };\nexport type { Import };\n"],"mappings":";;;;;;;;;AAQA,MAAM,iBAAiB,IAAI,IAAI;CAAC;CAAO;CAAQ;CAAS;CAAQ,CAAC;AACjE,MAAM,eAAe,IAAI,IAAI;CAAC;CAAS;CAAS;CAAO,CAAC;AAOxD,SAAS,WAAW,MAAwB;CAC1C,MAAM,SAAS,IAAI,QAAQ;AAC3B,QAAO,YAAY,KAAmC;CACtD,MAAM,OAAO,OAAO,MAAM,KAAK;CAC/B,MAAM,UAAoB,EAAE;AAE5B,MAAK,MAAM,QAAQ,KAAK,SAAS,UAAU;EACzC,IAAI;AAEJ,MAAI,KAAK,SAAS,mBAAmB;GACnC,MAAM,MAAM,KAAK,MAAM,EAAE;AACzB,OAAI,CAAC,IAAK;AACV,OAAI,IAAI,SAAS,gBAAgB,IAAI,SAAS,oBAC5C,aAAY,IAAI,KAAK,MAAM,KAAK,CAAC;;AAIrC,MAAI,WAAW;AACb,OAAI,aAAa,IAAI,UAAU,CAC7B,OAAM,IAAI,MACR,0BAA0B,UAAU,gBACpB,MAAM,KAAK,aAAa,CACnC,KAAK,MAAM,IAAI,EAAE,GAAG,CACpB,KAAK,KAAK,CAAC,qBACjB;AAGH,WAAQ,KAAK;IACX,SAAS;IACT,YAAY,CAAC,eAAe,IAAI,UAAU;IAC3C,CAAC;;;AAIN,QAAO;;AAOT,SAAS,aAAa,iBAAyB;AAC7C,QAAO,GAAG,gBAAgB;;AAG5B,eAAe,kBACb,MACA,SACA,UAA8B,EAAE,EAChC;AACA,QAAO,KACL,yCACA,QAAQ,KAAK,MAAM,EAAE,QAAQ,CAC9B;AAED,KAAI,QAAQ,iBAAiB;AAC3B,SAAO,KAAK,iCAAiC,QAAQ,gBAAgB;AACrE,QAAM,MAAM,GAAG,QAAQ,gBAAgB,OAAO,EAAE,WAAW,MAAM,CAAC;AAClE,QAAM,UAAU,aAAa,QAAQ,gBAAgB,EAAE,KAAK;AAC5D,SAAO,QAAQ;;CAGjB,MAAM,WAAW,MAAM,SAAS,IAAI,IAAI,8BAA8B,OAAO,KAAK,IAAI,EAAE,QAAQ;CAChG,MAAM,OAAO,KAAK,QAAQ,EAAE,UAAU,YAAY,CAAC;AACnD,OAAM,MAAM,GAAG,KAAK,OAAO,EAAE,WAAW,MAAM,CAAC;AAC/C,OAAM,QAAQ,IAAI,CAChB,UAAU,GAAG,KAAK,cAAc,SAAS,EACzC,UAAU,GAAG,KAAK,eAAe,KAAK,CACvC,CAAC;AACF,KAAI,QAAQ,SAAS,GAAG;EACtB,MAAM,SAAS,QAAQ,QAAQ,MAAM,EAAE,WAAW,CAAC,KAAK,MAAM,EAAE,QAAQ;AACxE,SAAO,KAAK,qBAAqB,OAAO;AACxC,QAAM,cAAc,aAAa,OAAO,KAAK,IAAI,IAAI,KAAK;;AAE5D,QAAO,KAAK,+BAA+B,KAAK;AAChD,QAAO"}
@@ -0,0 +1,8 @@
1
+ import { adapterWrapperJavaScript } from "../javascript/index.mjs";
2
+
3
+ //#region src/adapters/tsx/index.ts
4
+ var tsx_default = (code, metadata) => adapterWrapperJavaScript(code, metadata, "tsx");
5
+
6
+ //#endregion
7
+ export { tsx_default as default };
8
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/adapters/tsx/index.ts"],"sourcesContent":["import { adapterWrapperJavaScript } from \"../javascript\";\n\nexport default (code: string, metadata: string[]) =>\n adapterWrapperJavaScript(code, metadata, \"tsx\");\n"],"mappings":";;;AAEA,mBAAgB,MAAc,aAC5B,yBAAyB,MAAM,UAAU,MAAM"}
@@ -0,0 +1,8 @@
1
+ import { adapterWrapperJavaScript } from "../javascript/index.mjs";
2
+
3
+ //#region src/adapters/typescript/index.ts
4
+ var typescript_default = (code, metadata) => adapterWrapperJavaScript(code, metadata, "ts");
5
+
6
+ //#endregion
7
+ export { typescript_default as default };
8
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/adapters/typescript/index.ts"],"sourcesContent":["import { adapterWrapperJavaScript } from \"../javascript\";\n\nexport default (code: string, metadata: string[]) => adapterWrapperJavaScript(code, metadata, \"ts\");\n"],"mappings":";;;AAEA,0BAAgB,MAAc,aAAuB,yBAAyB,MAAM,UAAU,KAAK"}
@@ -0,0 +1,11 @@
1
+ //#region assets/package.json
2
+ var package_default = {
3
+ name: "docval-env",
4
+ version: "0.0.0",
5
+ "private": true,
6
+ type: "module"
7
+ };
8
+
9
+ //#endregion
10
+ export { package_default as default };
11
+ //# sourceMappingURL=package.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.mjs","names":[],"sources":["../../assets/package.json"],"sourcesContent":[""],"mappings":""}
@@ -0,0 +1,2 @@
1
+ import { remarkDocval } from "./remark/plugin.mjs";
2
+ export { remarkDocval as remarkDocVal };
package/dist/main.mjs ADDED
@@ -0,0 +1,3 @@
1
+ import remarkDocval from "./remark/plugin.mjs";
2
+
3
+ export { remarkDocval as remarkDocVal };
@@ -0,0 +1,12 @@
1
+ import { Root } from "mdast";
2
+
3
+ //#region src/remark/plugin.d.ts
4
+ type DocValOptions = {
5
+ include?: boolean;
6
+ };
7
+ declare function remarkDocval({
8
+ include
9
+ }?: DocValOptions): (tree: Root) => Promise<Root>;
10
+ //#endregion
11
+ export { remarkDocval };
12
+ //# sourceMappingURL=plugin.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.mts","names":[],"sources":["../../src/remark/plugin.ts"],"mappings":";;;KAGY,aAAA;EACV,OAAA;AAAA;AAAA,iBAGsB,YAAA,CAAA;EAAe;AAAA,IAAW,aAAA,IAAkB,IAAA,EACrC,IAAA,KAAI,OAAA,CAAA,IAAA"}
@@ -0,0 +1,25 @@
1
+ import map from "../adapters/index.mjs";
2
+
3
+ //#region src/remark/plugin.ts
4
+ function remarkDocval({ include } = {}) {
5
+ return async function(tree) {
6
+ const promises = [];
7
+ tree.children.forEach((node) => {
8
+ if (node.type === "code" && node.lang && node.lang in map) {
9
+ const metadata = node.meta?.split(" ") ?? [];
10
+ const docValIndex = metadata.findIndex((item) => item === "docval");
11
+ if (include || docValIndex !== -1) promises.push(map[node.lang](node.value, metadata));
12
+ } else if (node.type === "code" && process.env.DOCVAL_TEST_NO_SKIP === "true") throw new Error(`Skipped code block: ${JSON.stringify(node)}`);
13
+ });
14
+ const res = await Promise.allSettled(promises);
15
+ if (res.some((r) => r.status === "rejected")) throw JSON.stringify({
16
+ message: "One or more code blocks failed validation.",
17
+ originalResults: res
18
+ });
19
+ return tree;
20
+ };
21
+ }
22
+
23
+ //#endregion
24
+ export { remarkDocval as default };
25
+ //# sourceMappingURL=plugin.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.mjs","names":["adapters"],"sources":["../../src/remark/plugin.ts"],"sourcesContent":["import adapters from \"@/adapters\";\nimport type { Root } from \"mdast\";\n\nexport type DocValOptions = {\n include?: boolean;\n};\n\nexport default function remarkDocval({ include }: DocValOptions = {}) {\n return async function (tree: Root) {\n const promises: Promise<void>[] = [];\n tree.children.forEach((node) => {\n if (node.type === \"code\" && node.lang && node.lang in adapters) {\n const metadata = node.meta?.split(\" \") ?? [];\n const docValIndex = metadata.findIndex((item) => item === \"docval\");\n if (include || docValIndex !== -1) {\n promises.push(adapters[node.lang as keyof typeof adapters](node.value, metadata));\n }\n } else if (node.type === \"code\" && process.env.DOCVAL_TEST_NO_SKIP === \"true\") {\n throw new Error(`Skipped code block: ${JSON.stringify(node)}`);\n }\n });\n const res = await Promise.allSettled(promises);\n if (res.some((r) => r.status === \"rejected\")) {\n throw JSON.stringify({\n message: \"One or more code blocks failed validation.\",\n originalResults: res,\n });\n }\n\n return tree;\n };\n}\n"],"mappings":";;;AAOA,SAAwB,aAAa,EAAE,YAA2B,EAAE,EAAE;AACpE,QAAO,eAAgB,MAAY;EACjC,MAAM,WAA4B,EAAE;AACpC,OAAK,SAAS,SAAS,SAAS;AAC9B,OAAI,KAAK,SAAS,UAAU,KAAK,QAAQ,KAAK,QAAQA,KAAU;IAC9D,MAAM,WAAW,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE;IAC5C,MAAM,cAAc,SAAS,WAAW,SAAS,SAAS,SAAS;AACnE,QAAI,WAAW,gBAAgB,GAC7B,UAAS,KAAKA,IAAS,KAAK,MAA+B,KAAK,OAAO,SAAS,CAAC;cAE1E,KAAK,SAAS,UAAU,QAAQ,IAAI,wBAAwB,OACrE,OAAM,IAAI,MAAM,uBAAuB,KAAK,UAAU,KAAK,GAAG;IAEhE;EACF,MAAM,MAAM,MAAM,QAAQ,WAAW,SAAS;AAC9C,MAAI,IAAI,MAAM,MAAM,EAAE,WAAW,WAAW,CAC1C,OAAM,KAAK,UAAU;GACnB,SAAS;GACT,iBAAiB;GAClB,CAAC;AAGJ,SAAO"}
@@ -0,0 +1,26 @@
1
+ import { hash } from "crypto";
2
+
3
+ //#region src/remark/utils.ts
4
+ function getFilename(_metadata, code) {
5
+ return hash("sha1", code);
6
+ }
7
+ function getOptions(metadata, defaultOptions) {
8
+ let options = { ...defaultOptions };
9
+ metadata.forEach((item) => {
10
+ const pairs = [];
11
+ const [key, ...rest] = item.split("=");
12
+ const value = rest.join("=").replace(/^["']|["']$/g, "");
13
+ if (!key || !value) return;
14
+ pairs.push([key, value.includes(",") ? value.split(",") : value]);
15
+ Object.fromEntries(pairs);
16
+ options = {
17
+ ...options,
18
+ ...Object.fromEntries(pairs)
19
+ };
20
+ });
21
+ return options;
22
+ }
23
+
24
+ //#endregion
25
+ export { getFilename, getOptions };
26
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.mjs","names":[],"sources":["../../src/remark/utils.ts"],"sourcesContent":["import { hash } from \"crypto\";\n\nfunction getFilename(_metadata: string[], code: string): string {\n // TODO: Use filename metadata to provide better error messages pointing to the exact codeblock.\n // const filenameIndex = metadata.findIndex((item) => item.startsWith(\"filename=\"));\n // if (filenameIndex !== -1) {\n // return metadata[filenameIndex].split(\"=\")[1];\n // }\n return hash(\"sha1\", code);\n}\n\nexport function getOptions<T extends Record<string, string | string[] | undefined>>(\n metadata: string[],\n defaultOptions: T,\n): T {\n let options = { ...defaultOptions };\n metadata.forEach((item) => {\n const pairs: [string, string | string[]][] = [];\n const [key, ...rest] = item.split(\"=\");\n const value = rest.join(\"=\").replace(/^[\"']|[\"']$/g, \"\");\n if (!key || !value) return;\n pairs.push([key, value.includes(\",\") ? value.split(\",\") : value]);\n Object.fromEntries(pairs);\n options = { ...options, ...Object.fromEntries(pairs) };\n });\n return options as T;\n}\n\nexport { getFilename };\n"],"mappings":";;;AAEA,SAAS,YAAY,WAAqB,MAAsB;AAM9D,QAAO,KAAK,QAAQ,KAAK;;AAG3B,SAAgB,WACd,UACA,gBACG;CACH,IAAI,UAAU,EAAE,GAAG,gBAAgB;AACnC,UAAS,SAAS,SAAS;EACzB,MAAM,QAAuC,EAAE;EAC/C,MAAM,CAAC,KAAK,GAAG,QAAQ,KAAK,MAAM,IAAI;EACtC,MAAM,QAAQ,KAAK,KAAK,IAAI,CAAC,QAAQ,gBAAgB,GAAG;AACxD,MAAI,CAAC,OAAO,CAAC,MAAO;AACpB,QAAM,KAAK,CAAC,KAAK,MAAM,SAAS,IAAI,GAAG,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC;AACjE,SAAO,YAAY,MAAM;AACzB,YAAU;GAAE,GAAG;GAAS,GAAG,OAAO,YAAY,MAAM;GAAE;GACtD;AACF,QAAO"}
package/dist/utils.mjs ADDED
@@ -0,0 +1,31 @@
1
+ import { spawn } from "child_process";
2
+ import consola from "consola";
3
+
4
+ //#region src/utils.ts
5
+ const logger = consola.withTag("Borrow").withTag("DocVal");
6
+ function execUntilExit(command, cwd) {
7
+ let error = "";
8
+ return new Promise((resolve, reject) => {
9
+ const process = spawn(command, {
10
+ cwd,
11
+ shell: true
12
+ });
13
+ process.stdout.on("data", (data) => {
14
+ logger.debug(data.toString());
15
+ });
16
+ process.stderr.on("data", (data) => {
17
+ error += data;
18
+ });
19
+ process.on("close", (code) => {
20
+ if (code === 0) resolve();
21
+ else reject(`Command failed with exit code ${code}\n${error})`);
22
+ });
23
+ });
24
+ }
25
+ async function cleanupEnvironment(path) {
26
+ await execUntilExit(`rm -rf ${path}`, process.cwd());
27
+ }
28
+
29
+ //#endregion
30
+ export { cleanupEnvironment, execUntilExit, logger };
31
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.mjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import { spawn } from \"child_process\";\nimport consola from \"consola\";\n\nconst logger = consola.withTag(\"Borrow\").withTag(\"DocVal\");\n\nfunction execUntilExit(command: string, cwd: string): Promise<void> {\n let error = \"\";\n return new Promise((resolve, reject) => {\n const process = spawn(command, { cwd, shell: true });\n\n process.stdout.on(\"data\", (data) => {\n logger.debug(data.toString());\n });\n\n process.stderr.on(\"data\", (data) => {\n error += data;\n });\n\n process.on(\"close\", (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(`Command failed with exit code ${code}\\n${error})`);\n }\n });\n });\n}\n\nasync function cleanupEnvironment(path: string) {\n await execUntilExit(`rm -rf ${path}`, process.cwd());\n}\n\nexport { execUntilExit, cleanupEnvironment, logger };\n"],"mappings":";;;;AAGA,MAAM,SAAS,QAAQ,QAAQ,SAAS,CAAC,QAAQ,SAAS;AAE1D,SAAS,cAAc,SAAiB,KAA4B;CAClE,IAAI,QAAQ;AACZ,QAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,UAAU,MAAM,SAAS;GAAE;GAAK,OAAO;GAAM,CAAC;AAEpD,UAAQ,OAAO,GAAG,SAAS,SAAS;AAClC,UAAO,MAAM,KAAK,UAAU,CAAC;IAC7B;AAEF,UAAQ,OAAO,GAAG,SAAS,SAAS;AAClC,YAAS;IACT;AAEF,UAAQ,GAAG,UAAU,SAAS;AAC5B,OAAI,SAAS,EACX,UAAS;OAET,QAAO,iCAAiC,KAAK,IAAI,MAAM,GAAG;IAE5D;GACF;;AAGJ,eAAe,mBAAmB,MAAc;AAC9C,OAAM,cAAc,UAAU,QAAQ,QAAQ,KAAK,CAAC"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@borrowdev/docval",
3
+ "version": "0.1.0",
4
+ "description": "Validate your documentation codeblocks at build-time",
5
+ "homepage": "https://borrow.dev",
6
+ "license": "MIT",
7
+ "author": "Lorenzo Bloedow <me@lorenzobloedow.com>",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/borrowdev/borrow.git"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "package.json",
15
+ "README.md"
16
+ ],
17
+ "type": "module",
18
+ "exports": {
19
+ ".": "./dist/main.mjs",
20
+ "./package.json": "./package.json"
21
+ },
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "dependencies": {
26
+ "consola": "^3.4.2",
27
+ "oxc-parser": "^0.123.0",
28
+ "tree-sitter": "^0.25.0",
29
+ "tree-sitter-rust": "^0.24.0",
30
+ "typescript": "~6.0.2"
31
+ },
32
+ "devDependencies": {
33
+ "@types/mdast": "^4.0.4",
34
+ "@types/node": "^25.5.0",
35
+ "@typescript/native-preview": "7.0.0-dev.20260401.1",
36
+ "vite": "npm:@voidzero-dev/vite-plus-core@^0.1.15",
37
+ "vite-plus": "latest",
38
+ "vitest": "npm:@voidzero-dev/vite-plus-test@^0.1.15"
39
+ },
40
+ "peerDependencies": {
41
+ "mdast": "^3.0.0",
42
+ "remark": "^15.0.1"
43
+ },
44
+ "scripts": {
45
+ "build": "vp pack",
46
+ "dev": "vp pack --watch",
47
+ "test": "vp test",
48
+ "check": "vp check"
49
+ }
50
+ }