@ls-stack/pkg-manager 0.2.0 → 0.2.2

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
@@ -31,9 +31,11 @@ pkg-manager init [--force]
31
31
  ```
32
32
 
33
33
  **Options:**
34
+
34
35
  - `--force` - Overwrite existing config file
35
36
 
36
37
  **Features:**
38
+
37
39
  - Detects monorepo setup (looks for `pnpm-workspace.yaml`)
38
40
  - Prompts for pre-publish scripts (lint, test, build)
39
41
  - Scans `packages/` directory for monorepo packages
@@ -48,15 +50,18 @@ pkg-manager publish [package] [--type <major|minor|patch>] [--force] [--dry-run]
48
50
  ```
49
51
 
50
52
  **Arguments:**
53
+
51
54
  - `package` - Package name to publish (monorepo only, optional - prompts if not provided)
52
55
 
53
56
  **Options:**
57
+
54
58
  - `--type <type>` - Version bump type: `major`, `minor`, or `patch`
55
59
  - `--force` - Publish even if no changes detected
56
60
  - `--dry-run` - Preview what would happen without making changes
57
61
  - `--skip-confirm` - Skip major version confirmation prompt
58
62
 
59
63
  **Workflow:**
64
+
60
65
  1. Verifies git working directory is clean
61
66
  2. Prompts for version type if not provided
62
67
  3. Confirms major version bumps (configurable)
@@ -71,10 +76,10 @@ pkg-manager publish [package] [--type <major|minor|patch>] [--force] [--dry-run]
71
76
 
72
77
  ## Configuration
73
78
 
74
- Configuration is stored in `pkg-manager.config.ts`:
79
+ Configuration is optional and stored in `pkg-manager.config.ts`:
75
80
 
76
81
  ```typescript
77
- import { defineConfig } from '@ls-stack/pkg-manager';
82
+ import { defineConfig } from '@ls-stack/pkg-manager'
78
83
 
79
84
  export default defineConfig({
80
85
  requireMajorConfirmation: true,
@@ -86,32 +91,37 @@ export default defineConfig({
86
91
  monorepo: {
87
92
  packages: [
88
93
  { name: '@scope/core', path: 'packages/core' },
89
- { name: '@scope/utils', path: 'packages/utils', dependsOn: ['@scope/core'] },
94
+ {
95
+ name: '@scope/utils',
96
+ path: 'packages/utils',
97
+ dependsOn: ['@scope/core'],
98
+ },
90
99
  ],
91
100
  },
92
- });
101
+ })
93
102
  ```
94
103
 
95
104
  ### Options
96
105
 
97
- | Option | Type | Default | Description |
98
- |--------|------|---------|-------------|
99
- | `prePublish` | `array` | Uses `pre-publish` script | Scripts to run before publishing |
100
- | `prePublish[].command` | `string` | Required | Command to execute |
101
- | `prePublish[].label` | `string` | Required | Display label for the script |
102
- | `monorepo` | `object` | - | Monorepo configuration |
103
- | `monorepo.packages` | `array` | Required | List of packages |
104
- | `monorepo.packages[].name` | `string` | Required | Package name (from package.json) |
105
- | `monorepo.packages[].path` | `string` | Required | Path to package directory |
106
- | `monorepo.packages[].dependsOn` | `string[]` | `[]` | Package names this depends on |
107
- | `hashStorePath` | `string` | `node_modules/.pkg-manager/hashes.json` | Where to store publish hashes |
108
- | `requireMajorConfirmation` | `boolean` | `true` | Require confirmation for major versions |
106
+ | Option | Type | Default | Description |
107
+ | ------------------------------- | ---------- | --------------------------------------- | --------------------------------------- |
108
+ | `prePublish` | `array` | Uses `pre-publish` script | Scripts to run before publishing |
109
+ | `prePublish[].command` | `string` | Required | Command to execute |
110
+ | `prePublish[].label` | `string` | Required | Display label for the script |
111
+ | `monorepo` | `object` | - | Monorepo configuration |
112
+ | `monorepo.packages` | `array` | Required | List of packages |
113
+ | `monorepo.packages[].name` | `string` | Required | Package name (from package.json) |
114
+ | `monorepo.packages[].path` | `string` | Required | Path to package directory |
115
+ | `monorepo.packages[].dependsOn` | `string[]` | `[]` | Package names this depends on |
116
+ | `hashStorePath` | `string` | `node_modules/.pkg-manager/hashes.json` | Where to store publish hashes |
117
+ | `requireMajorConfirmation` | `boolean` | `true` | Require confirmation for major versions |
109
118
 
110
119
  ## Pre-Publish Scripts
111
120
 
112
121
  Pre-publish scripts are **required**. They ensure your package is built and validated before publishing.
113
122
 
114
123
  **Resolution order:**
124
+
115
125
  1. If `prePublish` is configured in `pkg-manager.config.ts`, those scripts are used
116
126
  2. Otherwise, looks for a `pre-publish` script in `package.json`
117
127
  3. If neither exists, the publish command exits with an error
@@ -0,0 +1,92 @@
1
+ import { existsSync, writeFileSync } from "fs";
2
+ import { join } from "path";
3
+ import { pathToFileURL } from "url";
4
+ import { z } from "zod";
5
+
6
+ //#region src/core/config.ts
7
+ const CONFIG_FILENAME = "pkg-manager.config.ts";
8
+ const DEFAULT_HASH_STORE_PATH = "node_modules/.pkg-manager/hashes.json";
9
+ const prePublishScriptSchema = z.object({
10
+ command: z.string(),
11
+ label: z.string()
12
+ });
13
+ const monorepoPackageSchema = z.object({
14
+ name: z.string(),
15
+ path: z.string(),
16
+ dependsOn: z.array(z.string()).optional()
17
+ });
18
+ const pkgManagerConfigSchema = z.object({
19
+ prePublish: z.array(prePublishScriptSchema).optional(),
20
+ monorepo: z.object({ packages: z.array(monorepoPackageSchema) }).optional(),
21
+ hashStorePath: z.string().optional(),
22
+ requireMajorConfirmation: z.boolean().optional()
23
+ });
24
+ /**
25
+ * Defines the configuration for pkg-manager.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * export default defineConfig({
30
+ * requireMajorConfirmation: true,
31
+ * prePublish: [{ command: 'pnpm build', label: 'Building' }],
32
+ * });
33
+ * ```
34
+ */
35
+ function defineConfig(config) {
36
+ return config;
37
+ }
38
+ function getConfigPath(cwd = process.cwd()) {
39
+ return join(cwd, CONFIG_FILENAME);
40
+ }
41
+ function configExists(cwd = process.cwd()) {
42
+ return existsSync(getConfigPath(cwd));
43
+ }
44
+ const defaultConfig = {
45
+ hashStorePath: DEFAULT_HASH_STORE_PATH,
46
+ requireMajorConfirmation: true
47
+ };
48
+ async function loadConfig(cwd = process.cwd()) {
49
+ const configPath = getConfigPath(cwd);
50
+ if (!existsSync(configPath)) return defaultConfig;
51
+ const configModule = await import(pathToFileURL(configPath).href);
52
+ const config = pkgManagerConfigSchema.parse(configModule.default);
53
+ return {
54
+ ...config,
55
+ hashStorePath: config.hashStorePath ?? DEFAULT_HASH_STORE_PATH,
56
+ requireMajorConfirmation: config.requireMajorConfirmation ?? true
57
+ };
58
+ }
59
+ function generateConfigFile(config, cwd = process.cwd()) {
60
+ const configPath = getConfigPath(cwd);
61
+ const lines = [
62
+ `import { defineConfig } from '@ls-stack/pkg-manager';`,
63
+ "",
64
+ "export default defineConfig({"
65
+ ];
66
+ if (config.requireMajorConfirmation !== void 0) lines.push(` requireMajorConfirmation: ${config.requireMajorConfirmation},`);
67
+ if (config.prePublish && config.prePublish.length > 0) {
68
+ lines.push(" prePublish: [");
69
+ for (const script of config.prePublish) lines.push(` { command: '${script.command}', label: '${script.label}' },`);
70
+ lines.push(" ],");
71
+ }
72
+ if (config.monorepo) {
73
+ lines.push(" monorepo: {");
74
+ lines.push(" packages: [");
75
+ for (const pkg of config.monorepo.packages) if (pkg.dependsOn && pkg.dependsOn.length > 0) {
76
+ const depsStr = pkg.dependsOn.map((d) => `'${d}'`).join(", ");
77
+ lines.push(` { name: '${pkg.name}', path: '${pkg.path}', dependsOn: [${depsStr}] },`);
78
+ } else lines.push(` { name: '${pkg.name}', path: '${pkg.path}' },`);
79
+ lines.push(" ],");
80
+ lines.push(" },");
81
+ }
82
+ lines.push("});");
83
+ lines.push("");
84
+ writeFileSync(configPath, lines.join("\n"));
85
+ }
86
+ function getHashStorePath(config) {
87
+ return config.hashStorePath ?? DEFAULT_HASH_STORE_PATH;
88
+ }
89
+
90
+ //#endregion
91
+ export { loadConfig as a, getHashStorePath as i, defineConfig as n, generateConfigFile as r, configExists as t };
92
+ //# sourceMappingURL=config-CG8p1aGY.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-CG8p1aGY.mjs","names":[],"sources":["../src/core/config.ts"],"sourcesContent":["import { existsSync, writeFileSync } from 'fs'\nimport { join } from 'path'\nimport { pathToFileURL } from 'url'\nimport { z } from 'zod'\n\nconst CONFIG_FILENAME = 'pkg-manager.config.ts'\nconst DEFAULT_HASH_STORE_PATH = 'node_modules/.pkg-manager/hashes.json'\n\nconst prePublishScriptSchema = z.object({\n command: z.string(),\n label: z.string(),\n})\n\nconst monorepoPackageSchema = z.object({\n name: z.string(),\n path: z.string(),\n dependsOn: z.array(z.string()).optional(),\n})\n\nconst pkgManagerConfigSchema = z.object({\n prePublish: z.array(prePublishScriptSchema).optional(),\n monorepo: z\n .object({\n packages: z.array(monorepoPackageSchema),\n })\n .optional(),\n hashStorePath: z.string().optional(),\n requireMajorConfirmation: z.boolean().optional(),\n})\n\nexport type MonorepoPackage = {\n /** Package name (as in package.json) */\n name: string\n /** Relative path to the package directory */\n path: string\n /** Package names this package depends on (for topological ordering) */\n dependsOn?: string[]\n}\n\nexport type PrePublishScript = {\n /** The shell command to execute */\n command: string\n /** Display label shown during execution */\n label: string\n}\n\n/**\n * Configuration for pkg-manager.\n */\nexport type PkgManagerConfig = {\n /** Scripts to run before publishing (e.g., build commands) */\n prePublish?: PrePublishScript[]\n /** Monorepo configuration for multi-package projects */\n monorepo?: {\n /** Array of packages in the monorepo */\n packages: MonorepoPackage[]\n }\n /**\n * Custom path for storing publish hashes.\n * @default \"node_modules/.pkg-manager/hashes.json\"\n */\n hashStorePath?: string\n /**\n * Require confirmation for major version bumps.\n * @default true\n */\n requireMajorConfirmation?: boolean\n}\n\n/**\n * Defines the configuration for pkg-manager.\n *\n * @example\n * ```ts\n * export default defineConfig({\n * requireMajorConfirmation: true,\n * prePublish: [{ command: 'pnpm build', label: 'Building' }],\n * });\n * ```\n */\nexport function defineConfig(config: PkgManagerConfig): PkgManagerConfig {\n return config\n}\n\nexport function getConfigPath(cwd: string = process.cwd()): string {\n return join(cwd, CONFIG_FILENAME)\n}\n\nexport function configExists(cwd: string = process.cwd()): boolean {\n return existsSync(getConfigPath(cwd))\n}\n\nconst defaultConfig: PkgManagerConfig = {\n hashStorePath: DEFAULT_HASH_STORE_PATH,\n requireMajorConfirmation: true,\n}\n\nexport async function loadConfig(\n cwd: string = process.cwd()\n): Promise<PkgManagerConfig> {\n const configPath = getConfigPath(cwd)\n\n if (!existsSync(configPath)) return defaultConfig\n\n const configModule: { default: unknown } = await import(\n pathToFileURL(configPath).href\n )\n const config = pkgManagerConfigSchema.parse(configModule.default)\n\n return {\n ...config,\n hashStorePath: config.hashStorePath ?? DEFAULT_HASH_STORE_PATH,\n requireMajorConfirmation: config.requireMajorConfirmation ?? true,\n }\n}\n\nexport function generateConfigFile(\n config: PkgManagerConfig,\n cwd: string = process.cwd()\n): void {\n const configPath = getConfigPath(cwd)\n\n const lines: string[] = [\n `import { defineConfig } from '@ls-stack/pkg-manager';`,\n '',\n 'export default defineConfig({',\n ]\n\n if (config.requireMajorConfirmation !== undefined) {\n lines.push(\n ` requireMajorConfirmation: ${config.requireMajorConfirmation},`\n )\n }\n\n if (config.prePublish && config.prePublish.length > 0) {\n lines.push(' prePublish: [')\n for (const script of config.prePublish) {\n lines.push(\n ` { command: '${script.command}', label: '${script.label}' },`\n )\n }\n lines.push(' ],')\n }\n\n if (config.monorepo) {\n lines.push(' monorepo: {')\n lines.push(' packages: [')\n for (const pkg of config.monorepo.packages) {\n if (pkg.dependsOn && pkg.dependsOn.length > 0) {\n const depsStr = pkg.dependsOn.map((d) => `'${d}'`).join(', ')\n lines.push(\n ` { name: '${pkg.name}', path: '${pkg.path}', dependsOn: [${depsStr}] },`\n )\n } else {\n lines.push(` { name: '${pkg.name}', path: '${pkg.path}' },`)\n }\n }\n lines.push(' ],')\n lines.push(' },')\n }\n\n lines.push('});')\n lines.push('')\n\n writeFileSync(configPath, lines.join('\\n'))\n}\n\nexport function getHashStorePath(config: PkgManagerConfig): string {\n return config.hashStorePath ?? DEFAULT_HASH_STORE_PATH\n}\n"],"mappings":";;;;;;AAKA,MAAM,kBAAkB;AACxB,MAAM,0BAA0B;AAEhC,MAAM,yBAAyB,EAAE,OAAO;CACtC,SAAS,EAAE,QAAQ;CACnB,OAAO,EAAE,QAAQ;CAClB,CAAC;AAEF,MAAM,wBAAwB,EAAE,OAAO;CACrC,MAAM,EAAE,QAAQ;CAChB,MAAM,EAAE,QAAQ;CAChB,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;CAC1C,CAAC;AAEF,MAAM,yBAAyB,EAAE,OAAO;CACtC,YAAY,EAAE,MAAM,uBAAuB,CAAC,UAAU;CACtD,UAAU,EACP,OAAO,EACN,UAAU,EAAE,MAAM,sBAAsB,EACzC,CAAC,CACD,UAAU;CACb,eAAe,EAAE,QAAQ,CAAC,UAAU;CACpC,0BAA0B,EAAE,SAAS,CAAC,UAAU;CACjD,CAAC;;;;;;;;;;;;AAoDF,SAAgB,aAAa,QAA4C;AACvE,QAAO;;AAGT,SAAgB,cAAc,MAAc,QAAQ,KAAK,EAAU;AACjE,QAAO,KAAK,KAAK,gBAAgB;;AAGnC,SAAgB,aAAa,MAAc,QAAQ,KAAK,EAAW;AACjE,QAAO,WAAW,cAAc,IAAI,CAAC;;AAGvC,MAAM,gBAAkC;CACtC,eAAe;CACf,0BAA0B;CAC3B;AAED,eAAsB,WACpB,MAAc,QAAQ,KAAK,EACA;CAC3B,MAAM,aAAa,cAAc,IAAI;AAErC,KAAI,CAAC,WAAW,WAAW,CAAE,QAAO;CAEpC,MAAM,eAAqC,MAAM,OAC/C,cAAc,WAAW,CAAC;CAE5B,MAAM,SAAS,uBAAuB,MAAM,aAAa,QAAQ;AAEjE,QAAO;EACL,GAAG;EACH,eAAe,OAAO,iBAAiB;EACvC,0BAA0B,OAAO,4BAA4B;EAC9D;;AAGH,SAAgB,mBACd,QACA,MAAc,QAAQ,KAAK,EACrB;CACN,MAAM,aAAa,cAAc,IAAI;CAErC,MAAM,QAAkB;EACtB;EACA;EACA;EACD;AAED,KAAI,OAAO,6BAA6B,OACtC,OAAM,KACJ,+BAA+B,OAAO,yBAAyB,GAChE;AAGH,KAAI,OAAO,cAAc,OAAO,WAAW,SAAS,GAAG;AACrD,QAAM,KAAK,kBAAkB;AAC7B,OAAK,MAAM,UAAU,OAAO,WAC1B,OAAM,KACJ,mBAAmB,OAAO,QAAQ,aAAa,OAAO,MAAM,MAC7D;AAEH,QAAM,KAAK,OAAO;;AAGpB,KAAI,OAAO,UAAU;AACnB,QAAM,KAAK,gBAAgB;AAC3B,QAAM,KAAK,kBAAkB;AAC7B,OAAK,MAAM,OAAO,OAAO,SAAS,SAChC,KAAI,IAAI,aAAa,IAAI,UAAU,SAAS,GAAG;GAC7C,MAAM,UAAU,IAAI,UAAU,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,KAAK;AAC7D,SAAM,KACJ,kBAAkB,IAAI,KAAK,YAAY,IAAI,KAAK,iBAAiB,QAAQ,MAC1E;QAED,OAAM,KAAK,kBAAkB,IAAI,KAAK,YAAY,IAAI,KAAK,MAAM;AAGrE,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,OAAO;;AAGpB,OAAM,KAAK,MAAM;AACjB,OAAM,KAAK,GAAG;AAEd,eAAc,YAAY,MAAM,KAAK,KAAK,CAAC;;AAG7C,SAAgB,iBAAiB,QAAkC;AACjE,QAAO,OAAO,iBAAiB"}
@@ -1,20 +1,44 @@
1
- //#region src/exports.d.ts
1
+ //#region src/core/config.d.ts
2
+ type MonorepoPackage = {
3
+ /** Package name (as in package.json) */name: string; /** Relative path to the package directory */
4
+ path: string; /** Package names this package depends on (for topological ordering) */
5
+ dependsOn?: string[];
6
+ };
7
+ type PrePublishScript = {
8
+ /** The shell command to execute */command: string; /** Display label shown during execution */
9
+ label: string;
10
+ };
11
+ /**
12
+ * Configuration for pkg-manager.
13
+ */
2
14
  type PkgManagerConfig = {
3
- prePublish?: {
4
- command: string;
5
- label: string;
6
- }[];
15
+ /** Scripts to run before publishing (e.g., build commands) */prePublish?: PrePublishScript[]; /** Monorepo configuration for multi-package projects */
7
16
  monorepo?: {
8
- packages: {
9
- name: string;
10
- path: string;
11
- dependsOn?: string[];
12
- }[];
17
+ /** Array of packages in the monorepo */packages: MonorepoPackage[];
13
18
  };
19
+ /**
20
+ * Custom path for storing publish hashes.
21
+ * @default "node_modules/.pkg-manager/hashes.json"
22
+ */
14
23
  hashStorePath?: string;
24
+ /**
25
+ * Require confirmation for major version bumps.
26
+ * @default true
27
+ */
15
28
  requireMajorConfirmation?: boolean;
16
29
  };
30
+ /**
31
+ * Defines the configuration for pkg-manager.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * export default defineConfig({
36
+ * requireMajorConfirmation: true,
37
+ * prePublish: [{ command: 'pnpm build', label: 'Building' }],
38
+ * });
39
+ * ```
40
+ */
17
41
  declare function defineConfig(config: PkgManagerConfig): PkgManagerConfig;
18
42
  //#endregion
19
- export { PkgManagerConfig, defineConfig };
43
+ export { type PkgManagerConfig, defineConfig };
20
44
  //# sourceMappingURL=exports.d.mts.map
package/dist/exports.mjs CHANGED
@@ -1,8 +1,3 @@
1
- //#region src/exports.ts
2
- function defineConfig(config) {
3
- return config;
4
- }
1
+ import { n as defineConfig } from "./config-CG8p1aGY.mjs";
5
2
 
6
- //#endregion
7
- export { defineConfig };
8
- //# sourceMappingURL=exports.mjs.map
3
+ export { defineConfig };
package/dist/main.mjs CHANGED
@@ -1,84 +1,13 @@
1
1
  #!/usr/bin/env node
2
+ import { a as loadConfig, i as getHashStorePath, r as generateConfigFile, t as configExists } from "./config-CG8p1aGY.mjs";
2
3
  import { cliInput, createCLI, createCmd } from "@ls-stack/cli";
3
4
  import { styleText } from "node:util";
4
5
  import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "fs";
5
6
  import { dirname, join } from "path";
6
- import { pathToFileURL } from "url";
7
7
  import { z } from "zod";
8
8
  import { spawn } from "child_process";
9
9
  import { createHash } from "crypto";
10
10
 
11
- //#region src/core/config.ts
12
- const CONFIG_FILENAME = "pkg-manager.config.ts";
13
- const DEFAULT_HASH_STORE_PATH = "node_modules/.pkg-manager/hashes.json";
14
- const prePublishScriptSchema = z.object({
15
- command: z.string(),
16
- label: z.string()
17
- });
18
- const monorepoPackageSchema = z.object({
19
- name: z.string(),
20
- path: z.string(),
21
- dependsOn: z.array(z.string()).optional()
22
- });
23
- const pkgManagerConfigSchema = z.object({
24
- prePublish: z.array(prePublishScriptSchema).optional(),
25
- monorepo: z.object({ packages: z.array(monorepoPackageSchema) }).optional(),
26
- hashStorePath: z.string().optional(),
27
- requireMajorConfirmation: z.boolean().optional()
28
- });
29
- function getConfigPath(cwd = process.cwd()) {
30
- return join(cwd, CONFIG_FILENAME);
31
- }
32
- function configExists(cwd = process.cwd()) {
33
- return existsSync(getConfigPath(cwd));
34
- }
35
- const defaultConfig = {
36
- hashStorePath: DEFAULT_HASH_STORE_PATH,
37
- requireMajorConfirmation: true
38
- };
39
- async function loadConfig(cwd = process.cwd()) {
40
- const configPath = getConfigPath(cwd);
41
- if (!existsSync(configPath)) return defaultConfig;
42
- const configModule = await import(pathToFileURL(configPath).href);
43
- const config = pkgManagerConfigSchema.parse(configModule.default);
44
- return {
45
- ...config,
46
- hashStorePath: config.hashStorePath ?? DEFAULT_HASH_STORE_PATH,
47
- requireMajorConfirmation: config.requireMajorConfirmation ?? true
48
- };
49
- }
50
- function generateConfigFile(config, cwd = process.cwd()) {
51
- const configPath = getConfigPath(cwd);
52
- const lines = [
53
- `import { defineConfig } from '@ls-stack/pkg-manager';`,
54
- "",
55
- "export default defineConfig({"
56
- ];
57
- if (config.requireMajorConfirmation !== void 0) lines.push(` requireMajorConfirmation: ${config.requireMajorConfirmation},`);
58
- if (config.prePublish && config.prePublish.length > 0) {
59
- lines.push(" prePublish: [");
60
- for (const script of config.prePublish) lines.push(` { command: '${script.command}', label: '${script.label}' },`);
61
- lines.push(" ],");
62
- }
63
- if (config.monorepo) {
64
- lines.push(" monorepo: {");
65
- lines.push(" packages: [");
66
- for (const pkg of config.monorepo.packages) if (pkg.dependsOn && pkg.dependsOn.length > 0) {
67
- const depsStr = pkg.dependsOn.map((d) => `'${d}'`).join(", ");
68
- lines.push(` { name: '${pkg.name}', path: '${pkg.path}', dependsOn: [${depsStr}] },`);
69
- } else lines.push(` { name: '${pkg.name}', path: '${pkg.path}' },`);
70
- lines.push(" ],");
71
- lines.push(" },");
72
- }
73
- lines.push("});");
74
- lines.push("");
75
- writeFileSync(configPath, lines.join("\n"));
76
- }
77
- function getHashStorePath(config) {
78
- return config.hashStorePath ?? DEFAULT_HASH_STORE_PATH;
79
- }
80
-
81
- //#endregion
82
11
  //#region src/utils/runCmd.ts
83
12
  async function runCmd(label, cmd, options = {}) {
84
13
  const [command, ...args] = cmd;
@@ -90,7 +19,6 @@ async function runCmd(label, cmd, options = {}) {
90
19
  return new Promise((resolve) => {
91
20
  const proc = spawn(command, args, {
92
21
  cwd: options.cwd,
93
- shell: true,
94
22
  stdio: options.silent ? "pipe" : "inherit"
95
23
  });
96
24
  let stdout = "";
package/dist/main.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.mjs","names":["packageJsonSchema"],"sources":["../src/core/config.ts","../src/utils/runCmd.ts","../src/core/monorepo.ts","../src/commands/init.ts","../src/core/git.ts","../src/core/hash.ts","../src/commands/publish.ts","../src/main.ts"],"sourcesContent":["import { existsSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport { pathToFileURL } from 'url';\nimport { z } from 'zod';\n\nconst CONFIG_FILENAME = 'pkg-manager.config.ts';\nconst DEFAULT_HASH_STORE_PATH = 'node_modules/.pkg-manager/hashes.json';\n\nconst prePublishScriptSchema = z.object({\n command: z.string(),\n label: z.string(),\n});\n\nconst monorepoPackageSchema = z.object({\n name: z.string(),\n path: z.string(),\n dependsOn: z.array(z.string()).optional(),\n});\n\nconst pkgManagerConfigSchema = z.object({\n prePublish: z.array(prePublishScriptSchema).optional(),\n monorepo: z.object({\n packages: z.array(monorepoPackageSchema),\n }).optional(),\n hashStorePath: z.string().optional(),\n requireMajorConfirmation: z.boolean().optional(),\n});\n\nexport type PrePublishScript = z.infer<typeof prePublishScriptSchema>;\nexport type MonorepoPackage = z.infer<typeof monorepoPackageSchema>;\nexport type PkgManagerConfig = z.infer<typeof pkgManagerConfigSchema>;\n\nexport function defineConfig(config: PkgManagerConfig): PkgManagerConfig {\n return config;\n}\n\nexport function getConfigPath(cwd: string = process.cwd()): string {\n return join(cwd, CONFIG_FILENAME);\n}\n\nexport function configExists(cwd: string = process.cwd()): boolean {\n return existsSync(getConfigPath(cwd));\n}\n\nconst defaultConfig: PkgManagerConfig = {\n hashStorePath: DEFAULT_HASH_STORE_PATH,\n requireMajorConfirmation: true,\n};\n\nexport async function loadConfig(cwd: string = process.cwd()): Promise<PkgManagerConfig> {\n const configPath = getConfigPath(cwd);\n\n if (!existsSync(configPath)) return defaultConfig;\n\n const configModule: { default: unknown } = await import(pathToFileURL(configPath).href);\n const config = pkgManagerConfigSchema.parse(configModule.default);\n\n return {\n ...config,\n hashStorePath: config.hashStorePath ?? DEFAULT_HASH_STORE_PATH,\n requireMajorConfirmation: config.requireMajorConfirmation ?? true,\n };\n}\n\nexport function generateConfigFile(\n config: PkgManagerConfig,\n cwd: string = process.cwd(),\n): void {\n const configPath = getConfigPath(cwd);\n\n const lines: string[] = [\n `import { defineConfig } from '@ls-stack/pkg-manager';`,\n '',\n 'export default defineConfig({',\n ];\n\n if (config.requireMajorConfirmation !== undefined) {\n lines.push(` requireMajorConfirmation: ${config.requireMajorConfirmation},`);\n }\n\n if (config.prePublish && config.prePublish.length > 0) {\n lines.push(' prePublish: [');\n for (const script of config.prePublish) {\n lines.push(` { command: '${script.command}', label: '${script.label}' },`);\n }\n lines.push(' ],');\n }\n\n if (config.monorepo) {\n lines.push(' monorepo: {');\n lines.push(' packages: [');\n for (const pkg of config.monorepo.packages) {\n if (pkg.dependsOn && pkg.dependsOn.length > 0) {\n const depsStr = pkg.dependsOn.map((d) => `'${d}'`).join(', ');\n lines.push(` { name: '${pkg.name}', path: '${pkg.path}', dependsOn: [${depsStr}] },`);\n } else {\n lines.push(` { name: '${pkg.name}', path: '${pkg.path}' },`);\n }\n }\n lines.push(' ],');\n lines.push(' },');\n }\n\n lines.push('});');\n lines.push('');\n\n writeFileSync(configPath, lines.join('\\n'));\n}\n\nexport function getHashStorePath(config: PkgManagerConfig): string {\n return config.hashStorePath ?? DEFAULT_HASH_STORE_PATH;\n}\n","import { spawn } from 'child_process';\nimport { styleText } from 'node:util';\n\nexport type RunCmdOptions = {\n cwd?: string;\n silent?: boolean;\n};\n\nexport async function runCmd(\n label: string,\n cmd: string[],\n options: RunCmdOptions = {},\n): Promise<{ ok: true; output: string } | { ok: false; error: string }> {\n const [command, ...args] = cmd;\n\n if (!command) {\n return { ok: false, error: 'No command provided' };\n }\n\n if (!options.silent) {\n console.log(styleText(['dim'], `> ${cmd.join(' ')}`));\n }\n\n return new Promise((resolve) => {\n const proc = spawn(command, args, {\n cwd: options.cwd,\n shell: true,\n stdio: options.silent ? 'pipe' : 'inherit',\n });\n\n let stdout = '';\n let stderr = '';\n\n if (options.silent) {\n proc.stdout?.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n\n proc.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n }\n\n proc.on('close', (code) => {\n if (code === 0) {\n resolve({ ok: true, output: stdout });\n } else {\n resolve({\n ok: false,\n error: stderr || stdout || `Command failed with exit code ${code}`,\n });\n }\n });\n\n proc.on('error', (error) => {\n resolve({ ok: false, error: error.message });\n });\n });\n}\n\nexport async function runCmdOrExit(\n label: string,\n cmd: string[],\n options: RunCmdOptions = {},\n): Promise<string> {\n const result = await runCmd(label, cmd, options);\n\n if (!result.ok) {\n console.error(styleText(['red', 'bold'], `Failed: ${label}`));\n console.error(result.error);\n process.exit(1);\n }\n\n return result.output;\n}\n","import { existsSync, readFileSync, readdirSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport type { MonorepoPackage } from './config.ts';\nimport { runCmdOrExit } from '../utils/runCmd.ts';\n\nexport function detectMonorepo(cwd: string = process.cwd()): boolean {\n return existsSync(join(cwd, 'pnpm-workspace.yaml'));\n}\n\nconst packageJsonSchema = z.object({\n name: z.string().optional(),\n});\n\nexport function scanPackages(cwd: string = process.cwd()): MonorepoPackage[] {\n const workspacePath = join(cwd, 'pnpm-workspace.yaml');\n\n if (!existsSync(workspacePath)) return [];\n\n const packages: MonorepoPackage[] = [];\n const packagesDir = join(cwd, 'packages');\n\n if (!existsSync(packagesDir)) return [];\n\n const items = readdirSync(packagesDir);\n\n for (const item of items) {\n const itemPath = join(packagesDir, item);\n const stat = statSync(itemPath);\n\n if (!stat.isDirectory()) continue;\n\n const packageJsonPath = join(itemPath, 'package.json');\n\n if (!existsSync(packageJsonPath)) continue;\n\n try {\n const content = readFileSync(packageJsonPath, 'utf-8');\n const parsed = JSON.parse(content);\n const packageJson = packageJsonSchema.parse(parsed);\n\n if (packageJson.name) {\n packages.push({\n name: packageJson.name,\n path: `packages/${item}`,\n });\n }\n } catch {\n continue;\n }\n }\n\n return packages;\n}\n\nexport function topologicalSort(packages: MonorepoPackage[]): MonorepoPackage[] {\n const nameToPackage = new Map<string, MonorepoPackage>();\n const inDegree = new Map<string, number>();\n const dependents = new Map<string, string[]>();\n\n for (const pkg of packages) {\n nameToPackage.set(pkg.name, pkg);\n inDegree.set(pkg.name, 0);\n dependents.set(pkg.name, []);\n }\n\n for (const pkg of packages) {\n if (pkg.dependsOn) {\n for (const dep of pkg.dependsOn) {\n if (nameToPackage.has(dep)) {\n inDegree.set(pkg.name, (inDegree.get(pkg.name) ?? 0) + 1);\n dependents.get(dep)?.push(pkg.name);\n }\n }\n }\n }\n\n const queue: string[] = [];\n\n for (const [name, degree] of inDegree) {\n if (degree === 0) {\n queue.push(name);\n }\n }\n\n const sorted: MonorepoPackage[] = [];\n\n while (queue.length > 0) {\n const name = queue.shift();\n\n if (!name) continue;\n\n const pkg = nameToPackage.get(name);\n\n if (pkg) {\n sorted.push(pkg);\n }\n\n for (const dependent of dependents.get(name) ?? []) {\n const newDegree = (inDegree.get(dependent) ?? 1) - 1;\n inDegree.set(dependent, newDegree);\n\n if (newDegree === 0) {\n queue.push(dependent);\n }\n }\n }\n\n if (sorted.length !== packages.length) {\n throw new Error('Circular dependency detected in package graph');\n }\n\n return sorted;\n}\n\nexport function getDependencyOrder(\n targetPackage: string,\n packages: MonorepoPackage[],\n): MonorepoPackage[] {\n const nameToPackage = new Map<string, MonorepoPackage>();\n\n for (const pkg of packages) {\n nameToPackage.set(pkg.name, pkg);\n }\n\n const target = nameToPackage.get(targetPackage);\n\n if (!target) return [];\n\n const visited = new Set<string>();\n const result: MonorepoPackage[] = [];\n\n function visit(name: string) {\n if (visited.has(name)) return;\n\n visited.add(name);\n\n const pkg = nameToPackage.get(name);\n\n if (!pkg) return;\n\n if (pkg.dependsOn) {\n for (const dep of pkg.dependsOn) {\n visit(dep);\n }\n }\n\n if (name !== targetPackage) {\n result.push(pkg);\n }\n }\n\n visit(targetPackage);\n\n return result;\n}\n\nexport async function buildPackage(\n packageName: string,\n cwd: string = process.cwd(),\n): Promise<void> {\n await runCmdOrExit(`build ${packageName}`, [\n 'pnpm',\n '--filter',\n packageName,\n 'build',\n ], { cwd });\n}\n\nexport async function buildDependencies(\n targetPackage: string,\n packages: MonorepoPackage[],\n cwd: string = process.cwd(),\n): Promise<void> {\n const deps = getDependencyOrder(targetPackage, packages);\n\n for (const dep of deps) {\n console.log(`Building dependency: ${dep.name}`);\n await buildPackage(dep.name, cwd);\n }\n}\n","import { cliInput } from '@ls-stack/cli';\nimport { styleText } from 'node:util';\nimport {\n configExists,\n generateConfigFile,\n type MonorepoPackage,\n type PkgManagerConfig,\n type PrePublishScript,\n} from '../core/config.ts';\nimport { detectMonorepo, scanPackages } from '../core/monorepo.ts';\n\ntype InitArgs = {\n force: boolean;\n};\n\nexport async function initCommand({ force }: InitArgs): Promise<void> {\n if (configExists() && !force) {\n console.error(\n styleText(['red', 'bold'], 'Config file already exists. Use --force to overwrite.'),\n );\n process.exit(1);\n }\n\n console.log(styleText(['blue', 'bold'], 'Initializing pkg-manager config...\\n'));\n\n const isMonorepo = detectMonorepo();\n\n if (isMonorepo) {\n console.log(styleText(['green'], 'Detected monorepo (pnpm-workspace.yaml found)\\n'));\n }\n\n const prePublishScripts = await selectPrePublishScripts();\n let monorepoConfig: { packages: MonorepoPackage[] } | undefined;\n\n if (isMonorepo) {\n const packages = scanPackages();\n\n if (packages.length > 0) {\n console.log(styleText(['blue'], `\\nFound ${packages.length} packages:`));\n\n for (const pkg of packages) {\n console.log(styleText(['dim'], ` - ${pkg.name} (${pkg.path})`));\n }\n\n const configureDeps = await cliInput.confirm(\n '\\nConfigure package dependencies?',\n { initial: true },\n );\n\n if (configureDeps) {\n monorepoConfig = await configureMonorepoDependencies(packages);\n } else {\n monorepoConfig = { packages };\n }\n }\n }\n\n const config: PkgManagerConfig = {\n requireMajorConfirmation: true,\n };\n\n if (prePublishScripts.length > 0) {\n config.prePublish = prePublishScripts;\n }\n\n if (monorepoConfig) {\n config.monorepo = monorepoConfig;\n }\n\n generateConfigFile(config);\n\n console.log(styleText(['green', 'bold'], '\\npkg-manager.config.ts created successfully!'));\n}\n\nasync function selectPrePublishScripts(): Promise<PrePublishScript[]> {\n const scripts: PrePublishScript[] = [];\n\n const selectedScripts = await cliInput.multipleSelect(\n 'Select pre-publish scripts to run:',\n {\n options: [\n {\n value: 'lint',\n label: 'Lint',\n hint: 'Run pnpm lint',\n },\n {\n value: 'test',\n label: 'Test',\n hint: 'Run pnpm test',\n },\n {\n value: 'build',\n label: 'Build',\n hint: 'Run pnpm build',\n },\n ],\n },\n );\n\n for (const script of selectedScripts) {\n switch (script) {\n case 'lint':\n scripts.push({ command: 'pnpm lint', label: 'Linting' });\n break;\n case 'test':\n scripts.push({ command: 'pnpm test', label: 'Testing' });\n break;\n case 'build':\n scripts.push({ command: 'pnpm build', label: 'Building' });\n break;\n }\n }\n\n return scripts;\n}\n\nasync function configureMonorepoDependencies(\n packages: MonorepoPackage[],\n): Promise<{ packages: MonorepoPackage[] }> {\n const configuredPackages: MonorepoPackage[] = [];\n\n for (const pkg of packages) {\n const otherPackages = packages.filter((p) => p.name !== pkg.name);\n\n if (otherPackages.length === 0) {\n configuredPackages.push(pkg);\n continue;\n }\n\n const deps = await cliInput.multipleSelect(\n `Select dependencies for ${pkg.name}:`,\n {\n options: [\n { value: '__none__', label: 'None', hint: 'No dependencies' },\n ...otherPackages.map((p) => ({\n value: p.name,\n label: p.name,\n hint: p.path,\n })),\n ],\n },\n );\n\n const filteredDeps = deps.filter((d) => d !== '__none__');\n\n if (filteredDeps.length > 0) {\n configuredPackages.push({\n ...pkg,\n dependsOn: filteredDeps,\n });\n } else {\n configuredPackages.push(pkg);\n }\n }\n\n return { packages: configuredPackages };\n}\n","import { runCmd, runCmdOrExit } from '../utils/runCmd.ts';\n\nexport async function isGitClean(): Promise<boolean> {\n const result = await runCmd('check git status', ['git', 'status', '--porcelain'], {\n silent: true,\n });\n\n if (!result.ok) return false;\n\n return result.output.trim() === '';\n}\n\nexport async function gitAdd(files: string[] = ['.']): Promise<void> {\n await runCmdOrExit('stage changes', ['git', 'add', ...files]);\n}\n\nexport async function gitCommit(message: string): Promise<void> {\n await runCmdOrExit('commit', ['git', 'commit', '-m', message]);\n}\n\nexport async function commitIfDirty(message: string): Promise<boolean> {\n const clean = await isGitClean();\n\n if (clean) {\n console.log('No changes to commit');\n return false;\n }\n\n await gitAdd();\n await gitCommit(message);\n return true;\n}\n","import { createHash } from 'crypto';\nimport {\n existsSync,\n mkdirSync,\n readFileSync,\n readdirSync,\n statSync,\n writeFileSync,\n} from 'fs';\nimport { dirname, join } from 'path';\nimport { z } from 'zod';\n\nconst packageHashesSchema = z.object({\n versions: z.record(z.string(), z.string()),\n lastVersion: z.string().optional(),\n});\n\nconst hashStoreSchema = z.object({\n packages: z.record(z.string(), packageHashesSchema),\n});\n\nexport function generateDirectoryHash(dirPath: string): string {\n if (!existsSync(dirPath)) {\n throw new Error(`Directory does not exist: ${dirPath}`);\n }\n\n const hash = createHash('sha256');\n const files: string[] = [];\n\n function collectFiles(currentPath: string, relativePath = '') {\n const items = readdirSync(currentPath).sort();\n for (const item of items) {\n const fullPath = join(currentPath, item);\n const itemRelativePath = relativePath ? join(relativePath, item) : item;\n const stat = statSync(fullPath);\n if (stat.isDirectory()) {\n collectFiles(fullPath, itemRelativePath);\n } else {\n files.push(itemRelativePath);\n }\n }\n }\n\n collectFiles(dirPath);\n\n for (const filePath of files) {\n const fullPath = join(dirPath, filePath);\n const content = readFileSync(fullPath);\n hash.update(filePath);\n hash.update(content);\n }\n\n return hash.digest('hex');\n}\n\ntype HashStore = z.infer<typeof hashStoreSchema>;\n\nexport function readHashStore(hashStorePath: string): HashStore {\n if (!existsSync(hashStorePath)) {\n return { packages: {} };\n }\n\n try {\n const content = readFileSync(hashStorePath, 'utf-8');\n const parsed = JSON.parse(content);\n return hashStoreSchema.parse(parsed);\n } catch {\n return { packages: {} };\n }\n}\n\nexport function writeHashStore(hashStorePath: string, store: HashStore): void {\n const dir = dirname(hashStorePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(hashStorePath, `${JSON.stringify(store, null, 2)}\\n`);\n}\n\nexport function checkHashForDuplicate(\n hashStorePath: string,\n packageName: string,\n currentHash: string,\n): { isDuplicate: boolean; existingVersion?: string } {\n const store = readHashStore(hashStorePath);\n const packageHashes = store.packages[packageName];\n\n if (!packageHashes) {\n return { isDuplicate: false };\n }\n\n for (const [version, hash] of Object.entries(packageHashes.versions)) {\n if (hash === currentHash) {\n return { isDuplicate: true, existingVersion: version };\n }\n }\n\n return { isDuplicate: false };\n}\n\nexport function savePackageHash(\n hashStorePath: string,\n packageName: string,\n version: string,\n hash: string,\n): void {\n const store = readHashStore(hashStorePath);\n\n if (!store.packages[packageName]) {\n store.packages[packageName] = { versions: {} };\n }\n\n const pkgStore = store.packages[packageName];\n\n pkgStore.versions[version] = hash;\n pkgStore.lastVersion = version;\n\n writeHashStore(hashStorePath, store);\n}\n","import { cliInput } from '@ls-stack/cli';\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { styleText } from 'node:util';\nimport { z } from 'zod';\nimport {\n getHashStorePath,\n loadConfig,\n type PkgManagerConfig,\n type PrePublishScript,\n} from '../core/config.ts';\nimport { commitIfDirty, isGitClean } from '../core/git.ts';\nimport {\n checkHashForDuplicate,\n generateDirectoryHash,\n savePackageHash,\n} from '../core/hash.ts';\nimport { buildDependencies } from '../core/monorepo.ts';\nimport { runCmdOrExit } from '../utils/runCmd.ts';\n\nconst VERSION_TYPES = ['major', 'minor', 'patch'] as const;\ntype VersionType = (typeof VERSION_TYPES)[number];\n\nconst packageJsonSchema = z.object({\n name: z.string().optional(),\n version: z.string().optional(),\n scripts: z.record(z.string(), z.string()).optional(),\n});\n\ntype PublishArgs = {\n package: string | undefined;\n type: string | undefined;\n force: boolean;\n dryRun: boolean;\n skipConfirm: boolean;\n};\n\nexport async function publishCommand(args: PublishArgs): Promise<void> {\n const config = await loadConfig();\n const cwd = process.cwd();\n\n const isClean = await isGitClean();\n\n if (!isClean) {\n console.error(\n styleText(['red', 'bold'], 'Git working directory is not clean.'),\n );\n console.error('Please commit or stash your changes before publishing.');\n process.exit(1);\n }\n\n const targetPackage = await resolveTargetPackage(args.package, config);\n const packagePath = getPackagePath(targetPackage, config, cwd);\n const packageName = getPackageName(packagePath);\n\n const currentVersion = getPackageVersion(packagePath);\n\n console.log(styleText(['blue', 'bold'], `\\nPublishing: ${packageName} (current: ${currentVersion})`));\n\n if (args.dryRun) {\n console.log(styleText(['yellow'], '(dry-run mode - no changes will be made)\\n'));\n }\n\n const versionType = await resolveVersionType(args.type, currentVersion);\n\n if (versionType === 'major' && config.requireMajorConfirmation && !args.skipConfirm) {\n const confirmed = await cliInput.confirm(\n 'You are about to publish a MAJOR version. Are you sure?',\n { initial: false },\n );\n\n if (!confirmed) {\n console.log('Aborted.');\n process.exit(0);\n }\n }\n\n if (config.monorepo?.packages) {\n console.log(styleText(['dim'], '\\nBuilding dependencies...'));\n if (!args.dryRun) {\n await buildDependencies(packageName, config.monorepo.packages, cwd);\n }\n }\n\n const prePublishScripts = getPrePublishScripts(config, packagePath, packageName);\n\n console.log(styleText(['dim'], '\\nRunning pre-publish scripts...'));\n\n for (const script of prePublishScripts) {\n console.log(styleText(['blue'], `\\n${script.label}...`));\n\n if (!args.dryRun) {\n const [cmd, ...cmdArgs] = script.command.split(' ');\n\n if (!cmd) {\n console.error(styleText(['red'], `Invalid command: ${script.command}`));\n process.exit(1);\n }\n\n if (config.monorepo) {\n await runCmdOrExit(script.label, ['pnpm', '--filter', packageName, ...cmdArgs], {\n cwd,\n });\n } else {\n await runCmdOrExit(script.label, [cmd, ...cmdArgs], { cwd: packagePath });\n }\n }\n }\n\n const distPath = join(packagePath, 'dist');\n\n if (!existsSync(distPath)) {\n console.error(styleText(['red', 'bold'], `dist directory not found at ${distPath}`));\n console.error('Please build your package first.');\n process.exit(1);\n }\n\n console.log(styleText(['dim'], '\\nGenerating build hash...'));\n const currentHash = generateDirectoryHash(distPath);\n console.log(styleText(['dim'], `Hash: ${currentHash.slice(0, 12)}...`));\n\n const hashStorePath = join(cwd, getHashStorePath(config));\n const hashCheck = checkHashForDuplicate(hashStorePath, packageName, currentHash);\n\n if (hashCheck.isDuplicate && !args.force) {\n console.error(\n styleText(\n ['red', 'bold'],\n `\\nThis build has already been published as ${packageName}@${hashCheck.existingVersion}`,\n ),\n );\n console.error('No changes detected in the build output.');\n console.error('Make code changes before attempting to publish.');\n console.error('Or use --force to publish anyway.');\n process.exit(1);\n }\n\n if (hashCheck.isDuplicate && args.force) {\n console.warn(\n styleText(\n ['yellow'],\n `\\nWarning: This build was already published as ${packageName}@${hashCheck.existingVersion}`,\n ),\n );\n console.warn('Force flag enabled - proceeding with publish anyway.');\n }\n\n console.log(styleText(['blue'], `\\nBumping version (${versionType})...`));\n\n if (!args.dryRun) {\n await runCmdOrExit('bump version', ['pnpm', 'version', versionType], {\n cwd: packagePath,\n });\n\n await commitIfDirty(`chore: bump ${packageName} to next ${versionType} version`);\n }\n\n const newVersion = getPackageVersion(packagePath);\n console.log(styleText(['green'], `New version: ${newVersion}`));\n\n console.log(styleText(['blue'], '\\nCreating git tag...'));\n\n if (!args.dryRun) {\n const tagName = `${packageName}@${newVersion}`;\n await runCmdOrExit('create tag', ['git', 'tag', tagName]);\n console.log(styleText(['dim'], `Created tag: ${tagName}`));\n }\n\n console.log(styleText(['blue'], '\\nPublishing to npm...'));\n\n if (!args.dryRun) {\n await runCmdOrExit('publish', ['pnpm', 'publish', '--access', 'public'], {\n cwd: packagePath,\n });\n\n savePackageHash(hashStorePath, packageName, newVersion, currentHash);\n\n await commitIfDirty(`chore: update publish hashes for ${packageName}@${newVersion}`);\n }\n\n console.log(\n styleText(['green', 'bold'], `\\nSuccessfully published ${packageName}@${newVersion}`),\n );\n}\n\nasync function resolveTargetPackage(\n packageArg: string | undefined,\n config: PkgManagerConfig,\n): Promise<string | undefined> {\n if (packageArg) return packageArg;\n\n if (!config.monorepo?.packages || config.monorepo.packages.length === 0) {\n return undefined;\n }\n\n const packageName = await cliInput.select('Select package to publish:', {\n options: config.monorepo.packages.map((pkg) => ({\n value: pkg.name,\n label: pkg.name,\n hint: pkg.path,\n })),\n });\n\n return packageName;\n}\n\nfunction bumpVersion(version: string, type: VersionType): string {\n const parts = version.split('.').map(Number);\n const major = parts[0] ?? 0;\n const minor = parts[1] ?? 0;\n const patch = parts[2] ?? 0;\n\n switch (type) {\n case 'major':\n return `${major + 1}.0.0`;\n case 'minor':\n return `${major}.${minor + 1}.0`;\n case 'patch':\n return `${major}.${minor}.${patch + 1}`;\n }\n}\n\nasync function resolveVersionType(\n typeArg: string | undefined,\n currentVersion: string,\n): Promise<VersionType> {\n if (typeArg) {\n const normalizedType = typeArg.toLowerCase();\n const matchingType = VERSION_TYPES.find((t) => t === normalizedType);\n\n if (!matchingType) {\n console.error(\n styleText(['red', 'bold'], `Invalid version type: ${typeArg}`),\n );\n console.error(`Valid types: ${VERSION_TYPES.join(', ')}`);\n process.exit(1);\n }\n return matchingType;\n }\n\n const versionType = await cliInput.select('Select version bump type:', {\n options: [\n { value: 'patch', label: 'patch', hint: `${currentVersion} → ${bumpVersion(currentVersion, 'patch')}` },\n { value: 'minor', label: 'minor', hint: `${currentVersion} → ${bumpVersion(currentVersion, 'minor')}` },\n { value: 'major', label: 'major', hint: `${currentVersion} → ${bumpVersion(currentVersion, 'major')}` },\n ],\n });\n\n return versionType;\n}\n\nfunction getPackagePath(\n targetPackage: string | undefined,\n config: PkgManagerConfig,\n cwd: string,\n): string {\n if (!targetPackage) return cwd;\n\n const pkg = config.monorepo?.packages.find((p) => p.name === targetPackage);\n\n if (pkg) return join(cwd, pkg.path);\n\n return cwd;\n}\n\nfunction readPackageJson(packagePath: string): z.infer<typeof packageJsonSchema> {\n const packageJsonPath = join(packagePath, 'package.json');\n const content = readFileSync(packageJsonPath, 'utf-8');\n const parsed = JSON.parse(content);\n return packageJsonSchema.parse(parsed);\n}\n\nfunction getPackageName(packagePath: string): string {\n const packageJsonPath = join(packagePath, 'package.json');\n\n if (!existsSync(packageJsonPath)) {\n console.error(\n styleText(['red', 'bold'], `package.json not found at ${packagePath}`),\n );\n process.exit(1);\n }\n\n const packageJson = readPackageJson(packagePath);\n\n if (!packageJson.name) {\n console.error(\n styleText(['red', 'bold'], 'package.json does not have a name field'),\n );\n process.exit(1);\n }\n\n return packageJson.name;\n}\n\nfunction getPackageVersion(packagePath: string): string {\n const packageJson = readPackageJson(packagePath);\n return packageJson.version ?? '0.0.0';\n}\n\nfunction getPrePublishScripts(\n config: PkgManagerConfig,\n packagePath: string,\n packageName: string,\n): PrePublishScript[] {\n if (config.prePublish && config.prePublish.length > 0) {\n return config.prePublish;\n }\n\n const packageJson = readPackageJson(packagePath);\n const hasPrePublishScript = packageJson.scripts?.['pre-publish'] !== undefined;\n\n if (hasPrePublishScript) {\n return [{ command: 'pnpm pre-publish', label: 'Running pre-publish script' }];\n }\n\n console.error(\n styleText(\n ['red', 'bold'],\n `\\nNo pre-publish scripts configured for ${packageName}`,\n ),\n );\n console.error(\n 'Either add a \"pre-publish\" script to package.json or configure \"prePublish\" in pkg-manager.config.ts',\n );\n process.exit(1);\n}\n","#!/usr/bin/env node\nimport { createCLI, createCmd } from '@ls-stack/cli';\nimport { initCommand } from './commands/init.ts';\nimport { publishCommand } from './commands/publish.ts';\n\nawait createCLI(\n {\n name: 'pkg-manager',\n baseCmd: 'pkg-manager',\n sort: ['publish', 'init'],\n },\n {\n init: createCmd({\n description: 'Initialize pkg-manager configuration',\n args: {\n force: {\n type: 'flag',\n name: 'force',\n description: 'Overwrite existing config file',\n },\n },\n run: async ({ force }) => {\n await initCommand({ force });\n },\n }),\n\n publish: createCmd({\n short: 'p',\n description: 'Publish a package with hash-based change detection',\n args: {\n package: {\n type: 'positional-string',\n name: 'package',\n description: 'Package name to publish (monorepo only)',\n default: '',\n },\n type: {\n type: 'value-string-flag',\n name: 'type',\n description: 'Version bump type: major, minor, or patch',\n },\n force: {\n type: 'flag',\n name: 'force',\n description: 'Force publish even if no changes detected',\n },\n dryRun: {\n type: 'flag',\n name: 'dry-run',\n description: 'Show what would be done without making changes',\n },\n skipConfirm: {\n type: 'flag',\n name: 'skip-confirm',\n description: 'Skip major version confirmation prompt',\n },\n },\n examples: [\n { args: ['--type', 'patch'], description: 'Publish a patch version' },\n { args: ['@my-scope/pkg', '--type', 'minor'], description: 'Publish specific package' },\n { args: ['--dry-run'], description: 'Preview publish without changes' },\n { args: ['--force', '--type', 'patch'], description: 'Force publish even if unchanged' },\n ],\n run: async ({ package: pkg, type, force, dryRun, skipConfirm }) => {\n await publishCommand({\n package: pkg || undefined,\n type,\n force,\n dryRun,\n skipConfirm,\n });\n },\n }),\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"main.mjs","names":["packageJsonSchema"],"sources":["../src/utils/runCmd.ts","../src/core/monorepo.ts","../src/commands/init.ts","../src/core/git.ts","../src/core/hash.ts","../src/commands/publish.ts","../src/main.ts"],"sourcesContent":["import { spawn } from 'child_process';\nimport { styleText } from 'node:util';\n\nexport type RunCmdOptions = {\n cwd?: string;\n silent?: boolean;\n};\n\nexport async function runCmd(\n label: string,\n cmd: string[],\n options: RunCmdOptions = {},\n): Promise<{ ok: true; output: string } | { ok: false; error: string }> {\n const [command, ...args] = cmd;\n\n if (!command) {\n return { ok: false, error: 'No command provided' };\n }\n\n if (!options.silent) {\n console.log(styleText(['dim'], `> ${cmd.join(' ')}`));\n }\n\n return new Promise((resolve) => {\n const proc = spawn(command, args, {\n cwd: options.cwd,\n stdio: options.silent ? 'pipe' : 'inherit',\n });\n\n let stdout = '';\n let stderr = '';\n\n if (options.silent) {\n proc.stdout?.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n\n proc.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n }\n\n proc.on('close', (code) => {\n if (code === 0) {\n resolve({ ok: true, output: stdout });\n } else {\n resolve({\n ok: false,\n error: stderr || stdout || `Command failed with exit code ${code}`,\n });\n }\n });\n\n proc.on('error', (error) => {\n resolve({ ok: false, error: error.message });\n });\n });\n}\n\nexport async function runCmdOrExit(\n label: string,\n cmd: string[],\n options: RunCmdOptions = {},\n): Promise<string> {\n const result = await runCmd(label, cmd, options);\n\n if (!result.ok) {\n console.error(styleText(['red', 'bold'], `Failed: ${label}`));\n console.error(result.error);\n process.exit(1);\n }\n\n return result.output;\n}\n","import { existsSync, readFileSync, readdirSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport type { MonorepoPackage } from './config.ts';\nimport { runCmdOrExit } from '../utils/runCmd.ts';\n\nexport function detectMonorepo(cwd: string = process.cwd()): boolean {\n return existsSync(join(cwd, 'pnpm-workspace.yaml'));\n}\n\nconst packageJsonSchema = z.object({\n name: z.string().optional(),\n});\n\nexport function scanPackages(cwd: string = process.cwd()): MonorepoPackage[] {\n const workspacePath = join(cwd, 'pnpm-workspace.yaml');\n\n if (!existsSync(workspacePath)) return [];\n\n const packages: MonorepoPackage[] = [];\n const packagesDir = join(cwd, 'packages');\n\n if (!existsSync(packagesDir)) return [];\n\n const items = readdirSync(packagesDir);\n\n for (const item of items) {\n const itemPath = join(packagesDir, item);\n const stat = statSync(itemPath);\n\n if (!stat.isDirectory()) continue;\n\n const packageJsonPath = join(itemPath, 'package.json');\n\n if (!existsSync(packageJsonPath)) continue;\n\n try {\n const content = readFileSync(packageJsonPath, 'utf-8');\n const parsed = JSON.parse(content);\n const packageJson = packageJsonSchema.parse(parsed);\n\n if (packageJson.name) {\n packages.push({\n name: packageJson.name,\n path: `packages/${item}`,\n });\n }\n } catch {\n continue;\n }\n }\n\n return packages;\n}\n\nexport function topologicalSort(packages: MonorepoPackage[]): MonorepoPackage[] {\n const nameToPackage = new Map<string, MonorepoPackage>();\n const inDegree = new Map<string, number>();\n const dependents = new Map<string, string[]>();\n\n for (const pkg of packages) {\n nameToPackage.set(pkg.name, pkg);\n inDegree.set(pkg.name, 0);\n dependents.set(pkg.name, []);\n }\n\n for (const pkg of packages) {\n if (pkg.dependsOn) {\n for (const dep of pkg.dependsOn) {\n if (nameToPackage.has(dep)) {\n inDegree.set(pkg.name, (inDegree.get(pkg.name) ?? 0) + 1);\n dependents.get(dep)?.push(pkg.name);\n }\n }\n }\n }\n\n const queue: string[] = [];\n\n for (const [name, degree] of inDegree) {\n if (degree === 0) {\n queue.push(name);\n }\n }\n\n const sorted: MonorepoPackage[] = [];\n\n while (queue.length > 0) {\n const name = queue.shift();\n\n if (!name) continue;\n\n const pkg = nameToPackage.get(name);\n\n if (pkg) {\n sorted.push(pkg);\n }\n\n for (const dependent of dependents.get(name) ?? []) {\n const newDegree = (inDegree.get(dependent) ?? 1) - 1;\n inDegree.set(dependent, newDegree);\n\n if (newDegree === 0) {\n queue.push(dependent);\n }\n }\n }\n\n if (sorted.length !== packages.length) {\n throw new Error('Circular dependency detected in package graph');\n }\n\n return sorted;\n}\n\nexport function getDependencyOrder(\n targetPackage: string,\n packages: MonorepoPackage[],\n): MonorepoPackage[] {\n const nameToPackage = new Map<string, MonorepoPackage>();\n\n for (const pkg of packages) {\n nameToPackage.set(pkg.name, pkg);\n }\n\n const target = nameToPackage.get(targetPackage);\n\n if (!target) return [];\n\n const visited = new Set<string>();\n const result: MonorepoPackage[] = [];\n\n function visit(name: string) {\n if (visited.has(name)) return;\n\n visited.add(name);\n\n const pkg = nameToPackage.get(name);\n\n if (!pkg) return;\n\n if (pkg.dependsOn) {\n for (const dep of pkg.dependsOn) {\n visit(dep);\n }\n }\n\n if (name !== targetPackage) {\n result.push(pkg);\n }\n }\n\n visit(targetPackage);\n\n return result;\n}\n\nexport async function buildPackage(\n packageName: string,\n cwd: string = process.cwd(),\n): Promise<void> {\n await runCmdOrExit(`build ${packageName}`, [\n 'pnpm',\n '--filter',\n packageName,\n 'build',\n ], { cwd });\n}\n\nexport async function buildDependencies(\n targetPackage: string,\n packages: MonorepoPackage[],\n cwd: string = process.cwd(),\n): Promise<void> {\n const deps = getDependencyOrder(targetPackage, packages);\n\n for (const dep of deps) {\n console.log(`Building dependency: ${dep.name}`);\n await buildPackage(dep.name, cwd);\n }\n}\n","import { cliInput } from '@ls-stack/cli';\nimport { styleText } from 'node:util';\nimport {\n configExists,\n generateConfigFile,\n type MonorepoPackage,\n type PkgManagerConfig,\n type PrePublishScript,\n} from '../core/config.ts';\nimport { detectMonorepo, scanPackages } from '../core/monorepo.ts';\n\ntype InitArgs = {\n force: boolean;\n};\n\nexport async function initCommand({ force }: InitArgs): Promise<void> {\n if (configExists() && !force) {\n console.error(\n styleText(['red', 'bold'], 'Config file already exists. Use --force to overwrite.'),\n );\n process.exit(1);\n }\n\n console.log(styleText(['blue', 'bold'], 'Initializing pkg-manager config...\\n'));\n\n const isMonorepo = detectMonorepo();\n\n if (isMonorepo) {\n console.log(styleText(['green'], 'Detected monorepo (pnpm-workspace.yaml found)\\n'));\n }\n\n const prePublishScripts = await selectPrePublishScripts();\n let monorepoConfig: { packages: MonorepoPackage[] } | undefined;\n\n if (isMonorepo) {\n const packages = scanPackages();\n\n if (packages.length > 0) {\n console.log(styleText(['blue'], `\\nFound ${packages.length} packages:`));\n\n for (const pkg of packages) {\n console.log(styleText(['dim'], ` - ${pkg.name} (${pkg.path})`));\n }\n\n const configureDeps = await cliInput.confirm(\n '\\nConfigure package dependencies?',\n { initial: true },\n );\n\n if (configureDeps) {\n monorepoConfig = await configureMonorepoDependencies(packages);\n } else {\n monorepoConfig = { packages };\n }\n }\n }\n\n const config: PkgManagerConfig = {\n requireMajorConfirmation: true,\n };\n\n if (prePublishScripts.length > 0) {\n config.prePublish = prePublishScripts;\n }\n\n if (monorepoConfig) {\n config.monorepo = monorepoConfig;\n }\n\n generateConfigFile(config);\n\n console.log(styleText(['green', 'bold'], '\\npkg-manager.config.ts created successfully!'));\n}\n\nasync function selectPrePublishScripts(): Promise<PrePublishScript[]> {\n const scripts: PrePublishScript[] = [];\n\n const selectedScripts = await cliInput.multipleSelect(\n 'Select pre-publish scripts to run:',\n {\n options: [\n {\n value: 'lint',\n label: 'Lint',\n hint: 'Run pnpm lint',\n },\n {\n value: 'test',\n label: 'Test',\n hint: 'Run pnpm test',\n },\n {\n value: 'build',\n label: 'Build',\n hint: 'Run pnpm build',\n },\n ],\n },\n );\n\n for (const script of selectedScripts) {\n switch (script) {\n case 'lint':\n scripts.push({ command: 'pnpm lint', label: 'Linting' });\n break;\n case 'test':\n scripts.push({ command: 'pnpm test', label: 'Testing' });\n break;\n case 'build':\n scripts.push({ command: 'pnpm build', label: 'Building' });\n break;\n }\n }\n\n return scripts;\n}\n\nasync function configureMonorepoDependencies(\n packages: MonorepoPackage[],\n): Promise<{ packages: MonorepoPackage[] }> {\n const configuredPackages: MonorepoPackage[] = [];\n\n for (const pkg of packages) {\n const otherPackages = packages.filter((p) => p.name !== pkg.name);\n\n if (otherPackages.length === 0) {\n configuredPackages.push(pkg);\n continue;\n }\n\n const deps = await cliInput.multipleSelect(\n `Select dependencies for ${pkg.name}:`,\n {\n options: [\n { value: '__none__', label: 'None', hint: 'No dependencies' },\n ...otherPackages.map((p) => ({\n value: p.name,\n label: p.name,\n hint: p.path,\n })),\n ],\n },\n );\n\n const filteredDeps = deps.filter((d) => d !== '__none__');\n\n if (filteredDeps.length > 0) {\n configuredPackages.push({\n ...pkg,\n dependsOn: filteredDeps,\n });\n } else {\n configuredPackages.push(pkg);\n }\n }\n\n return { packages: configuredPackages };\n}\n","import { runCmd, runCmdOrExit } from '../utils/runCmd.ts';\n\nexport async function isGitClean(): Promise<boolean> {\n const result = await runCmd('check git status', ['git', 'status', '--porcelain'], {\n silent: true,\n });\n\n if (!result.ok) return false;\n\n return result.output.trim() === '';\n}\n\nexport async function gitAdd(files: string[] = ['.']): Promise<void> {\n await runCmdOrExit('stage changes', ['git', 'add', ...files]);\n}\n\nexport async function gitCommit(message: string): Promise<void> {\n await runCmdOrExit('commit', ['git', 'commit', '-m', message]);\n}\n\nexport async function commitIfDirty(message: string): Promise<boolean> {\n const clean = await isGitClean();\n\n if (clean) {\n console.log('No changes to commit');\n return false;\n }\n\n await gitAdd();\n await gitCommit(message);\n return true;\n}\n","import { createHash } from 'crypto';\nimport {\n existsSync,\n mkdirSync,\n readFileSync,\n readdirSync,\n statSync,\n writeFileSync,\n} from 'fs';\nimport { dirname, join } from 'path';\nimport { z } from 'zod';\n\nconst packageHashesSchema = z.object({\n versions: z.record(z.string(), z.string()),\n lastVersion: z.string().optional(),\n});\n\nconst hashStoreSchema = z.object({\n packages: z.record(z.string(), packageHashesSchema),\n});\n\nexport function generateDirectoryHash(dirPath: string): string {\n if (!existsSync(dirPath)) {\n throw new Error(`Directory does not exist: ${dirPath}`);\n }\n\n const hash = createHash('sha256');\n const files: string[] = [];\n\n function collectFiles(currentPath: string, relativePath = '') {\n const items = readdirSync(currentPath).sort();\n for (const item of items) {\n const fullPath = join(currentPath, item);\n const itemRelativePath = relativePath ? join(relativePath, item) : item;\n const stat = statSync(fullPath);\n if (stat.isDirectory()) {\n collectFiles(fullPath, itemRelativePath);\n } else {\n files.push(itemRelativePath);\n }\n }\n }\n\n collectFiles(dirPath);\n\n for (const filePath of files) {\n const fullPath = join(dirPath, filePath);\n const content = readFileSync(fullPath);\n hash.update(filePath);\n hash.update(content);\n }\n\n return hash.digest('hex');\n}\n\ntype HashStore = z.infer<typeof hashStoreSchema>;\n\nexport function readHashStore(hashStorePath: string): HashStore {\n if (!existsSync(hashStorePath)) {\n return { packages: {} };\n }\n\n try {\n const content = readFileSync(hashStorePath, 'utf-8');\n const parsed = JSON.parse(content);\n return hashStoreSchema.parse(parsed);\n } catch {\n return { packages: {} };\n }\n}\n\nexport function writeHashStore(hashStorePath: string, store: HashStore): void {\n const dir = dirname(hashStorePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(hashStorePath, `${JSON.stringify(store, null, 2)}\\n`);\n}\n\nexport function checkHashForDuplicate(\n hashStorePath: string,\n packageName: string,\n currentHash: string,\n): { isDuplicate: boolean; existingVersion?: string } {\n const store = readHashStore(hashStorePath);\n const packageHashes = store.packages[packageName];\n\n if (!packageHashes) {\n return { isDuplicate: false };\n }\n\n for (const [version, hash] of Object.entries(packageHashes.versions)) {\n if (hash === currentHash) {\n return { isDuplicate: true, existingVersion: version };\n }\n }\n\n return { isDuplicate: false };\n}\n\nexport function savePackageHash(\n hashStorePath: string,\n packageName: string,\n version: string,\n hash: string,\n): void {\n const store = readHashStore(hashStorePath);\n\n if (!store.packages[packageName]) {\n store.packages[packageName] = { versions: {} };\n }\n\n const pkgStore = store.packages[packageName];\n\n pkgStore.versions[version] = hash;\n pkgStore.lastVersion = version;\n\n writeHashStore(hashStorePath, store);\n}\n","import { cliInput } from '@ls-stack/cli';\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { styleText } from 'node:util';\nimport { z } from 'zod';\nimport {\n getHashStorePath,\n loadConfig,\n type PkgManagerConfig,\n type PrePublishScript,\n} from '../core/config.ts';\nimport { commitIfDirty, isGitClean } from '../core/git.ts';\nimport {\n checkHashForDuplicate,\n generateDirectoryHash,\n savePackageHash,\n} from '../core/hash.ts';\nimport { buildDependencies } from '../core/monorepo.ts';\nimport { runCmdOrExit } from '../utils/runCmd.ts';\n\nconst VERSION_TYPES = ['major', 'minor', 'patch'] as const;\ntype VersionType = (typeof VERSION_TYPES)[number];\n\nconst packageJsonSchema = z.object({\n name: z.string().optional(),\n version: z.string().optional(),\n scripts: z.record(z.string(), z.string()).optional(),\n});\n\ntype PublishArgs = {\n package: string | undefined;\n type: string | undefined;\n force: boolean;\n dryRun: boolean;\n skipConfirm: boolean;\n};\n\nexport async function publishCommand(args: PublishArgs): Promise<void> {\n const config = await loadConfig();\n const cwd = process.cwd();\n\n const isClean = await isGitClean();\n\n if (!isClean) {\n console.error(\n styleText(['red', 'bold'], 'Git working directory is not clean.'),\n );\n console.error('Please commit or stash your changes before publishing.');\n process.exit(1);\n }\n\n const targetPackage = await resolveTargetPackage(args.package, config);\n const packagePath = getPackagePath(targetPackage, config, cwd);\n const packageName = getPackageName(packagePath);\n\n const currentVersion = getPackageVersion(packagePath);\n\n console.log(styleText(['blue', 'bold'], `\\nPublishing: ${packageName} (current: ${currentVersion})`));\n\n if (args.dryRun) {\n console.log(styleText(['yellow'], '(dry-run mode - no changes will be made)\\n'));\n }\n\n const versionType = await resolveVersionType(args.type, currentVersion);\n\n if (versionType === 'major' && config.requireMajorConfirmation && !args.skipConfirm) {\n const confirmed = await cliInput.confirm(\n 'You are about to publish a MAJOR version. Are you sure?',\n { initial: false },\n );\n\n if (!confirmed) {\n console.log('Aborted.');\n process.exit(0);\n }\n }\n\n if (config.monorepo?.packages) {\n console.log(styleText(['dim'], '\\nBuilding dependencies...'));\n if (!args.dryRun) {\n await buildDependencies(packageName, config.monorepo.packages, cwd);\n }\n }\n\n const prePublishScripts = getPrePublishScripts(config, packagePath, packageName);\n\n console.log(styleText(['dim'], '\\nRunning pre-publish scripts...'));\n\n for (const script of prePublishScripts) {\n console.log(styleText(['blue'], `\\n${script.label}...`));\n\n if (!args.dryRun) {\n const [cmd, ...cmdArgs] = script.command.split(' ');\n\n if (!cmd) {\n console.error(styleText(['red'], `Invalid command: ${script.command}`));\n process.exit(1);\n }\n\n if (config.monorepo) {\n await runCmdOrExit(script.label, ['pnpm', '--filter', packageName, ...cmdArgs], {\n cwd,\n });\n } else {\n await runCmdOrExit(script.label, [cmd, ...cmdArgs], { cwd: packagePath });\n }\n }\n }\n\n const distPath = join(packagePath, 'dist');\n\n if (!existsSync(distPath)) {\n console.error(styleText(['red', 'bold'], `dist directory not found at ${distPath}`));\n console.error('Please build your package first.');\n process.exit(1);\n }\n\n console.log(styleText(['dim'], '\\nGenerating build hash...'));\n const currentHash = generateDirectoryHash(distPath);\n console.log(styleText(['dim'], `Hash: ${currentHash.slice(0, 12)}...`));\n\n const hashStorePath = join(cwd, getHashStorePath(config));\n const hashCheck = checkHashForDuplicate(hashStorePath, packageName, currentHash);\n\n if (hashCheck.isDuplicate && !args.force) {\n console.error(\n styleText(\n ['red', 'bold'],\n `\\nThis build has already been published as ${packageName}@${hashCheck.existingVersion}`,\n ),\n );\n console.error('No changes detected in the build output.');\n console.error('Make code changes before attempting to publish.');\n console.error('Or use --force to publish anyway.');\n process.exit(1);\n }\n\n if (hashCheck.isDuplicate && args.force) {\n console.warn(\n styleText(\n ['yellow'],\n `\\nWarning: This build was already published as ${packageName}@${hashCheck.existingVersion}`,\n ),\n );\n console.warn('Force flag enabled - proceeding with publish anyway.');\n }\n\n console.log(styleText(['blue'], `\\nBumping version (${versionType})...`));\n\n if (!args.dryRun) {\n await runCmdOrExit('bump version', ['pnpm', 'version', versionType], {\n cwd: packagePath,\n });\n\n await commitIfDirty(`chore: bump ${packageName} to next ${versionType} version`);\n }\n\n const newVersion = getPackageVersion(packagePath);\n console.log(styleText(['green'], `New version: ${newVersion}`));\n\n console.log(styleText(['blue'], '\\nCreating git tag...'));\n\n if (!args.dryRun) {\n const tagName = `${packageName}@${newVersion}`;\n await runCmdOrExit('create tag', ['git', 'tag', tagName]);\n console.log(styleText(['dim'], `Created tag: ${tagName}`));\n }\n\n console.log(styleText(['blue'], '\\nPublishing to npm...'));\n\n if (!args.dryRun) {\n await runCmdOrExit('publish', ['pnpm', 'publish', '--access', 'public'], {\n cwd: packagePath,\n });\n\n savePackageHash(hashStorePath, packageName, newVersion, currentHash);\n\n await commitIfDirty(`chore: update publish hashes for ${packageName}@${newVersion}`);\n }\n\n console.log(\n styleText(['green', 'bold'], `\\nSuccessfully published ${packageName}@${newVersion}`),\n );\n}\n\nasync function resolveTargetPackage(\n packageArg: string | undefined,\n config: PkgManagerConfig,\n): Promise<string | undefined> {\n if (packageArg) return packageArg;\n\n if (!config.monorepo?.packages || config.monorepo.packages.length === 0) {\n return undefined;\n }\n\n const packageName = await cliInput.select('Select package to publish:', {\n options: config.monorepo.packages.map((pkg) => ({\n value: pkg.name,\n label: pkg.name,\n hint: pkg.path,\n })),\n });\n\n return packageName;\n}\n\nfunction bumpVersion(version: string, type: VersionType): string {\n const parts = version.split('.').map(Number);\n const major = parts[0] ?? 0;\n const minor = parts[1] ?? 0;\n const patch = parts[2] ?? 0;\n\n switch (type) {\n case 'major':\n return `${major + 1}.0.0`;\n case 'minor':\n return `${major}.${minor + 1}.0`;\n case 'patch':\n return `${major}.${minor}.${patch + 1}`;\n }\n}\n\nasync function resolveVersionType(\n typeArg: string | undefined,\n currentVersion: string,\n): Promise<VersionType> {\n if (typeArg) {\n const normalizedType = typeArg.toLowerCase();\n const matchingType = VERSION_TYPES.find((t) => t === normalizedType);\n\n if (!matchingType) {\n console.error(\n styleText(['red', 'bold'], `Invalid version type: ${typeArg}`),\n );\n console.error(`Valid types: ${VERSION_TYPES.join(', ')}`);\n process.exit(1);\n }\n return matchingType;\n }\n\n const versionType = await cliInput.select('Select version bump type:', {\n options: [\n { value: 'patch', label: 'patch', hint: `${currentVersion} → ${bumpVersion(currentVersion, 'patch')}` },\n { value: 'minor', label: 'minor', hint: `${currentVersion} → ${bumpVersion(currentVersion, 'minor')}` },\n { value: 'major', label: 'major', hint: `${currentVersion} → ${bumpVersion(currentVersion, 'major')}` },\n ],\n });\n\n return versionType;\n}\n\nfunction getPackagePath(\n targetPackage: string | undefined,\n config: PkgManagerConfig,\n cwd: string,\n): string {\n if (!targetPackage) return cwd;\n\n const pkg = config.monorepo?.packages.find((p) => p.name === targetPackage);\n\n if (pkg) return join(cwd, pkg.path);\n\n return cwd;\n}\n\nfunction readPackageJson(packagePath: string): z.infer<typeof packageJsonSchema> {\n const packageJsonPath = join(packagePath, 'package.json');\n const content = readFileSync(packageJsonPath, 'utf-8');\n const parsed = JSON.parse(content);\n return packageJsonSchema.parse(parsed);\n}\n\nfunction getPackageName(packagePath: string): string {\n const packageJsonPath = join(packagePath, 'package.json');\n\n if (!existsSync(packageJsonPath)) {\n console.error(\n styleText(['red', 'bold'], `package.json not found at ${packagePath}`),\n );\n process.exit(1);\n }\n\n const packageJson = readPackageJson(packagePath);\n\n if (!packageJson.name) {\n console.error(\n styleText(['red', 'bold'], 'package.json does not have a name field'),\n );\n process.exit(1);\n }\n\n return packageJson.name;\n}\n\nfunction getPackageVersion(packagePath: string): string {\n const packageJson = readPackageJson(packagePath);\n return packageJson.version ?? '0.0.0';\n}\n\nfunction getPrePublishScripts(\n config: PkgManagerConfig,\n packagePath: string,\n packageName: string,\n): PrePublishScript[] {\n if (config.prePublish && config.prePublish.length > 0) {\n return config.prePublish;\n }\n\n const packageJson = readPackageJson(packagePath);\n const hasPrePublishScript = packageJson.scripts?.['pre-publish'] !== undefined;\n\n if (hasPrePublishScript) {\n return [{ command: 'pnpm pre-publish', label: 'Running pre-publish script' }];\n }\n\n console.error(\n styleText(\n ['red', 'bold'],\n `\\nNo pre-publish scripts configured for ${packageName}`,\n ),\n );\n console.error(\n 'Either add a \"pre-publish\" script to package.json or configure \"prePublish\" in pkg-manager.config.ts',\n );\n process.exit(1);\n}\n","#!/usr/bin/env node\nimport { createCLI, createCmd } from '@ls-stack/cli';\nimport { initCommand } from './commands/init.ts';\nimport { publishCommand } from './commands/publish.ts';\n\nawait createCLI(\n {\n name: 'pkg-manager',\n baseCmd: 'pkg-manager',\n sort: ['publish', 'init'],\n },\n {\n init: createCmd({\n description: 'Initialize pkg-manager configuration',\n args: {\n force: {\n type: 'flag',\n name: 'force',\n description: 'Overwrite existing config file',\n },\n },\n run: async ({ force }) => {\n await initCommand({ force });\n },\n }),\n\n publish: createCmd({\n short: 'p',\n description: 'Publish a package with hash-based change detection',\n args: {\n package: {\n type: 'positional-string',\n name: 'package',\n description: 'Package name to publish (monorepo only)',\n default: '',\n },\n type: {\n type: 'value-string-flag',\n name: 'type',\n description: 'Version bump type: major, minor, or patch',\n },\n force: {\n type: 'flag',\n name: 'force',\n description: 'Force publish even if no changes detected',\n },\n dryRun: {\n type: 'flag',\n name: 'dry-run',\n description: 'Show what would be done without making changes',\n },\n skipConfirm: {\n type: 'flag',\n name: 'skip-confirm',\n description: 'Skip major version confirmation prompt',\n },\n },\n examples: [\n { args: ['--type', 'patch'], description: 'Publish a patch version' },\n { args: ['@my-scope/pkg', '--type', 'minor'], description: 'Publish specific package' },\n { args: ['--dry-run'], description: 'Preview publish without changes' },\n { args: ['--force', '--type', 'patch'], description: 'Force publish even if unchanged' },\n ],\n run: async ({ package: pkg, type, force, dryRun, skipConfirm }) => {\n await publishCommand({\n package: pkg || undefined,\n type,\n force,\n dryRun,\n skipConfirm,\n });\n },\n }),\n },\n);\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ls-stack/pkg-manager",
3
3
  "description": "CLI tool for managing package publishing with hash-based change tracking and monorepo support",
4
- "version": "0.2.0",
4
+ "version": "0.2.2",
5
5
  "license": "MIT",
6
6
  "files": [
7
7
  "dist"
@@ -33,6 +33,7 @@
33
33
  "devDependencies": {
34
34
  "@ls-stack/eslint-cfg": "^0.5.1",
35
35
  "@types/node": "^24.7.1",
36
+ "eslint": "^9.39.2",
36
37
  "tsdown": "^0.20.2",
37
38
  "tsx": "^4.19.4",
38
39
  "typescript": "5.9.3"
@@ -1 +0,0 @@
1
- {"version":3,"file":"exports.mjs","names":[],"sources":["../src/exports.ts"],"sourcesContent":["export type PkgManagerConfig = {\n prePublish?: { command: string; label: string }[];\n monorepo?: {\n packages: {\n name: string;\n path: string;\n dependsOn?: string[];\n }[];\n };\n hashStorePath?: string;\n requireMajorConfirmation?: boolean;\n};\n\nexport function defineConfig(config: PkgManagerConfig): PkgManagerConfig {\n return config;\n}\n"],"mappings":";AAaA,SAAgB,aAAa,QAA4C;AACvE,QAAO"}