UNPKG

5.14 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.Workspace = void 0;
4const tslib_1 = require("tslib");
5const fslib_1 = require("@yarnpkg/fslib");
6const globby_1 = tslib_1.__importDefault(require("globby"));
7const semver_1 = tslib_1.__importDefault(require("semver"));
8const Manifest_1 = require("./Manifest");
9const WorkspaceResolver_1 = require("./WorkspaceResolver");
10const hashUtils = tslib_1.__importStar(require("./hashUtils"));
11const structUtils = tslib_1.__importStar(require("./structUtils"));
12class Workspace {
13 constructor(workspaceCwd, { project }) {
14 this.workspacesCwds = new Set();
15 // Generated at resolution; basically dependencies + devDependencies + child workspaces
16 this.dependencies = new Map();
17 this.project = project;
18 this.cwd = workspaceCwd;
19 }
20 async setup() {
21 // @ts-expect-error: It's ok to initialize it now
22 this.manifest = fslib_1.xfs.existsSync(fslib_1.ppath.join(this.cwd, Manifest_1.Manifest.fileName))
23 ? await Manifest_1.Manifest.find(this.cwd)
24 : new Manifest_1.Manifest();
25 // We use ppath.relative to guarantee that the default hash will be consistent even if the project is installed on different OS / path
26 // @ts-expect-error: It's ok to initialize it now, even if it's readonly (setup is called right after construction)
27 this.relativeCwd = fslib_1.ppath.relative(this.project.cwd, this.cwd) || fslib_1.PortablePath.dot;
28 const ident = this.manifest.name ? this.manifest.name : structUtils.makeIdent(null, `${this.computeCandidateName()}-${hashUtils.makeHash(this.relativeCwd).substr(0, 6)}`);
29 const reference = this.manifest.version ? this.manifest.version : `0.0.0`;
30 // @ts-expect-error: It's ok to initialize it now, even if it's readonly (setup is called right after construction)
31 this.locator = structUtils.makeLocator(ident, reference);
32 // @ts-expect-error: It's ok to initialize it now, even if it's readonly (setup is called right after construction)
33 this.anchoredDescriptor = structUtils.makeDescriptor(this.locator, `${WorkspaceResolver_1.WorkspaceResolver.protocol}${this.relativeCwd}`);
34 // @ts-expect-error: It's ok to initialize it now, even if it's readonly (setup is called right after construction)
35 this.anchoredLocator = structUtils.makeLocator(this.locator, `${WorkspaceResolver_1.WorkspaceResolver.protocol}${this.relativeCwd}`);
36 const patterns = this.manifest.workspaceDefinitions.map(({ pattern }) => pattern);
37 const relativeCwds = await globby_1.default(patterns, {
38 absolute: true,
39 cwd: fslib_1.npath.fromPortablePath(this.cwd),
40 expandDirectories: false,
41 onlyDirectories: true,
42 onlyFiles: false,
43 ignore: [`**/node_modules`, `**/.git`, `**/.yarn`],
44 });
45 // It seems that the return value of globby isn't in any guaranteed order - not even the directory listing order
46 relativeCwds.sort();
47 for (const relativeCwd of relativeCwds) {
48 const candidateCwd = fslib_1.ppath.resolve(this.cwd, fslib_1.npath.toPortablePath(relativeCwd));
49 if (fslib_1.xfs.existsSync(fslib_1.ppath.join(candidateCwd, `package.json`))) {
50 this.workspacesCwds.add(candidateCwd);
51 }
52 }
53 }
54 accepts(range) {
55 const protocolIndex = range.indexOf(`:`);
56 const protocol = protocolIndex !== -1
57 ? range.slice(0, protocolIndex + 1)
58 : null;
59 const pathname = protocolIndex !== -1
60 ? range.slice(protocolIndex + 1)
61 : range;
62 if (protocol === WorkspaceResolver_1.WorkspaceResolver.protocol && fslib_1.ppath.normalize(pathname) === this.relativeCwd)
63 return true;
64 if (protocol === WorkspaceResolver_1.WorkspaceResolver.protocol && pathname === `*`)
65 return true;
66 if (!semver_1.default.validRange(pathname))
67 return false;
68 if (protocol === WorkspaceResolver_1.WorkspaceResolver.protocol)
69 return semver_1.default.satisfies(this.manifest.version !== null ? this.manifest.version : `0.0.0`, pathname);
70 if (!this.project.configuration.get(`enableTransparentWorkspaces`))
71 return false;
72 if (this.manifest.version !== null)
73 return semver_1.default.satisfies(this.manifest.version, pathname);
74 return false;
75 }
76 computeCandidateName() {
77 if (this.cwd === this.project.cwd) {
78 return `root-workspace`;
79 }
80 else {
81 return `${fslib_1.ppath.basename(this.cwd)}` || `unnamed-workspace`;
82 }
83 }
84 async persistManifest() {
85 const data = {};
86 this.manifest.exportTo(data);
87 const path = fslib_1.ppath.join(this.cwd, Manifest_1.Manifest.fileName);
88 const content = `${JSON.stringify(data, null, this.manifest.indent)}\n`;
89 await fslib_1.xfs.changeFilePromise(path, content, {
90 automaticNewlines: true,
91 });
92 }
93}
94exports.Workspace = Workspace;