depflow 3.0.0-dev.10 → 3.0.0-dev.12
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 +513 -117
- package/dist/builder/Builder.d.ts +279 -0
- package/dist/builder/Builder.js +391 -0
- package/dist/builder/Builder.js.map +1 -0
- package/dist/cli/Actions.d.ts +187 -0
- package/dist/cli/Actions.js +793 -0
- package/dist/cli/Actions.js.map +1 -0
- package/dist/cli/CLI.d.ts +170 -0
- package/dist/cli/CLI.js +231 -0
- package/dist/cli/CLI.js.map +1 -0
- package/dist/cli/DepflowCLI.d.ts +62 -0
- package/dist/cli/DepflowCLI.js +229 -0
- package/dist/cli/DepflowCLI.js.map +1 -0
- package/dist/cli/Flags.d.ts +106 -0
- package/dist/cli/Flags.js +125 -0
- package/dist/cli/Flags.js.map +1 -0
- package/dist/cli/bin.js +63 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/config/Config.d.ts +690 -0
- package/dist/config/Config.js +45 -0
- package/dist/config/Config.js.map +1 -0
- package/dist/config/ImportMap.d.ts +60 -0
- package/dist/config/ImportMap.js +66 -0
- package/dist/config/ImportMap.js.map +1 -0
- package/dist/config/JsonSchema.d.ts +12 -0
- package/dist/config/JsonSchema.js +26 -0
- package/dist/config/JsonSchema.js.map +1 -0
- package/dist/config/Settings.d.ts +201 -0
- package/dist/config/Settings.js +191 -0
- package/dist/config/Settings.js.map +1 -0
- package/dist/config/TSConfig.d.ts +73 -0
- package/dist/config/TSConfig.js +73 -0
- package/dist/config/TSConfig.js.map +1 -0
- package/dist/config/codecs/JsonCodec.d.ts +30 -0
- package/dist/config/codecs/JsonCodec.js +31 -0
- package/dist/config/codecs/JsonCodec.js.map +1 -0
- package/dist/config/codecs/YamlCodec.d.ts +62 -0
- package/dist/config/codecs/YamlCodec.js +89 -0
- package/dist/config/codecs/YamlCodec.js.map +1 -0
- package/dist/dependency/DepUtils.d.ts +78 -0
- package/dist/dependency/DepUtils.js +122 -0
- package/dist/dependency/DepUtils.js.map +1 -0
- package/dist/dependency/Dependency.d.ts +81 -0
- package/dist/dependency/Dependency.js +71 -0
- package/dist/dependency/Dependency.js.map +1 -0
- package/dist/dependency/Git.d.ts +75 -0
- package/dist/dependency/Git.js +97 -0
- package/dist/dependency/Git.js.map +1 -0
- package/dist/dependency/GitDependency.d.ts +30 -0
- package/dist/dependency/GitDependency.js +79 -0
- package/dist/dependency/GitDependency.js.map +1 -0
- package/dist/dependency/NpmDependency.d.ts +27 -0
- package/dist/dependency/NpmDependency.js +91 -0
- package/dist/dependency/NpmDependency.js.map +1 -0
- package/{build/support/PathResolver → dist/resolve}/AliasCompiler.d.ts +18 -5
- package/{build/support/PathResolver → dist/resolve}/AliasCompiler.js +31 -9
- package/dist/resolve/AliasCompiler.js.map +1 -0
- package/{build/support/PathResolver → dist/resolve}/PathResolver.d.ts +25 -8
- package/dist/resolve/PathResolver.js +133 -0
- package/dist/resolve/PathResolver.js.map +1 -0
- package/dist/resolve/PathRewriter.d.ts +24 -0
- package/{build/support/PathResolver → dist/resolve}/PathRewriter.js +21 -11
- package/dist/resolve/PathRewriter.js.map +1 -0
- package/{build → dist}/schema/Config/Builder.d.ts +114 -49
- package/dist/schema/Config/Builder.js +78 -0
- package/dist/schema/Config/Builder.js.map +1 -0
- package/{build → dist}/schema/Config/Config.d.ts +169 -78
- package/dist/schema/Config/Config.js +62 -0
- package/dist/schema/Config/Config.js.map +1 -0
- package/{build → dist}/schema/Config/Dependency.d.ts +219 -89
- package/dist/schema/Config/Dependency.js +80 -0
- package/dist/schema/Config/Dependency.js.map +1 -0
- package/{build → dist}/schema/Config/Extractor.d.ts +41 -17
- package/dist/schema/Config/Extractor.js +43 -0
- package/dist/schema/Config/Extractor.js.map +1 -0
- package/{build → dist}/schema/Config/Resolver.d.ts +25 -8
- package/dist/schema/Config/Resolver.js +43 -0
- package/dist/schema/Config/Resolver.js.map +1 -0
- package/{build → dist}/schema/Config/Transform.d.ts +22 -5
- package/dist/schema/Config/Transform.js +51 -0
- package/dist/schema/Config/Transform.js.map +1 -0
- package/dist/schema/Defaults.d.ts +20 -0
- package/dist/schema/Defaults.js +24 -0
- package/dist/schema/Defaults.js.map +1 -0
- package/dist/schema/ImportMap.d.ts +30 -0
- package/dist/schema/ImportMap.js +28 -0
- package/dist/schema/ImportMap.js.map +1 -0
- package/{build → dist}/schema/TSConfig.d.ts +23 -9
- package/dist/schema/TSConfig.js +39 -0
- package/dist/schema/TSConfig.js.map +1 -0
- package/{build → dist}/schema/schema.d.ts +11 -2
- package/{build → dist}/schema/schema.js +11 -2
- package/dist/schema/schema.js.map +1 -0
- package/dist/task/Command.d.ts +287 -0
- package/dist/task/Command.js +404 -0
- package/dist/task/Command.js.map +1 -0
- package/dist/task/Group.d.ts +15 -0
- package/dist/task/Group.js +29 -0
- package/dist/task/Group.js.map +1 -0
- package/dist/task/OutputPolicy.d.ts +262 -0
- package/dist/task/OutputPolicy.js +364 -0
- package/dist/task/OutputPolicy.js.map +1 -0
- package/dist/task/Task.d.ts +210 -0
- package/dist/task/Task.js +312 -0
- package/dist/task/Task.js.map +1 -0
- package/package.json +14 -10
- package/.gitignore +0 -7
- package/build/cli/DepFLowCLI.d.ts +0 -16
- package/build/cli/DepFLowCLI.js +0 -254
- package/build/cli/DepFLowCLI.js.map +0 -1
- package/build/cli/bin.js +0 -38
- package/build/cli/bin.js.map +0 -1
- package/build/config/Config.d.ts +0 -28
- package/build/config/Config.js +0 -46
- package/build/config/Config.js.map +0 -1
- package/build/config/ImportMap.d.ts +0 -51
- package/build/config/ImportMap.js +0 -97
- package/build/config/ImportMap.js.map +0 -1
- package/build/config/TSConfig.d.ts +0 -54
- package/build/config/TSConfig.js +0 -104
- package/build/config/TSConfig.js.map +0 -1
- package/build/schema/Config/Builder.js +0 -48
- package/build/schema/Config/Builder.js.map +0 -1
- package/build/schema/Config/Config.js +0 -20
- package/build/schema/Config/Config.js.map +0 -1
- package/build/schema/Config/Dependency.js +0 -25
- package/build/schema/Config/Dependency.js.map +0 -1
- package/build/schema/Config/Extractor.js +0 -25
- package/build/schema/Config/Extractor.js.map +0 -1
- package/build/schema/Config/Resolver.js +0 -25
- package/build/schema/Config/Resolver.js.map +0 -1
- package/build/schema/Config/Transform.js +0 -27
- package/build/schema/Config/Transform.js.map +0 -1
- package/build/schema/ImportMap.d.ts +0 -22
- package/build/schema/ImportMap.js +0 -12
- package/build/schema/ImportMap.js.map +0 -1
- package/build/schema/TSConfig.js +0 -19
- package/build/schema/TSConfig.js.map +0 -1
- package/build/schema/schema.js.map +0 -1
- package/build/support/Builder/Builder.d.ts +0 -46
- package/build/support/Builder/Builder.js +0 -116
- package/build/support/Builder/Builder.js.map +0 -1
- package/build/support/Dependency/Dependency.d.ts +0 -38
- package/build/support/Dependency/Dependency.js +0 -14
- package/build/support/Dependency/Dependency.js.map +0 -1
- package/build/support/Dependency/GitDependency.d.ts +0 -20
- package/build/support/Dependency/GitDependency.js +0 -67
- package/build/support/Dependency/GitDependency.js.map +0 -1
- package/build/support/Dependency/NpmDependency.d.ts +0 -18
- package/build/support/Dependency/NpmDependency.js +0 -65
- package/build/support/Dependency/NpmDependency.js.map +0 -1
- package/build/support/Git.d.ts +0 -53
- package/build/support/Git.js +0 -86
- package/build/support/Git.js.map +0 -1
- package/build/support/PathResolver/AliasCompiler.js.map +0 -1
- package/build/support/PathResolver/PathResolver.js +0 -105
- package/build/support/PathResolver/PathResolver.js.map +0 -1
- package/build/support/PathResolver/PathRewriter.d.ts +0 -18
- package/build/support/PathResolver/PathRewriter.js.map +0 -1
- package/build/support/PathResolver/Utils.d.ts +0 -36
- package/build/support/PathResolver/Utils.js +0 -45
- package/build/support/PathResolver/Utils.js.map +0 -1
- package/build/support/Task/Command.d.ts +0 -49
- package/build/support/Task/Command.js +0 -100
- package/build/support/Task/Command.js.map +0 -1
- package/build/support/Task/Task.d.ts +0 -84
- package/build/support/Task/Task.js +0 -145
- package/build/support/Task/Task.js.map +0 -1
- package/build/support/Utils.d.ts +0 -40
- package/build/support/Utils.js +0 -138
- package/build/support/Utils.js.map +0 -1
- package/build/support/Validator.d.ts +0 -22
- package/build/support/Validator.js +0 -28
- package/build/support/Validator.js.map +0 -1
- /package/{build → dist}/cli/bin.d.ts +0 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>.
|
|
3
|
+
* @description The console surface of DepFlow: it declares the project commands and wires each one to the
|
|
4
|
+
* action of `Actions` that carries it out.
|
|
5
|
+
* @license Apache-2.0
|
|
6
|
+
*/
|
|
7
|
+
import { Path } from '@netfeez/common-node';
|
|
8
|
+
import CLI from './CLI.js';
|
|
9
|
+
import Actions from './Actions.js';
|
|
10
|
+
import Flags from './Flags.js';
|
|
11
|
+
/** The flags accepted by every command of the CLI. **/
|
|
12
|
+
export const options = new Flags({
|
|
13
|
+
flow: {
|
|
14
|
+
type: 'string',
|
|
15
|
+
default: 'depflow.yml',
|
|
16
|
+
aliases: ['p', 'f'],
|
|
17
|
+
description: 'Path to the configuration file the command operates on.'
|
|
18
|
+
},
|
|
19
|
+
watch: {
|
|
20
|
+
type: 'boolean',
|
|
21
|
+
default: false,
|
|
22
|
+
aliases: ['w'],
|
|
23
|
+
description: 'Keeps watching the built files and rewrites their paths on every change.'
|
|
24
|
+
},
|
|
25
|
+
cdn: {
|
|
26
|
+
type: 'boolean',
|
|
27
|
+
default: false,
|
|
28
|
+
description: 'Resolves the dependency paths to their CDN target instead of their local one.'
|
|
29
|
+
},
|
|
30
|
+
verbose: {
|
|
31
|
+
type: 'boolean',
|
|
32
|
+
default: false,
|
|
33
|
+
aliases: ['v'],
|
|
34
|
+
description: 'Streams the output of every command as it runs, attributed to the command that wrote it, instead of only reporting how each of them ended. The indentation of that output is lost, and the complete buffer of every command reaches the evidence file whether this flag is given or not.'
|
|
35
|
+
},
|
|
36
|
+
silent: {
|
|
37
|
+
type: 'boolean',
|
|
38
|
+
default: false,
|
|
39
|
+
description: 'Says only what failed, one line per failed command. It silences the progress of DepFlow itself, such as "Installing dependencies...", and not the help, which belongs to the console interface. The exit status and the evidence file are the same as in any other mode.'
|
|
40
|
+
},
|
|
41
|
+
decorate: {
|
|
42
|
+
type: 'boolean',
|
|
43
|
+
default: true,
|
|
44
|
+
description: 'Draws boxes, indentation, timestamps, levels and names around what is reported. --decorate=false leaves the content alone and keeps the color of the markers and the diagnostics, which carry information and are not decoration.'
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
/**
|
|
48
|
+
* The flags an editing command owns, defined once so every command that carries one shares its type
|
|
49
|
+
* and its description instead of restating them.
|
|
50
|
+
**/
|
|
51
|
+
const EDITING = {
|
|
52
|
+
dep: {
|
|
53
|
+
type: 'string',
|
|
54
|
+
description: 'Name of the dependency whose resolver or builder an editing command targets. Omitted, the command edits the project resolver.'
|
|
55
|
+
},
|
|
56
|
+
action: {
|
|
57
|
+
type: 'string',
|
|
58
|
+
description: 'Name of the named action whose builder an editing command targets.'
|
|
59
|
+
},
|
|
60
|
+
type: {
|
|
61
|
+
type: 'string',
|
|
62
|
+
description: 'Type identifier of a resolver target, set alongside its local path.'
|
|
63
|
+
},
|
|
64
|
+
cdnUrl: {
|
|
65
|
+
type: 'string',
|
|
66
|
+
aliases: ['cdn-url'],
|
|
67
|
+
description: 'CDN URL of a resolver target, set alongside its local path.'
|
|
68
|
+
},
|
|
69
|
+
to: {
|
|
70
|
+
type: 'string',
|
|
71
|
+
description: 'Destination folder of an extract build step.'
|
|
72
|
+
},
|
|
73
|
+
map: {
|
|
74
|
+
type: 'string',
|
|
75
|
+
description: 'Pattern applied to the destination path of an extract build step.'
|
|
76
|
+
},
|
|
77
|
+
search: {
|
|
78
|
+
type: 'string',
|
|
79
|
+
description: 'Regular expression a transform build step searches for.'
|
|
80
|
+
},
|
|
81
|
+
replace: {
|
|
82
|
+
type: 'string',
|
|
83
|
+
description: 'Replacement string of a transform build step.'
|
|
84
|
+
},
|
|
85
|
+
flags: {
|
|
86
|
+
type: 'string',
|
|
87
|
+
description: 'Flags of the regular expression of a transform build step. Defaults to "g".'
|
|
88
|
+
},
|
|
89
|
+
maxTime: {
|
|
90
|
+
type: 'string',
|
|
91
|
+
aliases: ['max-time'],
|
|
92
|
+
description: 'Maximum execution time in milliseconds of a run build step. A value of -1 disables the limit.'
|
|
93
|
+
},
|
|
94
|
+
allowFails: {
|
|
95
|
+
type: 'boolean',
|
|
96
|
+
aliases: ['allow-fails'],
|
|
97
|
+
description: 'Whether the commands of a run build step may fail. Defaults to false.'
|
|
98
|
+
},
|
|
99
|
+
index: {
|
|
100
|
+
type: 'string',
|
|
101
|
+
description: 'Position at which a build step is inserted. Omitted, it is appended at the end.'
|
|
102
|
+
},
|
|
103
|
+
force: {
|
|
104
|
+
type: 'boolean',
|
|
105
|
+
description: 'Overwrites an existing resolver alias instead of failing.'
|
|
106
|
+
},
|
|
107
|
+
npm: {
|
|
108
|
+
type: 'boolean',
|
|
109
|
+
description: 'Adds an npm dependency instead of a git one.'
|
|
110
|
+
},
|
|
111
|
+
tag: {
|
|
112
|
+
type: 'string',
|
|
113
|
+
description: 'Git tag, branch or commit an added git dependency is checked out at. Defaults to "main".'
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
/** The flags the `resolver` command owns, beside the global ones. **/
|
|
117
|
+
const resolverOwn = { dep: EDITING.dep, type: EDITING.type, cdnUrl: EDITING.cdnUrl, force: EDITING.force };
|
|
118
|
+
/** The flags the `builder` command owns, beside the global ones. **/
|
|
119
|
+
const builderOwn = {
|
|
120
|
+
dep: EDITING.dep,
|
|
121
|
+
action: EDITING.action,
|
|
122
|
+
to: EDITING.to,
|
|
123
|
+
map: EDITING.map,
|
|
124
|
+
search: EDITING.search,
|
|
125
|
+
replace: EDITING.replace,
|
|
126
|
+
flags: EDITING.flags,
|
|
127
|
+
maxTime: EDITING.maxTime,
|
|
128
|
+
allowFails: EDITING.allowFails,
|
|
129
|
+
index: EDITING.index
|
|
130
|
+
};
|
|
131
|
+
/** The flags the `add` command owns, beside the global ones. **/
|
|
132
|
+
const addOwn = { npm: EDITING.npm, tag: EDITING.tag };
|
|
133
|
+
/** The flags accepted by `resolver`: the global ones plus the ones it owns. **/
|
|
134
|
+
const resolverFlags = new Flags({ ...options.declaration, ...resolverOwn });
|
|
135
|
+
/** The flags accepted by `builder`: the global ones plus the ones it owns. **/
|
|
136
|
+
const builderFlags = new Flags({ ...options.declaration, ...builderOwn });
|
|
137
|
+
/** The flags accepted by `add`: the global ones plus the ones it owns. **/
|
|
138
|
+
const addFlags = new Flags({ ...options.declaration, ...addOwn });
|
|
139
|
+
export class DepflowCLI extends CLI {
|
|
140
|
+
/** Path of the configuration file the commands operate on, as the command line gave it. **/
|
|
141
|
+
configPath;
|
|
142
|
+
constructor(configPath = 'depFlow.yml') {
|
|
143
|
+
super(options.declaration, {
|
|
144
|
+
name: 'C-UI',
|
|
145
|
+
title: '&C1DepFlow &C5CLI &C6by NetFeez',
|
|
146
|
+
prompt: '&C5[DepFlow] << &C6&S'
|
|
147
|
+
});
|
|
148
|
+
this.configPath = configPath;
|
|
149
|
+
this.addCommand('add', (command, args, flags = addFlags.defaults) => Actions.add(this.context, args, flags), {
|
|
150
|
+
usage: 'dep add <repo_url> [name] [--tag <ref>] | dep add --npm <name>[@<version>]',
|
|
151
|
+
description: 'Add a dependency to the configuration file.',
|
|
152
|
+
args: {
|
|
153
|
+
repo_url: { description: 'URL of the git repository to add.' },
|
|
154
|
+
name: { description: 'Name to register the dependency under; derived from the repository URL when it is omitted.', required: false }
|
|
155
|
+
},
|
|
156
|
+
flags: addOwn
|
|
157
|
+
});
|
|
158
|
+
this.addCommand('remove', (command, args, flags = options.defaults) => Actions.remove(this.context, args, flags), {
|
|
159
|
+
usage: 'dep remove <name> | <repo_url>',
|
|
160
|
+
description: 'Remove a dependency from the configuration file and uninstall its files.',
|
|
161
|
+
args: {
|
|
162
|
+
identifier: { description: 'Name or repository URL of the dependency to remove.' }
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
this.addCommand('install', (command, args, flags = options.defaults) => Actions.install(this.context, args, flags), {
|
|
166
|
+
usage: 'dep install [name1 name2 ...]',
|
|
167
|
+
description: 'Install dependencies. If names are provided, only those dependencies will be installed.',
|
|
168
|
+
args: {
|
|
169
|
+
names: { description: 'Names of the dependencies to install; every dependency when none is given.', required: false, variadic: true }
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
this.addCommand('run', (command, args, flags = options.defaults) => Actions.run(this.context, args, flags), {
|
|
173
|
+
usage: 'dep run <script>',
|
|
174
|
+
description: 'Run a custom action defined in the configuration file.',
|
|
175
|
+
args: {
|
|
176
|
+
script: { description: 'Name of the action declared in the configuration file.' }
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
this.addCommand('list', (command, args, flags = options.defaults) => Actions.list(this.context, args, flags), { usage: 'dep list', description: 'List all dependencies in the configuration file.' });
|
|
180
|
+
this.addCommand('resolver', (command, args, flags = resolverFlags.defaults) => Actions.resolver(this.context, args, flags), {
|
|
181
|
+
usage: 'dep resolver add <alias> <local> [--type <t>] [--cdn-url <url>] | remove <alias> | list | clear [--dep <name>]',
|
|
182
|
+
description: 'Edits the resolver aliases of the project or of a named dependency.',
|
|
183
|
+
flags: resolverOwn
|
|
184
|
+
});
|
|
185
|
+
this.addCommand('builder', (command, args, flags = builderFlags.defaults) => Actions.builder(this.context, args, flags), {
|
|
186
|
+
usage: 'dep builder add <run|extract|transform> ... | remove <index> | move <from> <to> | list | clear [--dep <name> | --action <name>]',
|
|
187
|
+
description: 'Edits the build pipeline of a dependency or of a named action.',
|
|
188
|
+
flags: builderOwn
|
|
189
|
+
});
|
|
190
|
+
this.addCommand('action', (command, args, flags = options.defaults) => Actions.action(this.context, args, flags), {
|
|
191
|
+
usage: 'dep action create <name> | remove <name> | list',
|
|
192
|
+
description: 'Manages the named build actions of the configuration.'
|
|
193
|
+
});
|
|
194
|
+
this.addCommand('config', (command, args, flags = options.defaults) => Actions.config(this.context, args, flags), {
|
|
195
|
+
usage: 'dep config get [key] | set <key> <value> | unset <key>',
|
|
196
|
+
description: 'Reads and edits the top-level settings of the configuration (outDir, tsconfig, importmap).'
|
|
197
|
+
});
|
|
198
|
+
this.addCommand('rewrite-paths', (command, args, flags = options.defaults) => Actions.rewritePaths(this.context, args, flags), { usage: 'dep rewrite-paths [--watch] [--cdn]', description: 'Rewrite the paths of the built files of outDir according to the resolver entries of the configuration.' });
|
|
199
|
+
this.addCommand('sync', (command, args, flags = options.defaults) => Actions.sync(this.context, args, flags), { usage: 'dep sync', description: 'Write the resolver entries into the paths of the declared tsconfig and into the declared importmap.' });
|
|
200
|
+
this.addCommand('json-to-yaml', (command, args, flags = options.defaults) => Actions.convert(this.context, command, args, flags), {
|
|
201
|
+
usage: 'dep json-to-yaml [output.yaml]',
|
|
202
|
+
description: 'Convert the depflow config file from JSON to YAML.',
|
|
203
|
+
args: {
|
|
204
|
+
output: { description: 'Path of the YAML file to write; derived from the config file name when it is omitted.', required: false }
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
this.addCommand('yaml-to-json', (command, args, flags = options.defaults) => Actions.convert(this.context, command, args, flags), {
|
|
208
|
+
usage: 'dep yaml-to-json [output.json]',
|
|
209
|
+
description: 'Convert the depflow config file from YAML to JSON.',
|
|
210
|
+
args: {
|
|
211
|
+
output: { description: 'Path of the JSON file to write; derived from the config file name when it is omitted.', required: false }
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
/** Absolute path of the directory holding the configuration file, the project root. **/
|
|
216
|
+
get projectRoot() { return Path.dirname(Path.resolve(process.cwd(), this.configPath)); }
|
|
217
|
+
/** Absolute path of the flow directory (`.depflow`) under the project root. **/
|
|
218
|
+
get flowDirectory() { return Path.join(this.projectRoot, '.depflow'); }
|
|
219
|
+
/** The project the commands operate on: the context every action is driven with. **/
|
|
220
|
+
get context() {
|
|
221
|
+
return {
|
|
222
|
+
configPath: this.configPath,
|
|
223
|
+
projectRoot: this.projectRoot,
|
|
224
|
+
flowDirectory: this.flowDirectory
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
export default DepflowCLI;
|
|
229
|
+
//# sourceMappingURL=DepflowCLI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DepflowCLI.js","sourceRoot":"","sources":["../../src/cli/DepflowCLI.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAE5C,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,KAAK,MAAM,YAAY,CAAC;AAE/B,uDAAuD;AACvD,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,KAAK,CAAC;IAC7B,IAAI,EAAE;QACF,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,aAAa;QACtB,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;QACnB,WAAW,EAAE,yDAAyD;KACzE;IACD,KAAK,EAAE;QACH,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,CAAC,GAAG,CAAC;QACd,WAAW,EAAE,0EAA0E;KAC1F;IACD,GAAG,EAAE;QACD,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,+EAA+E;KAC/F;IACD,OAAO,EAAE;QACL,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,CAAC,GAAG,CAAC;QACd,WAAW,EAAE,0RAA0R;KAC1S;IACD,MAAM,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,0QAA0Q;KAC1R;IACD,QAAQ,EAAE;QACN,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,mOAAmO;KACnP;CACJ,CAAC,CAAC;AAEH;;;IAGI;AACJ,MAAM,OAAO,GAAG;IACZ,GAAG,EAAE;QACD,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,+HAA+H;KAC/I;IACD,MAAM,EAAE;QACJ,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,oEAAoE;KACpF;IACD,IAAI,EAAE;QACF,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,qEAAqE;KACrF;IACD,MAAM,EAAE;QACJ,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,CAAC,SAAS,CAAC;QACpB,WAAW,EAAE,6DAA6D;KAC7E;IACD,EAAE,EAAE;QACA,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,8CAA8C;KAC9D;IACD,GAAG,EAAE;QACD,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,mEAAmE;KACnF;IACD,MAAM,EAAE;QACJ,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,yDAAyD;KACzE;IACD,OAAO,EAAE;QACL,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,+CAA+C;KAC/D;IACD,KAAK,EAAE;QACH,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,6EAA6E;KAC7F;IACD,OAAO,EAAE;QACL,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,CAAC,UAAU,CAAC;QACrB,WAAW,EAAE,+FAA+F;KAC/G;IACD,UAAU,EAAE;QACR,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,CAAC,aAAa,CAAC;QACxB,WAAW,EAAE,uEAAuE;KACvF;IACD,KAAK,EAAE;QACH,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,iFAAiF;KACjG;IACD,KAAK,EAAE;QACH,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,2DAA2D;KAC3E;IACD,GAAG,EAAE;QACD,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,8CAA8C;KAC9D;IACD,GAAG,EAAE;QACD,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,0FAA0F;KAC1G;CACiC,CAAC;AAEvC,sEAAsE;AACtE,MAAM,WAAW,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAuC,CAAC;AAEhJ,qEAAqE;AACrE,MAAM,UAAU,GAAG;IACf,GAAG,EAAE,OAAO,CAAC,GAAG;IAChB,MAAM,EAAE,OAAO,CAAC,MAAM;IACtB,EAAE,EAAE,OAAO,CAAC,EAAE;IACd,GAAG,EAAE,OAAO,CAAC,GAAG;IAChB,MAAM,EAAE,OAAO,CAAC,MAAM;IACtB,OAAO,EAAE,OAAO,CAAC,OAAO;IACxB,KAAK,EAAE,OAAO,CAAC,KAAK;IACpB,OAAO,EAAE,OAAO,CAAC,OAAO;IACxB,UAAU,EAAE,OAAO,CAAC,UAAU;IAC9B,KAAK,EAAE,OAAO,CAAC,KAAK;CACc,CAAC;AAEvC,iEAAiE;AACjE,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAuC,CAAC;AAE3F,gFAAgF;AAChF,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,GAAG,WAAW,EAAE,CAAC,CAAC;AAE5E,+EAA+E;AAC/E,MAAM,YAAY,GAAG,IAAI,KAAK,CAAC,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC;AAE1E,2EAA2E;AAC3E,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;AAElE,MAAM,OAAO,UAAW,SAAQ,GAAG;IAC/B,4FAA4F;IACrF,UAAU,CAAS;IAE1B,YAAmB,UAAU,GAAW,aAAa;QAAI,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE;YAChF,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,iCAAiC;YACxC,MAAM,EAAE,uBAAuB;SAClC,CAAC,CAAC;QAEC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAE7B,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,GAA0B,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE;YAChI,KAAK,EAAE,4EAA4E;YACnF,WAAW,EAAE,6CAA6C;YAC1D,IAAI,EAAE;gBACF,QAAQ,EAAE,EAAE,WAAW,EAAE,mCAAmC,EAAE;gBAC9D,IAAI,EAAE,EAAE,WAAW,EAAE,4FAA4F,EAAE,QAAQ,EAAE,KAAK,EAAE;aACvI;YACD,KAAK,EAAE,MAAM;SAChB,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE;YAC9G,KAAK,EAAE,gCAAgC;YACvC,WAAW,EAAE,0EAA0E;YACvF,IAAI,EAAE;gBACF,UAAU,EAAE,EAAE,WAAW,EAAE,qDAAqD,EAAE;aACrF;SACJ,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE;YAChH,KAAK,EAAE,+BAA+B;YACtC,WAAW,EAAE,yFAAyF;YACtG,IAAI,EAAE;gBACF,KAAK,EAAE,EAAE,WAAW,EAAE,4EAA4E,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE;aACxI;SACJ,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE;YACxG,KAAK,EAAE,kBAAkB;YACzB,WAAW,EAAE,wDAAwD;YACrE,IAAI,EAAE;gBACF,MAAM,EAAE,EAAE,WAAW,EAAE,wDAAwD,EAAE;aACpF;SACJ,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,kDAAkD,EAAE,CAAC,CAAC;QACtM,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,GAA+B,aAAa,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE;YACpJ,KAAK,EAAE,gHAAgH;YACvH,WAAW,EAAE,qEAAqE;YAClF,KAAK,EAAE,WAAW;SACrB,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,GAA8B,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE;YAChJ,KAAK,EAAE,iIAAiI;YACxI,WAAW,EAAE,gEAAgE;YAC7E,KAAK,EAAE,UAAU;SACpB,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE;YAC9G,KAAK,EAAE,iDAAiD;YACxD,WAAW,EAAE,uDAAuD;SACvE,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE;YAC9G,KAAK,EAAE,wDAAwD;YAC/D,WAAW,EAAE,4FAA4F;SAC5G,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,qCAAqC,EAAE,WAAW,EAAE,wGAAwG,EAAE,CAAC,CAAC;QACxS,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,qGAAqG,EAAG,CAAC,CAAC;QAC1P,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE;YAC9H,KAAK,EAAE,gCAAgC;YACvC,WAAW,EAAE,oDAAoD;YACjE,IAAI,EAAE;gBACF,MAAM,EAAE,EAAE,WAAW,EAAE,uFAAuF,EAAE,QAAQ,EAAE,KAAK,EAAE;aACpI;SACJ,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE;YAC9H,KAAK,EAAE,gCAAgC;YACvC,WAAW,EAAE,oDAAoD;YACjE,IAAI,EAAE;gBACF,MAAM,EAAE,EAAE,WAAW,EAAE,uFAAuF,EAAE,QAAQ,EAAE,KAAK,EAAE;aACpI;SACJ,CAAC,CAAC;IACP,CAAC;IAED,wFAAwF;IACxF,IAAW,WAAW,KAAa,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAEvG,gFAAgF;IAChF,IAAc,aAAa,KAAa,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IAEzF,qFAAqF;IACrF,IAAW,OAAO;QACd,OAAO;YACH,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,aAAa,EAAE,IAAI,CAAC,aAAa;SACpC,CAAC;IACN,CAAC;CACJ;AAOD,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>.
|
|
3
|
+
* @description CLI flag parsing: declarative flag definitions, command-line tokenization and typed value extraction.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import Schema, { Definition } from '@netfeez/schema';
|
|
7
|
+
export declare class Flags<const D extends Flags.Declaration> {
|
|
8
|
+
/** The declared flags, kept at their declared type so the parsed values are inferred from them. */
|
|
9
|
+
readonly declaration: D;
|
|
10
|
+
/** Maps every accepted name, canonical or alias, to the name of the flag declaring it. */
|
|
11
|
+
private readonly names;
|
|
12
|
+
/**
|
|
13
|
+
* Declares the flags accepted by a command line.
|
|
14
|
+
* @param declaration - The declared flags, keyed by the name each one is declared under.
|
|
15
|
+
* @throws { Error } When a name is declared or aliased twice, or when an alias carries a dash prefix.
|
|
16
|
+
*/
|
|
17
|
+
constructor(declaration: D);
|
|
18
|
+
/** The values a parsed command line carries when a flag is absent, taken from the declared defaults. **/
|
|
19
|
+
get defaults(): Flags.Values<D>;
|
|
20
|
+
/** The values parsed from a command line. Type-only: accessing it at runtime throws. **/
|
|
21
|
+
get infer(): Flags.Values<D>;
|
|
22
|
+
/**
|
|
23
|
+
* Extracts the positional arguments and the flag values of a command line.
|
|
24
|
+
* @param args - The command-line arguments.
|
|
25
|
+
* @returns The positional arguments and the values of the declared flags.
|
|
26
|
+
* @throws { Error } When a flag is not declared, or when a boolean flag carries a value other than "true" or "false".
|
|
27
|
+
*
|
|
28
|
+
* @remarks
|
|
29
|
+
* A flag is the whole token, so short clusters are not expanded: `-abc` is the single flag `-abc`.
|
|
30
|
+
* Names are matched without their dash prefix, so `-f` and `--flow` reach the same declaration.
|
|
31
|
+
* A boolean flag never consumes the following argument and only accepts `=true` or `=false` inline.
|
|
32
|
+
* A value flag takes the following argument as its value when that argument is not a flag; when it is,
|
|
33
|
+
* the value has to be written inline as `--flag=value`. The `--` terminator moves every remaining token
|
|
34
|
+
* to the positional arguments, and the last occurrence of a flag wins.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* const options = new Flags({
|
|
39
|
+
* flow: { type: 'string', default: 'depflow.yml', aliases: [ 'f' ] },
|
|
40
|
+
* cdn: { type: 'boolean', default: false }
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* const { args, flags } = options.parse([ '-f', 'depflow.yml', 'install', '--cdn' ]);
|
|
44
|
+
* // args → [ 'install' ]
|
|
45
|
+
* // flags → { flow: 'depflow.yml', cdn: true }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
parse(args: readonly string[]): Flags.Result<Flags.Values<D>>;
|
|
49
|
+
/**
|
|
50
|
+
* Resolves the token of a flag to the name of the flag declaring it.
|
|
51
|
+
* @param token - The token of the flag, without its inline value.
|
|
52
|
+
* @returns The name the flag is declared under, or `undefined` when no declaration accepts the token.
|
|
53
|
+
*/
|
|
54
|
+
private resolve;
|
|
55
|
+
/**
|
|
56
|
+
* Whether a declared flag carries a boolean value, meaning it never consumes the following argument.
|
|
57
|
+
* @param name - The name the flag is declared under.
|
|
58
|
+
* @returns Whether the flag is declared as a boolean.
|
|
59
|
+
*/
|
|
60
|
+
private isBoolean;
|
|
61
|
+
/** Whether an argument is a flag token, meaning a dash prefix longer than a single dash. **/
|
|
62
|
+
private static isFlag;
|
|
63
|
+
/**
|
|
64
|
+
* Builds the lookup of every accepted name, canonical or alias, to the name of the flag declaring it.
|
|
65
|
+
* @param declaration - The declared flags.
|
|
66
|
+
* @returns The lookup of accepted names to declared names.
|
|
67
|
+
* @throws { Error } When a name is declared or aliased twice, or when an alias carries a dash prefix.
|
|
68
|
+
*/
|
|
69
|
+
private static index;
|
|
70
|
+
}
|
|
71
|
+
export declare namespace Flags {
|
|
72
|
+
/**
|
|
73
|
+
* A declared flag: the definition of the value it carries, plus the extra names accepted for it.
|
|
74
|
+
*
|
|
75
|
+
* @remarks The parser honors `type`, `default` and `aliases`; `description` documents the flag.
|
|
76
|
+
*/
|
|
77
|
+
export type Flag = (Definition.StringDef | Definition.BooleanDef) & {
|
|
78
|
+
/** The extra names accepted for the flag, written without their dash prefix. */
|
|
79
|
+
aliases?: readonly string[];
|
|
80
|
+
};
|
|
81
|
+
/** The declaration of the flags accepted by a command line, keyed by the name each flag is declared under. **/
|
|
82
|
+
export type Declaration = {
|
|
83
|
+
[name: string]: Flag;
|
|
84
|
+
};
|
|
85
|
+
/** The value carried by a declared flag, derived from its definition through the schema inference. **/
|
|
86
|
+
export type Value<F> = Schema.Output<Extract<F, Definition.Definition>>;
|
|
87
|
+
/** The values of a declaration: every flag declaring a default is materialized, every other one is optional. **/
|
|
88
|
+
export type Values<D> = {
|
|
89
|
+
[K in keyof D as Defaulted<D[K]> extends true ? K : never]: Value<D[K]>;
|
|
90
|
+
} & {
|
|
91
|
+
[K in keyof D as Defaulted<D[K]> extends true ? never : K]?: Value<D[K]>;
|
|
92
|
+
};
|
|
93
|
+
/** The outcome of parsing a command line, carrying the values of the declared flags. **/
|
|
94
|
+
export interface Result<V> {
|
|
95
|
+
/** The positional arguments of the command line, in order. */
|
|
96
|
+
args: string[];
|
|
97
|
+
/** The values of the declared flags. */
|
|
98
|
+
flags: V;
|
|
99
|
+
}
|
|
100
|
+
/** Whether a declared flag declares a default, meaning its value is always present in a parsed command line. **/
|
|
101
|
+
type Defaulted<F> = F extends {
|
|
102
|
+
default: unknown;
|
|
103
|
+
} ? true : false;
|
|
104
|
+
export {};
|
|
105
|
+
}
|
|
106
|
+
export default Flags;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
export class Flags {
|
|
2
|
+
/** The declared flags, kept at their declared type so the parsed values are inferred from them. */
|
|
3
|
+
declaration;
|
|
4
|
+
/** Maps every accepted name, canonical or alias, to the name of the flag declaring it. */
|
|
5
|
+
names;
|
|
6
|
+
/**
|
|
7
|
+
* Declares the flags accepted by a command line.
|
|
8
|
+
* @param declaration - The declared flags, keyed by the name each one is declared under.
|
|
9
|
+
* @throws { Error } When a name is declared or aliased twice, or when an alias carries a dash prefix.
|
|
10
|
+
*/
|
|
11
|
+
constructor(declaration) {
|
|
12
|
+
this.declaration = declaration;
|
|
13
|
+
this.names = Flags.index(declaration);
|
|
14
|
+
}
|
|
15
|
+
/** The values a parsed command line carries when a flag is absent, taken from the declared defaults. **/
|
|
16
|
+
get defaults() {
|
|
17
|
+
const values = {};
|
|
18
|
+
for (const [name, flag] of Object.entries(this.declaration)) {
|
|
19
|
+
if ('default' in flag)
|
|
20
|
+
values[name] = flag.default;
|
|
21
|
+
}
|
|
22
|
+
return values;
|
|
23
|
+
}
|
|
24
|
+
/** The values parsed from a command line. Type-only: accessing it at runtime throws. **/
|
|
25
|
+
get infer() { throw new Error('Flags.infer is type-only.'); }
|
|
26
|
+
/**
|
|
27
|
+
* Extracts the positional arguments and the flag values of a command line.
|
|
28
|
+
* @param args - The command-line arguments.
|
|
29
|
+
* @returns The positional arguments and the values of the declared flags.
|
|
30
|
+
* @throws { Error } When a flag is not declared, or when a boolean flag carries a value other than "true" or "false".
|
|
31
|
+
*
|
|
32
|
+
* @remarks
|
|
33
|
+
* A flag is the whole token, so short clusters are not expanded: `-abc` is the single flag `-abc`.
|
|
34
|
+
* Names are matched without their dash prefix, so `-f` and `--flow` reach the same declaration.
|
|
35
|
+
* A boolean flag never consumes the following argument and only accepts `=true` or `=false` inline.
|
|
36
|
+
* A value flag takes the following argument as its value when that argument is not a flag; when it is,
|
|
37
|
+
* the value has to be written inline as `--flag=value`. The `--` terminator moves every remaining token
|
|
38
|
+
* to the positional arguments, and the last occurrence of a flag wins.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* const options = new Flags({
|
|
43
|
+
* flow: { type: 'string', default: 'depflow.yml', aliases: [ 'f' ] },
|
|
44
|
+
* cdn: { type: 'boolean', default: false }
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* const { args, flags } = options.parse([ '-f', 'depflow.yml', 'install', '--cdn' ]);
|
|
48
|
+
* // args → [ 'install' ]
|
|
49
|
+
* // flags → { flow: 'depflow.yml', cdn: true }
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
parse(args) {
|
|
53
|
+
const positionals = [];
|
|
54
|
+
const values = {};
|
|
55
|
+
let parsing = true;
|
|
56
|
+
let index = 0;
|
|
57
|
+
while (parsing && index < args.length) {
|
|
58
|
+
const arg = args[index++];
|
|
59
|
+
if (arg === '--') {
|
|
60
|
+
parsing = false;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (!Flags.isFlag(arg)) {
|
|
64
|
+
positionals.push(arg);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const separator = arg.indexOf('=');
|
|
68
|
+
const name = this.resolve(separator < 0 ? arg : arg.slice(0, separator));
|
|
69
|
+
if (name === undefined)
|
|
70
|
+
throw new Error(`Unknown flag: ${arg}`);
|
|
71
|
+
if (this.isBoolean(name)) {
|
|
72
|
+
const value = separator < 0 ? 'true' : arg.slice(separator + 1);
|
|
73
|
+
if (value !== 'true' && value !== 'false')
|
|
74
|
+
throw new Error(`Invalid boolean value: ${arg}`);
|
|
75
|
+
values[name] = value === 'true';
|
|
76
|
+
}
|
|
77
|
+
else if (separator >= 0)
|
|
78
|
+
values[name] = arg.slice(separator + 1);
|
|
79
|
+
else if (index < args.length && !Flags.isFlag(args[index]))
|
|
80
|
+
values[name] = args[index++];
|
|
81
|
+
}
|
|
82
|
+
while (index < args.length)
|
|
83
|
+
positionals.push(args[index++]);
|
|
84
|
+
return { args: positionals, flags: { ...this.defaults, ...values } };
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Resolves the token of a flag to the name of the flag declaring it.
|
|
88
|
+
* @param token - The token of the flag, without its inline value.
|
|
89
|
+
* @returns The name the flag is declared under, or `undefined` when no declaration accepts the token.
|
|
90
|
+
*/
|
|
91
|
+
resolve(token) {
|
|
92
|
+
return this.names.get(token.replace(/^--?/, ''));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Whether a declared flag carries a boolean value, meaning it never consumes the following argument.
|
|
96
|
+
* @param name - The name the flag is declared under.
|
|
97
|
+
* @returns Whether the flag is declared as a boolean.
|
|
98
|
+
*/
|
|
99
|
+
isBoolean(name) {
|
|
100
|
+
return this.declaration[name].type === 'boolean';
|
|
101
|
+
}
|
|
102
|
+
/** Whether an argument is a flag token, meaning a dash prefix longer than a single dash. **/
|
|
103
|
+
static isFlag(arg) { return arg.length > 1 && arg.startsWith('-'); }
|
|
104
|
+
/**
|
|
105
|
+
* Builds the lookup of every accepted name, canonical or alias, to the name of the flag declaring it.
|
|
106
|
+
* @param declaration - The declared flags.
|
|
107
|
+
* @returns The lookup of accepted names to declared names.
|
|
108
|
+
* @throws { Error } When a name is declared or aliased twice, or when an alias carries a dash prefix.
|
|
109
|
+
*/
|
|
110
|
+
static index(declaration) {
|
|
111
|
+
const names = new Map();
|
|
112
|
+
for (const [name, flag] of Object.entries(declaration)) {
|
|
113
|
+
for (const alias of [name, ...flag.aliases ?? []]) {
|
|
114
|
+
if (alias.startsWith('-'))
|
|
115
|
+
throw new Error(`Flag name must not carry a dash prefix: ${alias}`);
|
|
116
|
+
if (names.has(alias))
|
|
117
|
+
throw new Error(`Duplicated flag name: ${alias}`);
|
|
118
|
+
names.set(alias, name);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return names;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
export default Flags;
|
|
125
|
+
//# sourceMappingURL=Flags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Flags.js","sourceRoot":"","sources":["../../src/cli/Flags.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/bin.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import DepflowCLI from "./DepflowCLI.js";
|
|
3
|
+
import Flags from "./Flags.js";
|
|
4
|
+
const skip = 2;
|
|
5
|
+
const [commandName, ...argsList] = process.argv.slice(skip);
|
|
6
|
+
/**
|
|
7
|
+
* Reports a failure to the user and marks the process as failed.
|
|
8
|
+
*
|
|
9
|
+
* @remarks The failure is reported as one line through the logger, and not as a box painted with
|
|
10
|
+
* literals: the box was a second implementation of the decoration of vterm, it disappeared with
|
|
11
|
+
* `--decorate=false` while this one did not, and the summary it printed is not a per-command diagnostic,
|
|
12
|
+
* so the policy never printed it and nothing was duplicated.
|
|
13
|
+
*
|
|
14
|
+
* @remarks The channel is the one of the console interface, which every mode leaves visible: a verdict
|
|
15
|
+
* that fails while the screen says nothing at all is a verdict nobody can see, and the exit status is
|
|
16
|
+
* the signal of a user who is not looking.
|
|
17
|
+
*
|
|
18
|
+
* @remarks The status is marked with `process.exitCode` and not forced with `process.exit`, and this is
|
|
19
|
+
* the only way the evidence of a failing run reaches the `.vlog`: `vterm` feeds that file from a queue
|
|
20
|
+
* it flushes without anyone awaiting it, and a forced exit kills the process while the complete buffer
|
|
21
|
+
* of the commands is still in it. The status a user observes is the same one in both, because the run
|
|
22
|
+
* is already over by the time this is called; what changes is whether the transcript survives it.
|
|
23
|
+
*
|
|
24
|
+
* @param out - The logger or engine the failure is reported to.
|
|
25
|
+
* @param error - The failure, either an error or a message.
|
|
26
|
+
* @returns void
|
|
27
|
+
*/
|
|
28
|
+
function fail(out, error) {
|
|
29
|
+
out.error(`&C1${error?.message || error}`);
|
|
30
|
+
process.exitCode = 1;
|
|
31
|
+
}
|
|
32
|
+
// The command is resolved before the flags are parsed because the flags are declared per command: the
|
|
33
|
+
// global ones every command carries and the ones the invoked command owns. A command the map does not
|
|
34
|
+
// carry leaves nothing to parse and is answered by the console interface, help included, in every mode.
|
|
35
|
+
const cli = new DepflowCLI();
|
|
36
|
+
const command = commandName ? cli.getCommand(commandName) : undefined;
|
|
37
|
+
if (command) {
|
|
38
|
+
let parsed;
|
|
39
|
+
try {
|
|
40
|
+
parsed = new Flags(cli.declarationOf(commandName)).parse(argsList);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
fail(cli.out, error);
|
|
44
|
+
}
|
|
45
|
+
// A failed parse leaves nothing to dispatch: the invocation was never understood, so there is no
|
|
46
|
+
// argument to hand the command. The process still ends here, with the status `fail` marked.
|
|
47
|
+
if (parsed !== undefined) {
|
|
48
|
+
const { args, flags } = parsed;
|
|
49
|
+
cli.configPath = flags.flow;
|
|
50
|
+
try {
|
|
51
|
+
const exec = command.exec;
|
|
52
|
+
await exec.call(cli, commandName, args, flags);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
fail(cli.out, error);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
cli.out.error(`Unknown command: ${commandName}`);
|
|
61
|
+
cli.getCommand('help')?.exec.call(cli, 'help', []);
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=bin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";AAQA,OAAO,UAAU,MAAM,iBAAiB,CAAC;AACzC,OAAO,KAAK,MAAM,YAAY,CAAC;AAE/B,MAAM,IAAI,GAAG,CAAC,CAAC;AACf,MAAM,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAS,IAAI,CAAC,GAAoB,EAAE,KAAU;IAC1C,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,EAAE,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,sGAAsG;AACtG,sGAAsG;AACtG,wGAAwG;AACxG,MAAM,GAAG,GAAG,IAAI,UAAU,EAAE,CAAC;AAC7B,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAEtE,IAAI,OAAO,EAAE,CAAC;IACV,IAAI,MAAoD,CAAC;IACzD,IAAI,CAAC;QAAC,MAAM,GAAG,IAAI,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAqC,CAAC;IAAC,CAAC;IAC/G,OAAO,KAAU,EAAE,CAAC;QAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAAC,CAAC;IAE5C,iGAAiG;IACjG,4FAA4F;IAC5F,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;QAC/B,GAAG,CAAC,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC;QAE5B,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAuB,CAAC;YAC7C,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAqB,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACzB,CAAC;IACL,CAAC;AACL,CAAC;KAAM,CAAC;IACJ,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,oBAAoB,WAAW,EAAE,CAAC,CAAC;IACjD,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;AACvD,CAAC"}
|