@travetto/pack 8.0.0-alpha.22 → 8.0.0-alpha.23
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 +10 -10
- package/__index__.ts +2 -2
- package/package.json +4 -4
- package/src/config-util.ts +26 -25
- package/src/types.ts +4 -4
- package/support/bin/docker-operation.ts +39 -19
- package/support/bin/operation.ts +48 -55
- package/support/bin/preamble.ts +12 -5
- package/support/bin/shell.ts +38 -41
- package/support/bin/util.ts +21 -13
- package/support/cli.pack.ts +1 -1
- package/support/cli.pack_docker.ts +8 -10
- package/support/cli.pack_zip.ts +2 -6
- package/support/pack.base.ts +11 -14
- package/support/pack.dockerfile.ts +2 -2
- package/support/rollup/build.ts +3 -3
- package/support/rollup/config.ts +15 -14
- package/support/rollup/rollup-travetto-entry.ts +3 -2
- package/support/rollup/rollup-travetto-import.ts +4 -4
- package/support/rollup/rollup-travetto-sourcemaps.ts +9 -11
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ npm install @travetto/pack
|
|
|
13
13
|
yarn add @travetto/pack
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
This module provides the necessary tools to produce deliverable output for [Travetto](https://travetto.dev) based projects.
|
|
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.
|
|
17
17
|
|
|
18
18
|
There are three primary cli commands for packing your code:
|
|
19
19
|
* pack
|
|
@@ -61,7 +61,7 @@ This command line operation will compile your project, and produce a ready to us
|
|
|
61
61
|
Specific to this CLI command, the `output` field determines where the final folder is written that contains all the compiled source.
|
|
62
62
|
|
|
63
63
|
### Entry Point Configuration
|
|
64
|
-
Every application requires an entry point to determine execution flow (and in [Rollup](https://rollupjs.org/)'s case, tree-shaking as well.).
|
|
64
|
+
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.
|
|
65
65
|
|
|
66
66
|
Within the command line, the `args` are positional arguments that will be passed to the entry point on application run.
|
|
67
67
|
|
|
@@ -85,16 +85,16 @@ And this entry point would be what is executed by [docker](https://www.docker.co
|
|
|
85
85
|
### General Packing Operations
|
|
86
86
|
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.
|
|
87
87
|
* `clean` - Empties workspace before beginning, controlled by the `--clean` flag, defaults to on
|
|
88
|
-
* `writeEnv` - Writes the .env.js files that includes the necessary details to start the application.
|
|
88
|
+
* `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.
|
|
89
89
|
* `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
|
|
90
90
|
* `writeEntryScript` - Create the entry script based on the `--entry-command`, `args`
|
|
91
91
|
* `copyResources` - Will pull in local `resources/**` files into the final output
|
|
92
|
-
* `primeAppCache` - Runs `trv run` to ensure the appropriate files are generated to allow for running the application.
|
|
93
|
-
* `writeManifest` - Produces the `production`-ready manifest that is used at runtime.
|
|
94
|
-
* `bundle` - Invokes [Rollup](https://rollupjs.org/) with the appropriate file set to produce a single output .js file.
|
|
92
|
+
* `primeAppCache` - Runs `trv run` to ensure the appropriate files are generated to allow for running the application. This only applies if the entry point is equivalent to `trv run`
|
|
93
|
+
* `writeManifest` - Produces the `production`-ready manifest that is used at runtime. Removes all devDependencies from the manifest.json
|
|
94
|
+
* `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.
|
|
95
95
|
|
|
96
96
|
## CLI - pack:zip
|
|
97
|
-
This command is nearly identical to the standard `pack` operation, except for the `output` flag.
|
|
97
|
+
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.
|
|
98
98
|
|
|
99
99
|
**Terminal: Help for pack:zip**
|
|
100
100
|
```bash
|
|
@@ -178,16 +178,16 @@ Options:
|
|
|
178
178
|
Examples:
|
|
179
179
|
```
|
|
180
180
|
|
|
181
|
-
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
|
|
181
|
+
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.
|
|
182
182
|
|
|
183
183
|
In addition to the standard operations, this command adds the following steps:
|
|
184
184
|
* `writeDockerFile` - Generate the docker file contents
|
|
185
185
|
* `pullDockerBaseImage` - Pull base image, to ensure its available and primed
|
|
186
186
|
* `buildDockerContainer` - Build final container
|
|
187
|
-
* `pushDockerContainer` - Push container with appropriate tags.
|
|
187
|
+
* `pushDockerContainer` - Push container with appropriate tags. Only applies if `--docker-push` is specified
|
|
188
188
|
|
|
189
189
|
## Ejected File
|
|
190
|
-
As indicated, any of the pack operations can be ejected, and produce an output that can be run independent of the pack command.
|
|
190
|
+
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.
|
|
191
191
|
|
|
192
192
|
**Terminal: Sample Ejected File**
|
|
193
193
|
```bash
|
package/__index__.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export
|
|
2
|
-
export {
|
|
1
|
+
export { PackConfigUtil } from './src/config-util.ts';
|
|
2
|
+
export type { CommonPackConfig, DockerPackConfig, DockerPackFactory } from './src/types.ts';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/pack",
|
|
3
|
-
"version": "8.0.0-alpha.
|
|
3
|
+
"version": "8.0.0-alpha.23",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Code packing utilities",
|
|
6
6
|
"keywords": [
|
|
@@ -30,12 +30,12 @@
|
|
|
30
30
|
"@rollup/plugin-json": "^6.1.0",
|
|
31
31
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
32
32
|
"@rollup/plugin-terser": "^1.0.0",
|
|
33
|
-
"@travetto/runtime": "^8.0.0-alpha.
|
|
34
|
-
"@travetto/terminal": "^8.0.0-alpha.
|
|
33
|
+
"@travetto/runtime": "^8.0.0-alpha.20",
|
|
34
|
+
"@travetto/terminal": "^8.0.0-alpha.20",
|
|
35
35
|
"rollup": "^4.62.2"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@travetto/cli": "^8.0.0-alpha.
|
|
38
|
+
"@travetto/cli": "^8.0.0-alpha.28"
|
|
39
39
|
},
|
|
40
40
|
"peerDependenciesMeta": {
|
|
41
41
|
"@travetto/cli": {
|
package/src/config-util.ts
CHANGED
|
@@ -18,11 +18,14 @@ export class PackConfigUtil {
|
|
|
18
18
|
const { os, packages } = config.dockerRuntime;
|
|
19
19
|
if (packages?.length) {
|
|
20
20
|
switch (os) {
|
|
21
|
-
case 'alpine':
|
|
22
|
-
|
|
23
|
-
case '
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
case 'alpine':
|
|
22
|
+
return `RUN apk --update add ${packages.join(' ')} && rm -rf /var/cache/apk/*`;
|
|
23
|
+
case 'debian':
|
|
24
|
+
return `RUN apt update && apt install -y ${packages.join(' ')} && rm -rf /var/lib/{apt,dpkg,cache,log}/`;
|
|
25
|
+
case 'centos':
|
|
26
|
+
return `RUN yum -y install ${packages.join(' ')} && yum -y clean all && rm -fr /var/cache`;
|
|
27
|
+
default:
|
|
28
|
+
throw new Error('Unable to install packages in an unknown os');
|
|
26
29
|
}
|
|
27
30
|
} else {
|
|
28
31
|
return '';
|
|
@@ -38,9 +41,11 @@ export class PackConfigUtil {
|
|
|
38
41
|
const [name, directive] = item.split(':');
|
|
39
42
|
switch (directive) {
|
|
40
43
|
case 'from-source':
|
|
41
|
-
out.push(`RUN npm_config_build_from_source=true npm install ${name} --build-from-source`);
|
|
44
|
+
out.push(`RUN npm_config_build_from_source=true npm install ${name} --build-from-source`);
|
|
45
|
+
break;
|
|
42
46
|
default:
|
|
43
|
-
out.push(`RUN npm install ${name}`);
|
|
47
|
+
out.push(`RUN npm install ${name}`);
|
|
48
|
+
break;
|
|
44
49
|
}
|
|
45
50
|
}
|
|
46
51
|
if (out.length) {
|
|
@@ -65,11 +70,13 @@ export class PackConfigUtil {
|
|
|
65
70
|
return '';
|
|
66
71
|
} else {
|
|
67
72
|
switch (os) {
|
|
68
|
-
case 'alpine':
|
|
73
|
+
case 'alpine':
|
|
74
|
+
return `RUN addgroup -g ${groupId} ${group} && adduser -D -G ${group} -u ${userId} ${user}`;
|
|
69
75
|
case 'debian':
|
|
70
|
-
case 'centos':
|
|
71
|
-
|
|
72
|
-
default:
|
|
76
|
+
case 'centos':
|
|
77
|
+
return `RUN groupadd --gid ${groupId} ${group} && useradd -u ${userId} -g ${group} ${user}`;
|
|
78
|
+
default:
|
|
79
|
+
throw new Error('Unable to add user/group for an unknown os');
|
|
73
80
|
}
|
|
74
81
|
}
|
|
75
82
|
}
|
|
@@ -78,9 +85,7 @@ export class PackConfigUtil {
|
|
|
78
85
|
* Setup Env Vars for NODE_OPTIONS and other standard environment variables
|
|
79
86
|
*/
|
|
80
87
|
static dockerEnvVars(config: DockerPackConfig): string {
|
|
81
|
-
return [
|
|
82
|
-
`ENV NODE_OPTIONS="${[...(config.sourcemap ? ['--enable-source-maps'] : [])].join(' ')}"`,
|
|
83
|
-
].join('\n');
|
|
88
|
+
return [`ENV NODE_OPTIONS="${[...(config.sourcemap ? ['--enable-source-maps'] : [])].join(' ')}"`].join('\n');
|
|
84
89
|
}
|
|
85
90
|
|
|
86
91
|
/**
|
|
@@ -88,9 +93,7 @@ export class PackConfigUtil {
|
|
|
88
93
|
*/
|
|
89
94
|
static dockerAppFolder(config: DockerPackConfig): string {
|
|
90
95
|
const { folder, user, group } = config.dockerRuntime;
|
|
91
|
-
return [
|
|
92
|
-
`RUN mkdir ${folder} && chown ${user}:${group} ${folder}`,
|
|
93
|
-
].join('\n');
|
|
96
|
+
return [`RUN mkdir ${folder} && chown ${user}:${group} ${folder}`].join('\n');
|
|
94
97
|
}
|
|
95
98
|
|
|
96
99
|
/**
|
|
@@ -106,11 +109,7 @@ export class PackConfigUtil {
|
|
|
106
109
|
*/
|
|
107
110
|
static dockerEntrypoint(config: DockerPackConfig): string {
|
|
108
111
|
const { user, folder } = config.dockerRuntime;
|
|
109
|
-
return [
|
|
110
|
-
`USER ${user}`,
|
|
111
|
-
`WORKDIR ${folder}`,
|
|
112
|
-
`ENTRYPOINT ["${folder}/${config.mainName}.sh"]`,
|
|
113
|
-
].join('\n');
|
|
112
|
+
return [`USER ${user}`, `WORKDIR ${folder}`, `ENTRYPOINT ["${folder}/${config.mainName}.sh"]`].join('\n');
|
|
114
113
|
}
|
|
115
114
|
/**
|
|
116
115
|
* Common docker environment setup
|
|
@@ -122,8 +121,10 @@ export class PackConfigUtil {
|
|
|
122
121
|
this.dockerPackageInstall(config),
|
|
123
122
|
this.dockerAppFolder(config),
|
|
124
123
|
this.dockerAppFiles(config),
|
|
125
|
-
this.dockerEnvVars(config)
|
|
126
|
-
]
|
|
124
|
+
this.dockerEnvVars(config)
|
|
125
|
+
]
|
|
126
|
+
.filter(line => !!line)
|
|
127
|
+
.join('\n');
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
/**
|
|
@@ -137,4 +138,4 @@ export class PackConfigUtil {
|
|
|
137
138
|
this.dockerEntrypoint(config)
|
|
138
139
|
].join('\n');
|
|
139
140
|
}
|
|
140
|
-
}
|
|
141
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type OutputOptions } from 'rollup';
|
|
2
1
|
import type terser from '@rollup/plugin-terser';
|
|
2
|
+
import type { OutputOptions } from 'rollup';
|
|
3
3
|
|
|
4
4
|
export type CommonPackConfig = {
|
|
5
5
|
buildDirectory: string;
|
|
@@ -59,10 +59,10 @@ export type ShellCommandProvider = {
|
|
|
59
59
|
comment(message: string): string[];
|
|
60
60
|
echo(text: string): string[];
|
|
61
61
|
zip(output: string): string[];
|
|
62
|
-
script(lines: string[], chdir?: boolean): { ext: string
|
|
62
|
+
script(lines: string[], chdir?: boolean): { ext: string; contents: string[] };
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
-
export type DockerPackFactory = (config: DockerPackConfig) =>
|
|
65
|
+
export type DockerPackFactory = (config: DockerPackConfig) => string | Promise<string>;
|
|
66
66
|
export type DockerPackFactoryModule = { factory: DockerPackFactory };
|
|
67
67
|
|
|
68
68
|
export type CoreRollupConfig = {
|
|
@@ -73,4 +73,4 @@ export type CoreRollupConfig = {
|
|
|
73
73
|
ignore: Set<string>;
|
|
74
74
|
external: string[];
|
|
75
75
|
minify: Parameters<typeof terser>[0];
|
|
76
|
-
};
|
|
76
|
+
};
|
|
@@ -1,46 +1,64 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
|
-
import { JSONUtil, Runtime } from '@travetto/runtime';
|
|
5
4
|
import { cliTpl } from '@travetto/cli';
|
|
5
|
+
import { JSONUtil, Runtime } from '@travetto/runtime';
|
|
6
6
|
|
|
7
|
-
import { ActiveShellCommand } from './shell.ts';
|
|
8
7
|
import type { DockerPackConfig, DockerPackFactoryModule } from '../../src/types.ts';
|
|
9
8
|
import { PackOperation } from './operation.ts';
|
|
9
|
+
import { ActiveShellCommand } from './shell.ts';
|
|
10
10
|
import { PackUtil } from './util.ts';
|
|
11
11
|
|
|
12
12
|
export class DockerPackOperation {
|
|
13
|
-
|
|
14
13
|
static getDockerTags(config: DockerPackConfig): string[] {
|
|
15
|
-
return (config.dockerTag ?? []).map(tag =>
|
|
14
|
+
return (config.dockerTag ?? []).map(tag =>
|
|
15
|
+
config.dockerRegistry ? `${config.dockerRegistry}/${config.dockerName}:${tag}` : `${config.dockerName}:${tag}`
|
|
16
|
+
);
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Detect image os
|
|
20
21
|
*/
|
|
21
|
-
static async*
|
|
22
|
+
static async *detectDockerImageOs(config: DockerPackConfig): AsyncIterable<string[]> {
|
|
22
23
|
// Read os before writing
|
|
23
|
-
config.dockerRuntime.os = await PackUtil.runCommand(
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
config.dockerRuntime.os = await PackUtil.runCommand([
|
|
25
|
+
'docker',
|
|
26
|
+
'run',
|
|
27
|
+
'--rm',
|
|
28
|
+
'--entrypoint',
|
|
29
|
+
'/bin/sh',
|
|
30
|
+
config.dockerImage,
|
|
31
|
+
'-c',
|
|
32
|
+
'cat /etc/*release*'
|
|
33
|
+
]).then(out => {
|
|
26
34
|
const found = out.toLowerCase().match(/\b(?:debian|alpine|centos)\b/)?.[0];
|
|
27
35
|
switch (found) {
|
|
28
|
-
case 'debian':
|
|
29
|
-
|
|
36
|
+
case 'debian':
|
|
37
|
+
case 'alpine':
|
|
38
|
+
case 'centos':
|
|
39
|
+
return found;
|
|
40
|
+
default:
|
|
41
|
+
return 'unknown';
|
|
30
42
|
}
|
|
31
43
|
});
|
|
32
|
-
yield* PackOperation.title(
|
|
44
|
+
yield* PackOperation.title(
|
|
45
|
+
config,
|
|
46
|
+
cliTpl`${{ title: 'Detected Image OS' }} ${{ param: config.dockerImage }} as ${{ param: config.dockerRuntime.os }}`
|
|
47
|
+
);
|
|
33
48
|
}
|
|
34
49
|
|
|
35
50
|
/**
|
|
36
51
|
* Write Docker File
|
|
37
52
|
*/
|
|
38
|
-
static async*
|
|
53
|
+
static async *writeDockerFile(config: DockerPackConfig): AsyncIterable<string[]> {
|
|
39
54
|
const dockerFile = path.resolve(config.buildDirectory, 'Dockerfile');
|
|
40
55
|
const { factory } = await Runtime.importFrom<DockerPackFactoryModule>(config.dockerFactory);
|
|
41
56
|
const content = (await factory(config)).trim();
|
|
42
57
|
|
|
43
|
-
yield* PackOperation.title(
|
|
58
|
+
yield* PackOperation.title(
|
|
59
|
+
config,
|
|
60
|
+
cliTpl`${{ title: 'Generating Docker File' }} ${{ path: dockerFile }} ${{ param: config.dockerFactory }}`
|
|
61
|
+
);
|
|
44
62
|
|
|
45
63
|
if (config.ejectFile) {
|
|
46
64
|
yield* ActiveShellCommand.createFile(dockerFile, content.split(/\n/));
|
|
@@ -52,7 +70,7 @@ export class DockerPackOperation {
|
|
|
52
70
|
/**
|
|
53
71
|
* Pull Docker Base Image
|
|
54
72
|
*/
|
|
55
|
-
static async*
|
|
73
|
+
static async *pullDockerBaseImage(config: DockerPackConfig): AsyncIterable<string[]> {
|
|
56
74
|
const command = ['docker', 'pull', config.dockerImage];
|
|
57
75
|
|
|
58
76
|
yield* PackOperation.title(config, cliTpl`${{ title: 'Pulling Docker Base Image' }} ${{ param: config.dockerImage }}`);
|
|
@@ -67,11 +85,13 @@ export class DockerPackOperation {
|
|
|
67
85
|
/**
|
|
68
86
|
* Building Docker Container
|
|
69
87
|
*/
|
|
70
|
-
static async*
|
|
88
|
+
static async *buildDockerContainer(config: DockerPackConfig): AsyncIterable<string[]> {
|
|
71
89
|
const cmd = [
|
|
72
|
-
'docker',
|
|
90
|
+
'docker',
|
|
91
|
+
'build',
|
|
73
92
|
...(config.dockerBuildPlatform ? ['--platform', config.dockerBuildPlatform] : []),
|
|
74
|
-
...DockerPackOperation.getDockerTags(config).flatMap(tag => ['-t', tag]),
|
|
93
|
+
...DockerPackOperation.getDockerTags(config).flatMap(tag => ['-t', tag]),
|
|
94
|
+
'.'
|
|
75
95
|
];
|
|
76
96
|
|
|
77
97
|
yield* PackOperation.title(config, cliTpl`${{ title: 'Building Docker Container' }} ${{ param: config.dockerTag?.join(',') }}`);
|
|
@@ -90,7 +110,7 @@ export class DockerPackOperation {
|
|
|
90
110
|
/**
|
|
91
111
|
* Push Docker Container
|
|
92
112
|
*/
|
|
93
|
-
static async*
|
|
113
|
+
static async *pushDockerContainer(config: DockerPackConfig): AsyncIterable<string[]> {
|
|
94
114
|
if (!config.dockerPush) {
|
|
95
115
|
return;
|
|
96
116
|
}
|
|
@@ -109,4 +129,4 @@ export class DockerPackOperation {
|
|
|
109
129
|
}
|
|
110
130
|
}
|
|
111
131
|
}
|
|
112
|
-
}
|
|
132
|
+
}
|
package/support/bin/operation.ts
CHANGED
|
@@ -2,18 +2,17 @@ import fs from 'node:fs/promises';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
4
|
import { cliTpl } from '@travetto/cli';
|
|
5
|
-
import {
|
|
5
|
+
import { Env, JSONUtil, Runtime, RuntimeIndex } from '@travetto/runtime';
|
|
6
6
|
|
|
7
7
|
import type { CommonPackConfig } from '../../src/types.ts';
|
|
8
|
-
import { PackUtil } from './util.ts';
|
|
9
8
|
import { ActiveShellCommand, ShellCommands } from './shell.ts';
|
|
9
|
+
import { PackUtil } from './util.ts';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* General pack operations
|
|
13
13
|
*/
|
|
14
14
|
export class PackOperation {
|
|
15
|
-
|
|
16
|
-
static async * title(config: CommonPackConfig, title: string): AsyncIterable<string[]> {
|
|
15
|
+
static async *title(config: CommonPackConfig, title: string): AsyncIterable<string[]> {
|
|
17
16
|
if (config.ejectFile) {
|
|
18
17
|
yield ActiveShellCommand.comment(title);
|
|
19
18
|
yield ActiveShellCommand.echo(title);
|
|
@@ -25,7 +24,7 @@ export class PackOperation {
|
|
|
25
24
|
/**
|
|
26
25
|
* Clean out pack workspace, removing all content
|
|
27
26
|
*/
|
|
28
|
-
static async *
|
|
27
|
+
static async *clean(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
29
28
|
if (!config.clean) {
|
|
30
29
|
return;
|
|
31
30
|
}
|
|
@@ -50,39 +49,47 @@ export class PackOperation {
|
|
|
50
49
|
/**
|
|
51
50
|
* Invoke bundler (rollup) to produce output in workspace folder
|
|
52
51
|
*/
|
|
53
|
-
static async *
|
|
52
|
+
static async *bundle(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
54
53
|
const cwd = RuntimeIndex.outputRoot;
|
|
55
54
|
const out = RuntimeIndex.manifest.build.outputFolder;
|
|
56
55
|
|
|
57
|
-
const bundleCommand = [
|
|
56
|
+
const bundleCommand = [
|
|
57
|
+
process.argv0,
|
|
58
|
+
RuntimeIndex.resolvePackageCommand('rollup'),
|
|
59
|
+
'-c',
|
|
60
|
+
RuntimeIndex.resolveFileImport(config.rollupConfiguration)
|
|
61
|
+
];
|
|
58
62
|
|
|
59
63
|
const entryPointFile = RuntimeIndex.getFromImport(config.entryPoint)!.outputFile.split(`${out}/`)[1];
|
|
60
64
|
|
|
61
65
|
const env = {
|
|
62
|
-
...Object.fromEntries(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
66
|
+
...Object.fromEntries(
|
|
67
|
+
(
|
|
68
|
+
[
|
|
69
|
+
['BUNDLE_ENTRY', entryPointFile],
|
|
70
|
+
['BUNDLE_MAIN_FILE', config.mainFile],
|
|
71
|
+
['BUNDLE_COMPRESS', config.minify],
|
|
72
|
+
['BUNDLE_SOURCEMAP', config.sourcemap],
|
|
73
|
+
['BUNDLE_SOURCES', config.includeSources],
|
|
74
|
+
['BUNDLE_OUTPUT', config.buildDirectory],
|
|
75
|
+
['BUNDLE_ENV_FILE', config.envFile],
|
|
76
|
+
['BUNDLE_EXTERNAL', config.externalDependencies.map(module => module.split(':')[0]).join(',')]
|
|
77
|
+
] as const
|
|
78
|
+
)
|
|
79
|
+
.filter(pair => pair[1] === false || pair[1])
|
|
80
|
+
.map(pair => [pair[0], `${pair[1]}`])
|
|
74
81
|
),
|
|
75
|
-
...Env.TRV_MANIFEST.export(RuntimeIndex.getModule(config.module)!.outputPath)
|
|
82
|
+
...Env.TRV_MANIFEST.export(RuntimeIndex.getModule(config.module)!.outputPath)
|
|
76
83
|
};
|
|
77
84
|
|
|
78
85
|
const properties = (['minify', 'sourcemap', 'entryPoint'] as const)
|
|
79
|
-
.map(key => cliTpl`${{ subtitle: key }}=${{ param: config[key] }}`)
|
|
86
|
+
.map(key => cliTpl`${{ subtitle: key }}=${{ param: config[key] }}`)
|
|
87
|
+
.join(' ');
|
|
80
88
|
|
|
81
89
|
yield* PackOperation.title(config, cliTpl`${{ title: 'Bundling Output' }} ${properties}`);
|
|
82
90
|
|
|
83
91
|
if (config.ejectFile) {
|
|
84
|
-
yield* Object
|
|
85
|
-
.entries(env)
|
|
92
|
+
yield* Object.entries(env)
|
|
86
93
|
.filter(pair => !!pair[1])
|
|
87
94
|
.map(pair => ActiveShellCommand.export(pair[0], pair[1]));
|
|
88
95
|
yield ActiveShellCommand.chdir(cwd);
|
|
@@ -98,29 +105,23 @@ export class PackOperation {
|
|
|
98
105
|
/**
|
|
99
106
|
* Write out package.json, to help define how output .js file should be interpreted
|
|
100
107
|
*/
|
|
101
|
-
static async *
|
|
108
|
+
static async *writePackageJson(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
102
109
|
const file = 'package.json';
|
|
103
110
|
const pkg = { type: 'module', main: config.mainFile };
|
|
104
111
|
|
|
105
112
|
yield* PackOperation.title(config, cliTpl`${{ title: 'Writing' }} ${{ path: file }}`);
|
|
106
113
|
|
|
107
114
|
if (config.ejectFile) {
|
|
108
|
-
yield* ActiveShellCommand.createFile(
|
|
109
|
-
path.resolve(config.buildDirectory, file),
|
|
110
|
-
[JSONUtil.toUTF8(pkg)]
|
|
111
|
-
);
|
|
115
|
+
yield* ActiveShellCommand.createFile(path.resolve(config.buildDirectory, file), [JSONUtil.toUTF8(pkg)]);
|
|
112
116
|
} else {
|
|
113
|
-
await PackUtil.writeRawFile(
|
|
114
|
-
path.resolve(config.buildDirectory, file),
|
|
115
|
-
[JSONUtil.toUTF8Pretty(pkg)]
|
|
116
|
-
);
|
|
117
|
+
await PackUtil.writeRawFile(path.resolve(config.buildDirectory, file), [JSONUtil.toUTF8Pretty(pkg)]);
|
|
117
118
|
}
|
|
118
119
|
}
|
|
119
120
|
|
|
120
121
|
/**
|
|
121
122
|
* Define .env.js file to control manifest location
|
|
122
123
|
*/
|
|
123
|
-
static async *
|
|
124
|
+
static async *writeEnv(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
124
125
|
const file = path.resolve(config.buildDirectory, config.envFile);
|
|
125
126
|
const env = {
|
|
126
127
|
...Env.NODE_ENV.export('production'),
|
|
@@ -129,40 +130,34 @@ export class PackOperation {
|
|
|
129
130
|
...Env.TRV_CLI_IPC.export(undefined),
|
|
130
131
|
...Env.TRV_RESOURCE_OVERRIDES.export({
|
|
131
132
|
'@#resources': '@@#resources',
|
|
132
|
-
...(config.includeWorkspaceResources
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
...(config.includeWorkspaceResources
|
|
134
|
+
? {
|
|
135
|
+
'@@#resources': `@@#${config.workspaceResourceFolder}`
|
|
136
|
+
}
|
|
137
|
+
: {})
|
|
135
138
|
})
|
|
136
139
|
};
|
|
137
140
|
|
|
138
141
|
yield* PackOperation.title(config, cliTpl`${{ title: 'Writing' }} ${{ path: file }}`);
|
|
139
142
|
|
|
140
143
|
if (config.ejectFile) {
|
|
141
|
-
yield* ActiveShellCommand.createFile(
|
|
142
|
-
path.resolve(config.buildDirectory, file),
|
|
143
|
-
PackUtil.buildEnvFile(env)
|
|
144
|
-
);
|
|
144
|
+
yield* ActiveShellCommand.createFile(path.resolve(config.buildDirectory, file), PackUtil.buildEnvFile(env));
|
|
145
145
|
} else {
|
|
146
|
-
await PackUtil.writeRawFile(
|
|
147
|
-
path.resolve(config.buildDirectory, file),
|
|
148
|
-
PackUtil.buildEnvFile(env)
|
|
149
|
-
);
|
|
146
|
+
await PackUtil.writeRawFile(path.resolve(config.buildDirectory, file), PackUtil.buildEnvFile(env));
|
|
150
147
|
}
|
|
151
148
|
}
|
|
152
149
|
|
|
153
150
|
/**
|
|
154
151
|
* Create launcher scripts (.sh, .cmd) to run output
|
|
155
152
|
*/
|
|
156
|
-
static async *
|
|
153
|
+
static async *writeEntryScript(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
157
154
|
if (!config.mainScripts && !config.entryPoint.includes('@travetto/cli')) {
|
|
158
155
|
return;
|
|
159
156
|
}
|
|
160
157
|
|
|
161
158
|
const title = 'Writing entry scripts';
|
|
162
159
|
for (const sh of [ShellCommands.posix, ShellCommands.win32]) {
|
|
163
|
-
const { ext, contents } = sh.script(
|
|
164
|
-
sh.callCommandWithAllArgs('node', config.mainFile, ...config.entryArguments), true
|
|
165
|
-
);
|
|
160
|
+
const { ext, contents } = sh.script(sh.callCommandWithAllArgs('node', config.mainFile, ...config.entryArguments), true);
|
|
166
161
|
const file = `${config.mainName}${ext}`;
|
|
167
162
|
const args = config.entryArguments.join(' ');
|
|
168
163
|
|
|
@@ -170,7 +165,6 @@ export class PackOperation {
|
|
|
170
165
|
|
|
171
166
|
if (config.ejectFile) {
|
|
172
167
|
yield* ActiveShellCommand.createFile(path.resolve(config.buildDirectory, file), contents, '755');
|
|
173
|
-
|
|
174
168
|
} else {
|
|
175
169
|
await PackUtil.writeRawFile(path.resolve(config.buildDirectory, file), contents, '755');
|
|
176
170
|
}
|
|
@@ -180,7 +174,7 @@ export class PackOperation {
|
|
|
180
174
|
/**
|
|
181
175
|
* Copy over repo /resources folder into workspace, will get packaged into final output
|
|
182
176
|
*/
|
|
183
|
-
static async *
|
|
177
|
+
static async *copyMonoRepoResources(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
184
178
|
if (!config.includeWorkspaceResources) {
|
|
185
179
|
return;
|
|
186
180
|
}
|
|
@@ -200,7 +194,7 @@ export class PackOperation {
|
|
|
200
194
|
/**
|
|
201
195
|
* Copy over /resources folder into workspace, will get packaged into final output
|
|
202
196
|
*/
|
|
203
|
-
static async *
|
|
197
|
+
static async *copyResources(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
204
198
|
const resources = {
|
|
205
199
|
count: RuntimeIndex.mainModule.files.resources?.length ?? 0,
|
|
206
200
|
sourceDirectory: path.resolve(Runtime.mainSourcePath, 'resources'),
|
|
@@ -223,7 +217,7 @@ export class PackOperation {
|
|
|
223
217
|
/**
|
|
224
218
|
* Produce the output manifest, only including production dependencies
|
|
225
219
|
*/
|
|
226
|
-
static async *
|
|
220
|
+
static async *writeManifest(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
227
221
|
const out = path.resolve(config.buildDirectory, config.manifestFile);
|
|
228
222
|
const cmd = [process.argv0, RuntimeIndex.resolvePackageCommand('trvc'), 'manifest:production', out];
|
|
229
223
|
const env = { ...Env.TRV_MODULE.export(config.module) };
|
|
@@ -240,8 +234,7 @@ export class PackOperation {
|
|
|
240
234
|
/**
|
|
241
235
|
* Generate ZIP file for workspace
|
|
242
236
|
*/
|
|
243
|
-
static async *
|
|
244
|
-
|
|
237
|
+
static async *compress(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
245
238
|
yield* PackOperation.title(config, cliTpl`${{ title: 'Compressing' }} ${{ path: config.output }}`);
|
|
246
239
|
|
|
247
240
|
if (config.ejectFile) {
|
|
@@ -254,4 +247,4 @@ export class PackOperation {
|
|
|
254
247
|
await PackUtil.runCommand(ActiveShellCommand.zip(config.output), { cwd: config.buildDirectory });
|
|
255
248
|
}
|
|
256
249
|
}
|
|
257
|
-
}
|
|
250
|
+
}
|
package/support/bin/preamble.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { readFileSync as readSyncPreamble } from 'node:fs';
|
|
2
2
|
|
|
3
3
|
// @ts-expect-error -- Lock to prevent __proto__ pollution in JSON
|
|
4
|
+
// biome-ignore lint/suspicious/noProto: Lock to prevent __proto__ pollution in JSON
|
|
4
5
|
const objectProto = Object.prototype.__proto__;
|
|
5
6
|
Object.defineProperty(Object.prototype, '__proto__', {
|
|
6
|
-
get() {
|
|
7
|
-
|
|
7
|
+
get() {
|
|
8
|
+
return objectProto;
|
|
9
|
+
},
|
|
10
|
+
set(value) {
|
|
11
|
+
Object.setPrototypeOf(this, value);
|
|
12
|
+
}
|
|
8
13
|
});
|
|
9
14
|
|
|
10
15
|
if (!process.env.TRV_MODULE && '%%ENV_FILE%%') {
|
|
@@ -13,6 +18,8 @@ if (!process.env.TRV_MODULE && '%%ENV_FILE%%') {
|
|
|
13
18
|
.split('\n')
|
|
14
19
|
.map(line => line.match(/\s*(?<key>[^ =]+)\s*=\s*(?<value>\S+)/)?.groups)
|
|
15
20
|
.filter(pair => !!pair)
|
|
16
|
-
.forEach(pair =>
|
|
17
|
-
|
|
18
|
-
}
|
|
21
|
+
.forEach(pair => {
|
|
22
|
+
process.env[pair.key] = pair.value;
|
|
23
|
+
});
|
|
24
|
+
} catch {}
|
|
25
|
+
}
|
package/support/bin/shell.ts
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
import util from 'node:util';
|
|
2
1
|
import path from 'node:path';
|
|
2
|
+
import util from 'node:util';
|
|
3
3
|
|
|
4
4
|
import type { ShellCommandProvider } from '../../src/types.ts';
|
|
5
5
|
|
|
6
|
-
const
|
|
7
|
-
text
|
|
8
|
-
.replaceAll('"', '\\"')
|
|
9
|
-
.replaceAll('$', '\\$');
|
|
6
|
+
const shellEscape = (text: string): string => text.replaceAll('"', '\\"').replaceAll('$', '\\$');
|
|
10
7
|
|
|
11
|
-
const escapedArgs = (args: string[]): string[] =>
|
|
12
|
-
arg.includes(' ') || arg.includes('"') ? `'${arg}'` :
|
|
13
|
-
);
|
|
8
|
+
const escapedArgs = (args: string[]): string[] =>
|
|
9
|
+
args.map(arg => (arg.includes(' ') || arg.includes('"') ? `'${arg}'` : arg.includes("'") ? `"${arg}"` : arg));
|
|
14
10
|
|
|
15
|
-
const toWin = (file: string): string => file.replace(/[
|
|
11
|
+
const toWin = (file: string): string => file.replace(/[/\\]+/g, path.win32.sep);
|
|
16
12
|
|
|
17
13
|
export const ShellCommands: Record<'win32' | 'posix', ShellCommandProvider> = {
|
|
18
14
|
win32: {
|
|
@@ -20,55 +16,56 @@ export const ShellCommands: Record<'win32' | 'posix', ShellCommandProvider> = {
|
|
|
20
16
|
callCommandWithAllArgs: (cmd, ...args) => [[cmd, ...escapedArgs(args), '%*'].join(' ')],
|
|
21
17
|
createFile: (file, text) => [
|
|
22
18
|
['@echo', 'off'],
|
|
23
|
-
...text.map((line, i) =>
|
|
24
|
-
['echo', `"${escape(line)}"`, i === 0 ? '>' : '>>', file]
|
|
25
|
-
)
|
|
19
|
+
...text.map((line, i) => ['echo', `"${shellEscape(line)}"`, i === 0 ? '>' : '>>', file])
|
|
26
20
|
],
|
|
27
21
|
copy: (sourceFile, destinationFile) => ['copy', sourceFile, destinationFile],
|
|
28
|
-
copyRecursive: (sourceDirectory, destinationDirectory, inclusive) =>
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
22
|
+
copyRecursive: (sourceDirectory, destinationDirectory, inclusive) => [
|
|
23
|
+
'xcopy',
|
|
24
|
+
'/y',
|
|
25
|
+
'/h',
|
|
26
|
+
'/s',
|
|
27
|
+
inclusive ? `${toWin(sourceDirectory)}\\*.*` : toWin(sourceDirectory),
|
|
28
|
+
toWin(destinationDirectory)
|
|
29
|
+
],
|
|
30
|
+
rmRecursive: destinationDirectory => ['rmdir', '/Q', '/S', destinationDirectory],
|
|
31
|
+
mkdir: destinationDirectory => ['md', destinationDirectory],
|
|
32
32
|
export: (key, value) => ['set', `${key}=${value}`],
|
|
33
|
-
chdir:
|
|
34
|
-
comment:
|
|
35
|
-
echo:
|
|
36
|
-
zip:
|
|
33
|
+
chdir: destinationDirectory => ['cd', destinationDirectory],
|
|
34
|
+
comment: message => ['\nREM', util.stripVTControlCharacters(message), '\n'],
|
|
35
|
+
echo: message => ['echo', `"${shellEscape(util.stripVTControlCharacters(message))}"\n`],
|
|
36
|
+
zip: outputFile => ['powershell', 'Compress-Archive', '-Path', '.', '-DestinationPath', outputFile],
|
|
37
37
|
script: (lines: string[], changeDirectory: boolean = false) => ({
|
|
38
38
|
ext: '.cmd',
|
|
39
|
-
contents: [
|
|
40
|
-
...(changeDirectory ? ['cd %~p0'] : []),
|
|
41
|
-
...lines,
|
|
42
|
-
]
|
|
39
|
+
contents: [...(changeDirectory ? ['cd %~p0'] : []), ...lines]
|
|
43
40
|
})
|
|
44
41
|
},
|
|
45
42
|
posix: {
|
|
46
43
|
var: (name: string) => `$${name}`,
|
|
47
44
|
callCommandWithAllArgs: (cmd, ...args) => [[cmd, ...escapedArgs(args), '$@'].join(' ')],
|
|
48
45
|
createFile: (file, text, mode) => [
|
|
49
|
-
...text.map((line, i) =>
|
|
50
|
-
['echo', `"${escape(line)}"`, i === 0 ? '>' : '>>', file]),
|
|
46
|
+
...text.map((line, i) => ['echo', `"${shellEscape(line)}"`, i === 0 ? '>' : '>>', file]),
|
|
51
47
|
...(mode ? [['chmod', mode, file]] : [])
|
|
52
48
|
],
|
|
53
49
|
copy: (sourceFile, destinationFile) => ['cp', sourceFile, destinationFile],
|
|
54
|
-
copyRecursive: (sourceDirectory, destinationDirectory, inclusive) =>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
50
|
+
copyRecursive: (sourceDirectory, destinationDirectory, inclusive) => [
|
|
51
|
+
'cp',
|
|
52
|
+
'-r',
|
|
53
|
+
'-p',
|
|
54
|
+
inclusive ? `${sourceDirectory}/*` : sourceDirectory,
|
|
55
|
+
destinationDirectory
|
|
56
|
+
],
|
|
57
|
+
rmRecursive: destinationDirectory => ['rm', '-rf', destinationDirectory],
|
|
58
|
+
mkdir: destinationDirectory => ['mkdir', '-p', destinationDirectory],
|
|
58
59
|
export: (key, value) => ['export', `${key}=${value}`],
|
|
59
|
-
chdir:
|
|
60
|
-
comment:
|
|
61
|
-
echo:
|
|
62
|
-
zip:
|
|
60
|
+
chdir: destinationDirectory => ['cd', destinationDirectory],
|
|
61
|
+
comment: message => ['\n#', util.stripVTControlCharacters(message), '\n'],
|
|
62
|
+
echo: message => ['echo', `"${shellEscape(util.stripVTControlCharacters(message))}"\n`],
|
|
63
|
+
zip: outputFile => ['zip', '-r', outputFile, '.'],
|
|
63
64
|
script: (lines: string[], changeDirectory: boolean = false) => ({
|
|
64
65
|
ext: '.sh',
|
|
65
|
-
contents: [
|
|
66
|
-
'#!/bin/sh',
|
|
67
|
-
...(changeDirectory ? ['cd $(dirname "$0")'] : []),
|
|
68
|
-
...lines,
|
|
69
|
-
]
|
|
66
|
+
contents: ['#!/bin/sh', ...(changeDirectory ? ['cd $(dirname "$0")'] : []), ...lines]
|
|
70
67
|
})
|
|
71
|
-
}
|
|
68
|
+
}
|
|
72
69
|
};
|
|
73
70
|
|
|
74
|
-
export const ActiveShellCommand = ShellCommands[process.platform === 'win32' ? 'win32' : 'posix'];
|
|
71
|
+
export const ActiveShellCommand = ShellCommands[process.platform === 'win32' ? 'win32' : 'posix'];
|
package/support/bin/util.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { type SpawnOptions, spawn } from 'node:child_process';
|
|
1
2
|
import fs from 'node:fs/promises';
|
|
2
|
-
import { spawn, type SpawnOptions } from 'node:child_process';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { ExecUtil, Runtime, RuntimeError, RuntimeIndex } from '@travetto/runtime';
|
|
6
6
|
|
|
7
7
|
import { ActiveShellCommand } from './shell.ts';
|
|
8
8
|
|
|
@@ -12,7 +12,7 @@ export class PackUtil {
|
|
|
12
12
|
*/
|
|
13
13
|
static buildEnvFile(env: Record<string, string | number | boolean | undefined>): string[] {
|
|
14
14
|
return Object.entries(env)
|
|
15
|
-
.filter(([, value]) =>
|
|
15
|
+
.filter(([, value]) => value !== undefined)
|
|
16
16
|
.map(([key, value]) => `${key}=${value}`);
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -21,7 +21,12 @@ export class PackUtil {
|
|
|
21
21
|
* @param sourceDirectory The folder to copy
|
|
22
22
|
* @param destinationDirectory The folder to copy to
|
|
23
23
|
*/
|
|
24
|
-
static async copyRecursive(
|
|
24
|
+
static async copyRecursive(
|
|
25
|
+
sourceDirectory: string,
|
|
26
|
+
destinationDirectory: string,
|
|
27
|
+
inclusive: boolean = false,
|
|
28
|
+
ignoreFailure = false
|
|
29
|
+
): Promise<void> {
|
|
25
30
|
try {
|
|
26
31
|
let final = destinationDirectory;
|
|
27
32
|
if (!inclusive) {
|
|
@@ -43,11 +48,11 @@ export class PackUtil {
|
|
|
43
48
|
const repoRoot = Runtime.workspaceRelative('.');
|
|
44
49
|
const vars = { ROOT: path.resolve(), TRV_OUT: RuntimeIndex.outputRoot, REPO_ROOT: repoRoot, DIST: workspace, MODULE: module };
|
|
45
50
|
|
|
46
|
-
const replaceArgs = (text: string): string =>
|
|
47
|
-
.reduce((result, [key, value]) => result.replaceAll(value, ActiveShellCommand.var(key)), text);
|
|
51
|
+
const replaceArgs = (text: string): string =>
|
|
52
|
+
Object.entries(vars).reduce((result, [key, value]) => result.replaceAll(value, ActiveShellCommand.var(key)), text);
|
|
48
53
|
|
|
49
54
|
const preamble = ActiveShellCommand.script(
|
|
50
|
-
Object.entries(vars).map(([key, value]) => ActiveShellCommand.export(key, value).join(' '))
|
|
55
|
+
Object.entries(vars).map(([key, value]) => ActiveShellCommand.export(key, value).join(' '))
|
|
51
56
|
).contents;
|
|
52
57
|
|
|
53
58
|
let stream: fs.FileHandle | undefined;
|
|
@@ -58,7 +63,7 @@ export class PackUtil {
|
|
|
58
63
|
stream = await fs.open(file, 'w', 0o755);
|
|
59
64
|
}
|
|
60
65
|
|
|
61
|
-
const write = (text: string): Promise<unknown> | unknown => stream ? stream.write(`${text}\n`) : process.stdout.write(`${text}\n`);
|
|
66
|
+
const write = (text: string): Promise<unknown> | unknown => (stream ? stream.write(`${text}\n`) : process.stdout.write(`${text}\n`));
|
|
62
67
|
|
|
63
68
|
for (const line of preamble) {
|
|
64
69
|
write(line);
|
|
@@ -75,10 +80,13 @@ export class PackUtil {
|
|
|
75
80
|
* Track result response
|
|
76
81
|
*/
|
|
77
82
|
static async runCommand(cmd: string[], options: SpawnOptions = {}): Promise<string> {
|
|
78
|
-
const { valid, code, stderr, message, stdout } = await ExecUtil.getResult(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
const { valid, code, stderr, message, stdout } = await ExecUtil.getResult(
|
|
84
|
+
spawn(cmd[0], cmd.slice(1), {
|
|
85
|
+
stdio: [0, 'pipe', 'pipe'],
|
|
86
|
+
...options
|
|
87
|
+
}),
|
|
88
|
+
{ catch: true }
|
|
89
|
+
);
|
|
82
90
|
|
|
83
91
|
if (!valid) {
|
|
84
92
|
process.exitCode = code;
|
|
@@ -93,4 +101,4 @@ export class PackUtil {
|
|
|
93
101
|
static async writeRawFile(file: string, contents: string[], mode?: string): Promise<void> {
|
|
94
102
|
await fs.writeFile(file, contents.join('\n'), { encoding: 'utf8', mode });
|
|
95
103
|
}
|
|
96
|
-
}
|
|
104
|
+
}
|
package/support/cli.pack.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
|
|
3
|
-
import { RuntimeIndex } from '@travetto/runtime';
|
|
4
3
|
import { CliCommand, CliFlag, CliUtil } from '@travetto/cli';
|
|
4
|
+
import { RuntimeIndex } from '@travetto/runtime';
|
|
5
5
|
import { Ignore, Max, Min, Required } from '@travetto/schema';
|
|
6
6
|
|
|
7
|
+
import type { DockerPackConfig } from '../src/types.ts';
|
|
7
8
|
import { DockerPackOperation } from './bin/docker-operation.ts';
|
|
8
9
|
import { BasePackCommand, type PackOperationShape } from './pack.base.ts';
|
|
9
|
-
import type { DockerPackConfig } from '../src/types.ts';
|
|
10
10
|
|
|
11
11
|
const NODE_MAJOR = process.version.match(/\d+/)?.[0] ?? '22';
|
|
12
|
-
const asNumber = (input?: string): number | undefined => (!input || isNaN(+input)
|
|
13
|
-
const asString = (input?: string): string | undefined => (input && asNumber(input)
|
|
12
|
+
const asNumber = (input?: string): number | undefined => (!input || Number.isNaN(+input) ? undefined : +input);
|
|
13
|
+
const asString = (input?: string): string | undefined => (input && asNumber(input) ? input : undefined);
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Build container-ready artifacts and optionally publish Docker images.
|
|
@@ -38,7 +38,8 @@ export class PackDockerCommand extends BasePackCommand {
|
|
|
38
38
|
dockerRuntimePackages: string[] = [];
|
|
39
39
|
/** Docker Image Port */
|
|
40
40
|
@CliFlag({ short: 'dp', envVars: ['PACK_DOCKER_PORT'] })
|
|
41
|
-
@Min(1)
|
|
41
|
+
@Min(1)
|
|
42
|
+
@Max(65536)
|
|
42
43
|
dockerPort: number[] = [];
|
|
43
44
|
|
|
44
45
|
// Publish flags
|
|
@@ -113,10 +114,7 @@ export class PackDockerCommand extends BasePackCommand {
|
|
|
113
114
|
DockerPackOperation.pullDockerBaseImage,
|
|
114
115
|
DockerPackOperation.detectDockerImageOs,
|
|
115
116
|
DockerPackOperation.writeDockerFile,
|
|
116
|
-
...this.dockerStageOnly ? [] : [
|
|
117
|
-
DockerPackOperation.buildDockerContainer,
|
|
118
|
-
DockerPackOperation.pushDockerContainer
|
|
119
|
-
]
|
|
117
|
+
...(this.dockerStageOnly ? [] : [DockerPackOperation.buildDockerContainer, DockerPackOperation.pushDockerContainer])
|
|
120
118
|
];
|
|
121
119
|
}
|
|
122
|
-
}
|
|
120
|
+
}
|
package/support/cli.pack_zip.ts
CHANGED
|
@@ -11,7 +11,6 @@ import { BasePackCommand, type PackOperationShape } from './pack.base.ts';
|
|
|
11
11
|
*/
|
|
12
12
|
@CliCommand()
|
|
13
13
|
export class PackZipCommand extends BasePackCommand {
|
|
14
|
-
|
|
15
14
|
finalize(forHelp?: boolean): void {
|
|
16
15
|
if (forHelp) {
|
|
17
16
|
this.output = '<module>.zip';
|
|
@@ -20,9 +19,6 @@ export class PackZipCommand extends BasePackCommand {
|
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
getOperations(): PackOperationShape<this>[] {
|
|
23
|
-
return [
|
|
24
|
-
...super.getOperations(),
|
|
25
|
-
PackOperation.compress
|
|
26
|
-
];
|
|
22
|
+
return [...super.getOperations(), PackOperation.compress];
|
|
27
23
|
}
|
|
28
|
-
}
|
|
24
|
+
}
|
package/support/pack.base.ts
CHANGED
|
@@ -2,31 +2,29 @@ import os from 'node:os';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
4
|
import { type CliCommandShape, CliFlag, CliModuleFlag, CliParseUtil, cliTpl } from '@travetto/cli';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { type IndexedModule, PackageUtil } from '@travetto/manifest';
|
|
6
|
+
import { Runtime, RuntimeIndex, TimeUtil } from '@travetto/runtime';
|
|
7
7
|
import { Ignore, Method, Required, Schema } from '@travetto/schema';
|
|
8
|
-
import {
|
|
8
|
+
import { Terminal } from '@travetto/terminal';
|
|
9
9
|
|
|
10
10
|
import { PackOperation } from './bin/operation.ts';
|
|
11
11
|
import { PackUtil } from './bin/util.ts';
|
|
12
12
|
|
|
13
|
-
export type PackOperationShape<T> = (
|
|
13
|
+
export type PackOperationShape<T> = (config: T) => AsyncIterable<string[]>;
|
|
14
14
|
|
|
15
15
|
@Schema()
|
|
16
16
|
export abstract class BasePackCommand implements CliCommandShape {
|
|
17
|
-
|
|
18
17
|
static get entryPoints(): string[] {
|
|
19
18
|
return RuntimeIndex.find({
|
|
20
19
|
module: module => module.production,
|
|
21
20
|
folder: folder => folder === 'support',
|
|
22
21
|
file: file => file.sourceFile.includes('entry.')
|
|
23
|
-
})
|
|
24
|
-
.map(file => file.import.replace(/[.][^.]+s$/, ''));
|
|
22
|
+
}).map(file => file.import.replace(/[.][^.]+s$/, ''));
|
|
25
23
|
}
|
|
26
24
|
|
|
27
25
|
/** Workspace for building */
|
|
28
26
|
@CliFlag({ short: 'b', full: 'buildDir' })
|
|
29
|
-
buildDirectory: string = path.resolve(os.tmpdir(), Runtime.mainSourcePath.replace(/[
|
|
27
|
+
buildDirectory: string = path.resolve(os.tmpdir(), Runtime.mainSourcePath.replace(/[/\\: ]/g, '_'));
|
|
30
28
|
|
|
31
29
|
/** Clean workspace */
|
|
32
30
|
clean = true;
|
|
@@ -105,14 +103,14 @@ export abstract class BasePackCommand implements CliCommandShape {
|
|
|
105
103
|
PackOperation.copyMonoRepoResources,
|
|
106
104
|
PackOperation.copyResources,
|
|
107
105
|
PackOperation.writeManifest,
|
|
108
|
-
PackOperation.bundle
|
|
106
|
+
PackOperation.bundle
|
|
109
107
|
];
|
|
110
108
|
}
|
|
111
109
|
|
|
112
110
|
/**
|
|
113
111
|
* Run all operations
|
|
114
112
|
*/
|
|
115
|
-
async *
|
|
113
|
+
async *runOperations(): AsyncIterable<string> {
|
|
116
114
|
for (const operation of this.getOperations()) {
|
|
117
115
|
for await (const message of operation(this)) {
|
|
118
116
|
yield message.join(' ');
|
|
@@ -128,8 +126,7 @@ export abstract class BasePackCommand implements CliCommandShape {
|
|
|
128
126
|
.map(name => RuntimeIndex.getModule(name))
|
|
129
127
|
.filter((module): module is IndexedModule => !!module?.production)
|
|
130
128
|
.map(module => PackageUtil.readPackage(module?.sourcePath))
|
|
131
|
-
.
|
|
132
|
-
.flat();
|
|
129
|
+
.flatMap(pkg => pkg?.travetto?.build?.externalDependencies ?? []);
|
|
133
130
|
}
|
|
134
131
|
|
|
135
132
|
@Method()
|
|
@@ -141,7 +138,7 @@ export abstract class BasePackCommand implements CliCommandShape {
|
|
|
141
138
|
|
|
142
139
|
// Update entry points
|
|
143
140
|
const parsed = CliParseUtil.getState(this);
|
|
144
|
-
this.entryArguments = [...this.entryArguments ?? [], ...args, ...parsed?.unknown ?? []];
|
|
141
|
+
this.entryArguments = [...(this.entryArguments ?? []), ...args, ...(parsed?.unknown ?? [])];
|
|
145
142
|
this.module ||= Runtime.main.name;
|
|
146
143
|
this.mainName ??= path.basename(this.module);
|
|
147
144
|
this.mainFile = `${this.mainName}.js`;
|
|
@@ -168,4 +165,4 @@ export abstract class BasePackCommand implements CliCommandShape {
|
|
|
168
165
|
await term.writer.writeLine(message).commit();
|
|
169
166
|
}
|
|
170
167
|
}
|
|
171
|
-
}
|
|
168
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DockerPackFactory } from '../src/types.ts';
|
|
2
1
|
import { PackConfigUtil } from '../src/config-util.ts';
|
|
2
|
+
import type { DockerPackFactory } from '../src/types.ts';
|
|
3
3
|
|
|
4
|
-
export const factory: DockerPackFactory = config => PackConfigUtil.dockerStandardFile(config);
|
|
4
|
+
export const factory: DockerPackFactory = config => PackConfigUtil.dockerStandardFile(config);
|
package/support/rollup/build.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import commonjsRequire from '@rollup/plugin-commonjs';
|
|
2
|
+
import jsonImport from '@rollup/plugin-json';
|
|
2
3
|
import nodeResolve from '@rollup/plugin-node-resolve';
|
|
3
4
|
import terser from '@rollup/plugin-terser';
|
|
4
|
-
import jsonImport from '@rollup/plugin-json';
|
|
5
5
|
import type { RollupOptions } from 'rollup';
|
|
6
6
|
|
|
7
7
|
import { getCoreConfig } from './config.ts';
|
|
8
|
+
import { travettoEntryPlugin } from './rollup-travetto-entry.ts';
|
|
8
9
|
import { travettoImportPlugin } from './rollup-travetto-import.ts';
|
|
9
10
|
import { travettoSourcemaps } from './rollup-travetto-sourcemaps.ts';
|
|
10
|
-
import { travettoEntryPlugin } from './rollup-travetto-entry.ts';
|
|
11
11
|
|
|
12
12
|
export default function buildConfig(): RollupOptions {
|
|
13
13
|
// Load up if not defined
|
|
@@ -27,4 +27,4 @@ export default function buildConfig(): RollupOptions {
|
|
|
27
27
|
...(config.output.compact ? [terser(config.minify)] : [])
|
|
28
28
|
]
|
|
29
29
|
};
|
|
30
|
-
}
|
|
30
|
+
}
|
package/support/rollup/config.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
|
|
3
|
-
import type { OutputOptions } from 'rollup';
|
|
4
3
|
import type terser from '@rollup/plugin-terser';
|
|
4
|
+
import type { OutputOptions } from 'rollup';
|
|
5
5
|
|
|
6
6
|
import { type ManifestModule, ManifestModuleUtil } from '@travetto/manifest';
|
|
7
7
|
import { EnvProp, Runtime, RuntimeIndex } from '@travetto/runtime';
|
|
@@ -10,11 +10,10 @@ import type { CoreRollupConfig } from '../../src/types.ts';
|
|
|
10
10
|
|
|
11
11
|
function getFilesFromModule(module: ManifestModule): string[] {
|
|
12
12
|
return [
|
|
13
|
-
...module.files.$index ?? [],
|
|
14
|
-
...module.files.src ?? [],
|
|
13
|
+
...(module.files.$index ?? []),
|
|
14
|
+
...(module.files.src ?? []),
|
|
15
15
|
...(module.files.bin ?? []).filter(file => !(/bin\/trv[.]js$/.test(file[0]) && module.name === '@travetto/cli')),
|
|
16
|
-
...(module.files.support ?? [])
|
|
17
|
-
.filter(file => !/support\/(test|doc|pack)/.test(file[0]))
|
|
16
|
+
...(module.files.support ?? []).filter(file => !/support\/(test|doc|pack)/.test(file[0]))
|
|
18
17
|
]
|
|
19
18
|
.filter(([, type]) => type === 'ts' || type === 'js' || type === 'json')
|
|
20
19
|
.filter(([, , , role]) => (role ?? 'std') === 'std') // Only include standard files
|
|
@@ -26,8 +25,7 @@ export function getOutput(): OutputOptions {
|
|
|
26
25
|
const mainFile = process.env.BUNDLE_MAIN_FILE!;
|
|
27
26
|
return {
|
|
28
27
|
format: 'module',
|
|
29
|
-
sourcemapPathTransform: (source, map): string =>
|
|
30
|
-
Runtime.stripWorkspacePath(path.resolve(path.dirname(map), source)),
|
|
28
|
+
sourcemapPathTransform: (source, map): string => Runtime.stripWorkspacePath(path.resolve(path.dirname(map), source)),
|
|
31
29
|
sourcemap: new EnvProp('BUNDLE_SOURCEMAP').bool ?? false,
|
|
32
30
|
sourcemapExcludeSources: !(new EnvProp('BUNDLE_SOURCES').bool ?? false),
|
|
33
31
|
compact: new EnvProp('BUNDLE_COMPRESS').bool ?? true,
|
|
@@ -49,9 +47,7 @@ export function getFiles(entry?: string): string[] {
|
|
|
49
47
|
}
|
|
50
48
|
|
|
51
49
|
export function getIgnoredModules(): ManifestModule[] {
|
|
52
|
-
return [...RuntimeIndex.getModuleList('all')]
|
|
53
|
-
.map(name => RuntimeIndex.getManifestModule(name))
|
|
54
|
-
.filter(module => !module.production);
|
|
50
|
+
return [...RuntimeIndex.getModuleList('all')].map(name => RuntimeIndex.getManifestModule(name)).filter(module => !module.production);
|
|
55
51
|
}
|
|
56
52
|
|
|
57
53
|
export function getMinifyConfig(): Parameters<typeof terser>[0] {
|
|
@@ -63,7 +59,7 @@ export function getMinifyConfig(): Parameters<typeof terser>[0] {
|
|
|
63
59
|
compress: {},
|
|
64
60
|
output: {
|
|
65
61
|
shebang: false,
|
|
66
|
-
comments: false
|
|
62
|
+
comments: false
|
|
67
63
|
}
|
|
68
64
|
};
|
|
69
65
|
}
|
|
@@ -79,7 +75,12 @@ export function getCoreConfig(): CoreRollupConfig {
|
|
|
79
75
|
const external = new EnvProp('BUNDLE_EXTERNAL').list ?? [];
|
|
80
76
|
|
|
81
77
|
return {
|
|
82
|
-
output,
|
|
83
|
-
|
|
78
|
+
output,
|
|
79
|
+
entry,
|
|
80
|
+
files,
|
|
81
|
+
envFile,
|
|
82
|
+
minify,
|
|
83
|
+
external,
|
|
84
|
+
ignore: new Set([...ignoreModules.map(module => module.name), ...ignoreFiles])
|
|
84
85
|
};
|
|
85
|
-
}
|
|
86
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
|
+
|
|
2
3
|
import type { Plugin } from 'rollup';
|
|
3
4
|
|
|
4
5
|
import { RuntimeIndex } from '@travetto/runtime';
|
|
@@ -10,7 +11,7 @@ export const GLOBAL_IMPORT = '__trv_imp';
|
|
|
10
11
|
export function travettoEntryPlugin(config: CoreRollupConfig): Plugin {
|
|
11
12
|
const imports = config.files
|
|
12
13
|
.map(file => file.split('node_modules/').pop()!)
|
|
13
|
-
.flatMap(file => file.endsWith('/__index__.js') ? [file.replace('/__index__.js', ''), file] : [file]);
|
|
14
|
+
.flatMap(file => (file.endsWith('/__index__.js') ? [file.replace('/__index__.js', ''), file] : [file]));
|
|
14
15
|
|
|
15
16
|
const importer = `
|
|
16
17
|
function trvImp(path) {
|
|
@@ -39,4 +40,4 @@ globalThis.${GLOBAL_IMPORT} = trvImp;
|
|
|
39
40
|
};
|
|
40
41
|
|
|
41
42
|
return out;
|
|
42
|
-
}
|
|
43
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type { AstNode, Plugin } from 'rollup';
|
|
2
1
|
// @ts-expect-error - This module lacks types
|
|
3
2
|
import { walk } from 'estree-walker';
|
|
4
3
|
import magicString from 'magic-string';
|
|
4
|
+
import type { AstNode, Plugin } from 'rollup';
|
|
5
5
|
|
|
6
|
-
import { GLOBAL_IMPORT } from './rollup-travetto-entry.ts';
|
|
7
6
|
import type { CoreRollupConfig } from '../../src/types.ts';
|
|
7
|
+
import { GLOBAL_IMPORT } from './rollup-travetto-entry.ts';
|
|
8
8
|
|
|
9
|
-
type TNode = AstNode & { source?: { type: string }
|
|
9
|
+
type TNode = AstNode & { source?: { type: string }; callee?: TNode & { name?: string }; args?: TNode[] };
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Handles importing via non-static strings (e.g. ClassSource)
|
|
@@ -59,4 +59,4 @@ export function travettoImportPlugin(config: CoreRollupConfig): Plugin {
|
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
return out;
|
|
62
|
-
}
|
|
62
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
1
|
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
3
|
|
|
4
4
|
import type { LoadResult, Plugin, PluginContext, SourceMapInput } from 'rollup';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { FileLoader, JSONUtil } from '@travetto/runtime';
|
|
7
7
|
|
|
8
8
|
import type { CoreRollupConfig } from '../../src/types.ts';
|
|
9
9
|
|
|
10
|
-
function
|
|
11
|
-
return error instanceof Error ? error.stack ?? error.toString() : JSONUtil.toUTF8(error);
|
|
10
|
+
function errorString(error: unknown): string {
|
|
11
|
+
return error instanceof Error ? (error.stack ?? error.toString()) : JSONUtil.toUTF8(error);
|
|
12
12
|
}
|
|
13
13
|
// Pulled from https://github.com/Azure/azure-sdk-for-js/blob/main/common/tools/dev-tool/src/config/rollup.base.config.ts#L128
|
|
14
14
|
export function travettoSourcemaps(config: CoreRollupConfig): Plugin {
|
|
@@ -30,18 +30,16 @@ export function travettoSourcemaps(config: CoreRollupConfig): Plugin {
|
|
|
30
30
|
return null;
|
|
31
31
|
}
|
|
32
32
|
const loader = new FileLoader([path.dirname(id)]);
|
|
33
|
-
const map = await loader
|
|
34
|
-
.
|
|
35
|
-
|
|
36
|
-
JSONUtil.fromBase64<SourceMapInput>(value)
|
|
37
|
-
);
|
|
33
|
+
const map = await loader
|
|
34
|
+
.readUTF8(mapPath)
|
|
35
|
+
.then(value => (value.startsWith('{') ? JSONUtil.fromUTF8<SourceMapInput>(value) : JSONUtil.fromBase64<SourceMapInput>(value)));
|
|
38
36
|
return { code, map };
|
|
39
37
|
}
|
|
40
38
|
return { code, map: null };
|
|
41
39
|
} catch (error) {
|
|
42
|
-
this.warn({ message:
|
|
40
|
+
this.warn({ message: errorString(error), id });
|
|
43
41
|
return null;
|
|
44
42
|
}
|
|
45
|
-
}
|
|
43
|
+
}
|
|
46
44
|
};
|
|
47
45
|
}
|