@jakubmazanec/carson 1.1.1 → 1.2.0-next.f67f269
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 +4 -3
- package/build/workspace/Project.js +3 -3
- package/build/workspace/Project.js.map +2 -2
- package/build/workspace/Workspace.js +65 -11
- package/build/workspace/Workspace.js.map +2 -2
- package/build/workspace/WorkspaceConfig.d.ts +3 -0
- package/build/workspace/WorkspaceConfig.js +2 -1
- package/build/workspace/WorkspaceConfig.js.map +2 -2
- package/build/workspace/WorkspaceError.d.ts +2 -2
- package/build/workspace/WorkspaceError.js +2 -1
- package/build/workspace/WorkspaceError.js.map +2 -2
- package/package.json +1 -1
- package/source/workspace/Project.ts +4 -4
- package/source/workspace/Workspace.ts +87 -14
- package/source/workspace/WorkspaceConfig.ts +1 -0
- package/source/workspace/WorkspaceError.ts +2 -0
package/README.md
CHANGED
|
@@ -201,9 +201,10 @@ configuration.
|
|
|
201
201
|
|
|
202
202
|
#### `workspace.json`
|
|
203
203
|
|
|
204
|
-
| Option | Type
|
|
205
|
-
| -------- |
|
|
206
|
-
| template | string
|
|
204
|
+
| Option | Type | Description |
|
|
205
|
+
| -------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
206
|
+
| template | string | Carson template ID |
|
|
207
|
+
| projects | string[] | Array of globs used to find projects in the workspace; alternative to [`package.json#workspaces`](https://docs.npmjs.com/cli/configuring-npm/package-json#workspaces) |
|
|
207
208
|
|
|
208
209
|
#### `project.json`
|
|
209
210
|
|
|
@@ -98,15 +98,15 @@ export class Project {
|
|
|
98
98
|
args
|
|
99
99
|
}
|
|
100
100
|
});
|
|
101
|
+
if (!template.config.autoEject && workspace.config.template) {
|
|
102
|
+
await saveProjectConfig({ projectPath: project.path, projectConfig: { template: templateId } });
|
|
103
|
+
}
|
|
101
104
|
await applyTemplateRenders({
|
|
102
105
|
templateRenders,
|
|
103
106
|
targetPath: project.path,
|
|
104
107
|
snapshotPath: template.config.autoEject || !workspace.config.template ? void 0 : path.join(project.path, CARSON_CONFIG_DIRECTORY, PROJECT_SNAPSHOT_FILENAME),
|
|
105
108
|
ignoreStrategies: ["check"]
|
|
106
109
|
});
|
|
107
|
-
if (!template.config.autoEject && workspace.config.template) {
|
|
108
|
-
await saveProjectConfig({ projectPath: project.path, projectConfig: { template: templateId } });
|
|
109
|
-
}
|
|
110
110
|
await project.read();
|
|
111
111
|
return project;
|
|
112
112
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../source/workspace/Project.ts"],
|
|
4
|
-
"sourcesContent": ["import {ensureEmptyDirectory, pathToPosixPath} from '@jakubmazanec/fs-utils';\nimport {type PackageJson, packageJsonSchema, readFile} from '@jakubmazanec/zod-utils';\nimport fs from 'fs-extra';\nimport json5 from 'json5';\nimport path from 'node:path';\nimport {z} from 'zod';\n\nimport {\n CARSON_CONFIG_DIRECTORY,\n PROJECT_CONFIG_FILENAME,\n PROJECT_SNAPSHOT_FILENAME,\n} from '../constants.js';\nimport {applyTemplateRenders} from '../template/applyTemplateRenders.js';\nimport {readCarsonTemplate} from '../template/internals.js';\nimport {renderCarsonTemplate} from '../template/renderCarsonTemplate.js';\nimport {type ProjectConfig, projectConfigSchema} from './ProjectConfig.js';\nimport {type ProjectCreateOptions} from './ProjectCreateOptions.js';\nimport {ProjectError} from './ProjectError.js';\nimport {type ProjectOptions} from './ProjectOptions.js';\nimport {type ProjectUpdateOptions} from './ProjectUpdateOptions.js';\nimport {saveProjectConfig} from './saveProjectConfig.js';\nimport {type Workspace} from './Workspace.js';\n\n/**\n * Project represent a self-contained piece of software (e.g. a package, or an app) that is part of a {@link Workspace}. Currently only Node.js projects are supported.\n *\n * @typeParam M If true, the project belongs to a multi-project workspace.\n */\nexport class Project<M extends boolean = true> {\n /** Project name. */\n name?: string;\n\n /** Project path. */\n path: string;\n\n /** Project path relative to workspace path. */\n relativePath: string;\n\n /** Project configuration; if it's not found, the default is an empty object. */\n config: ProjectConfig;\n\n /** Parsed project `package.json` file; if it's not found, the default is an empty object. */\n packageJson: PackageJson;\n\n /** Parent {@link Workspace} instance. */\n workspace: Workspace<M>;\n\n /** Errors found during reading from the file system. */\n errors: Array<InstanceType<typeof ProjectError>> = [];\n\n constructor({\n path: projectPath,\n name,\n config,\n packageJson,\n workspace,\n errors,\n }: ProjectOptions<M>) {\n // TODO: check that this path and workspace path are correct, i.e. project path must always be inside of workspace path\n this.path = projectPath;\n\n if (name) {\n this.name = name;\n }\n\n if (config) {\n this.config = config;\n } else {\n this.config = {};\n }\n\n if (packageJson) {\n this.packageJson = packageJson;\n } else {\n this.packageJson = {};\n }\n\n this.workspace = workspace;\n\n if (errors) {\n this.errors = errors;\n }\n\n if (this.packageJson.name?.length) {\n this.name = this.packageJson.name;\n }\n\n this.relativePath = pathToPosixPath(path.relative(this.workspace.path, this.path));\n }\n\n static async create<M extends boolean>({\n templateId,\n workspace,\n projectPath,\n projectName,\n args,\n }: ProjectCreateOptions<M>): Promise<Project<M>> {\n let project = new this({\n path: projectPath,\n name: projectName,\n config: {\n template: templateId,\n },\n workspace,\n });\n\n // if the workspace is single-project, it shares a directory with the project, so we can't insist on it being an empty directory\n if (workspace.isMultiProject) {\n try {\n await ensureEmptyDirectory(project.path);\n } catch {\n throw new ProjectError('PROJECT_PATH_NOT_EMPTY', {\n messageParameters: [project.path],\n data: {\n path: project.path,\n },\n });\n }\n }\n\n let template = await readCarsonTemplate(templateId);\n let templateRenders = await renderCarsonTemplate({\n template,\n templateData: {\n workspace,\n project,\n args,\n },\n });\n\n await applyTemplateRenders({\n templateRenders,\n targetPath: project.path,\n snapshotPath:\n template.config.autoEject || !workspace.config.template ?\n undefined\n : path.join(project.path, CARSON_CONFIG_DIRECTORY, PROJECT_SNAPSHOT_FILENAME),\n ignoreStrategies: ['check'],\n });\n\n
|
|
5
|
-
"mappings": ";AAAA,SAAQ,sBAAsB,uBAAsB;AACpD,SAA0B,mBAAmB,gBAAe;AAC5D,OAAO,QAAQ;AACf,OAAO,WAAW;AAClB,OAAO,UAAU;AACjB,SAAQ,SAAQ;AAEhB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAQ,4BAA2B;AACnC,SAAQ,0BAAyB;AACjC,SAAQ,4BAA2B;AACnC,SAA4B,2BAA0B;AAEtD,SAAQ,oBAAmB;AAG3B,SAAQ,yBAAwB;AAQzB,aAAM,QAAkC;AAAA;AAAA,EAE7C;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA,SAAmD,CAAC;AAAA,EAEpD,YAAY;AAAA,IACV,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAsB;AAEpB,SAAK,OAAO;AAEZ,QAAI,MAAM;AACR,WAAK,OAAO;AAAA,IACd;AAEA,QAAI,QAAQ;AACV,WAAK,SAAS;AAAA,IAChB,OAAO;AACL,WAAK,SAAS,CAAC;AAAA,IACjB;AAEA,QAAI,aAAa;AACf,WAAK,cAAc;AAAA,IACrB,OAAO;AACL,WAAK,cAAc,CAAC;AAAA,IACtB;AAEA,SAAK,YAAY;AAEjB,QAAI,QAAQ;AACV,WAAK,SAAS;AAAA,IAChB;AAEA,QAAI,KAAK,YAAY,MAAM,QAAQ;AACjC,WAAK,OAAO,KAAK,YAAY;AAAA,IAC/B;AAEA,SAAK,eAAe,gBAAgB,KAAK,SAAS,KAAK,UAAU,MAAM,KAAK,IAAI,CAAC;AAAA,EACnF;AAAA,EAEA,aAAa,OAA0B;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAiD;AAC/C,QAAI,UAAU,IAAI,KAAK;AAAA,MACrB,MAAM;AAAA,MACN,MAAM;AAAA,MACN,QAAQ;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,MACA;AAAA,IACF,CAAC;AAGD,QAAI,UAAU,gBAAgB;AAC5B,UAAI;AACF,cAAM,qBAAqB,QAAQ,IAAI;AAAA,MACzC,QAAQ;AACN,cAAM,IAAI,aAAa,0BAA0B;AAAA,UAC/C,mBAAmB,CAAC,QAAQ,IAAI;AAAA,UAChC,MAAM;AAAA,YACJ,MAAM,QAAQ;AAAA,UAChB;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,WAAW,MAAM,mBAAmB,UAAU;AAClD,QAAI,kBAAkB,MAAM,qBAAqB;AAAA,MAC/C;AAAA,MACA,cAAc;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAED,UAAM,qBAAqB;AAAA,MACzB;AAAA,MACA,YAAY,QAAQ;AAAA,MACpB,cACE,SAAS,OAAO,aAAa,CAAC,UAAU,OAAO,WAC7C,SACA,KAAK,KAAK,QAAQ,MAAM,yBAAyB,yBAAyB;AAAA,MAC9E,kBAAkB,CAAC,OAAO;AAAA,IAC5B,CAAC;AAED,
|
|
4
|
+
"sourcesContent": ["import {ensureEmptyDirectory, pathToPosixPath} from '@jakubmazanec/fs-utils';\nimport {type PackageJson, packageJsonSchema, readFile} from '@jakubmazanec/zod-utils';\nimport fs from 'fs-extra';\nimport json5 from 'json5';\nimport path from 'node:path';\nimport {z} from 'zod';\n\nimport {\n CARSON_CONFIG_DIRECTORY,\n PROJECT_CONFIG_FILENAME,\n PROJECT_SNAPSHOT_FILENAME,\n} from '../constants.js';\nimport {applyTemplateRenders} from '../template/applyTemplateRenders.js';\nimport {readCarsonTemplate} from '../template/internals.js';\nimport {renderCarsonTemplate} from '../template/renderCarsonTemplate.js';\nimport {type ProjectConfig, projectConfigSchema} from './ProjectConfig.js';\nimport {type ProjectCreateOptions} from './ProjectCreateOptions.js';\nimport {ProjectError} from './ProjectError.js';\nimport {type ProjectOptions} from './ProjectOptions.js';\nimport {type ProjectUpdateOptions} from './ProjectUpdateOptions.js';\nimport {saveProjectConfig} from './saveProjectConfig.js';\nimport {type Workspace} from './Workspace.js';\n\n/**\n * Project represent a self-contained piece of software (e.g. a package, or an app) that is part of a {@link Workspace}. Currently only Node.js projects are supported.\n *\n * @typeParam M If true, the project belongs to a multi-project workspace.\n */\nexport class Project<M extends boolean = true> {\n /** Project name. */\n name?: string;\n\n /** Project path. */\n path: string;\n\n /** Project path relative to workspace path. */\n relativePath: string;\n\n /** Project configuration; if it's not found, the default is an empty object. */\n config: ProjectConfig;\n\n /** Parsed project `package.json` file; if it's not found, the default is an empty object. */\n packageJson: PackageJson;\n\n /** Parent {@link Workspace} instance. */\n workspace: Workspace<M>;\n\n /** Errors found during reading from the file system. */\n errors: Array<InstanceType<typeof ProjectError>> = [];\n\n constructor({\n path: projectPath,\n name,\n config,\n packageJson,\n workspace,\n errors,\n }: ProjectOptions<M>) {\n // TODO: check that this path and workspace path are correct, i.e. project path must always be inside of workspace path\n this.path = projectPath;\n\n if (name) {\n this.name = name;\n }\n\n if (config) {\n this.config = config;\n } else {\n this.config = {};\n }\n\n if (packageJson) {\n this.packageJson = packageJson;\n } else {\n this.packageJson = {};\n }\n\n this.workspace = workspace;\n\n if (errors) {\n this.errors = errors;\n }\n\n if (this.packageJson.name?.length) {\n this.name = this.packageJson.name;\n }\n\n this.relativePath = pathToPosixPath(path.relative(this.workspace.path, this.path));\n }\n\n static async create<M extends boolean>({\n templateId,\n workspace,\n projectPath,\n projectName,\n args,\n }: ProjectCreateOptions<M>): Promise<Project<M>> {\n let project = new this({\n path: projectPath,\n name: projectName,\n config: {\n template: templateId,\n },\n workspace,\n });\n\n // if the workspace is single-project, it shares a directory with the project, so we can't insist on it being an empty directory\n if (workspace.isMultiProject) {\n try {\n await ensureEmptyDirectory(project.path);\n } catch {\n throw new ProjectError('PROJECT_PATH_NOT_EMPTY', {\n messageParameters: [project.path],\n data: {\n path: project.path,\n },\n });\n }\n }\n\n let template = await readCarsonTemplate(templateId);\n let templateRenders = await renderCarsonTemplate({\n template,\n templateData: {\n workspace,\n project,\n args,\n },\n });\n\n if (!template.config.autoEject && workspace.config.template) {\n await saveProjectConfig({projectPath: project.path, projectConfig: {template: templateId}});\n }\n\n await applyTemplateRenders({\n templateRenders,\n targetPath: project.path,\n snapshotPath:\n template.config.autoEject || !workspace.config.template ?\n undefined\n : path.join(project.path, CARSON_CONFIG_DIRECTORY, PROJECT_SNAPSHOT_FILENAME),\n ignoreStrategies: ['check'],\n });\n\n await project.read();\n\n return project;\n }\n\n static async read<M extends boolean>(\n projectPath: string,\n workspace: Workspace<M>,\n ): Promise<Project<M>> {\n let project = new this({\n path: projectPath,\n workspace,\n });\n\n await project.read();\n\n return project;\n }\n\n async read() {\n if (!(await fs.pathExists(this.path))) {\n throw new ProjectError('NO_SUCH_PROJECT_PATH', {\n messageParameters: [this.path],\n data: {\n path: this.path,\n },\n });\n }\n\n let errors: Array<InstanceType<typeof ProjectError>> = [];\n\n // load project config\n let projectConfigPath = path.join(this.path, CARSON_CONFIG_DIRECTORY, PROJECT_CONFIG_FILENAME);\n let doesProjectConfigExist = await fs.pathExists(projectConfigPath);\n let projectConfig: ProjectConfig | z.ZodError;\n\n if (doesProjectConfigExist) {\n projectConfig = await readFile(projectConfigPath, projectConfigSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n } else {\n projectConfig = {};\n }\n\n if (projectConfig instanceof z.ZodError) {\n let zodError = projectConfig;\n\n errors.push(\n new ProjectError('INVALID_PROJECT_CONFIG', {\n messageParameters: [projectConfigPath],\n data: {\n path: projectConfigPath,\n zodIssues: zodError.issues,\n },\n }),\n );\n\n projectConfig = {};\n }\n\n // load package.json\n let packageJsonPath = path.join(this.path, 'package.json');\n let doesPackageJsonExist = await fs.pathExists(packageJsonPath);\n let packageJson: PackageJson | z.ZodError;\n\n if (doesPackageJsonExist) {\n packageJson = await readFile(packageJsonPath, packageJsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n } else {\n packageJson = {};\n }\n\n if (packageJson instanceof z.ZodError) {\n let zodError = packageJson;\n\n errors.push(\n new ProjectError('INVALID_PACKAGE_JSON', {\n messageParameters: [packageJsonPath],\n data: {\n path: packageJsonPath,\n zodIssues: zodError.issues,\n },\n }),\n );\n\n packageJson = {};\n }\n\n if (packageJson.name?.length) {\n this.name = packageJson.name;\n }\n\n this.config = projectConfig;\n this.packageJson = packageJson;\n this.errors = errors;\n\n return this;\n }\n\n async update({args}: ProjectUpdateOptions): Promise<this> {\n if (!this.config.template) {\n throw new ProjectError('MISSING_CARSON_TEMPLATE_ID', {\n messageParameters: [path.join(this.path, CARSON_CONFIG_DIRECTORY, PROJECT_CONFIG_FILENAME)],\n });\n }\n\n let template = await readCarsonTemplate(this.config.template);\n let templateRenders = await renderCarsonTemplate({\n template,\n templateData: {\n workspace: this.workspace,\n project: this,\n args,\n },\n });\n\n await applyTemplateRenders({\n templateRenders,\n targetPath: this.path,\n snapshotPath:\n template.config.autoEject || !this.workspace.config.template ?\n undefined\n : path.join(this.path, CARSON_CONFIG_DIRECTORY, PROJECT_SNAPSHOT_FILENAME),\n ignoreStrategies: ['create'],\n });\n\n await this.read();\n\n return this;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -4,6 +4,7 @@ import { jsonSchema, packageJsonSchema, readFile } from "@jakubmazanec/zod-utils
|
|
|
4
4
|
import glob from "fast-glob";
|
|
5
5
|
import fs from "fs-extra";
|
|
6
6
|
import json5 from "json5";
|
|
7
|
+
import _ from "lodash";
|
|
7
8
|
import path from "node:path";
|
|
8
9
|
import { z } from "zod";
|
|
9
10
|
import {
|
|
@@ -138,18 +139,18 @@ export class Workspace {
|
|
|
138
139
|
args
|
|
139
140
|
}
|
|
140
141
|
});
|
|
141
|
-
await applyTemplateRenders({
|
|
142
|
-
templateRenders,
|
|
143
|
-
targetPath: workspace.path,
|
|
144
|
-
snapshotPath: template.config.autoEject ? void 0 : path.join(workspace.path, CARSON_CONFIG_DIRECTORY, WORKSPACE_SNAPSHOT_FILENAME),
|
|
145
|
-
ignoreStrategies: ["check"]
|
|
146
|
-
});
|
|
147
142
|
if (!template.config.autoEject) {
|
|
148
143
|
await saveWorkspaceConfig({
|
|
149
144
|
workspacePath: workspace.path,
|
|
150
145
|
workspaceConfig: { template: templateId }
|
|
151
146
|
});
|
|
152
147
|
}
|
|
148
|
+
await applyTemplateRenders({
|
|
149
|
+
templateRenders,
|
|
150
|
+
targetPath: workspace.path,
|
|
151
|
+
snapshotPath: template.config.autoEject ? void 0 : path.join(workspace.path, CARSON_CONFIG_DIRECTORY, WORKSPACE_SNAPSHOT_FILENAME),
|
|
152
|
+
ignoreStrategies: ["check"]
|
|
153
|
+
});
|
|
153
154
|
return Workspace.read(workspace.path);
|
|
154
155
|
}
|
|
155
156
|
static async read(workspacePath) {
|
|
@@ -186,7 +187,33 @@ export class Workspace {
|
|
|
186
187
|
} catch {
|
|
187
188
|
}
|
|
188
189
|
}
|
|
189
|
-
let
|
|
190
|
+
let workspaceConfigPath = path.join(
|
|
191
|
+
resolvedWorkspacePath,
|
|
192
|
+
CARSON_CONFIG_DIRECTORY,
|
|
193
|
+
WORKSPACE_CONFIG_FILENAME
|
|
194
|
+
);
|
|
195
|
+
let doesWorkspaceConfigExist = await fs.pathExists(workspaceConfigPath);
|
|
196
|
+
let workspaceConfig;
|
|
197
|
+
if (doesWorkspaceConfigExist) {
|
|
198
|
+
workspaceConfig = await readFile(workspaceConfigPath, workspaceConfigSchema, {
|
|
199
|
+
parser: (rawString) => json5.parse(rawString)
|
|
200
|
+
});
|
|
201
|
+
} else {
|
|
202
|
+
workspaceConfig = {};
|
|
203
|
+
}
|
|
204
|
+
if (workspaceConfig instanceof z.ZodError) {
|
|
205
|
+
workspaceConfig = {};
|
|
206
|
+
}
|
|
207
|
+
let packageJsonProjectGlobs = getPackageJsonWorkspaces(rootPackageJson);
|
|
208
|
+
let workspaceConfigProjectGlobs = workspaceConfig.projects;
|
|
209
|
+
if (packageJsonProjectGlobs?.length && workspaceConfigProjectGlobs?.length && !_.isEqual(packageJsonProjectGlobs, workspaceConfigProjectGlobs)) {
|
|
210
|
+
throw new WorkspaceError("PROJECT_GLOBS_MISMATCH", {
|
|
211
|
+
data: {
|
|
212
|
+
path: resolvedWorkspacePath
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
let projectGlobs = packageJsonProjectGlobs ?? workspaceConfigProjectGlobs;
|
|
190
217
|
if (!projectGlobs) {
|
|
191
218
|
let workspace2 = new this({
|
|
192
219
|
path: resolvedWorkspacePath,
|
|
@@ -219,13 +246,31 @@ export class Workspace {
|
|
|
219
246
|
let multiPackageWorkspacePath;
|
|
220
247
|
while (!(isRootPath(currentPath) || singlePackageWorkspacePath && multiPackageWorkspacePath)) {
|
|
221
248
|
if (await containsWorkspace(currentPath)) {
|
|
222
|
-
|
|
249
|
+
let packageJsonPath = path.join(currentPath, PACKAGE_JSON_FILENAME);
|
|
250
|
+
let workspaceConfigPath = path.join(
|
|
251
|
+
currentPath,
|
|
252
|
+
CARSON_CONFIG_DIRECTORY,
|
|
253
|
+
WORKSPACE_CONFIG_FILENAME
|
|
254
|
+
);
|
|
223
255
|
if (await fs.pathExists(packageJsonPath)) {
|
|
224
|
-
|
|
256
|
+
let packageJson = await readFile(packageJsonPath, jsonSchema, {
|
|
225
257
|
parser: (rawString) => json5.parse(rawString)
|
|
226
258
|
});
|
|
227
259
|
if (!(packageJson instanceof Error)) {
|
|
228
|
-
|
|
260
|
+
let projectGlobs = getPackageJsonWorkspaces(packageJson);
|
|
261
|
+
if (projectGlobs?.length) {
|
|
262
|
+
multiPackageWorkspacePath ??= currentPath;
|
|
263
|
+
} else {
|
|
264
|
+
singlePackageWorkspacePath ??= currentPath;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (await fs.pathExists(workspaceConfigPath)) {
|
|
269
|
+
let workspaceConfig = await readFile(workspaceConfigPath, workspaceConfigSchema, {
|
|
270
|
+
parser: (rawString) => json5.parse(rawString)
|
|
271
|
+
});
|
|
272
|
+
if (!(workspaceConfig instanceof z.ZodError)) {
|
|
273
|
+
let projectGlobs = workspaceConfig.projects;
|
|
229
274
|
if (projectGlobs?.length) {
|
|
230
275
|
multiPackageWorkspacePath ??= currentPath;
|
|
231
276
|
} else {
|
|
@@ -323,7 +368,16 @@ export class Workspace {
|
|
|
323
368
|
errors.push(workspaceError);
|
|
324
369
|
rootPackageJson = {};
|
|
325
370
|
}
|
|
326
|
-
let
|
|
371
|
+
let packageJsonProjectGlobs = getPackageJsonWorkspaces(rootPackageJson);
|
|
372
|
+
let workspaceConfigProjectGlobs = workspaceConfig.projects;
|
|
373
|
+
if (packageJsonProjectGlobs && workspaceConfigProjectGlobs && !_.isEqual(packageJsonProjectGlobs, workspaceConfigProjectGlobs)) {
|
|
374
|
+
throw new WorkspaceError("PROJECT_GLOBS_MISMATCH", {
|
|
375
|
+
data: {
|
|
376
|
+
path: this.path
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
let projectGlobs = packageJsonProjectGlobs ?? workspaceConfigProjectGlobs;
|
|
327
381
|
this.projectGlobs = projectGlobs ?? [];
|
|
328
382
|
this.packageJson = rootPackageJson;
|
|
329
383
|
this.config = workspaceConfig;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../source/workspace/Workspace.ts"],
|
|
4
|
-
"sourcesContent": ["import {ensureEmptyDirectory, findExistingDirectory, isRootPath} from '@jakubmazanec/fs-utils';\nimport {jsonSchema, type PackageJson, packageJsonSchema, readFile} from '@jakubmazanec/zod-utils';\nimport glob from 'fast-glob';\nimport fs from 'fs-extra';\nimport json5 from 'json5';\nimport path from 'node:path';\nimport {z} from 'zod';\n\nimport {\n CARSON_CONFIG_DIRECTORY,\n PACKAGE_JSON_FILENAME,\n WORKSPACE_CONFIG_FILENAME,\n WORKSPACE_SNAPSHOT_FILENAME,\n} from '../constants.js';\nimport {applyTemplateRenders} from '../template/applyTemplateRenders.js';\nimport {readCarsonTemplate} from '../template/internals.js';\nimport {renderCarsonTemplate} from '../template/renderCarsonTemplate.js';\nimport {\n compareProjectPath,\n containsProject,\n containsWorkspace,\n getPackageJsonWorkspaces,\n getRepositoryBranches,\n getRepositoryUrl,\n} from './internals.js';\nimport {Project} from './Project.js';\nimport {saveWorkspaceConfig} from './saveWorkspaceConfig.js';\nimport {workspaceConfigSchema} from './WorkspaceConfig.js';\nimport {type WorkspaceConfig} from './WorkspaceConfig.js';\nimport {type WorkspaceCreateOptions} from './WorkspaceCreateOptions.js';\nimport {type WorkspaceCreateProjectOptions} from './WorkspaceCreateProjectOptions.js';\nimport {WorkspaceDependencies} from './WorkspaceDependencies.js';\nimport {WorkspaceError} from './WorkspaceError.js';\nimport {type WorkspaceFindAndReadOptions} from './WorkspaceFindAndReadOptions.js';\nimport {type WorkspaceOptions} from './WorkspaceOptions.js';\nimport {type WorkspacePackageJson} from './WorkspacePackageJson.js';\nimport {type WorkspaceProjectGlobs} from './WorkspaceProjectGlobs.js';\nimport {type WorkspaceProjects} from './WorkspaceProjects.js';\nimport {type WorkspaceRepository} from './WorkspaceRepository.js';\nimport {type WorkspaceUpdateOptions} from './WorkspaceUpdateOptions.js';\n\n/**\n * Workspace represent a directory, usually a git repository, that contains {@link Project} instances.\n *\n * @typeParam M If true, the workspace is multi-project workspace (so-called \"monorepo\").\n */\nexport class Workspace<M extends boolean = true> {\n /** Workspace path. */\n readonly path: string;\n\n /** Does the workspace contain a multiple projects? */\n readonly isMultiProject: M;\n\n /** Globs used to find projects. */\n projectGlobs: WorkspaceProjectGlobs<M>;\n\n /** Workspace projects. */\n projects: WorkspaceProjects<M>;\n\n /** Workspace configuration; if it's not found, the default is an empty object. */\n config: WorkspaceConfig;\n\n /** Parsed workspace `package.json` file (if the workspace contains multiple projects); if it's not found, the default is an empty object. */\n packageJson: WorkspacePackageJson<M>;\n\n /** Workspace git repository. */\n repository?: WorkspaceRepository;\n\n /** Dependencies of all projects. */\n dependencies: WorkspaceDependencies<M> = [] as unknown as WorkspaceDependencies<M>;\n\n /** Development dependencies of all projects. */\n devDependencies: WorkspaceDependencies<M> = [] as unknown as WorkspaceDependencies<M>;\n\n /** All dependencies of all projects and workspace dependencies. */\n allDependencies: WorkspaceDependencies<M> = [] as unknown as WorkspaceDependencies<M>;\n\n /** Versions of each dependency. */\n dependencyVersions: Record<string, string[]> = {};\n\n /** Errors found during reading from the file system. */\n errors: Array<InstanceType<typeof WorkspaceError>> = [];\n\n constructor(options: WorkspaceOptions<M>) {\n this.path = options.path;\n\n if (options.isMultiProject === undefined || options.isMultiProject) {\n this.isMultiProject = true as M;\n\n let projectGlobOption = (options as WorkspaceOptions<true>).projectGlobs;\n\n if (projectGlobOption) {\n this.projectGlobs = projectGlobOption as WorkspaceProjectGlobs<M>;\n } else {\n this.projectGlobs = [] as string[] as WorkspaceProjectGlobs<M>;\n }\n\n this.projects = [] as Array<Project<M>> as WorkspaceProjects<M>;\n\n let {projects} = options as WorkspaceOptions<true>;\n\n if (projects) {\n this.addProjects(projects.map((project) => new Project({...project, workspace: this})));\n }\n\n let packageJsonOption = (options as WorkspaceOptions<true>).packageJson;\n\n if (packageJsonOption) {\n this.packageJson = packageJsonOption as M extends true ? PackageJson : null;\n } else {\n let emptyPackageJson: PackageJson = {};\n\n this.packageJson = emptyPackageJson as M extends true ? PackageJson : null;\n }\n } else {\n this.isMultiProject = false as M;\n this.projectGlobs = null as M extends true ? string[] : null;\n this.packageJson = null as M extends true ? PackageJson : null;\n this.projects = [] as Array<Project<M>> as WorkspaceProjects<M>;\n\n let {projects} = options as WorkspaceOptions<false>;\n\n if (projects) {\n this.addProjects(projects.map((project) => new Project({...project, workspace: this})));\n }\n }\n\n let configOption = options.config;\n\n if (configOption) {\n this.config = configOption;\n } else {\n let emptyWorkspaceConfig: WorkspaceConfig = {};\n\n this.config = emptyWorkspaceConfig;\n }\n\n if (options.repository) {\n this.repository = options.repository;\n }\n\n if (options.errors) {\n this.errors = options.errors;\n }\n\n // add missing project globs\n if (this.isMultiProject && !(this.projectGlobs as string[]).length) {\n let packageJsonWorkspaces = getPackageJsonWorkspaces(this.packageJson as PackageJson);\n\n if (packageJsonWorkspaces) {\n this.projectGlobs = [...packageJsonWorkspaces] as M extends true ? string[] : null;\n }\n }\n\n this.sortProjects();\n this.updateDependencies();\n }\n\n /**\n * Creates new workspace within the file system.\n *\n * @param options Options.\n * @returns The new workspace.\n */\n static async create({args, path: workspacePath, templateId}: WorkspaceCreateOptions) {\n // TODO: test that workspace returned by this method has the same value of isMultiProject when the same workspace is after its creation re-read with .read()\n let workspace = new this({\n path: workspacePath,\n config: {\n template: templateId,\n },\n });\n\n try {\n await ensureEmptyDirectory(workspace.path, {allowGit: true});\n } catch {\n throw new WorkspaceError('WORKSPACE_PATH_NOT_EMPTY', {\n messageParameters: [workspace.path],\n data: {\n path: workspace.path,\n },\n });\n }\n\n let template = await readCarsonTemplate(templateId);\n let templateRenders = await renderCarsonTemplate({\n template,\n templateData: {\n workspace,\n args,\n },\n });\n\n await applyTemplateRenders({\n templateRenders,\n targetPath: workspace.path,\n snapshotPath:\n template.config.autoEject ?\n undefined\n : path.join(workspace.path, CARSON_CONFIG_DIRECTORY, WORKSPACE_SNAPSHOT_FILENAME),\n ignoreStrategies: ['check'],\n });\n\n if (!template.config.autoEject) {\n await saveWorkspaceConfig({\n workspacePath: workspace.path,\n workspaceConfig: {template: templateId},\n });\n }\n\n return Workspace.read(workspace.path);\n }\n\n static async read(workspacePath: string): Promise<Workspace | Workspace<false>> {\n let resolvedWorkspacePath = path.resolve(workspacePath);\n\n if (!(await fs.pathExists(resolvedWorkspacePath))) {\n throw new WorkspaceError('NO_SUCH_WORKSPACE_PATH', {\n messageParameters: [resolvedWorkspacePath],\n data: {\n path: resolvedWorkspacePath,\n },\n });\n }\n\n // load root package.json\n let rootPackageJsonPath = path.join(resolvedWorkspacePath, 'package.json');\n let doesRootPackageJsonExist = await fs.pathExists(rootPackageJsonPath);\n let rootPackageJson: PackageJson | z.ZodError;\n\n if (doesRootPackageJsonExist) {\n rootPackageJson = await readFile(rootPackageJsonPath, packageJsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n } else {\n rootPackageJson = {};\n }\n\n if (rootPackageJson instanceof z.ZodError) {\n rootPackageJson = {};\n\n // even if the package.json file has errors, maybe there's still a correct workspace field\n try {\n let rootJson = await readFile(rootPackageJsonPath, jsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n throwOnZodError: true,\n });\n let projectGlobs = getPackageJsonWorkspaces(rootJson);\n\n // add back to the empty package.json object\n if (projectGlobs) {\n rootPackageJson.workspaces = projectGlobs;\n }\n } catch {\n // no-op\n }\n }\n\n // add projects\n let projectGlobs = getPackageJsonWorkspaces(rootPackageJson);\n\n // we're dealing with single-project workspace\n if (!projectGlobs) {\n let workspace = new this({\n path: resolvedWorkspacePath,\n isMultiProject: false,\n });\n\n await workspace.read();\n await workspace.readProjects();\n\n return workspace;\n }\n\n // assemble workspace options\n let workspace = new this({\n path: resolvedWorkspacePath,\n isMultiProject: true,\n projectGlobs,\n packageJson: rootPackageJson,\n });\n\n await workspace.read();\n await workspace.readProjects();\n\n return workspace;\n }\n\n /**\n * Traverses file system up from the search path and tries to find a directory that is a root of a workspace.\n *\n * @param searchPath Search path.\n * @returns Workspace path, if found.\n */\n static async find(searchPath: string): Promise<string | undefined> {\n let startingPath = await findExistingDirectory(path.resolve(searchPath));\n let currentPath = startingPath;\n let singlePackageWorkspacePath: string | undefined;\n let multiPackageWorkspacePath: string | undefined;\n\n while (\n !(isRootPath(currentPath) || (singlePackageWorkspacePath && multiPackageWorkspacePath))\n ) {\n if (await containsWorkspace(currentPath)) {\n const packageJsonPath = path.join(currentPath, PACKAGE_JSON_FILENAME);\n\n if (await fs.pathExists(packageJsonPath)) {\n const packageJson = await readFile(packageJsonPath, jsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n\n if (!(packageJson instanceof Error)) {\n const projectGlobs = getPackageJsonWorkspaces(packageJson);\n\n if (projectGlobs?.length) {\n multiPackageWorkspacePath ??= currentPath;\n } else {\n singlePackageWorkspacePath ??= currentPath;\n }\n }\n } else {\n singlePackageWorkspacePath ??= currentPath;\n }\n }\n\n currentPath = path.dirname(currentPath);\n }\n\n if (multiPackageWorkspacePath) {\n return multiPackageWorkspacePath;\n } else if (singlePackageWorkspacePath) {\n return singlePackageWorkspacePath;\n }\n\n return undefined;\n }\n\n /**\n * Traverses file system up from the search path and tries to find and read a workspace.\n */\n static async findAndRead<O extends WorkspaceFindAndReadOptions | undefined = undefined>(\n searchPath: string,\n options?: O,\n ): Promise<\n O extends undefined ? Workspace | Workspace<false> | undefined\n : NonNullable<O>['throwIfNotFound'] extends true ? Workspace | Workspace<false>\n : Workspace | Workspace<false> | undefined\n > {\n let workspacePath = await Workspace.find(searchPath);\n\n if (workspacePath) {\n return Workspace.read(workspacePath) as Promise<\n O extends undefined ? Workspace | Workspace<false> | undefined\n : NonNullable<O>['throwIfNotFound'] extends true ? Workspace | Workspace<false>\n : Workspace | Workspace<false> | undefined\n >;\n } else if (options?.throwIfNotFound) {\n throw new WorkspaceError('NO_WORKSPACE_FOUND', {\n messageParameters: [searchPath],\n data: {\n path: searchPath,\n },\n });\n }\n\n return undefined as unknown as Promise<\n O extends undefined ? Workspace | Workspace<false> | undefined\n : NonNullable<O>['throwIfNotFound'] extends true ? Workspace | Workspace<false>\n : Workspace | Workspace<false> | undefined\n >;\n }\n\n async read(): Promise<this> {\n if (!(await fs.pathExists(this.path))) {\n throw new WorkspaceError('NO_SUCH_WORKSPACE_PATH', {\n messageParameters: [this.path],\n data: {\n path: this.path,\n },\n });\n }\n\n let errors: Array<InstanceType<typeof WorkspaceError>> = [];\n let repositoryUrl = await getRepositoryUrl(this.path);\n let repositoryBranches = await getRepositoryBranches(this.path);\n\n // load workspace config\n let workspaceConfigPath = path.join(\n this.path,\n CARSON_CONFIG_DIRECTORY,\n WORKSPACE_CONFIG_FILENAME,\n );\n let doesWorkspaceConfigExist = await fs.pathExists(workspaceConfigPath);\n let workspaceConfig: WorkspaceConfig | z.ZodError;\n\n if (doesWorkspaceConfigExist) {\n workspaceConfig = await readFile(workspaceConfigPath, workspaceConfigSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n } else {\n workspaceConfig = {};\n }\n\n if (workspaceConfig instanceof z.ZodError) {\n let zodError = workspaceConfig;\n let workspaceError = new WorkspaceError('INVALID_WORKSPACE_CONFIG', {\n messageParameters: [workspaceConfigPath],\n data: {\n path: workspaceConfigPath,\n zodIssues: zodError.issues,\n },\n });\n\n errors.push(workspaceError);\n\n workspaceConfig = {};\n }\n\n if (this.isMultiProject) {\n // load root package.json\n let rootPackageJsonPath = path.join(this.path, 'package.json');\n let doesRootPackageJsonExist = await fs.pathExists(rootPackageJsonPath);\n let rootPackageJson: PackageJson | z.ZodError;\n\n if (doesRootPackageJsonExist) {\n rootPackageJson = await readFile(rootPackageJsonPath, packageJsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n } else {\n rootPackageJson = {};\n }\n\n if (rootPackageJson instanceof z.ZodError) {\n let zodError = rootPackageJson;\n let workspaceError = new WorkspaceError('INVALID_PACKAGE_JSON', {\n messageParameters: [rootPackageJsonPath],\n data: {\n path: rootPackageJsonPath,\n zodIssues: zodError.issues,\n },\n });\n\n errors.push(workspaceError);\n\n rootPackageJson = {};\n }\n\n let projectGlobs = getPackageJsonWorkspaces(rootPackageJson);\n\n this.projectGlobs = (projectGlobs ?? []) as WorkspaceProjectGlobs<M>;\n this.packageJson = rootPackageJson as WorkspacePackageJson<M>;\n this.config = workspaceConfig;\n this.errors = errors;\n\n if (repositoryUrl) {\n this.repository = {\n url: repositoryUrl,\n branches: repositoryBranches ?? [],\n };\n } else if (repositoryBranches) {\n this.repository = {\n branches: repositoryBranches,\n };\n }\n\n await this.readProjects();\n\n return this;\n }\n\n // we're dealing with single-project workspace\n this.config = workspaceConfig;\n this.errors = errors;\n\n if (repositoryUrl) {\n this.repository = {\n url: repositoryUrl,\n branches: repositoryBranches ?? [],\n };\n } else if (repositoryBranches) {\n this.repository = {\n branches: repositoryBranches,\n };\n }\n\n await this.readProjects();\n\n return this;\n }\n\n async update({args}: WorkspaceUpdateOptions): Promise<this> {\n if (!this.config.template) {\n throw new WorkspaceError('MISSING_CARSON_TEMPLATE_ID', {\n messageParameters: [\n path.join(this.path, CARSON_CONFIG_DIRECTORY, WORKSPACE_CONFIG_FILENAME),\n ],\n });\n }\n\n let template = await readCarsonTemplate(this.config.template);\n let templateRenders = await renderCarsonTemplate({\n template,\n templateData: {\n workspace: this,\n args,\n },\n });\n\n await applyTemplateRenders({\n templateRenders,\n targetPath: this.path,\n snapshotPath:\n template.config.autoEject ?\n undefined\n : path.join(this.path, CARSON_CONFIG_DIRECTORY, WORKSPACE_SNAPSHOT_FILENAME),\n ignoreStrategies: ['create'],\n });\n\n await this.read();\n\n return this;\n }\n\n getProject(projectName: Project<M> | string): Project<M> | undefined {\n for (let project of this.projects) {\n if (project.name === projectName || project === projectName) {\n return project;\n }\n }\n\n return undefined;\n }\n\n async createProject({\n templateId,\n projectPath,\n projectName,\n args,\n }: WorkspaceCreateProjectOptions): Promise<Project<M>> {\n let resolvedProjectPath = path.resolve(projectPath);\n\n if (this.projects.some((project) => resolvedProjectPath === project.path)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_PATH', {\n messageParameters: [resolvedProjectPath],\n });\n }\n\n if (this.projects.some((project) => projectName === project.name)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_NAME', {messageParameters: [projectName]});\n }\n\n if (!this.isMultiProject && this.projects.length >= 1) {\n throw new WorkspaceError('TOO_MANY_PROJECTS');\n }\n\n if (!this.isMultiProject && projectPath !== this.path) {\n throw new WorkspaceError('PATH_MISMATCH');\n }\n\n let newProject = await Project.create({\n templateId,\n projectPath,\n projectName,\n args,\n workspace: this,\n });\n\n this.addProject(newProject);\n\n return newProject;\n }\n\n addProject(newProject: Project<M>): this {\n if (this.projects.some((project) => newProject.path === project.path)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_PATH', {\n messageParameters: [newProject.path],\n });\n }\n\n if (this.projects.some((project) => newProject.name === project.name)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_NAME', {messageParameters: [newProject.name]});\n }\n\n if (!this.isMultiProject && this.projects.length >= 1) {\n throw new WorkspaceError('TOO_MANY_PROJECTS');\n }\n\n if (!this.isMultiProject && newProject.path !== this.path) {\n throw new WorkspaceError('PATH_MISMATCH');\n }\n\n this.projects.push(newProject);\n this.sortProjects();\n this.updateDependencies();\n\n return this;\n }\n\n addProjects(newProjects: Array<Project<M>>): this {\n for (let newProject of newProjects) {\n if (this.projects.some((project) => newProject.path === project.path)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_PATH', {\n messageParameters: [newProject.path],\n });\n }\n\n if (this.projects.some((project) => newProject.name === project.name)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_NAME', {messageParameters: [newProject.name]});\n }\n\n if (!this.isMultiProject && this.projects.length >= 1) {\n throw new WorkspaceError('TOO_MANY_PROJECTS');\n }\n\n if (!this.isMultiProject && newProject.path !== this.path) {\n throw new WorkspaceError('PATH_MISMATCH');\n }\n\n this.projects.push(newProject);\n }\n\n this.sortProjects();\n this.updateDependencies();\n\n return this;\n }\n\n async readProjects(): Promise<Array<Project<M>>> {\n if (this.projectGlobs) {\n let projects: Array<Project<M>> = [];\n let packagePaths = await glob(this.projectGlobs, {\n cwd: this.path,\n onlyDirectories: true,\n });\n\n for (let packagePath of packagePaths) {\n let projectPath = path.join(this.path, packagePath);\n\n if (await containsProject(projectPath)) {\n let project = await Project.read(projectPath, this);\n\n projects.push(project);\n }\n }\n\n this.projects = projects;\n\n this.sortProjects();\n this.updateDependencies();\n } else if (await containsProject(this.path)) {\n this.projects = [await Project.read(this.path, this)];\n\n this.sortProjects();\n this.updateDependencies();\n }\n\n return this.projects;\n }\n\n protected sortProjects(): void {\n this.projects.sort(compareProjectPath);\n }\n\n protected updateDependencies(): void {\n this.dependencies = WorkspaceDependencies.fromWorkspace(this);\n this.devDependencies = WorkspaceDependencies.fromWorkspace(this, {\n includeOnlyDevDependencies: true,\n });\n this.allDependencies = WorkspaceDependencies.fromWorkspace(this, {\n includeDevDependencies: true,\n includeWorkspaceDependencies: true,\n });\n this.dependencyVersions = this.allDependencies.getVersions({\n useExactVersions: true,\n });\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import {ensureEmptyDirectory, findExistingDirectory, isRootPath} from '@jakubmazanec/fs-utils';\nimport {jsonSchema, type PackageJson, packageJsonSchema, readFile} from '@jakubmazanec/zod-utils';\nimport glob from 'fast-glob';\nimport fs from 'fs-extra';\nimport json5 from 'json5';\nimport _ from 'lodash';\nimport path from 'node:path';\nimport {z} from 'zod';\n\nimport {\n CARSON_CONFIG_DIRECTORY,\n PACKAGE_JSON_FILENAME,\n WORKSPACE_CONFIG_FILENAME,\n WORKSPACE_SNAPSHOT_FILENAME,\n} from '../constants.js';\nimport {applyTemplateRenders} from '../template/applyTemplateRenders.js';\nimport {readCarsonTemplate} from '../template/internals.js';\nimport {renderCarsonTemplate} from '../template/renderCarsonTemplate.js';\nimport {\n compareProjectPath,\n containsProject,\n containsWorkspace,\n getPackageJsonWorkspaces,\n getRepositoryBranches,\n getRepositoryUrl,\n} from './internals.js';\nimport {Project} from './Project.js';\nimport {saveWorkspaceConfig} from './saveWorkspaceConfig.js';\nimport {workspaceConfigSchema} from './WorkspaceConfig.js';\nimport {type WorkspaceConfig} from './WorkspaceConfig.js';\nimport {type WorkspaceCreateOptions} from './WorkspaceCreateOptions.js';\nimport {type WorkspaceCreateProjectOptions} from './WorkspaceCreateProjectOptions.js';\nimport {WorkspaceDependencies} from './WorkspaceDependencies.js';\nimport {WorkspaceError} from './WorkspaceError.js';\nimport {type WorkspaceFindAndReadOptions} from './WorkspaceFindAndReadOptions.js';\nimport {type WorkspaceOptions} from './WorkspaceOptions.js';\nimport {type WorkspacePackageJson} from './WorkspacePackageJson.js';\nimport {type WorkspaceProjectGlobs} from './WorkspaceProjectGlobs.js';\nimport {type WorkspaceProjects} from './WorkspaceProjects.js';\nimport {type WorkspaceRepository} from './WorkspaceRepository.js';\nimport {type WorkspaceUpdateOptions} from './WorkspaceUpdateOptions.js';\n\n/**\n * Workspace represent a directory, usually a git repository, that contains {@link Project} instances.\n *\n * @typeParam M If true, the workspace is multi-project workspace (so-called \"monorepo\").\n */\nexport class Workspace<M extends boolean = true> {\n /** Workspace path. */\n readonly path: string;\n\n /** Does the workspace contain a multiple projects? */\n readonly isMultiProject: M;\n\n /** Globs used to find projects. */\n projectGlobs: WorkspaceProjectGlobs<M>;\n\n /** Workspace projects. */\n projects: WorkspaceProjects<M>;\n\n /** Workspace configuration; if it's not found, the default is an empty object. */\n config: WorkspaceConfig;\n\n /** Parsed workspace `package.json` file (if the workspace contains multiple projects); if it's not found, the default is an empty object. */\n packageJson: WorkspacePackageJson<M>;\n\n /** Workspace git repository. */\n repository?: WorkspaceRepository;\n\n /** Dependencies of all projects. */\n dependencies: WorkspaceDependencies<M> = [] as unknown as WorkspaceDependencies<M>;\n\n /** Development dependencies of all projects. */\n devDependencies: WorkspaceDependencies<M> = [] as unknown as WorkspaceDependencies<M>;\n\n /** All dependencies of all projects and workspace dependencies. */\n allDependencies: WorkspaceDependencies<M> = [] as unknown as WorkspaceDependencies<M>;\n\n /** Versions of each dependency. */\n dependencyVersions: Record<string, string[]> = {};\n\n /** Errors found during reading from the file system. */\n errors: Array<InstanceType<typeof WorkspaceError>> = [];\n\n constructor(options: WorkspaceOptions<M>) {\n this.path = options.path;\n\n if (options.isMultiProject === undefined || options.isMultiProject) {\n this.isMultiProject = true as M;\n\n let projectGlobOption = (options as WorkspaceOptions<true>).projectGlobs;\n\n if (projectGlobOption) {\n this.projectGlobs = projectGlobOption as WorkspaceProjectGlobs<M>;\n } else {\n this.projectGlobs = [] as string[] as WorkspaceProjectGlobs<M>;\n }\n\n this.projects = [] as Array<Project<M>> as WorkspaceProjects<M>;\n\n let {projects} = options as WorkspaceOptions<true>;\n\n if (projects) {\n this.addProjects(projects.map((project) => new Project({...project, workspace: this})));\n }\n\n let packageJsonOption = (options as WorkspaceOptions<true>).packageJson;\n\n if (packageJsonOption) {\n this.packageJson = packageJsonOption as M extends true ? PackageJson : null;\n } else {\n let emptyPackageJson: PackageJson = {};\n\n this.packageJson = emptyPackageJson as M extends true ? PackageJson : null;\n }\n } else {\n this.isMultiProject = false as M;\n this.projectGlobs = null as M extends true ? string[] : null;\n this.packageJson = null as M extends true ? PackageJson : null;\n this.projects = [] as Array<Project<M>> as WorkspaceProjects<M>;\n\n let {projects} = options as WorkspaceOptions<false>;\n\n if (projects) {\n this.addProjects(projects.map((project) => new Project({...project, workspace: this})));\n }\n }\n\n let configOption = options.config;\n\n if (configOption) {\n this.config = configOption;\n } else {\n let emptyWorkspaceConfig: WorkspaceConfig = {};\n\n this.config = emptyWorkspaceConfig;\n }\n\n if (options.repository) {\n this.repository = options.repository;\n }\n\n if (options.errors) {\n this.errors = options.errors;\n }\n\n // add missing project globs\n if (this.isMultiProject && !(this.projectGlobs as string[]).length) {\n let packageJsonWorkspaces = getPackageJsonWorkspaces(this.packageJson as PackageJson);\n\n if (packageJsonWorkspaces) {\n this.projectGlobs = [...packageJsonWorkspaces] as M extends true ? string[] : null;\n }\n }\n\n this.sortProjects();\n this.updateDependencies();\n }\n\n /**\n * Creates new workspace within the file system.\n *\n * @param options Options.\n * @returns The new workspace.\n */\n static async create({args, path: workspacePath, templateId}: WorkspaceCreateOptions) {\n // TODO: test that workspace returned by this method has the same value of isMultiProject when the same workspace is after its creation re-read with .read()\n let workspace = new this({\n path: workspacePath,\n config: {\n template: templateId,\n },\n });\n\n try {\n await ensureEmptyDirectory(workspace.path, {allowGit: true});\n } catch {\n throw new WorkspaceError('WORKSPACE_PATH_NOT_EMPTY', {\n messageParameters: [workspace.path],\n data: {\n path: workspace.path,\n },\n });\n }\n\n let template = await readCarsonTemplate(templateId);\n let templateRenders = await renderCarsonTemplate({\n template,\n templateData: {\n workspace,\n args,\n },\n });\n\n if (!template.config.autoEject) {\n await saveWorkspaceConfig({\n workspacePath: workspace.path,\n workspaceConfig: {template: templateId},\n });\n }\n\n await applyTemplateRenders({\n templateRenders,\n targetPath: workspace.path,\n snapshotPath:\n template.config.autoEject ?\n undefined\n : path.join(workspace.path, CARSON_CONFIG_DIRECTORY, WORKSPACE_SNAPSHOT_FILENAME),\n ignoreStrategies: ['check'],\n });\n\n return Workspace.read(workspace.path);\n }\n\n static async read(workspacePath: string): Promise<Workspace | Workspace<false>> {\n let resolvedWorkspacePath = path.resolve(workspacePath);\n\n if (!(await fs.pathExists(resolvedWorkspacePath))) {\n throw new WorkspaceError('NO_SUCH_WORKSPACE_PATH', {\n messageParameters: [resolvedWorkspacePath],\n data: {\n path: resolvedWorkspacePath,\n },\n });\n }\n\n // load root package.json\n let rootPackageJsonPath = path.join(resolvedWorkspacePath, 'package.json');\n let doesRootPackageJsonExist = await fs.pathExists(rootPackageJsonPath);\n let rootPackageJson: PackageJson | z.ZodError;\n\n if (doesRootPackageJsonExist) {\n rootPackageJson = await readFile(rootPackageJsonPath, packageJsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n } else {\n rootPackageJson = {};\n }\n\n if (rootPackageJson instanceof z.ZodError) {\n rootPackageJson = {};\n\n // even if the package.json file has errors, maybe there's still a correct workspace field\n try {\n let rootJson = await readFile(rootPackageJsonPath, jsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n throwOnZodError: true,\n });\n let projectGlobs = getPackageJsonWorkspaces(rootJson);\n\n // add back to the empty package.json object\n if (projectGlobs) {\n rootPackageJson.workspaces = projectGlobs;\n }\n } catch {\n // no-op\n }\n }\n\n // load workspace config\n let workspaceConfigPath = path.join(\n resolvedWorkspacePath,\n CARSON_CONFIG_DIRECTORY,\n WORKSPACE_CONFIG_FILENAME,\n );\n let doesWorkspaceConfigExist = await fs.pathExists(workspaceConfigPath);\n let workspaceConfig: WorkspaceConfig | z.ZodError;\n\n if (doesWorkspaceConfigExist) {\n workspaceConfig = await readFile(workspaceConfigPath, workspaceConfigSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n } else {\n workspaceConfig = {};\n }\n\n if (workspaceConfig instanceof z.ZodError) {\n workspaceConfig = {};\n }\n\n // how to find projects\n let packageJsonProjectGlobs = getPackageJsonWorkspaces(rootPackageJson);\n let workspaceConfigProjectGlobs = workspaceConfig.projects;\n\n if (\n packageJsonProjectGlobs?.length &&\n workspaceConfigProjectGlobs?.length &&\n !_.isEqual(packageJsonProjectGlobs, workspaceConfigProjectGlobs)\n ) {\n throw new WorkspaceError('PROJECT_GLOBS_MISMATCH', {\n data: {\n path: resolvedWorkspacePath,\n },\n });\n }\n\n let projectGlobs = packageJsonProjectGlobs ?? workspaceConfigProjectGlobs;\n\n // we're dealing with single-project workspace\n if (!projectGlobs) {\n let workspace = new this({\n path: resolvedWorkspacePath,\n isMultiProject: false,\n });\n\n await workspace.read();\n await workspace.readProjects();\n\n return workspace;\n }\n\n // we're dealing with multi-project workspace\n let workspace = new this({\n path: resolvedWorkspacePath,\n isMultiProject: true,\n projectGlobs,\n packageJson: rootPackageJson,\n });\n\n await workspace.read();\n await workspace.readProjects();\n\n return workspace;\n }\n\n /**\n * Traverses file system up from the search path and tries to find a directory that is a root of a workspace.\n *\n * @param searchPath Search path.\n * @returns Workspace path, if found.\n */\n static async find(searchPath: string): Promise<string | undefined> {\n let startingPath = await findExistingDirectory(path.resolve(searchPath));\n let currentPath = startingPath;\n let singlePackageWorkspacePath: string | undefined;\n let multiPackageWorkspacePath: string | undefined;\n\n while (\n !(isRootPath(currentPath) || (singlePackageWorkspacePath && multiPackageWorkspacePath))\n ) {\n if (await containsWorkspace(currentPath)) {\n let packageJsonPath = path.join(currentPath, PACKAGE_JSON_FILENAME);\n let workspaceConfigPath = path.join(\n currentPath,\n CARSON_CONFIG_DIRECTORY,\n WORKSPACE_CONFIG_FILENAME,\n );\n\n if (await fs.pathExists(packageJsonPath)) {\n let packageJson = await readFile(packageJsonPath, jsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n\n if (!(packageJson instanceof Error)) {\n let projectGlobs = getPackageJsonWorkspaces(packageJson);\n\n if (projectGlobs?.length) {\n multiPackageWorkspacePath ??= currentPath;\n } else {\n singlePackageWorkspacePath ??= currentPath;\n }\n }\n }\n if (await fs.pathExists(workspaceConfigPath)) {\n let workspaceConfig = await readFile(workspaceConfigPath, workspaceConfigSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n\n if (!(workspaceConfig instanceof z.ZodError)) {\n let projectGlobs = workspaceConfig.projects;\n\n if (projectGlobs?.length) {\n multiPackageWorkspacePath ??= currentPath;\n } else {\n singlePackageWorkspacePath ??= currentPath;\n }\n }\n } else {\n singlePackageWorkspacePath ??= currentPath;\n }\n }\n\n currentPath = path.dirname(currentPath);\n }\n\n if (multiPackageWorkspacePath) {\n return multiPackageWorkspacePath;\n } else if (singlePackageWorkspacePath) {\n return singlePackageWorkspacePath;\n }\n\n return undefined;\n }\n\n /**\n * Traverses file system up from the search path and tries to find and read a workspace.\n */\n static async findAndRead<O extends WorkspaceFindAndReadOptions | undefined = undefined>(\n searchPath: string,\n options?: O,\n ): Promise<\n O extends undefined ? Workspace | Workspace<false> | undefined\n : NonNullable<O>['throwIfNotFound'] extends true ? Workspace | Workspace<false>\n : Workspace | Workspace<false> | undefined\n > {\n let workspacePath = await Workspace.find(searchPath);\n\n if (workspacePath) {\n return Workspace.read(workspacePath) as Promise<\n O extends undefined ? Workspace | Workspace<false> | undefined\n : NonNullable<O>['throwIfNotFound'] extends true ? Workspace | Workspace<false>\n : Workspace | Workspace<false> | undefined\n >;\n } else if (options?.throwIfNotFound) {\n throw new WorkspaceError('NO_WORKSPACE_FOUND', {\n messageParameters: [searchPath],\n data: {\n path: searchPath,\n },\n });\n }\n\n return undefined as unknown as Promise<\n O extends undefined ? Workspace | Workspace<false> | undefined\n : NonNullable<O>['throwIfNotFound'] extends true ? Workspace | Workspace<false>\n : Workspace | Workspace<false> | undefined\n >;\n }\n\n async read(): Promise<this> {\n if (!(await fs.pathExists(this.path))) {\n throw new WorkspaceError('NO_SUCH_WORKSPACE_PATH', {\n messageParameters: [this.path],\n data: {\n path: this.path,\n },\n });\n }\n\n let errors: Array<InstanceType<typeof WorkspaceError>> = [];\n let repositoryUrl = await getRepositoryUrl(this.path);\n let repositoryBranches = await getRepositoryBranches(this.path);\n\n // load workspace config\n let workspaceConfigPath = path.join(\n this.path,\n CARSON_CONFIG_DIRECTORY,\n WORKSPACE_CONFIG_FILENAME,\n );\n let doesWorkspaceConfigExist = await fs.pathExists(workspaceConfigPath);\n let workspaceConfig: WorkspaceConfig | z.ZodError;\n\n if (doesWorkspaceConfigExist) {\n workspaceConfig = await readFile(workspaceConfigPath, workspaceConfigSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n } else {\n workspaceConfig = {};\n }\n\n if (workspaceConfig instanceof z.ZodError) {\n let zodError = workspaceConfig;\n let workspaceError = new WorkspaceError('INVALID_WORKSPACE_CONFIG', {\n messageParameters: [workspaceConfigPath],\n data: {\n path: workspaceConfigPath,\n zodIssues: zodError.issues,\n },\n });\n\n errors.push(workspaceError);\n\n workspaceConfig = {};\n }\n\n if (this.isMultiProject) {\n // load root package.json\n let rootPackageJsonPath = path.join(this.path, 'package.json');\n let doesRootPackageJsonExist = await fs.pathExists(rootPackageJsonPath);\n let rootPackageJson: PackageJson | z.ZodError;\n\n if (doesRootPackageJsonExist) {\n rootPackageJson = await readFile(rootPackageJsonPath, packageJsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n } else {\n rootPackageJson = {};\n }\n\n if (rootPackageJson instanceof z.ZodError) {\n let zodError = rootPackageJson;\n let workspaceError = new WorkspaceError('INVALID_PACKAGE_JSON', {\n messageParameters: [rootPackageJsonPath],\n data: {\n path: rootPackageJsonPath,\n zodIssues: zodError.issues,\n },\n });\n\n errors.push(workspaceError);\n\n rootPackageJson = {};\n }\n\n // how to find projects\n let packageJsonProjectGlobs = getPackageJsonWorkspaces(rootPackageJson);\n let workspaceConfigProjectGlobs = workspaceConfig.projects;\n\n if (\n packageJsonProjectGlobs &&\n workspaceConfigProjectGlobs &&\n !_.isEqual(packageJsonProjectGlobs, workspaceConfigProjectGlobs)\n ) {\n throw new WorkspaceError('PROJECT_GLOBS_MISMATCH', {\n data: {\n path: this.path,\n },\n });\n }\n\n let projectGlobs = packageJsonProjectGlobs ?? workspaceConfigProjectGlobs;\n\n this.projectGlobs = (projectGlobs ?? []) as WorkspaceProjectGlobs<M>;\n this.packageJson = rootPackageJson as WorkspacePackageJson<M>;\n this.config = workspaceConfig;\n this.errors = errors;\n\n if (repositoryUrl) {\n this.repository = {\n url: repositoryUrl,\n branches: repositoryBranches ?? [],\n };\n } else if (repositoryBranches) {\n this.repository = {\n branches: repositoryBranches,\n };\n }\n\n await this.readProjects();\n\n return this;\n }\n\n // we're dealing with single-project workspace\n this.config = workspaceConfig;\n this.errors = errors;\n\n if (repositoryUrl) {\n this.repository = {\n url: repositoryUrl,\n branches: repositoryBranches ?? [],\n };\n } else if (repositoryBranches) {\n this.repository = {\n branches: repositoryBranches,\n };\n }\n\n await this.readProjects();\n\n return this;\n }\n\n async update({args}: WorkspaceUpdateOptions): Promise<this> {\n if (!this.config.template) {\n throw new WorkspaceError('MISSING_CARSON_TEMPLATE_ID', {\n messageParameters: [\n path.join(this.path, CARSON_CONFIG_DIRECTORY, WORKSPACE_CONFIG_FILENAME),\n ],\n });\n }\n\n let template = await readCarsonTemplate(this.config.template);\n let templateRenders = await renderCarsonTemplate({\n template,\n templateData: {\n workspace: this,\n args,\n },\n });\n\n await applyTemplateRenders({\n templateRenders,\n targetPath: this.path,\n snapshotPath:\n template.config.autoEject ?\n undefined\n : path.join(this.path, CARSON_CONFIG_DIRECTORY, WORKSPACE_SNAPSHOT_FILENAME),\n ignoreStrategies: ['create'],\n });\n\n await this.read();\n\n return this;\n }\n\n getProject(projectName: Project<M> | string): Project<M> | undefined {\n for (let project of this.projects) {\n if (project.name === projectName || project === projectName) {\n return project;\n }\n }\n\n return undefined;\n }\n\n async createProject({\n templateId,\n projectPath,\n projectName,\n args,\n }: WorkspaceCreateProjectOptions): Promise<Project<M>> {\n let resolvedProjectPath = path.resolve(projectPath);\n\n if (this.projects.some((project) => resolvedProjectPath === project.path)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_PATH', {\n messageParameters: [resolvedProjectPath],\n });\n }\n\n if (this.projects.some((project) => projectName === project.name)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_NAME', {messageParameters: [projectName]});\n }\n\n if (!this.isMultiProject && this.projects.length >= 1) {\n throw new WorkspaceError('TOO_MANY_PROJECTS');\n }\n\n if (!this.isMultiProject && projectPath !== this.path) {\n throw new WorkspaceError('PATH_MISMATCH');\n }\n\n let newProject = await Project.create({\n templateId,\n projectPath,\n projectName,\n args,\n workspace: this,\n });\n\n this.addProject(newProject);\n\n return newProject;\n }\n\n addProject(newProject: Project<M>): this {\n if (this.projects.some((project) => newProject.path === project.path)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_PATH', {\n messageParameters: [newProject.path],\n });\n }\n\n if (this.projects.some((project) => newProject.name === project.name)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_NAME', {messageParameters: [newProject.name]});\n }\n\n if (!this.isMultiProject && this.projects.length >= 1) {\n throw new WorkspaceError('TOO_MANY_PROJECTS');\n }\n\n if (!this.isMultiProject && newProject.path !== this.path) {\n throw new WorkspaceError('PATH_MISMATCH');\n }\n\n this.projects.push(newProject);\n this.sortProjects();\n this.updateDependencies();\n\n return this;\n }\n\n addProjects(newProjects: Array<Project<M>>): this {\n for (let newProject of newProjects) {\n if (this.projects.some((project) => newProject.path === project.path)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_PATH', {\n messageParameters: [newProject.path],\n });\n }\n\n if (this.projects.some((project) => newProject.name === project.name)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_NAME', {messageParameters: [newProject.name]});\n }\n\n if (!this.isMultiProject && this.projects.length >= 1) {\n throw new WorkspaceError('TOO_MANY_PROJECTS');\n }\n\n if (!this.isMultiProject && newProject.path !== this.path) {\n throw new WorkspaceError('PATH_MISMATCH');\n }\n\n this.projects.push(newProject);\n }\n\n this.sortProjects();\n this.updateDependencies();\n\n return this;\n }\n\n async readProjects(): Promise<Array<Project<M>>> {\n if (this.projectGlobs) {\n let projects: Array<Project<M>> = [];\n let packagePaths = await glob(this.projectGlobs, {\n cwd: this.path,\n onlyDirectories: true,\n });\n\n for (let packagePath of packagePaths) {\n let projectPath = path.join(this.path, packagePath);\n\n if (await containsProject(projectPath)) {\n let project = await Project.read(projectPath, this);\n\n projects.push(project);\n }\n }\n\n this.projects = projects;\n\n this.sortProjects();\n this.updateDependencies();\n } else if (await containsProject(this.path)) {\n this.projects = [await Project.read(this.path, this)];\n\n this.sortProjects();\n this.updateDependencies();\n }\n\n return this.projects;\n }\n\n protected sortProjects(): void {\n this.projects.sort(compareProjectPath);\n }\n\n protected updateDependencies(): void {\n this.dependencies = WorkspaceDependencies.fromWorkspace(this);\n this.devDependencies = WorkspaceDependencies.fromWorkspace(this, {\n includeOnlyDevDependencies: true,\n });\n this.allDependencies = WorkspaceDependencies.fromWorkspace(this, {\n includeDevDependencies: true,\n includeWorkspaceDependencies: true,\n });\n this.dependencyVersions = this.allDependencies.getVersions({\n useExactVersions: true,\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["projectGlobs", "workspace"]
|
|
7
7
|
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export declare const workspaceConfigSchema: z.ZodObject<{
|
|
3
3
|
template: z.ZodOptional<z.ZodString>;
|
|
4
|
+
projects: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
4
5
|
}, "strip", z.ZodUnknown, z.objectOutputType<{
|
|
5
6
|
template: z.ZodOptional<z.ZodString>;
|
|
7
|
+
projects: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
6
8
|
}, z.ZodUnknown, "strip">, z.objectInputType<{
|
|
7
9
|
template: z.ZodOptional<z.ZodString>;
|
|
10
|
+
projects: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
8
11
|
}, z.ZodUnknown, "strip">>;
|
|
9
12
|
/**
|
|
10
13
|
* A workspace configuration.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
export const workspaceConfigSchema = z.object({
|
|
4
|
-
template: z.string().optional()
|
|
4
|
+
template: z.string().optional(),
|
|
5
|
+
projects: z.string().array().optional()
|
|
5
6
|
}).catchall(z.unknown());
|
|
6
7
|
//# sourceMappingURL=WorkspaceConfig.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../source/workspace/WorkspaceConfig.ts"],
|
|
4
|
-
"sourcesContent": ["import {z} from 'zod';\n\nexport const workspaceConfigSchema = z\n .object({\n template: z.string().optional(),\n })\n .catchall(z.unknown());\n\n/**\n * A workspace configuration.\n */\nexport type WorkspaceConfig = z.infer<typeof workspaceConfigSchema>;\n"],
|
|
5
|
-
"mappings": ";AAAA,SAAQ,SAAQ;AAET,aAAM,wBAAwB,EAClC,OAAO;AAAA,EACN,UAAU,EAAE,OAAO,EAAE,SAAS;
|
|
4
|
+
"sourcesContent": ["import {z} from 'zod';\n\nexport const workspaceConfigSchema = z\n .object({\n template: z.string().optional(),\n projects: z.string().array().optional(),\n })\n .catchall(z.unknown());\n\n/**\n * A workspace configuration.\n */\nexport type WorkspaceConfig = z.infer<typeof workspaceConfigSchema>;\n"],
|
|
5
|
+
"mappings": ";AAAA,SAAQ,SAAQ;AAET,aAAM,wBAAwB,EAClC,OAAO;AAAA,EACN,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS;AACxC,CAAC,EACA,SAAS,EAAE,QAAQ,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -2,10 +2,10 @@ import { type ZodIssue } from 'zod';
|
|
|
2
2
|
/**
|
|
3
3
|
* A subclass of `Error` that indicates a workspace failure.
|
|
4
4
|
*/
|
|
5
|
-
export declare const WorkspaceError: new (code: "INVALID_PACKAGE_JSON" | "MISSING_CARSON_TEMPLATE_ID" | "INVALID_WORKSPACE_CONFIG" | "NO_SUCH_WORKSPACE_PATH" | "NO_WORKSPACE_FOUND" | "PATH_MISMATCH" | "WORKSPACE_PATH_NOT_EMPTY" | "DUPLICATE_PROJECT_NAME" | "DUPLICATE_PROJECT_PATH" | "TOO_MANY_PROJECTS", options?: import("@jakubmazanec/error").CustomErrorWithDataOptions<{
|
|
5
|
+
export declare const WorkspaceError: new (code: "INVALID_PACKAGE_JSON" | "MISSING_CARSON_TEMPLATE_ID" | "INVALID_WORKSPACE_CONFIG" | "NO_SUCH_WORKSPACE_PATH" | "NO_WORKSPACE_FOUND" | "PATH_MISMATCH" | "WORKSPACE_PATH_NOT_EMPTY" | "DUPLICATE_PROJECT_NAME" | "DUPLICATE_PROJECT_PATH" | "TOO_MANY_PROJECTS" | "PROJECT_GLOBS_MISMATCH", options?: import("@jakubmazanec/error").CustomErrorWithDataOptions<{
|
|
6
6
|
path?: string;
|
|
7
7
|
zodIssues?: ZodIssue[];
|
|
8
|
-
}> | undefined) => import("@jakubmazanec/error").CustomErrorWithData<"INVALID_PACKAGE_JSON" | "MISSING_CARSON_TEMPLATE_ID" | "UNKNOWN_ERROR" | "INVALID_WORKSPACE_CONFIG" | "NO_SUCH_WORKSPACE_PATH" | "NO_WORKSPACE_FOUND" | "PATH_MISMATCH" | "WORKSPACE_PATH_NOT_EMPTY" | "DUPLICATE_PROJECT_NAME" | "DUPLICATE_PROJECT_PATH" | "TOO_MANY_PROJECTS", {
|
|
8
|
+
}> | undefined) => import("@jakubmazanec/error").CustomErrorWithData<"INVALID_PACKAGE_JSON" | "MISSING_CARSON_TEMPLATE_ID" | "UNKNOWN_ERROR" | "INVALID_WORKSPACE_CONFIG" | "NO_SUCH_WORKSPACE_PATH" | "NO_WORKSPACE_FOUND" | "PATH_MISMATCH" | "WORKSPACE_PATH_NOT_EMPTY" | "DUPLICATE_PROJECT_NAME" | "DUPLICATE_PROJECT_PATH" | "TOO_MANY_PROJECTS" | "PROJECT_GLOBS_MISMATCH", {
|
|
9
9
|
path?: string;
|
|
10
10
|
zodIssues?: ZodIssue[];
|
|
11
11
|
}>;
|
|
@@ -12,7 +12,8 @@ export const WorkspaceError = createCustomErrorWithData(
|
|
|
12
12
|
MISSING_CARSON_TEMPLATE_ID: 'Workspace config "{0}" is missing the Carson template ID.',
|
|
13
13
|
DUPLICATE_PROJECT_NAME: 'Workspace already contains project with name "{0}"',
|
|
14
14
|
DUPLICATE_PROJECT_PATH: 'Workspace already contains project with path "{0}"',
|
|
15
|
-
TOO_MANY_PROJECTS: "Workspace can't contain more projects."
|
|
15
|
+
TOO_MANY_PROJECTS: "Workspace can't contain more projects.",
|
|
16
|
+
PROJECT_GLOBS_MISMATCH: "Workspace has mismatched project globs in package.json and workspace.json."
|
|
16
17
|
},
|
|
17
18
|
class WorkspaceErrorData {
|
|
18
19
|
path;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../source/workspace/WorkspaceError.ts"],
|
|
4
|
-
"sourcesContent": ["import {createCustomErrorWithData} from '@jakubmazanec/error';\nimport {type ZodIssue} from 'zod';\n\n/**\n * A subclass of `Error` that indicates a workspace failure.\n */\nexport const WorkspaceError = createCustomErrorWithData(\n 'WorkspaceError',\n {\n INVALID_PACKAGE_JSON: 'Invalid package.json file \"{0}\".',\n INVALID_WORKSPACE_CONFIG: 'Invalid workspace config file \"{0}\".',\n NO_SUCH_WORKSPACE_PATH: 'Workspace path \"{0}\" doesn\\'t exist.',\n NO_WORKSPACE_FOUND: 'No workspace was found at path \"{0}\".',\n PATH_MISMATCH:\n 'In a single-project workspace, the workspace path must be the same as the project path.',\n WORKSPACE_PATH_NOT_EMPTY: 'Workspace path \"{0}\" must be an empty directory.',\n MISSING_CARSON_TEMPLATE_ID: 'Workspace config \"{0}\" is missing the Carson template ID.',\n\n DUPLICATE_PROJECT_NAME: 'Workspace already contains project with name \"{0}\"',\n DUPLICATE_PROJECT_PATH: 'Workspace already contains project with path \"{0}\"',\n TOO_MANY_PROJECTS: \"Workspace can't contain more projects.\",\n },\n class WorkspaceErrorData {\n path?: string;\n zodIssues?: ZodIssue[];\n },\n);\n"],
|
|
5
|
-
"mappings": ";AAAA,SAAQ,iCAAgC;AAMjC,aAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,IACE,sBAAsB;AAAA,IACtB,0BAA0B;AAAA,IAC1B,wBAAwB;AAAA,IACxB,oBAAoB;AAAA,IACpB,eACE;AAAA,IACF,0BAA0B;AAAA,IAC1B,4BAA4B;AAAA,IAE5B,wBAAwB;AAAA,IACxB,wBAAwB;AAAA,IACxB,mBAAmB;AAAA,
|
|
4
|
+
"sourcesContent": ["import {createCustomErrorWithData} from '@jakubmazanec/error';\nimport {type ZodIssue} from 'zod';\n\n/**\n * A subclass of `Error` that indicates a workspace failure.\n */\nexport const WorkspaceError = createCustomErrorWithData(\n 'WorkspaceError',\n {\n INVALID_PACKAGE_JSON: 'Invalid package.json file \"{0}\".',\n INVALID_WORKSPACE_CONFIG: 'Invalid workspace config file \"{0}\".',\n NO_SUCH_WORKSPACE_PATH: 'Workspace path \"{0}\" doesn\\'t exist.',\n NO_WORKSPACE_FOUND: 'No workspace was found at path \"{0}\".',\n PATH_MISMATCH:\n 'In a single-project workspace, the workspace path must be the same as the project path.',\n WORKSPACE_PATH_NOT_EMPTY: 'Workspace path \"{0}\" must be an empty directory.',\n MISSING_CARSON_TEMPLATE_ID: 'Workspace config \"{0}\" is missing the Carson template ID.',\n\n DUPLICATE_PROJECT_NAME: 'Workspace already contains project with name \"{0}\"',\n DUPLICATE_PROJECT_PATH: 'Workspace already contains project with path \"{0}\"',\n TOO_MANY_PROJECTS: \"Workspace can't contain more projects.\",\n PROJECT_GLOBS_MISMATCH:\n 'Workspace has mismatched project globs in package.json and workspace.json.',\n },\n class WorkspaceErrorData {\n path?: string;\n zodIssues?: ZodIssue[];\n },\n);\n"],
|
|
5
|
+
"mappings": ";AAAA,SAAQ,iCAAgC;AAMjC,aAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,IACE,sBAAsB;AAAA,IACtB,0BAA0B;AAAA,IAC1B,wBAAwB;AAAA,IACxB,oBAAoB;AAAA,IACpB,eACE;AAAA,IACF,0BAA0B;AAAA,IAC1B,4BAA4B;AAAA,IAE5B,wBAAwB;AAAA,IACxB,wBAAwB;AAAA,IACxB,mBAAmB;AAAA,IACnB,wBACE;AAAA,EACJ;AAAA,EACA,MAAM,mBAAmB;AAAA,IACvB;AAAA,IACA;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -128,6 +128,10 @@ export class Project<M extends boolean = true> {
|
|
|
128
128
|
},
|
|
129
129
|
});
|
|
130
130
|
|
|
131
|
+
if (!template.config.autoEject && workspace.config.template) {
|
|
132
|
+
await saveProjectConfig({projectPath: project.path, projectConfig: {template: templateId}});
|
|
133
|
+
}
|
|
134
|
+
|
|
131
135
|
await applyTemplateRenders({
|
|
132
136
|
templateRenders,
|
|
133
137
|
targetPath: project.path,
|
|
@@ -138,10 +142,6 @@ export class Project<M extends boolean = true> {
|
|
|
138
142
|
ignoreStrategies: ['check'],
|
|
139
143
|
});
|
|
140
144
|
|
|
141
|
-
if (!template.config.autoEject && workspace.config.template) {
|
|
142
|
-
await saveProjectConfig({projectPath: project.path, projectConfig: {template: templateId}});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
145
|
await project.read();
|
|
146
146
|
|
|
147
147
|
return project;
|
|
@@ -3,6 +3,7 @@ import {jsonSchema, type PackageJson, packageJsonSchema, readFile} from '@jakubm
|
|
|
3
3
|
import glob from 'fast-glob';
|
|
4
4
|
import fs from 'fs-extra';
|
|
5
5
|
import json5 from 'json5';
|
|
6
|
+
import _ from 'lodash';
|
|
6
7
|
import path from 'node:path';
|
|
7
8
|
import {z} from 'zod';
|
|
8
9
|
|
|
@@ -191,6 +192,13 @@ export class Workspace<M extends boolean = true> {
|
|
|
191
192
|
},
|
|
192
193
|
});
|
|
193
194
|
|
|
195
|
+
if (!template.config.autoEject) {
|
|
196
|
+
await saveWorkspaceConfig({
|
|
197
|
+
workspacePath: workspace.path,
|
|
198
|
+
workspaceConfig: {template: templateId},
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
194
202
|
await applyTemplateRenders({
|
|
195
203
|
templateRenders,
|
|
196
204
|
targetPath: workspace.path,
|
|
@@ -201,13 +209,6 @@ export class Workspace<M extends boolean = true> {
|
|
|
201
209
|
ignoreStrategies: ['check'],
|
|
202
210
|
});
|
|
203
211
|
|
|
204
|
-
if (!template.config.autoEject) {
|
|
205
|
-
await saveWorkspaceConfig({
|
|
206
|
-
workspacePath: workspace.path,
|
|
207
|
-
workspaceConfig: {template: templateId},
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
|
|
211
212
|
return Workspace.read(workspace.path);
|
|
212
213
|
}
|
|
213
214
|
|
|
@@ -256,8 +257,44 @@ export class Workspace<M extends boolean = true> {
|
|
|
256
257
|
}
|
|
257
258
|
}
|
|
258
259
|
|
|
259
|
-
//
|
|
260
|
-
let
|
|
260
|
+
// load workspace config
|
|
261
|
+
let workspaceConfigPath = path.join(
|
|
262
|
+
resolvedWorkspacePath,
|
|
263
|
+
CARSON_CONFIG_DIRECTORY,
|
|
264
|
+
WORKSPACE_CONFIG_FILENAME,
|
|
265
|
+
);
|
|
266
|
+
let doesWorkspaceConfigExist = await fs.pathExists(workspaceConfigPath);
|
|
267
|
+
let workspaceConfig: WorkspaceConfig | z.ZodError;
|
|
268
|
+
|
|
269
|
+
if (doesWorkspaceConfigExist) {
|
|
270
|
+
workspaceConfig = await readFile(workspaceConfigPath, workspaceConfigSchema, {
|
|
271
|
+
parser: (rawString: string) => json5.parse<unknown>(rawString),
|
|
272
|
+
});
|
|
273
|
+
} else {
|
|
274
|
+
workspaceConfig = {};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (workspaceConfig instanceof z.ZodError) {
|
|
278
|
+
workspaceConfig = {};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// how to find projects
|
|
282
|
+
let packageJsonProjectGlobs = getPackageJsonWorkspaces(rootPackageJson);
|
|
283
|
+
let workspaceConfigProjectGlobs = workspaceConfig.projects;
|
|
284
|
+
|
|
285
|
+
if (
|
|
286
|
+
packageJsonProjectGlobs?.length &&
|
|
287
|
+
workspaceConfigProjectGlobs?.length &&
|
|
288
|
+
!_.isEqual(packageJsonProjectGlobs, workspaceConfigProjectGlobs)
|
|
289
|
+
) {
|
|
290
|
+
throw new WorkspaceError('PROJECT_GLOBS_MISMATCH', {
|
|
291
|
+
data: {
|
|
292
|
+
path: resolvedWorkspacePath,
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
let projectGlobs = packageJsonProjectGlobs ?? workspaceConfigProjectGlobs;
|
|
261
298
|
|
|
262
299
|
// we're dealing with single-project workspace
|
|
263
300
|
if (!projectGlobs) {
|
|
@@ -272,7 +309,7 @@ export class Workspace<M extends boolean = true> {
|
|
|
272
309
|
return workspace;
|
|
273
310
|
}
|
|
274
311
|
|
|
275
|
-
//
|
|
312
|
+
// we're dealing with multi-project workspace
|
|
276
313
|
let workspace = new this({
|
|
277
314
|
path: resolvedWorkspacePath,
|
|
278
315
|
isMultiProject: true,
|
|
@@ -302,15 +339,35 @@ export class Workspace<M extends boolean = true> {
|
|
|
302
339
|
!(isRootPath(currentPath) || (singlePackageWorkspacePath && multiPackageWorkspacePath))
|
|
303
340
|
) {
|
|
304
341
|
if (await containsWorkspace(currentPath)) {
|
|
305
|
-
|
|
342
|
+
let packageJsonPath = path.join(currentPath, PACKAGE_JSON_FILENAME);
|
|
343
|
+
let workspaceConfigPath = path.join(
|
|
344
|
+
currentPath,
|
|
345
|
+
CARSON_CONFIG_DIRECTORY,
|
|
346
|
+
WORKSPACE_CONFIG_FILENAME,
|
|
347
|
+
);
|
|
306
348
|
|
|
307
349
|
if (await fs.pathExists(packageJsonPath)) {
|
|
308
|
-
|
|
350
|
+
let packageJson = await readFile(packageJsonPath, jsonSchema, {
|
|
309
351
|
parser: (rawString: string) => json5.parse<unknown>(rawString),
|
|
310
352
|
});
|
|
311
353
|
|
|
312
354
|
if (!(packageJson instanceof Error)) {
|
|
313
|
-
|
|
355
|
+
let projectGlobs = getPackageJsonWorkspaces(packageJson);
|
|
356
|
+
|
|
357
|
+
if (projectGlobs?.length) {
|
|
358
|
+
multiPackageWorkspacePath ??= currentPath;
|
|
359
|
+
} else {
|
|
360
|
+
singlePackageWorkspacePath ??= currentPath;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
if (await fs.pathExists(workspaceConfigPath)) {
|
|
365
|
+
let workspaceConfig = await readFile(workspaceConfigPath, workspaceConfigSchema, {
|
|
366
|
+
parser: (rawString: string) => json5.parse<unknown>(rawString),
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
if (!(workspaceConfig instanceof z.ZodError)) {
|
|
370
|
+
let projectGlobs = workspaceConfig.projects;
|
|
314
371
|
|
|
315
372
|
if (projectGlobs?.length) {
|
|
316
373
|
multiPackageWorkspacePath ??= currentPath;
|
|
@@ -445,7 +502,23 @@ export class Workspace<M extends boolean = true> {
|
|
|
445
502
|
rootPackageJson = {};
|
|
446
503
|
}
|
|
447
504
|
|
|
448
|
-
|
|
505
|
+
// how to find projects
|
|
506
|
+
let packageJsonProjectGlobs = getPackageJsonWorkspaces(rootPackageJson);
|
|
507
|
+
let workspaceConfigProjectGlobs = workspaceConfig.projects;
|
|
508
|
+
|
|
509
|
+
if (
|
|
510
|
+
packageJsonProjectGlobs &&
|
|
511
|
+
workspaceConfigProjectGlobs &&
|
|
512
|
+
!_.isEqual(packageJsonProjectGlobs, workspaceConfigProjectGlobs)
|
|
513
|
+
) {
|
|
514
|
+
throw new WorkspaceError('PROJECT_GLOBS_MISMATCH', {
|
|
515
|
+
data: {
|
|
516
|
+
path: this.path,
|
|
517
|
+
},
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
let projectGlobs = packageJsonProjectGlobs ?? workspaceConfigProjectGlobs;
|
|
449
522
|
|
|
450
523
|
this.projectGlobs = (projectGlobs ?? []) as WorkspaceProjectGlobs<M>;
|
|
451
524
|
this.packageJson = rootPackageJson as WorkspacePackageJson<M>;
|
|
@@ -19,6 +19,8 @@ export const WorkspaceError = createCustomErrorWithData(
|
|
|
19
19
|
DUPLICATE_PROJECT_NAME: 'Workspace already contains project with name "{0}"',
|
|
20
20
|
DUPLICATE_PROJECT_PATH: 'Workspace already contains project with path "{0}"',
|
|
21
21
|
TOO_MANY_PROJECTS: "Workspace can't contain more projects.",
|
|
22
|
+
PROJECT_GLOBS_MISMATCH:
|
|
23
|
+
'Workspace has mismatched project globs in package.json and workspace.json.',
|
|
22
24
|
},
|
|
23
25
|
class WorkspaceErrorData {
|
|
24
26
|
path?: string;
|