@travetto/pack 3.4.9 → 4.0.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
@@ -40,7 +40,9 @@ Options:
40
40
  -is, --include-sources Include source with source maps (default: false)
41
41
  -x, --eject-file <string> Eject commands to file
42
42
  -r, --rollup-configuration <string> Rollup configuration file (default: "@travetto/pack/support/bin/rollup")
43
- -m, --module <string> Module to run for
43
+ --env-file <string> Env Flag File Name (default: ".env")
44
+ --manifest-file <string> Manifest File Name (default: "manifest.json")
45
+ -m, --module <module> Module to run for
44
46
  -h, --help display help for command
45
47
  ```
46
48
 
@@ -102,7 +104,9 @@ Options:
102
104
  -is, --include-sources Include source with source maps (default: false)
103
105
  -x, --eject-file <string> Eject commands to file
104
106
  -r, --rollup-configuration <string> Rollup configuration file (default: "@travetto/pack/support/bin/rollup")
105
- -m, --module <string> Module to run for
107
+ --env-file <string> Env Flag File Name (default: ".env")
108
+ --manifest-file <string> Manifest File Name (default: "manifest.json")
109
+ -m, --module <module> Module to run for
106
110
  -h, --help display help for command
107
111
  ```
108
112
 
@@ -127,6 +131,8 @@ Options:
127
131
  -is, --include-sources Include source with source maps (default: false)
128
132
  -x, --eject-file <string> Eject commands to file
129
133
  -r, --rollup-configuration <string> Rollup configuration file (default: "@travetto/pack/support/bin/rollup")
134
+ --env-file <string> Env Flag File Name (default: ".env")
135
+ --manifest-file <string> Manifest File Name (default: "manifest.json")
130
136
  -df, --docker-factory <string> Docker Factory source (default: "@travetto/pack/support/pack.dockerfile")
131
137
  -di, --docker-image <string> Docker Image to extend (default: "node:20-alpine")
132
138
  -dn, --docker-name <string> Docker Image Name (default: "travetto_pack")
@@ -136,7 +142,7 @@ Options:
136
142
  -db, --docker-build-platform <string> Docker Build Platform
137
143
  -dr, --docker-registry <string> Docker Registry
138
144
  -du, --docker-runtime-user <string> Docker Runtime user
139
- -m, --module <string> Module to run for
145
+ -m, --module <module> Module to run for
140
146
  -h, --help display help for command
141
147
  ```
142
148
 
@@ -168,13 +174,14 @@ echo "Cleaning Output $DIST"
168
174
  rm -rf $DIST
169
175
  mkdir -p $DIST
170
176
 
171
- # Writing .env.js
177
+ # Writing $DIST/.env
172
178
 
173
- echo "Writing .env.js"
179
+ echo "Writing $DIST/.env"
174
180
 
175
- echo "process.env.TRV_MANIFEST = 'manifest.json';" > $DIST/.env.js
176
- echo "process.env.TRV_MODULE = '$MOD';" >> $DIST/.env.js
177
- echo "process.env.TRV_CLI_IPC = '';" >> $DIST/.env.js
181
+ echo "NODE_ENV=production" > $DIST/.env
182
+ echo "TRV_MANIFEST=manifest.json" >> $DIST/.env
183
+ echo "TRV_MODULE=$MOD" >> $DIST/.env
184
+ echo "TRV_CLI_IPC=" >> $DIST/.env
178
185
 
179
186
  # Writing package.json
180
187
 
@@ -188,7 +195,7 @@ echo "Writing entry scripts todo-app.sh args=(run:rest)"
188
195
 
189
196
  echo "#!/bin/sh" > $DIST/todo-app.sh
190
197
  echo "cd \$(dirname \"\$0\")" >> $DIST/todo-app.sh
191
- echo "node todo-app.js run:rest \$@" >> $DIST/todo-app.sh
198
+ echo "node --env-file=.env todo-app.js run:rest \$@" >> $DIST/todo-app.sh
192
199
  chmod 755 $DIST/todo-app.sh
193
200
 
194
201
  # Writing entry scripts todo-app.cmd args=(run:rest)
@@ -197,7 +204,7 @@ echo "Writing entry scripts todo-app.cmd args=(run:rest)"
197
204
 
198
205
  echo "" > $DIST/todo-app.cmd
199
206
  echo "cd %~p0" >> $DIST/todo-app.cmd
200
- echo "node todo-app.js run:rest %*" >> $DIST/todo-app.cmd
207
+ echo "node --env-file=.env todo-app.js run:rest %*" >> $DIST/todo-app.cmd
201
208
  chmod 755 $DIST/todo-app.cmd
202
209
 
203
210
  # Copying over resources
@@ -210,7 +217,7 @@ cp -r -p $ROOT/resources $DIST/resources
210
217
 
211
218
  echo "Writing Manifest manifest.json"
212
219
 
213
- TRV_MODULE=$MOD npx trvc manifest $DIST/manifest.json prod
220
+ TRV_MODULE=$MOD npx trvc manifest --prod $DIST/manifest.json
214
221
 
215
222
  # Bundling Output minify=true sourcemap=false entryPoint=@travetto/cli/support/entry.trv
216
223
 
@@ -223,6 +230,7 @@ export BUNDLE_SOURCEMAP=false
223
230
  export BUNDLE_SOURCES=false
224
231
  export BUNDLE_OUTPUT=$DIST
225
232
  export BUNDLE_FORMAT=commonjs
233
+ export BUNDLE_ENV_FILE=.env
226
234
  export TRV_MANIFEST=$TRV_OUT/node_modules/$MOD
227
235
  cd $TRV_OUT
228
236
  npx rollup -c $TRV_OUT/node_modules/@travetto/pack/support/bin/rollup.js
@@ -236,6 +244,7 @@ echo "FROM node:20-alpine" > $DIST/Dockerfile
236
244
  echo "RUN which useradd && (groupadd --gid 2000 app && useradd -u 2000 -g app app) || (addgroup -g 2000 app && adduser -D -G app -u 2000 app)" >> $DIST/Dockerfile
237
245
  echo "RUN mkdir /app && chown app:app /app" >> $DIST/Dockerfile
238
246
  echo "COPY --chown=\"app:app\" . /app" >> $DIST/Dockerfile
247
+ echo "ENV NODE_OPTIONS=\"--disable-proto=delete\"" >> $DIST/Dockerfile
239
248
  echo "USER app" >> $DIST/Dockerfile
240
249
  echo "WORKDIR /app" >> $DIST/Dockerfile
241
250
  echo "ENTRYPOINT [\"/app/todo-app.sh\"]" >> $DIST/Dockerfile
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/pack",
3
- "version": "3.4.9",
3
+ "version": "4.0.0-rc.0",
4
4
  "description": "Code packing utilities",
5
5
  "keywords": [
6
6
  "travetto",
@@ -28,11 +28,12 @@
28
28
  "@rollup/plugin-json": "^6.0.1",
29
29
  "@rollup/plugin-node-resolve": "^15.2.3",
30
30
  "@rollup/plugin-terser": "^0.4.4",
31
- "@travetto/base": "^3.4.2",
32
- "rollup": "^4.5.0"
31
+ "@travetto/base": "^4.0.0-rc.0",
32
+ "@travetto/terminal": "^4.0.0-rc.0",
33
+ "rollup": "^4.6.1"
33
34
  },
34
35
  "peerDependencies": {
35
- "@travetto/cli": "^3.4.7"
36
+ "@travetto/cli": "^4.0.0-rc.0"
36
37
  },
37
38
  "peerDependenciesMeta": {
38
39
  "@travetto/cli": {
@@ -22,7 +22,6 @@ export class PackConfigUtil {
22
22
 
23
23
  /**
24
24
  * Setup docker user
25
- * @returns
26
25
  */
27
26
  static dockerUser(cfg: DockerPackConfig): string {
28
27
  const { user, group, uid, gid } = cfg.dockerRuntime;
@@ -35,6 +34,18 @@ export class PackConfigUtil {
35
34
  ].join('\n');
36
35
  }
37
36
 
37
+ /**
38
+ * Setup Env Vars for NODE_OPTIONS and other standard environment variables
39
+ */
40
+ static dockerEnvVars(cfg: DockerPackConfig): string {
41
+ return [
42
+ `ENV NODE_OPTIONS="${[
43
+ '--disable-proto=delete', // Security enforcement
44
+ ...(cfg.sourcemap ? ['--enable-source-maps'] : []),
45
+ ].join(' ')}"`,
46
+ ].join('\n');
47
+ }
48
+
38
49
  /**
39
50
  * Setup docker runtime folder
40
51
  */
@@ -73,6 +84,7 @@ export class PackConfigUtil {
73
84
  this.dockerUser(cfg),
74
85
  this.dockerAppFolder(cfg),
75
86
  this.dockerAppFiles(cfg),
87
+ this.dockerEnvVars(cfg),
76
88
  ].filter(x => !!x).join('\n');
77
89
  }
78
90
 
@@ -1,24 +1,27 @@
1
+ import type fs from 'node:fs';
1
2
  import type { OutputOptions } from 'rollup';
2
- import { __importStar } from 'tslib';
3
3
 
4
4
  import type terser from '@rollup/plugin-terser';
5
5
 
6
- import { Env } from '@travetto/base';
7
- import { ManifestModule, ManifestModuleUtil, Package, path, RootIndex } from '@travetto/manifest';
6
+ import { ManifestModule, ManifestModuleUtil, NodeModuleType, path, RuntimeIndex, RuntimeContext } from '@travetto/manifest';
7
+ import { EnvProp } from '@travetto/base';
8
8
 
9
- const makeIntro = (doImport: (name: string) => string, ...extra: string[]): string => [
10
- `try { globalThis.crypto = ${doImport('crypto')}; } catch {}`,
11
- `try { ${doImport('./.env.js')} } catch {}`,
12
- ...extra
13
- ].map(x => x.trim()).join('\n');
9
+ // eslint-disable-next-line @typescript-eslint/naming-convention
10
+ function __envImport(mod: typeof fs, file: string): void {
11
+ if (process.env.TRV_MODULE) { return; }
12
+ try {
13
+ mod.readFileSync(file, 'utf8')
14
+ .split('\n')
15
+ .map(x => x.match(/\s*(?<key>[^ =]+)\s*=\s*(?<value>\S+)/)?.groups)
16
+ .filter((x): x is Exclude<typeof x, null | undefined> => !!x)
17
+ .forEach(x => process.env[x.key] = x.value);
18
+ } catch { }
19
+ }
14
20
 
15
- const INTRO = {
16
- commonjs: makeIntro(
17
- v => `require('${v}')`,
18
- __importStar.toString().replace(/function([^(]+)/, 'function __importStar'),
19
- ),
20
- module: makeIntro(v => `await import('${v}')`)
21
- };
21
+ const INTRO = (envFile: string | undefined): Record<NodeModuleType, string[]> => ({
22
+ commonjs: !envFile ? [] : [`(${__envImport.toString()})(require('node:fs'), '${envFile}')`],
23
+ module: !envFile ? [] : [`(${__envImport.toString()})(await import('node:fs'), '${envFile}')`]
24
+ });
22
25
 
23
26
  function getFilesFromModule(m: ManifestModule): string[] {
24
27
  return [
@@ -34,20 +37,19 @@ function getFilesFromModule(m: ManifestModule): string[] {
34
37
  }
35
38
 
36
39
  export function getOutput(): OutputOptions {
37
- const format: Package['type'] = Env.get('BUNDLE_FORMAT', 'commonjs');
38
- const dir = Env.get('BUNDLE_OUTPUT')!;
39
- const mainFile = Env.get('BUNDLE_MAIN_FILE')!;
40
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
41
+ const format = (process.env.BUNDLE_FORMAT ?? 'commonjs') as NodeModuleType;
42
+ const dir = process.env.BUNDLE_OUTPUT!;
43
+ const mainFile = process.env.BUNDLE_MAIN_FILE!;
40
44
  return {
41
45
  format,
42
- intro: INTRO[format],
46
+ interop: format === 'commonjs' ? 'auto' : undefined,
47
+ intro: INTRO(new EnvProp('BUNDLE_ENV_FILE').val)[format].join(';\n'),
43
48
  sourcemapPathTransform: (src, map): string =>
44
- path.resolve(path.dirname(map), src).replace(`${RootIndex.manifest.workspacePath}/`, ''),
45
- sourcemap:
46
- Env.getBoolean('BUNDLE_SOURCEMAP') ?? false,
47
- sourcemapExcludeSources:
48
- !(Env.getBoolean('BUNDLE_SOURCES') ?? false),
49
- compact:
50
- Env.getBoolean('BUNDLE_COMPRESS') ?? true,
49
+ path.resolve(path.dirname(map), src).replace(`${RuntimeContext.workspace.path}/`, ''),
50
+ sourcemap: new EnvProp('BUNDLE_SOURCEMAP').bool ?? false,
51
+ sourcemapExcludeSources: !(new EnvProp('BUNDLE_SOURCES').bool ?? false),
52
+ compact: new EnvProp('BUNDLE_COMPRESS').bool ?? true,
51
53
  file: path.resolve(dir, mainFile),
52
54
  ...(format === 'commonjs' ? {} : {
53
55
  inlineDynamicImports: true
@@ -56,19 +58,19 @@ export function getOutput(): OutputOptions {
56
58
  }
57
59
 
58
60
  export function getEntry(): string {
59
- return Env.get('BUNDLE_ENTRY')!;
61
+ return process.env.BUNDLE_ENTRY!;
60
62
  }
61
63
 
62
64
  export function getFiles(): string[] {
63
- return [...RootIndex.getModuleList('all')]
64
- .map(x => RootIndex.manifest.modules[x])
65
+ return [...RuntimeIndex.getModuleList('all')]
66
+ .map(x => RuntimeIndex.getManifestModule(x))
65
67
  .filter(m => m.prod)
66
68
  .flatMap(getFilesFromModule);
67
69
  }
68
70
 
69
71
  export function getIgnoredModules(): string[] {
70
- return [...RootIndex.getModuleList('all')]
71
- .map(x => RootIndex.manifest.modules[x])
72
+ return [...RuntimeIndex.getModuleList('all')]
73
+ .map(x => RuntimeIndex.getManifestModule(x))
72
74
  .filter(m => !m.prod)
73
75
  .map(m => m.name);
74
76
  }
@@ -1,6 +1,6 @@
1
- import fs from 'fs/promises';
1
+ import fs from 'node:fs/promises';
2
2
 
3
- import { path, RootIndex } from '@travetto/manifest';
3
+ import { path, RuntimeIndex } from '@travetto/manifest';
4
4
  import { cliTpl } from '@travetto/cli';
5
5
 
6
6
  import { ActiveShellCommand } from './shell';
@@ -20,7 +20,7 @@ export class DockerPackOperation {
20
20
  static async* writeDockerFile(cfg: DockerPackConfig): AsyncIterable<string[]> {
21
21
  const dockerFile = path.resolve(cfg.workspace, 'Dockerfile');
22
22
 
23
- const factory = RootIndex.getFromImport(cfg.dockerFactory);
23
+ const factory = RuntimeIndex.getFromImport(cfg.dockerFactory);
24
24
  if (!factory) {
25
25
  throw new Error(`Unable to resolve docker factory at ${cfg.dockerFactory}`);
26
26
  }
@@ -1,16 +1,13 @@
1
- import fs from 'fs/promises';
1
+ import fs from 'node:fs/promises';
2
2
 
3
- import { path, RootIndex } from '@travetto/manifest';
3
+ import { path, RuntimeIndex, RuntimeContext } from '@travetto/manifest';
4
4
  import { cliTpl } from '@travetto/cli';
5
+ import { Env } from '@travetto/base';
5
6
 
6
7
  import { CommonPackConfig } from './types';
7
8
  import { PackUtil } from './util';
8
9
  import { ActiveShellCommand, ShellCommands } from './shell';
9
10
 
10
- async function writeRawFile(file: string, contents: string, mode?: string): Promise<void> {
11
- await fs.writeFile(file, contents, { encoding: 'utf8', mode });
12
- }
13
-
14
11
  /**
15
12
  * General pack operations
16
13
  */
@@ -54,25 +51,29 @@ export class PackOperation {
54
51
  * Invoke bundler (rollup) to produce output in workspace folder
55
52
  */
56
53
  static async * bundle(cfg: CommonPackConfig): AsyncIterable<string[]> {
57
- const cwd = RootIndex.outputRoot;
58
-
59
- const bundleCommand = ['npx', 'rollup', '-c', RootIndex.resolveFileImport(cfg.rollupConfiguration)];
60
-
61
- const entryPointFile = RootIndex.getFromImport(cfg.entryPoint)!.outputFile.split(`${RootIndex.manifest.outputFolder}/`)[1];
62
-
63
- const env = Object.fromEntries(([
64
- ['BUNDLE_ENTRY', entryPointFile],
65
- ['BUNDLE_MAIN_FILE', `${cfg.mainName}.js`],
66
- ['BUNDLE_COMPRESS', cfg.minify],
67
- ['BUNDLE_SOURCEMAP', cfg.sourcemap],
68
- ['BUNDLE_SOURCES', cfg.includeSources],
69
- ['BUNDLE_OUTPUT', cfg.workspace],
70
- ['BUNDLE_FORMAT', RootIndex.manifest.moduleType],
71
- ['TRV_MANIFEST', RootIndex.getModule(cfg.module)!.outputPath]
72
- ] as const)
73
- .filter(x => x[1] === false || x[1])
74
- .map(x => [x[0], `${x[1]}`])
75
- );
54
+ const cwd = RuntimeIndex.outputRoot;
55
+ const out = RuntimeIndex.manifest.build.outputFolder;
56
+
57
+ const bundleCommand = ['npx', 'rollup', '-c', RuntimeIndex.resolveFileImport(cfg.rollupConfiguration)];
58
+
59
+ const entryPointFile = RuntimeIndex.getFromImport(cfg.entryPoint)!.outputFile.split(`${out}/`)[1];
60
+
61
+ const env = {
62
+ ...Object.fromEntries(([
63
+ ['BUNDLE_ENTRY', entryPointFile],
64
+ ['BUNDLE_MAIN_FILE', cfg.mainFile],
65
+ ['BUNDLE_COMPRESS', cfg.minify],
66
+ ['BUNDLE_SOURCEMAP', cfg.sourcemap],
67
+ ['BUNDLE_SOURCES', cfg.includeSources],
68
+ ['BUNDLE_OUTPUT', cfg.workspace],
69
+ ['BUNDLE_FORMAT', RuntimeContext.workspace.type],
70
+ ['BUNDLE_ENV_FILE', cfg.envFile]
71
+ ] as const)
72
+ .filter(x => x[1] === false || x[1])
73
+ .map(x => [x[0], `${x[1]}`])
74
+ ),
75
+ ...Env.TRV_MANIFEST.export(RuntimeIndex.getModule(cfg.module)!.outputPath),
76
+ };
76
77
 
77
78
  const props = (['minify', 'sourcemap', 'entryPoint'] as const)
78
79
  .map(k => cliTpl`${{ subtitle: k }}=${{ param: cfg[k] }}`).join(' ');
@@ -88,7 +89,7 @@ export class PackOperation {
88
89
  yield ActiveShellCommand.chdir(path.cwd());
89
90
  } else {
90
91
  await PackUtil.runCommand(bundleCommand, { cwd, env });
91
- const stat = await fs.stat(path.resolve(cfg.workspace, `${cfg.mainName}.js`));
92
+ const stat = await fs.stat(path.resolve(cfg.workspace, cfg.mainFile));
92
93
  yield [cliTpl`${{ title: 'Bundled Output ' }} ${{ identifier: 'sizeKb' }}=${{ param: Math.trunc(stat.size / 2 ** 10) }}`];
93
94
  }
94
95
  }
@@ -98,7 +99,7 @@ export class PackOperation {
98
99
  */
99
100
  static async * writePackageJson(cfg: CommonPackConfig): AsyncIterable<string[]> {
100
101
  const file = 'package.json';
101
- const pkg = { type: RootIndex.manifest.moduleType, main: `${cfg.mainName}.js` };
102
+ const pkg = { type: RuntimeContext.workspace.type, main: cfg.mainFile };
102
103
 
103
104
  yield* PackOperation.title(cfg, cliTpl`${{ title: 'Writing' }} ${{ path: file }}`);
104
105
 
@@ -108,9 +109,9 @@ export class PackOperation {
108
109
  [JSON.stringify(pkg)]
109
110
  );
110
111
  } else {
111
- await writeRawFile(
112
+ await PackUtil.writeRawFile(
112
113
  path.resolve(cfg.workspace, file),
113
- JSON.stringify(pkg, null, 2)
114
+ [JSON.stringify(pkg, null, 2)]
114
115
  );
115
116
  }
116
117
  }
@@ -119,11 +120,12 @@ export class PackOperation {
119
120
  * Define .env.js file to control manifest location
120
121
  */
121
122
  static async * writeEnv(cfg: CommonPackConfig): AsyncIterable<string[]> {
122
- const file = '.env.js';
123
+ const file = path.resolve(cfg.workspace, cfg.envFile);
123
124
  const env = {
124
- TRV_MANIFEST: 'manifest.json',
125
- TRV_MODULE: cfg.module,
126
- TRV_CLI_IPC: ''
125
+ ...Env.NODE_ENV.export('production'),
126
+ ...Env.TRV_MANIFEST.export(cfg.manifestFile),
127
+ ...Env.TRV_MODULE.export(cfg.module),
128
+ ...Env.TRV_CLI_IPC.export(undefined)
127
129
  };
128
130
 
129
131
  yield* PackOperation.title(cfg, cliTpl`${{ title: 'Writing' }} ${{ path: file }}`);
@@ -131,12 +133,12 @@ export class PackOperation {
131
133
  if (cfg.ejectFile) {
132
134
  yield* ActiveShellCommand.createFile(
133
135
  path.resolve(cfg.workspace, file),
134
- PackUtil.buildEnvJS(env)
136
+ PackUtil.buildEnvFile(env)
135
137
  );
136
138
  } else {
137
- await writeRawFile(
139
+ await PackUtil.writeRawFile(
138
140
  path.resolve(cfg.workspace, file),
139
- PackUtil.buildEnvJS(env).join('\n')
141
+ PackUtil.buildEnvFile(env)
140
142
  );
141
143
  }
142
144
  }
@@ -158,7 +160,7 @@ export class PackOperation {
158
160
  text: [
159
161
  ShellCommands[type].scriptOpen(),
160
162
  ShellCommands[type].chdirScript(),
161
- ShellCommands[type].callCommandWithAllArgs('node', `${cfg.mainName}.js`, ...cfg.entryArguments),
163
+ ShellCommands[type].callCommandWithAllArgs('node', `--env-file=${cfg.envFile}`, cfg.mainFile, ...cfg.entryArguments),
162
164
  ].map(x => x.join(' '))
163
165
  }));
164
166
 
@@ -170,7 +172,7 @@ export class PackOperation {
170
172
  } else {
171
173
  for (const { fileTitle, text, file } of files) {
172
174
  yield* PackOperation.title(cfg, fileTitle);
173
- await writeRawFile(path.resolve(cfg.workspace, file), text.join('\n'), '755');
175
+ await PackUtil.writeRawFile(path.resolve(cfg.workspace, file), text, '755');
174
176
  }
175
177
  }
176
178
  }
@@ -180,8 +182,8 @@ export class PackOperation {
180
182
  */
181
183
  static async * copyResources(cfg: CommonPackConfig): AsyncIterable<string[]> {
182
184
  const resources = {
183
- count: RootIndex.mainModule.files.resources?.length ?? 0,
184
- src: path.resolve(RootIndex.mainModule.sourcePath, 'resources'),
185
+ count: RuntimeIndex.mainModule.files.resources?.length ?? 0,
186
+ src: path.resolve(RuntimeIndex.mainModule.sourcePath, 'resources'),
185
187
  dest: path.resolve(cfg.workspace, 'resources')
186
188
  };
187
189
 
@@ -203,11 +205,11 @@ export class PackOperation {
203
205
  * Produce the output manifest, only including prod dependencies
204
206
  */
205
207
  static async * writeManifest(cfg: CommonPackConfig): AsyncIterable<string[]> {
206
- const out = path.resolve(cfg.workspace, 'manifest.json');
207
- const cmd = ['npx', 'trvc', 'manifest', out, 'prod'];
208
- const env = { TRV_MODULE: cfg.module };
208
+ const out = path.resolve(cfg.workspace, cfg.manifestFile);
209
+ const cmd = ['npx', 'trvc', 'manifest', '--prod', out];
210
+ const env = { ...Env.TRV_MODULE.export(cfg.module) };
209
211
 
210
- yield* PackOperation.title(cfg, cliTpl`${{ title: 'Writing Manifest' }} ${{ path: 'manifest.json' }}`);
212
+ yield* PackOperation.title(cfg, cliTpl`${{ title: 'Writing Manifest' }} ${{ path: cfg.manifestFile }}`);
211
213
 
212
214
  if (cfg.ejectFile) {
213
215
  yield [...Object.entries(env).map(([k, v]) => `${k}=${v}`), ...cmd];
@@ -1,5 +1,5 @@
1
- import path from 'path';
2
- import fs from 'fs/promises';
1
+ import path from 'node:path';
2
+ import fs from 'node:fs/promises';
3
3
 
4
4
  import { LoadResult, Plugin, PluginContext } from 'rollup';
5
5
 
@@ -4,7 +4,7 @@ import terser from '@rollup/plugin-terser';
4
4
  import jsonImport from '@rollup/plugin-json';
5
5
  import type { RollupOptions } from 'rollup';
6
6
 
7
- import { RootIndex } from '@travetto/manifest';
7
+ import { RuntimeContext } from '@travetto/manifest';
8
8
 
9
9
  import { getEntry, getOutput, getTerserConfig, getFiles, getIgnoredModules } from './config';
10
10
  import { travettoImportPlugin } from './rollup-esm-dynamic-import';
@@ -26,7 +26,7 @@ export default function buildConfig(): RollupOptions {
26
26
  jsonImport(),
27
27
  commonjsRequire({
28
28
  ignore: id => ignoreRe.test(id) || NEVER_INCLUDE.has(id),
29
- dynamicRequireRoot: RootIndex.manifest.workspacePath,
29
+ dynamicRequireRoot: RuntimeContext.workspace.path,
30
30
  dynamicRequireTargets: (output.format === 'commonjs' ? files : [])
31
31
  }),
32
32
  ...(output.format === 'module' ? [travettoImportPlugin(entry, files)] : []),
@@ -1,5 +1,5 @@
1
1
  import { path } from '@travetto/manifest';
2
- import { stripAnsiCodes } from '@travetto/terminal';
2
+ import { StyleUtil } from '@travetto/terminal';
3
3
 
4
4
  import { ShellCommandImpl } from './types';
5
5
 
@@ -30,8 +30,8 @@ export const ShellCommands: Record<'win32' | 'posix', ShellCommandImpl> = {
30
30
  mkdir: (dest) => ['md', dest],
31
31
  export: (key, value) => ['set', `${key}=${value}`],
32
32
  chdir: (dest) => ['cd', dest],
33
- comment: (message) => ['\nREM', stripAnsiCodes(message), '\n'],
34
- echo: (message) => ['echo', `"${escape(stripAnsiCodes(message))}"\n`],
33
+ comment: (message) => ['\nREM', StyleUtil.cleanText(message), '\n'],
34
+ echo: (message) => ['echo', `"${escape(StyleUtil.cleanText(message))}"\n`],
35
35
  zip: (outputFile) => ['powershell', 'Compress-Archive', '-Path', '.', '-DestinationPath', outputFile]
36
36
  },
37
37
  posix: {
@@ -50,8 +50,8 @@ export const ShellCommands: Record<'win32' | 'posix', ShellCommandImpl> = {
50
50
  mkdir: (dest) => ['mkdir', '-p', dest],
51
51
  export: (key, value) => ['export', `${key}=${value}`],
52
52
  chdir: (dest) => ['cd', dest],
53
- comment: (message) => ['\n#', stripAnsiCodes(message), '\n'],
54
- echo: (message) => ['echo', `"${escape(stripAnsiCodes(message))}"\n`],
53
+ comment: (message) => ['\n#', StyleUtil.cleanText(message), '\n'],
54
+ echo: (message) => ['echo', `"${escape(StyleUtil.cleanText(message))}"\n`],
55
55
  zip: (outputFile) => ['zip', '-r', outputFile, '.']
56
56
  },
57
57
  };
@@ -4,8 +4,11 @@ export type CommonPackConfig = {
4
4
  clean: boolean;
5
5
  ejectFile?: string;
6
6
  mainName: string;
7
+ mainFile: string;
7
8
  mainScripts?: boolean;
8
9
  module: string;
10
+ envFile: string;
11
+ manifestFile: string;
9
12
 
10
13
  // Bundle
11
14
  rollupConfiguration: string;
@@ -1,19 +1,18 @@
1
- import fs from 'fs/promises';
1
+ import fs from 'node:fs/promises';
2
2
 
3
- import { path, RootIndex } from '@travetto/manifest';
3
+ import { path, RuntimeIndex } from '@travetto/manifest';
4
4
  import { AppError, ExecUtil, ExecutionOptions } from '@travetto/base';
5
5
 
6
6
  import { ActiveShellCommand } from './shell';
7
7
 
8
8
  export class PackUtil {
9
9
  /**
10
- * Generate env.js
10
+ * Generate .env file
11
11
  */
12
- static buildEnvJS(env: Record<string, string | number | boolean | undefined>): string[] {
13
- const entries = Object.entries(env)
12
+ static buildEnvFile(env: Record<string, string | number | boolean | undefined>): string[] {
13
+ return Object.entries(env)
14
14
  .filter(([k, v]) => (v !== undefined))
15
- .map(([k, v]) => [k, `${v}`]);
16
- return entries.map(([k, v]) => `process.env.${k} = '${v}';`);
15
+ .map(([k, v]) => `${k}=${v}`);
17
16
  }
18
17
 
19
18
  /**
@@ -34,7 +33,7 @@ export class PackUtil {
34
33
  * Finalize eject output
35
34
  */
36
35
  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 };
36
+ const vars = { DIST: workspace, TRV_OUT: RuntimeIndex.outputRoot, ROOT: path.cwd(), MOD: module };
38
37
 
39
38
  const replaceArgs = (text: string): string => Object.entries(vars)
40
39
  .reduce((str, [k, v]) => str.replaceAll(v, ActiveShellCommand.var(k)), text);
@@ -78,4 +77,11 @@ export class PackUtil {
78
77
  }
79
78
  return stdout;
80
79
  }
80
+
81
+ /**
82
+ * Write a file directly
83
+ */
84
+ static async writeRawFile(file: string, contents: string[], mode?: string): Promise<void> {
85
+ await fs.writeFile(file, contents.join('\n'), { encoding: 'utf8', mode });
86
+ }
81
87
  }
@@ -1,12 +1,12 @@
1
- import { path, RootIndex } from '@travetto/manifest';
1
+ import { path, RuntimeIndex } from '@travetto/manifest';
2
2
  import { CliCommand, CliFlag, CliUtil, CliValidationError } from '@travetto/cli';
3
- import { GlobalEnv } from '@travetto/base';
4
3
  import { Ignore, Required } from '@travetto/schema';
5
4
 
6
5
  import { DockerPackOperation } from './bin/docker-operation';
7
6
  import { BasePackCommand, PackOperationShape } from './pack.base';
8
7
  import { DockerPackConfig } from './bin/types';
9
8
 
9
+ const NODE_MAJOR = +process.version.match(/\d+/)![0];
10
10
  const DEFAULT_USER_ID = 2000;
11
11
  const DEFAULT_USER = 'app';
12
12
 
@@ -18,7 +18,7 @@ export class PackDockerCommand extends BasePackCommand {
18
18
  @CliFlag({ desc: 'Docker Factory source ', short: 'df', envVars: ['PACK_DOCKER_FACTORY'] })
19
19
  dockerFactory = '@travetto/pack/support/pack.dockerfile';
20
20
  @CliFlag({ desc: 'Docker Image to extend ', short: 'di', envVars: ['PACK_DOCKER_IMAGE'] })
21
- dockerImage = `node:${GlobalEnv.nodeVersion}-alpine`;
21
+ dockerImage = `node:${NODE_MAJOR}-alpine`;
22
22
  @CliFlag({ desc: 'Docker Image Name ', short: 'dn', envVars: ['PACK_DOCKER_IMAGE'] })
23
23
  @Required(false)
24
24
  dockerName: string;
@@ -54,7 +54,7 @@ export class PackDockerCommand extends BasePackCommand {
54
54
 
55
55
  preMain(): void {
56
56
  if (this.dockerFactory.startsWith('.')) {
57
- this.dockerFactory = RootIndex.getFromSource(path.resolve(this.dockerFactory))?.import ?? this.dockerFactory;
57
+ this.dockerFactory = RuntimeIndex.getFromSource(path.resolve(this.dockerFactory))?.import ?? this.dockerFactory;
58
58
  }
59
59
  this.dockerName ??= CliUtil.getSimpleModuleName('<module>', this.module || undefined);
60
60
 
@@ -1,9 +1,9 @@
1
- import os from 'os';
1
+ import os from 'node:os';
2
2
 
3
- import { CliCommandShape, CliFlag, CliParseUtil, cliTpl } from '@travetto/cli';
4
- import { path, RootIndex } from '@travetto/manifest';
3
+ import { CliCommandShape, CliFlag, ParsedState, cliTpl } from '@travetto/cli';
4
+ import { path, RuntimeIndex, RuntimeContext } from '@travetto/manifest';
5
5
  import { TimeUtil } from '@travetto/base';
6
- import { GlobalTerminal } from '@travetto/terminal';
6
+ import { Terminal } from '@travetto/terminal';
7
7
  import { Ignore, Required, Schema } from '@travetto/schema';
8
8
 
9
9
  import { PackOperation } from './bin/operation';
@@ -15,7 +15,7 @@ export type PackOperationShape<T> = ((config: T) => AsyncIterable<string[]>);
15
15
  export abstract class BasePackCommand implements CliCommandShape {
16
16
 
17
17
  static get entryPoints(): string[] {
18
- return RootIndex.find({
18
+ return RuntimeIndex.find({
19
19
  module: m => m.prod,
20
20
  folder: f => f === 'support',
21
21
  file: f => f.sourceFile.includes('entry.')
@@ -23,8 +23,11 @@ export abstract class BasePackCommand implements CliCommandShape {
23
23
  .map(x => x.import.replace(/[.][^.]+s$/, ''));
24
24
  }
25
25
 
26
+ @Ignore()
27
+ _parsed: ParsedState;
28
+
26
29
  @CliFlag({ desc: 'Workspace for building', short: 'w' })
27
- workspace: string = path.resolve(os.tmpdir(), RootIndex.mainModule.sourcePath.replace(/[\/\\: ]/g, '_'));
30
+ workspace: string = path.resolve(os.tmpdir(), RuntimeIndex.mainModule.sourcePath.replace(/[\/\\: ]/g, '_'));
28
31
 
29
32
  @CliFlag({ desc: 'Clean workspace' })
30
33
  clean = true;
@@ -59,9 +62,18 @@ export abstract class BasePackCommand implements CliCommandShape {
59
62
  @CliFlag({ desc: 'Rollup configuration file', short: 'r' })
60
63
  rollupConfiguration = '@travetto/pack/support/bin/rollup';
61
64
 
65
+ @CliFlag({ desc: 'Env Flag File Name' })
66
+ envFile = '.env';
67
+
68
+ @CliFlag({ desc: 'Manifest File Name' })
69
+ manifestFile = 'manifest.json';
70
+
62
71
  @Ignore()
63
72
  module: string;
64
73
 
74
+ @Ignore()
75
+ mainFile: string;
76
+
65
77
  /** Entry arguments */
66
78
  @Ignore()
67
79
  entryArguments: string[] = [];
@@ -96,9 +108,10 @@ export abstract class BasePackCommand implements CliCommandShape {
96
108
  this.workspace = path.resolve(this.workspace);
97
109
 
98
110
  // Update entry points
99
- this.entryArguments = [...this.entryArguments ?? [], ...args, ...CliParseUtil.getState(this)?.unknown ?? []];
100
- this.module ||= RootIndex.mainModuleName;
111
+ this.entryArguments = [...this.entryArguments ?? [], ...args, ...this._parsed.unknown];
112
+ this.module ||= RuntimeContext.main.name;
101
113
  this.mainName ??= path.basename(this.module);
114
+ this.mainFile = `${this.mainName}.js`;
102
115
 
103
116
  const stream = this.runOperations();
104
117
 
@@ -107,19 +120,15 @@ export abstract class BasePackCommand implements CliCommandShape {
107
120
  await PackUtil.writeEjectOutput(this.workspace, this.module, stream, this.ejectFile);
108
121
  } else {
109
122
  const start = Date.now();
123
+ const term = new Terminal();
124
+
125
+ await term.streamLines(stream);
110
126
 
111
- await GlobalTerminal.streamLinesWithWaiting(stream, {
112
- initialDelay: 0,
113
- cycleDelay: 100,
114
- end: false,
115
- position: 'inline',
116
- committedPrefix: String.fromCharCode(171)
117
- });
118
127
  let msg = cliTpl`${{ success: 'Success' }} (${{ identifier: TimeUtil.prettyDeltaSinceTime(start) }}) ${{ subtitle: 'module' }}=${{ param: this.module }}`;
119
128
  if (this.output) {
120
129
  msg = cliTpl`${msg} ${{ subtitle: 'output' }}=${{ path: this.output }}`;
121
130
  }
122
- await GlobalTerminal.writeLines(msg);
131
+ await term.writer.writeLine(msg).commit();
123
132
  }
124
133
  }
125
134
  }