isolate-package 0.0.0 → 1.0.0-beta.1

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
@@ -1,3 +1,196 @@
1
1
  # Isolate Package
2
2
 
3
- Coming soon...
3
+ Isolate a monorepo workspace package so that it can be deployed as a completely
4
+ self-contained directory with the sources of all local dependencies included.
5
+
6
+ **NOTE**: This package has only been tested with [PNPM](https://pnpm.io/) but it
7
+ was designed to be compatible with NPM and Yarn. That being said, I am
8
+ personally very happy with the switch to PNPM and I encourage anyone to give it
9
+ a try.
10
+
11
+ ## Motivation
12
+
13
+ This solution was developed out of a desire to deploy to
14
+ [Firebase](https://firebase.google.com/) from a monorepo without resorting to
15
+ hacks, shell scripts and manual tasks. You can read more about this issue
16
+ [here](#the-problem-with-firebase-in-monorepos).
17
+
18
+ There is nothing Firebase specific to this solution but I am currently not aware
19
+ of any other reason to isolate a workspace package. If you find a different
20
+ use-case, I would love to hear about it.
21
+
22
+ ## Features
23
+
24
+ These are the key aspects that set this approach apart from other solutions:
25
+
26
+ - Zero-config for the majority of use-cases. No manual steps involved.
27
+ - Designed to support NPM, Yarn and PNPM workspaces.
28
+ - Compatible with the firebase CLI.
29
+ - Uses a pack/unpack approach to only isolate files that would have been part of
30
+ the published package, so the resulting output only contains the necessary
31
+ files.
32
+ - Isolates dependencies recursively. If package A depends on local package B
33
+ which depends on local package C, all of them will be isolated.
34
+ - Include and adjust the lockfile so you can be sure the isolated deployment is
35
+ using the exact same versions.
36
+ - Optionally include dev dependencies in the isolated output.
37
+
38
+ ## Usage
39
+
40
+ Run `pnpm add isolate-package -D` or do the equivalent for `yarn` or `npm`.
41
+
42
+ This package exposes the `isolate` executable. Once installed you can run `npx
43
+ isolate` in any package directory _after_ you have build the source files, and
44
+ by default this will produce a directory at `./isolate`.
45
+
46
+ You will probably want to add the output directory to your `.gitignore` file.
47
+
48
+ ### Deploy to Firebase
49
+
50
+ This solution allows you to deploy to Firebase from multiple packages in your
51
+ monorepo, so I advise you to co-locate your `firebase.json` file with the
52
+ package, and not place it in the root of the monorepo.
53
+
54
+ In order to deploy to Firebase, the `functions.source` setting in
55
+ `firebase.json` needs to point to the isolated output folder, which would be
56
+ `./isolate` when using the default configuration.
57
+
58
+ The `predeploy` phase should first build and then isolate the output.
59
+
60
+ Here's an example using [Turborepo](https://turbo.build/) for the build process:
61
+
62
+ ```json
63
+ {
64
+ "functions": {
65
+ "source": "./isolate",
66
+ "predeploy": ["turbo build", "isolate"]
67
+ }
68
+ }
69
+ ```
70
+
71
+ With this configuration you can run `firebase deploy --only functions` from the
72
+ package you isolated.
73
+
74
+ If you like to deploy to Firebase Functions from multiple packages you will also
75
+ need to configure a unique `codebase` identifier for each of them. For more
76
+ information, [read
77
+ this](https://firebase.google.com/docs/functions/beta/organize-functions).
78
+
79
+ ## Configuration
80
+
81
+ For most users the defaults are fine and no configuration is needed. Otherwise,
82
+ you can configure the isolate process by placing a `isolate.config.json` file in
83
+ the root of the package that you want to isolate.
84
+
85
+ Below you find a description of every available config option.
86
+
87
+ ### logLevel
88
+
89
+ Type: `"info" | "debug" | "warn" | "error"`, default: `"info"`.
90
+
91
+ Because the configuration loader depends on this setting, its output is not
92
+ affected by this setting. If you want to debug the configuration set
93
+ `ISOLATE_CONFIG_LOG_LEVEL=debug` before you run `isolate`
94
+
95
+ ### workspaceRoot
96
+
97
+ Type: `string`, default: `"../.."`
98
+
99
+ The relative path, from the package you want to isolate to the root of the
100
+ workspace / monorepo.
101
+
102
+ In a typical monorepo you will have a `packages` and possibly an `apps`
103
+ directory in the root of the workspace, so any package you want to isolate would
104
+ be 2 levels up from the root.
105
+
106
+ ### workspacePackages
107
+
108
+ Type: `string[] | undefined`, default: `undefined`
109
+
110
+ When workspacePackages is not defined, `isolate` will try to find the packages
111
+ in the workspace by looking up the settings in `pnpm-workspace.yaml` or
112
+ `package.json` files depending on the detected package manager.
113
+
114
+ In case this fails, you can override this process by specifying globs manually.
115
+ For example `"workspacePackages": ["packages/*", "apps/*"]`. Paths are relative
116
+ from the root of the workspace.
117
+
118
+ ### isolateOutDir
119
+
120
+ Type: `string`, default: `"isolate"`
121
+
122
+ The name of the isolate output directory.
123
+
124
+ ### includeDevDependencies
125
+
126
+ Type: `boolean`, default: `false`
127
+
128
+ By default devDependencies are ignored and stripped from the isolated output
129
+ `package.json` files. If you enable this the devDependencies will be included
130
+ and isolated just like the production dependencies.
131
+
132
+ ### tsconfigPath
133
+
134
+ Type: `string`, default: `"./tsconfig.json"`
135
+
136
+ The path to the `tsconfig.json` file relative to the package you want to
137
+ isolate. The tsconfig is only used for reading the `compilerOptions.outDir`
138
+ setting. If no tsconfig is found, possibly because you are not using Typescript
139
+ in your project, the process will fall back to the `buildOutputDir` setting.
140
+
141
+ ### buildOutputDir
142
+
143
+ Type: `string | undefined`, default: `undefined`
144
+
145
+ When you are not using Typescript you can use this setting to specify where the
146
+ build output files are located.
147
+
148
+ ## TODO
149
+
150
+ - [ ] Alter the pnpm lockfile
151
+ - [ ] Add support for Yarn and NPM lock files
152
+
153
+ ## Used Terminology
154
+
155
+ The various package managers, while being very similar, seem to use a different
156
+ definition for the term "workspace". If you want to read the code it might be
157
+ good to know that I consider the workspace to be the monorepo itself. The
158
+ overall structure that holds all the packages. Also, in the code you see the
159
+ word manifest a lot. It refers to the contents of a package.json file.
160
+
161
+ ## The problem with Firebase in monorepos
162
+
163
+ When deploying to Firebase it expects a folder with source files together with a
164
+ package.json file. This folder will be zipped and uploaded after which Firebase
165
+ will run an npm or yarn install in the cloud as part of the deployment pipeline.
166
+
167
+ In a private monorepo your Firebase package(s) typically have one or more shared
168
+ local dependencies that are never published to NPM. When Firebase tries to look
169
+ up those dependencies from the package.json they can not be found and deployment
170
+ fails.
171
+
172
+ In order to solve this you could try to use a bundler like Webpack to include
173
+ dependencies code in the bundle and then strip those packages from the list in
174
+ the package.json that is sent to Firebase, so doesn't know about them, but this
175
+ strategy quickly falls apart. If the shared packages themselves do not bundle
176
+ all of their dependencies in their build output, then those dependencies will
177
+ still need to be installed, and Firebase wouldn't know about it.
178
+
179
+ Without Firebase natively supporting monorepos, the only solution seems to be to
180
+ bundle each shared workspace dependency in a way that its build output, together
181
+ with its package.json file, becomes part of the overall bundle that is uploaded
182
+ in the Firebase deployment. This way, Firebase can find each shared package
183
+ source code, and also know what dependencies need to be installed to make that
184
+ source code work.
185
+
186
+ There are many different hacks that people have come up with [discussing this
187
+ issue](https://github.com/firebase/firebase-tools/issues/653) but they all seem
188
+ to come down to this:
189
+
190
+ - Copy the shared packages to some deployment folder
191
+ - Create a modified package.json file for the deployment that points all local
192
+ dependencies to the copied files for each shared dependency.
193
+ - Point the Firebase deploy process to that folder
194
+
195
+ The `isolate` process from this solution takes a similar approach but is more
196
+ sophisticated and hides all complexity from the user.
package/dist/index.js CHANGED
@@ -1,7 +1,550 @@
1
1
  // src/index.ts
2
- async function src_default() {
2
+ import fs10 from "fs-extra";
3
+ import assert2 from "node:assert";
4
+ import path13 from "node:path";
5
+ import sourceMaps from "source-map-support";
6
+
7
+ // src/helpers/adapt-manifest-files.ts
8
+ import fs from "fs-extra";
9
+ import path from "node:path";
10
+ async function adaptManifestFiles(localDependencies, packagesRegistry, isolateDir) {
11
+ await Promise.all(
12
+ localDependencies.map(async (packageName) => {
13
+ const { manifest, rootRelativeDir } = packagesRegistry[packageName];
14
+ const outputManifest = adaptManifestWorkspaceDeps(
15
+ { manifest, packagesRegistry },
16
+ { includeDevDependencies: getConfig().includeDevDependencies }
17
+ );
18
+ await fs.writeFile(
19
+ path.join(isolateDir, rootRelativeDir, "package.json"),
20
+ JSON.stringify(outputManifest, null, 2)
21
+ );
22
+ })
23
+ );
3
24
  }
4
- export {
5
- src_default as default
25
+
26
+ // src/helpers/adapt-manifest-workspace-deps.ts
27
+ import { omit } from "lodash-es";
28
+
29
+ // src/utils/filter-object-undefined.ts
30
+ function filterObjectUndefined(object) {
31
+ return Object.fromEntries(
32
+ Object.entries(object).filter(([_, value]) => value !== void 0)
33
+ );
34
+ }
35
+
36
+ // src/utils/get-relative-path.ts
37
+ function getRelativePath(path14, relativeTo) {
38
+ return path14.replace(relativeTo, "");
39
+ }
40
+
41
+ // src/utils/inspect-value.ts
42
+ import { inspect } from "node:util";
43
+ function inspectValue(value) {
44
+ return inspect(value, false, 4, true);
45
+ }
46
+
47
+ // src/utils/json.ts
48
+ import fs2 from "fs-extra";
49
+ function readTypedJsonSync(filePath) {
50
+ const rawContent = fs2.readFileSync(filePath, "utf-8");
51
+ const data = JSON.parse(rawContent);
52
+ return data;
53
+ }
54
+ async function readTypedJson(filePath) {
55
+ const rawContent = await fs2.readFile(filePath, "utf-8");
56
+ const data = JSON.parse(rawContent);
57
+ return data;
58
+ }
59
+
60
+ // src/utils/logger.ts
61
+ import chalk from "chalk";
62
+ function createLogger(logLevel) {
63
+ return {
64
+ debug(...args) {
65
+ if (logLevel === "debug") {
66
+ console.log(chalk.blue("debug"), ...args);
67
+ }
68
+ },
69
+ info(...args) {
70
+ if (logLevel === "debug" || logLevel === "info") {
71
+ console.log(chalk.green("info"), ...args);
72
+ }
73
+ },
74
+ warn(...args) {
75
+ if (logLevel === "debug" || logLevel === "info" || logLevel === "warn") {
76
+ console.log(chalk.yellow("warning"), ...args);
77
+ }
78
+ },
79
+ error(...args) {
80
+ console.log(chalk.red("error"), ...args);
81
+ }
82
+ };
83
+ }
84
+
85
+ // src/utils/pack.ts
86
+ import { exec } from "node:child_process";
87
+ import path2 from "node:path";
88
+ async function pack(srcDir, destDir, packageManager) {
89
+ const log2 = createLogger(getConfig().logLevel);
90
+ const cwd = process.cwd();
91
+ process.chdir(srcDir);
92
+ switch (packageManager) {
93
+ case "pnpm": {
94
+ const stdout = await new Promise((resolve, reject) => {
95
+ exec(`pnpm pack --pack-destination ${destDir}`, (err, stdout2) => {
96
+ if (err) {
97
+ return reject(err);
98
+ }
99
+ resolve(stdout2);
100
+ });
101
+ });
102
+ const packedFilePath = stdout.trim();
103
+ log2.debug("Packed", path2.basename(packedFilePath));
104
+ process.chdir(cwd);
105
+ return packedFilePath;
106
+ }
107
+ case "yarn":
108
+ case "npm": {
109
+ const stdout = await new Promise((resolve, reject) => {
110
+ exec(`npm pack --pack-destination ${destDir}`, (err, stdout2) => {
111
+ if (err) {
112
+ return reject(err);
113
+ }
114
+ resolve(stdout2);
115
+ });
116
+ });
117
+ const packedFileName = stdout.trim();
118
+ log2.debug("Packed", packedFileName);
119
+ process.chdir(cwd);
120
+ return path2.join(destDir, packedFileName);
121
+ }
122
+ }
123
+ }
124
+
125
+ // src/utils/unpack.ts
126
+ import fs3 from "fs-extra";
127
+ import tar from "tar-fs";
128
+ import { createGunzip } from "zlib";
129
+ async function unpack(filePath, unpackDir) {
130
+ await new Promise((resolve, reject) => {
131
+ fs3.createReadStream(filePath).pipe(createGunzip()).pipe(tar.extract(unpackDir)).on("finish", () => resolve()).on("error", (err) => reject(err));
132
+ });
133
+ }
134
+
135
+ // src/utils/yaml.ts
136
+ import fs4 from "fs-extra";
137
+ import yaml from "yaml";
138
+ function readTypedYamlSync(filePath) {
139
+ const rawContent = fs4.readFileSync(filePath, "utf-8");
140
+ const data = yaml.parse(rawContent);
141
+ return data;
142
+ }
143
+
144
+ // src/helpers/adapt-manifest-workspace-deps.ts
145
+ function adaptManifestWorkspaceDeps({
146
+ manifest,
147
+ packagesRegistry
148
+ }, opts = {}) {
149
+ return Object.assign(
150
+ omit(manifest, ["scripts", "devDependencies"]),
151
+ filterObjectUndefined({
152
+ dependencies: manifest.dependencies ? patchWorkspaceEntries(manifest.dependencies, packagesRegistry) : void 0,
153
+ devDependencies: opts.includeDevDependencies && manifest.devDependencies ? patchWorkspaceEntries(manifest.devDependencies, packagesRegistry) : void 0
154
+ })
155
+ );
156
+ }
157
+
158
+ // src/helpers/adapt-target-package-manifest.ts
159
+ import fs5 from "fs-extra";
160
+ import path3 from "node:path";
161
+ async function adaptTargetPackageManifest(manifest, packagesRegistry, isolateDir) {
162
+ const outputManifest = adaptManifestWorkspaceDeps(
163
+ {
164
+ manifest,
165
+ packagesRegistry
166
+ },
167
+ { includeDevDependencies: getConfig().includeDevDependencies }
168
+ );
169
+ await fs5.writeFile(
170
+ path3.join(isolateDir, "package.json"),
171
+ JSON.stringify(outputManifest, null, 2)
172
+ );
173
+ }
174
+
175
+ // src/helpers/config.ts
176
+ import { isEmpty } from "lodash-es";
177
+ import path4 from "node:path";
178
+ var configDefaults = {
179
+ logLevel: "info",
180
+ workspaceRoot: "../..",
181
+ isolateOutDir: "./isolate",
182
+ includeDevDependencies: false,
183
+ tsconfigPath: "./tsconfig.json",
184
+ workspacePackages: void 0,
185
+ buildOutputDir: void 0
6
186
  };
187
+ var __config;
188
+ var validConfigKeys = Object.keys(configDefaults);
189
+ var CONFIG_FILE_NAME = "isolate.config.json";
190
+ function getConfig() {
191
+ if (__config) {
192
+ return __config;
193
+ }
194
+ const log2 = createLogger(
195
+ process.env.ISOLATE_CONFIG_LOG_LEVEL ?? "warn"
196
+ );
197
+ const configFilePath = path4.join(process.cwd(), CONFIG_FILE_NAME);
198
+ log2.debug(`Attempting to load config from ${configFilePath}`);
199
+ const configFromFile = readTypedJsonSync(
200
+ path4.join(process.cwd(), CONFIG_FILE_NAME)
201
+ );
202
+ const foreignKeys = Object.keys(configFromFile).filter(
203
+ (key) => !validConfigKeys.includes(key)
204
+ );
205
+ if (!isEmpty(foreignKeys)) {
206
+ log2.warn(`Found invalid config settings:`, foreignKeys.join(", "));
207
+ }
208
+ const config2 = Object.assign(
209
+ {},
210
+ configDefaults,
211
+ configFromFile
212
+ );
213
+ log2.debug("Using configuration:", inspectValue(config2));
214
+ __config = config2;
215
+ return config2;
216
+ }
217
+
218
+ // src/helpers/create-packages-registry.ts
219
+ import { globSync } from "glob";
220
+ import { set } from "lodash-es";
221
+ import path7 from "node:path";
222
+
223
+ // src/helpers/find-packages-globs.ts
224
+ import path6 from "node:path";
225
+
226
+ // src/helpers/detect-package-manager.ts
227
+ import fs6 from "fs-extra";
228
+ import path5 from "node:path";
229
+ function detectPackageManager(workspaceRoot) {
230
+ if (fs6.existsSync(path5.join(workspaceRoot, "pnpm-lock.yaml"))) {
231
+ return "pnpm";
232
+ }
233
+ if (fs6.existsSync(path5.join(workspaceRoot, "yarn.lock"))) {
234
+ return "yarn";
235
+ }
236
+ if (fs6.existsSync(path5.join(workspaceRoot, "package-lock.json"))) {
237
+ return "npm";
238
+ }
239
+ throw new Error(`Failed to detect package manager`);
240
+ }
241
+
242
+ // src/helpers/find-packages-globs.ts
243
+ function findPackagesGlobs(workspaceRootDir) {
244
+ const log2 = createLogger(getConfig().logLevel);
245
+ const packageManager = detectPackageManager(workspaceRootDir);
246
+ switch (packageManager) {
247
+ case "pnpm": {
248
+ const { packages: globs } = readTypedYamlSync(
249
+ path6.join(workspaceRootDir, "pnpm-workspace.yaml")
250
+ );
251
+ log2.debug("Detected pnpm packages globs:", inspectValue(globs));
252
+ return globs;
253
+ }
254
+ case "yarn":
255
+ case "npm": {
256
+ const workspaceRootManifestPath = path6.join(
257
+ workspaceRootDir,
258
+ "package.json"
259
+ );
260
+ const { workspaces } = readTypedJsonSync(
261
+ workspaceRootManifestPath
262
+ );
263
+ if (!workspaces) {
264
+ throw new Error(
265
+ `No workspaces field found in ${workspaceRootManifestPath}`
266
+ );
267
+ }
268
+ return workspaces;
269
+ }
270
+ }
271
+ }
272
+
273
+ // src/helpers/create-packages-registry.ts
274
+ async function createPackagesRegistry(workspaceRootDir, workspacePackagesOverride) {
275
+ const log2 = createLogger(getConfig().logLevel);
276
+ if (workspacePackagesOverride) {
277
+ log2.debug(
278
+ `Override workspace packages via config: ${workspacePackagesOverride}`
279
+ );
280
+ }
281
+ const packagesGlobs = workspacePackagesOverride ?? findPackagesGlobs(workspaceRootDir);
282
+ const cwd = process.cwd();
283
+ process.chdir(workspaceRootDir);
284
+ const allPackages = packagesGlobs.flatMap((glob) => globSync(glob));
285
+ const registry = (await Promise.all(
286
+ allPackages.map(async (rootRelativeDir) => {
287
+ log2.debug(`Registering package ${rootRelativeDir}`);
288
+ const manifest = await readTypedJson(
289
+ path7.join(rootRelativeDir, "package.json")
290
+ );
291
+ return {
292
+ manifest,
293
+ rootRelativeDir,
294
+ absoluteDir: path7.join(workspaceRootDir, rootRelativeDir)
295
+ };
296
+ })
297
+ )).reduce(
298
+ (acc, info) => set(acc, info.manifest.name, info),
299
+ {}
300
+ );
301
+ process.chdir(cwd);
302
+ return registry;
303
+ }
304
+
305
+ // src/helpers/find-build-output-dir.ts
306
+ import path8 from "node:path";
307
+ async function findBuildOutputDir(targetPackageDir) {
308
+ const config2 = getConfig();
309
+ const log2 = createLogger(getConfig().logLevel);
310
+ if (config2.buildOutputDir) {
311
+ log2.debug("Using buildOutputDir from config:", config2.buildOutputDir);
312
+ return path8.join(targetPackageDir, config2.buildOutputDir);
313
+ }
314
+ const tsconfigPath = path8.join(targetPackageDir, config2.tsconfigPath);
315
+ try {
316
+ const tsconfig = await readTypedJson(tsconfigPath);
317
+ return path8.join(targetPackageDir, tsconfig.compilerOptions.outDir);
318
+ } catch (err) {
319
+ throw new Error(
320
+ `Failed to find tsconfig at ${tsconfigPath}. Without a buildOutputDir config setting a tsconfig file is required to know where the build output directory is located.If your tsconfig is located elsewhere you can configure it using the tsconfigPath setting.`
321
+ );
322
+ }
323
+ }
324
+
325
+ // src/helpers/list-local-dependencies.ts
326
+ function listLocalDependencies(manifest, packagesRegistry, { includeDevDependencies = false } = {}) {
327
+ const allWorkspacePackageNames = Object.keys(packagesRegistry);
328
+ const localDependencyPackageNames = (includeDevDependencies ? [
329
+ ...Object.keys(manifest.dependencies ?? {}),
330
+ ...Object.keys(manifest.devDependencies ?? {})
331
+ ] : Object.keys(manifest.dependencies ?? {})).filter((name) => allWorkspacePackageNames.includes(name));
332
+ const nestedLocalDependencies = localDependencyPackageNames.flatMap(
333
+ (packageName) => listLocalDependencies(
334
+ packagesRegistry[packageName].manifest,
335
+ packagesRegistry,
336
+ { includeDevDependencies }
337
+ )
338
+ );
339
+ return localDependencyPackageNames.concat(nestedLocalDependencies);
340
+ }
341
+
342
+ // src/helpers/manifest.ts
343
+ import path9 from "node:path";
344
+
345
+ // src/helpers/pack-dependencies.ts
346
+ import assert from "node:assert";
347
+ async function packDependencies({
348
+ /**
349
+ * All packages found in the monorepo by workspaces declaration
350
+ */
351
+ packagesRegistry,
352
+ /**
353
+ * The package names that appear to be local dependencies
354
+ */
355
+ localDependencies,
356
+ /**
357
+ * The directory where the isolated package and all its dependencies will end
358
+ * up. This is also the directory from where the package will be deployed. By
359
+ * default it is a subfolder in targetPackageDir called "isolate" but you can
360
+ * configure it.
361
+ */
362
+ packDestinationDir,
363
+ packageManager
364
+ }) {
365
+ const config2 = getConfig();
366
+ const log2 = createLogger(config2.logLevel);
367
+ const packedFileByName = {};
368
+ for (const dependency of localDependencies) {
369
+ const def = packagesRegistry[dependency];
370
+ assert(dependency, `Failed to find package definition for ${dependency}`);
371
+ const { name } = def.manifest;
372
+ if (packedFileByName[name]) {
373
+ log2.debug(`Skipping ${name} because it has already been packed`);
374
+ continue;
375
+ }
376
+ packedFileByName[name] = await pack(
377
+ def.absoluteDir,
378
+ packDestinationDir,
379
+ packageManager
380
+ );
381
+ }
382
+ return packedFileByName;
383
+ }
384
+
385
+ // src/helpers/patch-workspace-entries.ts
386
+ function patchWorkspaceEntries(dependencies, packagesRegistry) {
387
+ const log2 = createLogger(getConfig().logLevel);
388
+ const allWorkspacePackageNames = Object.keys(packagesRegistry);
389
+ return Object.fromEntries(
390
+ Object.entries(dependencies).map(([key, value]) => {
391
+ if (allWorkspacePackageNames.includes(key)) {
392
+ const def = packagesRegistry[key];
393
+ log2.debug(`Linking dependency ${key} to file:${def.rootRelativeDir}`);
394
+ return [key, `file:${def.rootRelativeDir}`];
395
+ } else {
396
+ return [key, value];
397
+ }
398
+ })
399
+ );
400
+ }
401
+
402
+ // src/helpers/process-build-output-files.ts
403
+ import fs7 from "fs-extra";
404
+ import path10 from "node:path";
405
+ async function processBuildOutputFiles({
406
+ targetPackageDir,
407
+ tmpDir,
408
+ packageManager,
409
+ isolateDir
410
+ }) {
411
+ const packedFilePath = await pack(targetPackageDir, tmpDir, packageManager);
412
+ const unpackDir = path10.join(tmpDir, "target");
413
+ await unpack(packedFilePath, unpackDir);
414
+ await fs7.copy(path10.join(unpackDir, "package"), isolateDir);
415
+ }
416
+
417
+ // src/helpers/process-lock-file.ts
418
+ import fs8 from "fs-extra";
419
+ import path11 from "node:path";
420
+ function getLockFileName(packageManager) {
421
+ switch (packageManager) {
422
+ case "pnpm":
423
+ return "pnpm-lock.yaml";
424
+ case "yarn":
425
+ return "yarn.lock";
426
+ case "npm":
427
+ return "package-lock.json";
428
+ }
429
+ }
430
+ async function processLockfile(workspaceRootDir, isolateDir, packageManager) {
431
+ const log2 = createLogger(getConfig().logLevel);
432
+ const lockfileName = getLockFileName(packageManager);
433
+ const lockfileSrcPath = path11.join(workspaceRootDir, lockfileName);
434
+ const lockfileDstPath = path11.join(isolateDir, lockfileName);
435
+ log2.debug("Copying lockfile", lockfileSrcPath, "to", isolateDir);
436
+ await fs8.copy(lockfileSrcPath, lockfileDstPath);
437
+ }
438
+
439
+ // src/helpers/unpack-dependencies.ts
440
+ import fs9 from "fs-extra";
441
+ import path12, { join } from "node:path";
442
+ async function unpackDependencies(packedFilesByName, packagesRegistry, tmpDir, isolateDir) {
443
+ const log2 = createLogger(getConfig().logLevel);
444
+ await Promise.all(
445
+ Object.entries(packedFilesByName).map(async ([packageName, filePath]) => {
446
+ const dir = packagesRegistry[packageName].rootRelativeDir;
447
+ const unpackDir = join(tmpDir, dir);
448
+ await unpack(filePath, unpackDir);
449
+ log2.debug("Unpacked", path12.basename(filePath));
450
+ const destinationDir = join(isolateDir, dir);
451
+ await fs9.ensureDir(destinationDir);
452
+ await fs9.move(join(unpackDir, "package"), destinationDir, {
453
+ overwrite: true
454
+ });
455
+ log2.debug(
456
+ `Moved package files to isolate ${getRelativePath(
457
+ destinationDir,
458
+ isolateDir
459
+ )}`
460
+ );
461
+ })
462
+ );
463
+ }
464
+
465
+ // src/index.ts
466
+ var config = getConfig();
467
+ var log = createLogger(config.logLevel);
468
+ sourceMaps.install();
469
+ async function start() {
470
+ const targetPackageDir = process.cwd();
471
+ const buildOutputDir = await findBuildOutputDir(targetPackageDir);
472
+ assert2(
473
+ fs10.existsSync(buildOutputDir),
474
+ `Failed to find build output path at ${buildOutputDir}. Please make sure you built the source before isolating it.`
475
+ );
476
+ const workspaceRootDir = path13.join(
477
+ targetPackageDir,
478
+ config.workspaceRoot,
479
+ "/"
480
+ );
481
+ log.debug("Workspace root", workspaceRootDir);
482
+ log.debug(
483
+ "Isolate target package",
484
+ getRelativePath(targetPackageDir, workspaceRootDir)
485
+ );
486
+ const packageManager = detectPackageManager(workspaceRootDir);
487
+ const isolateDir = path13.join(targetPackageDir, config.isolateOutDir);
488
+ log.debug(
489
+ "Isolate output dir",
490
+ getRelativePath(isolateDir, workspaceRootDir)
491
+ );
492
+ await fs10.ensureDir(isolateDir);
493
+ const packagesRegistry = await createPackagesRegistry(
494
+ workspaceRootDir,
495
+ config.workspacePackages
496
+ );
497
+ const tmpDir = path13.join(isolateDir, "__tmp");
498
+ await fs10.ensureDir(tmpDir);
499
+ if (packageManager === "pnpm") {
500
+ log.debug("Using pnpm to pack dependencies");
501
+ } else {
502
+ log.debug("Using npm to pack dependencies");
503
+ }
504
+ const manifest = await readTypedJson(
505
+ path13.join(targetPackageDir, "package.json")
506
+ );
507
+ const localDependencies = listLocalDependencies(manifest, packagesRegistry, {
508
+ includeDevDependencies: config.includeDevDependencies
509
+ });
510
+ const packedFilesByName = await packDependencies({
511
+ localDependencies,
512
+ packagesRegistry,
513
+ packDestinationDir: tmpDir,
514
+ packageManager
515
+ });
516
+ await unpackDependencies(
517
+ packedFilesByName,
518
+ packagesRegistry,
519
+ tmpDir,
520
+ isolateDir
521
+ );
522
+ await adaptManifestFiles(localDependencies, packagesRegistry, isolateDir);
523
+ await processBuildOutputFiles({
524
+ targetPackageDir,
525
+ tmpDir,
526
+ packageManager,
527
+ isolateDir
528
+ });
529
+ await adaptTargetPackageManifest(manifest, packagesRegistry, isolateDir);
530
+ await processLockfile(workspaceRootDir, isolateDir, packageManager);
531
+ log.debug(
532
+ "Deleting temporary directory",
533
+ getRelativePath(tmpDir, workspaceRootDir)
534
+ );
535
+ await fs10.remove(tmpDir);
536
+ log.info(
537
+ "Isolate completed at",
538
+ path13.join("./", getRelativePath(isolateDir, targetPackageDir))
539
+ );
540
+ }
541
+ start().catch((err) => {
542
+ if (err instanceof Error) {
543
+ log.error(err.stack);
544
+ process.exit(1);
545
+ } else {
546
+ console.error(err);
547
+ }
548
+ });
549
+ process.on("unhandledRejection", log.error);
7
550
  //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/helpers/adapt-manifest-files.ts","../src/helpers/adapt-manifest-workspace-deps.ts","../src/utils/filter-object-undefined.ts","../src/utils/get-relative-path.ts","../src/utils/inspect-value.ts","../src/utils/json.ts","../src/utils/logger.ts","../src/utils/pack.ts","../src/utils/unpack.ts","../src/utils/yaml.ts","../src/helpers/adapt-target-package-manifest.ts","../src/helpers/config.ts","../src/helpers/create-packages-registry.ts","../src/helpers/find-packages-globs.ts","../src/helpers/detect-package-manager.ts","../src/helpers/find-build-output-dir.ts","../src/helpers/list-local-dependencies.ts","../src/helpers/manifest.ts","../src/helpers/pack-dependencies.ts","../src/helpers/patch-workspace-entries.ts","../src/helpers/process-build-output-files.ts","../src/helpers/process-lock-file.ts","../src/helpers/unpack-dependencies.ts"],"sourcesContent":["import fs from \"fs-extra\";\nimport assert from \"node:assert\";\nimport path from \"node:path\";\nimport sourceMaps from \"source-map-support\";\nimport {\n PackageManifestMinimum,\n adaptManifestFiles,\n adaptTargetPackageManifest,\n createPackagesRegistry,\n detectPackageManager,\n findBuildOutputDir,\n getConfig,\n listLocalDependencies,\n packDependencies,\n processBuildOutputFiles,\n processLockfile,\n unpackDependencies,\n} from \"~/helpers\";\nimport { createLogger, getRelativePath, readTypedJson } from \"~/utils\";\n\nconst config = getConfig();\nconst log = createLogger(config.logLevel);\n\nsourceMaps.install();\n\nasync function start() {\n const targetPackageDir = process.cwd();\n\n const buildOutputDir = await findBuildOutputDir(targetPackageDir);\n\n assert(\n fs.existsSync(buildOutputDir),\n `Failed to find build output path at ${buildOutputDir}. Please make sure you built the source before isolating it.`,\n );\n\n /**\n * We want a trailing slash here. Functionally it doesn't matter, but it makes\n * the relative paths print correctly in the cli output.\n */\n const workspaceRootDir = path.join(\n targetPackageDir,\n config.workspaceRoot,\n \"/\",\n );\n\n log.debug(\"Workspace root\", workspaceRootDir);\n log.debug(\n \"Isolate target package\",\n getRelativePath(targetPackageDir, workspaceRootDir),\n );\n\n const packageManager = detectPackageManager(workspaceRootDir);\n\n const isolateDir = path.join(targetPackageDir, config.isolateOutDir);\n\n log.debug(\n \"Isolate output dir\",\n getRelativePath(isolateDir, workspaceRootDir),\n );\n\n /**\n * Make sure the isolate dir exists so we can write to it\n */\n await fs.ensureDir(isolateDir);\n\n /**\n * Build a packages registry so we can find the workspace packages by name and\n * have access to their manifest files and relative paths.\n */\n const packagesRegistry = await createPackagesRegistry(\n workspaceRootDir,\n config.workspacePackages,\n );\n\n const tmpDir = path.join(isolateDir, \"__tmp\");\n await fs.ensureDir(tmpDir);\n\n /**\n * PNPM pack seems to be much faster than NPM pack so we use that when PNPM is\n * detected. We log it here because the pack function will be called\n * recursively.\n */\n if (packageManager === \"pnpm\") {\n log.debug(\"Using pnpm to pack dependencies\");\n } else {\n log.debug(\"Using npm to pack dependencies\");\n }\n\n const manifest = await readTypedJson<PackageManifestMinimum>(\n path.join(targetPackageDir, \"package.json\"),\n );\n\n const localDependencies = listLocalDependencies(manifest, packagesRegistry, {\n includeDevDependencies: config.includeDevDependencies,\n });\n\n const packedFilesByName = await packDependencies({\n localDependencies,\n packagesRegistry,\n packDestinationDir: tmpDir,\n packageManager,\n });\n\n await unpackDependencies(\n packedFilesByName,\n packagesRegistry,\n tmpDir,\n isolateDir,\n );\n\n /**\n * Adapt the manifest files for all the unpacked local dependencies\n */\n await adaptManifestFiles(localDependencies, packagesRegistry, isolateDir);\n\n /**\n * Pack the target package directory, and unpack it in the isolate location\n */\n await processBuildOutputFiles({\n targetPackageDir,\n tmpDir,\n packageManager,\n isolateDir,\n });\n\n /**\n * Copy the target manifest file to the isolate location and adapt its\n * workspace dependencies to point to the isolated packages.\n */\n await adaptTargetPackageManifest(manifest, packagesRegistry, isolateDir);\n\n /**\n * Copy and adapt the lockfile\n */\n await processLockfile(workspaceRootDir, isolateDir, packageManager);\n\n /**\n * Clean up\n */\n log.debug(\n \"Deleting temporary directory\",\n getRelativePath(tmpDir, workspaceRootDir),\n );\n await fs.remove(tmpDir);\n\n log.info(\n \"Isolate completed at\",\n path.join(\"./\", getRelativePath(isolateDir, targetPackageDir)),\n );\n}\n\nstart().catch((err) => {\n if (err instanceof Error) {\n log.error(err.stack);\n process.exit(1);\n } else {\n console.error(err);\n }\n});\n\nprocess.on(\"unhandledRejection\", log.error);\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport {\n PackagesRegistry,\n adaptManifestWorkspaceDeps,\n getConfig,\n} from \"~/helpers\";\n\nexport async function adaptManifestFiles(\n localDependencies: string[],\n packagesRegistry: PackagesRegistry,\n isolateDir: string,\n) {\n await Promise.all(\n localDependencies.map(async (packageName) => {\n const { manifest, rootRelativeDir } = packagesRegistry[packageName];\n\n const outputManifest = adaptManifestWorkspaceDeps(\n { manifest, packagesRegistry },\n { includeDevDependencies: getConfig().includeDevDependencies },\n );\n\n await fs.writeFile(\n path.join(isolateDir, rootRelativeDir, \"package.json\"),\n JSON.stringify(outputManifest, null, 2),\n );\n }),\n );\n}\n","import { omit } from \"lodash-es\";\nimport { filterObjectUndefined } from \"~/utils\";\nimport {\n PackageManifestMinimum,\n PackagesRegistry,\n patchWorkspaceEntries,\n} from \".\";\n\nexport function adaptManifestWorkspaceDeps(\n {\n manifest,\n packagesRegistry,\n }: {\n manifest: PackageManifestMinimum;\n packagesRegistry: PackagesRegistry;\n },\n opts: { includeDevDependencies?: boolean } = {},\n): PackageManifestMinimum {\n return Object.assign(\n omit(manifest, [\"scripts\", \"devDependencies\"]),\n filterObjectUndefined({\n dependencies: manifest.dependencies\n ? patchWorkspaceEntries(manifest.dependencies, packagesRegistry)\n : undefined,\n devDependencies:\n opts.includeDevDependencies && manifest.devDependencies\n ? patchWorkspaceEntries(manifest.devDependencies, packagesRegistry)\n : undefined,\n }),\n );\n}\n","export function filterObjectUndefined(object: Record<string, unknown>) {\n return Object.fromEntries(\n Object.entries(object).filter(([_, value]) => value !== undefined),\n );\n}\n","export function getRelativePath(path: string, relativeTo: string) {\n return path.replace(relativeTo, \"\");\n}\n","import { inspect } from \"node:util\";\nimport { JsonValue } from \"type-fest\";\n\nexport function inspectValue(value: JsonValue) {\n return inspect(value, false, 4, true);\n}\n","import fs from \"fs-extra\";\n\n/**\n * @TODO pass in zod schema and validate\n */\nexport function readTypedJsonSync<T>(filePath: string) {\n const rawContent = fs.readFileSync(filePath, \"utf-8\");\n const data = JSON.parse(rawContent) as T;\n return data;\n}\n\nexport async function readTypedJson<T>(filePath: string) {\n const rawContent = await fs.readFile(filePath, \"utf-8\");\n const data = JSON.parse(rawContent) as T;\n return data;\n}\n","import chalk from \"chalk\";\nimport { IsolateConfigResolved } from \"~/helpers\";\n\nexport function createLogger(logLevel: IsolateConfigResolved[\"logLevel\"]) {\n return {\n debug(...args: any[]) {\n if (logLevel === \"debug\") {\n console.log(chalk.blue(\"debug\"), ...args);\n }\n },\n info(...args: any[]) {\n if (logLevel === \"debug\" || logLevel === \"info\") {\n console.log(chalk.green(\"info\"), ...args);\n }\n },\n warn(...args: any[]) {\n if (logLevel === \"debug\" || logLevel === \"info\" || logLevel === \"warn\") {\n console.log(chalk.yellow(\"warning\"), ...args);\n }\n },\n error(...args: any[]) {\n console.log(chalk.red(\"error\"), ...args);\n },\n };\n}\n","import { exec } from \"node:child_process\";\nimport path from \"node:path\";\nimport { PackageManager, getConfig } from \"~/helpers\";\nimport { createLogger } from \"./logger\";\n\nexport async function pack(\n srcDir: string,\n destDir: string,\n packageManager: PackageManager,\n) {\n const log = createLogger(getConfig().logLevel);\n const cwd = process.cwd();\n process.chdir(srcDir);\n\n /**\n * PNPM pack seems to be a lot faster than NPM pack, so when PNPM is detected we\n * use that instead.\n */\n switch (packageManager) {\n case \"pnpm\": {\n const stdout = await new Promise<string>((resolve, reject) => {\n exec(`pnpm pack --pack-destination ${destDir}`, (err, stdout) => {\n if (err) {\n return reject(err);\n }\n\n resolve(stdout);\n });\n });\n\n /**\n * Trim newlines and whitespace\n */\n const packedFilePath = stdout.trim();\n\n log.debug(\"Packed\", path.basename(packedFilePath));\n\n process.chdir(cwd);\n return packedFilePath;\n }\n\n case \"yarn\":\n case \"npm\": {\n const stdout = await new Promise<string>((resolve, reject) => {\n exec(`npm pack --pack-destination ${destDir}`, (err, stdout) => {\n if (err) {\n return reject(err);\n }\n\n resolve(stdout);\n });\n });\n\n /**\n * Trim newlines and whitespace\n */\n const packedFileName = stdout.trim();\n\n log.debug(\"Packed\", packedFileName);\n\n process.chdir(cwd);\n return path.join(destDir, packedFileName);\n }\n }\n}\n","import fs from \"fs-extra\";\nimport tar from \"tar-fs\";\nimport { createGunzip } from \"zlib\";\n\nexport async function unpack(filePath: string, unpackDir: string) {\n await new Promise<void>((resolve, reject) => {\n fs.createReadStream(filePath)\n .pipe(createGunzip())\n .pipe(tar.extract(unpackDir))\n .on(\"finish\", () => resolve())\n .on(\"error\", (err) => reject(err));\n });\n}\n","import fs from \"fs-extra\";\nimport yaml from \"yaml\";\n\nexport function readTypedYamlSync<T>(filePath: string) {\n const rawContent = fs.readFileSync(filePath, \"utf-8\");\n const data = yaml.parse(rawContent);\n /**\n * @TODO add some zod validation maybe\n */\n return data as T;\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport {\n PackageManifestMinimum,\n PackagesRegistry,\n adaptManifestWorkspaceDeps,\n getConfig,\n} from \"~/helpers\";\n\nexport async function adaptTargetPackageManifest(\n manifest: PackageManifestMinimum,\n packagesRegistry: PackagesRegistry,\n isolateDir: string,\n) {\n const outputManifest = adaptManifestWorkspaceDeps(\n {\n manifest,\n packagesRegistry,\n },\n { includeDevDependencies: getConfig().includeDevDependencies },\n );\n\n await fs.writeFile(\n path.join(isolateDir, \"package.json\"),\n JSON.stringify(outputManifest, null, 2),\n );\n}\n","import { isEmpty } from \"lodash-es\";\nimport path from \"node:path\";\nimport { createLogger, inspectValue, readTypedJsonSync } from \"~/utils\";\n\nexport type IsolateConfigResolved = {\n logLevel: \"info\" | \"debug\" | \"warn\" | \"error\";\n workspaceRoot: string;\n workspacePackages?: string[];\n isolateOutDir: string;\n includeDevDependencies: boolean;\n tsconfigPath: string;\n buildOutputDir?: string;\n};\n\nexport type IsolateConfig = Partial<IsolateConfigResolved>;\n\nconst configDefaults: IsolateConfigResolved = {\n logLevel: \"info\",\n workspaceRoot: \"../..\",\n isolateOutDir: \"./isolate\",\n includeDevDependencies: false,\n tsconfigPath: \"./tsconfig.json\",\n workspacePackages: undefined,\n buildOutputDir: undefined,\n};\n\n/**\n * Only initialize the configuration once, and keeping it here for subsequent\n * calls to getConfig.\n */\nlet __config: IsolateConfigResolved | undefined;\n\nconst validConfigKeys = Object.keys(configDefaults);\n\nconst CONFIG_FILE_NAME = \"isolate.config.json\";\n\ntype LogLevel = IsolateConfigResolved[\"logLevel\"];\n\nexport function getConfig(): IsolateConfigResolved {\n if (__config) {\n return __config;\n }\n\n /**\n * Since the logLevel is set via config we can't use it to determine if we\n * should output verbose logging as part of the config loading process. Using\n * the env var ISOLATE_CONFIG_LOG_LEVEL you have the option to log debug\n * output.\n */\n const log = createLogger(\n (process.env.ISOLATE_CONFIG_LOG_LEVEL as LogLevel) ?? \"warn\",\n );\n\n const configFilePath = path.join(process.cwd(), CONFIG_FILE_NAME);\n\n log.debug(`Attempting to load config from ${configFilePath}`);\n\n const configFromFile = readTypedJsonSync<IsolateConfig>(\n path.join(process.cwd(), CONFIG_FILE_NAME),\n );\n\n const foreignKeys = Object.keys(configFromFile).filter(\n (key) => !validConfigKeys.includes(key),\n );\n\n if (!isEmpty(foreignKeys)) {\n log.warn(`Found invalid config settings:`, foreignKeys.join(\", \"));\n }\n\n const config = Object.assign(\n {},\n configDefaults,\n configFromFile,\n ) satisfies IsolateConfigResolved;\n\n log.debug(\"Using configuration:\", inspectValue(config));\n\n __config = config;\n return config;\n}\n","import { globSync } from \"glob\";\nimport { set } from \"lodash-es\";\nimport path from \"node:path\";\nimport { createLogger, readTypedJson } from \"~/utils\";\nimport { getConfig } from \"./config\";\nimport { findPackagesGlobs } from \"./find-packages-globs\";\n\nexport type PackageManifestMinimum = {\n name: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n main: string;\n module?: string;\n exports?: Record<string, { require: string; import: string }>;\n files: string[];\n version?: string;\n typings?: string;\n scripts?: Record<string, string>;\n};\n\nexport type WorkspacePackageInfo = {\n absoluteDir: string;\n /**\n * The path of the package relative to the workspace root. This is the path\n * referenced in the lock file.\n */\n rootRelativeDir: string;\n /**\n * The package.json file contents\n */\n manifest: PackageManifestMinimum;\n};\n\nexport type PackagesRegistry = Record<string, WorkspacePackageInfo>;\n\n/**\n * Build a list of all packages in the workspace, depending on the package\n * manager used, with a possible override from the config file. The list contains\n * the manifest with some directory info mapped by module name.\n */\nexport async function createPackagesRegistry(\n workspaceRootDir: string,\n workspacePackagesOverride: string[] | undefined,\n): Promise<PackagesRegistry> {\n const log = createLogger(getConfig().logLevel);\n\n if (workspacePackagesOverride) {\n log.debug(\n `Override workspace packages via config: ${workspacePackagesOverride}`,\n );\n }\n\n const packagesGlobs =\n workspacePackagesOverride ?? findPackagesGlobs(workspaceRootDir);\n\n const cwd = process.cwd();\n process.chdir(workspaceRootDir);\n\n const allPackages = packagesGlobs.flatMap((glob) => globSync(glob));\n\n const registry: PackagesRegistry = (\n await Promise.all(\n allPackages.map(async (rootRelativeDir) => {\n log.debug(`Registering package ${rootRelativeDir}`);\n const manifest = await readTypedJson<PackageManifestMinimum>(\n path.join(rootRelativeDir, \"package.json\"),\n );\n\n return {\n manifest,\n rootRelativeDir,\n absoluteDir: path.join(workspaceRootDir, rootRelativeDir),\n };\n }),\n )\n ).reduce<PackagesRegistry>(\n (acc, info) => set(acc, info.manifest.name, info),\n {},\n );\n\n process.chdir(cwd);\n\n return registry;\n}\n","import path from \"node:path\";\nimport {\n createLogger,\n inspectValue,\n readTypedJsonSync,\n readTypedYamlSync,\n} from \"~/utils\";\nimport { getConfig } from \"./config\";\nimport { detectPackageManager } from \"./detect-package-manager\";\n\n/**\n * Find the globs that define where the packages are located within the\n * monorepo. This configuration is dependent on the package manager used, and I\n * don't know if we're covering all cases yet...\n */\nexport function findPackagesGlobs(workspaceRootDir: string) {\n const log = createLogger(getConfig().logLevel);\n\n const packageManager = detectPackageManager(workspaceRootDir);\n\n switch (packageManager) {\n case \"pnpm\": {\n const { packages: globs } = readTypedYamlSync<{ packages: string[] }>(\n path.join(workspaceRootDir, \"pnpm-workspace.yaml\"),\n );\n\n log.debug(\"Detected pnpm packages globs:\", inspectValue(globs));\n return globs;\n }\n case \"yarn\":\n case \"npm\": {\n const workspaceRootManifestPath = path.join(\n workspaceRootDir,\n \"package.json\",\n );\n\n const { workspaces } = readTypedJsonSync<{ workspaces: string[] }>(\n workspaceRootManifestPath,\n );\n\n if (!workspaces) {\n throw new Error(\n `No workspaces field found in ${workspaceRootManifestPath}`,\n );\n }\n\n return workspaces;\n }\n }\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\n\nexport type PackageManager = \"pnpm\" | \"yarn\" | \"npm\";\n\nexport function detectPackageManager(workspaceRoot: string): PackageManager {\n if (fs.existsSync(path.join(workspaceRoot, \"pnpm-lock.yaml\"))) {\n return \"pnpm\";\n }\n\n if (fs.existsSync(path.join(workspaceRoot, \"yarn.lock\"))) {\n return \"yarn\";\n }\n\n if (fs.existsSync(path.join(workspaceRoot, \"package-lock.json\"))) {\n return \"npm\";\n }\n\n throw new Error(`Failed to detect package manager`);\n}\n","import path from \"node:path\";\nimport { config } from \"node:process\";\nimport { getConfig } from \"~/helpers\";\nimport { createLogger, readTypedJson } from \"~/utils\";\n\n/**\n * Find the build output dir by reading the tsconfig.json file or if that\n * doesn't exist by looking for a dist, build, or output directory.\n */\nexport async function findBuildOutputDir(targetPackageDir: string) {\n const config = getConfig();\n const log = createLogger(getConfig().logLevel);\n\n if (config.buildOutputDir) {\n log.debug(\"Using buildOutputDir from config:\", config.buildOutputDir);\n return path.join(targetPackageDir, config.buildOutputDir);\n }\n\n const tsconfigPath = path.join(targetPackageDir, config.tsconfigPath);\n try {\n const tsconfig = await readTypedJson<{\n compilerOptions: { outDir: string };\n }>(tsconfigPath);\n\n return path.join(targetPackageDir, tsconfig.compilerOptions.outDir);\n } catch (err) {\n throw new Error(\n `Failed to find tsconfig at ${tsconfigPath}. Without a buildOutputDir config setting a tsconfig file is required to know where the build output directory is located.If your tsconfig is located elsewhere you can configure it using the tsconfigPath setting.`,\n );\n }\n}\n","import {\n PackageManifestMinimum,\n PackagesRegistry,\n} from \"./create-packages-registry\";\n\n/**\n * Recursively list the packages from dependencies (and optionally\n * devDependencies) that are found in the workspace.\n *\n * Here we do not need to rely on packages being declared as \"workspace:\" in the\n * manifest. We can simply compare the package names with the list of packages\n * that were found via the workspace glob patterns and added to the registry.\n */\nexport function listLocalDependencies(\n manifest: PackageManifestMinimum,\n packagesRegistry: PackagesRegistry,\n { includeDevDependencies = false } = {},\n): string[] {\n const allWorkspacePackageNames = Object.keys(packagesRegistry);\n\n const localDependencyPackageNames = (\n includeDevDependencies\n ? [\n ...Object.keys(manifest.dependencies ?? {}),\n ...Object.keys(manifest.devDependencies ?? {}),\n ]\n : Object.keys(manifest.dependencies ?? {})\n ).filter((name) => allWorkspacePackageNames.includes(name));\n\n const nestedLocalDependencies = localDependencyPackageNames.flatMap(\n (packageName) =>\n listLocalDependencies(\n packagesRegistry[packageName].manifest,\n packagesRegistry,\n { includeDevDependencies },\n ),\n );\n\n return localDependencyPackageNames.concat(nestedLocalDependencies);\n}\n","import path from \"node:path\";\nimport { readTypedJson } from \"~/utils\";\nimport { PackageManifestMinimum } from \"./create-packages-registry\";\n\nexport async function importManifest(packageDir: string) {\n return readTypedJson<PackageManifestMinimum>(\n path.join(packageDir, \"package.json\"),\n );\n}\n","import assert from \"node:assert\";\nimport { createLogger, pack } from \"~/utils\";\nimport { getConfig } from \"./config\";\nimport { PackagesRegistry } from \"./create-packages-registry\";\nimport { PackageManager } from \"./detect-package-manager\";\n\n/**\n * Pack dependencies so that we extract only the files that are supposed to be\n * published by the packages.\n *\n * @returns A map of package names to the path of the packed file\n */\nexport async function packDependencies({\n /**\n * All packages found in the monorepo by workspaces declaration\n */\n packagesRegistry,\n /**\n * The package names that appear to be local dependencies\n */\n localDependencies,\n /**\n * The directory where the isolated package and all its dependencies will end\n * up. This is also the directory from where the package will be deployed. By\n * default it is a subfolder in targetPackageDir called \"isolate\" but you can\n * configure it.\n */\n packDestinationDir,\n\n packageManager,\n}: {\n packagesRegistry: PackagesRegistry;\n localDependencies: string[];\n packDestinationDir: string;\n packageManager: PackageManager;\n}) {\n const config = getConfig();\n const log = createLogger(config.logLevel);\n\n const packedFileByName: Record<string, string> = {};\n\n for (const dependency of localDependencies) {\n const def = packagesRegistry[dependency];\n\n assert(dependency, `Failed to find package definition for ${dependency}`);\n\n const { name } = def.manifest;\n\n /**\n * If this dependency has already been packed, we skip it. It could happen\n * because we are packing workspace dependencies recursively.\n */\n if (packedFileByName[name]) {\n log.debug(`Skipping ${name} because it has already been packed`);\n continue;\n }\n\n packedFileByName[name] = await pack(\n def.absoluteDir,\n packDestinationDir,\n packageManager,\n );\n\n /**\n * @TODO call recursively\n */\n }\n\n return packedFileByName;\n}\n","import { createLogger } from \"~/utils\";\nimport { getConfig } from \"./config\";\nimport { PackagesRegistry } from \"./create-packages-registry\";\n\nexport function patchWorkspaceEntries(\n dependencies: Record<string, string>,\n packagesRegistry: PackagesRegistry,\n) {\n const log = createLogger(getConfig().logLevel);\n const allWorkspacePackageNames = Object.keys(packagesRegistry);\n\n return Object.fromEntries(\n Object.entries(dependencies).map(([key, value]) => {\n if (allWorkspacePackageNames.includes(key)) {\n const def = packagesRegistry[key];\n\n /**\n * The rootRelativeDir is the package location in the monorepo. In the\n * isolate folder we keep the same structure so we can use the same\n * relative path.\n */\n log.debug(`Linking dependency ${key} to file:${def.rootRelativeDir}`);\n\n return [key, `file:${def.rootRelativeDir}`];\n } else {\n return [key, value];\n }\n }),\n );\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { PackageManager } from \"~/helpers\";\nimport { pack, unpack } from \"~/utils\";\n\nexport async function processBuildOutputFiles({\n targetPackageDir,\n tmpDir,\n packageManager,\n isolateDir,\n}: {\n targetPackageDir: string;\n tmpDir: string;\n packageManager: PackageManager;\n isolateDir: string;\n}) {\n const packedFilePath = await pack(targetPackageDir, tmpDir, packageManager);\n const unpackDir = path.join(tmpDir, \"target\");\n await unpack(packedFilePath, unpackDir);\n await fs.copy(path.join(unpackDir, \"package\"), isolateDir);\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { createLogger } from \"~/utils\";\nimport { getConfig } from \"./config\";\nimport { PackageManager } from \"./detect-package-manager\";\n\nexport function getLockFileName(packageManager: PackageManager) {\n switch (packageManager) {\n case \"pnpm\":\n return \"pnpm-lock.yaml\";\n case \"yarn\":\n return \"yarn.lock\";\n case \"npm\":\n return \"package-lock.json\";\n }\n}\n\nexport async function processLockfile(\n workspaceRootDir: string,\n isolateDir: string,\n packageManager: PackageManager,\n) {\n const log = createLogger(getConfig().logLevel);\n\n const lockfileName = getLockFileName(packageManager);\n\n const lockfileSrcPath = path.join(workspaceRootDir, lockfileName);\n const lockfileDstPath = path.join(isolateDir, lockfileName);\n\n log.debug(\"Copying lockfile\", lockfileSrcPath, \"to\", isolateDir);\n\n await fs.copy(lockfileSrcPath, lockfileDstPath);\n}\n","import fs from \"fs-extra\";\nimport path, { join } from \"node:path\";\nimport { getRelativePath } from \"~/utils\";\nimport { createLogger } from \"~/utils/logger\";\nimport { PackagesRegistry, getConfig } from \".\";\nimport { unpack } from \"../utils/unpack\";\n\nexport async function unpackDependencies(\n packedFilesByName: Record<string, string>,\n packagesRegistry: PackagesRegistry,\n tmpDir: string,\n isolateDir: string,\n) {\n const log = createLogger(getConfig().logLevel);\n await Promise.all(\n Object.entries(packedFilesByName).map(async ([packageName, filePath]) => {\n const dir = packagesRegistry[packageName].rootRelativeDir;\n\n const unpackDir = join(tmpDir, dir);\n\n await unpack(filePath, unpackDir);\n\n log.debug(\"Unpacked\", path.basename(filePath));\n\n const destinationDir = join(isolateDir, dir);\n\n await fs.ensureDir(destinationDir);\n\n await fs.move(join(unpackDir, \"package\"), destinationDir, {\n overwrite: true,\n });\n\n log.debug(\n `Moved package files to isolate ${getRelativePath(\n destinationDir,\n isolateDir,\n )}`,\n );\n }),\n );\n}\n"],"mappings":"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","names":["fs","assert","path","path","fs","path","log","stdout","path","fs","fs","fs","path","fs","path","path","log","path","config","path","path","fs","path","log","path","log","path","path","config","log","path","path","config","log","log","fs","path","path","fs","fs","path","log","path","fs","fs","path","log","path","fs","assert","fs","path"]}
package/package.json CHANGED
@@ -1,20 +1,47 @@
1
1
  {
2
2
  "name": "isolate-package",
3
- "version": "0.0.0",
4
- "description": "Coming soon",
5
- "main": "dist/index.js",
6
- "module": "dist/index.js",
3
+ "version": "1.0.0-beta.1",
4
+ "description": "Isolate a monorepo package by bundling the build output with its shared workspace packages and lock file to form a self-contained directory.",
5
+ "author": "Thijs Koerselman",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "monorepo",
9
+ "workspace",
10
+ "isolate",
11
+ "package",
12
+ "deploy",
13
+ "firebase",
14
+ "ci",
15
+ "pnpm",
16
+ "yarn",
17
+ "npm"
18
+ ],
7
19
  "type": "module",
20
+ "module": "dist/index.js",
8
21
  "files": [
9
22
  "dist"
10
23
  ],
11
- "author": "Thijs Koerselman",
12
- "license": "MIT",
24
+ "bin": {
25
+ "isolate": "dist/index.js"
26
+ },
27
+ "dependencies": {
28
+ "chalk": "^5.2.0",
29
+ "fs-extra": "^11.1.1",
30
+ "glob": "^10.2.2",
31
+ "lodash-es": "^4.17.21",
32
+ "source-map-support": "^0.5.21",
33
+ "tar-fs": "^2.1.1",
34
+ "yaml": "^2.2.2"
35
+ },
13
36
  "devDependencies": {
14
- "@types/node": "^20.1.0",
37
+ "@types/fs-extra": "^11.0.1",
38
+ "@types/lodash-es": "^4.17.7",
39
+ "@types/node": "^18.16.2",
40
+ "@types/source-map-support": "^0.5.6",
41
+ "@types/tar-fs": "^2.0.1",
15
42
  "tsup": "^6.7.0",
16
- "typescript": "^5.0.4",
17
- "vitest": "^0.31.0"
43
+ "type-fest": "^3.9.0",
44
+ "vitest": "^0.30.1"
18
45
  },
19
46
  "scripts": {
20
47
  "build": "tsup-node",
package/dist/index.d.ts DELETED
@@ -1,3 +0,0 @@
1
- declare function export_default(): Promise<void>;
2
-
3
- export { export_default as default };