depflow 3.0.0-dev.10 → 3.0.0-dev.11

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.
Files changed (172) hide show
  1. package/README.md +108 -43
  2. package/dist/builder/Builder.d.ts +279 -0
  3. package/dist/builder/Builder.js +391 -0
  4. package/dist/builder/Builder.js.map +1 -0
  5. package/dist/cli/CLI.d.ts +157 -0
  6. package/dist/cli/CLI.js +214 -0
  7. package/dist/cli/CLI.js.map +1 -0
  8. package/dist/cli/DepFLowCLI.d.ts +93 -0
  9. package/dist/cli/DepFLowCLI.js +413 -0
  10. package/dist/cli/DepFLowCLI.js.map +1 -0
  11. package/dist/cli/Flags.d.ts +106 -0
  12. package/dist/cli/Flags.js +125 -0
  13. package/dist/cli/Flags.js.map +1 -0
  14. package/dist/cli/bin.js +68 -0
  15. package/dist/cli/bin.js.map +1 -0
  16. package/dist/config/Config.d.ts +690 -0
  17. package/dist/config/Config.js +45 -0
  18. package/dist/config/Config.js.map +1 -0
  19. package/dist/config/ImportMap.d.ts +60 -0
  20. package/dist/config/ImportMap.js +66 -0
  21. package/dist/config/ImportMap.js.map +1 -0
  22. package/dist/config/JsonSchema.d.ts +12 -0
  23. package/dist/config/JsonSchema.js +26 -0
  24. package/dist/config/JsonSchema.js.map +1 -0
  25. package/dist/config/Settings.d.ts +201 -0
  26. package/dist/config/Settings.js +191 -0
  27. package/dist/config/Settings.js.map +1 -0
  28. package/dist/config/TSConfig.d.ts +73 -0
  29. package/dist/config/TSConfig.js +73 -0
  30. package/dist/config/TSConfig.js.map +1 -0
  31. package/dist/config/codecs/JsonCodec.d.ts +30 -0
  32. package/dist/config/codecs/JsonCodec.js +31 -0
  33. package/dist/config/codecs/JsonCodec.js.map +1 -0
  34. package/dist/config/codecs/YamlCodec.d.ts +62 -0
  35. package/dist/config/codecs/YamlCodec.js +89 -0
  36. package/dist/config/codecs/YamlCodec.js.map +1 -0
  37. package/dist/dependency/DepUtils.d.ts +50 -0
  38. package/dist/dependency/DepUtils.js +71 -0
  39. package/dist/dependency/DepUtils.js.map +1 -0
  40. package/dist/dependency/Dependency.d.ts +81 -0
  41. package/dist/dependency/Dependency.js +71 -0
  42. package/dist/dependency/Dependency.js.map +1 -0
  43. package/dist/dependency/Git.d.ts +75 -0
  44. package/dist/dependency/Git.js +97 -0
  45. package/dist/dependency/Git.js.map +1 -0
  46. package/dist/dependency/GitDependency.d.ts +30 -0
  47. package/dist/dependency/GitDependency.js +79 -0
  48. package/dist/dependency/GitDependency.js.map +1 -0
  49. package/dist/dependency/NpmDependency.d.ts +27 -0
  50. package/dist/dependency/NpmDependency.js +91 -0
  51. package/dist/dependency/NpmDependency.js.map +1 -0
  52. package/{build/support/PathResolver → dist/resolve}/AliasCompiler.d.ts +18 -5
  53. package/{build/support/PathResolver → dist/resolve}/AliasCompiler.js +31 -9
  54. package/dist/resolve/AliasCompiler.js.map +1 -0
  55. package/{build/support/PathResolver → dist/resolve}/PathResolver.d.ts +25 -8
  56. package/dist/resolve/PathResolver.js +133 -0
  57. package/dist/resolve/PathResolver.js.map +1 -0
  58. package/dist/resolve/PathRewriter.d.ts +24 -0
  59. package/{build/support/PathResolver → dist/resolve}/PathRewriter.js +21 -11
  60. package/dist/resolve/PathRewriter.js.map +1 -0
  61. package/{build → dist}/schema/Config/Builder.d.ts +114 -49
  62. package/dist/schema/Config/Builder.js +78 -0
  63. package/dist/schema/Config/Builder.js.map +1 -0
  64. package/{build → dist}/schema/Config/Config.d.ts +169 -78
  65. package/dist/schema/Config/Config.js +62 -0
  66. package/dist/schema/Config/Config.js.map +1 -0
  67. package/{build → dist}/schema/Config/Dependency.d.ts +219 -89
  68. package/dist/schema/Config/Dependency.js +80 -0
  69. package/dist/schema/Config/Dependency.js.map +1 -0
  70. package/{build → dist}/schema/Config/Extractor.d.ts +41 -17
  71. package/dist/schema/Config/Extractor.js +43 -0
  72. package/dist/schema/Config/Extractor.js.map +1 -0
  73. package/{build → dist}/schema/Config/Resolver.d.ts +25 -8
  74. package/dist/schema/Config/Resolver.js +43 -0
  75. package/dist/schema/Config/Resolver.js.map +1 -0
  76. package/{build → dist}/schema/Config/Transform.d.ts +22 -5
  77. package/dist/schema/Config/Transform.js +51 -0
  78. package/dist/schema/Config/Transform.js.map +1 -0
  79. package/dist/schema/Defaults.d.ts +20 -0
  80. package/dist/schema/Defaults.js +24 -0
  81. package/dist/schema/Defaults.js.map +1 -0
  82. package/dist/schema/ImportMap.d.ts +30 -0
  83. package/dist/schema/ImportMap.js +28 -0
  84. package/dist/schema/ImportMap.js.map +1 -0
  85. package/{build → dist}/schema/TSConfig.d.ts +23 -9
  86. package/dist/schema/TSConfig.js +39 -0
  87. package/dist/schema/TSConfig.js.map +1 -0
  88. package/{build → dist}/schema/schema.d.ts +11 -2
  89. package/{build → dist}/schema/schema.js +11 -2
  90. package/dist/schema/schema.js.map +1 -0
  91. package/dist/task/Command.d.ts +287 -0
  92. package/dist/task/Command.js +404 -0
  93. package/dist/task/Command.js.map +1 -0
  94. package/dist/task/Group.d.ts +15 -0
  95. package/dist/task/Group.js +29 -0
  96. package/dist/task/Group.js.map +1 -0
  97. package/dist/task/OutputPolicy.d.ts +262 -0
  98. package/dist/task/OutputPolicy.js +364 -0
  99. package/dist/task/OutputPolicy.js.map +1 -0
  100. package/dist/task/Task.d.ts +210 -0
  101. package/dist/task/Task.js +312 -0
  102. package/dist/task/Task.js.map +1 -0
  103. package/package.json +13 -10
  104. package/.gitignore +0 -7
  105. package/build/cli/DepFLowCLI.d.ts +0 -16
  106. package/build/cli/DepFLowCLI.js +0 -254
  107. package/build/cli/DepFLowCLI.js.map +0 -1
  108. package/build/cli/bin.js +0 -38
  109. package/build/cli/bin.js.map +0 -1
  110. package/build/config/Config.d.ts +0 -28
  111. package/build/config/Config.js +0 -46
  112. package/build/config/Config.js.map +0 -1
  113. package/build/config/ImportMap.d.ts +0 -51
  114. package/build/config/ImportMap.js +0 -97
  115. package/build/config/ImportMap.js.map +0 -1
  116. package/build/config/TSConfig.d.ts +0 -54
  117. package/build/config/TSConfig.js +0 -104
  118. package/build/config/TSConfig.js.map +0 -1
  119. package/build/schema/Config/Builder.js +0 -48
  120. package/build/schema/Config/Builder.js.map +0 -1
  121. package/build/schema/Config/Config.js +0 -20
  122. package/build/schema/Config/Config.js.map +0 -1
  123. package/build/schema/Config/Dependency.js +0 -25
  124. package/build/schema/Config/Dependency.js.map +0 -1
  125. package/build/schema/Config/Extractor.js +0 -25
  126. package/build/schema/Config/Extractor.js.map +0 -1
  127. package/build/schema/Config/Resolver.js +0 -25
  128. package/build/schema/Config/Resolver.js.map +0 -1
  129. package/build/schema/Config/Transform.js +0 -27
  130. package/build/schema/Config/Transform.js.map +0 -1
  131. package/build/schema/ImportMap.d.ts +0 -22
  132. package/build/schema/ImportMap.js +0 -12
  133. package/build/schema/ImportMap.js.map +0 -1
  134. package/build/schema/TSConfig.js +0 -19
  135. package/build/schema/TSConfig.js.map +0 -1
  136. package/build/schema/schema.js.map +0 -1
  137. package/build/support/Builder/Builder.d.ts +0 -46
  138. package/build/support/Builder/Builder.js +0 -116
  139. package/build/support/Builder/Builder.js.map +0 -1
  140. package/build/support/Dependency/Dependency.d.ts +0 -38
  141. package/build/support/Dependency/Dependency.js +0 -14
  142. package/build/support/Dependency/Dependency.js.map +0 -1
  143. package/build/support/Dependency/GitDependency.d.ts +0 -20
  144. package/build/support/Dependency/GitDependency.js +0 -67
  145. package/build/support/Dependency/GitDependency.js.map +0 -1
  146. package/build/support/Dependency/NpmDependency.d.ts +0 -18
  147. package/build/support/Dependency/NpmDependency.js +0 -65
  148. package/build/support/Dependency/NpmDependency.js.map +0 -1
  149. package/build/support/Git.d.ts +0 -53
  150. package/build/support/Git.js +0 -86
  151. package/build/support/Git.js.map +0 -1
  152. package/build/support/PathResolver/AliasCompiler.js.map +0 -1
  153. package/build/support/PathResolver/PathResolver.js +0 -105
  154. package/build/support/PathResolver/PathResolver.js.map +0 -1
  155. package/build/support/PathResolver/PathRewriter.d.ts +0 -18
  156. package/build/support/PathResolver/PathRewriter.js.map +0 -1
  157. package/build/support/PathResolver/Utils.d.ts +0 -36
  158. package/build/support/PathResolver/Utils.js +0 -45
  159. package/build/support/PathResolver/Utils.js.map +0 -1
  160. package/build/support/Task/Command.d.ts +0 -49
  161. package/build/support/Task/Command.js +0 -100
  162. package/build/support/Task/Command.js.map +0 -1
  163. package/build/support/Task/Task.d.ts +0 -84
  164. package/build/support/Task/Task.js +0 -145
  165. package/build/support/Task/Task.js.map +0 -1
  166. package/build/support/Utils.d.ts +0 -40
  167. package/build/support/Utils.js +0 -138
  168. package/build/support/Utils.js.map +0 -1
  169. package/build/support/Validator.d.ts +0 -22
  170. package/build/support/Validator.js +0 -28
  171. package/build/support/Validator.js.map +0 -1
  172. /package/{build → dist}/cli/bin.d.ts +0 -0
package/README.md CHANGED
@@ -14,6 +14,7 @@ Key goals:
14
14
  - NPM dependency extraction and local mirroring
15
15
  - Automatic `tsconfig` paths and browser `importmap` generation via `dep sync`
16
16
  - Flexible resolver aliases for local and CDN targets
17
+ - Reproducible checkouts: every install lands on the tag the configuration asks for
17
18
 
18
19
  ---
19
20
 
@@ -31,16 +32,16 @@ Alternatively, add it as a dev-dependency for project-specific usage.
31
32
 
32
33
  ## Quick Start
33
34
 
34
- 1. Create a configuration file (recommended name: `depflow.json`).
35
+ 1. Create a configuration file, `depflow.yml` (or any other name, passed with `--flow`).
35
36
  2. Run `dep install` to fetch and build all configured dependencies.
36
37
  3. Run `dep sync` to update `tsconfig` paths and `importmap` (if configured).
37
38
 
38
39
  CLI examples:
39
40
 
40
41
  ```bash
41
- # install dependencies defined in .df.json
42
+ # install the dependencies declared in depflow.yml
42
43
  dep install
43
- # --flow filepath.json for use an specific config
44
+ # --flow <file> to use a specific config instead
44
45
 
45
46
  # sync tsconfig/importmap from the configuration
46
47
  dep sync
@@ -50,24 +51,27 @@ dep sync
50
51
 
51
52
  ## Configuration
52
53
 
53
- DepFlow uses a JSON configuration file describing where to fetch dependencies and how to build and expose them. The minimal structure:
54
+ DepFlow uses a single configuration file describing where to fetch dependencies and how to build and expose them. The format follows the extension: `.yml` and `.yaml` are read and written as YAML, `.json` as JSON. Without `--flow`, the CLI reads `depflow.yml` from the current working directory.
54
55
 
55
- - `flowFolder` (string): folder where DepFlow stores temporary state (default: `.depflow`).
56
- - `outDir` (string): project output root used by extract rules.
56
+ A YAML config is read as a document, so key order, indentation and the comments of the keys a save does not touch are preserved; a config created from scratch is written in block style, documented with a comment per key, and accompanied by an editor JSON Schema at `.depflow/schema.json`.
57
+
58
+ The minimal structure:
59
+
60
+ - `outDir` (string): project output root scanned by `rewrite-paths` (and by the watcher). Defaults to `dist`. Extraction targets are *not* relative to it, they are relative to the project root, see [Builder rules](#builder-rules).
57
61
  - `tsconfig` (string|null): optional path to TypeScript `tsconfig.json` to update `compilerOptions.paths`.
58
62
  - `importmap` (string|null): optional path to write a browser `importmap`.
63
+ - `actions` (object): named pipelines runnable with `dep run <action>`.
59
64
  - `dependencies` (array): Git-based dependencies.
60
65
  - `npmDependencies` (array): NPM packages to extract files from.
61
66
 
62
- Each dependency supports `builder` steps (run commands, file extraction) and `resolver` entries that map aliases to local or CDN targets.
67
+ Each dependency supports `builder` steps (run commands, file extraction, content transformation) and `resolver` entries that map aliases to local or CDN targets.
63
68
 
64
69
  ### Example Configuration
65
70
 
66
- Below is an example adapted from a real project configuration. Use it as a template for your repository.
71
+ Shown as JSON, which the CLI reads and writes just as well as YAML whenever the file is named `.json`. The extraction targets are shown as absolute paths, which is the only form that survives being copied between machines: a relative one is resolved against the project root, the same as every other relative path of the configuration.
67
72
 
68
73
  ```json
69
74
  {
70
- "flowFolder": ".depflow",
71
75
  "outDir": ".",
72
76
  "tsconfig": "tsconfig.web.json",
73
77
  "importmap": "public/importmap.json",
@@ -75,19 +79,22 @@ Below is an example adapted from a real project configuration. Use it as a templ
75
79
  {
76
80
  "name": "NetFeez.Vizui",
77
81
  "repo": "https://github.com/NetFeez/Vizui.git",
82
+ "tag": "v1.2.0",
78
83
  "builder": [
79
84
  {
80
- "run": ["npm install", "npm run compile"],
81
- "extract": [
82
- { "from": "build/**/*.js", "to": "public/lib/vizui/", "replacer": "^build/" },
83
- { "from": "build/**/*.d.ts", "to": "public/lib/vizui/", "replacer": "^build/" }
84
- ]
85
+ "run": [ "npm install", "npm run compile" ]
86
+ },
87
+ {
88
+ "extract": {
89
+ "build/**/*.js": { "to": "/abs/path/to/app/public/lib/vizui/", "map": "^build/" },
90
+ "build/**/*.d.ts": { "to": "/abs/path/to/app/public/lib/vizui/", "map": "^build/" }
91
+ }
85
92
  }
86
93
  ],
87
- "resolver": [
88
- { "alias": "vizui", "target": "public/lib/vizui/vizui.js" },
89
- { "alias": "vizui/*", "target": "public/lib/vizui/*" }
90
- ]
94
+ "resolver": {
95
+ "vizui": "public/lib/vizui/vizui.js",
96
+ "vizui/*": "public/lib/vizui/*"
97
+ }
91
98
  }
92
99
  ],
93
100
  "npmDependencies": [
@@ -96,40 +103,88 @@ Below is an example adapted from a real project configuration. Use it as a templ
96
103
  "version": "latest",
97
104
  "builder": [
98
105
  {
99
- "extract": [
100
- { "from": "build/**/*.js", "to": "public/lib/common/", "replacer": "^build/" },
101
- { "from": "build/**/*.d.ts", "to": "public/lib/common/", "replacer": "^build/" }
102
- ]
106
+ "extract": {
107
+ "build/**/*.js": { "to": "/abs/path/to/app/public/lib/common/", "map": "^build/" },
108
+ "build/**/*.d.ts": { "to": "/abs/path/to/app/public/lib/common/", "map": "^build/" }
109
+ }
103
110
  }
104
111
  ],
105
- "resolver": [
106
- { "alias": "@netfeez/common", "target": "public/lib/common/index.js" },
107
- { "alias": "@netfeez/common/*", "target": "public/lib/common/*" }
108
- ]
112
+ "resolver": {
113
+ "@netfeez/common": "public/lib/common/index.js",
114
+ "@netfeez/common/*": "public/lib/common/*"
115
+ }
109
116
  }
110
117
  ]
111
118
  }
112
119
  ```
113
120
 
121
+ ### Dependency identity
122
+
123
+ The `name` of a dependency is its identity, not a path: it is a single path segment, and it is also the
124
+ name of its checkout folder inside `.depflow`. A name may not be a path, may not start with a dot, and may
125
+ not be one of the names the flow folder reserves for itself (`schema.json` and `node_modules`).
126
+
127
+ The `repo` of a git dependency is any value `git clone` accepts: a URL with its scheme, an SSH address or a
128
+ local path of a repository. It always carries the `.git` suffix, whichever transport it comes in. `tag` is the
129
+ revision the checkout lands on after cloning and after every reinstall; it defaults to `main`.
130
+
114
131
  ### Builder rules
115
- - `run`: a string or array of shell commands executed inside the dependency checkout.
116
- - `extract`: patterns describing which files to copy from the dependency build output into your project. Each extractor may include `from`, `to`, and an optional `replacer` regex used to rewrite paths.
132
+
133
+ A pipeline is an ordered list of steps, each of them exactly one of:
134
+
135
+ - `run`: a string or a list of shell commands executed inside the dependency checkout. It accepts
136
+ `maxTimeMs` (deadline in milliseconds, `-1` for no deadline, defaults to `60000`) and `allowFails`
137
+ (whether a failed command is tolerated, defaults to `false`).
138
+ - `extract`: a mapping of source globs to extraction entries, or a destination folder as a shorthand for
139
+ `**/*` → that folder. The globs are matched against the folder the pipeline works in (the dependency
140
+ checkout, or the project itself for a `dep run` action) and an entry is a destination (`to`) plus,
141
+ optionally, a `map` transformation applied to the destination path and a `transform` transformation
142
+ applied to the content of the files. A relative `to` is resolved against the project root and an
143
+ absolute one is used as it stands, so a pipeline reads from the dependency and deposits into the
144
+ project. `map` runs against the *relative* path of the matched file, inside the destination.
145
+ - `transform`: a `glob` plus a `search`/`replace` transformation applied in place to the matched files.
146
+
147
+ Every transformation (`map`, `transform`, and the in-place `transform` step) takes one of two forms, and
148
+ they do not mean the same thing:
149
+
150
+ - a **string** is a pattern to *remove*: `"^build/"` strips that prefix from the path of every matched
151
+ file, globally;
152
+ - an **object** `{ "search": ..., "flags": ..., "replace": ... }` is the only form that *substitutes*
153
+ something: `search` is the pattern, `replace` what takes its place, and `flags` defaults to `g`.
154
+
155
+ ```json
156
+ { "map": "^build/" }
157
+ { "map": { "search": "^build/(.*)\\.js$", "replace": "$1.js" } }
158
+ ```
159
+
160
+ An object whose `replace` is empty removes the matches exactly as the string form does.
117
161
 
118
162
  ### Resolver entries
119
- - `alias`: module alias exposed to your project (used in `importmap` and `tsconfig` paths).
120
- - `target`: a string path or an object with `local` and `cdn` properties for multi-target deployments.
163
+
164
+ The `resolver` of a dependency, and the `resolver` of the configuration, are mappings of an alias to its
165
+ target. The target is either a string path or an object with these keys:
166
+
167
+ - `local` (string, required): the path the alias resolves to, resolved against the project root. `sync`
168
+ turns it into the `tsconfig` `paths` entry (and into the `importmap` entry unless `--cdn` is given),
169
+ and `rewrite-paths` rewrites the built files' imports that point at it.
170
+ - `type` (string, optional): the target holding the type declarations. It becomes the *first* entry of
171
+ the generated `paths` array, so the editor finds the `.d.ts` next to the value. Unlike `local`, it is
172
+ not resolved against the project root, so it has to be an absolute path.
173
+ - `cdn` (string, optional): the URL that replaces `local` when `--cdn` is given.
174
+
175
+ A `*` suffix on the alias turns it into a mapping, so `vizui/*` also covers `vizui/Button`.
121
176
 
122
177
  ---
123
178
 
124
179
  ## CLI Reference
125
180
 
126
- Use the distribution script in `build/cli/bin.js` or install the package globally.
181
+ Use the distribution script in `dist/cli/bin.js` or install the package globally.
127
182
 
128
183
  - `install`: Clone, build and extract artifacts for all dependencies in your config.
129
184
  - `sync`: Generate/update `tsconfig` paths and browser `importmap` according to `resolver` entries.
130
- - `list`: Show configured dependencies and their status.
185
+ - `list`: Show configured dependencies and whether each one is installed.
131
186
 
132
- Use `node ./build/cli/bin.js <command> --flow <config>` when running locally from the repository.
187
+ Use `node ./dist/cli/bin.js <command> --flow <config>` when running locally from the repository.
133
188
 
134
189
  ### Commands
135
190
 
@@ -137,20 +192,21 @@ The CLI exposes the following commands (all commands accept the global `--flow <
137
192
 
138
193
  | Command | Usage | Description |
139
194
  |---|---|---|
140
- | `add` | `dep add <repo_url> [name] [--flow <file>]` | Add a git dependency to the configuration file. If the configuration file does not exist it will be created automatically (default: `depflow.json`). If `name` is omitted the repo name is used. |
141
- | `remove` | `dep remove <name|repo_url> [--flow <file>]` | Remove a dependency by `name` or repository URL. |
142
- | `install` | `dep install [name1 name2 ...] [--flow <file>]` | Clone, build and extract artifacts for all or specific dependencies. Runs `dep sync` after install. |
143
- | `uninstall` | `dep uninstall [name1 name2 ...] [--flow <file>]` | Remove local files for configured dependencies. |
144
- | `list` | `dep list [--flow <file>]` | List all dependencies declared in the configuration. |
145
- | `rewrite-paths` | `dep rewrite-paths [--watch] [--cdn] [--flow <file>]` | Rewrite built files' paths according to resolver aliases. Use `--watch` to run a watcher; use `--cdn` to apply CDN targets instead of local targets. |
195
+ | `add` | `dep add <repo_url> [name] [--flow <file>]` | Add a git dependency to the configuration file. If the configuration file does not exist it will be created automatically, in the format its extension asks for (default: `depflow.yml`). When the name is omitted it is derived from the repository, which only a GitHub repository allows; any other repository needs the name to be given. A name already taken by another dependency is refused. |
196
+ | `remove` | `dep remove <name\|repo_url> [--flow <file>]` | Remove a dependency by `name` or repository URL and uninstall its local files. An identifier that no dependency declares is an error. |
197
+ | `install` | `dep install [name1 name2 ...] [--flow <file>]` | Clone, build and extract artifacts for all or specific dependencies. Runs `dep sync` after install. A dependency that is already present is brought to the revision of its `tag` instead of being cloned again. |
198
+ | `list` | `dep list [--flow <file>]` | List all dependencies declared in the configuration, telling an `installed` one (its folder is in place under `.depflow`) from a `missing` one. |
199
+ | `rewrite-paths` | `dep rewrite-paths [--watch] [--cdn] [--flow <file>]` | Rewrite built files' paths according to resolver aliases. Use `--watch` to run a watcher; use `--cdn` to apply CDN targets instead of local targets. A built file that cannot be rewritten makes the command fail instead of being left pointing at the source tree. |
146
200
  | `sync` | `dep sync [--cdn] [--flow <file>]` | Update `tsconfig` paths and generate `importmap` from resolver aliases. Use `--cdn` to prefer CDN targets when generating the importmap. |
147
201
 
148
202
  ### Flags
149
203
 
150
- - `--flow <file>`: Specify an alternate configuration file (for example `.df.json` or `depflow.json`). If omitted, the CLI defaults to `depflow.json` in the current working directory.
204
+ - `--flow <file>` / `-f <file>` / `-p <file>`: Specify an alternate configuration file (for example `depflow.json` or `depflow.yaml`). When omitted, the CLI uses `depflow.yml` in the current working directory; any other file has to be named here.
151
205
  - `--cdn`: When present for `sync` or `rewrite-paths`, instructs the tool to use CDN targets from resolver entries instead of `local` targets when generating the `importmap` or rewriting paths.
152
206
  - `--watch` / `-w`: For `rewrite-paths` only — run a file watcher that keeps rewriting paths as files change.
153
207
 
208
+ Every token starting with a dash is a flag, and a flag is the whole token, so short clusters are not expanded (`-abc` is the single flag `-abc`, not `-a -b -c`). A value flag takes the value from the next token when that token is not a flag, or written inline as `--flag=value`; a boolean flag never consumes the next token and only accepts `=true` or `=false` inline. Names are matched with or without their dash prefix, so `-f` and `--flow` reach the same flag. The last occurrence of a flag wins, `--` ends the flags and turns the remaining tokens into positional arguments, and an undeclared flag is reported as an error.
209
+
154
210
  Examples:
155
211
 
156
212
  ```bash
@@ -166,6 +222,15 @@ dep rewrite-paths --flow .df.json --watch
166
222
 
167
223
  ---
168
224
 
169
- If you want, I can also:
170
- - add quick examples for `tsconfig` path snippets generated by `dep sync`,
171
- - or produce a Spanish summary for quick internal reference.
225
+ ## Build steps in depth
226
+
227
+ A `run` step is the only place where a shell script is interpreted, and it is where the failure semantics
228
+ live:
229
+
230
+ - every command of the step runs, even after one of them fails, so a build reports the whole picture;
231
+ - `allowFails: true` turns a failed command into information: the step completes and the build continues;
232
+ - `maxTimeMs` is a deadline for the whole step, not per command, and a deadline that is reached fails the
233
+ step even when `allowFails` is set: the work never finished, so the result is not the one that was asked for.
234
+
235
+ The verdict of a step is awaited, never read from a log: a build that cannot do what it was configured to
236
+ do fails, and the failure travels up to whoever asked for the build.
@@ -0,0 +1,279 @@
1
+ import type Logger from "@netfeez/vterm";
2
+ import Task from "../task/Task.js";
3
+ import OutputPolicy from "../task/OutputPolicy.js";
4
+ import schema from "../schema/schema.js";
5
+ export declare class Builder {
6
+ protected readonly pipeline: schema.Builder;
7
+ protected readonly cwd: string;
8
+ protected readonly projectRoot: string;
9
+ protected readonly logger: Logger | null;
10
+ protected readonly policy: OutputPolicy | null;
11
+ /** The step that stopped the pipeline, or `null` while it is still walking it. */
12
+ protected vStopped: Builder.Stopped | null;
13
+ constructor(info: Builder.Info);
14
+ /**
15
+ * Runs the pipeline and reports what every step of it did.
16
+ * @returns A promise resolving with the report of the run, or rejecting with a
17
+ * {@link Builder.Failure} carrying that same report, when a step stopped the pipeline.
18
+ *
19
+ * @remarks The report is the verdict of the run, and it is produced whether the run succeeded or
20
+ * failed: a caller that catches a {@link Builder.Failure} gets the steps that ran before the one
21
+ * that stopped it, and the steps that never ran at all, so nothing about the pipeline is missing
22
+ * from a failure.
23
+ *
24
+ * @remarks The group of the run is closed in a `finally`, so the steps of a pipeline that threw leave
25
+ * the output as closed as the ones of a pipeline that finished. It is opened only when the run
26
+ * decorates its output, because a group that draws nothing still leaves a box and an indentation
27
+ * around every line written inside it.
28
+ */
29
+ run(): Promise<Builder.Report>;
30
+ /**
31
+ * Walks the pipeline in order, running each step until one of them stops it.
32
+ * @returns A promise resolving with one report per step of the pipeline, the ones that ran and the
33
+ * ones the stop left behind.
34
+ */
35
+ protected walk(): Promise<Builder.StepReport[]>;
36
+ /**
37
+ * Runs one step of the pipeline and turns it into its report.
38
+ * @param index - The position of the step inside the pipeline, starting at 1.
39
+ * @param entry - The entry of the pipeline describing the step.
40
+ * @returns A promise resolving with the report of the step.
41
+ *
42
+ * @remarks An entry that carries no step at all is reported as one that did not run, the way the
43
+ * pipeline has always walked over it, and the report accounts for it all the same.
44
+ */
45
+ protected runStep(index: number, entry: schema.BuilderEntry): Promise<Builder.StepReport>;
46
+ /**
47
+ * Runs the commands of a `run` step as a Task, settling the step with the verdict of the task.
48
+ * @param index - The position of the step inside the pipeline, starting at 1.
49
+ * @param entry - The `run` entry describing the step.
50
+ * @returns A promise resolving with the report of the step.
51
+ *
52
+ * @remarks A step that does not tolerate its failures stops the pipeline, so the steps after it are
53
+ * reported as steps that never ran. The step itself is not rethrown from here: the report of the run
54
+ * is the verdict of the pipeline, and rejecting twice would report the same failure twice.
55
+ */
56
+ protected runRun(index: number, entry: schema.RunEntry): Promise<Builder.StepReport>;
57
+ /**
58
+ * How many steps of the pipeline run commands, the number a command identity is qualified by.
59
+ * @returns The amount of `run` entries in the pipeline.
60
+ */
61
+ protected get steps(): number;
62
+ /**
63
+ * Runs the shell commands of a build step as a Task, reporting them through the policy of the run.
64
+ * The verdict of the task is the verdict of the step: it is awaited, never read from an event.
65
+ * @param commands - The shell commands to run, in order.
66
+ * @param cwd - The working directory the commands run in.
67
+ * @param options - The options of the step: its deadline and whether its failures are tolerated.
68
+ * @param identity - The identity the commands of this task are reported under.
69
+ * @returns A promise resolving with the summary of the run of the task.
70
+ * @throws { Task.Failure } When the step fails and does not tolerate failures.
71
+ */
72
+ protected runTask(commands: string[], cwd: string, options: Task.Options, identity: OutputPolicy.Identity): Promise<Task.FinishData>;
73
+ /**
74
+ * Applies a global transformation to every file of the working directory, the one the configuration
75
+ * asks for through its glob.
76
+ * @param options - The transformation to apply, either as a search and replace pair or as a plain
77
+ * regular expression.
78
+ * @returns A promise resolving when every file of the glob has been transformed.
79
+ */
80
+ protected runGlobalTransform(options: schema.GlobalTransform): Promise<void>;
81
+ /**
82
+ * Resolves the destination folder of an extraction entry, which is relative to the project root, and
83
+ * guarantees it stays inside it.
84
+ * @param to - The destination folder declared by the entry.
85
+ * @returns The normalized path of the destination folder.
86
+ * @throws { Error } When a relative destination escapes the project root.
87
+ *
88
+ * @remarks An absolute destination is taken as it stands: writing outside the project is a decision
89
+ * the configuration takes on purpose, and spelling it out as an absolute path is what makes it one.
90
+ * A relative destination cannot, because a `..` that walks out of the project is a mistake and not a
91
+ * decision. The project root is a destination like any other, so it is not treated as an escape.
92
+ */
93
+ protected resolveDestination(to: string): string;
94
+ /**
95
+ * Runs the extraction process based on the provided entry configuration, which can be either a string or an array of extraction entries.
96
+ * It handles the copying of files from the specified source to the target location, applying any necessary path transformations based on the provided replacer configuration.
97
+ * This method is essential for managing the file extraction phase of the build process, allowing for flexible and customizable file handling as defined in the builder configuration.
98
+ * @param entry - A string or an array of extraction entries that define the source, target, and optional path transformation for the extraction process.
99
+ * @returns A promise that resolves when the extraction process is complete, or rejects with an error if any issues occur during the file copying or transformation.
100
+ * @throws Will throw an error if any issues occur during the file copying process, such as problems with reading or writing files, or if the provided entry configuration is invalid.
101
+ */
102
+ protected runExtractor(entry: string | schema.Extractor): Promise<void>;
103
+ /**
104
+ * Creates a string replacement function based on the provided replacer configuration, which can be either a simple string or an object defining a search pattern and replacement string. This method is used to generate a function that can be applied to strings for dynamic transformations during the build process, allowing for flexible and customizable string manipulation as defined in the builder configuration.
105
+ * @param replacer - A configuration for string replacement, which can be either a string (used as a regex pattern) or an object containing a search pattern and replacement string.
106
+ * @returns A function that takes a string as input and returns a new string with the specified replacements applied, based on the provided replacer configuration.
107
+ * @throws Will throw an error if the provided replacer configuration is invalid, such as if it is neither a string nor an object with the required properties.
108
+ */
109
+ protected static replacer(replacer?: schema.Transform): Builder.Transformer;
110
+ /**
111
+ * The kind of step an entry of the pipeline describes, decided by the key it carries.
112
+ * @param entry - The entry of the pipeline.
113
+ * @returns The kind of the step, or `null` when the entry describes no step at all.
114
+ */
115
+ protected static kind(entry: schema.BuilderEntry): Builder.Kind | null;
116
+ /**
117
+ * The identity the commands of a `run` step are reported under.
118
+ *
119
+ * @remarks A command is identified as `C<M>` inside its own task, and as `S<N> · C<M>` when the
120
+ * pipeline runs more than one of them: with a single `run` step there is nothing to qualify it
121
+ * against, and with more than one there is, so `C1` alone would name two different commands.
122
+ *
123
+ * @param index - The position of the step inside the pipeline, starting at 1.
124
+ * @param steps - How many `run` steps the pipeline has.
125
+ * @returns The identity of the commands of the step.
126
+ */
127
+ protected static identity(index: number, steps: number): OutputPolicy.Identity;
128
+ /**
129
+ * The report of a command inside a step: who it was and how it ended, without what it printed.
130
+ *
131
+ * @remarks The output of a command is not part of the report: a report says what the pipeline did,
132
+ * and a build that printed a log would carry that log in every summary it produced, in every layer
133
+ * that received it. The output stays where it was produced, in the results of the task, and it is
134
+ * read once, when the task settles.
135
+ *
136
+ * @param result - The result of the command.
137
+ * @returns The report of the command.
138
+ */
139
+ protected static commandReport(result: Task.commandResult): Builder.CommandReport;
140
+ /**
141
+ * The report of a step that ran and had nothing to report beyond having run.
142
+ * @param index - The position of the step inside the pipeline, starting at 1.
143
+ * @param kind - The kind of the step, which a step that only works on files never has.
144
+ * @returns The report of the step.
145
+ */
146
+ protected static settled(index: number, kind: Builder.Kind): Builder.StepReport;
147
+ /**
148
+ * The report of a step that never ran, either because an earlier one stopped the pipeline or because
149
+ * the entry describes no step at all.
150
+ * @param index - The position of the step inside the pipeline, starting at 1.
151
+ * @param kind - The kind of the step, `null` when the entry describes none.
152
+ * @returns The report of the step that did not run.
153
+ */
154
+ protected static pending(index: number, kind: Builder.Kind | null): Builder.StepReport;
155
+ /**
156
+ * The report of a whole pipeline.
157
+ * @param steps - One report per step of the pipeline, in order.
158
+ * @returns The report of the run.
159
+ */
160
+ protected static report(steps: Builder.StepReport[]): Builder.Report;
161
+ /**
162
+ * Why the pipeline stopped, read from the step that stopped it: the reason the step could not
163
+ * complete, or the commands that failed and it did not tolerate.
164
+ * @param report - The report of the run.
165
+ * @returns The reason the run did not finish successfully.
166
+ */
167
+ protected static reason(report: Builder.Report): Builder.Reason;
168
+ }
169
+ export declare namespace Builder {
170
+ type Transformer = (str: string) => string;
171
+ type Kind = 'run' | 'extract' | 'transform';
172
+ type Entry = schema.RunEntry | schema.ExtractEntry | schema.TransformEntry;
173
+ type Reason = Task.Reason | 'command' | 'step';
174
+ interface Info {
175
+ pipeline: schema.Builder;
176
+ /**
177
+ * The folder the pipeline reads and works in: the checkout of a dependency, or the project itself
178
+ * for a `dep run` action. It is the base of every glob, of every `run` step and of every `map`.
179
+ */
180
+ cwd: string;
181
+ /**
182
+ * The root of the project the pipeline deposits into. It is the base of every relative `to` of an
183
+ * extraction step, which is where the artifacts of a dependency are meant to land.
184
+ */
185
+ projectRoot: string;
186
+ logger?: Logger | null;
187
+ /**
188
+ * The policy the output of the commands of the pipeline is reported through. Without it the
189
+ * builder falls back to the logger it was given, which streams the live output and says nothing
190
+ * else about it.
191
+ */
192
+ policy?: OutputPolicy | null;
193
+ }
194
+ /** What one command of a `run` step did, without what it printed. */
195
+ interface CommandReport {
196
+ /** The position of the command inside its step, starting at 1. */
197
+ ordinal: number;
198
+ /** The human readable form of the command, whole, as it was given. */
199
+ label: string;
200
+ /** Whether the command ended as it was asked to. */
201
+ success: boolean;
202
+ /** The exit status, or `null` when there was none. */
203
+ code: number | null;
204
+ /** The signal that took the command down, or `null` when there was none. */
205
+ signal: NodeJS.Signals | null;
206
+ /** Why there is no status at all, or `null` when the command reported one. */
207
+ reason: Task.Reason | null;
208
+ /** The time the command took, in milliseconds. */
209
+ time: number;
210
+ }
211
+ /**
212
+ * What one step of the pipeline did.
213
+ *
214
+ * @remarks The kind of a step is `null` only for an entry that describes no step at all, which the
215
+ * pipeline walks over: the report accounts for every entry of the pipeline, and an entry that runs
216
+ * nothing has no kind to account for it with.
217
+ */
218
+ interface StepReport {
219
+ /** The position of the step inside the pipeline, starting at 1. */
220
+ index: number;
221
+ /** The kind of the step, `null` when the entry describes none. */
222
+ kind: Kind | null;
223
+ /** Whether the step ran, `false` for the steps an earlier failure left behind. */
224
+ ran: boolean;
225
+ /** Whether the step ended as it was asked to. */
226
+ success: boolean;
227
+ /** How many commands of the step failed. */
228
+ failed: number;
229
+ /** Whether the step tolerated the failures it had, so the pipeline kept going. */
230
+ tolerated: boolean;
231
+ /** Why the step could not complete, or `null` when it completed. */
232
+ reason: Reason | null;
233
+ /** One report per command of a `run` step, empty for every other kind. */
234
+ commands: CommandReport[];
235
+ }
236
+ /** What a whole pipeline did. */
237
+ interface Report {
238
+ /** Whether every step of the pipeline ran and succeeded. */
239
+ ok: boolean;
240
+ /** How many commands ran, across every step. */
241
+ commands: number;
242
+ /** How many of them failed. */
243
+ failed: number;
244
+ /** How many of those failures a step tolerated, so the pipeline kept going. */
245
+ tolerated: number;
246
+ /** One report per step of the pipeline, in order, the ones that ran and the ones that did not. */
247
+ steps: StepReport[];
248
+ }
249
+ /** Why the pipeline stopped, and at which step, kept while the remaining steps are still being reported. */
250
+ interface Stopped {
251
+ index: number;
252
+ reason: Reason;
253
+ }
254
+ /**
255
+ * The failure of a pipeline, carrying the report of the run that produced it.
256
+ *
257
+ * @remarks The report is the same one the run would have resolved with, so a caller that only wants
258
+ * to know how the pipeline went catches this and reads it instead of rebuilding it from the steps
259
+ * that did run.
260
+ */
261
+ class Failure extends Error {
262
+ readonly report: Report;
263
+ readonly reason: Reason;
264
+ /**
265
+ * Creates the failure of a pipeline.
266
+ * @param report - The report of the run.
267
+ * @param reason - Why the pipeline stopped.
268
+ */
269
+ constructor(report: Report, reason?: Reason);
270
+ /**
271
+ * The message describing which step stopped the pipeline and why, in one line.
272
+ * @param report - The report of the run.
273
+ * @param reason - Why the pipeline stopped.
274
+ * @returns The message of the failure.
275
+ */
276
+ private static message;
277
+ }
278
+ }
279
+ export default Builder;