@fuman/build 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +108 -0
  3. package/ci/github-actions.d.ts +3 -0
  4. package/ci/github-actions.js +28 -0
  5. package/ci/index.d.ts +1 -0
  6. package/cli/commands/_utils.d.ts +8 -0
  7. package/cli/commands/_utils.js +18 -0
  8. package/cli/commands/build.d.ts +20 -0
  9. package/cli/commands/build.js +45 -0
  10. package/cli/commands/bump-version.d.ts +18 -0
  11. package/cli/commands/bump-version.js +72 -0
  12. package/cli/commands/cr.d.ts +17 -0
  13. package/cli/commands/cr.js +76 -0
  14. package/cli/commands/find-changed-packages.d.ts +12 -0
  15. package/cli/commands/find-changed-packages.js +44 -0
  16. package/cli/commands/gen-changelog.d.ts +12 -0
  17. package/cli/commands/gen-changelog.js +49 -0
  18. package/cli/commands/gen-deps-graph.d.ts +15 -0
  19. package/cli/commands/gen-deps-graph.js +78 -0
  20. package/cli/commands/jsr.d.ts +6 -0
  21. package/cli/commands/jsr.js +79 -0
  22. package/cli/commands/publish.d.ts +48 -0
  23. package/cli/commands/publish.js +197 -0
  24. package/cli/commands/release.d.ts +34 -0
  25. package/cli/commands/release.js +226 -0
  26. package/cli/commands/validate-workspace-deps.d.ts +38 -0
  27. package/cli/commands/validate-workspace-deps.js +68 -0
  28. package/cli/index.d.ts +3 -0
  29. package/cli/main.d.ts +2 -0
  30. package/config.d.ts +32 -0
  31. package/fuman-build.d.ts +1 -0
  32. package/fuman-build.js +33 -0
  33. package/git/github.d.ts +14 -0
  34. package/git/github.js +48 -0
  35. package/git/index.d.ts +1 -0
  36. package/git/utils.d.ts +38 -0
  37. package/git/utils.js +110 -0
  38. package/index.d.ts +7 -0
  39. package/index.js +46 -0
  40. package/jsr/build-jsr.d.ts +7 -0
  41. package/jsr/build-jsr.js +145 -0
  42. package/jsr/config.d.ts +48 -0
  43. package/jsr/create-packages.d.ts +8 -0
  44. package/jsr/create-packages.js +46 -0
  45. package/jsr/deno-json.d.ts +19 -0
  46. package/jsr/deno-json.js +80 -0
  47. package/jsr/generate-workspace.d.ts +9 -0
  48. package/jsr/generate-workspace.js +174 -0
  49. package/jsr/index.d.ts +5 -0
  50. package/jsr/populate.d.ts +45 -0
  51. package/jsr/populate.js +132 -0
  52. package/jsr/utils/external-libs.d.ts +8 -0
  53. package/jsr/utils/external-libs.js +46 -0
  54. package/jsr/utils/index.d.ts +4 -0
  55. package/jsr/utils/jsr-api.d.ts +23 -0
  56. package/jsr/utils/jsr-api.js +115 -0
  57. package/jsr/utils/jsr-json.d.ts +10 -0
  58. package/jsr/utils/jsr-json.js +80 -0
  59. package/jsr/utils/jsr.d.ts +11 -0
  60. package/jsr/utils/jsr.js +74 -0
  61. package/jsr.d.ts +1 -0
  62. package/jsr.js +23 -0
  63. package/misc/_config.d.ts +1 -0
  64. package/misc/_config.js +18 -0
  65. package/misc/exec.d.ts +9 -0
  66. package/misc/exec.js +40 -0
  67. package/misc/fs.d.ts +4 -0
  68. package/misc/fs.js +32 -0
  69. package/misc/index.d.ts +4 -0
  70. package/misc/path.d.ts +1 -0
  71. package/misc/path.js +12 -0
  72. package/misc/publish-order.d.ts +3 -0
  73. package/misc/publish-order.js +56 -0
  74. package/misc/tsconfig.d.ts +2 -0
  75. package/misc/tsconfig.js +28 -0
  76. package/npm/index.d.ts +1 -0
  77. package/npm/npm-api.d.ts +7 -0
  78. package/npm/npm-api.js +18 -0
  79. package/package-json/collect-package-jsons.d.ts +8 -0
  80. package/package-json/collect-package-jsons.js +61 -0
  81. package/package-json/find-package-json.d.ts +7 -0
  82. package/package-json/find-package-json.js +28 -0
  83. package/package-json/index.d.ts +5 -0
  84. package/package-json/parse.d.ts +4 -0
  85. package/package-json/parse.js +40 -0
  86. package/package-json/process-package-json.d.ts +13 -0
  87. package/package-json/process-package-json.js +132 -0
  88. package/package-json/types.d.ts +56 -0
  89. package/package-json/types.js +57 -0
  90. package/package-json/utils.d.ts +4 -0
  91. package/package-json/utils.js +27 -0
  92. package/package.json +67 -0
  93. package/versioning/bump-version.d.ts +48 -0
  94. package/versioning/bump-version.js +129 -0
  95. package/versioning/collect-files.d.ts +22 -0
  96. package/versioning/collect-files.js +66 -0
  97. package/versioning/generate-changelog.d.ts +13 -0
  98. package/versioning/generate-changelog.js +81 -0
  99. package/versioning/types.d.ts +32 -0
  100. package/vite/build-plugin.d.ts +73 -0
  101. package/vite/build-plugin.js +170 -0
  102. package/vite/config.d.ts +34 -0
  103. package/vite/index.d.ts +2 -0
  104. package/vite.d.ts +1 -0
  105. package/vite.js +4 -0
@@ -0,0 +1,132 @@
1
+ const DEFAULT_FIELDS_TO_COPY_ROOT = ["license", "author", "contributors", "homepage", "repository", "bugs"];
2
+ function processPackageJson(params) {
3
+ const {
4
+ packageJson: packageJsonOrig,
5
+ workspaceVersions,
6
+ rootPackageJson,
7
+ rootFieldsToCopy = DEFAULT_FIELDS_TO_COPY_ROOT,
8
+ bundledWorkspaceDeps,
9
+ fixedVersion
10
+ } = params;
11
+ const packageJson = structuredClone(packageJsonOrig);
12
+ const entrypoints = {};
13
+ for (const field of rootFieldsToCopy) {
14
+ if (rootPackageJson?.[field] != null && packageJson[field] == null) {
15
+ packageJson[field] = rootPackageJson[field];
16
+ }
17
+ }
18
+ const newScripts = {};
19
+ if (packageJson.scripts && Array.isArray(packageJson.fuman?.keepScripts)) {
20
+ for (const script of packageJson.fuman.keepScripts) {
21
+ if (typeof script !== "string") continue;
22
+ if (script in packageJson.scripts) continue;
23
+ newScripts[script] = packageJson.scripts[script];
24
+ }
25
+ delete packageJson.keepScripts;
26
+ }
27
+ packageJson.scripts = newScripts;
28
+ delete packageJson.devDependencies;
29
+ delete packageJson.private;
30
+ if (packageJson.fuman?.distOnlyFields) {
31
+ Object.assign(packageJson, packageJson.fuman.distOnlyFields);
32
+ delete packageJson.distOnlyFields;
33
+ }
34
+ function replaceWorkspaceDependencies(field) {
35
+ if (packageJson[field] == null) return;
36
+ const dependencies = packageJson[field];
37
+ for (const name of Object.keys(dependencies)) {
38
+ const value = dependencies[name];
39
+ if (value.startsWith("workspace:")) {
40
+ if (bundledWorkspaceDeps) {
41
+ let found = false;
42
+ for (const dep of bundledWorkspaceDeps) {
43
+ if (dep.test(name)) {
44
+ delete dependencies[name];
45
+ found = true;
46
+ break;
47
+ }
48
+ }
49
+ if (found) continue;
50
+ }
51
+ if (value !== "workspace:^" && value !== "workspace:*") {
52
+ throw new Error(
53
+ `Cannot replace workspace dependency ${name} with ${value} - only workspace:^ and * are supported`
54
+ );
55
+ }
56
+ if (workspaceVersions?.[name] == null) {
57
+ throw new Error(`Cannot replace workspace: dependency ${name} not found in workspace`);
58
+ }
59
+ if (fixedVersion != null) {
60
+ dependencies[name] = fixedVersion;
61
+ continue;
62
+ }
63
+ const workspaceVersion = workspaceVersions?.[name];
64
+ const depVersion = value === "workspace:*" ? workspaceVersion : `^${workspaceVersion}`;
65
+ dependencies[name] = depVersion;
66
+ }
67
+ }
68
+ }
69
+ replaceWorkspaceDependencies("dependencies");
70
+ replaceWorkspaceDependencies("devDependencies");
71
+ replaceWorkspaceDependencies("peerDependencies");
72
+ replaceWorkspaceDependencies("optionalDependencies");
73
+ delete packageJson.typedoc;
74
+ delete packageJson.eslintConfig;
75
+ delete packageJson.eslintIgnore;
76
+ delete packageJson.prettier;
77
+ delete packageJson.fuman;
78
+ if (packageJson.exports != null) {
79
+ let exports = packageJson.exports;
80
+ if (typeof exports === "string") {
81
+ exports = { ".": exports };
82
+ }
83
+ if (typeof exports !== "object") {
84
+ throw new TypeError("package.json exports must be an object");
85
+ }
86
+ const newExports = {};
87
+ for (const [key, value] of Object.entries(exports)) {
88
+ if (typeof value !== "string") {
89
+ throw new TypeError(`package.json exports value must be a string: ${key}`);
90
+ }
91
+ if (value.endsWith(".wasm")) {
92
+ newExports[key] = value;
93
+ continue;
94
+ }
95
+ let entrypointName = key.replace(/^\.(?:\/|$)/, "").replace(/\.js$/, "");
96
+ if (entrypointName === "") entrypointName = "index";
97
+ entrypoints[entrypointName] = value;
98
+ newExports[key] = {
99
+ import: {
100
+ types: `./${entrypointName}.d.ts`,
101
+ default: `./${entrypointName}.js`
102
+ },
103
+ require: {
104
+ types: `./${entrypointName}.d.cts`,
105
+ default: `./${entrypointName}.cjs`
106
+ }
107
+ };
108
+ }
109
+ packageJson.exports = newExports;
110
+ }
111
+ if (packageJson.bin != null) {
112
+ const newBin = {};
113
+ for (const [key, value] of Object.entries(packageJson.bin)) {
114
+ if (typeof value !== "string") {
115
+ throw new TypeError(`package.json bin value must be a string: ${key}`);
116
+ }
117
+ let entrypointName = key.replace(/^\.(?:\/|$)/, "").replace(/\.js$/, "");
118
+ if (entrypointName === "") entrypointName = "index";
119
+ entrypoints[entrypointName] = value;
120
+ newBin[key] = `${entrypointName}.js`;
121
+ }
122
+ packageJson.bin = newBin;
123
+ }
124
+ return {
125
+ packageJsonOrig,
126
+ packageJson,
127
+ entrypoints
128
+ };
129
+ }
130
+ export {
131
+ processPackageJson
132
+ };
@@ -0,0 +1,56 @@
1
+ import { z } from 'zod';
2
+ export interface PackageJson {
3
+ name?: string;
4
+ type?: 'module' | 'commonjs';
5
+ version?: string;
6
+ private?: boolean;
7
+ description?: string;
8
+ packageManager?: string;
9
+ license?: string;
10
+ homepage?: string;
11
+ repository?: (string | {
12
+ type: string;
13
+ url: string;
14
+ });
15
+ keywords?: string[];
16
+ workspaces?: string[];
17
+ scripts?: Record<string, string>;
18
+ dependencies?: Record<string, string>;
19
+ devDependencies?: Record<string, string>;
20
+ peerDependencies?: Record<string, string>;
21
+ optionalDependencies?: Record<string, string>;
22
+ bundledDependencies?: Record<string, string>;
23
+ engines?: Record<string, string>;
24
+ pnpm?: {
25
+ overrides: Record<string, string>;
26
+ };
27
+ /** fuman-specific package.json fields */
28
+ fuman?: {
29
+ /**
30
+ * whether the package should be published to jsr
31
+ * (skip – it won't be published to jsr, only – it will only be published to jsr)
32
+ */
33
+ jsr?: 'skip' | 'only';
34
+ /**
35
+ * whether the package should be published to npm
36
+ * (skip – it won't be published to npm, only – it will only be published to npm)
37
+ */
38
+ npm?: 'skip' | 'only';
39
+ /** by default @fuman/build strips all scripts, but you can keep some of them by passing their names here */
40
+ keepScripts?: string[];
41
+ /**
42
+ * any additional fields that will be shallowly merged into the resulting package.json.
43
+ * for more complex modifications than shallow merging, consider using build.config.js
44
+ */
45
+ distOnlyFields?: Record<string, unknown>;
46
+ /**
47
+ * whether this package has its own versioning scheme
48
+ * (be careful with this option! this might break cross-release semver compatibility)
49
+ */
50
+ ownVersioning?: boolean;
51
+ /** whether this package should not be published */
52
+ private?: boolean;
53
+ };
54
+ [key: string]: any;
55
+ }
56
+ export declare const PackageJsonSchema: z.AnyZodObject;
@@ -0,0 +1,57 @@
1
+ import { z } from "zod";
2
+ const PackageJsonSchema = z.object({
3
+ name: z.string(),
4
+ type: z.union([
5
+ z.literal("module"),
6
+ z.literal("commonjs")
7
+ ]),
8
+ version: z.string(),
9
+ private: z.boolean(),
10
+ description: z.string(),
11
+ packageManager: z.string(),
12
+ license: z.string(),
13
+ homepage: z.string(),
14
+ repository: z.union([
15
+ z.string(),
16
+ z.object({
17
+ type: z.string(),
18
+ url: z.string()
19
+ })
20
+ ]).transform((val) => {
21
+ if (typeof val === "string") {
22
+ return { type: "git", url: val };
23
+ }
24
+ return val;
25
+ }),
26
+ keywords: z.array(z.string()),
27
+ workspaces: z.array(z.string()),
28
+ scripts: z.record(z.string()),
29
+ dependencies: z.record(z.string()),
30
+ devDependencies: z.record(z.string()),
31
+ peerDependencies: z.record(z.string()),
32
+ optionalDependencies: z.record(z.string()),
33
+ bundledDependencies: z.array(z.string()),
34
+ engines: z.record(z.string()),
35
+ pnpm: z.object({
36
+ overrides: z.record(z.string())
37
+ }),
38
+ fuman: z.object({
39
+ jsr: z.union([
40
+ z.literal("skip"),
41
+ z.literal("only")
42
+ ]),
43
+ npm: z.union([
44
+ z.literal("skip"),
45
+ z.literal("only")
46
+ ]),
47
+ keepScripts: z.array(z.string()),
48
+ distOnlyFields: z.record(z.unknown()),
49
+ ownVersioning: z.boolean(),
50
+ private: z.boolean()
51
+ }).partial(),
52
+ // todo: properly type this
53
+ exports: z.any()
54
+ }).passthrough().partial();
55
+ export {
56
+ PackageJsonSchema
57
+ };
@@ -0,0 +1,4 @@
1
+ import { WorkspacePackage } from './collect-package-jsons.js';
2
+ export declare function findPackageByName(packages: WorkspacePackage[], name: string): WorkspacePackage;
3
+ export declare function findRootPackage(packages: WorkspacePackage[]): WorkspacePackage;
4
+ export declare function collectVersions(packages: WorkspacePackage[]): Record<string, string>;
@@ -0,0 +1,27 @@
1
+ function findPackageByName(packages, name) {
2
+ const pkg = packages.find((it) => it.json.name === name);
3
+ if (!pkg) {
4
+ throw new Error(`Could not find package.json for ${name}`);
5
+ }
6
+ return pkg;
7
+ }
8
+ function findRootPackage(packages) {
9
+ const pkg = packages.find((it) => it.root);
10
+ if (!pkg) {
11
+ throw new Error("Could not find package.json for workspace root");
12
+ }
13
+ return pkg;
14
+ }
15
+ function collectVersions(packages) {
16
+ const versions = {};
17
+ for (const pkg of packages) {
18
+ if (pkg.root || pkg.json.name == null || pkg.json.version == null) continue;
19
+ versions[pkg.json.name] = pkg.json.version;
20
+ }
21
+ return versions;
22
+ }
23
+ export {
24
+ collectVersions,
25
+ findPackageByName,
26
+ findRootPackage
27
+ };
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@fuman/build",
3
+ "type": "module",
4
+ "version": "0.0.1",
5
+ "description": "utils for building packages and managing monorepos",
6
+ "license": "MIT",
7
+ "scripts": {},
8
+ "dependencies": {
9
+ "@drizzle-team/brocli": "^0.10.2",
10
+ "@fuman/fetch": "^0.0.1",
11
+ "@fuman/io": "^0.0.1",
12
+ "@fuman/node": "^0.0.1",
13
+ "@fuman/utils": "^0.0.1",
14
+ "cross-spawn": "^7.0.5",
15
+ "detect-indent": "^7.0.1",
16
+ "js-yaml": "^4.1.0",
17
+ "picomatch": "^4.0.2",
18
+ "semver": "^7.6.3",
19
+ "tinyglobby": "^0.2.6",
20
+ "zod": "^3.23.8"
21
+ },
22
+ "peerDependencies": {
23
+ "typescript": "^5.2.2",
24
+ "vite": "^5.4.0"
25
+ },
26
+ "exports": {
27
+ ".": {
28
+ "import": {
29
+ "types": "./index.d.ts",
30
+ "default": "./index.js"
31
+ },
32
+ "require": {
33
+ "types": "./index.d.cts",
34
+ "default": "./index.cjs"
35
+ }
36
+ },
37
+ "./vite": {
38
+ "import": {
39
+ "types": "./vite.d.ts",
40
+ "default": "./vite.js"
41
+ },
42
+ "require": {
43
+ "types": "./vite.d.cts",
44
+ "default": "./vite.cjs"
45
+ }
46
+ },
47
+ "./jsr": {
48
+ "import": {
49
+ "types": "./jsr.d.ts",
50
+ "default": "./jsr.js"
51
+ },
52
+ "require": {
53
+ "types": "./jsr.d.cts",
54
+ "default": "./jsr.cjs"
55
+ }
56
+ }
57
+ },
58
+ "sideEffects": false,
59
+ "bin": {
60
+ "fuman-build": "fuman-build.js"
61
+ },
62
+ "author": "",
63
+ "repository": {
64
+ "type": "git",
65
+ "url": "git+https://github.com/teidesu/fuman.git"
66
+ }
67
+ }
@@ -0,0 +1,48 @@
1
+ import { ReleaseType } from 'semver';
2
+ import { WorkspacePackage } from '../package-json/collect-package-jsons.js';
3
+ import { VersioningOptions } from './types.js';
4
+ export interface BumpVersionPackage {
5
+ /** info about the package */
6
+ package: WorkspacePackage;
7
+ /**
8
+ * if the package was not changed by itself,
9
+ * but the bump is required because of another package
10
+ * that was changed depending on it, name of that package
11
+ */
12
+ because?: string[];
13
+ }
14
+ export interface BumpVersionResult {
15
+ /** max version of all packages */
16
+ maxVersion: string;
17
+ /** next version */
18
+ nextVersion: string;
19
+ /** changed packages which will be bumped to `nextVersion` */
20
+ changedPackages: BumpVersionPackage[];
21
+ /** detected release type */
22
+ releaseType: ReleaseType;
23
+ /**
24
+ * whether there are breaking changes
25
+ * (note: will be false if release type is explicitly provided)
26
+ */
27
+ hasBreakingChanges: boolean;
28
+ /**
29
+ * whether there are new features
30
+ * (note: will be false if release type is explicitly provided)
31
+ */
32
+ hasFeatures: boolean;
33
+ }
34
+ export declare function bumpVersion(params: {
35
+ /** packages for which to generate the changelog */
36
+ workspace: WorkspacePackage[];
37
+ /** whether to bump version of all packages, not just changed ones */
38
+ all?: boolean;
39
+ type?: ReleaseType;
40
+ /** root of the git repo */
41
+ cwd?: string | URL;
42
+ /** starting point for the changelog (defaults to latest tag) */
43
+ since: string;
44
+ /** versioning params */
45
+ params?: VersioningOptions;
46
+ /** whether to not actually write the files */
47
+ dryRun?: boolean;
48
+ }): Promise<BumpVersionResult>;
@@ -0,0 +1,129 @@
1
+ import * as fsp from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import process from "node:process";
4
+ import { asNonNull } from "@fuman/utils";
5
+ import detectIndent from "detect-indent";
6
+ import { parse, inc, satisfies, gt } from "semver";
7
+ import { getCommitsBetween, parseConventionalCommit } from "../git/utils.js";
8
+ import { collectVersions } from "../package-json/utils.js";
9
+ import { findProjectChangedPackages } from "./collect-files.js";
10
+ async function bumpVersion(params) {
11
+ const {
12
+ workspace,
13
+ all,
14
+ cwd = process.cwd(),
15
+ since,
16
+ dryRun = false
17
+ } = params;
18
+ let maxVersion = null;
19
+ for (const pkg of workspace) {
20
+ const version = asNonNull(pkg.json.version);
21
+ if (pkg.json.fuman?.ownVersioning) {
22
+ continue;
23
+ }
24
+ if (maxVersion == null || gt(version, maxVersion)) {
25
+ maxVersion = version;
26
+ }
27
+ }
28
+ if (maxVersion == null) {
29
+ throw new Error("No packages found with fuman-managed versioning");
30
+ }
31
+ const changedPackages = all ? workspace : await findProjectChangedPackages({
32
+ root: cwd,
33
+ since,
34
+ params: params.params
35
+ });
36
+ let type = params.type;
37
+ let hasFeatures = false;
38
+ let hasBreakingChanges = false;
39
+ if (type == null) {
40
+ for (const commit of await getCommitsBetween({
41
+ since,
42
+ cwd
43
+ })) {
44
+ const parsed = parseConventionalCommit(commit.message);
45
+ if (!parsed) continue;
46
+ if (parsed.breaking) hasBreakingChanges = true;
47
+ if (parsed.type === "feat") hasFeatures = true;
48
+ }
49
+ const parsedVersion = parse(maxVersion);
50
+ if (!parsedVersion) {
51
+ throw new Error(`Invalid version: ${maxVersion}`);
52
+ }
53
+ if (hasBreakingChanges) {
54
+ if (parsedVersion.major === 0 && parsedVersion.minor === 0) {
55
+ type = "patch";
56
+ } else if (parsedVersion.major === 0) {
57
+ type = "minor";
58
+ } else {
59
+ type = "major";
60
+ }
61
+ } else if (hasFeatures) {
62
+ type = parsedVersion.major === 0 ? "patch" : "minor";
63
+ } else {
64
+ type = "patch";
65
+ }
66
+ }
67
+ const nextVersion = inc(maxVersion, type);
68
+ if (nextVersion == null) {
69
+ throw new Error(`Invalid version increment: ${maxVersion} → ${type}`);
70
+ }
71
+ const workspaceVersions = collectVersions(workspace);
72
+ const result = [];
73
+ for (const pkg of changedPackages) {
74
+ if (pkg.json.fuman?.ownVersioning) continue;
75
+ result.push({ package: pkg });
76
+ }
77
+ for (const pkg of changedPackages) {
78
+ if (pkg.json.fuman?.ownVersioning) continue;
79
+ const pkgName = asNonNull(pkg.json.name);
80
+ for (const otherPkg of workspace) {
81
+ for (const kind of ["dependencies", "peerDependencies"]) {
82
+ const obj = otherPkg.json[kind];
83
+ if (obj == null) continue;
84
+ if (obj[pkgName] == null || typeof obj[pkgName] !== "string") continue;
85
+ let expandedVersion = obj[pkgName];
86
+ if (expandedVersion === "workspace:^") expandedVersion = `^${workspaceVersions[pkgName]}`;
87
+ if (expandedVersion === "workspace:*") expandedVersion = workspaceVersions[pkgName];
88
+ if (!satisfies(nextVersion, expandedVersion)) {
89
+ if (otherPkg.json.fuman?.ownVersioning) {
90
+ throw new Error(`package ${otherPkg.json.name}@${otherPkg.json.version} is marked as "own versioning", and will not be compatible with ${pkgName}@${expandedVersion} after bumping. please bump it manually`);
91
+ }
92
+ const existing = result.find((pkg2) => pkg2.package.json.name === otherPkg.json.name);
93
+ if (existing) {
94
+ if (!existing.because) break;
95
+ existing.because.push(pkgName);
96
+ } else {
97
+ result.push({
98
+ package: otherPkg,
99
+ because: [pkgName]
100
+ });
101
+ }
102
+ break;
103
+ }
104
+ }
105
+ }
106
+ }
107
+ if (!dryRun) {
108
+ for (const { package: pkg } of result) {
109
+ const pkgJsonPath = join(pkg.path, "package.json");
110
+ const pkgJsonText = await fsp.readFile(pkgJsonPath, "utf8");
111
+ const indent = detectIndent(pkgJsonText).indent || " ";
112
+ const pkgJson = JSON.parse(pkgJsonText);
113
+ pkgJson.version = nextVersion;
114
+ await fsp.writeFile(pkgJsonPath, `${JSON.stringify(pkgJson, null, indent)}
115
+ `);
116
+ }
117
+ }
118
+ return {
119
+ maxVersion,
120
+ nextVersion,
121
+ changedPackages: result,
122
+ releaseType: type,
123
+ hasBreakingChanges,
124
+ hasFeatures
125
+ };
126
+ }
127
+ export {
128
+ bumpVersion
129
+ };
@@ -0,0 +1,22 @@
1
+ import { VersioningOptions } from './types.js';
2
+ import { WorkspacePackage } from '../package-json/index.js';
3
+ export interface ProjectChangedFile {
4
+ /** package to which the file belongs */
5
+ package: WorkspacePackage;
6
+ /** path to the file relative to the package root */
7
+ file: string;
8
+ /** path to workspace root */
9
+ root: string;
10
+ }
11
+ export declare function findProjectChangedFiles(params: {
12
+ params?: VersioningOptions;
13
+ root?: string | URL;
14
+ since: string;
15
+ until?: string;
16
+ }): Promise<ProjectChangedFile[]>;
17
+ export declare function findProjectChangedPackages(params: {
18
+ params?: VersioningOptions;
19
+ root?: string | URL;
20
+ since: string;
21
+ until?: string;
22
+ }): Promise<WorkspacePackage[]>;
@@ -0,0 +1,66 @@
1
+ import { relative, join } from "node:path";
2
+ import process from "node:process";
3
+ import picomatch from "picomatch";
4
+ import { findChangedFiles } from "../git/utils.js";
5
+ import { normalizeFilePath } from "../misc/path.js";
6
+ import { getTsconfigFiles } from "../misc/tsconfig.js";
7
+ import { collectPackageJsons } from "../package-json/collect-package-jsons.js";
8
+ async function defaultShouldInclude(file) {
9
+ if (!file.file.endsWith(".ts")) return true;
10
+ if (file.package == null) return false;
11
+ const tsconfigFiles = await getTsconfigFiles(join(file.root, file.package.path));
12
+ return tsconfigFiles.includes(file.file);
13
+ }
14
+ async function findProjectChangedFiles(params) {
15
+ const {
16
+ params: {
17
+ include,
18
+ exclude = ["**/*.test.ts"],
19
+ shouldInclude = defaultShouldInclude
20
+ } = {},
21
+ root: root_ = process.cwd(),
22
+ since,
23
+ until
24
+ } = params;
25
+ const root = normalizeFilePath(root_);
26
+ const changed = await findChangedFiles({
27
+ since,
28
+ until,
29
+ cwd: root
30
+ });
31
+ if (!changed.length) return [];
32
+ const packages = await collectPackageJsons(root);
33
+ for (const pkg of packages) {
34
+ pkg.path = relative(root, pkg.path);
35
+ }
36
+ const files = [];
37
+ const includeGlobs = include == null ? null : picomatch(include);
38
+ const excludeGlobs = exclude == null ? null : picomatch(exclude);
39
+ for (const file of changed) {
40
+ const pkg = packages.find((pkg2) => file.startsWith(pkg2.path));
41
+ if (!pkg) continue;
42
+ const relPath = relative(pkg.path, file);
43
+ if (includeGlobs != null && !includeGlobs(relPath)) continue;
44
+ if (excludeGlobs != null && excludeGlobs(relPath)) continue;
45
+ const info = {
46
+ file: relPath,
47
+ package: pkg,
48
+ root
49
+ };
50
+ if (!await shouldInclude(info)) continue;
51
+ files.push(info);
52
+ }
53
+ return files;
54
+ }
55
+ async function findProjectChangedPackages(params) {
56
+ const files = await findProjectChangedFiles(params);
57
+ const set = /* @__PURE__ */ new Set();
58
+ for (const file of files) {
59
+ if (file.package != null) set.add(file.package);
60
+ }
61
+ return Array.from(set);
62
+ }
63
+ export {
64
+ findProjectChangedFiles,
65
+ findProjectChangedPackages
66
+ };
@@ -0,0 +1,13 @@
1
+ import { WorkspacePackage } from '../package-json/index.js';
2
+ import { VersioningOptions } from './types.js';
3
+ /** simple changelog generator based on git commits history */
4
+ export declare function generateChangelog(params: {
5
+ /** packages for which to generate the changelog */
6
+ workspace: WorkspacePackage[];
7
+ /** root of the git repo */
8
+ cwd?: string | URL;
9
+ /** starting point for the changelog (defaults to latest tag) */
10
+ since: string;
11
+ /** versioning params */
12
+ params?: VersioningOptions;
13
+ }): Promise<string>;