@rse/nunjucks-cli 1.6.0 → 2.0.1
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/CHANGELOG.md +131 -0
- package/Dockerfile +3 -3
- package/eslint.mjs +7 -2
- package/nunjucks.js +107 -99
- package/nunjucks.ts +233 -0
- package/package.json +26 -15
- package/stx.conf +95 -0
- package/tsconfig.json +23 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
|
|
2
|
+
ChangeLog
|
|
3
|
+
=========
|
|
4
|
+
|
|
5
|
+
2.0.0 (2025-12-21)
|
|
6
|
+
------------------
|
|
7
|
+
|
|
8
|
+
- REFACTORING: switched to ESLint 9
|
|
9
|
+
- REFACTORING: switched to TypeScript
|
|
10
|
+
- REFACTORING: converted to STX and added packaging
|
|
11
|
+
- MAINTENANCE: upgraded dependencies
|
|
12
|
+
|
|
13
|
+
1.6.0 (2025-06-02)
|
|
14
|
+
------------------
|
|
15
|
+
|
|
16
|
+
- REFACTORING: upgraded to ESM land
|
|
17
|
+
- MAINTENANCE: upgraded dependencies
|
|
18
|
+
- MAINTENANCE: bumped year in all copyright messages
|
|
19
|
+
|
|
20
|
+
1.5.2 (2024-03-11)
|
|
21
|
+
------------------
|
|
22
|
+
|
|
23
|
+
- MAINTENANCE: updated copyright messages
|
|
24
|
+
- MAINTENANCE: upgraded dependencies
|
|
25
|
+
- MAINTENANCE: updated Dockerfile
|
|
26
|
+
|
|
27
|
+
1.5.1 (2023-12-25)
|
|
28
|
+
------------------
|
|
29
|
+
|
|
30
|
+
- MAINTENANCE: upgraded dependencies
|
|
31
|
+
|
|
32
|
+
1.5.0 (2023-10-02)
|
|
33
|
+
------------------
|
|
34
|
+
|
|
35
|
+
- FEATURE: support that option -d can occur multiple times (mixes structures deeply)
|
|
36
|
+
- MAINTENANCE: made ESLint happy with newer language features
|
|
37
|
+
- MAINTENANCE: upgraded dependencies
|
|
38
|
+
- MAINTENANCE: added Docker scripts
|
|
39
|
+
- MAINTENANCE: fixed stdver
|
|
40
|
+
|
|
41
|
+
1.4.5 (2023-08-28)
|
|
42
|
+
------------------
|
|
43
|
+
|
|
44
|
+
- BUGFIX: fixed once again the repo URL
|
|
45
|
+
|
|
46
|
+
1.4.4 (2023-08-28)
|
|
47
|
+
------------------
|
|
48
|
+
|
|
49
|
+
- BUGFIX: fixed repo URL
|
|
50
|
+
- FEATURE: added manpage
|
|
51
|
+
|
|
52
|
+
1.4.3 (2023-08-27)
|
|
53
|
+
------------------
|
|
54
|
+
|
|
55
|
+
- MAINTENANCE: linked manpage
|
|
56
|
+
- MAINTENANCE: added stdver
|
|
57
|
+
- MAINTENANCE: improved badges
|
|
58
|
+
|
|
59
|
+
1.4.2 (2023-08-26)
|
|
60
|
+
------------------
|
|
61
|
+
|
|
62
|
+
- FEATURE: added Unix manual page
|
|
63
|
+
|
|
64
|
+
1.4.1 (2023-08-21)
|
|
65
|
+
------------------
|
|
66
|
+
|
|
67
|
+
- REFACTORING: switched option parser from yargs to commander in order to support -Dx=y and not just -D x=y (with space)
|
|
68
|
+
|
|
69
|
+
1.4.0 (2023-08-20)
|
|
70
|
+
------------------
|
|
71
|
+
|
|
72
|
+
- FEATURE: added CLI option -C
|
|
73
|
+
- MAINTENANCE: upgraded dependencies
|
|
74
|
+
|
|
75
|
+
1.3.1 (2023-08-18)
|
|
76
|
+
------------------
|
|
77
|
+
|
|
78
|
+
- FEATURE: support local paths, too
|
|
79
|
+
|
|
80
|
+
1.3.0 (2023-08-18)
|
|
81
|
+
------------------
|
|
82
|
+
|
|
83
|
+
- FEATURE: added better installation and usage hints
|
|
84
|
+
- REFACTORING: removed addons as they are now in their own package
|
|
85
|
+
|
|
86
|
+
1.2.1 (2023-08-17)
|
|
87
|
+
------------------
|
|
88
|
+
|
|
89
|
+
- FEATURE: added uuid global function
|
|
90
|
+
- FEATURE: provided sprintf global function
|
|
91
|
+
- FEATURE: added sprintf filter
|
|
92
|
+
- FEATURE: added pad filter
|
|
93
|
+
|
|
94
|
+
1.2.0 (2023-08-15)
|
|
95
|
+
------------------
|
|
96
|
+
|
|
97
|
+
- FEATURE: added jsonpath extension
|
|
98
|
+
- REFACTORING: made jsYAML usage more modern and added support for jsonpath extension
|
|
99
|
+
|
|
100
|
+
1.1.1 (2023-08-15)
|
|
101
|
+
------------------
|
|
102
|
+
|
|
103
|
+
- MAINTENANCE: used copyright symbol
|
|
104
|
+
|
|
105
|
+
1.1.0 (2023-08-15)
|
|
106
|
+
------------------
|
|
107
|
+
|
|
108
|
+
- FEATURE: allowed NPM modules to be used as extensions
|
|
109
|
+
|
|
110
|
+
1.0.1 (2023-08-15)
|
|
111
|
+
------------------
|
|
112
|
+
|
|
113
|
+
- BUGFIX: remembered extensions
|
|
114
|
+
|
|
115
|
+
1.0.0 (2023-08-15)
|
|
116
|
+
------------------
|
|
117
|
+
|
|
118
|
+
- FEATURE: added hint to npx usage
|
|
119
|
+
|
|
120
|
+
0.9.6 (2023-08-15)
|
|
121
|
+
------------------
|
|
122
|
+
|
|
123
|
+
- MAINTENANCE: final cleanup
|
|
124
|
+
- MAINTENANCE: fixed npm publishing
|
|
125
|
+
- MAINTENANCE: switched to private namespace
|
|
126
|
+
|
|
127
|
+
0.9.5 (2023-08-15)
|
|
128
|
+
------------------
|
|
129
|
+
|
|
130
|
+
(first version)
|
|
131
|
+
|
package/Dockerfile
CHANGED
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
# build arguments (early)
|
|
6
6
|
ARG IMAGE_PREFIX=docker.io/engelschall/
|
|
7
7
|
ARG IMAGE_NAME=nunjucks-cli
|
|
8
|
-
ARG IMAGE_VERSION=
|
|
9
|
-
ARG IMAGE_RELEASE=
|
|
8
|
+
ARG IMAGE_VERSION=2.0.0
|
|
9
|
+
ARG IMAGE_RELEASE=20251221
|
|
10
10
|
ARG IMAGE_ALIAS=latest
|
|
11
11
|
|
|
12
12
|
# derive image from a certain base image
|
|
13
|
-
FROM node:24-alpine3.
|
|
13
|
+
FROM node:24-alpine3.23
|
|
14
14
|
|
|
15
15
|
# add additional build tools
|
|
16
16
|
RUN apk update && \
|
package/eslint.mjs
CHANGED
|
@@ -9,10 +9,12 @@ import pluginStd from "neostandard"
|
|
|
9
9
|
import pluginN from "eslint-plugin-n"
|
|
10
10
|
import pluginImport from "eslint-plugin-import"
|
|
11
11
|
import pluginPromise from "eslint-plugin-promise"
|
|
12
|
+
import pluginTS from "typescript-eslint"
|
|
12
13
|
import globals from "globals"
|
|
13
14
|
|
|
14
15
|
export default [
|
|
15
16
|
pluginJs.configs.recommended,
|
|
17
|
+
...pluginTS.configs.recommended,
|
|
16
18
|
...pluginStd({
|
|
17
19
|
ignores: pluginStd.resolveIgnoresFromGitignore()
|
|
18
20
|
}),
|
|
@@ -22,7 +24,7 @@ export default [
|
|
|
22
24
|
"import": pluginImport,
|
|
23
25
|
"promise": pluginPromise
|
|
24
26
|
},
|
|
25
|
-
files: [ "**/*.js" ],
|
|
27
|
+
files: [ "**/*.js", "**/*.ts" ],
|
|
26
28
|
ignores: [ "dst/" ],
|
|
27
29
|
languageOptions: {
|
|
28
30
|
ecmaVersion: 2022,
|
|
@@ -58,7 +60,10 @@ export default [
|
|
|
58
60
|
"@stylistic/array-bracket-spacing": "off",
|
|
59
61
|
"@stylistic/lines-between-class-members": "off",
|
|
60
62
|
"@stylistic/multiline-ternary": "off",
|
|
61
|
-
"@stylistic/quote-props": "off"
|
|
63
|
+
"@stylistic/quote-props": "off",
|
|
64
|
+
|
|
65
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
66
|
+
"@typescript-eslint/no-unused-vars": [ "error", { "argsIgnorePattern": "^_", "caughtErrorsIgnorePattern": "^_" } ]
|
|
62
67
|
}
|
|
63
68
|
}
|
|
64
69
|
]
|
package/nunjucks.js
CHANGED
|
@@ -4,176 +4,184 @@
|
|
|
4
4
|
** Copyright (c) 2019-2025 Dr. Ralf S. Engelschall <http://engelschall.com>
|
|
5
5
|
** Licensed under MIT <http://spdx.org/licenses/MIT.html>
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
|
|
7
|
+
/* built-in requirements */
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { createRequire } from "node:module";
|
|
12
11
|
/* external requirements */
|
|
13
|
-
import { Command } from "commander"
|
|
14
|
-
import chalk
|
|
15
|
-
import jsYAML
|
|
16
|
-
import nunjucks
|
|
17
|
-
import deepmerge
|
|
18
|
-
|
|
12
|
+
import { Command } from "commander";
|
|
13
|
+
import chalk from "chalk";
|
|
14
|
+
import jsYAML from "js-yaml";
|
|
15
|
+
import nunjucks from "nunjucks";
|
|
16
|
+
import deepmerge from "deepmerge";
|
|
19
17
|
/* load my own information */
|
|
20
|
-
const my = JSON.parse(await fs.promises.readFile(new URL("./package.json", import.meta.url)))
|
|
21
|
-
|
|
18
|
+
const my = JSON.parse(await fs.promises.readFile(new URL("./package.json", import.meta.url), "utf-8"));
|
|
22
19
|
/* parse command-line arguments */
|
|
23
|
-
const program = new Command()
|
|
20
|
+
const program = new Command();
|
|
21
|
+
const reduceArray = (v, l) => l.concat([v]);
|
|
24
22
|
program.name("nunjucks")
|
|
25
23
|
.description("Nunjucks Template Rendering Command-Line Interface")
|
|
26
24
|
.showHelpAfterError("hint: use option --help for usage information")
|
|
27
25
|
.option("-h, --help", "show usage help", false)
|
|
28
26
|
.option("-V, --version", "show program version information", false)
|
|
29
27
|
.option("-c, --config <config-file>", "load Nunjucks configuration YAML file", "")
|
|
30
|
-
.option("-C, --option <key>=<value>", "set Nunjucks configuration option",
|
|
31
|
-
.option("-d, --defines <context-file>", "load context definition YAML file",
|
|
32
|
-
.option("-D, --define <key>=<value>", "set context definition key/value",
|
|
33
|
-
.option("-e, --extension <module-name>", "load Nunjucks JavaScript extension module",
|
|
28
|
+
.option("-C, --option <key>=<value>", "set Nunjucks configuration option", reduceArray, [])
|
|
29
|
+
.option("-d, --defines <context-file>", "load context definition YAML file", reduceArray, [])
|
|
30
|
+
.option("-D, --define <key>=<value>", "set context definition key/value", reduceArray, [])
|
|
31
|
+
.option("-e, --extension <module-name>", "load Nunjucks JavaScript extension module", reduceArray, [])
|
|
34
32
|
.option("-o, --output <output-file>", "save output file", "-")
|
|
35
|
-
.argument("[<input-file>]", "input file")
|
|
36
|
-
program.parse(process.argv)
|
|
37
|
-
const argv = {
|
|
38
|
-
|
|
33
|
+
.argument("[<input-file>]", "input file");
|
|
34
|
+
program.parse(process.argv);
|
|
35
|
+
const argv = {
|
|
36
|
+
...program.opts(),
|
|
37
|
+
_: program.args
|
|
38
|
+
};
|
|
39
39
|
/* handle special help request */
|
|
40
40
|
if (argv.help) {
|
|
41
|
-
console.log(program.helpInformation())
|
|
42
|
-
console.log("Example:\n $ echo \"Hello, {{ who }}!\" | nunjucks -Dwho=World -\n")
|
|
43
|
-
process.exit(0)
|
|
41
|
+
console.log(program.helpInformation());
|
|
42
|
+
console.log("Example:\n $ echo \"Hello, {{ who }}!\" | nunjucks -Dwho=World -\n");
|
|
43
|
+
process.exit(0);
|
|
44
44
|
}
|
|
45
|
-
|
|
46
45
|
/* handle special version request */
|
|
47
46
|
if (argv.version) {
|
|
48
|
-
console.log(`${my.name} ${my.version} (Node.js ${process.versions.node}, Nunjucks: ${my.dependencies.nunjucks})`)
|
|
49
|
-
console.log(`${my.description}`)
|
|
50
|
-
console.log(`Copyright (c) 2019-2025 ${my.author.name} <${my.author.url}>`)
|
|
51
|
-
console.log(`Licensed under ${my.license} <http://spdx.org/licenses/${my.license}.html>`)
|
|
52
|
-
process.exit(0)
|
|
47
|
+
console.log(`${my.name} ${my.version} (Node.js ${process.versions.node}, Nunjucks: ${my.dependencies.nunjucks})`);
|
|
48
|
+
console.log(`${my.description}`);
|
|
49
|
+
console.log(`Copyright (c) 2019-2025 ${my.author.name} <${my.author.url}>`);
|
|
50
|
+
console.log(`Licensed under ${my.license} <http://spdx.org/licenses/${my.license}.html>`);
|
|
51
|
+
process.exit(0);
|
|
53
52
|
}
|
|
54
|
-
|
|
55
53
|
/* read input file */
|
|
56
|
-
let input = ""
|
|
54
|
+
let input = "";
|
|
57
55
|
if (argv._.length > 1) {
|
|
58
|
-
console.error(chalk.red("nunjucks: ERROR: invalid number of arguments (zero or one input file expected)"))
|
|
59
|
-
process.exit(1)
|
|
56
|
+
console.error(chalk.red("nunjucks: ERROR: invalid number of arguments (zero or one input file expected)"));
|
|
57
|
+
process.exit(1);
|
|
60
58
|
}
|
|
61
|
-
let inputFile = argv._[0] ?? "-"
|
|
59
|
+
let inputFile = argv._[0] ?? "-";
|
|
62
60
|
if (inputFile === "-") {
|
|
63
|
-
inputFile = "<stdin>"
|
|
64
|
-
process.stdin.setEncoding("utf-8")
|
|
65
|
-
const BUFSIZE = 256
|
|
66
|
-
const buf = Buffer.alloc(BUFSIZE)
|
|
61
|
+
inputFile = "<stdin>";
|
|
62
|
+
process.stdin.setEncoding("utf-8");
|
|
63
|
+
const BUFSIZE = 256;
|
|
64
|
+
const buf = Buffer.alloc(BUFSIZE);
|
|
67
65
|
while (true) {
|
|
68
|
-
let bytesRead = 0
|
|
66
|
+
let bytesRead = 0;
|
|
69
67
|
try {
|
|
70
|
-
bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE)
|
|
68
|
+
bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE, null);
|
|
71
69
|
}
|
|
72
70
|
catch (ex) {
|
|
73
|
-
if
|
|
74
|
-
|
|
75
|
-
else
|
|
71
|
+
if (ex.code === "EAGAIN")
|
|
72
|
+
continue;
|
|
73
|
+
else if (ex.code === "EOF")
|
|
74
|
+
break;
|
|
75
|
+
else
|
|
76
|
+
throw ex;
|
|
76
77
|
}
|
|
77
78
|
if (bytesRead === 0)
|
|
78
|
-
break
|
|
79
|
-
input += buf.toString("utf8", 0, bytesRead)
|
|
79
|
+
break;
|
|
80
|
+
input += buf.toString("utf8", 0, bytesRead);
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
else {
|
|
83
84
|
if (!fs.existsSync(inputFile)) {
|
|
84
|
-
console.error(chalk.red(`nunjucks: ERROR: failed to find input file: ${inputFile}`))
|
|
85
|
-
process.exit(1)
|
|
85
|
+
console.error(chalk.red(`nunjucks: ERROR: failed to find input file: ${inputFile}`));
|
|
86
|
+
process.exit(1);
|
|
86
87
|
}
|
|
87
|
-
input = fs.readFileSync(inputFile, { encoding: "utf8" })
|
|
88
|
+
input = fs.readFileSync(inputFile, { encoding: "utf8" });
|
|
88
89
|
}
|
|
89
|
-
|
|
90
90
|
/* provide context variables for template */
|
|
91
|
-
let context = {}
|
|
91
|
+
let context = {};
|
|
92
92
|
for (const define of argv.defines) {
|
|
93
93
|
try {
|
|
94
|
-
context = deepmerge(context, jsYAML.load(fs.readFileSync(define, { encoding: "utf8" })))
|
|
94
|
+
context = deepmerge(context, jsYAML.load(fs.readFileSync(define, { encoding: "utf8" })));
|
|
95
95
|
}
|
|
96
96
|
catch (ex) {
|
|
97
|
-
console.error(chalk.red(`nunjucks: ERROR: failed to load context YAML file: ${ex.toString()}`))
|
|
98
|
-
process.exit(1)
|
|
97
|
+
console.error(chalk.red(`nunjucks: ERROR: failed to load context YAML file: ${ex.toString()}`));
|
|
98
|
+
process.exit(1);
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
|
-
|
|
102
101
|
/* expose environment variables to template */
|
|
103
|
-
context.env = process.env
|
|
104
|
-
|
|
102
|
+
context.env = process.env;
|
|
105
103
|
/* add context defines */
|
|
106
104
|
argv.define.forEach((define) => {
|
|
107
|
-
|
|
105
|
+
const match = define.match(/^([^=]+)(?:=(.*))?$/);
|
|
106
|
+
if (!match)
|
|
107
|
+
return;
|
|
108
|
+
let [, key, val] = match;
|
|
109
|
+
if (!key)
|
|
110
|
+
return;
|
|
108
111
|
if (val === undefined)
|
|
109
|
-
val = true
|
|
110
|
-
context[key] = val
|
|
111
|
-
})
|
|
112
|
-
|
|
112
|
+
val = "true";
|
|
113
|
+
context[key] = val;
|
|
114
|
+
});
|
|
113
115
|
/* determine Nunjucks options */
|
|
114
|
-
let options = {}
|
|
116
|
+
let options = {};
|
|
115
117
|
if (argv.config) {
|
|
116
118
|
try {
|
|
117
|
-
options = jsYAML.load(fs.readFileSync(argv.config, { encoding: "utf8" }))
|
|
119
|
+
options = jsYAML.load(fs.readFileSync(argv.config, { encoding: "utf8" }));
|
|
118
120
|
}
|
|
119
121
|
catch (ex) {
|
|
120
|
-
console.error(chalk.red(`nunjucks: ERROR: failed to load options YAML file: ${ex.toString()}`))
|
|
121
|
-
process.exit(1)
|
|
122
|
+
console.error(chalk.red(`nunjucks: ERROR: failed to load options YAML file: ${ex.toString()}`));
|
|
123
|
+
process.exit(1);
|
|
122
124
|
}
|
|
123
125
|
}
|
|
124
126
|
if (argv.option.length > 0)
|
|
125
|
-
options = Object.assign(options, argv.option)
|
|
126
|
-
options =
|
|
127
|
-
autoescape:
|
|
127
|
+
options = Object.assign(options, argv.option);
|
|
128
|
+
options = {
|
|
129
|
+
autoescape: false,
|
|
128
130
|
throwOnUndefined: false,
|
|
129
|
-
trimBlocks:
|
|
130
|
-
lstripBlocks:
|
|
131
|
-
watch:
|
|
132
|
-
noCache:
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
trimBlocks: true,
|
|
132
|
+
lstripBlocks: true,
|
|
133
|
+
watch: false,
|
|
134
|
+
noCache: true,
|
|
135
|
+
...options
|
|
136
|
+
};
|
|
135
137
|
/* configure environment */
|
|
136
|
-
const env = nunjucks.configure(inputFile, options)
|
|
137
|
-
|
|
138
|
+
const env = nunjucks.configure(inputFile, options);
|
|
138
139
|
/* load external extension files */
|
|
139
140
|
for (const extension of argv.extension) {
|
|
140
|
-
let modpath = path.resolve(extension)
|
|
141
|
+
let modpath = path.resolve(extension);
|
|
141
142
|
if (!fs.existsSync(modpath)) {
|
|
142
143
|
try {
|
|
143
|
-
|
|
144
|
+
const require = createRequire(import.meta.url);
|
|
145
|
+
modpath = require.resolve(extension);
|
|
144
146
|
}
|
|
145
|
-
catch (
|
|
146
|
-
modpath = null
|
|
147
|
+
catch (_ex) {
|
|
148
|
+
modpath = null;
|
|
147
149
|
}
|
|
148
150
|
}
|
|
149
151
|
if (modpath === null) {
|
|
150
|
-
console.error(chalk.red(`nunjucks: ERROR: failed to find extension module: ${extension}`))
|
|
151
|
-
process.exit(1)
|
|
152
|
+
console.error(chalk.red(`nunjucks: ERROR: failed to find extension module: ${extension}`));
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
/* dynamically import the module */
|
|
156
|
+
let mod;
|
|
157
|
+
try {
|
|
158
|
+
mod = await import(modpath);
|
|
159
|
+
/* handle both default and named exports */
|
|
160
|
+
mod = mod.default ?? mod;
|
|
161
|
+
}
|
|
162
|
+
catch (ex) {
|
|
163
|
+
console.error(chalk.red(`nunjucks: ERROR: failed to load extension module: ${ex.toString()}`));
|
|
164
|
+
process.exit(1);
|
|
152
165
|
}
|
|
153
|
-
const mod = require(modpath)
|
|
154
166
|
if (!(mod !== null && typeof mod === "function")) {
|
|
155
|
-
console.error(chalk.red(`nunjucks: ERROR: failed to call extension file: ${modpath}`))
|
|
156
|
-
process.exit(1)
|
|
167
|
+
console.error(chalk.red(`nunjucks: ERROR: failed to call extension file: ${modpath}`));
|
|
168
|
+
process.exit(1);
|
|
157
169
|
}
|
|
158
|
-
mod(env)
|
|
170
|
+
mod(env);
|
|
159
171
|
}
|
|
160
|
-
|
|
161
172
|
/* render Nunjucks template */
|
|
162
|
-
let output
|
|
173
|
+
let output;
|
|
163
174
|
try {
|
|
164
|
-
output = env.renderString(input, context)
|
|
175
|
+
output = env.renderString(input, context);
|
|
165
176
|
}
|
|
166
177
|
catch (ex) {
|
|
167
|
-
console.error(chalk.red(`nunjucks: ERROR: failed to render template: ${ex.toString()}`))
|
|
168
|
-
process.exit(1)
|
|
178
|
+
console.error(chalk.red(`nunjucks: ERROR: failed to render template: ${ex.toString()}`));
|
|
179
|
+
process.exit(1);
|
|
169
180
|
}
|
|
170
|
-
|
|
171
181
|
/* write output */
|
|
172
182
|
if (argv.output === "-")
|
|
173
|
-
process.stdout.write(output)
|
|
183
|
+
process.stdout.write(output);
|
|
174
184
|
else
|
|
175
|
-
fs.writeFileSync(argv.output, output, { encoding: "utf8" })
|
|
176
|
-
|
|
185
|
+
fs.writeFileSync(argv.output, output, { encoding: "utf8" });
|
|
177
186
|
/* die gracefully */
|
|
178
|
-
process.exit(0)
|
|
179
|
-
|
|
187
|
+
process.exit(0);
|
package/nunjucks.ts
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/*
|
|
3
|
+
** nunjucks -- Nunjucks Template Rendering Command-Line Interface
|
|
4
|
+
** Copyright (c) 2019-2025 Dr. Ralf S. Engelschall <http://engelschall.com>
|
|
5
|
+
** Licensed under MIT <http://spdx.org/licenses/MIT.html>
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/* built-in requirements */
|
|
9
|
+
import fs from "node:fs"
|
|
10
|
+
import path from "node:path"
|
|
11
|
+
import { createRequire } from "node:module"
|
|
12
|
+
|
|
13
|
+
/* external requirements */
|
|
14
|
+
import { Command } from "commander"
|
|
15
|
+
import chalk from "chalk"
|
|
16
|
+
import jsYAML from "js-yaml"
|
|
17
|
+
import nunjucks from "nunjucks"
|
|
18
|
+
import deepmerge from "deepmerge"
|
|
19
|
+
|
|
20
|
+
/* type definitions */
|
|
21
|
+
type PackageInfo = {
|
|
22
|
+
name: string
|
|
23
|
+
version: string
|
|
24
|
+
description: string
|
|
25
|
+
author: { name: string; email: string; url: string }
|
|
26
|
+
license: string
|
|
27
|
+
dependencies: { nunjucks: string }
|
|
28
|
+
}
|
|
29
|
+
type ContextType = Record<string, any>
|
|
30
|
+
type OptionsType = {
|
|
31
|
+
autoescape?: boolean
|
|
32
|
+
throwOnUndefined?: boolean
|
|
33
|
+
trimBlocks?: boolean
|
|
34
|
+
lstripBlocks?: boolean
|
|
35
|
+
watch?: boolean
|
|
36
|
+
noCache?: boolean
|
|
37
|
+
}
|
|
38
|
+
type CLIOptions = {
|
|
39
|
+
help: boolean
|
|
40
|
+
version: boolean
|
|
41
|
+
config: string
|
|
42
|
+
option: string[]
|
|
43
|
+
defines: string[]
|
|
44
|
+
define: string[]
|
|
45
|
+
extension: string[]
|
|
46
|
+
output: string
|
|
47
|
+
_: string[]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* load my own information */
|
|
51
|
+
const my: PackageInfo = JSON.parse(await fs.promises.readFile(new URL("./package.json", import.meta.url), "utf-8"))
|
|
52
|
+
|
|
53
|
+
/* parse command-line arguments */
|
|
54
|
+
const program = new Command()
|
|
55
|
+
const reduceArray = (v: string, l: string[]) => l.concat([ v ])
|
|
56
|
+
program.name("nunjucks")
|
|
57
|
+
.description("Nunjucks Template Rendering Command-Line Interface")
|
|
58
|
+
.showHelpAfterError("hint: use option --help for usage information")
|
|
59
|
+
.option("-h, --help", "show usage help", false)
|
|
60
|
+
.option("-V, --version", "show program version information", false)
|
|
61
|
+
.option("-c, --config <config-file>", "load Nunjucks configuration YAML file", "")
|
|
62
|
+
.option("-C, --option <key>=<value>", "set Nunjucks configuration option", reduceArray, [])
|
|
63
|
+
.option("-d, --defines <context-file>", "load context definition YAML file", reduceArray, [])
|
|
64
|
+
.option("-D, --define <key>=<value>", "set context definition key/value", reduceArray, [])
|
|
65
|
+
.option("-e, --extension <module-name>", "load Nunjucks JavaScript extension module", reduceArray, [])
|
|
66
|
+
.option("-o, --output <output-file>", "save output file", "-")
|
|
67
|
+
.argument("[<input-file>]", "input file")
|
|
68
|
+
program.parse(process.argv)
|
|
69
|
+
const argv: CLIOptions = {
|
|
70
|
+
...program.opts(),
|
|
71
|
+
_: program.args
|
|
72
|
+
} as CLIOptions
|
|
73
|
+
|
|
74
|
+
/* handle special help request */
|
|
75
|
+
if (argv.help) {
|
|
76
|
+
console.log(program.helpInformation())
|
|
77
|
+
console.log("Example:\n $ echo \"Hello, {{ who }}!\" | nunjucks -Dwho=World -\n")
|
|
78
|
+
process.exit(0)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* handle special version request */
|
|
82
|
+
if (argv.version) {
|
|
83
|
+
console.log(`${my.name} ${my.version} (Node.js ${process.versions.node}, Nunjucks: ${my.dependencies.nunjucks})`)
|
|
84
|
+
console.log(`${my.description}`)
|
|
85
|
+
console.log(`Copyright (c) 2019-2025 ${my.author.name} <${my.author.url}>`)
|
|
86
|
+
console.log(`Licensed under ${my.license} <http://spdx.org/licenses/${my.license}.html>`)
|
|
87
|
+
process.exit(0)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* read input file */
|
|
91
|
+
let input = ""
|
|
92
|
+
if (argv._.length > 1) {
|
|
93
|
+
console.error(chalk.red("nunjucks: ERROR: invalid number of arguments (zero or one input file expected)"))
|
|
94
|
+
process.exit(1)
|
|
95
|
+
}
|
|
96
|
+
let inputFile: string = argv._[0] ?? "-"
|
|
97
|
+
if (inputFile === "-") {
|
|
98
|
+
inputFile = "<stdin>"
|
|
99
|
+
process.stdin.setEncoding("utf-8")
|
|
100
|
+
const BUFSIZE = 256
|
|
101
|
+
const buf = Buffer.alloc(BUFSIZE)
|
|
102
|
+
while (true) {
|
|
103
|
+
let bytesRead = 0
|
|
104
|
+
try {
|
|
105
|
+
bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE, null)
|
|
106
|
+
}
|
|
107
|
+
catch (ex: any) {
|
|
108
|
+
if (ex.code === "EAGAIN") continue
|
|
109
|
+
else if (ex.code === "EOF") break
|
|
110
|
+
else throw ex
|
|
111
|
+
}
|
|
112
|
+
if (bytesRead === 0)
|
|
113
|
+
break
|
|
114
|
+
input += buf.toString("utf8", 0, bytesRead)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
if (!fs.existsSync(inputFile)) {
|
|
119
|
+
console.error(chalk.red(`nunjucks: ERROR: failed to find input file: ${inputFile}`))
|
|
120
|
+
process.exit(1)
|
|
121
|
+
}
|
|
122
|
+
input = fs.readFileSync(inputFile, { encoding: "utf8" })
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* provide context variables for template */
|
|
126
|
+
let context: ContextType = {}
|
|
127
|
+
for (const define of argv.defines) {
|
|
128
|
+
try {
|
|
129
|
+
context = deepmerge(context, jsYAML.load(fs.readFileSync(define, { encoding: "utf8" })) as ContextType)
|
|
130
|
+
}
|
|
131
|
+
catch (ex: any) {
|
|
132
|
+
console.error(chalk.red(`nunjucks: ERROR: failed to load context YAML file: ${ex.toString()}`))
|
|
133
|
+
process.exit(1)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* expose environment variables to template */
|
|
138
|
+
context.env = process.env
|
|
139
|
+
|
|
140
|
+
/* add context defines */
|
|
141
|
+
argv.define.forEach((define: string) => {
|
|
142
|
+
const match = define.match(/^([^=]+)(?:=(.*))?$/)
|
|
143
|
+
if (!match)
|
|
144
|
+
return
|
|
145
|
+
let [ , key, val ]: (string | undefined)[] = match
|
|
146
|
+
if (!key)
|
|
147
|
+
return
|
|
148
|
+
if (val === undefined)
|
|
149
|
+
val = "true"
|
|
150
|
+
context[key] = val
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
/* determine Nunjucks options */
|
|
154
|
+
let options: OptionsType = {}
|
|
155
|
+
if (argv.config) {
|
|
156
|
+
try {
|
|
157
|
+
options = jsYAML.load(fs.readFileSync(argv.config, { encoding: "utf8" })) as OptionsType
|
|
158
|
+
}
|
|
159
|
+
catch (ex: any) {
|
|
160
|
+
console.error(chalk.red(`nunjucks: ERROR: failed to load options YAML file: ${ex.toString()}`))
|
|
161
|
+
process.exit(1)
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (argv.option.length > 0)
|
|
165
|
+
options = Object.assign(options, argv.option)
|
|
166
|
+
options = {
|
|
167
|
+
autoescape: false,
|
|
168
|
+
throwOnUndefined: false,
|
|
169
|
+
trimBlocks: true,
|
|
170
|
+
lstripBlocks: true,
|
|
171
|
+
watch: false,
|
|
172
|
+
noCache: true,
|
|
173
|
+
...options
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* configure environment */
|
|
177
|
+
const env = nunjucks.configure(inputFile, options)
|
|
178
|
+
|
|
179
|
+
/* load external extension files */
|
|
180
|
+
for (const extension of argv.extension) {
|
|
181
|
+
let modpath: string | null = path.resolve(extension)
|
|
182
|
+
if (!fs.existsSync(modpath)) {
|
|
183
|
+
try {
|
|
184
|
+
const require = createRequire(import.meta.url)
|
|
185
|
+
modpath = require.resolve(extension)
|
|
186
|
+
}
|
|
187
|
+
catch (_ex) {
|
|
188
|
+
modpath = null
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (modpath === null) {
|
|
192
|
+
console.error(chalk.red(`nunjucks: ERROR: failed to find extension module: ${extension}`))
|
|
193
|
+
process.exit(1)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/* dynamically import the module */
|
|
197
|
+
let mod: any
|
|
198
|
+
try {
|
|
199
|
+
mod = await import(modpath)
|
|
200
|
+
|
|
201
|
+
/* handle both default and named exports */
|
|
202
|
+
mod = mod.default ?? mod
|
|
203
|
+
}
|
|
204
|
+
catch (ex: any) {
|
|
205
|
+
console.error(chalk.red(`nunjucks: ERROR: failed to load extension module: ${ex.toString()}`))
|
|
206
|
+
process.exit(1)
|
|
207
|
+
}
|
|
208
|
+
if (!(mod !== null && typeof mod === "function")) {
|
|
209
|
+
console.error(chalk.red(`nunjucks: ERROR: failed to call extension file: ${modpath}`))
|
|
210
|
+
process.exit(1)
|
|
211
|
+
}
|
|
212
|
+
mod(env)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/* render Nunjucks template */
|
|
216
|
+
let output: string
|
|
217
|
+
try {
|
|
218
|
+
output = env.renderString(input, context)
|
|
219
|
+
}
|
|
220
|
+
catch (ex: any) {
|
|
221
|
+
console.error(chalk.red(`nunjucks: ERROR: failed to render template: ${ex.toString()}`))
|
|
222
|
+
process.exit(1)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* write output */
|
|
226
|
+
if (argv.output === "-")
|
|
227
|
+
process.stdout.write(output)
|
|
228
|
+
else
|
|
229
|
+
fs.writeFileSync(argv.output, output, { encoding: "utf8" })
|
|
230
|
+
|
|
231
|
+
/* die gracefully */
|
|
232
|
+
process.exit(0)
|
|
233
|
+
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rse/nunjucks-cli",
|
|
3
3
|
"publishConfig": { "access": "public" },
|
|
4
|
-
"version": "
|
|
5
|
-
"stdver": "
|
|
4
|
+
"version": "2.0.1",
|
|
5
|
+
"stdver": "2.0.0-GA",
|
|
6
6
|
"description": "Nunjucks Template Rendering Command-Line Interface",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Dr. Ralf S. Engelschall",
|
|
@@ -22,28 +22,39 @@
|
|
|
22
22
|
},
|
|
23
23
|
"man": "nunjucks.1",
|
|
24
24
|
"type": "module",
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=22.18.0"
|
|
27
|
+
},
|
|
25
28
|
"dependencies": {
|
|
26
29
|
"nunjucks": "3.2.4",
|
|
27
|
-
"chalk": "5.
|
|
28
|
-
"commander": "14.0.
|
|
29
|
-
"js-yaml": "4.1.
|
|
30
|
+
"chalk": "5.6.2",
|
|
31
|
+
"commander": "14.0.2",
|
|
32
|
+
"js-yaml": "4.1.1",
|
|
30
33
|
"deepmerge": "4.3.1"
|
|
31
34
|
},
|
|
32
35
|
"devDependencies": {
|
|
33
|
-
"eslint": "9.
|
|
34
|
-
"@eslint/js": "9.
|
|
35
|
-
"neostandard": "0.12.
|
|
36
|
+
"eslint": "9.39.2",
|
|
37
|
+
"@eslint/js": "9.39.2",
|
|
38
|
+
"neostandard": "0.12.2",
|
|
36
39
|
"eslint-plugin-promise": "7.2.1",
|
|
37
|
-
"eslint-plugin-import": "2.
|
|
38
|
-
"eslint-plugin-n": "17.
|
|
39
|
-
"globals": "16.
|
|
40
|
+
"eslint-plugin-import": "2.32.0",
|
|
41
|
+
"eslint-plugin-n": "17.23.1",
|
|
42
|
+
"globals": "16.5.0",
|
|
40
43
|
"remark-cli": "12.0.1",
|
|
41
44
|
"remark": "15.0.1",
|
|
42
|
-
"remark-man": "9.0.0"
|
|
45
|
+
"remark-man": "9.0.0",
|
|
46
|
+
"typescript": "5.9.3",
|
|
47
|
+
"typescript-eslint": "8.50.0",
|
|
48
|
+
"@rse/stx": "1.1.3",
|
|
49
|
+
"shx": "0.4.0",
|
|
50
|
+
"@yao-pkg/pkg": "6.11.0",
|
|
51
|
+
|
|
52
|
+
"@types/node": "25.0.3",
|
|
53
|
+
"@types/js-yaml": "4.0.9",
|
|
54
|
+
"@types/nunjucks": "3.2.6"
|
|
43
55
|
},
|
|
44
56
|
"scripts": {
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"test": "echo 'Hello, {{who}}!' | node nunjucks.js -D who=world -"
|
|
57
|
+
"start": "stx -v4 -c stx.conf",
|
|
58
|
+
"test": "npm start test"
|
|
48
59
|
}
|
|
49
60
|
}
|
package/stx.conf
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
##
|
|
2
|
+
## nunjucks -- Nunjucks Template Rendering Command-Line Interface
|
|
3
|
+
## Copyright (c) 2019-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
|
|
4
|
+
## Licensed under MIT <https://spdx.org/licenses/MIT>
|
|
5
|
+
##
|
|
6
|
+
|
|
7
|
+
# static code analysis
|
|
8
|
+
lint
|
|
9
|
+
eslint --config eslint.mjs nunjucks.ts && \
|
|
10
|
+
tsc --noEmit --project tsconfig.json
|
|
11
|
+
|
|
12
|
+
# build JavaScript from TypeScript
|
|
13
|
+
build
|
|
14
|
+
tsc --project tsconfig.json
|
|
15
|
+
|
|
16
|
+
# build manual page
|
|
17
|
+
man
|
|
18
|
+
remark --quiet --use remark-man --output nunjucks.1 nunjucks.md
|
|
19
|
+
|
|
20
|
+
# execute simple smole test
|
|
21
|
+
test : build
|
|
22
|
+
echo 'Hello, {{who}}!' | node nunjucks.js -D who=world -
|
|
23
|
+
|
|
24
|
+
# build all-in-one packages
|
|
25
|
+
build:pkg [hostname=en4.*]
|
|
26
|
+
|
|
27
|
+
# package distribution archives
|
|
28
|
+
package : build build:pkg [hostname=en4.*]
|
|
29
|
+
VERSION=`sed -n '/"version":/ s/.*: *"\(.*\)".*/\1/p' package.json` && \
|
|
30
|
+
targets="node24-linux-x64,node24-linux-arm64" && \
|
|
31
|
+
targets="$targets,node24-win-x64,node24-win-arm64" && \
|
|
32
|
+
targets="$targets,node24-macos-x64,node24-macos-arm64" && \
|
|
33
|
+
sed -e 's;@rse/nunjucks-cli;nunjucks;' <package.json >nunjucks.json && \
|
|
34
|
+
pkg --sea --public -c nunjucks.json -t "$targets" nunjucks.js && \
|
|
35
|
+
rm -f nunjucks.json && \
|
|
36
|
+
shx mv nunjucks-linux-x64 nunjucks-lnx-x64 && \
|
|
37
|
+
shx mv nunjucks-linux-arm64 nunjucks-lnx-a64 && \
|
|
38
|
+
shx mv nunjucks-win-x64.exe nunjucks-win-x64.exe && \
|
|
39
|
+
shx mv nunjucks-win-arm64.exe nunjucks-win-a64.exe && \
|
|
40
|
+
shx mv nunjucks-macos-x64 nunjucks-mac-x64 && \
|
|
41
|
+
shx mv nunjucks-macos-arm64 nunjucks-mac-a64
|
|
42
|
+
mkdir -p nunjucks-$VERSION/ && \
|
|
43
|
+
mkdir -p nunjucks-$VERSION-win-x64/ && \
|
|
44
|
+
mkdir -p nunjucks-$VERSION-win-a64/ && \
|
|
45
|
+
mkdir -p nunjucks-$VERSION-mac-x64/ && \
|
|
46
|
+
mkdir -p nunjucks-$VERSION-mac-a64/ && \
|
|
47
|
+
mkdir -p nunjucks-$VERSION-lnx-x64/ && \
|
|
48
|
+
mkdir -p nunjucks-$VERSION-lnx-a64/ && \
|
|
49
|
+
cp -p nunjucks.js nunjucks-$VERSION/nunjucks.js && \
|
|
50
|
+
cp -p nunjucks-win-x64.exe nunjucks-$VERSION-win-x64/nunjucks.exe && \
|
|
51
|
+
cp -p nunjucks-win-a64.exe nunjucks-$VERSION-win-a64/nunjucks.exe && \
|
|
52
|
+
cp -p nunjucks-mac-x64 nunjucks-$VERSION-mac-x64/nunjucks && \
|
|
53
|
+
cp -p nunjucks-mac-a64 nunjucks-$VERSION-mac-a64/nunjucks && \
|
|
54
|
+
cp -p nunjucks-lnx-x64 nunjucks-$VERSION-lnx-x64/nunjucks && \
|
|
55
|
+
cp -p nunjucks-lnx-a64 nunjucks-$VERSION-lnx-a64/nunjucks && \
|
|
56
|
+
cp -p nunjucks.1 nunjucks-$VERSION/nunjucks.man && \
|
|
57
|
+
cp -p nunjucks.1 nunjucks-$VERSION-win-x64/nunjucks.man && \
|
|
58
|
+
cp -p nunjucks.1 nunjucks-$VERSION-win-a64/nunjucks.man && \
|
|
59
|
+
cp -p nunjucks.1 nunjucks-$VERSION-mac-x64/nunjucks.man && \
|
|
60
|
+
cp -p nunjucks.1 nunjucks-$VERSION-mac-a64/nunjucks.man && \
|
|
61
|
+
cp -p nunjucks.1 nunjucks-$VERSION-lnx-x64/nunjucks.man && \
|
|
62
|
+
cp -p nunjucks.1 nunjucks-$VERSION-lnx-a64/nunjucks.man && \
|
|
63
|
+
zip -9 -r nunjucks-$VERSION.zip nunjucks-$VERSION/ && \
|
|
64
|
+
zip -9 -r nunjucks-$VERSION-win-x64.zip nunjucks-$VERSION-win-x64/ && \
|
|
65
|
+
zip -9 -r nunjucks-$VERSION-win-a64.zip nunjucks-$VERSION-win-a64/ && \
|
|
66
|
+
zip -9 -r nunjucks-$VERSION-mac-x64.zip nunjucks-$VERSION-mac-x64/ && \
|
|
67
|
+
zip -9 -r nunjucks-$VERSION-mac-a64.zip nunjucks-$VERSION-mac-a64/ && \
|
|
68
|
+
zip -9 -r nunjucks-$VERSION-lnx-x64.zip nunjucks-$VERSION-lnx-x64/ && \
|
|
69
|
+
zip -9 -r nunjucks-$VERSION-lnx-a64.zip nunjucks-$VERSION-lnx-a64/
|
|
70
|
+
|
|
71
|
+
# publish distribution archives
|
|
72
|
+
publish : package [hostname=en4.*]
|
|
73
|
+
VERSION=`sed -n '/"version":/ s/.*: *"\(.*\)".*/\1/p' package.json` && \
|
|
74
|
+
V=`echo "$VERSION" | sed -e 's;\.;\\.;g'` && \
|
|
75
|
+
sed -n -e "/^${V} /, /^[0-9]\\./ { /^${V} /p; /^[0-9]\\./!p; }" <CHANGELOG.md >.notes.md && \
|
|
76
|
+
gh release create --title "Nunjucks $VERSION" --notes-file .notes.md --verify-tag $VERSION \
|
|
77
|
+
nunjucks-$VERSION.zip \
|
|
78
|
+
nunjucks-$VERSION-win-x64.zip \
|
|
79
|
+
nunjucks-$VERSION-win-a64.zip \
|
|
80
|
+
nunjucks-$VERSION-mac-x64.zip \
|
|
81
|
+
nunjucks-$VERSION-mac-a64.zip \
|
|
82
|
+
nunjucks-$VERSION-lnx-x64.zip \
|
|
83
|
+
nunjucks-$VERSION-lnx-a64.zip && \
|
|
84
|
+
rm -f .notes.md
|
|
85
|
+
|
|
86
|
+
# remove all generated artifacts
|
|
87
|
+
clean
|
|
88
|
+
shx rm -f nunjucks.js && \
|
|
89
|
+
shx rm -rf nunjucks-*.zip
|
|
90
|
+
|
|
91
|
+
# remove all generated artifacts
|
|
92
|
+
distclean: clean
|
|
93
|
+
shx rm -f package-lock.json && \
|
|
94
|
+
shx rm -rf node_modules
|
|
95
|
+
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2024",
|
|
4
|
+
"module": "node20",
|
|
5
|
+
"lib": [ "ES2024" ],
|
|
6
|
+
"moduleResolution": "node16",
|
|
7
|
+
"resolveJsonModule": true,
|
|
8
|
+
"declaration": false,
|
|
9
|
+
"allowSyntheticDefaultImports": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"strict": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"outDir": ".",
|
|
15
|
+
"types": [ "node" ]
|
|
16
|
+
},
|
|
17
|
+
"include": [
|
|
18
|
+
"nunjucks.ts"
|
|
19
|
+
],
|
|
20
|
+
"exclude": [
|
|
21
|
+
"node_modules"
|
|
22
|
+
]
|
|
23
|
+
}
|