state-machine-cat 10.1.2 → 10.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/smcat.mjs +5 -0
- package/dist/commonjs/bundle.js +64 -64
- package/package.json +40 -69
- package/src/cli/actions.mjs +9 -0
- package/src/cli/file-name-to-stream.mjs +5 -6
- package/src/cli/make-description.mjs +9 -0
- package/src/cli/normalize.mjs +100 -47
- package/src/cli/validations.mjs +27 -1
- package/src/index-node.mjs +15 -47
- package/src/index.mjs +9 -9
- package/src/options.mjs +19 -13
- package/src/parse/index.mjs +13 -0
- package/src/parse/parser-helpers.mjs +70 -6
- package/src/parse/scxml/index.mjs +72 -20
- package/src/parse/scxml/normalize-machine.mjs +27 -21
- package/src/render/dot/README.md +12 -0
- package/src/render/dot/attributebuilder.mjs +7 -0
- package/src/render/dot/counter.mjs +13 -0
- package/src/render/dot/index.mjs +66 -28
- package/src/render/dot/render-dot-from-ast.js +37 -15
- package/src/render/dot/state-transformers.mjs +4 -2
- package/src/render/dot/utl.mjs +20 -0
- package/src/render/index-node.mjs +9 -3
- package/src/render/index.mjs +3 -3
- package/src/render/scjson/index.mjs +6 -0
- package/src/render/scjson/make-valid-xml-name.mjs +7 -1
- package/src/render/scxml/index.mjs +2 -0
- package/src/render/smcat/index.js +48 -14
- package/src/render/vector/dot-to-vector-native.mjs +1 -1
- package/src/render/vector/vector-native-dot-with-fallback.mjs +3 -2
- package/src/render/vector/vector-with-viz-js.mjs +3 -2
- package/src/state-machine-model.mjs +46 -4
- package/src/transform/desugar.mjs +67 -18
- package/src/transform/utl.mjs +8 -0
- package/src/version.mjs +1 -1
- package/types/state-machine-cat.d.ts +41 -14
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "state-machine-cat",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.5",
|
|
4
4
|
"description": "write beautiful state charts",
|
|
5
5
|
"main": "./dist/commonjs/index.js",
|
|
6
6
|
"module": "./src/index.mjs",
|
|
@@ -38,10 +38,9 @@
|
|
|
38
38
|
"depcruise:graph:dev": "wireit",
|
|
39
39
|
"depcruise:graph:dev:flat": "wireit",
|
|
40
40
|
"depcruise:view-report": "wireit",
|
|
41
|
-
"depcruise:github-actions:markdown": "
|
|
42
|
-
"depcruise:github-actions:mermaid": "
|
|
43
|
-
"depcruise:github-actions:mermaid:affected": "
|
|
44
|
-
"depcruise:github-actions:mermaid:diff": "wireit",
|
|
41
|
+
"depcruise:github-actions:markdown": "depcruise bin src test types --config config/dependency-cruiser.js --output-type markdown",
|
|
42
|
+
"depcruise:github-actions:mermaid": "depcruise bin src --include-only '^(bin|src)' --config config/dependency-cruiser.js --output-type mermaid",
|
|
43
|
+
"depcruise:github-actions:mermaid:affected": "depcruise bin src test types tools --config config/dependency-cruiser.js --output-type mermaid --reaches \"$(watskeburt $SHA -T regex)\"",
|
|
45
44
|
"lint": "wireit",
|
|
46
45
|
"lint:eslint": "wireit",
|
|
47
46
|
"lint:prettier": "wireit",
|
|
@@ -90,11 +89,6 @@
|
|
|
90
89
|
"policy": "wanted",
|
|
91
90
|
"because": "fast-xml-parser 4 has some breaking changes we still need to grok (why? how?)"
|
|
92
91
|
},
|
|
93
|
-
{
|
|
94
|
-
"package": "husky",
|
|
95
|
-
"policy": "pin",
|
|
96
|
-
"because": "(npm7 & husky don't play nice together - and it might be it's not going to be solved satisfactorily) https://github.com/typicode/husky/issues/822 "
|
|
97
|
-
},
|
|
98
92
|
{
|
|
99
93
|
"package": "viz.js",
|
|
100
94
|
"policy": "pin",
|
|
@@ -120,7 +114,7 @@
|
|
|
120
114
|
"packageLocks": []
|
|
121
115
|
},
|
|
122
116
|
"depcruise:json": {
|
|
123
|
-
"command": "dependency-cruise --progress
|
|
117
|
+
"command": "dependency-cruise --progress performance-log --output-type json --output-to node_modules/.cache/depcruise-cache.json --config config/dependency-cruiser.js src test bin",
|
|
124
118
|
"files": [
|
|
125
119
|
"src/**/*",
|
|
126
120
|
"test/**/*",
|
|
@@ -244,13 +238,13 @@
|
|
|
244
238
|
]
|
|
245
239
|
},
|
|
246
240
|
"depcruise:graph:dev": {
|
|
247
|
-
"command": "depcruise-fmt node_modules/.cache/depcruise-cache.json --output-type dot --include-only '^(bin|src|package\\.json)' --prefix vscode://file/$(pwd)/ | dot -Tsvg | depcruise-wrap-stream-in-html | browser",
|
|
241
|
+
"command": "depcruise-fmt node_modules/.cache/depcruise-cache.json --output-type dot --include-only '^(bin|src|package\\.json)' --prefix vscode://file/$(pwd)/ --highlight \"$(watskeburt develop)\"| dot -Tsvg | depcruise-wrap-stream-in-html | browser",
|
|
248
242
|
"dependencies": [
|
|
249
243
|
"depcruise:json"
|
|
250
244
|
]
|
|
251
245
|
},
|
|
252
246
|
"depcruise:graph:dev:flat": {
|
|
253
|
-
"command": "depcruise-fmt node_modules/.cache/depcruise-cache.json --output-type flat --include-only '^(bin|src|package\\.json)' --prefix vscode://file/$(pwd)/ | twopi -Tsvg | depcruise-wrap-stream-in-html | browser",
|
|
247
|
+
"command": "depcruise-fmt node_modules/.cache/depcruise-cache.json --output-type flat --include-only '^(bin|src|package\\.json)' --prefix vscode://file/$(pwd)/ --highlight \"$(watskeburt develop)\"| twopi -Tsvg | depcruise-wrap-stream-in-html | browser",
|
|
254
248
|
"dependencies": [
|
|
255
249
|
"depcruise:json"
|
|
256
250
|
]
|
|
@@ -261,30 +255,6 @@
|
|
|
261
255
|
"depcruise:json"
|
|
262
256
|
]
|
|
263
257
|
},
|
|
264
|
-
"depcruise:github-actions:markdown": {
|
|
265
|
-
"command": "depcruise-fmt node_modules/.cache/depcruise-cache.json --output-type markdown >> $GITHUB_STEP_SUMMARY",
|
|
266
|
-
"dependencies": [
|
|
267
|
-
"depcruise:json"
|
|
268
|
-
]
|
|
269
|
-
},
|
|
270
|
-
"depcruise:github-actions:mermaid": {
|
|
271
|
-
"command": "echo '\n\n```mermaid' >> $GITHUB_STEP_SUMMARY && depcruise-fmt node_modules/.cache/depcruise-cache.json --include-only '^(bin|src)' --output-type mermaid >> $GITHUB_STEP_SUMMARY && echo '```\n\n' >> $GITHUB_STEP_SUMMARY",
|
|
272
|
-
"dependencies": [
|
|
273
|
-
"depcruise:json"
|
|
274
|
-
]
|
|
275
|
-
},
|
|
276
|
-
"depcruise:github-actions:mermaid:affected": {
|
|
277
|
-
"command": "echo '\n\n```mermaid' >> $GITHUB_STEP_SUMMARY && depcruise-fmt node_modules/.cache/depcruise-cache.json --include-only --reaches '$(watskeburt $SHA -T regex)' --output-type mermaid >> $GITHUB_STEP_SUMMARY && echo '```\n\n' >> $GITHUB_STEP_SUMMARY",
|
|
278
|
-
"dependencies": [
|
|
279
|
-
"depcruise:json"
|
|
280
|
-
]
|
|
281
|
-
},
|
|
282
|
-
"depcruise:github-actions:mermaid:diff": {
|
|
283
|
-
"command": "echo '\n\n```mermaid' >> $GITHUB_STEP_SUMMARY && depcruise-fmt node_modules/.cache/depcruise-cache.json --include-only '^(bin|src)' --highlight '$(watskeburt $SHA -T regex)' --output-type mermaid >> $GITHUB_STEP_SUMMARY && echo '```\n\n' >> $GITHUB_STEP_SUMMARY",
|
|
284
|
-
"dependencies": [
|
|
285
|
-
"depcruise:json"
|
|
286
|
-
]
|
|
287
|
-
},
|
|
288
258
|
"lint": {
|
|
289
259
|
"dependencies": [
|
|
290
260
|
"lint:eslint",
|
|
@@ -301,7 +271,7 @@
|
|
|
301
271
|
]
|
|
302
272
|
},
|
|
303
273
|
"lint:prettier": {
|
|
304
|
-
"command": "prettier --check \"bin/*.mjs\" \"{src,test}/**/*.{js,mjs}\" \"{config,test}/**/*.{js,json}\" \"tools/*.{js,mjs,json}\" \"types
|
|
274
|
+
"command": "prettier --check \"bin/*.mjs\" \"{src,test}/**/*.{js,mjs}\" \"{config,test}/**/*.{js,json}\" \"tools/*.{js,mjs,json}\" \"{src,types}/**/*.{ts,mts}\" \"*.{json,yml,md}\" \"docs/{smcat-online-interpreter.js,*.md}\"",
|
|
305
275
|
"files": [
|
|
306
276
|
"bin/*.mjs",
|
|
307
277
|
"{src,test}/**/*.{js,mjs}",
|
|
@@ -319,15 +289,15 @@
|
|
|
319
289
|
]
|
|
320
290
|
},
|
|
321
291
|
"lint:types:tsc": {
|
|
322
|
-
"command": "tsc --noEmit --strict --types --noUnusedLocals --noUnusedParameters --pretty types/*.d.ts",
|
|
292
|
+
"command": "tsc --noEmit --strict --types --noUnusedLocals --noUnusedParameters --pretty types/*.d.ts src/cli/*.d.mts src/cli/*.d.ts src/parse/scxml/*.d.ts",
|
|
323
293
|
"files": [
|
|
324
294
|
"types/*.d.ts"
|
|
325
295
|
]
|
|
326
296
|
},
|
|
327
297
|
"lint:types:eslint": {
|
|
328
|
-
"command": "eslint types/*.d.ts",
|
|
298
|
+
"command": "eslint types/*.d.ts src/cli/*.d.mts src/cli/*.d.ts src/parse/scxml/*.d.ts",
|
|
329
299
|
"files": [
|
|
330
|
-
"types
|
|
300
|
+
"{src,types}/**/*.d.{ts,mts}",
|
|
331
301
|
".eslintrc.json"
|
|
332
302
|
]
|
|
333
303
|
},
|
|
@@ -347,10 +317,10 @@
|
|
|
347
317
|
]
|
|
348
318
|
},
|
|
349
319
|
"lint:fix:prettier": {
|
|
350
|
-
"command": "prettier --loglevel warn --write \"bin/*.mjs\" \"{src,test}/**/*.{js,mjs}\" \"{config,test}/**/*.{js,json}\" \"tools/*.{js,mjs,json}\" \"types
|
|
320
|
+
"command": "prettier --loglevel warn --write \"bin/*.mjs\" \"{src,test}/**/*.{js,mjs}\" \"{config,test}/**/*.{js,json}\" \"tools/*.{js,mjs,json}\" \"{src,types}/**/*.{ts,mts}\" \"*.{json,yml,md}\" \"docs/{smcat-online-interpreter.js,*.md}\"",
|
|
351
321
|
"files": [
|
|
352
322
|
"bin/*.mjs",
|
|
353
|
-
"{src,test}/**/*.{js,mjs}",
|
|
323
|
+
"{src,test}/**/*.{js,mjs,ts,mts}",
|
|
354
324
|
"{config,test}/**/*.{js,json}",
|
|
355
325
|
"tools/*.{js,mjs,json}",
|
|
356
326
|
"types/*.ts",
|
|
@@ -359,9 +329,9 @@
|
|
|
359
329
|
]
|
|
360
330
|
},
|
|
361
331
|
"lint:fix:types": {
|
|
362
|
-
"command": "eslint --fix types/*.d.ts",
|
|
332
|
+
"command": "eslint --fix types/*.d.ts src/cli/*.d.mts src/cli/*.d.ts src/parse/scxml/*.d.ts",
|
|
363
333
|
"files": [
|
|
364
|
-
"types
|
|
334
|
+
"{src,types}/**/*.d.{ts,mts}",
|
|
365
335
|
".eslintrc.json"
|
|
366
336
|
]
|
|
367
337
|
},
|
|
@@ -372,9 +342,10 @@
|
|
|
372
342
|
]
|
|
373
343
|
},
|
|
374
344
|
"test:cover": {
|
|
375
|
-
"command": "c8 --all --check-coverage --statements 100 --branches 99.1 --functions 100 --lines 100 --exclude \"{bin/*,config/**/*,coverage/**/*,docs/**/*,public/**/*,test/**/*,tools/**/*,types/**/*,dist/commonjs/*,src/**/*{template,-parser}.{mjs,cjs,js},tmp*}\" --reporter text-summary --reporter html --reporter lcov mocha",
|
|
345
|
+
"command": "c8 --all --check-coverage --statements 100 --branches 99.1 --functions 100 --lines 100 --exclude \"{bin/*,config/**/*,coverage/**/*,docs/**/*,public/**/*,test/**/*,tools/**/*,types/**/*,dist/commonjs/*,src/**/*.d.{ts,mts},src/**/*{template,-parser}.{mjs,cjs,js},tmp*}\" --reporter text-summary --reporter html --reporter lcov --reporter json-summary mocha",
|
|
376
346
|
"output": [
|
|
377
|
-
"coverage/lcov.info"
|
|
347
|
+
"coverage/lcov.info",
|
|
348
|
+
"coverage/coverage-summary.json"
|
|
378
349
|
],
|
|
379
350
|
"files": [
|
|
380
351
|
"{src,test}/**/*.{js,mjs,json}"
|
|
@@ -400,9 +371,9 @@
|
|
|
400
371
|
"state-machine-cat": "bin/smcat.mjs"
|
|
401
372
|
},
|
|
402
373
|
"dependencies": {
|
|
403
|
-
"ajv": "8.
|
|
404
|
-
"chalk": "5.
|
|
405
|
-
"commander": "
|
|
374
|
+
"ajv": "8.12.0",
|
|
375
|
+
"chalk": "5.2.0",
|
|
376
|
+
"commander": "10.0.0",
|
|
406
377
|
"fast-xml-parser": "3.21.1",
|
|
407
378
|
"get-stream": "6.0.1",
|
|
408
379
|
"handlebars": "4.7.7",
|
|
@@ -414,38 +385,38 @@
|
|
|
414
385
|
"wrap-ansi": "8.0.1"
|
|
415
386
|
},
|
|
416
387
|
"devDependencies": {
|
|
417
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
418
|
-
"@typescript-eslint/parser": "5.
|
|
388
|
+
"@typescript-eslint/eslint-plugin": "5.48.2",
|
|
389
|
+
"@typescript-eslint/parser": "5.48.2",
|
|
419
390
|
"c8": "7.12.0",
|
|
420
|
-
"chai": "4.3.
|
|
391
|
+
"chai": "4.3.7",
|
|
421
392
|
"chai-as-promised": "7.1.1",
|
|
422
393
|
"chai-json-schema": "1.5.1",
|
|
423
394
|
"chai-xml": "0.4.0",
|
|
424
|
-
"dependency-cruiser": "
|
|
425
|
-
"esbuild": "0.
|
|
426
|
-
"eslint": "8.
|
|
395
|
+
"dependency-cruiser": "12.5.1",
|
|
396
|
+
"esbuild": "0.17.3",
|
|
397
|
+
"eslint": "8.32.0",
|
|
427
398
|
"eslint-config-moving-meadow": "4.0.2",
|
|
428
|
-
"eslint-config-prettier": "8.
|
|
399
|
+
"eslint-config-prettier": "8.6.0",
|
|
429
400
|
"eslint-plugin-budapestian": "5.0.1",
|
|
430
401
|
"eslint-plugin-eslint-comments": "3.2.0",
|
|
431
|
-
"eslint-plugin-import": "2.
|
|
402
|
+
"eslint-plugin-import": "2.27.5",
|
|
432
403
|
"eslint-plugin-mocha": "10.1.0",
|
|
433
404
|
"eslint-plugin-node": "11.1.0",
|
|
434
|
-
"eslint-plugin-security": "1.
|
|
435
|
-
"eslint-plugin-unicorn": "
|
|
436
|
-
"husky": "8.0.
|
|
405
|
+
"eslint-plugin-security": "1.6.0",
|
|
406
|
+
"eslint-plugin-unicorn": "45.0.2",
|
|
407
|
+
"husky": "8.0.3",
|
|
437
408
|
"is-pdf": "1.0.0",
|
|
438
409
|
"is-png": "3.0.1",
|
|
439
|
-
"lint-staged": "13.0
|
|
440
|
-
"mocha": "10.
|
|
410
|
+
"lint-staged": "13.1.0",
|
|
411
|
+
"mocha": "10.2.0",
|
|
441
412
|
"npm-run-all": "4.1.5",
|
|
442
413
|
"peggy": "2.0.1",
|
|
443
|
-
"prettier": "2.
|
|
444
|
-
"query-string": "
|
|
445
|
-
"typescript": "4.
|
|
446
|
-
"upem": "7.3.
|
|
447
|
-
"watskeburt": "0.
|
|
448
|
-
"wireit": "0.
|
|
414
|
+
"prettier": "2.8.3",
|
|
415
|
+
"query-string": "8.1.0",
|
|
416
|
+
"typescript": "4.9.4",
|
|
417
|
+
"upem": "7.3.1",
|
|
418
|
+
"watskeburt": "0.9.0",
|
|
419
|
+
"wireit": "0.9.3",
|
|
449
420
|
"xml-name-validator": "4.0.0"
|
|
450
421
|
},
|
|
451
422
|
"eslintIgnore": [
|
package/src/cli/actions.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import getStream from "get-stream";
|
|
2
3
|
import smcat from "../index-node.mjs";
|
|
3
4
|
import { getOutStream, getInStream } from "./file-name-to-stream.mjs";
|
|
@@ -31,7 +32,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
31
32
|
`;
|
|
32
33
|
|
|
33
34
|
export default {
|
|
35
|
+
/** @type {string} */
|
|
34
36
|
LICENSE,
|
|
37
|
+
/**
|
|
38
|
+
* @param {import("./cli").ICLIRenderOptions} pOptions
|
|
39
|
+
*/
|
|
35
40
|
transform(pOptions) {
|
|
36
41
|
return getStream(getInStream(pOptions.inputFrom)).then((pInput) => {
|
|
37
42
|
const lOutput = smcat.render(pInput, {
|
|
@@ -54,6 +59,10 @@ export default {
|
|
|
54
59
|
});
|
|
55
60
|
},
|
|
56
61
|
|
|
62
|
+
/**
|
|
63
|
+
* @param {any} pError
|
|
64
|
+
* @returns {string}
|
|
65
|
+
*/
|
|
57
66
|
formatError(pError) {
|
|
58
67
|
if (Boolean(pError.location)) {
|
|
59
68
|
return `\n syntax error on line ${pError.location.start.line}, column ${pError.location.start.column}:\n ${pError.message}\n\n`;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
/* eslint-disable security/detect-non-literal-fs-filename */
|
|
2
|
-
|
|
3
|
-
import * as fs from "node:fs";
|
|
3
|
+
import fs from "node:fs";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
6
|
* @param {string} pOutputTo
|
|
8
|
-
* @returns {
|
|
7
|
+
* @returns {NodeJS.WritableStream}
|
|
9
8
|
*/
|
|
10
9
|
export function getOutStream(pOutputTo) {
|
|
11
10
|
if ("-" === pOutputTo) {
|
|
@@ -13,10 +12,10 @@ export function getOutStream(pOutputTo) {
|
|
|
13
12
|
}
|
|
14
13
|
return fs.createWriteStream(pOutputTo);
|
|
15
14
|
}
|
|
15
|
+
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
17
|
* @param {string} pInputFrom
|
|
19
|
-
* @returns {
|
|
18
|
+
* @returns {NodeJS.ReadableStream}
|
|
20
19
|
*/
|
|
21
20
|
export function getInStream(pInputFrom) {
|
|
22
21
|
if ("-" === pInputFrom) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
// seems eslint-plugin-import and eslint-plugin-node can't handle exports
|
|
2
3
|
// fields yet. No man overboard not checking against this, because dependency-cruiser
|
|
3
4
|
// will also find them
|
|
@@ -7,6 +8,10 @@ import indentString from "indent-string";
|
|
|
7
8
|
import wrapAnsi from "wrap-ansi";
|
|
8
9
|
import dotToVectorNative from "../render/vector/dot-to-vector-native.mjs";
|
|
9
10
|
|
|
11
|
+
/**
|
|
12
|
+
* @param {string} pString
|
|
13
|
+
* @returns {string}
|
|
14
|
+
*/
|
|
10
15
|
function wrapAndIndent(pString) {
|
|
11
16
|
const lDogmaticMaxConsoleWidth = 78;
|
|
12
17
|
const lDefaultIndent = 2;
|
|
@@ -16,6 +21,10 @@ function wrapAndIndent(pString) {
|
|
|
16
21
|
return indentString(wrapAnsi(pString, lMaxWidth), lDefaultIndent);
|
|
17
22
|
}
|
|
18
23
|
|
|
24
|
+
/**
|
|
25
|
+
* @param {boolean} pDotIsAvailable
|
|
26
|
+
* @return {string}
|
|
27
|
+
*/
|
|
19
28
|
export default (pDotIsAvailable = dotToVectorNative.isAvailable({})) => {
|
|
20
29
|
const lDescription =
|
|
21
30
|
"Write beautiful state charts - https://github.com/sverweij/state-machine-cat";
|
package/src/cli/normalize.mjs
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
// @ts-check
|
|
2
|
+
/* eslint-disable security/detect-object-injection, no-inline-comments */
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import options from "../options.mjs";
|
|
4
5
|
import { parse as parseAttributes } from "./attributes-parser.mjs";
|
|
5
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {{[extension: string]: string}} DictionaryType
|
|
9
|
+
*/
|
|
10
|
+
|
|
6
11
|
const INPUT_EXTENSIONS = {
|
|
7
12
|
".smcat": "smcat",
|
|
8
13
|
".scxml": "scxml",
|
|
@@ -10,17 +15,20 @@ const INPUT_EXTENSIONS = {
|
|
|
10
15
|
".json": "json",
|
|
11
16
|
".ast": "json",
|
|
12
17
|
};
|
|
18
|
+
|
|
13
19
|
const OUTPUT_EXTENSIONS = {
|
|
14
|
-
".
|
|
20
|
+
".ast": "json",
|
|
15
21
|
".dot": "dot",
|
|
22
|
+
".eps": "eps",
|
|
16
23
|
".json": "json",
|
|
17
|
-
".
|
|
24
|
+
".pdf": "pdf",
|
|
25
|
+
".png": "png",
|
|
26
|
+
".ps": "ps",
|
|
27
|
+
".ps2": "ps2",
|
|
18
28
|
".scjson": "scjson",
|
|
19
29
|
".scxml": "scxml",
|
|
30
|
+
".smcat": "smcat",
|
|
20
31
|
".svg": "svg",
|
|
21
|
-
".ps": "ps",
|
|
22
|
-
".ps2": "ps2",
|
|
23
|
-
".eps": "eps",
|
|
24
32
|
};
|
|
25
33
|
|
|
26
34
|
/**
|
|
@@ -31,7 +39,7 @@ const OUTPUT_EXTENSIONS = {
|
|
|
31
39
|
* When in doubt returns pDefault
|
|
32
40
|
*
|
|
33
41
|
* @param {string} pString - filename
|
|
34
|
-
* @param {
|
|
42
|
+
* @param {DictionaryType} pExtensionMap - a dictionary with
|
|
35
43
|
* extension : classification pairs
|
|
36
44
|
* @param {string} pDefault - the default to return when the extension
|
|
37
45
|
* does not occur in the extension map
|
|
@@ -42,15 +50,26 @@ function classifyExtension(pString, pExtensionMap, pDefault) {
|
|
|
42
50
|
return pExtensionMap[path.extname(pString)] || pDefault;
|
|
43
51
|
}
|
|
44
52
|
|
|
53
|
+
/**
|
|
54
|
+
* @param {import("../..").OutputType} pOutputType
|
|
55
|
+
* @returns {import("../..").OutputType}
|
|
56
|
+
*/
|
|
45
57
|
function outputType2Extension(pOutputType) {
|
|
46
58
|
const lExceptions = {
|
|
47
|
-
oldsvg: "svg",
|
|
48
|
-
oldps2: "ps",
|
|
49
59
|
oldeps: "eps",
|
|
60
|
+
oldps: "ps",
|
|
61
|
+
oldps2: "ps",
|
|
62
|
+
oldsvg: "svg",
|
|
50
63
|
ps2: "ps",
|
|
51
64
|
};
|
|
52
65
|
return lExceptions[pOutputType] || pOutputType;
|
|
53
66
|
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @param {string} pInputFrom
|
|
70
|
+
* @param {import("../..").OutputType} pOutputType
|
|
71
|
+
* @returns {string}
|
|
72
|
+
*/
|
|
54
73
|
function deriveOutputFromInput(pInputFrom, pOutputType) {
|
|
55
74
|
const lExtension = outputType2Extension(pOutputType);
|
|
56
75
|
|
|
@@ -66,46 +85,79 @@ function deriveOutputFromInput(pInputFrom, pOutputType) {
|
|
|
66
85
|
.concat(lExtension);
|
|
67
86
|
}
|
|
68
87
|
|
|
88
|
+
/**
|
|
89
|
+
* @param {string|undefined} pOutputTo
|
|
90
|
+
* @param {string} pInputFrom
|
|
91
|
+
* @param {import("../..").OutputType} pOutputType
|
|
92
|
+
* @returns {string}
|
|
93
|
+
*/
|
|
69
94
|
function determineOutputTo(pOutputTo, pInputFrom, pOutputType) {
|
|
70
|
-
return
|
|
71
|
-
? pOutputTo
|
|
72
|
-
: deriveOutputFromInput(pInputFrom, pOutputType);
|
|
95
|
+
return pOutputTo ? pOutputTo : deriveOutputFromInput(pInputFrom, pOutputType);
|
|
73
96
|
}
|
|
74
97
|
|
|
75
|
-
|
|
98
|
+
/**
|
|
99
|
+
* @param {string} pInputFrom
|
|
100
|
+
* @param {import("../..").InputType} [pInputType]
|
|
101
|
+
* @returns {import("../..").InputType}
|
|
102
|
+
*/
|
|
103
|
+
function determineInputType(pInputFrom, pInputType) {
|
|
76
104
|
if (pInputType) {
|
|
77
105
|
return pInputType;
|
|
78
106
|
}
|
|
107
|
+
// @ts-expect-error we can safely cast this to InputType. classifyExtension
|
|
108
|
+
// can probably use treatment with a generic, but with jsdoc annotations
|
|
109
|
+
// if at all possible would likely be awkward.
|
|
79
110
|
return classifyExtension(
|
|
80
111
|
pInputFrom,
|
|
81
112
|
INPUT_EXTENSIONS,
|
|
82
113
|
options.getAllowedValues().inputType.default
|
|
83
114
|
);
|
|
84
115
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
116
|
+
/**
|
|
117
|
+
*
|
|
118
|
+
* @param {string} [pOutputTo]
|
|
119
|
+
* @param {import("../..").OutputType} [pOutputType]
|
|
120
|
+
* @returns {import("../..").OutputType}
|
|
121
|
+
*/
|
|
122
|
+
function determineOutputType(pOutputTo, pOutputType) {
|
|
123
|
+
if (pOutputType) {
|
|
88
124
|
return pOutputType;
|
|
89
125
|
}
|
|
90
|
-
if (
|
|
126
|
+
if (pOutputTo) {
|
|
127
|
+
// @ts-expect-error we can safely cast this to OutputType. classifyExtension
|
|
128
|
+
// can probably use treatment with a generic, but with jsdoc annotations
|
|
129
|
+
// if at all possible would likely be awkward.
|
|
91
130
|
return classifyExtension(
|
|
92
131
|
pOutputTo,
|
|
93
132
|
OUTPUT_EXTENSIONS,
|
|
94
133
|
options.getAllowedValues().outputType.default
|
|
95
134
|
);
|
|
96
135
|
}
|
|
136
|
+
// @ts-expect-error cast to OutputType is safe - see above
|
|
97
137
|
return options.getAllowedValues().outputType.default;
|
|
98
138
|
}
|
|
99
|
-
|
|
139
|
+
/**
|
|
140
|
+
*
|
|
141
|
+
* @param {import("./cli").ILooseCLIRenderOptions} pOptions
|
|
142
|
+
* @param {string} pParameter
|
|
143
|
+
* @returns string
|
|
144
|
+
*/
|
|
100
145
|
function determineParameter(pOptions, pParameter) {
|
|
101
146
|
return Object.prototype.hasOwnProperty.call(pOptions, pParameter)
|
|
102
147
|
? pOptions[pParameter]
|
|
103
148
|
: options.getAllowedValues()[pParameter].default;
|
|
104
149
|
}
|
|
105
150
|
|
|
151
|
+
/**
|
|
152
|
+
* @param {Partial<import("./cli").ILooseCLIRenderOptions>} pOptions
|
|
153
|
+
* @param {keyof import("./cli").ILooseCLIRenderOptions} pDotAttributes
|
|
154
|
+
* @returns {import("../..").dotAttributesType}
|
|
155
|
+
*/
|
|
106
156
|
function determineDotAttributes(pOptions, pDotAttributes) {
|
|
107
|
-
return
|
|
108
|
-
|
|
157
|
+
return Boolean(pOptions?.[pDotAttributes]) &&
|
|
158
|
+
typeof pOptions[pDotAttributes] === "string"
|
|
159
|
+
? // @ts-expect-error parseAttributes expects a string - which we can guarantee (see above) - but tsc can't/ doesn't see it
|
|
160
|
+
parseAttributes(pOptions[pDotAttributes])
|
|
109
161
|
: [];
|
|
110
162
|
}
|
|
111
163
|
|
|
@@ -114,38 +166,39 @@ function determineDotAttributes(pOptions, pDotAttributes) {
|
|
|
114
166
|
*
|
|
115
167
|
* - guesses the input type when not given
|
|
116
168
|
* - guesses the output type when not given
|
|
117
|
-
* -
|
|
169
|
+
* - guesses the filename to output to when not given
|
|
118
170
|
* - translates parserOutput to a regular output type
|
|
119
171
|
*
|
|
120
172
|
* @param {string} pArgument an argument (containing the filename to parse)
|
|
121
|
-
* @param {
|
|
122
|
-
* @return {
|
|
173
|
+
* @param {import("./cli").ILooseCLIRenderOptions} pLooseOptions
|
|
174
|
+
* @return {import("./cli").ICLIRenderOptions}
|
|
175
|
+
* the passed options object, but normalized
|
|
123
176
|
*/
|
|
124
|
-
export default function normalize(pArgument = "-",
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
pOptions.inputType,
|
|
130
|
-
lReturnValue.inputFrom
|
|
131
|
-
);
|
|
132
|
-
lReturnValue.outputType = determineOutputType(
|
|
133
|
-
pOptions.outputType,
|
|
134
|
-
pOptions.outputTo
|
|
177
|
+
export default function normalize(pArgument = "-", pLooseOptions = {}) {
|
|
178
|
+
const lNormalizedInputFrom = pArgument || "-";
|
|
179
|
+
const lNormalizedInputType = determineInputType(
|
|
180
|
+
lNormalizedInputFrom,
|
|
181
|
+
pLooseOptions.inputType
|
|
135
182
|
);
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
lReturnValue.outputType
|
|
183
|
+
const lNormalizedOutputType = determineOutputType(
|
|
184
|
+
pLooseOptions.outputTo,
|
|
185
|
+
pLooseOptions.outputType
|
|
140
186
|
);
|
|
141
|
-
lReturnValue.engine = determineParameter(pOptions, "engine");
|
|
142
|
-
lReturnValue.direction = determineParameter(pOptions, "direction");
|
|
143
|
-
lReturnValue.dotGraphAttrs = determineDotAttributes(
|
|
144
|
-
pOptions,
|
|
145
|
-
"dotGraphAttrs"
|
|
146
|
-
);
|
|
147
|
-
lReturnValue.dotNodeAttrs = determineDotAttributes(pOptions, "dotNodeAttrs");
|
|
148
|
-
lReturnValue.dotEdgeAttrs = determineDotAttributes(pOptions, "dotEdgeAttrs");
|
|
149
187
|
|
|
150
|
-
return
|
|
188
|
+
return {
|
|
189
|
+
inputFrom: lNormalizedInputFrom,
|
|
190
|
+
inputType: lNormalizedInputType,
|
|
191
|
+
outputType: lNormalizedOutputType,
|
|
192
|
+
outputTo: determineOutputTo(
|
|
193
|
+
pLooseOptions.outputTo,
|
|
194
|
+
lNormalizedInputFrom,
|
|
195
|
+
lNormalizedOutputType
|
|
196
|
+
),
|
|
197
|
+
engine: determineParameter(pLooseOptions, "engine"),
|
|
198
|
+
direction: determineParameter(pLooseOptions, "direction"),
|
|
199
|
+
dotGraphAttrs: determineDotAttributes(pLooseOptions, "dotGraphAttrs"),
|
|
200
|
+
dotNodeAttrs: determineDotAttributes(pLooseOptions, "dotNodeAttrs"),
|
|
201
|
+
dotEdgeAttrs: determineDotAttributes(pLooseOptions, "dotEdgeAttrs"),
|
|
202
|
+
desugar: pLooseOptions?.desugar ?? false,
|
|
203
|
+
};
|
|
151
204
|
}
|
package/src/cli/validations.mjs
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import fs from "node:fs";
|
|
2
3
|
import smcat from "../index-node.mjs";
|
|
3
4
|
import { parse as parseAttributes } from "./attributes-parser.mjs";
|
|
4
5
|
|
|
5
6
|
const allowedValues = smcat.getAllowedValues();
|
|
6
7
|
|
|
8
|
+
/**
|
|
9
|
+
* @param {{name: string}} pValue
|
|
10
|
+
* @returns {string}
|
|
11
|
+
*/
|
|
7
12
|
function getName(pValue) {
|
|
8
13
|
return pValue.name;
|
|
9
14
|
}
|
|
@@ -13,14 +18,22 @@ const VALID_INPUT_TYPES = allowedValues.inputType.values.map(getName);
|
|
|
13
18
|
const VALID_ENGINES = allowedValues.engine.values.map(getName);
|
|
14
19
|
const VALID_DIRECTIONS = allowedValues.direction.values.map(getName);
|
|
15
20
|
|
|
21
|
+
/**
|
|
22
|
+
* @param {string} pFilename
|
|
23
|
+
* @returns {boolean}
|
|
24
|
+
*/
|
|
16
25
|
function isStdout(pFilename) {
|
|
17
26
|
return "-" === pFilename;
|
|
18
27
|
}
|
|
19
28
|
|
|
29
|
+
/**
|
|
30
|
+
* @param {string} pFilename
|
|
31
|
+
* @returns {boolean}
|
|
32
|
+
*/
|
|
20
33
|
function fileExists(pFilename) {
|
|
21
34
|
try {
|
|
22
35
|
if (!isStdout(pFilename)) {
|
|
23
|
-
fs.accessSync(pFilename, fs.R_OK);
|
|
36
|
+
fs.accessSync(pFilename, fs.constants.R_OK);
|
|
24
37
|
}
|
|
25
38
|
return true;
|
|
26
39
|
} catch (pError) {
|
|
@@ -28,6 +41,15 @@ function fileExists(pFilename) {
|
|
|
28
41
|
}
|
|
29
42
|
}
|
|
30
43
|
|
|
44
|
+
/**
|
|
45
|
+
* This function is shaped so it can serve as a validation function in a
|
|
46
|
+
* commander option.
|
|
47
|
+
*
|
|
48
|
+
* @param {keyof import("../../types/state-machine-cat").IRenderOptions} pOption
|
|
49
|
+
* @param {string[]} pValidValues
|
|
50
|
+
* @param {string} pError
|
|
51
|
+
* @returns {never|keyof import("../../types/state-machine-cat").IRenderOptions}
|
|
52
|
+
*/
|
|
31
53
|
function validOption(pOption, pValidValues, pError) {
|
|
32
54
|
if (pValidValues.includes(pOption)) {
|
|
33
55
|
return pOption;
|
|
@@ -78,6 +100,10 @@ export default {
|
|
|
78
100
|
}
|
|
79
101
|
},
|
|
80
102
|
|
|
103
|
+
/**
|
|
104
|
+
* @param {import("./cli").ICLIRenderOptions} pOptions
|
|
105
|
+
* @returns {never|import("./cli").ICLIRenderOptions}
|
|
106
|
+
*/
|
|
81
107
|
validateArguments(pOptions) {
|
|
82
108
|
if (!pOptions.inputFrom) {
|
|
83
109
|
throw new Error(`\n error: Please specify an input file.\n\n`);
|