@vellum-docs/engine-nunjucks 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.
@@ -0,0 +1,25 @@
1
+ import { TemplateContext, TemplateEngine } from "@vellum-docs/core";
2
+
3
+ //#region src/engine.d.ts
4
+ interface NunjucksEngineOptions {
5
+ /** Extra directories to resolve `{% include %}` / `{% extends %}` from. */
6
+ searchPaths?: string[];
7
+ /** Additional Nunjucks globals (merged with built-ins). */
8
+ globals?: Record<string, unknown>;
9
+ /** Additional Nunjucks filters (merged with built-ins). */
10
+ filters?: Record<string, (...args: unknown[]) => unknown>;
11
+ /** Override the source extension (default `.vel`). */
12
+ sourceExtension?: string;
13
+ }
14
+ declare class NunjucksEngine implements TemplateEngine {
15
+ readonly name = "nunjucks";
16
+ readonly sourceExtension: string;
17
+ private readonly searchPaths;
18
+ private readonly extraGlobals;
19
+ private readonly extraFilters;
20
+ constructor(opts?: NunjucksEngineOptions);
21
+ render(source: string, ctx: TemplateContext): Promise<string>;
22
+ }
23
+ //#endregion
24
+ export { NunjucksEngine, type NunjucksEngineOptions };
25
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/engine.ts"],"mappings":";;;UAUiB,qBAAA;;EAEf,WAAA;EAFoC;EAKpC,OAAA,GAAU,MAAA;EAGM;EAAhB,OAAA,GAAU,MAAA,aAAmB,IAAA;EAH7B;EAMA,eAAA;AAAA;AAAA,cAMW,cAAA,YAA0B,cAAA;EAAA,SAC5B,IAAA;EAAA,SACA,eAAA;EAAA,iBAEQ,WAAA;EAAA,iBACA,YAAA;EAAA,iBACA,YAAA;cAEL,IAAA,GAAM,qBAAA;EAOZ,MAAA,CAAO,MAAA,UAAgB,GAAA,EAAK,eAAA,GAAkB,OAAA;AAAA"}
package/dist/index.mjs ADDED
@@ -0,0 +1,85 @@
1
+ import { dirname, resolve } from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import nunjucks from "nunjucks";
4
+ //#region src/filters.ts
5
+ function buildFilters(ctx) {
6
+ const resolve = (id) => ctx.index.symbol(id);
7
+ const renderCtx = {
8
+ profile: ctx.profile,
9
+ resolve
10
+ };
11
+ return {
12
+ mdxLink: (sym) => ctx.profile.link(sym, renderCtx),
13
+ mdxSignature: (sym) => ctx.profile.signature(sym, renderCtx),
14
+ typeRef: (sym) => ctx.profile.typeRef(sym, renderCtx),
15
+ typeCard: (sym) => ctx.profile.typeCard(sym, renderCtx),
16
+ typeString: (ts) => ctx.profile.typeString(ts, renderCtx),
17
+ example: (sym, n = 0) => {
18
+ const ex = sym.doc.examples[n];
19
+ if (!ex) return "";
20
+ return ex.code;
21
+ },
22
+ summary: (target) => {
23
+ if (!target) return "";
24
+ if ("doc" in target) return target.doc.summary;
25
+ if ("summary" in target) return target.summary;
26
+ return "";
27
+ }
28
+ };
29
+ }
30
+ //#endregion
31
+ //#region src/globals.ts
32
+ function buildGlobals(ctx) {
33
+ return {
34
+ symbol: (id) => ctx.index.symbol(id),
35
+ symbols: (query = {}) => ctx.index.symbols(query),
36
+ module: (path) => ctx.index.module(path)
37
+ };
38
+ }
39
+ //#endregion
40
+ //#region src/engine.ts
41
+ const builtinPartialsDir = resolve(dirname(fileURLToPath(import.meta.url)), "./partials");
42
+ var NunjucksEngine = class {
43
+ name = "nunjucks";
44
+ sourceExtension;
45
+ searchPaths;
46
+ extraGlobals;
47
+ extraFilters;
48
+ constructor(opts = {}) {
49
+ this.sourceExtension = opts.sourceExtension ?? ".vel";
50
+ this.searchPaths = [builtinPartialsDir, ...opts.searchPaths ?? []];
51
+ this.extraGlobals = opts.globals ?? {};
52
+ this.extraFilters = opts.filters ?? {};
53
+ }
54
+ async render(source, ctx) {
55
+ const env = new nunjucks.Environment(new nunjucks.FileSystemLoader(this.searchPaths, {
56
+ noCache: true,
57
+ watch: false
58
+ }), {
59
+ autoescape: false,
60
+ throwOnUndefined: false,
61
+ trimBlocks: false,
62
+ lstripBlocks: false
63
+ });
64
+ const originalGetTemplate = env.getTemplate.bind(env);
65
+ env.getTemplate = function(name, ...rest) {
66
+ return originalGetTemplate(name.startsWith("@vellum-docs/partials/") ? name.slice(22) : name, ...rest);
67
+ };
68
+ const globals = buildGlobals(ctx);
69
+ for (const [k, v] of Object.entries(globals)) env.addGlobal(k, v);
70
+ for (const [k, v] of Object.entries(this.extraGlobals)) env.addGlobal(k, v);
71
+ const filters = buildFilters(ctx);
72
+ for (const [k, v] of Object.entries(filters)) env.addFilter(k, v);
73
+ for (const [k, v] of Object.entries(this.extraFilters)) env.addFilter(k, v);
74
+ return new Promise((resolvePromise, reject) => {
75
+ env.renderString(source, {}, (err, result) => {
76
+ if (err) reject(err);
77
+ else resolvePromise(result ?? "");
78
+ });
79
+ });
80
+ }
81
+ };
82
+ //#endregion
83
+ export { NunjucksEngine };
84
+
85
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/filters.ts","../src/globals.ts","../src/engine.ts"],"sourcesContent":["import type { Symbol, TemplateContext, TypeString } from '@vellum-docs/core'\n\nexport function buildFilters(ctx: TemplateContext) {\n const resolve = (id: string) => ctx.index.symbol(id)\n const renderCtx = { profile: ctx.profile, resolve }\n\n return {\n mdxLink: (sym: Symbol) => ctx.profile.link(sym, renderCtx),\n mdxSignature: (sym: Symbol) => ctx.profile.signature(sym, renderCtx),\n typeRef: (sym: Symbol) => ctx.profile.typeRef(sym, renderCtx),\n typeCard: (sym: Symbol) => ctx.profile.typeCard(sym, renderCtx),\n typeString: (ts: TypeString) => ctx.profile.typeString(ts, renderCtx),\n\n /** Return the nth @example code block, or empty string. */\n example: (sym: Symbol, n: number = 0) => {\n const ex = sym.doc.examples[n]\n if (!ex)\n return ''\n return ex.code\n },\n\n /** Just the summary from a DocComment (or a Symbol). */\n summary: (target: Symbol | { summary: string } | null | undefined) => {\n if (!target)\n return ''\n if ('doc' in target)\n return target.doc.summary\n if ('summary' in target)\n return target.summary\n return ''\n },\n }\n}\n","import type { Module, Symbol, SymbolId, SymbolQuery, TemplateContext } from '@vellum-docs/core'\n\nexport interface GlobalFunctions {\n symbol: (id: SymbolId) => Symbol | null\n symbols: (query?: SymbolQuery) => Symbol[]\n module: (path: string) => Module | null\n}\n\nexport function buildGlobals(ctx: TemplateContext): GlobalFunctions {\n return {\n symbol: id => ctx.index.symbol(id),\n symbols: (query = {}) => ctx.index.symbols(query),\n module: path => ctx.index.module(path),\n }\n}\n","import type { TemplateContext, TemplateEngine } from '@vellum-docs/core'\nimport { dirname, resolve } from 'node:path'\n\nimport { fileURLToPath } from 'node:url'\n\nimport nunjucks from 'nunjucks'\n\nimport { buildFilters } from './filters'\nimport { buildGlobals } from './globals'\n\nexport interface NunjucksEngineOptions {\n /** Extra directories to resolve `{% include %}` / `{% extends %}` from. */\n searchPaths?: string[]\n\n /** Additional Nunjucks globals (merged with built-ins). */\n globals?: Record<string, unknown>\n\n /** Additional Nunjucks filters (merged with built-ins). */\n filters?: Record<string, (...args: unknown[]) => unknown>\n\n /** Override the source extension (default `.vel`). */\n sourceExtension?: string\n}\n\nconst here = dirname(fileURLToPath(import.meta.url))\nconst builtinPartialsDir = resolve(here, './partials')\n\nexport class NunjucksEngine implements TemplateEngine {\n readonly name = 'nunjucks'\n readonly sourceExtension: string\n\n private readonly searchPaths: string[]\n private readonly extraGlobals: Record<string, unknown>\n private readonly extraFilters: Record<string, (...args: unknown[]) => unknown>\n\n constructor(opts: NunjucksEngineOptions = {}) {\n this.sourceExtension = opts.sourceExtension ?? '.vel'\n this.searchPaths = [builtinPartialsDir, ...(opts.searchPaths ?? [])]\n this.extraGlobals = opts.globals ?? {}\n this.extraFilters = opts.filters ?? {}\n }\n\n async render(source: string, ctx: TemplateContext): Promise<string> {\n const env = new nunjucks.Environment(\n new nunjucks.FileSystemLoader(this.searchPaths, {\n noCache: true,\n watch: false,\n }),\n { autoescape: false, throwOnUndefined: false, trimBlocks: false, lstripBlocks: false },\n )\n\n // Path alias: `{% include \"@vellum-docs/partials/...\" %}` → built-in partials dir.\n type GetTemplateFn = (name: string, ...rest: unknown[]) => unknown\n const originalGetTemplate = (env as unknown as { getTemplate: GetTemplateFn }).getTemplate.bind(env);\n (env as unknown as { getTemplate: GetTemplateFn }).getTemplate = function (\n name: string,\n ...rest: unknown[]\n ) {\n const resolved = name.startsWith('@vellum-docs/partials/')\n ? name.slice('@vellum-docs/partials/'.length)\n : name\n return originalGetTemplate(resolved, ...rest)\n }\n\n const globals = buildGlobals(ctx)\n for (const [k, v] of Object.entries(globals)) env.addGlobal(k, v as never)\n for (const [k, v] of Object.entries(this.extraGlobals)) env.addGlobal(k, v as never)\n\n const filters = buildFilters(ctx)\n for (const [k, v] of Object.entries(filters)) env.addFilter(k, v)\n for (const [k, v] of Object.entries(this.extraFilters)) env.addFilter(k, v)\n\n return new Promise<string>((resolvePromise, reject) => {\n env.renderString(source, {}, (err, result) => {\n if (err)\n reject(err)\n else resolvePromise(result ?? '')\n })\n })\n }\n}\n"],"mappings":";;;;AAEA,SAAgB,aAAa,KAAsB;CACjD,MAAM,WAAW,OAAe,IAAI,MAAM,OAAO,GAAG;CACpD,MAAM,YAAY;EAAE,SAAS,IAAI;EAAS;EAAS;AAEnD,QAAO;EACL,UAAU,QAAgB,IAAI,QAAQ,KAAK,KAAK,UAAU;EAC1D,eAAe,QAAgB,IAAI,QAAQ,UAAU,KAAK,UAAU;EACpE,UAAU,QAAgB,IAAI,QAAQ,QAAQ,KAAK,UAAU;EAC7D,WAAW,QAAgB,IAAI,QAAQ,SAAS,KAAK,UAAU;EAC/D,aAAa,OAAmB,IAAI,QAAQ,WAAW,IAAI,UAAU;EAGrE,UAAU,KAAa,IAAY,MAAM;GACvC,MAAM,KAAK,IAAI,IAAI,SAAS;AAC5B,OAAI,CAAC,GACH,QAAO;AACT,UAAO,GAAG;;EAIZ,UAAU,WAA4D;AACpE,OAAI,CAAC,OACH,QAAO;AACT,OAAI,SAAS,OACX,QAAO,OAAO,IAAI;AACpB,OAAI,aAAa,OACf,QAAO,OAAO;AAChB,UAAO;;EAEV;;;;ACvBH,SAAgB,aAAa,KAAuC;AAClE,QAAO;EACL,SAAQ,OAAM,IAAI,MAAM,OAAO,GAAG;EAClC,UAAU,QAAQ,EAAE,KAAK,IAAI,MAAM,QAAQ,MAAM;EACjD,SAAQ,SAAQ,IAAI,MAAM,OAAO,KAAK;EACvC;;;;ACYH,MAAM,qBAAqB,QADd,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC,EACX,aAAa;AAEtD,IAAa,iBAAb,MAAsD;CACpD,OAAgB;CAChB;CAEA;CACA;CACA;CAEA,YAAY,OAA8B,EAAE,EAAE;AAC5C,OAAK,kBAAkB,KAAK,mBAAmB;AAC/C,OAAK,cAAc,CAAC,oBAAoB,GAAI,KAAK,eAAe,EAAE,CAAE;AACpE,OAAK,eAAe,KAAK,WAAW,EAAE;AACtC,OAAK,eAAe,KAAK,WAAW,EAAE;;CAGxC,MAAM,OAAO,QAAgB,KAAuC;EAClE,MAAM,MAAM,IAAI,SAAS,YACvB,IAAI,SAAS,iBAAiB,KAAK,aAAa;GAC9C,SAAS;GACT,OAAO;GACR,CAAC,EACF;GAAE,YAAY;GAAO,kBAAkB;GAAO,YAAY;GAAO,cAAc;GAAO,CACvF;EAID,MAAM,sBAAuB,IAAkD,YAAY,KAAK,IAAI;AACnG,MAAkD,cAAc,SAC/D,MACA,GAAG,MACH;AAIA,UAAO,oBAHU,KAAK,WAAW,yBAAyB,GACtD,KAAK,MAAM,GAAgC,GAC3C,MACiC,GAAG,KAAK;;EAG/C,MAAM,UAAU,aAAa,IAAI;AACjC,OAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,QAAQ,CAAE,KAAI,UAAU,GAAG,EAAW;AAC1E,OAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,KAAK,aAAa,CAAE,KAAI,UAAU,GAAG,EAAW;EAEpF,MAAM,UAAU,aAAa,IAAI;AACjC,OAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,QAAQ,CAAE,KAAI,UAAU,GAAG,EAAE;AACjE,OAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,KAAK,aAAa,CAAE,KAAI,UAAU,GAAG,EAAE;AAE3E,SAAO,IAAI,SAAiB,gBAAgB,WAAW;AACrD,OAAI,aAAa,QAAQ,EAAE,GAAG,KAAK,WAAW;AAC5C,QAAI,IACF,QAAO,IAAI;QACR,gBAAe,UAAU,GAAG;KACjC;IACF"}
@@ -0,0 +1,6 @@
1
+ {%- set consts = symbols({ module: module, kind: "const" }) -%}
2
+ | Name | Value | Description |
3
+ | ---- | ----- | ----------- |
4
+ {%- for c in consts %}
5
+ | `{{ c.name }}` | `{{ c.value.text if c.value else "" }}` | {{ c.doc.summary }} |
6
+ {%- endfor %}
@@ -0,0 +1,17 @@
1
+ {%- if sym -%}
2
+ {{ sym | mdxSignature | safe }}
3
+
4
+ {%- if sym.parameters and sym.parameters.length > 0 %}
5
+
6
+ **Parameters**
7
+
8
+ {%- for p in sym.parameters %}
9
+ - **`{{ p.name }}`**{% if p.optional %} _(optional)_{% endif %} — `{{ p.type.text }}`{% if p.doc %} — {{ p.doc }}{% endif %}
10
+ {%- endfor %}
11
+ {%- endif %}
12
+
13
+ {%- if sym.returnType and sym.returnType.text %}
14
+
15
+ **Returns** — `{{ sym.returnType.text }}`{% if sym.doc.returns %} — {{ sym.doc.returns }}{% endif %}
16
+ {%- endif %}
17
+ {%- endif %}
@@ -0,0 +1,23 @@
1
+ {%- if sym -%}
2
+ ### {{ sym.name }}
3
+
4
+ {{ sym.doc.summary }}
5
+
6
+ {{ sym | mdxSignature | safe }}
7
+
8
+ {%- if sym.doc.description %}
9
+
10
+ {{ sym.doc.description }}
11
+ {%- endif %}
12
+
13
+ {%- if sym.doc.examples.length > 0 %}
14
+
15
+ **Examples**
16
+
17
+ {%- for ex in sym.doc.examples %}
18
+ ```{{ ex.lang }}
19
+ {{ ex.code }}
20
+ ```
21
+ {%- endfor %}
22
+ {%- endif %}
23
+ {%- endif %}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@vellum-docs/engine-nunjucks",
3
+ "type": "module",
4
+ "version": "0.1.0",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/photon-hq/vellum.git",
8
+ "directory": "packages/engine-nunjucks"
9
+ },
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.mts",
13
+ "import": "./dist/index.mjs"
14
+ }
15
+ },
16
+ "main": "./dist/index.mjs",
17
+ "types": "./dist/index.d.mts",
18
+ "files": [
19
+ "dist",
20
+ "partials"
21
+ ],
22
+ "dependencies": {
23
+ "nunjucks": "^3.2.4",
24
+ "@vellum-docs/core": "0.1.0"
25
+ },
26
+ "devDependencies": {
27
+ "@types/nunjucks": "^3.2.6",
28
+ "typescript": "^5.6.3"
29
+ },
30
+ "scripts": {
31
+ "build": "tsdown src/index.ts --format esm --out-dir dist --dts && cp -r src/partials dist/partials",
32
+ "clean": "rm -rf dist",
33
+ "typecheck": "tsc -p tsconfig.json --noEmit"
34
+ }
35
+ }