@libria/clean-publish 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ 675881b84cbff8c3f5defc16a3e80a85dd43086e43b2916a556cb6efd218fcc7
package/README.md ADDED
@@ -0,0 +1,143 @@
1
+ # @libria/clean-publish
2
+
3
+ A CLI tool for publishing clean npm packages. Stage only the files you need, sanitize your `package.json`, and publish a minimal, production-ready package.
4
+
5
+ ## Why?
6
+
7
+ When you publish a package to npm, you often include unnecessary files like tests, source code, configs, and development scripts. This tool lets you:
8
+
9
+ - Copy only the files you want to publish (using glob patterns)
10
+ - Remove `devDependencies`, `scripts`, and other fields from `package.json`
11
+ - Preview what will be published before actually publishing
12
+ - Skip publishing when nothing has changed (hash-based detection)
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install -D @libria/clean-publish
18
+ ```
19
+
20
+ Or use it directly with npx:
21
+
22
+ ```bash
23
+ npx lb-clean-publish <command>
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ```bash
29
+ # Initialize config file
30
+ lb-clean-publish init
31
+
32
+ # Preview what will be staged
33
+ lb-clean-publish dry-run
34
+
35
+ # Stage files for publishing
36
+ lb-clean-publish build
37
+
38
+ # Publish to npm
39
+ lb-clean-publish publish
40
+ ```
41
+
42
+ ## Commands
43
+
44
+ | Command | Description |
45
+ | --------- | ---------------------------------------------- |
46
+ | `init` | Create a `.clnpb.json` config file |
47
+ | `build` | Stage files to temp directory and sanitize pkg |
48
+ | `dry-run` | Preview matched files and package.json rules |
49
+ | `pack` | Generate an npm tarball from staged files |
50
+ | `publish` | Publish staged files to npm registry |
51
+
52
+ ## Configuration
53
+
54
+ Create a `.clnpb.json` file in your project root (or run `lb-clean-publish init`):
55
+
56
+ ```json
57
+ {
58
+ "tmpDir": ".tmp-clean-publish",
59
+ "copy": [
60
+ "dist/**",
61
+ "README.md",
62
+ "LICENSE"
63
+ ],
64
+ "packageJson": {
65
+ "remove": {
66
+ "scripts": true,
67
+ "devDependencies": true
68
+ }
69
+ }
70
+ }
71
+ ```
72
+
73
+ ### Config Options
74
+
75
+ #### `tmpDir`
76
+
77
+ **Type:** `string`
78
+
79
+ Directory where files are staged before publishing.
80
+
81
+ #### `copy`
82
+
83
+ **Type:** `string[]`
84
+
85
+ Glob patterns for files to include in the published package. Uses [fast-glob](https://github.com/mrmlnc/fast-glob) syntax.
86
+
87
+ #### `packageJson`
88
+
89
+ Rules for sanitizing `package.json`:
90
+
91
+ | Option | Type | Description |
92
+ | ----------------------------- | ---------- | --------------------------------------------- |
93
+ | `remove.scripts` | `boolean` | Remove all scripts |
94
+ | `remove.devDependencies` | `boolean` | Remove devDependencies |
95
+ | `remove.optionalDependencies` | `boolean` | Remove optionalDependencies |
96
+ | `keepScripts` | `string[]` | Scripts to keep when `remove.scripts` is true |
97
+ | `removeFields` | `string[]` | Additional top-level fields to remove |
98
+
99
+ ### Example: Keep specific scripts
100
+
101
+ ```json
102
+ {
103
+ "tmpDir": ".tmp-clean-publish",
104
+ "copy": ["dist/**", "README.md"],
105
+ "packageJson": {
106
+ "remove": {
107
+ "scripts": true,
108
+ "devDependencies": true
109
+ },
110
+ "keepScripts": ["postinstall"]
111
+ }
112
+ }
113
+ ```
114
+
115
+ ### Example: Remove custom fields
116
+
117
+ ```json
118
+ {
119
+ "tmpDir": ".tmp-clean-publish",
120
+ "copy": ["dist/**", "README.md"],
121
+ "packageJson": {
122
+ "remove": {
123
+ "scripts": true,
124
+ "devDependencies": true,
125
+ "optionalDependencies": true
126
+ },
127
+ "removeFields": ["prettier", "eslintConfig", "jest"]
128
+ }
129
+ }
130
+ ```
131
+
132
+ ## Workflow
133
+
134
+ 1. **Build your project** - Compile TypeScript, bundle, etc.
135
+ 2. **Run `lb-clean-publish build`** - Stages files to temp directory
136
+ 3. **Run `lb-clean-publish pack`** (optional) - Creates a tarball to inspect
137
+ 4. **Run `lb-clean-publish publish`** - Publishes to npm
138
+
139
+ The publish command automatically skips if nothing has changed since the last publish (using content hashing).
140
+
141
+ ## License
142
+
143
+ MIT
package/dist/cli.cjs ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`node:crypto`);c=s(c);let l=require(`fs-extra`);l=s(l);let u=require(`fast-glob`);u=s(u);let d=require(`path`);d=s(d);let f=require(`execa`),p=require(`commander`);async function m(e,t){let n=c.default.createHash(`sha256`);for(let r of e.sort())n.update(r),n.update(await l.default.readFile(`${t}/${r}`));return n.digest(`hex`)}async function h(){let e=`.clnpb.json`;if(!await l.default.pathExists(e))throw Error(`Missing .clnpb.json`);return l.default.readJson(e)}async function g(e){await l.default.remove(e),await l.default.ensureDir(e)}function _(e,t){let n=structuredClone(e);if(t.remove?.devDependencies&&delete n.devDependencies,t.remove?.optionalDependencies&&delete n.optionalDependencies,t.remove?.scripts)if(t.keepScripts?.length){let r=e.scripts||{};n.scripts=Object.fromEntries(Object.entries(r).filter(([e])=>t.keepScripts.includes(e)))}else delete n.scripts;for(let e of t.removeFields||[])delete n[e];return n}async function v(e,t){e.some(e=>e.endsWith(`/`))&&console.warn(`⚠ Trailing slashes in glob patterns are ignored`);let n=await(0,u.default)(e,{dot:!0,onlyFiles:!0,unique:!0});for(let e of n){let n=d.default.join(t,e);await l.default.ensureDir(d.default.dirname(n)),await l.default.copyFile(e,n)}return{files:n,patterns:e}}async function y(){let e=await h(),t=e.tmpDir;await g(t);let{files:n}=await v(e.copy,t);n.length||console.warn(`⚠ All files excluded by glob patterns`);let r=_(await l.default.readJson(`package.json`),e.packageJson);await l.default.writeJson(`${t}/package.json`,r,{spaces:2});let i=await m(n,t);await l.default.writeFile(`${t}/.clean-publish.hash`,i),console.log(`✅ Staged ${n.length} files into ${t}`)}async function b(){let e=await h(),t=await(0,u.default)(e.copy,{dot:!0,onlyFiles:!0,unique:!0});t.length||console.warn(`⚠ All files excluded by glob patterns`),console.log(`📂 tmp dir:`,e.tmpDir),console.log(`📦 Matched files:`),t.forEach(e=>console.log(` -`,e)),console.log(`
3
+ 🧼 package.json rules:`),console.dir(e.packageJson,{depth:null})}const x={tmpDir:`.tmp-clean-publish`,copy:[`dist/**`,`README.md`,`LICENSE`],packageJson:{remove:{scripts:!0,devDependencies:!0}}};async function S(){let e=d.default.resolve(`.clnpb.json`);await l.default.pathExists(e)&&(console.error(`❌ .clnpb.json already exists`),process.exit(1)),await l.default.writeJson(e,x,{spaces:2}),console.log(`✅ Created .clnpb.json`)}async function C(){let{tmpDir:e}=await h();await(0,f.execa)(`npm`,[`pack`],{cwd:e,stdio:`inherit`})}const w=`.clean-publish.last-hash`;async function T(){let{tmpDir:e}=await h(),t=`${e}/.clean-publish.hash`;if(!await l.default.pathExists(t))throw Error("No staged build found. Run `lb-clean-publish build` first.");let n=(await l.default.readFile(t,`utf-8`)).trim();if((await l.default.pathExists(w)?(await l.default.readFile(w,`utf-8`)).trim():null)===n){console.log(`⏭ No changes detected, skipping publish`);return}await(0,f.execa)(`npm`,(await l.default.readJson(`${e}/package.json`)).name?.startsWith(`@`)?[`publish`,`--access`,`public`]:[`publish`],{cwd:e,stdio:`inherit`}),await l.default.writeFile(w,n),console.log(`✅ Published successfully`)}const E=new p.Command;E.name(`clean-publish`).description(`Publish clean npm packages from a staged directory`).version(`0.0.1`),E.command(`init`).description(`Create config file`).action(S),E.command(`build`).description(`Stage files and sanitize package.json`).action(y),E.command(`pack`).description(`Generate npm tarball`).action(C),E.command(`publish`).description(`Publish to registry`).action(T),E.command(`dry-run`).description(`Preview staged output`).action(b),E.parse(),exports.a=y,exports.c=g,exports.i=b,exports.l=h,exports.n=C,exports.o=v,exports.r=S,exports.s=_,exports.t=T,exports.u=m;
4
+ //# sourceMappingURL=cli.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.cjs","names":["crypto","fs","fs","fs","fs","fs","fs","fs","Command"],"sources":["../src/core/compute-hash.ts","../src/core/load-config.ts","../src/core/reset-tmp-dir.ts","../src/core/sanitize-package-json.ts","../src/core/stage-files.ts","../src/commands/build.ts","../src/commands/dry-run.ts","../src/commands/init.ts","../src/commands/pack.ts","../src/commands/publish.ts","../src/cli.ts"],"sourcesContent":["import crypto from \"node:crypto\";\r\nimport fs from \"fs-extra\";\r\n\r\nexport async function computeHash(files: string[], baseDir: string) {\r\n const hash = crypto.createHash('sha256');\r\n\r\n for (const file of files.sort()) {\r\n hash.update(file);\r\n hash.update(await fs.readFile(`${baseDir}/${file}`));\r\n }\r\n\r\n return hash.digest('hex');\r\n}","import fs from 'fs-extra';\r\nimport type { ClnpbConfig } from '../types';\r\n\r\nexport async function loadConfig(): Promise<ClnpbConfig> {\r\n const file = '.clnpb.json';\r\n if (!(await fs.pathExists(file))) {\r\n throw new Error('Missing .clnpb.json');\r\n }\r\n return fs.readJson(file) as Promise<ClnpbConfig>;\r\n}\r\n\r\n","import fs from \"fs-extra\";\r\n\r\nexport async function resetTmpDir(dir: string) {\r\n await fs.remove(dir);\r\n await fs.ensureDir(dir);\r\n}\r\n\r\n","import type { PackageJsonRules } from '../types';\r\n\r\nexport function sanitizePackageJson(pkg: Record<string, unknown>, rules: PackageJsonRules) {\r\n const copy = structuredClone(pkg);\r\n\r\n if (rules.remove?.devDependencies) delete copy.devDependencies;\r\n if (rules.remove?.optionalDependencies) delete copy.optionalDependencies;\r\n\r\n if (rules.remove?.scripts) {\r\n if (rules.keepScripts?.length) {\r\n const scripts = (pkg.scripts || {}) as Record<string, string>;\r\n copy.scripts = Object.fromEntries(\r\n Object.entries(scripts).filter(([k]) =>\r\n rules.keepScripts!.includes(k)\r\n )\r\n );\r\n } else {\r\n delete copy.scripts;\r\n }\r\n }\r\n\r\n for (const field of rules.removeFields || []) {\r\n delete copy[field];\r\n }\r\n\r\n return copy;\r\n}","import fg from 'fast-glob';\r\nimport fs from 'fs-extra';\r\nimport path from 'path';\r\n\r\nexport interface StageResult {\r\n files: string[];\r\n patterns: string[];\r\n}\r\n\r\nexport async function stageFiles(\r\n patterns: string[],\r\n tmpDir: string\r\n): Promise<StageResult> {\r\n if (patterns.some(p => p.endsWith('/'))) {\r\n console.warn('⚠ Trailing slashes in glob patterns are ignored');\r\n }\r\n\r\n const files = await fg(patterns, {\r\n dot: true,\r\n onlyFiles: true,\r\n unique: true\r\n });\r\n\r\n for (const file of files) {\r\n const dest = path.join(tmpDir, file);\r\n await fs.ensureDir(path.dirname(dest));\r\n await fs.copyFile(file, dest);\r\n }\r\n\r\n return { files, patterns };\r\n}\r\n","// src/commands/build.ts\r\nimport fs from 'fs-extra';\r\nimport {computeHash, loadConfig, resetTmpDir, sanitizePackageJson, stageFiles} from \"../core\";\r\n\r\nexport async function build() {\r\n const config = await loadConfig();\r\n const tmpDir = config.tmpDir;\r\n\r\n await resetTmpDir(tmpDir);\r\n\r\n const { files } = await stageFiles(config.copy, tmpDir);\r\n\r\n if (!files.length) {\r\n console.warn('⚠ All files excluded by glob patterns');\r\n }\r\n\r\n const pkg = await fs.readJson('package.json');\r\n const cleanPkg = sanitizePackageJson(pkg, config.packageJson);\r\n\r\n await fs.writeJson(`${tmpDir}/package.json`, cleanPkg, { spaces: 2 });\r\n\r\n const hash = await computeHash(files, tmpDir);\r\n await fs.writeFile(`${tmpDir}/.clean-publish.hash`, hash);\r\n\r\n console.log(`✅ Staged ${files.length} files into ${tmpDir}`);\r\n}\r\n","// src/commands/dryRun.ts\r\nimport fg from 'fast-glob';\r\nimport {loadConfig} from \"../core\";\r\n\r\nexport async function dryRun() {\r\n const config = await loadConfig();\r\n const files = await fg(config.copy, { dot: true, onlyFiles: true, unique: true });\r\n\r\n if (!files.length) {\r\n console.warn('⚠ All files excluded by glob patterns');\r\n }\r\n\r\n console.log('📂 tmp dir:', config.tmpDir);\r\n console.log('📦 Matched files:');\r\n\r\n files.forEach(f => console.log(' -', f));\r\n\r\n console.log('\\n🧼 package.json rules:');\r\n console.dir(config.packageJson, { depth: null });\r\n}\r\n","// src/commands/init.ts\r\nimport fs from 'fs-extra';\r\nimport path from 'path';\r\nimport type { ClnpbConfig } from '../types';\r\n\r\nconst DEFAULT_CONFIG: ClnpbConfig = {\r\n tmpDir: '.tmp-clean-publish',\r\n copy: ['dist/**', 'README.md', 'LICENSE'],\r\n packageJson: {\r\n remove: {\r\n scripts: true,\r\n devDependencies: true,\r\n },\r\n },\r\n};\r\n\r\nexport async function init() {\r\n const target = path.resolve('.clnpb.json');\r\n\r\n if (await fs.pathExists(target)) {\r\n console.error('❌ .clnpb.json already exists');\r\n process.exit(1);\r\n }\r\n\r\n await fs.writeJson(target, DEFAULT_CONFIG, { spaces: 2 });\r\n\r\n console.log('✅ Created .clnpb.json');\r\n}\r\n","// src/commands/pack.ts\r\nimport { execa } from 'execa';\r\nimport {loadConfig} from \"../core\";\r\n\r\nexport async function pack() {\r\n const { tmpDir } = await loadConfig();\r\n await execa('npm', ['pack'], { cwd: tmpDir, stdio: 'inherit' });\r\n}\r\n","// src/commands/publish.ts\r\nimport { execa } from 'execa';\r\nimport fs from 'fs-extra';\r\nimport { loadConfig } from \"../core\";\r\n\r\nconst LAST_HASH_FILE = '.clean-publish.last-hash';\r\n\r\nexport async function publish() {\r\n const { tmpDir } = await loadConfig();\r\n\r\n const currentHashFile = `${tmpDir}/.clean-publish.hash`;\r\n if (!(await fs.pathExists(currentHashFile))) {\r\n throw new Error('No staged build found. Run `lb-clean-publish build` first.');\r\n }\r\n\r\n const currentHash = (await fs.readFile(currentHashFile, 'utf-8')).trim();\r\n const previousHash = await fs.pathExists(LAST_HASH_FILE)\r\n ? (await fs.readFile(LAST_HASH_FILE, 'utf-8')).trim()\r\n : null;\r\n\r\n if (previousHash === currentHash) {\r\n console.log('⏭ No changes detected, skipping publish');\r\n return;\r\n }\r\n\r\n const pkg = await fs.readJson(`${tmpDir}/package.json`);\r\n const isScoped = pkg.name?.startsWith('@');\r\n\r\n const args = isScoped ? ['publish', '--access', 'public'] : ['publish'];\r\n await execa('npm', args, { cwd: tmpDir, stdio: 'inherit' });\r\n\r\n await fs.writeFile(LAST_HASH_FILE, currentHash);\r\n console.log('✅ Published successfully');\r\n}\r\n","#!/usr/bin/env node\r\nimport { Command } from 'commander';\r\nimport {build, dryRun, init, pack, publish} from \"./commands\";\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name('clean-publish')\r\n .description('Publish clean npm packages from a staged directory')\r\n .version('0.0.1');\r\n\r\nprogram.command('init').description('Create config file').action(init);\r\nprogram.command('build').description('Stage files and sanitize package.json').action(build);\r\nprogram.command('pack').description('Generate npm tarball').action(pack);\r\nprogram.command('publish').description('Publish to registry').action(publish);\r\nprogram.command('dry-run').description('Preview staged output').action(dryRun);\r\n\r\nprogram.parse();\r\n"],"mappings":"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"}
package/dist/cli.d.cts ADDED
@@ -0,0 +1 @@
1
+ export { };
package/dist/cli.d.mts ADDED
@@ -0,0 +1 @@
1
+ export { };
package/dist/cli.mjs ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import e from"node:crypto";import t from"fs-extra";import n from"fast-glob";import r from"path";import{execa as i}from"execa";import{Command as a}from"commander";async function o(n,r){let i=e.createHash(`sha256`);for(let e of n.sort())i.update(e),i.update(await t.readFile(`${r}/${e}`));return i.digest(`hex`)}async function s(){let e=`.clnpb.json`;if(!await t.pathExists(e))throw Error(`Missing .clnpb.json`);return t.readJson(e)}async function c(e){await t.remove(e),await t.ensureDir(e)}function l(e,t){let n=structuredClone(e);if(t.remove?.devDependencies&&delete n.devDependencies,t.remove?.optionalDependencies&&delete n.optionalDependencies,t.remove?.scripts)if(t.keepScripts?.length){let r=e.scripts||{};n.scripts=Object.fromEntries(Object.entries(r).filter(([e])=>t.keepScripts.includes(e)))}else delete n.scripts;for(let e of t.removeFields||[])delete n[e];return n}async function u(e,i){e.some(e=>e.endsWith(`/`))&&console.warn(`⚠ Trailing slashes in glob patterns are ignored`);let a=await n(e,{dot:!0,onlyFiles:!0,unique:!0});for(let e of a){let n=r.join(i,e);await t.ensureDir(r.dirname(n)),await t.copyFile(e,n)}return{files:a,patterns:e}}async function d(){let e=await s(),n=e.tmpDir;await c(n);let{files:r}=await u(e.copy,n);r.length||console.warn(`⚠ All files excluded by glob patterns`);let i=l(await t.readJson(`package.json`),e.packageJson);await t.writeJson(`${n}/package.json`,i,{spaces:2});let a=await o(r,n);await t.writeFile(`${n}/.clean-publish.hash`,a),console.log(`✅ Staged ${r.length} files into ${n}`)}async function f(){let e=await s(),t=await n(e.copy,{dot:!0,onlyFiles:!0,unique:!0});t.length||console.warn(`⚠ All files excluded by glob patterns`),console.log(`📂 tmp dir:`,e.tmpDir),console.log(`📦 Matched files:`),t.forEach(e=>console.log(` -`,e)),console.log(`
3
+ 🧼 package.json rules:`),console.dir(e.packageJson,{depth:null})}const p={tmpDir:`.tmp-clean-publish`,copy:[`dist/**`,`README.md`,`LICENSE`],packageJson:{remove:{scripts:!0,devDependencies:!0}}};async function m(){let e=r.resolve(`.clnpb.json`);await t.pathExists(e)&&(console.error(`❌ .clnpb.json already exists`),process.exit(1)),await t.writeJson(e,p,{spaces:2}),console.log(`✅ Created .clnpb.json`)}async function h(){let{tmpDir:e}=await s();await i(`npm`,[`pack`],{cwd:e,stdio:`inherit`})}const g=`.clean-publish.last-hash`;async function _(){let{tmpDir:e}=await s(),n=`${e}/.clean-publish.hash`;if(!await t.pathExists(n))throw Error("No staged build found. Run `lb-clean-publish build` first.");let r=(await t.readFile(n,`utf-8`)).trim();if((await t.pathExists(g)?(await t.readFile(g,`utf-8`)).trim():null)===r){console.log(`⏭ No changes detected, skipping publish`);return}await i(`npm`,(await t.readJson(`${e}/package.json`)).name?.startsWith(`@`)?[`publish`,`--access`,`public`]:[`publish`],{cwd:e,stdio:`inherit`}),await t.writeFile(g,r),console.log(`✅ Published successfully`)}const v=new a;v.name(`clean-publish`).description(`Publish clean npm packages from a staged directory`).version(`0.0.1`),v.command(`init`).description(`Create config file`).action(m),v.command(`build`).description(`Stage files and sanitize package.json`).action(d),v.command(`pack`).description(`Generate npm tarball`).action(h),v.command(`publish`).description(`Publish to registry`).action(_),v.command(`dry-run`).description(`Preview staged output`).action(f),v.parse();export{d as a,c,f as i,s as l,h as n,u as o,m as r,l as s,_ as t,o as u};
4
+ //# sourceMappingURL=cli.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.mjs","names":[],"sources":["../src/core/compute-hash.ts","../src/core/load-config.ts","../src/core/reset-tmp-dir.ts","../src/core/sanitize-package-json.ts","../src/core/stage-files.ts","../src/commands/build.ts","../src/commands/dry-run.ts","../src/commands/init.ts","../src/commands/pack.ts","../src/commands/publish.ts","../src/cli.ts"],"sourcesContent":["import crypto from \"node:crypto\";\r\nimport fs from \"fs-extra\";\r\n\r\nexport async function computeHash(files: string[], baseDir: string) {\r\n const hash = crypto.createHash('sha256');\r\n\r\n for (const file of files.sort()) {\r\n hash.update(file);\r\n hash.update(await fs.readFile(`${baseDir}/${file}`));\r\n }\r\n\r\n return hash.digest('hex');\r\n}","import fs from 'fs-extra';\r\nimport type { ClnpbConfig } from '../types';\r\n\r\nexport async function loadConfig(): Promise<ClnpbConfig> {\r\n const file = '.clnpb.json';\r\n if (!(await fs.pathExists(file))) {\r\n throw new Error('Missing .clnpb.json');\r\n }\r\n return fs.readJson(file) as Promise<ClnpbConfig>;\r\n}\r\n\r\n","import fs from \"fs-extra\";\r\n\r\nexport async function resetTmpDir(dir: string) {\r\n await fs.remove(dir);\r\n await fs.ensureDir(dir);\r\n}\r\n\r\n","import type { PackageJsonRules } from '../types';\r\n\r\nexport function sanitizePackageJson(pkg: Record<string, unknown>, rules: PackageJsonRules) {\r\n const copy = structuredClone(pkg);\r\n\r\n if (rules.remove?.devDependencies) delete copy.devDependencies;\r\n if (rules.remove?.optionalDependencies) delete copy.optionalDependencies;\r\n\r\n if (rules.remove?.scripts) {\r\n if (rules.keepScripts?.length) {\r\n const scripts = (pkg.scripts || {}) as Record<string, string>;\r\n copy.scripts = Object.fromEntries(\r\n Object.entries(scripts).filter(([k]) =>\r\n rules.keepScripts!.includes(k)\r\n )\r\n );\r\n } else {\r\n delete copy.scripts;\r\n }\r\n }\r\n\r\n for (const field of rules.removeFields || []) {\r\n delete copy[field];\r\n }\r\n\r\n return copy;\r\n}","import fg from 'fast-glob';\r\nimport fs from 'fs-extra';\r\nimport path from 'path';\r\n\r\nexport interface StageResult {\r\n files: string[];\r\n patterns: string[];\r\n}\r\n\r\nexport async function stageFiles(\r\n patterns: string[],\r\n tmpDir: string\r\n): Promise<StageResult> {\r\n if (patterns.some(p => p.endsWith('/'))) {\r\n console.warn('⚠ Trailing slashes in glob patterns are ignored');\r\n }\r\n\r\n const files = await fg(patterns, {\r\n dot: true,\r\n onlyFiles: true,\r\n unique: true\r\n });\r\n\r\n for (const file of files) {\r\n const dest = path.join(tmpDir, file);\r\n await fs.ensureDir(path.dirname(dest));\r\n await fs.copyFile(file, dest);\r\n }\r\n\r\n return { files, patterns };\r\n}\r\n","// src/commands/build.ts\r\nimport fs from 'fs-extra';\r\nimport {computeHash, loadConfig, resetTmpDir, sanitizePackageJson, stageFiles} from \"../core\";\r\n\r\nexport async function build() {\r\n const config = await loadConfig();\r\n const tmpDir = config.tmpDir;\r\n\r\n await resetTmpDir(tmpDir);\r\n\r\n const { files } = await stageFiles(config.copy, tmpDir);\r\n\r\n if (!files.length) {\r\n console.warn('⚠ All files excluded by glob patterns');\r\n }\r\n\r\n const pkg = await fs.readJson('package.json');\r\n const cleanPkg = sanitizePackageJson(pkg, config.packageJson);\r\n\r\n await fs.writeJson(`${tmpDir}/package.json`, cleanPkg, { spaces: 2 });\r\n\r\n const hash = await computeHash(files, tmpDir);\r\n await fs.writeFile(`${tmpDir}/.clean-publish.hash`, hash);\r\n\r\n console.log(`✅ Staged ${files.length} files into ${tmpDir}`);\r\n}\r\n","// src/commands/dryRun.ts\r\nimport fg from 'fast-glob';\r\nimport {loadConfig} from \"../core\";\r\n\r\nexport async function dryRun() {\r\n const config = await loadConfig();\r\n const files = await fg(config.copy, { dot: true, onlyFiles: true, unique: true });\r\n\r\n if (!files.length) {\r\n console.warn('⚠ All files excluded by glob patterns');\r\n }\r\n\r\n console.log('📂 tmp dir:', config.tmpDir);\r\n console.log('📦 Matched files:');\r\n\r\n files.forEach(f => console.log(' -', f));\r\n\r\n console.log('\\n🧼 package.json rules:');\r\n console.dir(config.packageJson, { depth: null });\r\n}\r\n","// src/commands/init.ts\r\nimport fs from 'fs-extra';\r\nimport path from 'path';\r\nimport type { ClnpbConfig } from '../types';\r\n\r\nconst DEFAULT_CONFIG: ClnpbConfig = {\r\n tmpDir: '.tmp-clean-publish',\r\n copy: ['dist/**', 'README.md', 'LICENSE'],\r\n packageJson: {\r\n remove: {\r\n scripts: true,\r\n devDependencies: true,\r\n },\r\n },\r\n};\r\n\r\nexport async function init() {\r\n const target = path.resolve('.clnpb.json');\r\n\r\n if (await fs.pathExists(target)) {\r\n console.error('❌ .clnpb.json already exists');\r\n process.exit(1);\r\n }\r\n\r\n await fs.writeJson(target, DEFAULT_CONFIG, { spaces: 2 });\r\n\r\n console.log('✅ Created .clnpb.json');\r\n}\r\n","// src/commands/pack.ts\r\nimport { execa } from 'execa';\r\nimport {loadConfig} from \"../core\";\r\n\r\nexport async function pack() {\r\n const { tmpDir } = await loadConfig();\r\n await execa('npm', ['pack'], { cwd: tmpDir, stdio: 'inherit' });\r\n}\r\n","// src/commands/publish.ts\r\nimport { execa } from 'execa';\r\nimport fs from 'fs-extra';\r\nimport { loadConfig } from \"../core\";\r\n\r\nconst LAST_HASH_FILE = '.clean-publish.last-hash';\r\n\r\nexport async function publish() {\r\n const { tmpDir } = await loadConfig();\r\n\r\n const currentHashFile = `${tmpDir}/.clean-publish.hash`;\r\n if (!(await fs.pathExists(currentHashFile))) {\r\n throw new Error('No staged build found. Run `lb-clean-publish build` first.');\r\n }\r\n\r\n const currentHash = (await fs.readFile(currentHashFile, 'utf-8')).trim();\r\n const previousHash = await fs.pathExists(LAST_HASH_FILE)\r\n ? (await fs.readFile(LAST_HASH_FILE, 'utf-8')).trim()\r\n : null;\r\n\r\n if (previousHash === currentHash) {\r\n console.log('⏭ No changes detected, skipping publish');\r\n return;\r\n }\r\n\r\n const pkg = await fs.readJson(`${tmpDir}/package.json`);\r\n const isScoped = pkg.name?.startsWith('@');\r\n\r\n const args = isScoped ? ['publish', '--access', 'public'] : ['publish'];\r\n await execa('npm', args, { cwd: tmpDir, stdio: 'inherit' });\r\n\r\n await fs.writeFile(LAST_HASH_FILE, currentHash);\r\n console.log('✅ Published successfully');\r\n}\r\n","#!/usr/bin/env node\r\nimport { Command } from 'commander';\r\nimport {build, dryRun, init, pack, publish} from \"./commands\";\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name('clean-publish')\r\n .description('Publish clean npm packages from a staged directory')\r\n .version('0.0.1');\r\n\r\nprogram.command('init').description('Create config file').action(init);\r\nprogram.command('build').description('Stage files and sanitize package.json').action(build);\r\nprogram.command('pack').description('Generate npm tarball').action(pack);\r\nprogram.command('publish').description('Publish to registry').action(publish);\r\nprogram.command('dry-run').description('Preview staged output').action(dryRun);\r\n\r\nprogram.parse();\r\n"],"mappings":"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"}
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ const e=require(`./cli.cjs`);exports.build=e.a,exports.computeHash=e.u,exports.dryRun=e.i,exports.init=e.r,exports.loadConfig=e.l,exports.pack=e.n,exports.publish=e.t,exports.resetTmpDir=e.c,exports.sanitizePackageJson=e.s,exports.stageFiles=e.o;
@@ -0,0 +1,52 @@
1
+ //#region src/core/compute-hash.d.ts
2
+ declare function computeHash(files: string[], baseDir: string): Promise<string>;
3
+ //#endregion
4
+ //#region src/types.d.ts
5
+ interface PackageJsonRules {
6
+ remove?: {
7
+ scripts?: boolean;
8
+ devDependencies?: boolean;
9
+ optionalDependencies?: boolean;
10
+ };
11
+ keepScripts?: string[];
12
+ removeFields?: string[];
13
+ }
14
+ interface ClnpbConfig {
15
+ tmpDir: string;
16
+ copy: string[];
17
+ packageJson: PackageJsonRules;
18
+ }
19
+ //#endregion
20
+ //#region src/core/load-config.d.ts
21
+ declare function loadConfig(): Promise<ClnpbConfig>;
22
+ //#endregion
23
+ //#region src/core/reset-tmp-dir.d.ts
24
+ declare function resetTmpDir(dir: string): Promise<void>;
25
+ //#endregion
26
+ //#region src/core/sanitize-package-json.d.ts
27
+ declare function sanitizePackageJson(pkg: Record<string, unknown>, rules: PackageJsonRules): Record<string, unknown>;
28
+ //#endregion
29
+ //#region src/core/stage-files.d.ts
30
+ interface StageResult {
31
+ files: string[];
32
+ patterns: string[];
33
+ }
34
+ declare function stageFiles(patterns: string[], tmpDir: string): Promise<StageResult>;
35
+ //#endregion
36
+ //#region src/commands/build.d.ts
37
+ declare function build(): Promise<void>;
38
+ //#endregion
39
+ //#region src/commands/dry-run.d.ts
40
+ declare function dryRun(): Promise<void>;
41
+ //#endregion
42
+ //#region src/commands/init.d.ts
43
+ declare function init(): Promise<void>;
44
+ //#endregion
45
+ //#region src/commands/pack.d.ts
46
+ declare function pack(): Promise<void>;
47
+ //#endregion
48
+ //#region src/commands/publish.d.ts
49
+ declare function publish(): Promise<void>;
50
+ //#endregion
51
+ export { ClnpbConfig, PackageJsonRules, StageResult, build, computeHash, dryRun, init, loadConfig, pack, publish, resetTmpDir, sanitizePackageJson, stageFiles };
52
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1,52 @@
1
+ //#region src/core/compute-hash.d.ts
2
+ declare function computeHash(files: string[], baseDir: string): Promise<string>;
3
+ //#endregion
4
+ //#region src/types.d.ts
5
+ interface PackageJsonRules {
6
+ remove?: {
7
+ scripts?: boolean;
8
+ devDependencies?: boolean;
9
+ optionalDependencies?: boolean;
10
+ };
11
+ keepScripts?: string[];
12
+ removeFields?: string[];
13
+ }
14
+ interface ClnpbConfig {
15
+ tmpDir: string;
16
+ copy: string[];
17
+ packageJson: PackageJsonRules;
18
+ }
19
+ //#endregion
20
+ //#region src/core/load-config.d.ts
21
+ declare function loadConfig(): Promise<ClnpbConfig>;
22
+ //#endregion
23
+ //#region src/core/reset-tmp-dir.d.ts
24
+ declare function resetTmpDir(dir: string): Promise<void>;
25
+ //#endregion
26
+ //#region src/core/sanitize-package-json.d.ts
27
+ declare function sanitizePackageJson(pkg: Record<string, unknown>, rules: PackageJsonRules): Record<string, unknown>;
28
+ //#endregion
29
+ //#region src/core/stage-files.d.ts
30
+ interface StageResult {
31
+ files: string[];
32
+ patterns: string[];
33
+ }
34
+ declare function stageFiles(patterns: string[], tmpDir: string): Promise<StageResult>;
35
+ //#endregion
36
+ //#region src/commands/build.d.ts
37
+ declare function build(): Promise<void>;
38
+ //#endregion
39
+ //#region src/commands/dry-run.d.ts
40
+ declare function dryRun(): Promise<void>;
41
+ //#endregion
42
+ //#region src/commands/init.d.ts
43
+ declare function init(): Promise<void>;
44
+ //#endregion
45
+ //#region src/commands/pack.d.ts
46
+ declare function pack(): Promise<void>;
47
+ //#endregion
48
+ //#region src/commands/publish.d.ts
49
+ declare function publish(): Promise<void>;
50
+ //#endregion
51
+ export { ClnpbConfig, PackageJsonRules, StageResult, build, computeHash, dryRun, init, loadConfig, pack, publish, resetTmpDir, sanitizePackageJson, stageFiles };
52
+ //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ import{a as e,c as t,i as n,l as r,n as i,o as a,r as o,s,t as c,u as l}from"./cli.mjs";export{e as build,l as computeHash,n as dryRun,o as init,r as loadConfig,i as pack,c as publish,t as resetTmpDir,s as sanitizePackageJson,a as stageFiles};
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@libria/clean-publish",
3
+ "version": "0.1.0",
4
+ "description": "A CLI tool for publishing clean npm packages",
5
+ "main": "dist/index.cjs",
6
+ "module": "dist/index.mjs",
7
+ "exports": {
8
+ ".": {
9
+ "require": {
10
+ "types": "./dist/index.d.cts",
11
+ "default": "./dist/index.cjs"
12
+ },
13
+ "import": {
14
+ "types": "./dist/index.d.mts",
15
+ "default": "./dist/index.mjs"
16
+ }
17
+ }
18
+ },
19
+ "type": "module",
20
+ "bin": {
21
+ "lb-clean-publish": "./dist/cli.mjs"
22
+ },
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/LibriaForge/clean-publish.git"
26
+ },
27
+ "keywords": [
28
+ "publish",
29
+ "typescript"
30
+ ],
31
+ "author": "LibriaForge",
32
+ "license": "MIT",
33
+ "bugs": {
34
+ "url": "https://github.com/LibriaForge/clean-publish/issues"
35
+ },
36
+ "homepage": "https://github.com/LibriaForge/clean-publish#readme",
37
+ "dependencies": {
38
+ "commander": "^14.0.3",
39
+ "execa": "^9.6.1",
40
+ "fast-glob": "^3.3.3",
41
+ "fs-extra": "^11.3.3",
42
+ "picocolors": "^1.1.1"
43
+ }
44
+ }