@travetto/pack 3.0.0-rc.0 → 3.0.0-rc.10
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 +1 -1
- package/__index__.ts +1 -0
- package/package.json +16 -11
- package/support/bin/config.ts +81 -0
- package/support/bin/docker-operation.ts +92 -0
- package/support/bin/operation.ts +255 -0
- package/support/bin/rollup-esm-dynamic-import.ts +55 -0
- package/support/bin/rollup.ts +36 -0
- package/support/bin/shell.ts +53 -0
- package/support/bin/types.ts +70 -0
- package/support/bin/util.ts +63 -0
- package/support/cli.pack.ts +14 -0
- package/support/cli.pack_docker.ts +48 -0
- package/support/cli.pack_zip.ts +24 -0
- package/support/pack.base.ts +138 -0
- package/support/pack.dockerfile.ts +9 -0
- package/bin/cli-pack.ts +0 -10
- package/bin/cli-pack_assemble.ts +0 -21
- package/bin/cli-pack_docker-export.ts +0 -54
- package/bin/cli-pack_docker.ts +0 -29
- package/bin/cli-pack_zip.ts +0 -19
- package/bin/lib/assemble.ts +0 -151
- package/bin/lib/dependencies.ts +0 -103
- package/bin/lib/types.ts +0 -19
- package/bin/lib/util.ts +0 -175
- package/bin/operation/assemble.ts +0 -75
- package/bin/operation/docker.ts +0 -96
- package/bin/operation/pack.ts +0 -69
- package/bin/operation/zip.ts +0 -51
- package/bin/pack-base.ts +0 -100
- package/index.d.ts +0 -5
- package/support/pack.config.ts +0 -66
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ Assemble is the operation that stages the project's code for deployment. The as
|
|
|
40
40
|
|
|
41
41
|
1. Cleaning Workspace - Cleans workspace to start with an empty workspace
|
|
42
42
|
1. Copying Dependencies - Computes the prod dependencies and copies them into the new workspace
|
|
43
|
-
1. Copying App Content - Copies over application content (src
|
|
43
|
+
1. Copying App Content - Copies over application content (src/, resources/, support/, bin/)
|
|
44
44
|
1. Excluding Pre-Compile Files - Any files that should be excluded pre-compilation, are removed
|
|
45
45
|
1. Compiling - Compiles the code in the new workspace, isolating it from your local development
|
|
46
46
|
1. Excluding Post-Compile Files - Removes any files that should be excluded, post compilation
|
package/__index__.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { CommonPackConfig, DockerPackFactory, DockerPackConfig } from './support/bin/types';
|
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/pack",
|
|
3
|
-
"
|
|
4
|
-
"version": "3.0.0-rc.0",
|
|
3
|
+
"version": "3.0.0-rc.10",
|
|
5
4
|
"description": "Code packing utilities",
|
|
6
5
|
"keywords": [
|
|
7
6
|
"travetto",
|
|
@@ -15,9 +14,9 @@
|
|
|
15
14
|
"email": "travetto.framework@gmail.com",
|
|
16
15
|
"name": "Travetto Framework"
|
|
17
16
|
},
|
|
17
|
+
"main": "__index__.ts",
|
|
18
18
|
"files": [
|
|
19
|
-
"
|
|
20
|
-
"bin",
|
|
19
|
+
"__index__.ts",
|
|
21
20
|
"support"
|
|
22
21
|
],
|
|
23
22
|
"repository": {
|
|
@@ -25,21 +24,27 @@
|
|
|
25
24
|
"directory": "module/pack"
|
|
26
25
|
},
|
|
27
26
|
"dependencies": {
|
|
28
|
-
"@
|
|
29
|
-
"@
|
|
30
|
-
"
|
|
27
|
+
"@rollup/plugin-commonjs": "^24.0.1",
|
|
28
|
+
"@rollup/plugin-json": "^6.0.0",
|
|
29
|
+
"@rollup/plugin-terser": "^0.4.0",
|
|
30
|
+
"@rollup/plugin-node-resolve": "^15.0.1",
|
|
31
|
+
"@travetto/base": "^3.0.0-rc.9",
|
|
32
|
+
"rollup": "^3.12.1",
|
|
33
|
+
"rollup-plugin-sourcemaps": "^0.6.3"
|
|
31
34
|
},
|
|
32
35
|
"peerDependencies": {
|
|
33
|
-
"@travetto/cli": "^3.0.0-rc.
|
|
36
|
+
"@travetto/cli": "^3.0.0-rc.10"
|
|
34
37
|
},
|
|
35
38
|
"peerDependenciesMeta": {
|
|
36
39
|
"@travetto/cli": {
|
|
37
40
|
"optional": true
|
|
38
41
|
}
|
|
39
42
|
},
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
+
"travetto": {
|
|
44
|
+
"displayName": "Pack",
|
|
45
|
+
"profiles": [
|
|
46
|
+
"build"
|
|
47
|
+
]
|
|
43
48
|
},
|
|
44
49
|
"publishConfig": {
|
|
45
50
|
"access": "public"
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { OutputOptions } from 'rollup';
|
|
2
|
+
import type terser from '@rollup/plugin-terser';
|
|
3
|
+
|
|
4
|
+
import { Env } from '@travetto/base';
|
|
5
|
+
import { ManifestModule, Package, path, RootIndex } from '@travetto/manifest';
|
|
6
|
+
|
|
7
|
+
const INTRO = {
|
|
8
|
+
commonjs: `
|
|
9
|
+
globalThis.crypto = require('crypto');
|
|
10
|
+
try { require('./.env.js')} catch {}
|
|
11
|
+
|
|
12
|
+
function __importStar(mod) {
|
|
13
|
+
if (mod && mod.__esModule) return mod;
|
|
14
|
+
var result = {};
|
|
15
|
+
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
|
16
|
+
result['default'] = mod;
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
`,
|
|
20
|
+
module: `
|
|
21
|
+
globalThis.crypto = await import('crypto');
|
|
22
|
+
try {await import('./.env.js')} catch {}
|
|
23
|
+
`
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
function getFilesFromModule(m: ManifestModule): string[] {
|
|
27
|
+
return [
|
|
28
|
+
...m.files.$index ?? [],
|
|
29
|
+
...m.files.src ?? [],
|
|
30
|
+
...m.files.bin ?? [],
|
|
31
|
+
...(m.files.support ?? [])
|
|
32
|
+
.filter(f => !/support\/(test|doc)/.test(f[0]))
|
|
33
|
+
]
|
|
34
|
+
.filter(([, t]) => t === 'ts' || t === 'js' || t === 'json')
|
|
35
|
+
.map(([f]) => path.resolve(m.outputFolder, f.replace(/[.]ts$/, '.js')));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function getOutput(): OutputOptions {
|
|
39
|
+
const format: Package['type'] = Env.get('BUNDLE_FORMAT', 'commonjs');
|
|
40
|
+
return {
|
|
41
|
+
format,
|
|
42
|
+
intro: INTRO[format],
|
|
43
|
+
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,
|
|
51
|
+
dir: Env.get('BUNDLE_OUTPUT')!,
|
|
52
|
+
...(format === 'commonjs' ? {} : {
|
|
53
|
+
inlineDynamicImports: true
|
|
54
|
+
}),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function getEntry(): string {
|
|
59
|
+
return Env.get('BUNDLE_ENTRY')!;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function getFiles(): string[] {
|
|
63
|
+
return [...RootIndex.getModuleList('all')]
|
|
64
|
+
.map(x => RootIndex.manifest.modules[x])
|
|
65
|
+
.filter(m => m.profiles.includes('std'))
|
|
66
|
+
.flatMap(getFilesFromModule);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function getTerserConfig(): Parameters<typeof terser>[0] {
|
|
70
|
+
return {
|
|
71
|
+
mangle: true,
|
|
72
|
+
keep_classnames: true,
|
|
73
|
+
keep_fnames: true,
|
|
74
|
+
ecma: 2020,
|
|
75
|
+
compress: {},
|
|
76
|
+
output: {
|
|
77
|
+
shebang: false,
|
|
78
|
+
comments: false,
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
|
|
3
|
+
import { path, RootIndex } from '@travetto/manifest';
|
|
4
|
+
import { ExecUtil } from '@travetto/base';
|
|
5
|
+
import { cliTpl } from '@travetto/cli';
|
|
6
|
+
|
|
7
|
+
import { ActiveShellCommand } from './shell';
|
|
8
|
+
import { DockerPackConfig, DockerPackFactoryModule } from './types';
|
|
9
|
+
|
|
10
|
+
export class DockerPackOperation {
|
|
11
|
+
|
|
12
|
+
static getDockerTags(cfg: DockerPackConfig): string[] {
|
|
13
|
+
return (cfg.dockerTag ?? []).map(x => cfg.dockerRegistry ? `${cfg.dockerRegistry}/${cfg.dockerName}:${x}` : `${cfg.dockerName}:${x}`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Write Docker File
|
|
18
|
+
*/
|
|
19
|
+
static async* writeDockerFile(cfg: DockerPackConfig): AsyncIterable<string[]> {
|
|
20
|
+
const dockerFile = path.resolve(cfg.workspace, 'Dockerfile');
|
|
21
|
+
const title = cliTpl`${{ title: 'Generating Docker File' }} ${{ path: dockerFile }} ${{ param: cfg.dockerFactory }}`;
|
|
22
|
+
const factory = RootIndex.getFromImport(cfg.dockerFactory);
|
|
23
|
+
if (!factory) {
|
|
24
|
+
throw new Error(`Unable to resolve docker factory at ${cfg.dockerFactory}`);
|
|
25
|
+
}
|
|
26
|
+
const mod: DockerPackFactoryModule = await import(factory.import);
|
|
27
|
+
const content = (await mod.factory(cfg)).trim();
|
|
28
|
+
|
|
29
|
+
if (cfg.ejectFile) {
|
|
30
|
+
yield ActiveShellCommand.comment(title);
|
|
31
|
+
yield* ActiveShellCommand.createFile(dockerFile, content.split(/\n/));
|
|
32
|
+
} else {
|
|
33
|
+
yield [title];
|
|
34
|
+
await fs.writeFile(dockerFile, content, 'utf8');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Pull Docker Base Image
|
|
40
|
+
*/
|
|
41
|
+
static async* pullDockerBaseImage(cfg: DockerPackConfig): AsyncIterable<string[]> {
|
|
42
|
+
const title = cliTpl`${{ title: 'Pulling Docker Base Image' }} ${{ param: cfg.dockerImage }}`;
|
|
43
|
+
|
|
44
|
+
const command = ['docker', 'pull', cfg.dockerImage];
|
|
45
|
+
|
|
46
|
+
if (cfg.ejectFile) {
|
|
47
|
+
yield ActiveShellCommand.comment(title);
|
|
48
|
+
yield command;
|
|
49
|
+
} else {
|
|
50
|
+
yield [title];
|
|
51
|
+
await ExecUtil.spawn(command[0], command.slice(1), {}).result;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Building Docker Container
|
|
57
|
+
*/
|
|
58
|
+
static async* buildDockerContainer(cfg: DockerPackConfig): AsyncIterable<string[]> {
|
|
59
|
+
const title = cliTpl`${{ title: 'Building Docker Container' }} ${{ param: cfg.dockerTag?.join(',') }}`;
|
|
60
|
+
const cmd = ['docker', 'build', ...DockerPackOperation.getDockerTags(cfg).flatMap(x => ['-t', x]), '.'];
|
|
61
|
+
|
|
62
|
+
if (cfg.ejectFile) {
|
|
63
|
+
yield ActiveShellCommand.comment(title);
|
|
64
|
+
yield ActiveShellCommand.chdir(cfg.workspace);
|
|
65
|
+
yield cmd;
|
|
66
|
+
yield ActiveShellCommand.chdir(path.cwd());
|
|
67
|
+
} else {
|
|
68
|
+
yield [title];
|
|
69
|
+
await ExecUtil.spawn(cmd[0], cmd.slice(1), { cwd: cfg.workspace, stdio: [0, 'pipe', 2] }).result;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Push Docker Container
|
|
75
|
+
*/
|
|
76
|
+
static async* pushDockerContainer(cfg: DockerPackConfig): AsyncIterable<string[]> {
|
|
77
|
+
if (!cfg.dockerPush) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const tags = DockerPackOperation.getDockerTags(cfg);
|
|
81
|
+
const title = cliTpl`${{ title: 'Push Container to registry' }} ${{ param: cfg.dockerRegistry }}`;
|
|
82
|
+
const cmd = ['docker', 'image', 'push', ...tags];
|
|
83
|
+
|
|
84
|
+
if (cfg.ejectFile) {
|
|
85
|
+
yield ActiveShellCommand.comment(title);
|
|
86
|
+
yield cmd;
|
|
87
|
+
} else {
|
|
88
|
+
yield [title];
|
|
89
|
+
await ExecUtil.spawn(cmd[0], cmd.slice(1), { stdio: [0, 'pipe', 2] }).result;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
|
|
3
|
+
import { path, RootIndex } from '@travetto/manifest';
|
|
4
|
+
import { ExecUtil } from '@travetto/base';
|
|
5
|
+
import { cliTpl } from '@travetto/cli';
|
|
6
|
+
|
|
7
|
+
import { CommonPackConfig } from './types';
|
|
8
|
+
import { PackUtil } from './util';
|
|
9
|
+
import { ActiveShellCommand, ShellCommands } from './shell';
|
|
10
|
+
|
|
11
|
+
async function writeRawFile(file: string, contents: string, mode?: string): Promise<void> {
|
|
12
|
+
await fs.writeFile(file, contents, { encoding: 'utf8', mode });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class PackOperation {
|
|
16
|
+
|
|
17
|
+
static async * clean(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
18
|
+
if (!cfg.clean) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const title = cliTpl`${{ title: 'Cleaning Output' }} ${{ path: cfg.workspace }}`;
|
|
23
|
+
|
|
24
|
+
if (cfg.ejectFile) {
|
|
25
|
+
yield ActiveShellCommand.comment(title);
|
|
26
|
+
yield ActiveShellCommand.rmRecursive(cfg.workspace);
|
|
27
|
+
if (cfg.output) {
|
|
28
|
+
yield ActiveShellCommand.rmRecursive(cfg.output);
|
|
29
|
+
}
|
|
30
|
+
yield ActiveShellCommand.mkdir(cfg.workspace);
|
|
31
|
+
} else {
|
|
32
|
+
yield [title];
|
|
33
|
+
await fs.rm(cfg.workspace, { recursive: true, force: true });
|
|
34
|
+
if (cfg.output) {
|
|
35
|
+
await fs.rm(cfg.output, { recursive: true, force: true });
|
|
36
|
+
}
|
|
37
|
+
await fs.mkdir(cfg.workspace, { recursive: true });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static async * bundle(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
42
|
+
const cwd = RootIndex.outputRoot;
|
|
43
|
+
|
|
44
|
+
const bundleCommand = ['npx', 'rollup', '-c', 'node_modules/@travetto/pack/support/bin/rollup.js'];
|
|
45
|
+
|
|
46
|
+
const env = Object.fromEntries(([
|
|
47
|
+
['BUNDLE_ENTRY', cfg.entryPoint],
|
|
48
|
+
['BUNDLE_ENTRY_NAME', cfg.entryCommand],
|
|
49
|
+
['BUNDLE_COMPRESS', cfg.minify],
|
|
50
|
+
['BUNDLE_SOURCEMAP', cfg.sourcemap],
|
|
51
|
+
['BUNDLE_SOURCES', cfg.includeSources],
|
|
52
|
+
['BUNDLE_OUTPUT', cfg.workspace],
|
|
53
|
+
['BUNDLE_FORMAT', RootIndex.manifest.moduleType],
|
|
54
|
+
['TRV_MANIFEST', RootIndex.getModule(cfg.module)!.outputPath]
|
|
55
|
+
] as const)
|
|
56
|
+
.filter(x => x[1] === false || x[1])
|
|
57
|
+
.map(x => [x[0], `${x[1]}`])
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const props = (['minify', 'sourcemap', 'entryPoint'] as const)
|
|
61
|
+
.map(k => cliTpl`${{ subtitle: k }}=${{ param: cfg[k] }}`).join(' ');
|
|
62
|
+
|
|
63
|
+
const title = cliTpl`${{ title: 'Bundling Output' }} ${props}`;
|
|
64
|
+
|
|
65
|
+
if (cfg.ejectFile) {
|
|
66
|
+
yield ActiveShellCommand.comment(title);
|
|
67
|
+
yield* Object.entries(env).filter(x => !!x[1]).map(x =>
|
|
68
|
+
ActiveShellCommand.export(x[0], x[1])
|
|
69
|
+
);
|
|
70
|
+
yield ActiveShellCommand.chdir(cwd);
|
|
71
|
+
yield bundleCommand;
|
|
72
|
+
yield ActiveShellCommand.chdir(path.cwd());
|
|
73
|
+
} else {
|
|
74
|
+
yield [title];
|
|
75
|
+
await ExecUtil.spawn(bundleCommand[0], bundleCommand.slice(1), { cwd, env, stdio: ['inherit', 'pipe', 'pipe'] }).result;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static async * writePackageJson(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
80
|
+
const file = 'package.json';
|
|
81
|
+
const title = cliTpl`${{ title: 'Writing' }} ${{ path: file }}`;
|
|
82
|
+
const pkg = { type: RootIndex.manifest.moduleType };
|
|
83
|
+
|
|
84
|
+
if (cfg.ejectFile) {
|
|
85
|
+
yield ActiveShellCommand.comment(title);
|
|
86
|
+
yield* ActiveShellCommand.createFile(
|
|
87
|
+
path.resolve(cfg.workspace, file),
|
|
88
|
+
[JSON.stringify(pkg)]
|
|
89
|
+
);
|
|
90
|
+
} else {
|
|
91
|
+
yield [title];
|
|
92
|
+
await writeRawFile(
|
|
93
|
+
path.resolve(cfg.workspace, file),
|
|
94
|
+
JSON.stringify(pkg, null, 2)
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static async * writeEnv(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
100
|
+
const file = '.env.js';
|
|
101
|
+
const title = cliTpl`${{ title: 'Writing' }} ${{ path: file }}`;
|
|
102
|
+
const env = {
|
|
103
|
+
TRV_MANIFEST: `node_modules/${cfg.module}`,
|
|
104
|
+
TRV_CLI_IPC: ''
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
if (cfg.ejectFile) {
|
|
108
|
+
yield ActiveShellCommand.comment(title);
|
|
109
|
+
yield* ActiveShellCommand.createFile(
|
|
110
|
+
path.resolve(cfg.workspace, file),
|
|
111
|
+
PackUtil.buildEnvJS(env)
|
|
112
|
+
);
|
|
113
|
+
} else {
|
|
114
|
+
yield [title];
|
|
115
|
+
await writeRawFile(
|
|
116
|
+
path.resolve(cfg.workspace, file),
|
|
117
|
+
PackUtil.buildEnvJS(env).join('\n')
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
static async * writeEntryScript(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
123
|
+
const title = 'Writing entry scripts';
|
|
124
|
+
|
|
125
|
+
const files = ([['posix', 'sh'], ['win32', 'cmd']] as const)
|
|
126
|
+
.map(([type, ext]) => ({
|
|
127
|
+
fileTitle: cliTpl`${{ title }} ${{ path: `${cfg.entryCommand}.${ext}` }} args=(${{ param: cfg.entryArguments.join(' ') }})`,
|
|
128
|
+
file: `${cfg.entryCommand}.${ext}`,
|
|
129
|
+
text: [
|
|
130
|
+
ShellCommands[type].scriptOpen(),
|
|
131
|
+
ShellCommands[type].chdirScript(),
|
|
132
|
+
ShellCommands[type].callCommandWithAllArgs('node', cfg.entryCommand, ...cfg.entryArguments),
|
|
133
|
+
].map(x => x.join(' '))
|
|
134
|
+
}));
|
|
135
|
+
|
|
136
|
+
if (cfg.ejectFile) {
|
|
137
|
+
for (const { fileTitle, text, file } of files) {
|
|
138
|
+
yield ActiveShellCommand.comment(fileTitle);
|
|
139
|
+
yield* ActiveShellCommand.createFile(path.resolve(cfg.workspace, file), text, '755');
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
for (const { fileTitle, text, file } of files) {
|
|
143
|
+
yield [fileTitle];
|
|
144
|
+
await writeRawFile(path.resolve(cfg.workspace, file), text.join('\n'), '755');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
static async * copyResources(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
150
|
+
const resources = {
|
|
151
|
+
count: RootIndex.mainModule.files.resources?.length ?? 0,
|
|
152
|
+
src: path.resolve(RootIndex.mainModule.sourcePath, 'resources'),
|
|
153
|
+
dest: path.resolve(cfg.workspace, 'resources')
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const copyFiles = [
|
|
157
|
+
RootIndex.manifest.modules[RootIndex.mainModule.name],
|
|
158
|
+
RootIndex.manifest.modules['@travetto/manifest']
|
|
159
|
+
].map(mod => ({
|
|
160
|
+
src: path.resolve(RootIndex.outputRoot, mod.outputFolder, 'package.json'),
|
|
161
|
+
dest: path.resolve(cfg.workspace, mod.outputFolder, 'package.json'),
|
|
162
|
+
destFolder: path.resolve(cfg.workspace, mod.outputFolder)
|
|
163
|
+
}));
|
|
164
|
+
|
|
165
|
+
const title = cliTpl`${{ title: 'Copying over resources' }}`;
|
|
166
|
+
|
|
167
|
+
if (cfg.ejectFile) {
|
|
168
|
+
yield ActiveShellCommand.comment(title);
|
|
169
|
+
yield* copyFiles.flatMap(mod => [
|
|
170
|
+
ActiveShellCommand.mkdir(path.dirname(mod.dest)),
|
|
171
|
+
ActiveShellCommand.copy(mod.src, mod.dest)
|
|
172
|
+
]);
|
|
173
|
+
if (resources.count) {
|
|
174
|
+
yield ActiveShellCommand.copyRecursive(resources.src, path.resolve(cfg.workspace, 'resources'));
|
|
175
|
+
}
|
|
176
|
+
} else {
|
|
177
|
+
yield [title];
|
|
178
|
+
|
|
179
|
+
for (const { src, dest, destFolder } of copyFiles) {
|
|
180
|
+
await fs.mkdir(destFolder, { recursive: true });
|
|
181
|
+
await fs.copyFile(src, dest);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (resources.count) {
|
|
185
|
+
await fs.mkdir(path.dirname(resources.dest), { recursive: true });
|
|
186
|
+
await PackUtil.copyRecursive(resources.src, resources.dest);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
static async * primeAppCache(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
192
|
+
const isCli = cfg.entryCommand === 'cli';
|
|
193
|
+
if (!isCli || !RootIndex.hasModule('@travetto/app')) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const appCacheCmd = ['npx', 'trv', 'main', '@travetto/app/support/bin/list'];
|
|
198
|
+
const sub = path.join(RootIndex.manifest.modules[RootIndex.mainModule.name].outputFolder, 'trv-app-cache.json');
|
|
199
|
+
const title = cliTpl`${{ title: 'Generating App Cache' }} ${{ path: sub }}`;
|
|
200
|
+
const env = { DEBUG: '0', TRV_MODULE: cfg.module };
|
|
201
|
+
const appCache = path.resolve(cfg.workspace, sub);
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
if (cfg.ejectFile) {
|
|
205
|
+
yield ActiveShellCommand.comment(title);
|
|
206
|
+
yield ActiveShellCommand.mkdir(path.dirname(appCache));
|
|
207
|
+
yield [...Object.entries(env).map(x => `${x[0]}=${x[1]}`), ...appCacheCmd, '>', appCache];
|
|
208
|
+
} else {
|
|
209
|
+
yield [title];
|
|
210
|
+
const { stdout } = await ExecUtil.spawn(appCacheCmd[0], appCacheCmd.slice(1), { env }).result;
|
|
211
|
+
|
|
212
|
+
await fs.mkdir(path.dirname(appCache), { recursive: true });
|
|
213
|
+
await fs.writeFile(appCache, stdout, 'utf8');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
static async * writeManifest(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
218
|
+
const out = path.resolve(cfg.workspace, 'node_modules', cfg.module);
|
|
219
|
+
const cmd = ['npx', 'trv', 'manifest', out, 'prod'];
|
|
220
|
+
const env = { TRV_MODULE: cfg.module };
|
|
221
|
+
const title = cliTpl`${{ title: 'Writing Manifest' }} ${{ path: path.join('node_modules', cfg.module) }}`;
|
|
222
|
+
|
|
223
|
+
if (cfg.ejectFile) {
|
|
224
|
+
yield ActiveShellCommand.comment(title);
|
|
225
|
+
yield [...Object.entries(env).map(([k, v]) => `${k}=${v}`), ...cmd];
|
|
226
|
+
} else {
|
|
227
|
+
yield [title];
|
|
228
|
+
await ExecUtil.spawn(cmd[0], cmd.slice(1), { env, stdio: ['inherit', 'ignore', 'inherit'] }).result;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
static async * compress(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
233
|
+
const title = cliTpl`${{ title: 'Compressing' }} ${{ path: cfg.output }}`;
|
|
234
|
+
|
|
235
|
+
if (cfg.ejectFile) {
|
|
236
|
+
yield ActiveShellCommand.comment(title);
|
|
237
|
+
yield ActiveShellCommand.chdir(cfg.workspace);
|
|
238
|
+
yield ActiveShellCommand.zip(cfg.output);
|
|
239
|
+
yield ActiveShellCommand.chdir(path.cwd());
|
|
240
|
+
} else {
|
|
241
|
+
yield [title];
|
|
242
|
+
const [cmd, ...args] = ActiveShellCommand.zip(cfg.output);
|
|
243
|
+
await ExecUtil.spawn(cmd, args, { cwd: cfg.workspace }).result;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
static async * runOperations<S>(cfg: S, operations: ((config: S) => AsyncIterable<string[]>)[]): AsyncIterable<string> {
|
|
249
|
+
for (const op of operations) {
|
|
250
|
+
for await (const msg of op(cfg)) {
|
|
251
|
+
yield msg.join(' ');
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { AcornNode, Plugin } from 'rollup';
|
|
2
|
+
import { walk } from 'estree-walker';
|
|
3
|
+
import MagicString from 'magic-string';
|
|
4
|
+
|
|
5
|
+
const BRAND = '__imp';
|
|
6
|
+
|
|
7
|
+
const DYNAMIC_IMPORT = (imports: string[]): string => `
|
|
8
|
+
function ${BRAND}(path) {
|
|
9
|
+
switch (path) {
|
|
10
|
+
${imports.map(p => ` case '${p}': return import('${p}');`).join('\n')}
|
|
11
|
+
default: return import(path); // Fall back for built-ins
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
globalThis.${BRAND} = ${BRAND}`;
|
|
15
|
+
|
|
16
|
+
export function travettoImportPlugin(entry: string, files: string[]): Plugin {
|
|
17
|
+
const imports = files
|
|
18
|
+
.map(x => x.split('node_modules/').pop()!)
|
|
19
|
+
.flatMap(x => x.endsWith('__index__.js') ? [x.replace('__index__.js', ''), x] : [x]);
|
|
20
|
+
|
|
21
|
+
const out: Plugin = {
|
|
22
|
+
name: 'travetto-import',
|
|
23
|
+
transform(code, id) {
|
|
24
|
+
const parsed = this.parse(code);
|
|
25
|
+
|
|
26
|
+
let ms: MagicString | undefined;
|
|
27
|
+
|
|
28
|
+
if (id.includes(entry)) {
|
|
29
|
+
(ms ??= new MagicString(code).append(DYNAMIC_IMPORT(imports)));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
walk(parsed, {
|
|
33
|
+
enter: (node) => {
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
35
|
+
const impNode = node as AcornNode & { source?: { type: string } };
|
|
36
|
+
if (impNode.type !== 'ImportExpression' || impNode.source?.type === 'Literal') {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
(ms ??= new MagicString(code)).overwrite(impNode.start, impNode.start + 6, BRAND);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
if (ms !== undefined) {
|
|
44
|
+
return {
|
|
45
|
+
code: ms.toString(),
|
|
46
|
+
map: ms.generateMap({ file: id, includeContent: true, hires: true })
|
|
47
|
+
};
|
|
48
|
+
} else {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import commonjsRequire from '@rollup/plugin-commonjs';
|
|
2
|
+
import nodeResolve from '@rollup/plugin-node-resolve';
|
|
3
|
+
import terser from '@rollup/plugin-terser';
|
|
4
|
+
import jsonImport from '@rollup/plugin-json';
|
|
5
|
+
import sourceMaps from 'rollup-plugin-sourcemaps';
|
|
6
|
+
import type { RollupOptions } from 'rollup';
|
|
7
|
+
|
|
8
|
+
import { RootIndex } from '@travetto/manifest';
|
|
9
|
+
|
|
10
|
+
import { getEntry, getOutput, getTerserConfig, getFiles } from './config';
|
|
11
|
+
import { travettoImportPlugin } from './rollup-esm-dynamic-import';
|
|
12
|
+
|
|
13
|
+
const NEVER_INCLUDE = new Set(['node-forge', '@parcel/watcher']);
|
|
14
|
+
|
|
15
|
+
export default function buildConfig(): RollupOptions {
|
|
16
|
+
const output = getOutput();
|
|
17
|
+
const entry = getEntry();
|
|
18
|
+
const files = getFiles();
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
input: [entry],
|
|
22
|
+
output,
|
|
23
|
+
plugins: [
|
|
24
|
+
jsonImport(),
|
|
25
|
+
commonjsRequire({
|
|
26
|
+
ignore: id => NEVER_INCLUDE.has(id),
|
|
27
|
+
dynamicRequireRoot: RootIndex.manifest.workspacePath,
|
|
28
|
+
dynamicRequireTargets: (output.format === 'commonjs' ? files : [])
|
|
29
|
+
}),
|
|
30
|
+
...(output.format === 'module' ? [travettoImportPlugin(entry, files)] : []),
|
|
31
|
+
nodeResolve({ preferBuiltins: true }),
|
|
32
|
+
...(output.sourcemap !== 'hidden' && output.sourcemap !== false ? [sourceMaps({})] : []),
|
|
33
|
+
...(output.compact ? [terser(getTerserConfig())] : [])
|
|
34
|
+
]
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { path } from '@travetto/manifest';
|
|
2
|
+
import { stripAnsiCodes } from '@travetto/terminal';
|
|
3
|
+
|
|
4
|
+
import { ShellCommandImpl } from './types';
|
|
5
|
+
|
|
6
|
+
const escape = (text: string): string =>
|
|
7
|
+
text
|
|
8
|
+
.replaceAll('"', '\\"')
|
|
9
|
+
.replaceAll('$', '\\$');
|
|
10
|
+
|
|
11
|
+
export const ShellCommands: Record<'win32' | 'posix', ShellCommandImpl> = {
|
|
12
|
+
win32: {
|
|
13
|
+
var: (name: string) => `%${name}%`,
|
|
14
|
+
scriptOpen: () => [],
|
|
15
|
+
chdirScript: () => ['cd', '%~p0'],
|
|
16
|
+
callCommandWithAllArgs: (cmd, ...args) => [cmd, ...args, '%*'],
|
|
17
|
+
createFile: (file, text) => [
|
|
18
|
+
['@echo', 'off'],
|
|
19
|
+
...text.map((line, i) =>
|
|
20
|
+
['echo', `"${escape(line)}"`, i === 0 ? '>' : '>>', file]
|
|
21
|
+
)
|
|
22
|
+
],
|
|
23
|
+
copy: (src, dest) => ['copy', src, dest],
|
|
24
|
+
copyRecursive: (src, dest) => ['xcopy', '/y', '/h', '/s', path.toNative(src), path.toNative(dest)],
|
|
25
|
+
rmRecursive: (dest) => ['rmdir', '/Q', '/S', dest],
|
|
26
|
+
mkdir: (dest) => ['md', dest],
|
|
27
|
+
export: (key, value) => ['set', `${key}=${value}`],
|
|
28
|
+
chdir: (dest) => ['cd', dest],
|
|
29
|
+
comment: (message) => ['\nREM', stripAnsiCodes(message), '\n'],
|
|
30
|
+
zip: (outputFile) => ['powershell', 'Compress-Archive', '-Path', '.', '-DestinationPath', outputFile]
|
|
31
|
+
},
|
|
32
|
+
posix: {
|
|
33
|
+
var: (name: string) => `$${name}`,
|
|
34
|
+
scriptOpen: () => ['#!/bin/sh'],
|
|
35
|
+
chdirScript: () => ['cd', '$(dirname "$0")'],
|
|
36
|
+
callCommandWithAllArgs: (cmd, ...args) => [cmd, ...args, '$@'],
|
|
37
|
+
createFile: (file, text, mode) => [
|
|
38
|
+
...text.map((line, i) =>
|
|
39
|
+
['echo', `"${escape(line)}"`, i === 0 ? '>' : '>>', file]),
|
|
40
|
+
...(mode ? [['chmod', mode, file]] : [])
|
|
41
|
+
],
|
|
42
|
+
copy: (src, dest) => ['cp', src, dest],
|
|
43
|
+
copyRecursive: (src, dest) => ['cp', '-r', '-p', src, dest],
|
|
44
|
+
rmRecursive: (dest) => ['rm', '-rf', dest],
|
|
45
|
+
mkdir: (dest) => ['mkdir', '-p', dest],
|
|
46
|
+
export: (key, value) => ['export', `${key}=${value}`],
|
|
47
|
+
chdir: (dest) => ['cd', dest],
|
|
48
|
+
comment: (message) => ['\n#', stripAnsiCodes(message), '\n'],
|
|
49
|
+
zip: (outputFile) => ['zip', '-r', outputFile, '.']
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const ActiveShellCommand = ShellCommands[process.platform === 'win32' ? 'win32' : 'posix'];
|