@yorozu/build 0.3.0 → 0.5.0

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
@@ -8,7 +8,7 @@ The root `package.json` `version` is the source of truth for every managed packa
8
8
 
9
9
  ```sh
10
10
  pnpm build # build every npm-publishable package (including standalone)
11
- pnpm lint:workspace # workspace: protocol + external version alignment
11
+ pnpm lint:workspace # workspace: protocol, external version alignment, prefer protected over private/#
12
12
  pnpm release:dry # print next version, changelog, and publish list
13
13
  pnpm release # bump, build, publish to npm, commit, and tag
14
14
  ```
@@ -1,4 +1,4 @@
1
- import { __toESM as __toESM$1, asNonNull, asyncPool, collectPackageJsons, error, fileExists, filterPackageJsonsForPublish, findPackageByName, findRootPackage, getWorkspaceRoot, info, loadBuildConfig, normalizeFilePath, number, object, parsePackageJsonFile, processPackageJson, require_picomatch, string as string$1, warn } from "./Boit7C7A.js";
1
+ import { __toESM as __toESM$1, asNonNull, asyncPool, collectPackageJsons, error, fileExists, filterPackageJsonsForPublish, findPackageByName, findRootPackage, getWorkspaceRoot, glob, info, loadBuildConfig, normalizeFilePath, number, object, parsePackageJsonFile, processPackageJson, require_picomatch, string as string$1, warn } from "./Boit7C7A.js";
2
2
  import { exec, require_semver, sortWorkspaceByPublishOrder } from "./C8taqIWx.js";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { appendFileSync } from "node:fs";
@@ -8,6 +8,7 @@ import { join, relative, resolve } from "node:path";
8
8
  import * as fsp from "node:fs/promises";
9
9
  import { readFile, writeFile } from "node:fs/promises";
10
10
  import * as td from "typedoc";
11
+ import ts from "typescript";
11
12
  //#region src/ci/github-actions.ts
12
13
  function isRunningInGithubActions() {
13
14
  return Boolean(process$1.env.GITHUB_ACTIONS);
@@ -29,50 +30,50 @@ function writeGithubActionsOutput(name, value) {
29
30
  //#endregion
30
31
  //#region ../utils/src/structures/lru-map.ts
31
32
  var LruMap = class {
32
- #capacity;
33
- #map;
33
+ _capacity;
34
+ _map;
34
35
  constructor(capacity, MapImpl = Map) {
35
- this.#capacity = capacity;
36
- this.#map = new MapImpl();
36
+ this._capacity = capacity;
37
+ this._map = new MapImpl();
37
38
  }
38
39
  get size() {
39
- return this.#map.size;
40
+ return this._map.size;
40
41
  }
41
42
  get(key) {
42
- if (!this.#map.has(key)) return void 0;
43
- let value = this.#map.get(key);
44
- this.#map.delete(key);
45
- this.#map.set(key, value);
43
+ if (!this._map.has(key)) return void 0;
44
+ let value = this._map.get(key);
45
+ this._map.delete(key);
46
+ this._map.set(key, value);
46
47
  return value;
47
48
  }
48
49
  has(key) {
49
- return this.#map.has(key);
50
+ return this._map.has(key);
50
51
  }
51
52
  set(key, value) {
52
- if (this.#map.has(key)) this.#map.delete(key);
53
- this.#map.set(key, value);
54
- if (this.#map.size > this.#capacity) {
55
- let oldest = this.#map.keys().next();
56
- if (!oldest.done) this.#map.delete(oldest.value);
53
+ if (this._map.has(key)) this._map.delete(key);
54
+ this._map.set(key, value);
55
+ if (this._map.size > this._capacity) {
56
+ let oldest = this._map.keys().next();
57
+ if (!oldest.done) this._map.delete(oldest.value);
57
58
  }
58
59
  }
59
60
  delete(key) {
60
- this.#map.delete(key);
61
+ this._map.delete(key);
61
62
  }
62
63
  clear() {
63
- this.#map.clear();
64
+ this._map.clear();
64
65
  }
65
66
  *[Symbol.iterator]() {
66
- yield* this.#map;
67
+ yield* this._map;
67
68
  }
68
69
  entries() {
69
- return this.#map.entries();
70
+ return this._map.entries();
70
71
  }
71
72
  keys() {
72
- return this.#map.keys();
73
+ return this._map.keys();
73
74
  }
74
75
  values() {
75
- return this.#map.values();
76
+ return this._map.values();
76
77
  }
77
78
  };
78
79
  //#endregion
@@ -1693,6 +1694,7 @@ var DEFAULT_CONFIG = {
1693
1694
  notDocumented: false
1694
1695
  },
1695
1696
  excludePrivate: true,
1697
+ excludeProtected: true,
1696
1698
  excludeExternals: true,
1697
1699
  excludeInternal: true,
1698
1700
  exclude: [
@@ -2176,6 +2178,77 @@ var runContinuousReleaseCli = command({
2176
2178
  handler: runContinuousRelease
2177
2179
  });
2178
2180
  //#endregion
2181
+ //#region src/cli/commands/lint/validate-prefer-protected.ts
2182
+ var IGNORE = [
2183
+ "**/node_modules/**",
2184
+ "**/dist/**",
2185
+ "**/__fixtures__/**"
2186
+ ];
2187
+ function findPreferProtectedIssues(source, fileName = "file.ts") {
2188
+ let file = ts.createSourceFile(fileName, source, ts.ScriptTarget.ESNext, true, ts.ScriptKind.TS);
2189
+ let errors = [];
2190
+ let visit = (node) => {
2191
+ let privateMod = privateModifier(node);
2192
+ if (privateMod) {
2193
+ let { line, character } = file.getLineAndCharacterOfPosition(privateMod.getStart(file));
2194
+ errors.push({
2195
+ type: "prefer_protected",
2196
+ file: fileName,
2197
+ line: line + 1,
2198
+ column: character + 1,
2199
+ kind: "private_keyword",
2200
+ name: memberName(node)
2201
+ });
2202
+ }
2203
+ if (ts.isPrivateIdentifier(node)) {
2204
+ let { line, character } = file.getLineAndCharacterOfPosition(node.getStart(file));
2205
+ errors.push({
2206
+ type: "prefer_protected",
2207
+ file: fileName,
2208
+ line: line + 1,
2209
+ column: character + 1,
2210
+ kind: "private_identifier",
2211
+ name: privateIdentifierName(node)
2212
+ });
2213
+ }
2214
+ ts.forEachChild(node, visit);
2215
+ };
2216
+ visit(file);
2217
+ return errors;
2218
+ }
2219
+ async function validatePreferProtected(params) {
2220
+ let workspaceRoot = normalizeFilePath(params.workspaceRoot);
2221
+ let { enabled = true, exclude = [] } = params.config?.preferProtected ?? {};
2222
+ if (!enabled) return [];
2223
+ let files = await glob("**/*.ts", {
2224
+ cwd: workspaceRoot,
2225
+ ignore: IGNORE
2226
+ });
2227
+ let isExcluded = exclude.length > 0 ? (0, import_picomatch.default)(exclude) : null;
2228
+ let errors = [];
2229
+ for (let file of files) {
2230
+ if (isExcluded?.(file)) continue;
2231
+ let source = await readFile(join(workspaceRoot, file), "utf8");
2232
+ errors.push(...findPreferProtectedIssues(source, file));
2233
+ }
2234
+ return errors;
2235
+ }
2236
+ function privateModifier(node) {
2237
+ if (!ts.canHaveModifiers(node)) return void 0;
2238
+ return ts.getModifiers(node)?.find((item) => item.kind === ts.SyntaxKind.PrivateKeyword);
2239
+ }
2240
+ function memberName(node) {
2241
+ if (ts.isConstructorDeclaration(node)) return "constructor";
2242
+ if (ts.isParameter(node) || ts.isPropertyDeclaration(node) || ts.isMethodDeclaration(node) || ts.isGetAccessorDeclaration(node) || ts.isSetAccessorDeclaration(node)) {
2243
+ if (ts.isIdentifier(node.name) || ts.isPrivateIdentifier(node.name)) return node.name.text;
2244
+ return node.name.getText();
2245
+ }
2246
+ return "";
2247
+ }
2248
+ function privateIdentifierName(node) {
2249
+ return node.text.startsWith("#") ? node.text.slice(1) : node.text;
2250
+ }
2251
+ //#endregion
2179
2252
  //#region src/cli/commands/lint/validate-workspace-deps.ts
2180
2253
  var import_semver = /* @__PURE__ */ __toESM$1(require_semver(), 1);
2181
2254
  var DEP_FIELDS = [
@@ -2617,4 +2690,4 @@ async function generateChangelog(params) {
2617
2690
  return changelog;
2618
2691
  }
2619
2692
  //#endregion
2620
- export { LruMap, NPM_PACKAGE_NAME_REGEX, boolean, buildPackage, buildPackageCli, buildWorkspace, bumpVersion, command, createGithubRelease, determineBumpType, findChangedFiles, findProjectChangedFiles, findProjectChangedPackages, generateChangelog, generateDepsGraph, generateDepsGraphCli, generateDocs, generateDocsCli, getCommitsBetween, getCurrentBranch, getCurrentCommit, getFirstCommit, getGithubActionsInput, getLatestTag, getTsconfigFiles, getTsconfigFor, gitTagExists, isRunningInGithubActions, loadConfig, npmCheckVersion, parseConventionalCommit, publishPackages, publishPackagesCli, resolveWorkspaceRoot, run, runContinuousRelease, runContinuousReleaseCli, string, validateWorkspaceDeps, writeGithubActionsOutput };
2693
+ export { LruMap, NPM_PACKAGE_NAME_REGEX, boolean, buildPackage, buildPackageCli, buildWorkspace, bumpVersion, command, createGithubRelease, determineBumpType, findChangedFiles, findProjectChangedFiles, findProjectChangedPackages, generateChangelog, generateDepsGraph, generateDepsGraphCli, generateDocs, generateDocsCli, getCommitsBetween, getCurrentBranch, getCurrentCommit, getFirstCommit, getGithubActionsInput, getLatestTag, getTsconfigFiles, getTsconfigFor, gitTagExists, isRunningInGithubActions, loadConfig, npmCheckVersion, parseConventionalCommit, publishPackages, publishPackagesCli, resolveWorkspaceRoot, run, runContinuousRelease, runContinuousReleaseCli, string, validatePreferProtected, validateWorkspaceDeps, writeGithubActionsOutput };
@@ -14,13 +14,13 @@ export declare function sharedWorkspaceBumpOptions(params: {
14
14
  export declare function formatBumpVersionResult(result: BumpVersionResult, withReleaseType: boolean): string;
15
15
  export declare let bumpVersionCli: bc.Command<{
16
16
  root: string | undefined;
17
- type: "patch" | "minor" | "major" | "auto";
17
+ type: "major" | "minor" | "patch" | "auto";
18
18
  since: string | undefined;
19
19
  dryRun: boolean | undefined;
20
20
  quiet: boolean | undefined;
21
21
  }, {
22
22
  root: string | undefined;
23
- type: "patch" | "minor" | "major" | "auto";
23
+ type: "major" | "minor" | "patch" | "auto";
24
24
  since: string | undefined;
25
25
  dryRun: boolean | undefined;
26
26
  quiet: boolean | undefined;
@@ -1,5 +1,8 @@
1
1
  import { bc } from '../_utils';
2
+ import { validatePreferProtected } from './validate-prefer-protected';
2
3
  import { validateWorkspaceDeps } from './validate-workspace-deps';
4
+ export { validatePreferProtected };
5
+ export type { PreferProtectedError } from './validate-prefer-protected';
3
6
  export { validateWorkspaceDeps };
4
7
  export type { ExternalDepsError, InternalDepsError, WorkspaceDepsError } from './validate-workspace-deps';
5
8
  export declare let lintCli: bc.Command<{
@@ -0,0 +1,15 @@
1
+ import { LintConfig } from './config';
2
+ export interface PreferProtectedError {
3
+ type: "prefer_protected";
4
+ file: string;
5
+ line: number;
6
+ column: number;
7
+ kind: "private_keyword" | "private_identifier";
8
+ name: string;
9
+ }
10
+ export declare function findPreferProtectedIssues(source: string, fileName?: string): Array<PreferProtectedError>;
11
+ export declare function rewritePreferProtected(source: string, fileName?: string): string;
12
+ export declare function validatePreferProtected(params: {
13
+ workspaceRoot: string | URL;
14
+ config?: LintConfig;
15
+ }): Promise<Array<PreferProtectedError>>;
@@ -5,7 +5,7 @@ export declare function shouldSkipAutoRelease(params: {
5
5
  commitsSincePrevTag: ReadonlyArray<unknown>;
6
6
  }): boolean;
7
7
  export declare let releaseCli: bc.Command<{
8
- kind: "patch" | "minor" | "major" | "auto";
8
+ kind: "major" | "minor" | "patch" | "auto";
9
9
  withGithubRelease: boolean;
10
10
  gitExtraOrigins: string | undefined;
11
11
  githubToken: string | undefined;
@@ -24,7 +24,7 @@ export declare let releaseCli: bc.Command<{
24
24
  noProvenance: boolean | undefined;
25
25
  dryRun: boolean | undefined;
26
26
  }, {
27
- kind: "patch" | "minor" | "major" | "auto";
27
+ kind: "major" | "minor" | "patch" | "auto";
28
28
  withGithubRelease: boolean;
29
29
  gitExtraOrigins: string | undefined;
30
30
  githubToken: string | undefined;
@@ -0,0 +1,32 @@
1
+ import { SpawnOptions } from 'node:child_process';
2
+ import { WorkspacePackage } from '../../package-json/collect-package-jsons';
3
+ import { ExecResult } from '../../misc/exec';
4
+ import { bc } from './_utils';
5
+ export interface TypecheckPackageResult {
6
+ name: string;
7
+ path: string;
8
+ ok: boolean;
9
+ output: string;
10
+ }
11
+ export interface TypecheckResult {
12
+ ok: boolean;
13
+ results: Array<TypecheckPackageResult>;
14
+ }
15
+ export type TypecheckExists = (file: string) => Promise<boolean>;
16
+ export type TypecheckRun = (cmd: Array<string>, options?: SpawnOptions & {
17
+ throwOnError?: boolean;
18
+ quiet?: boolean;
19
+ }) => Promise<ExecResult>;
20
+ export declare function typecheckTargets(packages: Array<WorkspacePackage>, exists?: TypecheckExists): Promise<Array<WorkspacePackage>>;
21
+ export declare function typecheckWorkspace(params: {
22
+ packages: Array<WorkspacePackage>;
23
+ exists?: TypecheckExists;
24
+ run?: TypecheckRun;
25
+ }): Promise<TypecheckResult>;
26
+ export declare let typecheckCli: bc.Command<{
27
+ workspace: string | undefined;
28
+ noErrorCode: boolean;
29
+ }, {
30
+ workspace: string | undefined;
31
+ noErrorCode: boolean;
32
+ }>;
package/cli/index.d.ts CHANGED
@@ -3,6 +3,8 @@ export { publishPackages } from './commands/publish';
3
3
  export { generateDocs } from './commands/docs';
4
4
  export { generateDepsGraph } from './commands/gen-deps-graph';
5
5
  export { runContinuousRelease } from './commands/cr';
6
+ export { validatePreferProtected } from './commands/lint/validate-prefer-protected';
7
+ export type { PreferProtectedError } from './commands/lint/validate-prefer-protected';
6
8
  export { validateWorkspaceDeps } from './commands/lint/validate-workspace-deps';
7
9
  export type { ExternalDepsError, InternalDepsError, WorkspaceDepsError, } from './commands/lint/validate-workspace-deps';
8
10
  export * from './log';
package/config.d.ts CHANGED
@@ -43,6 +43,10 @@ export interface LintConfig {
43
43
  field: "dependencies" | "devDependencies" | "peerDependencies" | "optionalDependencies";
44
44
  }) => boolean;
45
45
  };
46
+ preferProtected?: {
47
+ enabled?: boolean;
48
+ exclude?: Array<string>;
49
+ };
46
50
  }
47
51
  export interface RootConfigObject {
48
52
  viteConfig?: string;
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { PackageJsonSchema, collectPackageJsons, collectVersions, directoryExists, error, fileExists, filterPackageJsonsForPublish, findPackageByName, findRootPackage, getWorkspaceRoot, info, loadBuildConfig, normalizeFilePath, parsePackageJson, parsePackageJsonFile, parsePackageJsonFromDir, parseWorkspaceRootPackageJson, processPackageJson, removeCommonjsExports, tryCopy, warn } from "./chunks/Boit7C7A.js";
2
- import { LruMap, NPM_PACKAGE_NAME_REGEX, buildPackage, buildWorkspace, bumpVersion, createGithubRelease, determineBumpType, findChangedFiles, findProjectChangedFiles, findProjectChangedPackages, generateChangelog, generateDepsGraph, generateDocs, getCommitsBetween, getCurrentBranch, getCurrentCommit, getFirstCommit, getGithubActionsInput, getLatestTag, getTsconfigFiles, getTsconfigFor, gitTagExists, isRunningInGithubActions, npmCheckVersion, parseConventionalCommit, publishPackages, runContinuousRelease, validateWorkspaceDeps, writeGithubActionsOutput } from "./chunks/D8T5_c6n.js";
2
+ import { LruMap, NPM_PACKAGE_NAME_REGEX, buildPackage, buildWorkspace, bumpVersion, createGithubRelease, determineBumpType, findChangedFiles, findProjectChangedFiles, findProjectChangedPackages, generateChangelog, generateDepsGraph, generateDocs, getCommitsBetween, getCurrentBranch, getCurrentCommit, getFirstCommit, getGithubActionsInput, getLatestTag, getTsconfigFiles, getTsconfigFor, gitTagExists, isRunningInGithubActions, npmCheckVersion, parseConventionalCommit, publishPackages, runContinuousRelease, validatePreferProtected, validateWorkspaceDeps, writeGithubActionsOutput } from "./chunks/D0lp9Y4h.js";
3
3
  import { ExecError, determinePublishOrder, exec, sortWorkspaceByPublishOrder } from "./chunks/C8taqIWx.js";
4
4
  import { join } from "node:path";
5
5
  //#region src/package-json/find-package-json.ts
@@ -23,4 +23,4 @@ async function findPackageJson(from) {
23
23
  }
24
24
  }
25
25
  //#endregion
26
- export { ExecError, NPM_PACKAGE_NAME_REGEX, PackageJsonSchema, buildPackage, buildWorkspace, bumpVersion, collectPackageJsons, collectVersions, createGithubRelease, determineBumpType, determinePublishOrder, directoryExists, error, exec, fileExists, filterPackageJsonsForPublish, findChangedFiles, findPackageByName, findPackageJson, findProjectChangedFiles, findProjectChangedPackages, findRootPackage, generateChangelog, generateDepsGraph, generateDocs, getCommitsBetween, getCurrentBranch, getCurrentCommit, getFirstCommit, getGithubActionsInput, getLatestTag, getTsconfigFiles, getTsconfigFor, getWorkspaceRoot, gitTagExists, info, isRunningInGithubActions, loadBuildConfig, normalizeFilePath, npmCheckVersion, parseConventionalCommit, parsePackageJson, parsePackageJsonFile, parsePackageJsonFromDir, parseWorkspaceRootPackageJson, processPackageJson, publishPackages, removeCommonjsExports, runContinuousRelease, sortWorkspaceByPublishOrder, tryCopy, validateWorkspaceDeps, warn, writeGithubActionsOutput };
26
+ export { ExecError, NPM_PACKAGE_NAME_REGEX, PackageJsonSchema, buildPackage, buildWorkspace, bumpVersion, collectPackageJsons, collectVersions, createGithubRelease, determineBumpType, determinePublishOrder, directoryExists, error, exec, fileExists, filterPackageJsonsForPublish, findChangedFiles, findPackageByName, findPackageJson, findProjectChangedFiles, findProjectChangedPackages, findRootPackage, generateChangelog, generateDepsGraph, generateDocs, getCommitsBetween, getCurrentBranch, getCurrentCommit, getFirstCommit, getGithubActionsInput, getLatestTag, getTsconfigFiles, getTsconfigFor, getWorkspaceRoot, gitTagExists, info, isRunningInGithubActions, loadBuildConfig, normalizeFilePath, npmCheckVersion, parseConventionalCommit, parsePackageJson, parsePackageJsonFile, parsePackageJsonFromDir, parseWorkspaceRootPackageJson, processPackageJson, publishPackages, removeCommonjsExports, runContinuousRelease, sortWorkspaceByPublishOrder, tryCopy, validatePreferProtected, validateWorkspaceDeps, warn, writeGithubActionsOutput };
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@yorozu/build",
3
3
  "type": "module",
4
- "version": "0.3.0",
4
+ "version": "0.5.0",
5
5
  "description": "build and release utilities for yorozu packages",
6
6
  "license": "MIT",
7
7
  "dependencies": {
8
8
  "@drizzle-team/brocli": "0.12.0",
9
- "@yorozu/utils": "^0.3.0",
9
+ "@yorozu/utils": "^0.5.0",
10
10
  "cross-spawn": "7.0.6",
11
11
  "detect-indent": "7.0.2",
12
12
  "esbuild": "0.25.12",
package/yorozu-build.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { asNonNull, collectPackageJsons, error, filterPackageJsonsForPublish, findRootPackage, getWorkspaceRoot, info, parallelMap, warn } from "./chunks/Boit7C7A.js";
3
- import { boolean, buildPackageCli, bumpVersion, command, createGithubRelease, findProjectChangedPackages, generateChangelog, generateDepsGraphCli, generateDocsCli, getCommitsBetween, getLatestTag, gitTagExists, isRunningInGithubActions, loadConfig, publishPackages, publishPackagesCli, resolveWorkspaceRoot, run, runContinuousReleaseCli, string, validateWorkspaceDeps, writeGithubActionsOutput } from "./chunks/D8T5_c6n.js";
2
+ import { asNonNull, collectPackageJsons, error, fileExists, filterPackageJsonsForPublish, findRootPackage, getWorkspaceRoot, info, parallelMap, warn } from "./chunks/Boit7C7A.js";
3
+ import { boolean, buildPackageCli, bumpVersion, command, createGithubRelease, findProjectChangedPackages, generateChangelog, generateDepsGraphCli, generateDocsCli, getCommitsBetween, getLatestTag, gitTagExists, isRunningInGithubActions, loadConfig, publishPackages, publishPackagesCli, resolveWorkspaceRoot, run, runContinuousReleaseCli, string, validatePreferProtected, validateWorkspaceDeps, writeGithubActionsOutput } from "./chunks/D0lp9Y4h.js";
4
4
  import { ExecError, exec, sortWorkspaceByPublishOrder } from "./chunks/C8taqIWx.js";
5
5
  import { generateDenoWorkspace, jsrCreatePackages, populateFromUpstream } from "./chunks/DOprhwii.js";
6
6
  import process from "node:process";
7
- import { basename } from "node:path";
7
+ import { basename, join } from "node:path";
8
8
  import { readFile } from "node:fs/promises";
9
9
  //#region src/cli/commands/lint/index.ts
10
10
  var INTERNAL_MESSAGES = {
@@ -21,23 +21,102 @@ var lintCli = command({
21
21
  handler: async (args) => {
22
22
  let workspaceRoot = resolveWorkspaceRoot(args.workspace);
23
23
  let config = (await loadConfig({ workspaceRoot }))?.lint;
24
- let errors = await validateWorkspaceDeps({
24
+ let depErrors = await validateWorkspaceDeps({
25
25
  workspaceRoot,
26
26
  config
27
27
  });
28
- if (errors.length === 0) {
29
- info("workspace dependencies look good");
30
- return;
31
- }
32
- let externalErrors = errors.filter((item) => item.type === "external");
33
- let internalErrors = errors.filter((item) => item.type === "internal");
34
- if (externalErrors.length > 0) {
35
- warn("Found external dependencies mismatch:");
36
- for (let item of externalErrors) warn(` - at ${item.package}: ${item.at} has ${item.dependency}@${item.version}, but ${item.otherPackage} has @${item.otherVersion}`);
28
+ let memberErrors = await validatePreferProtected({
29
+ workspaceRoot,
30
+ config
31
+ });
32
+ if (depErrors.length === 0) info("workspace dependencies look good");
33
+ else reportDepErrors(depErrors);
34
+ if (memberErrors.length === 0) info("class members look good");
35
+ else reportMemberErrors(memberErrors);
36
+ if (depErrors.length === 0 && memberErrors.length === 0) return;
37
+ if (!args.noErrorCode) process.exit(1);
38
+ }
39
+ });
40
+ function reportDepErrors(errors) {
41
+ let externalErrors = errors.filter((item) => item.type === "external");
42
+ let internalErrors = errors.filter((item) => item.type === "internal");
43
+ if (externalErrors.length > 0) {
44
+ warn("Found external dependencies mismatch:");
45
+ for (let item of externalErrors) warn(` - at ${item.package}: ${item.at} has ${item.dependency}@${item.version}, but ${item.otherPackage} has @${item.otherVersion}`);
46
+ }
47
+ if (internalErrors.length > 0) {
48
+ warn("Found issues with internal dependencies:");
49
+ for (let item of internalErrors) warn(` - at ${item.package}, dependency ${item.dependency}: ${INTERNAL_MESSAGES[item.subtype]}`);
50
+ }
51
+ }
52
+ function reportMemberErrors(errors) {
53
+ warn("Found private / # class members (use protected):");
54
+ for (let item of errors) {
55
+ let label = item.kind === "private_identifier" ? `#${item.name}` : `private ${item.name}`;
56
+ let hint = item.kind === "private_identifier" ? `protected ${item.name.startsWith("_") ? item.name : `_${item.name}`}` : "protected";
57
+ warn(` - at ${item.file}:${item.line}:${item.column}: ${label} — use ${hint}`);
58
+ }
59
+ }
60
+ //#endregion
61
+ //#region src/cli/commands/typecheck.ts
62
+ async function typecheckTargets(packages, exists = fileExists) {
63
+ let targets = [];
64
+ for (let item of packages) {
65
+ if (item.root) continue;
66
+ if (!await exists(join(item.path, "tsconfig.json"))) continue;
67
+ targets.push(item);
68
+ }
69
+ return targets;
70
+ }
71
+ async function typecheckWorkspace(params) {
72
+ let run = params.run ?? exec;
73
+ let targets = await typecheckTargets(params.packages, params.exists);
74
+ let results = [];
75
+ for (let item of targets) {
76
+ let spawned = await run([
77
+ "npx",
78
+ "tsc",
79
+ "--noEmit",
80
+ "--pretty",
81
+ "false",
82
+ "-p",
83
+ "tsconfig.json"
84
+ ], {
85
+ cwd: item.path,
86
+ throwOnError: false
87
+ });
88
+ let output = `${spawned.stdout}${spawned.stderr}`;
89
+ results.push({
90
+ name: asNonNull(item.json.name),
91
+ path: item.path,
92
+ ok: spawned.exitCode === 0,
93
+ output
94
+ });
95
+ }
96
+ return {
97
+ ok: results.every((item) => item.ok),
98
+ results
99
+ };
100
+ }
101
+ var typecheckCli = command({
102
+ name: "typecheck",
103
+ desc: "run tsc --noEmit for every workspace package",
104
+ options: {
105
+ workspace: string().desc("path to the workspace root (default: cwd)"),
106
+ noErrorCode: boolean("no-error-code").desc("whether to always exit with a zero code").default(false)
107
+ },
108
+ handler: async (args) => {
109
+ let result = await typecheckWorkspace({ packages: await collectPackageJsons(resolveWorkspaceRoot(args.workspace), true) });
110
+ for (let item of result.results) {
111
+ if (item.ok) {
112
+ info(`typecheck ok: ${item.name}`);
113
+ continue;
114
+ }
115
+ error(/* @__PURE__ */ new Error(`typecheck failed: ${item.name}\n${item.output}`));
37
116
  }
38
- if (internalErrors.length > 0) {
39
- warn("Found issues with internal dependencies:");
40
- for (let item of internalErrors) warn(` - at ${item.package}, dependency ${item.dependency}: ${INTERNAL_MESSAGES[item.subtype]}`);
117
+ if (result.ok) {
118
+ info("all packages typecheck");
119
+ return;
41
120
  }
42
121
  if (!args.noErrorCode) process.exit(1);
43
122
  }
@@ -205,6 +284,7 @@ async function nextDateTag(root) {
205
284
  //#region src/cli/main.ts
206
285
  await run([
207
286
  lintCli,
287
+ typecheckCli,
208
288
  buildPackageCli,
209
289
  publishPackagesCli,
210
290
  bumpVersionCli,