@travetto/pack 3.0.0-rc.2 → 3.0.0-rc.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -40,7 +40,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/resources/support/bin)
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
- "displayName": "Pack",
4
- "version": "3.0.0-rc.2",
3
+ "version": "3.0.0-rc.20",
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
- "index.d.ts",
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
- "@travetto/base": "^3.0.0-rc.2",
29
- "@types/picomatch": "^2.3.0",
30
- "picomatch": "^2.3.1"
27
+ "@rollup/plugin-commonjs": "^24.0.1",
28
+ "@rollup/plugin-json": "^6.0.0",
29
+ "@rollup/plugin-node-resolve": "^15.0.1",
30
+ "@rollup/plugin-terser": "^0.4.0",
31
+ "@travetto/base": "^3.0.0-rc.16",
32
+ "rollup": "^3.17.2",
33
+ "rollup-plugin-sourcemaps": "^0.6.3"
31
34
  },
32
35
  "peerDependencies": {
33
- "@travetto/cli": "^3.0.0-rc.2"
36
+ "@travetto/cli": "^3.0.0-rc.18"
34
37
  },
35
38
  "peerDependenciesMeta": {
36
39
  "@travetto/cli": {
37
40
  "optional": true
38
41
  }
39
42
  },
40
- "docDependencies": {
41
- "@travetto/rest": true,
42
- "@travetto/rest-aws-lambda": true
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,96 @@
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'];
83
+
84
+ if (cfg.ejectFile) {
85
+ yield ActiveShellCommand.comment(title);
86
+ for (const tag of tags) {
87
+ yield [...cmd, tag];
88
+ }
89
+ } else {
90
+ yield [title];
91
+ for (const tag of tags) {
92
+ await ExecUtil.spawn(cmd[0], [...cmd.slice(1), tag], { stdio: [0, 'pipe', 2] }).result;
93
+ }
94
+ }
95
+ }
96
+ }
@@ -0,0 +1,273 @@
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
+ /**
18
+ * Clean out pack workspace, removing all content
19
+ */
20
+ static async * clean(cfg: CommonPackConfig): AsyncIterable<string[]> {
21
+ if (!cfg.clean) {
22
+ return;
23
+ }
24
+
25
+ const title = cliTpl`${{ title: 'Cleaning Output' }} ${{ path: cfg.workspace }}`;
26
+
27
+ if (cfg.ejectFile) {
28
+ yield ActiveShellCommand.comment(title);
29
+ yield ActiveShellCommand.rmRecursive(cfg.workspace);
30
+ if (cfg.output) {
31
+ yield ActiveShellCommand.rmRecursive(cfg.output);
32
+ }
33
+ yield ActiveShellCommand.mkdir(cfg.workspace);
34
+ } else {
35
+ yield [title];
36
+ await fs.rm(cfg.workspace, { recursive: true, force: true });
37
+ if (cfg.output) {
38
+ await fs.rm(cfg.output, { recursive: true, force: true });
39
+ }
40
+ await fs.mkdir(cfg.workspace, { recursive: true });
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Invoke bundler (rollup) to produce output in workspace folder
46
+ */
47
+ static async * bundle(cfg: CommonPackConfig): AsyncIterable<string[]> {
48
+ const cwd = RootIndex.outputRoot;
49
+
50
+ const bundleCommand = ['npx', 'rollup', '-c', 'node_modules/@travetto/pack/support/bin/rollup.js'];
51
+
52
+ const env = Object.fromEntries(([
53
+ ['BUNDLE_ENTRY', cfg.entryPoint],
54
+ ['BUNDLE_ENTRY_NAME', cfg.entryCommand],
55
+ ['BUNDLE_COMPRESS', cfg.minify],
56
+ ['BUNDLE_SOURCEMAP', cfg.sourcemap],
57
+ ['BUNDLE_SOURCES', cfg.includeSources],
58
+ ['BUNDLE_OUTPUT', cfg.workspace],
59
+ ['BUNDLE_FORMAT', RootIndex.manifest.moduleType],
60
+ ['TRV_MANIFEST', RootIndex.getModule(cfg.module)!.outputPath]
61
+ ] as const)
62
+ .filter(x => x[1] === false || x[1])
63
+ .map(x => [x[0], `${x[1]}`])
64
+ );
65
+
66
+ const props = (['minify', 'sourcemap', 'entryPoint'] as const)
67
+ .map(k => cliTpl`${{ subtitle: k }}=${{ param: cfg[k] }}`).join(' ');
68
+
69
+ const title = cliTpl`${{ title: 'Bundling Output' }} ${props}`;
70
+
71
+ if (cfg.ejectFile) {
72
+ yield ActiveShellCommand.comment(title);
73
+ yield* Object.entries(env).filter(x => !!x[1]).map(x =>
74
+ ActiveShellCommand.export(x[0], x[1])
75
+ );
76
+ yield ActiveShellCommand.chdir(cwd);
77
+ yield bundleCommand;
78
+ yield ActiveShellCommand.chdir(path.cwd());
79
+ } else {
80
+ yield [title];
81
+ await ExecUtil.spawn(bundleCommand[0], bundleCommand.slice(1), { cwd, env, stdio: ['inherit', 'pipe', 'pipe'] }).result;
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Write out package.json, to help define how output .js file should be interpreted
87
+ */
88
+ static async * writePackageJson(cfg: CommonPackConfig): AsyncIterable<string[]> {
89
+ const file = 'package.json';
90
+ const title = cliTpl`${{ title: 'Writing' }} ${{ path: file }}`;
91
+ const pkg = { type: RootIndex.manifest.moduleType };
92
+
93
+ if (cfg.ejectFile) {
94
+ yield ActiveShellCommand.comment(title);
95
+ yield* ActiveShellCommand.createFile(
96
+ path.resolve(cfg.workspace, file),
97
+ [JSON.stringify(pkg)]
98
+ );
99
+ } else {
100
+ yield [title];
101
+ await writeRawFile(
102
+ path.resolve(cfg.workspace, file),
103
+ JSON.stringify(pkg, null, 2)
104
+ );
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Define .env.js file to control manifest location
110
+ */
111
+ static async * writeEnv(cfg: CommonPackConfig): AsyncIterable<string[]> {
112
+ const file = '.env.js';
113
+ const title = cliTpl`${{ title: 'Writing' }} ${{ path: file }}`;
114
+ const env = {
115
+ TRV_MANIFEST: `node_modules/${cfg.module}`,
116
+ TRV_CLI_IPC: ''
117
+ };
118
+
119
+ if (cfg.ejectFile) {
120
+ yield ActiveShellCommand.comment(title);
121
+ yield* ActiveShellCommand.createFile(
122
+ path.resolve(cfg.workspace, file),
123
+ PackUtil.buildEnvJS(env)
124
+ );
125
+ } else {
126
+ yield [title];
127
+ await writeRawFile(
128
+ path.resolve(cfg.workspace, file),
129
+ PackUtil.buildEnvJS(env).join('\n')
130
+ );
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Create launcher scripts (.sh, .cmd) to run output
136
+ */
137
+ static async * writeEntryScript(cfg: CommonPackConfig): AsyncIterable<string[]> {
138
+ const title = 'Writing entry scripts';
139
+
140
+ const files = ([['posix', 'sh'], ['win32', 'cmd']] as const)
141
+ .map(([type, ext]) => ({
142
+ fileTitle: cliTpl`${{ title }} ${{ path: `${cfg.entryCommand}.${ext}` }} args=(${{ param: cfg.entryArguments.join(' ') }})`,
143
+ file: `${cfg.entryCommand}.${ext}`,
144
+ text: [
145
+ ShellCommands[type].scriptOpen(),
146
+ ShellCommands[type].chdirScript(),
147
+ ShellCommands[type].callCommandWithAllArgs('node', cfg.entryCommand, ...cfg.entryArguments),
148
+ ].map(x => x.join(' '))
149
+ }));
150
+
151
+ if (cfg.ejectFile) {
152
+ for (const { fileTitle, text, file } of files) {
153
+ yield ActiveShellCommand.comment(fileTitle);
154
+ yield* ActiveShellCommand.createFile(path.resolve(cfg.workspace, file), text, '755');
155
+ }
156
+ } else {
157
+ for (const { fileTitle, text, file } of files) {
158
+ yield [fileTitle];
159
+ await writeRawFile(path.resolve(cfg.workspace, file), text.join('\n'), '755');
160
+ }
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Copy over /resources folder into workspace, will get packaged into final output
166
+ */
167
+ static async * copyResources(cfg: CommonPackConfig): AsyncIterable<string[]> {
168
+ const resources = {
169
+ count: RootIndex.mainModule.files.resources?.length ?? 0,
170
+ src: path.resolve(RootIndex.mainModule.sourcePath, 'resources'),
171
+ dest: path.resolve(cfg.workspace, 'resources')
172
+ };
173
+
174
+ const copyFiles = [
175
+ RootIndex.manifest.modules[RootIndex.mainModule.name],
176
+ RootIndex.manifest.modules['@travetto/manifest']
177
+ ].map(mod => ({
178
+ src: path.resolve(RootIndex.outputRoot, mod.outputFolder, 'package.json'),
179
+ dest: path.resolve(cfg.workspace, mod.outputFolder, 'package.json'),
180
+ destFolder: path.resolve(cfg.workspace, mod.outputFolder)
181
+ }));
182
+
183
+ const title = cliTpl`${{ title: 'Copying over resources' }}`;
184
+
185
+ if (cfg.ejectFile) {
186
+ yield ActiveShellCommand.comment(title);
187
+ yield* copyFiles.flatMap(mod => [
188
+ ActiveShellCommand.mkdir(path.dirname(mod.dest)),
189
+ ActiveShellCommand.copy(mod.src, mod.dest)
190
+ ]);
191
+ if (resources.count) {
192
+ yield ActiveShellCommand.copyRecursive(resources.src, path.resolve(cfg.workspace, 'resources'));
193
+ }
194
+ } else {
195
+ yield [title];
196
+
197
+ for (const { src, dest, destFolder } of copyFiles) {
198
+ await fs.mkdir(destFolder, { recursive: true });
199
+ await fs.copyFile(src, dest);
200
+ }
201
+
202
+ if (resources.count) {
203
+ await fs.mkdir(path.dirname(resources.dest), { recursive: true });
204
+ await PackUtil.copyRecursive(resources.src, resources.dest);
205
+ }
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Generate the trv-app-cache.json for @travetto/app, which is needed for 'running' programs
211
+ */
212
+ static async * primeAppCache(cfg: CommonPackConfig): AsyncIterable<string[]> {
213
+ const isRun = cfg.entryCommand === 'cli' && cfg.entryArguments.filter(x => !x.startsWith('-'))[0] === 'run';
214
+ if (!isRun) {
215
+ return;
216
+ }
217
+
218
+ const appCacheCmd = ['npx', 'trv', 'main', '@travetto/app/support/bin/list'];
219
+ const sub = path.join(RootIndex.manifest.modules[RootIndex.mainModule.name].outputFolder, 'trv-app-cache.json');
220
+ const title = cliTpl`${{ title: 'Generating App Cache' }} ${{ path: sub }}`;
221
+ const env = { DEBUG: '0', TRV_MODULE: cfg.module };
222
+ const appCache = path.resolve(cfg.workspace, sub);
223
+
224
+
225
+ if (cfg.ejectFile) {
226
+ yield ActiveShellCommand.comment(title);
227
+ yield ActiveShellCommand.mkdir(path.dirname(appCache));
228
+ yield [...Object.entries(env).map(x => `${x[0]}=${x[1]}`), ...appCacheCmd, '>', appCache];
229
+ } else {
230
+ yield [title];
231
+ const { stdout } = await ExecUtil.spawn(appCacheCmd[0], appCacheCmd.slice(1), { env }).result;
232
+
233
+ await fs.mkdir(path.dirname(appCache), { recursive: true });
234
+ await fs.writeFile(appCache, stdout, 'utf8');
235
+ }
236
+ }
237
+
238
+ /**
239
+ * Produce the output manifest, only including prod dependencies
240
+ */
241
+ static async * writeManifest(cfg: CommonPackConfig): AsyncIterable<string[]> {
242
+ const out = path.resolve(cfg.workspace, 'node_modules', cfg.module);
243
+ const cmd = ['npx', 'trv', 'manifest', out, 'prod'];
244
+ const env = { TRV_MODULE: cfg.module };
245
+ const title = cliTpl`${{ title: 'Writing Manifest' }} ${{ path: path.join('node_modules', cfg.module) }}`;
246
+
247
+ if (cfg.ejectFile) {
248
+ yield ActiveShellCommand.comment(title);
249
+ yield [...Object.entries(env).map(([k, v]) => `${k}=${v}`), ...cmd];
250
+ } else {
251
+ yield [title];
252
+ await ExecUtil.spawn(cmd[0], cmd.slice(1), { env, stdio: ['inherit', 'ignore', 'inherit'] }).result;
253
+ }
254
+ }
255
+
256
+ /**
257
+ * Generate ZIP file for workspace
258
+ */
259
+ static async * compress(cfg: CommonPackConfig): AsyncIterable<string[]> {
260
+ const title = cliTpl`${{ title: 'Compressing' }} ${{ path: cfg.output }}`;
261
+
262
+ if (cfg.ejectFile) {
263
+ yield ActiveShellCommand.comment(title);
264
+ yield ActiveShellCommand.chdir(cfg.workspace);
265
+ yield ActiveShellCommand.zip(cfg.output);
266
+ yield ActiveShellCommand.chdir(path.cwd());
267
+ } else {
268
+ yield [title];
269
+ const [cmd, ...args] = ActiveShellCommand.zip(cfg.output);
270
+ await ExecUtil.spawn(cmd, args, { cwd: cfg.workspace }).result;
271
+ }
272
+ }
273
+ }
@@ -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'];