@travetto/pack 3.0.0-rc.6 → 3.0.0-rc.8
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/__index__.ts +1 -5
- package/package.json +9 -5
- 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 +34 -0
- package/support/bin/shell.ts +53 -0
- package/support/bin/types.ts +61 -15
- package/support/bin/util.ts +39 -154
- package/support/cli.pack.ts +10 -6
- package/support/cli.pack_docker.ts +27 -21
- package/support/cli.pack_zip.ts +18 -13
- package/support/pack.base.ts +136 -0
- package/support/bin/assemble/operation.ts +0 -59
- package/support/bin/assemble/util.ts +0 -139
- package/support/bin/docker.ts +0 -97
- package/support/bin/pack.ts +0 -69
- package/support/bin/zip.ts +0 -51
- package/support/cli.pack-base.ts +0 -97
- package/support/cli.pack_assemble.ts +0 -21
- package/support/cli.pack_docker-export.ts +0 -55
- package/support/pack.config.ts +0 -60
package/__index__.ts
CHANGED
|
@@ -1,5 +1 @@
|
|
|
1
|
-
export type {
|
|
2
|
-
export type { CommonConfig } from './support/bin/types';
|
|
3
|
-
export type { AssembleConfig } from './support/bin/assemble/operation';
|
|
4
|
-
export type { ZipConfig } from './support/bin/zip';
|
|
5
|
-
export type { DockerConfig } from './support/bin/docker';
|
|
1
|
+
export type { CommonPackConfig } from './support/bin/types';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/pack",
|
|
3
|
-
"version": "3.0.0-rc.
|
|
3
|
+
"version": "3.0.0-rc.8",
|
|
4
4
|
"description": "Code packing utilities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"travetto",
|
|
@@ -23,12 +23,16 @@
|
|
|
23
23
|
"directory": "module/pack"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@
|
|
27
|
-
"@
|
|
28
|
-
"
|
|
26
|
+
"@rollup/plugin-commonjs": "^24.0.1",
|
|
27
|
+
"@rollup/plugin-json": "^6.0.0",
|
|
28
|
+
"@rollup/plugin-terser": "^0.4.0",
|
|
29
|
+
"@rollup/plugin-node-resolve": "^15.0.1",
|
|
30
|
+
"@travetto/base": "^3.0.0-rc.8",
|
|
31
|
+
"rollup": "^3.12.1",
|
|
32
|
+
"rollup-plugin-sourcemaps": "^0.6.3"
|
|
29
33
|
},
|
|
30
34
|
"peerDependencies": {
|
|
31
|
-
"@travetto/cli": "^3.0.0-rc.
|
|
35
|
+
"@travetto/cli": "^3.0.0-rc.9"
|
|
32
36
|
},
|
|
33
37
|
"peerDependenciesMeta": {
|
|
34
38
|
"@travetto/cli": {
|
|
@@ -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 } from '@travetto/manifest';
|
|
4
|
+
import { ExecUtil } from '@travetto/base';
|
|
5
|
+
import { cliTpl } from '@travetto/cli';
|
|
6
|
+
|
|
7
|
+
import { ActiveShellCommand } from './shell';
|
|
8
|
+
import { DockerPackConfig } 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 }}`;
|
|
22
|
+
const content = `
|
|
23
|
+
FROM ${cfg.dockerImage}
|
|
24
|
+
WORKDIR /app
|
|
25
|
+
COPY . .
|
|
26
|
+
${(cfg.dockerPort ?? []).map(x => `EXPOSE ${x}`).join('\n')}
|
|
27
|
+
ENTRYPOINT ["/app/${cfg.entryCommand}.sh"]
|
|
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', 'bat']] 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,34 @@
|
|
|
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
|
+
export default function buildConfig(): RollupOptions {
|
|
14
|
+
const output = getOutput();
|
|
15
|
+
const entry = getEntry();
|
|
16
|
+
const files = getFiles();
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
input: [entry],
|
|
20
|
+
output,
|
|
21
|
+
external: ['node-forge', '@parcel/watcher'],
|
|
22
|
+
plugins: [
|
|
23
|
+
jsonImport(),
|
|
24
|
+
commonjsRequire({
|
|
25
|
+
dynamicRequireRoot: RootIndex.manifest.workspacePath,
|
|
26
|
+
dynamicRequireTargets: (output.format === 'commonjs' ? files : [])
|
|
27
|
+
}),
|
|
28
|
+
...(output.format === 'module' ? [travettoImportPlugin(entry, files)] : []),
|
|
29
|
+
nodeResolve({ preferBuiltins: true }),
|
|
30
|
+
...(output.sourcemap !== 'hidden' && output.sourcemap !== false ? [sourceMaps({})] : []),
|
|
31
|
+
...(output.compact ? [terser(getTerserConfig())] : [])
|
|
32
|
+
]
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -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'];
|