@travetto/pack 3.0.2 → 3.1.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  <!-- This file was generated by @travetto/doc and should not be modified directly -->
2
- <!-- Please modify https://github.com/travetto/travetto/tree/main/module/pack/DOC.ts and execute "npx trv doc" to rebuild -->
2
+ <!-- Please modify https://github.com/travetto/travetto/tree/main/module/pack/DOC.tsx and execute "npx trv doc" to rebuild -->
3
3
  # Pack
4
+
4
5
  ## Code packing utilities
5
6
 
6
7
  **Install: @travetto/pack**
@@ -12,44 +13,44 @@ npm install @travetto/pack
12
13
  yarn add @travetto/pack
13
14
  ```
14
15
 
15
- This module provides the necessary tools to produce deliverable output for [Travetto](https://travetto.dev) based projects. The main interaction with this module is through the command line interface, and the operations it provides. Under the covers, the code bundling is performed by [Rollup](https://rollupjs.org/), with specific configuration to support the frameworks runtime expectations.
16
+ This module provides the necessary tools to produce deliverable output for [Travetto](https://travetto.dev) based projects. The main interaction with this module is through the command line interface, and the operations it provides. Under the covers, the code bundling is performed by [Rollup](https://rollupjs.org/), with specific configuration to support the frameworks runtime expectations.
16
17
 
17
18
  There are three primary cli commands for packing your code:
18
-
19
19
  * pack
20
20
  * pack:zip
21
21
  * pack:docker
22
22
 
23
- ## CLI - pack
23
+ ## CLI - pack
24
24
 
25
25
  **Terminal: Pack usage**
26
26
  ```bash
27
27
  $ trv pack --help
28
28
 
29
- Usage: pack [options] [args...]
29
+ Usage: pack [options]
30
30
 
31
31
  Options:
32
- -w, --workspace <workspace> Workspace for building
33
- -c, --no-clean Disables: Clean workspace
34
- -o, --output <output> Output location
35
- -es, --main-scripts <main-scripts> Create entry scripts
36
- -f, --main-name <main-name> Main name for build artifact
37
- -e, --entry-point <entry-point> Entry point (default: "@travetto/cli/support/entry.cli")
38
- -m, --no-minify Disables: Minify output
39
- -sm, --sourcemap Bundle source maps
40
- -is, --include-sources Include source with source maps
41
- -x, --eject-file <eject-file> Eject commands to file
42
- -h, --help display help for command
32
+ -w, --workspace <string> Workspace for building (default: "/tmp/<temp-folder>")
33
+ --clean, --no-clean Clean workspace (default: true)
34
+ -o, --output <string> Output location
35
+ --main-scripts, --no-main-scripts Create entry scripts (default: true)
36
+ -f, --main-name <string> Main name for build artifact
37
+ -e, --entry-point <string> Entry point (default: "@travetto/cli/support/entry.cli")
38
+ --minify, --no-minify Minify output (default: true)
39
+ -sm, --sourcemap Bundle source maps (default: false)
40
+ -is, --include-sources Include source with source maps (default: false)
41
+ -x, --eject-file <string> Eject commands to file
42
+ -m, --module <string> Module to run for
43
+ -h, --help display help for command
43
44
  ```
44
45
 
45
- This command line operation will compile your project, and produce a ready to use workspace as a deliverable. Additionally, you can pass in a file to the `eject-file` flag that will allow for a script to be produced (base on the host operating system).
46
+ This command line operation will compile your project, and produce a ready to use workspace as a deliverable. Additionally, you can pass in a file to the `eject-file` flag that will allow for a script to be produced (base on the host operating system).
46
47
 
47
- Specific to this CLI command, the `output` field determines where the final folder is written that contains all the compiled source.
48
+ Specific to this CLI command, the `output` field determines where the final folder is written that contains all the compiled source.
48
49
 
49
50
  ### Entry Point Configuration
50
- Every application requires an entry point to determine execution flow (and in [Rollup](https://rollupjs.org/)'s case, tree-shaking as well.). By default the [Command Line Interface](https://github.com/travetto/travetto/tree/main/module/cli#readme "CLI infrastructure for Travetto framework") acts as the entry point. This bypasses the [Compiler](https://github.com/travetto/travetto/tree/main/module/compiler#readme "The compiler infrastructure for the Travetto framework") intentionally, as the compiler is not available at runtime.
51
+ Every application requires an entry point to determine execution flow (and in [Rollup](https://rollupjs.org/)'s case, tree-shaking as well.). By default the [Command Line Interface](https://github.com/travetto/travetto/tree/main/module/cli#readme "CLI infrastructure for Travetto framework") acts as the entry point. This bypasses the [Compiler](https://github.com/travetto/travetto/tree/main/module/compiler#readme "The compiler infrastructure for the Travetto framework") intentionally, as the compiler is not available at runtime.
51
52
 
52
- Within the command line, the `args` are positional arguments that will be passed to the entry point on application run.
53
+ Within the command line, the `args` are positional arguments that will be passed to the entry point on application run.
53
54
 
54
55
  **Code: Packing an application run**
55
56
  ```typescript
@@ -60,6 +61,7 @@ Would then produce an executable script, in the output folder, that would look l
60
61
 
61
62
  **Code: Entry script for Packed application**
62
63
  ```typescript
64
+
63
65
  #!/bin/sh
64
66
  cd $(dirname "$0")
65
67
  node cli run myapp
@@ -69,8 +71,6 @@ And this entry point would be what is executed by [docker](https://www.docker.co
69
71
 
70
72
  ### General Packing Operations
71
73
  Every [Pack](https://github.com/travetto/travetto/tree/main/module/pack#readme "Code packing utilities") operation extends from the base command, and that provides some consistent operations that run on every packing command.
72
-
73
-
74
74
  * `clean` - Empties workspace before beginning, controlled by the `--clean` flag, defaults to on
75
75
  * `writeEnv` - Writes the .env.js files that includes the necessary details to start the application. This is primarily to identify the location of the manifest file needed to run.
76
76
  * `writePackageJson` - Generates the [Package JSON](https://docs.npmjs.com/cli/v9/configuring-npm/package-json) with the appropriate module type ([CommonJS](https://nodejs.org/api/modules.html) or [Ecmascript Module](https://nodejs.org/api/esm.html)) for interpreting plain `.js` files
@@ -81,151 +81,145 @@ Every [Pack](https://github.com/travetto/travetto/tree/main/module/pack#readme "
81
81
  * `bundle` - Invokes [Rollup](https://rollupjs.org/) with the appropriate file set to produce a single output .js file. Depending on the module type ([CommonJS](https://nodejs.org/api/modules.html) or [Ecmascript Module](https://nodejs.org/api/esm.html)) the build process differs to handle the dynamic loading that application does at runtime.
82
82
 
83
83
  ## CLI - pack:zip
84
-
85
- This command is nearly identical to the standard `pack` operation, except for the `output` flag. In this scenario, the `output` flag determines the location and name of the final zip file.
84
+ This command is nearly identical to the standard `pack` operation, except for the `output` flag. In this scenario, the `output` flag determines the location and name of the final zip file.
86
85
 
87
86
  **Terminal: Pack:zip usage**
88
87
  ```bash
89
88
  $ trv pack:zip --help
90
89
 
91
- Usage: pack:zip [options] [args...]
90
+ Usage: pack:zip [options]
92
91
 
93
92
  Options:
94
- -w, --workspace <workspace> Workspace for building
95
- -c, --no-clean Disables: Clean workspace
96
- -o, --output <output> Output location (default: "travetto_pack.zip")
97
- -es, --main-scripts <main-scripts> Create entry scripts
98
- -f, --main-name <main-name> Main name for build artifact
99
- -e, --entry-point <entry-point> Entry point (default: "@travetto/cli/support/entry.cli")
100
- -m, --no-minify Disables: Minify output
101
- -sm, --sourcemap Bundle source maps
102
- -is, --include-sources Include source with source maps
103
- -x, --eject-file <eject-file> Eject commands to file
104
- -h, --help display help for command
93
+ -w, --workspace <string> Workspace for building (default: "/tmp/<temp-folder>")
94
+ --clean, --no-clean Clean workspace (default: true)
95
+ -o, --output <string> Output location (default: "travetto_pack.zip")
96
+ --main-scripts, --no-main-scripts Create entry scripts (default: true)
97
+ -f, --main-name <string> Main name for build artifact
98
+ -e, --entry-point <string> Entry point (default: "@travetto/cli/support/entry.cli")
99
+ --minify, --no-minify Minify output (default: true)
100
+ -sm, --sourcemap Bundle source maps (default: false)
101
+ -is, --include-sources Include source with source maps (default: false)
102
+ -x, --eject-file <string> Eject commands to file
103
+ -m, --module <string> Module to run for
104
+ -h, --help display help for command
105
105
  ```
106
106
 
107
107
  ## CLI - pack:docker
108
-
109
108
  This command starts off identical to the standard `pack` operation, but it contains a few additional flags, and ultimately a few additional operations to support creating of the final [docker](https://www.docker.com/community-edition) image.
110
109
 
111
110
  **Terminal: Pack:docker usage**
112
111
  ```bash
113
112
  $ trv pack:docker --help
114
113
 
115
- Usage: pack:docker [options] [args...]
114
+ Usage: pack:docker [options]
116
115
 
117
116
  Options:
118
- -w, --workspace <workspace> Workspace for building
119
- -c, --no-clean Disables: Clean workspace
120
- -o, --output <output> Output location
121
- -es, --main-scripts <main-scripts> Create entry scripts
122
- -f, --main-name <main-name> Main name for build artifact
123
- -e, --entry-point <entry-point> Entry point (default: "@travetto/cli/support/entry.cli")
124
- -m, --no-minify Disables: Minify output
125
- -sm, --sourcemap Bundle source maps
126
- -is, --include-sources Include source with source maps
127
- -x, --eject-file <eject-file> Eject commands to file
128
- -df, --docker-factory <docker-factory> Docker Factory source (default: "@travetto/pack/support/pack.dockerfile")
129
- -di, --docker-image <docker-image> Docker Image to extend (default: "node:18-alpine3.16")
130
- -dn, --docker-name <docker-name> Docker Image Name (default: "travetto_pack")
131
- -dt, --docker-tag <docker-tag> Docker Image Tag (default: ["latest"])
132
- -dp, --docker-port <docker-port> Docker Image Port (default: [])
133
- -dx, --docker-push Docker Push Tags
134
- -dr, --docker-registry <docker-registry> Docker Registry
135
- -h, --help display help for command
117
+ -w, --workspace <string> Workspace for building (default: "/tmp/<temp-folder>")
118
+ --clean, --no-clean Clean workspace (default: true)
119
+ -o, --output <string> Output location
120
+ --main-scripts, --no-main-scripts Create entry scripts (default: true)
121
+ -f, --main-name <string> Main name for build artifact
122
+ -e, --entry-point <string> Entry point (default: "@travetto/cli/support/entry.cli")
123
+ --minify, --no-minify Minify output (default: true)
124
+ -sm, --sourcemap Bundle source maps (default: false)
125
+ -is, --include-sources Include source with source maps (default: false)
126
+ -x, --eject-file <string> Eject commands to file
127
+ -df, --docker-factory <string> Docker Factory source (default: "@travetto/pack/support/pack.dockerfile")
128
+ -di, --docker-image <string> Docker Image to extend (default: "node:18-alpine3.16")
129
+ -dn, --docker-name <string> Docker Image Name (default: "travetto_pack")
130
+ -dt, --docker-tag <string> Docker Image Tag (default: ["latest"])
131
+ -dp, --docker-port <number> Docker Image Port (default: [])
132
+ -dx, --docker-push Docker Push Tags (default: false)
133
+ -dr, --docker-registry <string> Docker Registry
134
+ -m, --module <string> Module to run for
135
+ -h, --help display help for command
136
136
  ```
137
137
 
138
- The additional flags provided are allow for specifying the base image, the final docker image name (and tags), and which registry to push to (if any). Additionally, there are flags for exposing which ports the image should expect to open as well. When using the `--eject-file` flag, the output script will produce the entire Dockerfile output inline, so that it can be easily modified as needed.
138
+ The additional flags provided are allow for specifying the base image, the final docker image name (and tags), and which registry to push to (if any). Additionally, there are flags for exposing which ports the image should expect to open as well. When using the `--eject-file` flag, the output script will produce the entire Dockerfile output inline, so that it can be easily modified as needed.
139
139
 
140
140
  In addition to the standard operations, this command adds the following steps:
141
-
142
141
  * `writeDockerFile` - Generate the docker file contents
143
142
  * `pullDockerBaseImage` - Pull base image, to ensure its available and primed
144
143
  * `buildDockerContainer` - Build final container
145
144
  * `pushDockerContainer` - Push container with appropriate tags. Only applies if `--docker-push` is specified
146
145
 
147
146
  ## Ejected File
148
-
149
147
  As indicated, any of the pack operations can be ejected, and produce an output that can be run independent of the pack command. This is helpful when integrating with more complicated build processes.
150
148
 
151
149
  **Terminal: Sample Ejected File**
152
150
  ```bash
153
- $ trv pack:docker -x /dev/stdout run rest
151
+ $ trv pack:docker -x /dev/stdout run:rest
154
152
 
155
153
  #!/bin/sh
156
- export DIST=/tmp/_home_tim_Code_travetto_related_todo-app
154
+ export DIST=/tmp/<temp-folder>
157
155
  export TRV_OUT=<workspace-root>/.trv_output
158
156
  export ROOT=<workspace-root>/related/todo-app
159
157
  export MOD=@travetto/todo-app
160
158
 
161
159
  # Cleaning Output $DIST
162
160
 
163
- echo "Cleaning Output $DIST
164
- "
161
+ echo "Cleaning Output $DIST"
162
+
165
163
  rm -rf $DIST
166
164
  mkdir -p $DIST
167
165
 
168
166
  # Writing .env.js
169
167
 
170
- echo "Writing .env.js
171
- "
168
+ echo "Writing .env.js"
169
+
172
170
  echo "process.env.TRV_MANIFEST = 'node_modules/$MOD';" > $DIST/.env.js
171
+ echo "process.env.TRV_MODULE = '$MOD';" >> $DIST/.env.js
173
172
  echo "process.env.TRV_CLI_IPC = '';" >> $DIST/.env.js
174
173
 
175
174
  # Writing package.json
176
175
 
177
- echo "Writing package.json
178
- "
176
+ echo "Writing package.json"
177
+
179
178
  echo "{\"type\":\"commonjs\"}" > $DIST/package.json
180
179
 
181
- # Writing entry scripts entry.cli.sh args=(run rest)
180
+ # Writing entry scripts todo-app.sh args=(run:rest)
181
+
182
+ echo "Writing entry scripts todo-app.sh args=(run:rest)"
182
183
 
183
- echo "Writing entry scripts entry.cli.sh args=(run rest)
184
- "
185
- echo "#!/bin/sh" > $DIST/entry.cli.sh
186
- echo "cd \$(dirname \"\$0\")" >> $DIST/entry.cli.sh
187
- echo "node entry.cli.js run rest \$@" >> $DIST/entry.cli.sh
188
- chmod 755 $DIST/entry.cli.sh
184
+ echo "#!/bin/sh" > $DIST/todo-app.sh
185
+ echo "cd \$(dirname \"\$0\")" >> $DIST/todo-app.sh
186
+ echo "node todo-app.js run:rest \$@" >> $DIST/todo-app.sh
187
+ chmod 755 $DIST/todo-app.sh
189
188
 
190
- # Writing entry scripts entry.cli.cmd args=(run rest)
189
+ # Writing entry scripts todo-app.cmd args=(run:rest)
191
190
 
192
- echo "Writing entry scripts entry.cli.cmd args=(run rest)
193
- "
194
- echo "" > $DIST/entry.cli.cmd
195
- echo "cd %~p0" >> $DIST/entry.cli.cmd
196
- echo "node entry.cli.js run rest %*" >> $DIST/entry.cli.cmd
197
- chmod 755 $DIST/entry.cli.cmd
191
+ echo "Writing entry scripts todo-app.cmd args=(run:rest)"
192
+
193
+ echo "" > $DIST/todo-app.cmd
194
+ echo "cd %~p0" >> $DIST/todo-app.cmd
195
+ echo "node todo-app.js run:rest %*" >> $DIST/todo-app.cmd
196
+ chmod 755 $DIST/todo-app.cmd
198
197
 
199
198
  # Copying over resources
200
199
 
201
- echo "Copying over resources
202
- "
200
+ echo "Copying over resources"
201
+
203
202
  mkdir -p $DIST/node_modules/$MOD
204
203
  cp $TRV_OUT/node_modules/$MOD/package.json $DIST/node_modules/$MOD/package.json
205
204
  mkdir -p $DIST/node_modules/@travetto/manifest
206
205
  cp $TRV_OUT/node_modules/@travetto/manifest/package.json $DIST/node_modules/@travetto/manifest/package.json
207
206
  cp -r -p $ROOT/resources $DIST/resources
208
207
 
209
- # Generating App Cache node_modules/$MOD/trv-app-cache.json
210
-
211
- echo "Generating App Cache node_modules/$MOD/trv-app-cache.json
212
- "
213
- mkdir -p $DIST/node_modules/$MOD
214
- DEBUG=0 TRV_MODULE=$MOD npx trv main @travetto/app/support/bin/list > $DIST/node_modules/$MOD/trv-app-cache.json
215
-
216
208
  # Writing Manifest node_modules/$MOD
217
209
 
218
- echo "Writing Manifest node_modules/$MOD
219
- "
210
+ echo "Writing Manifest node_modules/$MOD"
211
+
220
212
  TRV_MODULE=$MOD npx trv manifest $DIST/node_modules/$MOD prod
221
213
 
222
- # Bundling Output minify=true sourcemap= entryPoint=@travetto/cli/support/entry.cli
214
+ # Bundling Output minify=true sourcemap=false entryPoint=@travetto/cli/support/entry.cli
215
+
216
+ echo "Bundling Output minify=true sourcemap=false entryPoint=@travetto/cli/support/entry.cli"
223
217
 
224
- echo "Bundling Output minify=true sourcemap= entryPoint=@travetto/cli/support/entry.cli
225
- "
226
218
  export BUNDLE_ENTRY=node_modules/@travetto/cli/support/entry.cli.js
227
- export BUNDLE_MAIN_FILE=entry.cli.js
219
+ export BUNDLE_MAIN_FILE=todo-app.js
228
220
  export BUNDLE_COMPRESS=true
221
+ export BUNDLE_SOURCEMAP=false
222
+ export BUNDLE_SOURCES=false
229
223
  export BUNDLE_OUTPUT=$DIST
230
224
  export BUNDLE_FORMAT=commonjs
231
225
  export TRV_MANIFEST=$TRV_OUT/node_modules/$MOD
@@ -235,24 +229,24 @@ cd $ROOT
235
229
 
236
230
  # Generating Docker File $DIST/Dockerfile @travetto/pack/support/pack.dockerfile
237
231
 
238
- echo "Generating Docker File $DIST/Dockerfile @travetto/pack/support/pack.dockerfile
239
- "
232
+ echo "Generating Docker File $DIST/Dockerfile @travetto/pack/support/pack.dockerfile"
233
+
240
234
  echo "FROM node:18-alpine3.16" > $DIST/Dockerfile
241
235
  echo "WORKDIR /app" >> $DIST/Dockerfile
242
236
  echo "COPY . ." >> $DIST/Dockerfile
243
237
  echo "" >> $DIST/Dockerfile
244
- echo "ENTRYPOINT [\"/app/entry.cli.sh\"]" >> $DIST/Dockerfile
238
+ echo "ENTRYPOINT [\"/app/todo-app.sh\"]" >> $DIST/Dockerfile
245
239
 
246
240
  # Pulling Docker Base Image node:18-alpine3.16
247
241
 
248
- echo "Pulling Docker Base Image node:18-alpine3.16
249
- "
242
+ echo "Pulling Docker Base Image node:18-alpine3.16"
243
+
250
244
  docker pull node:18-alpine3.16
251
245
 
252
246
  # Building Docker Container latest
253
247
 
254
- echo "Building Docker Container latest
255
- "
248
+ echo "Building Docker Container latest"
249
+
256
250
  cd $DIST
257
251
  docker build -t travetto_todo-app:latest .
258
252
  cd $ROOT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/pack",
3
- "version": "3.0.2",
3
+ "version": "3.1.0-rc.0",
4
4
  "description": "Code packing utilities",
5
5
  "keywords": [
6
6
  "travetto",
@@ -28,12 +28,12 @@
28
28
  "@rollup/plugin-json": "^6.0.0",
29
29
  "@rollup/plugin-node-resolve": "^15.0.1",
30
30
  "@rollup/plugin-terser": "^0.4.0",
31
- "@travetto/base": "^3.0.2",
31
+ "@travetto/base": "^3.1.0-rc.0",
32
32
  "rollup": "^3.17.2",
33
33
  "rollup-plugin-sourcemaps": "^0.6.3"
34
34
  },
35
35
  "peerDependencies": {
36
- "@travetto/cli": "^3.0.2"
36
+ "@travetto/cli": "^3.1.0-rc.0"
37
37
  },
38
38
  "peerDependenciesMeta": {
39
39
  "@travetto/cli": {
@@ -2,7 +2,7 @@ import type { OutputOptions } from 'rollup';
2
2
  import type terser from '@rollup/plugin-terser';
3
3
 
4
4
  import { Env } from '@travetto/base';
5
- import { ManifestModule, Package, path, RootIndex } from '@travetto/manifest';
5
+ import { ManifestModule, ManifestModuleUtil, Package, path, RootIndex } from '@travetto/manifest';
6
6
 
7
7
  const INTRO = {
8
8
  commonjs: `
@@ -32,7 +32,7 @@ function getFilesFromModule(m: ManifestModule): string[] {
32
32
  .filter(f => !/support\/(test|doc)/.test(f[0]))
33
33
  ]
34
34
  .filter(([, t]) => t === 'ts' || t === 'js' || t === 'json')
35
- .map(([f]) => path.resolve(m.outputFolder, f.replace(/[.]ts$/, '.js')));
35
+ .map(([f]) => ManifestModuleUtil.sourceToOutputExt(path.resolve(m.outputFolder, f)));
36
36
  }
37
37
 
38
38
  export function getOutput(): OutputOptions {
@@ -12,6 +12,9 @@ async function writeRawFile(file: string, contents: string, mode?: string): Prom
12
12
  await fs.writeFile(file, contents, { encoding: 'utf8', mode });
13
13
  }
14
14
 
15
+ /**
16
+ * General pack operations
17
+ */
15
18
  export class PackOperation {
16
19
 
17
20
  static async * title(cfg: CommonPackConfig, title: string): AsyncIterable<string[]> {
@@ -118,6 +121,7 @@ export class PackOperation {
118
121
  const file = '.env.js';
119
122
  const env = {
120
123
  TRV_MANIFEST: `node_modules/${cfg.module}`,
124
+ TRV_MODULE: cfg.module,
121
125
  TRV_CLI_IPC: ''
122
126
  };
123
127
 
@@ -212,33 +216,6 @@ export class PackOperation {
212
216
  }
213
217
  }
214
218
 
215
- /**
216
- * Generate the trv-app-cache.json for @travetto/app, which is needed for 'running' programs
217
- */
218
- static async * primeAppCache(cfg: CommonPackConfig): AsyncIterable<string[]> {
219
- const isRun = /entry[.]cli/.test(cfg.entryPoint) && cfg.entryArguments.filter(x => !x.startsWith('-'))[0] === 'run';
220
- if (!isRun) {
221
- return;
222
- }
223
-
224
- const appCacheCmd = ['npx', 'trv', 'main', '@travetto/app/support/bin/list'];
225
- const sub = path.join(RootIndex.manifest.modules[RootIndex.mainModule.name].outputFolder, 'trv-app-cache.json');
226
- const env = { DEBUG: '0', TRV_MODULE: cfg.module };
227
- const appCache = path.resolve(cfg.workspace, sub);
228
-
229
- yield* PackOperation.title(cfg, cliTpl`${{ title: 'Generating App Cache' }} ${{ path: sub }}`);
230
-
231
- if (cfg.ejectFile) {
232
- yield ActiveShellCommand.mkdir(path.dirname(appCache));
233
- yield [...Object.entries(env).map(x => `${x[0]}=${x[1]}`), ...appCacheCmd, '>', appCache];
234
- } else {
235
- const { stdout } = await ExecUtil.spawn(appCacheCmd[0], appCacheCmd.slice(1), { env }).result;
236
-
237
- await fs.mkdir(path.dirname(appCache), { recursive: true });
238
- await fs.writeFile(appCache, stdout, 'utf8');
239
- }
240
- }
241
-
242
219
  /**
243
220
  * Produce the output manifest, only including prod dependencies
244
221
  */
@@ -27,7 +27,7 @@ export const ShellCommands: Record<'win32' | 'posix', ShellCommandImpl> = {
27
27
  export: (key, value) => ['set', `${key}=${value}`],
28
28
  chdir: (dest) => ['cd', dest],
29
29
  comment: (message) => ['\nREM', stripAnsiCodes(message), '\n'],
30
- echo: (message) => ['echo', `"${escape(stripAnsiCodes(message))}\n"`],
30
+ echo: (message) => ['echo', `"${escape(stripAnsiCodes(message))}"\n`],
31
31
  zip: (outputFile) => ['powershell', 'Compress-Archive', '-Path', '.', '-DestinationPath', outputFile]
32
32
  },
33
33
  posix: {
@@ -47,7 +47,7 @@ export const ShellCommands: Record<'win32' | 'posix', ShellCommandImpl> = {
47
47
  export: (key, value) => ['export', `${key}=${value}`],
48
48
  chdir: (dest) => ['cd', dest],
49
49
  comment: (message) => ['\n#', stripAnsiCodes(message), '\n'],
50
- echo: (message) => ['echo', `"${escape(stripAnsiCodes(message))}\n"`],
50
+ echo: (message) => ['echo', `"${escape(stripAnsiCodes(message))}"\n`],
51
51
  zip: (outputFile) => ['zip', '-r', outputFile, '.']
52
52
  },
53
53
  };
@@ -1,12 +1,10 @@
1
- import { ListOptionConfig, OptionConfig } from '@travetto/cli';
2
-
3
1
  export type CommonPackConfig = {
4
2
  workspace: string;
5
3
  output: string;
6
4
  clean: boolean;
7
- ejectFile: string;
5
+ ejectFile?: string;
8
6
  mainName: string;
9
- mainScripts: boolean;
7
+ mainScripts?: boolean;
10
8
  module: string;
11
9
 
12
10
  // Bundle
@@ -17,40 +15,17 @@ export type CommonPackConfig = {
17
15
  includeSources: boolean;
18
16
  };
19
17
 
20
- export type CommonPackOptions = {
21
- workspace: OptionConfig<string>;
22
- output: OptionConfig<string>;
23
- clean: OptionConfig<boolean>;
24
- ejectFile: OptionConfig<string>;
25
- mainName: OptionConfig<string>;
26
- mainScripts: OptionConfig<boolean>;
27
-
28
- // Bundle
29
- entryPoint: OptionConfig<string>;
30
- minify: OptionConfig<boolean>;
31
- sourcemap: OptionConfig<boolean>;
32
- includeSources: OptionConfig<boolean>;
33
- };
34
18
 
35
19
  export type DockerPackConfig = {
36
20
  dockerFactory: string;
37
21
  dockerImage: string;
38
22
  dockerName: string;
39
- dockerTag: string[];
40
- dockerPort: string[];
41
- dockerPush: boolean;
42
- dockerRegistry: string;
23
+ dockerTag?: string[];
24
+ dockerPort?: number[];
25
+ dockerPush?: boolean;
26
+ dockerRegistry?: string;
43
27
  } & CommonPackConfig;
44
28
 
45
- export type DockerPackOptions = {
46
- dockerFactory: OptionConfig<string>;
47
- dockerImage: OptionConfig<string>;
48
- dockerName: OptionConfig<string>;
49
- dockerTag: ListOptionConfig<string>;
50
- dockerPort: ListOptionConfig<string>;
51
- dockerPush: OptionConfig<boolean>;
52
- dockerRegistry: OptionConfig<string>;
53
- } & CommonPackOptions;
54
29
 
55
30
  export type ShellCommandImpl = {
56
31
  var(name: string): string;
@@ -33,31 +33,33 @@ export class PackUtil {
33
33
  /**
34
34
  * Finalize eject output
35
35
  */
36
- static async writeEjectOutput(
37
- workspace: string,
38
- module: string,
39
- output: string[],
40
- file: string
41
- ): Promise<void> {
42
- const vars = {
43
- DIST: workspace,
44
- TRV_OUT: RootIndex.outputRoot,
45
- ROOT: path.cwd(),
46
- MOD: module
47
- };
48
-
49
- const content = [
36
+ static async writeEjectOutput(workspace: string, module: string, output: AsyncIterable<string>, file: string): Promise<void> {
37
+ const vars = { DIST: workspace, TRV_OUT: RootIndex.outputRoot, ROOT: path.cwd(), MOD: module };
38
+
39
+ const replaceArgs = (text: string): string => Object.entries(vars)
40
+ .reduce((str, [k, v]) => str.replaceAll(v, ActiveShellCommand.var(k)), text);
41
+
42
+ const preamble = [
50
43
  ActiveShellCommand.scriptOpen(),
51
44
  ...Object.entries(vars).map(([k, v]) => ActiveShellCommand.export(k, v).join(' ')),
52
- Object.entries(vars).reduce((text, [k, v]) => text.replaceAll(v, ActiveShellCommand.var(k)), output.join('\n')),
53
- '', ''
54
45
  ].join('\n');
55
46
 
56
- if (file === '-' || file === '/dev/stdout') {
57
- console.log!(content);
58
- } else {
47
+ let stream: fs.FileHandle | undefined;
48
+
49
+ if (!(file === '-' || file === '/dev/stdout')) {
59
50
  await fs.mkdir(path.dirname(file), { recursive: true });
60
- await fs.writeFile(file, content, 'utf8');
51
+ await fs.truncate(file);
52
+ stream = await fs.open(file, 'utf8');
61
53
  }
54
+
55
+ const write = (text: string): Promise<unknown> | unknown => stream ? stream.write(`${text}\n`) : process.stdout.write(`${text}\n`);
56
+
57
+ await write(preamble);
58
+ for await (const line of output) {
59
+ await write(replaceArgs(line));
60
+ }
61
+ await write('\n');
62
+
63
+ await stream?.close();
62
64
  }
63
65
  }
@@ -1,14 +1,9 @@
1
+ import { CliCommand } from '@travetto/cli';
2
+
1
3
  import { BasePackCommand } from './pack.base';
2
- import { CommonPackConfig, CommonPackOptions } from './bin/types';
3
4
 
4
5
  /**
5
6
  * Standard pack support
6
7
  */
7
- export class PackCommand extends BasePackCommand<CommonPackOptions, CommonPackConfig> {
8
-
9
- name = 'pack';
10
-
11
- getOptions(): CommonPackOptions {
12
- return this.getCommonOptions();
13
- }
14
- }
8
+ @CliCommand({ fields: ['module'] })
9
+ export class PackCommand extends BasePackCommand { }
@@ -1,42 +1,38 @@
1
1
  import { path, RootIndex } from '@travetto/manifest';
2
+ import { CliCommand, CliFlag, CliUtil } from '@travetto/cli';
2
3
 
3
- import { DockerPackConfig, DockerPackOptions } from './bin/types';
4
4
  import { DockerPackOperation } from './bin/docker-operation';
5
5
  import { BasePackCommand, PackOperationShape } from './pack.base';
6
6
 
7
-
8
7
  /**
9
8
  * Standard docker support for pack
10
9
  */
11
- export class PackDockerCommand extends BasePackCommand<DockerPackOptions, DockerPackConfig> {
12
-
13
- name = 'pack:docker';
14
-
15
- getOptions(): DockerPackOptions {
16
- const opts = this.getCommonOptions();
17
- return {
18
- ...opts,
19
- dockerFactory: this.option({ short: 'df', desc: 'Docker Factory source', def: '@travetto/pack/support/pack.dockerfile' }),
20
- dockerImage: this.option({ short: 'di', desc: 'Docker Image to extend', def: 'node:18-alpine3.16' }),
21
- dockerName: this.option({ short: 'dn', desc: 'Docker Image Name', def: this.monoRoot ? '<module>' : this.getSimpleModuleName() }),
22
- dockerTag: this.listOption({ short: 'dt', desc: 'Docker Image Tag', def: ['latest'] }),
23
- dockerPort: this.listOption({ short: 'dp', desc: 'Docker Image Port' }),
24
- dockerPush: this.boolOption({ short: 'dx', desc: 'Docker Push Tags' }),
25
- dockerRegistry: this.option({ short: 'dr', desc: 'Docker Registry' })
26
- };
27
- }
10
+ @CliCommand({ fields: ['module'] })
11
+ export class PackDockerCommand extends BasePackCommand {
12
+ @CliFlag({ desc: 'Docker Factory source ', short: 'df', envVars: ['PACK_DOCKER_FACTORY'] })
13
+ dockerFactory = '@travetto/pack/support/pack.dockerfile';
14
+ @CliFlag({ desc: 'Docker Image to extend ', short: 'di', envVars: ['PACK_DOCKER_IMAGE'] })
15
+ dockerImage = 'node:18-alpine3.16';
16
+ @CliFlag({ desc: 'Docker Image Name ', short: 'dn', envVars: ['PACK_DOCKER_IMAGE'] })
17
+ dockerName = CliUtil.monoRoot ? '<module>' : CliUtil.getSimpleModuleName();
18
+ @CliFlag({ desc: 'Docker Image Tag ', short: 'dt', envVars: ['PACK_DOCKER_TAGS'] })
19
+ dockerTag: string[] = ['latest'];
20
+ @CliFlag({ desc: 'Docker Image Port ', short: 'dp', envVars: ['PACK_DOCKER_PORT'] })
21
+ dockerPort: number[] = [];
22
+ @CliFlag({ desc: 'Docker Push Tags ', short: 'dx', envVars: ['PACK_DOCKER_PUSH'] })
23
+ dockerPush = false;
24
+ @CliFlag({ desc: 'Docker Registry ', short: 'dr', envVars: ['PACK_DOCKER_REGISTRY'] })
25
+ dockerRegistry?: string;
28
26
 
29
- async buildConfig(): Promise<DockerPackConfig> {
30
- const cfg = await super.buildConfig();
31
- if (cfg.dockerFactory.startsWith('.')) {
32
- cfg.dockerFactory = RootIndex.getFromSource(path.resolve(cfg.dockerFactory))?.import ?? cfg.dockerFactory;
27
+ finalize(unknownArgs: string[]): void {
28
+ super.finalize(unknownArgs);
29
+ if (this.dockerFactory.startsWith('.')) {
30
+ this.dockerFactory = RootIndex.getFromSource(path.resolve(this.dockerFactory))?.import ?? this.dockerFactory;
33
31
  }
34
- cfg.dockerPort ??= [];
35
- cfg.dockerTag ??= [];
36
- return cfg;
32
+ this.dockerName = this.dockerName.replace('<module>', CliUtil.getSimpleModuleName(this.module ?? ''));
37
33
  }
38
34
 
39
- getOperations(): PackOperationShape<DockerPackConfig>[] {
35
+ getOperations(): PackOperationShape<this>[] {
40
36
  return [
41
37
  ...super.getOperations(),
42
38
  DockerPackOperation.writeDockerFile,
@@ -1,21 +1,19 @@
1
- import { CommonPackConfig, CommonPackOptions } from './bin/types';
1
+ import { CliCommand, CliUtil } from '@travetto/cli';
2
+
2
3
  import { PackOperation } from './bin/operation';
3
4
  import { BasePackCommand, PackOperationShape } from './pack.base';
4
5
 
5
6
  /**
6
7
  * Standard zip support for pack
7
8
  */
8
- export class PackZipCommand extends BasePackCommand<CommonPackOptions, CommonPackConfig> {
9
-
10
- name = 'pack:zip';
9
+ @CliCommand({ fields: ['module'] })
10
+ export class PackZipCommand extends BasePackCommand {
11
11
 
12
- getOptions(): CommonPackOptions {
13
- const opts = this.getCommonOptions();
14
- opts.output.def = this.monoRoot ? '<module>.zip' : `${this.getSimpleModuleName()}.zip`;
15
- return opts;
12
+ initialize(): void {
13
+ this.output = CliUtil.monoRoot ? '<module>.zip' : `${CliUtil.getSimpleModuleName()}.zip`;
16
14
  }
17
15
 
18
- getOperations(): PackOperationShape<CommonPackConfig>[] {
16
+ getOperations(): PackOperationShape<this>[] {
19
17
  return [
20
18
  ...super.getOperations(),
21
19
  PackOperation.compress
@@ -1,149 +1,117 @@
1
1
  import os from 'os';
2
2
 
3
- import { CliCommand, cliTpl } from '@travetto/cli';
3
+ import { CliCommandShape, CliFlag, cliTpl, CliUtil } from '@travetto/cli';
4
4
  import { path, RootIndex } from '@travetto/manifest';
5
5
  import { TimeUtil } from '@travetto/base';
6
6
  import { GlobalTerminal } from '@travetto/terminal';
7
+ import { Ignore, Required, Schema } from '@travetto/schema';
7
8
 
8
- import { CommonPackConfig, CommonPackOptions } from './bin/types';
9
9
  import { PackOperation } from './bin/operation';
10
10
  import { PackUtil } from './bin/util';
11
11
 
12
- export type PackOperationShape<T extends CommonPackConfig> = ((config: T) => AsyncIterable<string[]>);
12
+ export type PackOperationShape<T> = ((config: T) => AsyncIterable<string[]>);
13
13
 
14
- const BASIC_OP_SET = [
15
- PackOperation.clean,
16
- PackOperation.writeEnv,
17
- PackOperation.writePackageJson,
18
- PackOperation.writeEntryScript,
19
- PackOperation.copyResources,
20
- PackOperation.primeAppCache,
21
- PackOperation.writeManifest,
22
- PackOperation.bundle,
23
- ];
14
+ @Schema()
15
+ export abstract class BasePackCommand implements CliCommandShape {
24
16
 
25
- export abstract class BasePackCommand<T extends CommonPackOptions, S extends CommonPackConfig> extends CliCommand<{}> {
26
-
27
- get monoRoot(): boolean {
28
- return !!RootIndex.manifest.monoRepo && path.cwd() === RootIndex.manifest.workspacePath;
29
- }
30
-
31
- get entryPoints(): string[] {
17
+ static get entryPoints(): string[] {
32
18
  return RootIndex.findSupport({ filter: x => x.includes('entry.') })
33
19
  .map(x => x.import.replace(/[.][^.]+s$/, ''));
34
20
  }
35
21
 
36
- getArgs(): string | undefined {
37
- return this.monoRoot ? '<module> [args...]' : '[args...]';
38
- }
22
+ #unknownArgs?: string[];
39
23
 
40
- getCommonOptions(): CommonPackOptions {
41
- const mainEntry = this.entryPoints.find(x => x.startsWith('@travetto/cli'))!;
42
- return {
43
- workspace: this.option({ short: 'w', desc: 'Workspace for building' }),
44
- clean: this.boolOption({ short: 'c', desc: 'Clean workspace', def: true }),
45
- output: this.option({ short: 'o', desc: 'Output location' }),
46
- mainScripts: this.option({ short: 'es', desc: 'Create entry scripts' }),
47
- mainName: this.option({ short: 'f', desc: 'Main name for build artifact' }),
48
- entryPoint: this.option({ short: 'e', desc: 'Entry point', def: mainEntry }),
49
- minify: this.boolOption({ short: 'm', desc: 'Minify output', def: true }),
50
- sourcemap: this.boolOption({ short: 'sm', desc: 'Bundle source maps' }),
51
- includeSources: this.boolOption({ short: 'is', desc: 'Include source with source maps' }),
52
- ejectFile: this.option({ short: 'x', desc: 'Eject commands to file' }),
53
- };
54
- }
24
+ @CliFlag({ desc: 'Workspace for building', short: 'w' })
25
+ workspace: string = path.resolve(os.tmpdir(), RootIndex.mainModule.sourcePath.replace(/[\/\\: ]/g, '_'));
55
26
 
56
- abstract getOptions(): T;
27
+ @CliFlag({ desc: 'Clean workspace' })
28
+ clean = true;
57
29
 
58
- get cmd(): S {
59
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
60
- return super.cmd as S;
61
- }
30
+ @CliFlag({ desc: 'Output location', short: 'o' })
31
+ @Required(false)
32
+ output: string;
62
33
 
63
- getSimpleModuleName(): string {
64
- return RootIndex.mainPackage.name.replace(/[\/]/, '_').replace(/@/, '');
65
- }
34
+ @CliFlag({ desc: 'Create entry scripts', short: 'es' })
35
+ mainScripts: boolean = true;
36
+
37
+ @CliFlag({ desc: 'Main name for build artifact', short: 'f' })
38
+ @Required(false)
39
+ mainName: string;
40
+
41
+ @CliFlag({ desc: 'Entry point', short: 'e' })
42
+ @Required(false)
43
+ entryPoint: string = '@travetto/cli/support/entry.cli';
66
44
 
67
- getOperations(): PackOperationShape<S>[] {
68
- return BASIC_OP_SET.slice(0);
45
+ @CliFlag({ desc: 'Minify output' })
46
+ minify = true;
47
+
48
+ @CliFlag({ desc: 'Bundle source maps', short: 'sm' })
49
+ sourcemap = false;
50
+
51
+ @CliFlag({ desc: 'Include source with source maps', short: 'is' })
52
+ includeSources = false;
53
+
54
+ @CliFlag({ desc: 'Eject commands to file', short: 'x' })
55
+ ejectFile?: string;
56
+
57
+ @Ignore()
58
+ module: string;
59
+
60
+ /** Entry arguments */
61
+ @Ignore()
62
+ entryArguments: string[] = [];
63
+
64
+ getOperations(): PackOperationShape<this>[] {
65
+ return [
66
+ PackOperation.clean,
67
+ PackOperation.writeEnv,
68
+ PackOperation.writePackageJson,
69
+ PackOperation.writeEntryScript,
70
+ PackOperation.copyResources,
71
+ PackOperation.writeManifest,
72
+ PackOperation.bundle,
73
+ ];
69
74
  }
70
75
 
71
76
  /**
72
77
  * Run all operations
73
78
  */
74
- async * runOperations(cfg: S): AsyncIterable<string> {
79
+ async * runOperations(): AsyncIterable<string> {
75
80
  for (const op of this.getOperations()) {
76
- for await (const msg of op(cfg)) {
81
+ for await (const msg of op(this)) {
77
82
  yield msg.join(' ');
78
83
  }
79
84
  }
80
85
  }
81
86
 
87
+ finalize(unknown: string[]): void {
88
+ this.#unknownArgs = unknown;
82
89
 
83
- getModule(moduleName: string): string {
84
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
85
- let module = this.monoRoot ? moduleName : RootIndex.mainModule.name;
86
- module = RootIndex.getModuleByFolder(module)?.name ?? module;
87
-
88
- // Reinitialize for module
89
- if (this.monoRoot) {
90
- RootIndex.reinitForModule(module);
91
- }
92
-
93
- return module;
94
- }
95
-
96
- async buildConfig(): Promise<S> {
97
- this.cmd.workspace ??= path.resolve(os.tmpdir(), RootIndex.mainModule.sourcePath.replace(/[\/\\: ]/g, '_'));
98
- this.cmd.module = RootIndex.mainModule.name;
99
- this.cmd.mainName ??= path.basename(this.cmd.entryPoint);
100
- return this.cmd;
101
- }
102
-
103
- async action(module: string, args: string[]): Promise<void> {
104
- if (Array.isArray(module)) {
105
- args = module;
106
- module = RootIndex.mainModule.name;
107
- }
108
- const start = Date.now();
109
- if (!module && this.monoRoot) {
110
- return this.showHelp(new Error('The module needs to specified when running from a monorepo root'));
111
- }
112
-
113
- module = this.getModule(module);
114
-
115
- const cfg = await this.buildConfig();
116
- cfg.entryArguments = Array.isArray(args) ? args : [];
117
-
118
- for (const k in this.cmd) {
119
- if (Object.hasOwn(this.cmd, k)) {
120
- const v = this.cmd[k];
121
- if (typeof v === 'string' && /<module>/.test(v)) {
122
- // @ts-expect-error
123
- this.cmd[k] = v.replace(/<module>/g, this.getSimpleModuleName());
124
- }
125
- }
126
- }
90
+ this.output = this.output?.replace('<module>', CliUtil.getSimpleModuleName(this.module ?? ''));
127
91
 
128
92
  // Resolve all files to absolute paths
129
- if (this.cmd.output) {
130
- this.cmd.output = path.resolve(this.cmd.output);
93
+ if (this.output) {
94
+ this.output = path.resolve(this.output);
131
95
  }
132
- if (this.cmd.ejectFile) {
133
- this.cmd.ejectFile = path.resolve(this.cmd.ejectFile);
96
+ if (this.ejectFile) {
97
+ this.ejectFile = path.resolve(this.ejectFile);
134
98
  }
135
- this.cmd.workspace = path.resolve(this.cmd.workspace);
99
+ this.workspace = path.resolve(this.workspace);
100
+ }
101
+
102
+ async main(args: string[] = []): Promise<void> {
103
+ this.entryArguments = [...args, ...this.#unknownArgs ?? []];
104
+ this.module ||= RootIndex.mainModule.name;
105
+ this.mainName ??= path.basename(this.module);
136
106
 
137
- const stream = this.runOperations(cfg);
107
+ const stream = this.runOperations();
138
108
 
139
109
  // Eject to file
140
- if (this.cmd.ejectFile) {
141
- const output: string[] = [];
142
- for await (const line of stream) {
143
- output.push(line);
144
- }
145
- await PackUtil.writeEjectOutput(this.cmd.workspace, cfg.module, output, this.cmd.ejectFile);
110
+ if (this.ejectFile) {
111
+ await PackUtil.writeEjectOutput(this.workspace, this.module, stream, this.ejectFile);
146
112
  } else {
113
+ const start = Date.now();
114
+
147
115
  await GlobalTerminal.streamLinesWithWaiting(stream, {
148
116
  initialDelay: 0,
149
117
  cycleDelay: 100,
@@ -151,9 +119,9 @@ export abstract class BasePackCommand<T extends CommonPackOptions, S extends Com
151
119
  position: 'inline',
152
120
  committedPrefix: String.fromCharCode(171)
153
121
  });
154
- let msg = cliTpl`${{ success: 'Success' }} (${{ identifier: TimeUtil.prettyDeltaSinceTime(start) }}) ${{ subtitle: 'module' }}=${{ param: this.cmd.module }}`;
155
- if (this.cmd.output) {
156
- msg = cliTpl`${msg} ${{ subtitle: 'output' }}=${{ path: this.cmd.output }}`;
122
+ let msg = cliTpl`${{ success: 'Success' }} (${{ identifier: TimeUtil.prettyDeltaSinceTime(start) }}) ${{ subtitle: 'module' }}=${{ param: this.module }}`;
123
+ if (this.output) {
124
+ msg = cliTpl`${msg} ${{ subtitle: 'output' }}=${{ path: this.output }}`;
157
125
  }
158
126
  await GlobalTerminal.writeLines(msg);
159
127
  }
@@ -4,6 +4,6 @@ export const factory: DockerPackFactory = cfg => `
4
4
  FROM ${cfg.dockerImage}
5
5
  WORKDIR /app
6
6
  COPY . .
7
- ${cfg.dockerPort.map(port => `EXPOSE ${port}`).join('\n')}
7
+ ${cfg.dockerPort?.map(port => `EXPOSE ${port}`).join('\n') ?? ''}
8
8
  ENTRYPOINT ["/app/${cfg.mainName}.sh"]
9
9
  `;