@rse/nunjucks-cli 1.5.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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=1.5.2
9
- ARG IMAGE_RELEASE=20240311
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:20.11-alpine3.18
13
+ FROM node:24-alpine3.23
14
14
 
15
15
  # add additional build tools
16
16
  RUN apk update && \
package/README.md CHANGED
@@ -98,7 +98,7 @@ Hello, world!
98
98
  License
99
99
  -------
100
100
 
101
- Copyright © 2019-2024 Dr. Ralf S. Engelschall (http://engelschall.com/)
101
+ Copyright © 2019-2025 Dr. Ralf S. Engelschall (http://engelschall.com/)
102
102
 
103
103
  Permission is hereby granted, free of charge, to any person obtaining
104
104
  a copy of this software and associated documentation files (the
package/eslint.mjs ADDED
@@ -0,0 +1,70 @@
1
+ /*
2
+ ** nunjucks -- Nunjucks Template Rendering Command-Line Interface
3
+ ** Copyright (c) 2019-2025 Dr. Ralf S. Engelschall <http://engelschall.com>
4
+ ** Licensed under MIT <http://spdx.org/licenses/MIT.html>
5
+ */
6
+
7
+ import pluginJs from "@eslint/js"
8
+ import pluginStd from "neostandard"
9
+ import pluginN from "eslint-plugin-n"
10
+ import pluginImport from "eslint-plugin-import"
11
+ import pluginPromise from "eslint-plugin-promise"
12
+ import pluginTS from "typescript-eslint"
13
+ import globals from "globals"
14
+
15
+ export default [
16
+ pluginJs.configs.recommended,
17
+ ...pluginTS.configs.recommended,
18
+ ...pluginStd({
19
+ ignores: pluginStd.resolveIgnoresFromGitignore()
20
+ }),
21
+ {
22
+ plugins: {
23
+ "n": pluginN,
24
+ "import": pluginImport,
25
+ "promise": pluginPromise
26
+ },
27
+ files: [ "**/*.js", "**/*.ts" ],
28
+ ignores: [ "dst/" ],
29
+ languageOptions: {
30
+ ecmaVersion: 2022,
31
+ sourceType: "module",
32
+ globals: {
33
+ ...globals.browser,
34
+ ...globals.node,
35
+ ...globals.commonjs,
36
+ ...globals.worker,
37
+ ...globals.serviceworker
38
+ }
39
+ },
40
+ rules: {
41
+ "curly": "off",
42
+ "require-atomic-updates": "off",
43
+ "dot-notation": "off",
44
+ "no-labels": "off",
45
+ "no-useless-constructor": "off",
46
+ "no-dupe-class-members": "off",
47
+
48
+ "@stylistic/indent": [ "error", 4, { SwitchCase: 1 } ],
49
+ "@stylistic/linebreak-style": [ "error", "unix" ],
50
+ "@stylistic/semi": [ "error", "never" ],
51
+ "@stylistic/operator-linebreak": [ "error", "after", { overrides: { "&&": "before", "||": "before", ":": "after" } } ],
52
+ "@stylistic/brace-style": [ "error", "stroustrup", { allowSingleLine: true } ],
53
+ "@stylistic/quotes": [ "error", "double" ],
54
+
55
+ "@stylistic/no-multi-spaces": "off",
56
+ "@stylistic/no-multiple-empty-lines": "off",
57
+ "@stylistic/key-spacing": "off",
58
+ "@stylistic/object-property-newline": "off",
59
+ "@stylistic/space-in-parens": "off",
60
+ "@stylistic/array-bracket-spacing": "off",
61
+ "@stylistic/lines-between-class-members": "off",
62
+ "@stylistic/multiline-ternary": "off",
63
+ "@stylistic/quote-props": "off",
64
+
65
+ "@typescript-eslint/no-explicit-any": "off",
66
+ "@typescript-eslint/no-unused-vars": [ "error", { "argsIgnorePattern": "^_", "caughtErrorsIgnorePattern": "^_" } ]
67
+ }
68
+ }
69
+ ]
70
+
package/nunjucks.1 CHANGED
@@ -1,4 +1,4 @@
1
- .TH "NUNJUCKS" "1" "August 2023" "" ""
1
+ .TH "NUNJUCKS" "1" "June 2025" "" ""
2
2
  .SH "NAME"
3
3
  \fBnunjucks\fR - Template Rendering Engine
4
4
  .SH "SYNOPSIS"
@@ -14,21 +14,21 @@ The following top-level options and arguments exist:
14
14
  .IP \(bu 4
15
15
  \[lB]\fB-h\fR|\fB--help\fR\[rB] Show usage help.
16
16
  .IP \(bu 4
17
- \[lB]\fB-V\fR|\fB--version\fR\[rB] show program version information.
17
+ \[lB]\fB-V\fR|\fB--version\fR\[rB] Show program version information.
18
18
  .IP \(bu 4
19
- \[lB]\fB-c\fR|\fB--config\fR \fIconfig-file\fR\[rB] load Nunjucks configuration YAML file.
19
+ \[lB]\fB-c\fR|\fB--config\fR \fIconfig-file\fR\[rB] Load Nunjucks configuration YAML file.
20
20
  .IP \(bu 4
21
- \[lB]\fB-C\fR|\fB--option\fR \fIkey\fR=\fIvalue\fR\[rB] set Nunjucks configuration option.
21
+ \[lB]\fB-C\fR|\fB--option\fR \fIkey\fR=\fIvalue\fR\[rB] Set Nunjucks configuration option.
22
22
  .IP \(bu 4
23
- \[lB]\fB-d\fR|\fB--defines\fR \fIcontext-file\fR\[rB] load context definition YAML file.
23
+ \[lB]\fB-d\fR|\fB--defines\fR \fIcontext-file\fR\[rB] Load context definition YAML file. Can occur multiple times.
24
24
  .IP \(bu 4
25
- \[lB]\fB-D\fR|\fB--define\fR \fIkey\fR=\fIvalue\fR\[rB] set context definition key/value.
25
+ \[lB]\fB-D\fR|\fB--define\fR \fIkey\fR=\fIvalue\fR\[rB] Set context definition key/value. Can occur multiple times.
26
26
  .IP \(bu 4
27
- \[lB]\fB-e\fR|\fB--extension\fR \fImodule-name\fR\[rB] load Nunjucks JavaScript extension module (installed via NPM).
27
+ \[lB]\fB-e\fR|\fB--extension\fR \fImodule-name\fR\[rB] Load Nunjucks JavaScript extension module (installed via NPM).
28
28
  .IP \(bu 4
29
- \[lB]\fB-o\fR|\fB--output\fR \fIoutput-file\fR|\fB-\fR\[rB] save output file (or stdout).
29
+ \[lB]\fB-o\fR|\fB--output\fR \fIoutput-file\fR|\fB-\fR\[rB] Save output file (or stdout).
30
30
  .IP \(bu 4
31
- \[lB]\fB<input-file>\fR|\fB-\fR\[rB] load input file (or stdin).
31
+ \[lB]\fB<input-file>\fR|\fB-\fR\[rB] Load input file (or stdin).
32
32
  .RE 0
33
33
 
34
34
  .SH "EXAMPLE"
@@ -1,40 +1,75 @@
1
1
  #!/usr/bin/env node
2
2
  /*
3
3
  ** nunjucks -- Nunjucks Template Rendering Command-Line Interface
4
- ** Copyright (c) 2019-2024 Dr. Ralf S. Engelschall <http://engelschall.com>
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
7
 
8
- /* own information */
9
- const my = require("./package.json")
10
-
11
- /* internal requirements */
12
- const fs = require("node:fs")
13
- const path = require("node:path")
8
+ /* built-in requirements */
9
+ import fs from "node:fs"
10
+ import path from "node:path"
11
+ import { createRequire } from "node:module"
14
12
 
15
13
  /* external requirements */
16
- const commander = require("commander")
17
- const chalk = require("chalk")
18
- const jsYAML = require("js-yaml")
19
- const nunjucks = require("nunjucks")
20
- const deepmerge = require("deepmerge")
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"))
21
52
 
22
53
  /* parse command-line arguments */
23
- const program = new commander.Command()
54
+ const program = new Command()
55
+ const reduceArray = (v: string, l: string[]) => l.concat([ v ])
24
56
  program.name("nunjucks")
25
57
  .description("Nunjucks Template Rendering Command-Line Interface")
26
58
  .showHelpAfterError("hint: use option --help for usage information")
27
- .option("-h, --help", "show usage help", false)
28
- .option("-V, --version", "show program version information", false)
29
- .option("-c, --config <config-file>", "load Nunjucks configuration YAML file", "")
30
- .option("-C, --option <key>=<value>", "set Nunjucks configuration option", (v, l) => l.concat([ v ]), [])
31
- .option("-d, --defines <context-file>", "load context definition YAML file", (v, l) => l.concat([ v ]), [])
32
- .option("-D, --define <key>=<value>", "set context definition key/value", (v, l) => l.concat([ v ]), [])
33
- .option("-e, --extension <module-name>", "load Nunjucks JavaScript extension module", (v, l) => l.concat([ v ]), [])
34
- .option("-o, --output <output-file>", "save output file", "-")
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", "-")
35
67
  .argument("[<input-file>]", "input file")
36
68
  program.parse(process.argv)
37
- const argv = { ...program.opts(), _: program.args }
69
+ const argv: CLIOptions = {
70
+ ...program.opts(),
71
+ _: program.args
72
+ } as CLIOptions
38
73
 
39
74
  /* handle special help request */
40
75
  if (argv.help) {
@@ -47,7 +82,7 @@ if (argv.help) {
47
82
  if (argv.version) {
48
83
  console.log(`${my.name} ${my.version} (Node.js ${process.versions.node}, Nunjucks: ${my.dependencies.nunjucks})`)
49
84
  console.log(`${my.description}`)
50
- console.log(`Copyright (c) 2019-2024 ${my.author.name} <${my.author.url}>`)
85
+ console.log(`Copyright (c) 2019-2025 ${my.author.name} <${my.author.url}>`)
51
86
  console.log(`Licensed under ${my.license} <http://spdx.org/licenses/${my.license}.html>`)
52
87
  process.exit(0)
53
88
  }
@@ -58,7 +93,7 @@ if (argv._.length > 1) {
58
93
  console.error(chalk.red("nunjucks: ERROR: invalid number of arguments (zero or one input file expected)"))
59
94
  process.exit(1)
60
95
  }
61
- let inputFile = argv._[0] ?? "-"
96
+ let inputFile: string = argv._[0] ?? "-"
62
97
  if (inputFile === "-") {
63
98
  inputFile = "<stdin>"
64
99
  process.stdin.setEncoding("utf-8")
@@ -67,9 +102,9 @@ if (inputFile === "-") {
67
102
  while (true) {
68
103
  let bytesRead = 0
69
104
  try {
70
- bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE)
105
+ bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE, null)
71
106
  }
72
- catch (ex) {
107
+ catch (ex: any) {
73
108
  if (ex.code === "EAGAIN") continue
74
109
  else if (ex.code === "EOF") break
75
110
  else throw ex
@@ -88,12 +123,12 @@ else {
88
123
  }
89
124
 
90
125
  /* provide context variables for template */
91
- let context = {}
126
+ let context: ContextType = {}
92
127
  for (const define of argv.defines) {
93
128
  try {
94
- context = deepmerge(context, jsYAML.load(fs.readFileSync(define, { encoding: "utf8" })))
129
+ context = deepmerge(context, jsYAML.load(fs.readFileSync(define, { encoding: "utf8" })) as ContextType)
95
130
  }
96
- catch (ex) {
131
+ catch (ex: any) {
97
132
  console.error(chalk.red(`nunjucks: ERROR: failed to load context YAML file: ${ex.toString()}`))
98
133
  process.exit(1)
99
134
  }
@@ -103,46 +138,53 @@ for (const define of argv.defines) {
103
138
  context.env = process.env
104
139
 
105
140
  /* add context defines */
106
- argv.define.forEach((define) => {
107
- let [ , key, val ] = define.match(/^([^=]+)(?:=(.*))?$/)
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
108
148
  if (val === undefined)
109
- val = true
149
+ val = "true"
110
150
  context[key] = val
111
151
  })
112
152
 
113
153
  /* determine Nunjucks options */
114
- let options = {}
154
+ let options: OptionsType = {}
115
155
  if (argv.config) {
116
156
  try {
117
- options = jsYAML.load(fs.readFileSync(argv.config, { encoding: "utf8" }))
157
+ options = jsYAML.load(fs.readFileSync(argv.config, { encoding: "utf8" })) as OptionsType
118
158
  }
119
- catch (ex) {
159
+ catch (ex: any) {
120
160
  console.error(chalk.red(`nunjucks: ERROR: failed to load options YAML file: ${ex.toString()}`))
121
161
  process.exit(1)
122
162
  }
123
163
  }
124
164
  if (argv.option.length > 0)
125
165
  options = Object.assign(options, argv.option)
126
- options = Object.assign({}, {
166
+ options = {
127
167
  autoescape: false,
128
168
  throwOnUndefined: false,
129
169
  trimBlocks: true,
130
170
  lstripBlocks: true,
131
171
  watch: false,
132
- noCache: true
133
- }, options)
172
+ noCache: true,
173
+ ...options
174
+ }
134
175
 
135
176
  /* configure environment */
136
177
  const env = nunjucks.configure(inputFile, options)
137
178
 
138
179
  /* load external extension files */
139
180
  for (const extension of argv.extension) {
140
- let modpath = path.resolve(extension)
181
+ let modpath: string | null = path.resolve(extension)
141
182
  if (!fs.existsSync(modpath)) {
142
183
  try {
184
+ const require = createRequire(import.meta.url)
143
185
  modpath = require.resolve(extension)
144
186
  }
145
- catch (ex) {
187
+ catch (_ex) {
146
188
  modpath = null
147
189
  }
148
190
  }
@@ -150,7 +192,19 @@ for (const extension of argv.extension) {
150
192
  console.error(chalk.red(`nunjucks: ERROR: failed to find extension module: ${extension}`))
151
193
  process.exit(1)
152
194
  }
153
- const mod = require(modpath)
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
+ }
154
208
  if (!(mod !== null && typeof mod === "function")) {
155
209
  console.error(chalk.red(`nunjucks: ERROR: failed to call extension file: ${modpath}`))
156
210
  process.exit(1)
@@ -159,11 +213,11 @@ for (const extension of argv.extension) {
159
213
  }
160
214
 
161
215
  /* render Nunjucks template */
162
- let output
216
+ let output: string
163
217
  try {
164
218
  output = env.renderString(input, context)
165
219
  }
166
- catch (ex) {
220
+ catch (ex: any) {
167
221
  console.error(chalk.red(`nunjucks: ERROR: failed to render template: ${ex.toString()}`))
168
222
  process.exit(1)
169
223
  }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@rse/nunjucks-cli",
3
3
  "publishConfig": { "access": "public" },
4
- "version": "1.5.3",
5
- "stdver": "1.5.3-GA",
4
+ "version": "2.0.0",
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",
@@ -18,30 +18,43 @@
18
18
  "url": "http://github.com/rse/nunjucks-cli/issues"
19
19
  },
20
20
  "bin": {
21
- "nunjucks": "nunjucks.js"
21
+ "nunjucks": "nunjucks.ts"
22
22
  },
23
23
  "man": "nunjucks.1",
24
+ "type": "module",
25
+ "engines": {
26
+ "node": ">=22.18.0"
27
+ },
24
28
  "dependencies": {
25
29
  "nunjucks": "3.2.4",
26
- "chalk": "4.1.0",
27
- "commander": "12.1.0",
28
- "js-yaml": "4.1.0",
30
+ "chalk": "5.6.2",
31
+ "commander": "14.0.2",
32
+ "js-yaml": "4.1.1",
29
33
  "deepmerge": "4.3.1"
30
34
  },
31
35
  "devDependencies": {
32
- "eslint": "8.57.0",
33
- "eslint-config-standard": "17.1.0",
34
- "eslint-plugin-promise": "6.2.0",
35
- "eslint-plugin-import": "2.29.1",
36
- "eslint-plugin-node": "11.1.0",
36
+ "eslint": "9.39.2",
37
+ "@eslint/js": "9.39.2",
38
+ "neostandard": "0.12.2",
39
+ "eslint-plugin-promise": "7.2.1",
40
+ "eslint-plugin-import": "2.32.0",
41
+ "eslint-plugin-n": "17.23.1",
42
+ "globals": "16.5.0",
37
43
  "remark-cli": "12.0.1",
38
44
  "remark": "15.0.1",
39
- "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"
40
55
  },
41
- "upd": [ "!chalk" ],
42
56
  "scripts": {
43
- "lint": "eslint --config eslint.yaml nunjucks.js",
44
- "man": "remark --quiet --use remark-man --output nunjucks.1 nunjucks.md",
45
- "test": "echo 'Hello, {{who}}!' | node nunjucks.js -D who=world -"
57
+ "start": "stx -v4 -c stx.conf",
58
+ "test": "npm start test"
46
59
  }
47
60
  }
package/stx.conf ADDED
@@ -0,0 +1,90 @@
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 --project tsconfig.json
11
+
12
+ # build manual page
13
+ man
14
+ remark --quiet --use remark-man --output nunjucks.1 nunjucks.md
15
+
16
+ # execute simple smole test
17
+ test
18
+ echo 'Hello, {{who}}!' | node nunjucks.ts -D who=world -
19
+
20
+ # build all-in-one packages
21
+ build:pkg [hostname=en4.*]
22
+
23
+ # package distribution archives
24
+ package : build:pkg [hostname=en4.*]
25
+ VERSION=`sed -n '/"version":/ s/.*: *"\(.*\)".*/\1/p' package.json` && \
26
+ targets="node24-linux-x64,node24-linux-arm64" && \
27
+ targets="$targets,node24-win-x64,node24-win-arm64" && \
28
+ targets="$targets,node24-macos-x64,node24-macos-arm64" && \
29
+ sed -e 's;@rse/nunjucks-cli;nunjucks;' <package.json >nunjucks.json && \
30
+ pkg --sea --public -c nunjucks.json -t "$targets" nunjucks.ts && \
31
+ rm -f nunjucks.json && \
32
+ shx mv nunjucks-linux-x64 nunjucks-lnx-x64 && \
33
+ shx mv nunjucks-linux-arm64 nunjucks-lnx-a64 && \
34
+ shx mv nunjucks-win-x64.exe nunjucks-win-x64.exe && \
35
+ shx mv nunjucks-win-arm64.exe nunjucks-win-a64.exe && \
36
+ shx mv nunjucks-macos-x64 nunjucks-mac-x64 && \
37
+ shx mv nunjucks-macos-arm64 nunjucks-mac-a64
38
+ mkdir -p nunjucks-$VERSION/ && \
39
+ mkdir -p nunjucks-$VERSION-win-x64/ && \
40
+ mkdir -p nunjucks-$VERSION-win-a64/ && \
41
+ mkdir -p nunjucks-$VERSION-mac-x64/ && \
42
+ mkdir -p nunjucks-$VERSION-mac-a64/ && \
43
+ mkdir -p nunjucks-$VERSION-lnx-x64/ && \
44
+ mkdir -p nunjucks-$VERSION-lnx-a64/ && \
45
+ cp -p nunjucks.ts nunjucks-$VERSION/nunjucks.ts && \
46
+ cp -p nunjucks-win-x64.exe nunjucks-$VERSION-win-x64/nunjucks.exe && \
47
+ cp -p nunjucks-win-a64.exe nunjucks-$VERSION-win-a64/nunjucks.exe && \
48
+ cp -p nunjucks-mac-x64 nunjucks-$VERSION-mac-x64/nunjucks && \
49
+ cp -p nunjucks-mac-a64 nunjucks-$VERSION-mac-a64/nunjucks && \
50
+ cp -p nunjucks-lnx-x64 nunjucks-$VERSION-lnx-x64/nunjucks && \
51
+ cp -p nunjucks-lnx-a64 nunjucks-$VERSION-lnx-a64/nunjucks && \
52
+ cp -p nunjucks.1 nunjucks-$VERSION/nunjucks.man && \
53
+ cp -p nunjucks.1 nunjucks-$VERSION-win-x64/nunjucks.man && \
54
+ cp -p nunjucks.1 nunjucks-$VERSION-win-a64/nunjucks.man && \
55
+ cp -p nunjucks.1 nunjucks-$VERSION-mac-x64/nunjucks.man && \
56
+ cp -p nunjucks.1 nunjucks-$VERSION-mac-a64/nunjucks.man && \
57
+ cp -p nunjucks.1 nunjucks-$VERSION-lnx-x64/nunjucks.man && \
58
+ cp -p nunjucks.1 nunjucks-$VERSION-lnx-a64/nunjucks.man && \
59
+ zip -9 -r nunjucks-$VERSION.zip nunjucks-$VERSION/ && \
60
+ zip -9 -r nunjucks-$VERSION-win-x64.zip nunjucks-$VERSION-win-x64/ && \
61
+ zip -9 -r nunjucks-$VERSION-win-a64.zip nunjucks-$VERSION-win-a64/ && \
62
+ zip -9 -r nunjucks-$VERSION-mac-x64.zip nunjucks-$VERSION-mac-x64/ && \
63
+ zip -9 -r nunjucks-$VERSION-mac-a64.zip nunjucks-$VERSION-mac-a64/ && \
64
+ zip -9 -r nunjucks-$VERSION-lnx-x64.zip nunjucks-$VERSION-lnx-x64/ && \
65
+ zip -9 -r nunjucks-$VERSION-lnx-a64.zip nunjucks-$VERSION-lnx-a64/
66
+
67
+ # publish distribution archives
68
+ publish : package [hostname=en4.*]
69
+ VERSION=`sed -n '/"version":/ s/.*: *"\(.*\)".*/\1/p' package.json` && \
70
+ V=`echo "$VERSION" | sed -e 's;\.;\\.;g'` && \
71
+ sed -n -e "/^${V} /, /^[0-9]\\./ { /^${V} /p; /^[0-9]\\./!p; }" <CHANGELOG.md >.notes.md && \
72
+ gh release create --title "Nunjucks $VERSION" --notes-file .notes.md --verify-tag $VERSION \
73
+ nunjucks-$VERSION.zip \
74
+ nunjucks-$VERSION-win-x64.zip \
75
+ nunjucks-$VERSION-win-a64.zip \
76
+ nunjucks-$VERSION-mac-x64.zip \
77
+ nunjucks-$VERSION-mac-a64.zip \
78
+ nunjucks-$VERSION-lnx-x64.zip \
79
+ nunjucks-$VERSION-lnx-a64.zip && \
80
+ rm -f .notes.md
81
+
82
+ # remove all generated artifacts
83
+ clean
84
+ shx rm -rf nunjucks-*.zip
85
+
86
+ # remove all generated artifacts
87
+ distclean: clean
88
+ shx rm -f package-lock.json && \
89
+ shx rm -rf node_modules
90
+
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
+ "allowImportingTsExtensions": true,
9
+ "allowSyntheticDefaultImports": true,
10
+ "esModuleInterop": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "strict": true,
13
+ "skipLibCheck": true,
14
+ "noEmit": true,
15
+ "types": [ "node" ]
16
+ },
17
+ "include": [
18
+ "nunjucks.ts"
19
+ ],
20
+ "exclude": [
21
+ "node_modules"
22
+ ]
23
+ }
package/eslint.yaml DELETED
@@ -1,51 +0,0 @@
1
- ##
2
- ## nunjucks -- Nunjucks Template Rendering Command-Line Interface
3
- ## Copyright (c) 2019-2024 Dr. Ralf S. Engelschall <http://engelschall.com>
4
- ## Licensed under MIT <http://spdx.org/licenses/MIT.html>
5
- ##
6
-
7
- ---
8
-
9
- extends:
10
- - eslint:recommended
11
- - eslint-config-standard
12
-
13
- parserOptions:
14
- ecmaVersion: 12
15
- sourceType: module
16
- ecmaFeatures:
17
- jsx: false
18
-
19
- env:
20
- browser: false
21
- node: true
22
- mocha: false
23
- commonjs: true
24
- worker: false
25
- serviceworker: false
26
-
27
- globals:
28
- process: true
29
-
30
- rules:
31
- # modified rules
32
- indent: [ "error", 4, { "SwitchCase": 1 } ]
33
- linebreak-style: [ "error", "unix" ]
34
- semi: [ "error", "never" ]
35
- operator-linebreak: [ "error", "after", { "overrides": { "&&": "before", "||": "before", ":": "after" } } ]
36
- brace-style: [ "error", "stroustrup", { "allowSingleLine": true } ]
37
- quotes: [ "error", "double" ]
38
-
39
- # disabled rules
40
- no-multi-spaces: off
41
- no-multiple-empty-lines: off
42
- key-spacing: off
43
- object-property-newline: off
44
- curly: off
45
- space-in-parens: off
46
- array-bracket-spacing: off
47
- require-atomic-updates: off
48
- dot-notation: off
49
- no-whitespace-before-property: off
50
- lines-between-class-members: off
51
-