screw-up 0.8.1 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,6 +49,7 @@ To insert banner header each bundled source files (`dist/index.js` and etc.):
49
49
  * Nested object support: Handles nested objects like `author.name`, `repository.url`.
50
50
  * Customizable: Choose which metadata fields to include in your banner.
51
51
  * TypeScript metadata generation: Automatically generates TypeScript files with metadata constants for use in your source code.
52
+ * Supported pack/publish CLI interface. When publishing using this feature, the package is generated after applying the above processing to `package.json`.
52
53
 
53
54
  ## Installation
54
55
 
@@ -295,6 +296,84 @@ The plugin automatically detects and supports:
295
296
 
296
297
  ----
297
298
 
299
+ ## CLI Usage
300
+
301
+ The `screw-up` package includes a command-line interface for packaging and publishing your projects.
302
+
303
+ ### Pack Command
304
+
305
+ Create a tar archive of your project:
306
+
307
+ ```bash
308
+ # Pack current directory
309
+ screw-up pack
310
+
311
+ # Pack specific directory
312
+ screw-up pack ./my-project
313
+
314
+ # Pack to specific output directory
315
+ screw-up pack --pack-destination ./dist
316
+ ```
317
+
318
+ The pack command:
319
+
320
+ - Automatically reads `package.json` for metadata and file inclusion rules
321
+ - Respects the `files` field in your `package.json`
322
+ - Supports workspace inheritance (inherits metadata from parent packages)
323
+ - Creates a compressed `.tgz` archive with format: `{name}-{version}.tgz`
324
+
325
+ ### Publish Command
326
+
327
+ Publish your project to registry server:
328
+
329
+ ```bash
330
+ # Publish current directory (creates archive and publishes)
331
+ screw-up publish
332
+
333
+ # Publish specific directory
334
+ screw-up publish ./my-project
335
+
336
+ # Publish existing tarball
337
+ screw-up publish package.tgz
338
+
339
+ # Publish with npm options (all npm publish options are supported)
340
+ screw-up publish --dry-run --tag beta --access public
341
+ ```
342
+
343
+ The publish command:
344
+
345
+ - Supports all `npm publish` options transparently
346
+ - Can publish from directory (automatically creates archive) or existing tarball
347
+ - Handles workspace packages with proper metadata inheritance
348
+ - Uses the same packaging logic as the pack command
349
+
350
+ ### Examples
351
+
352
+ ```bash
353
+ # Build and publish with dry run
354
+ screw-up publish --dry-run
355
+
356
+ # Publish to beta channel
357
+ screw-up publish --tag beta
358
+
359
+ # Publish scoped package as public
360
+ screw-up publish --access public
361
+
362
+ # Pack to custom directory then publish
363
+ screw-up pack --pack-destination ./release
364
+ screw-up publish ./release/my-package-1.0.0.tgz
365
+ ```
366
+
367
+ For help with any command:
368
+
369
+ ```bash
370
+ screw-up --help
371
+ screw-up pack --help
372
+ screw-up publish --help
373
+ ```
374
+
375
+ ----
376
+
298
377
  ## License
299
378
 
300
379
  Under MIT
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Pack assets into a tar archive
3
+ * @param targetDir - Target directory to pack
4
+ * @param outputDir - Output directory to write the tarball
5
+ * @returns Package metadata (package.json) or undefined if failed
6
+ */
7
+ export declare const packAssets: (targetDir: string, outputDir: string) => Promise<any>;
8
+ export interface ParsedArgs {
9
+ command?: string;
10
+ positional: string[];
11
+ options: Record<string, string | boolean>;
12
+ }
13
+ export declare const parseArgs: (argv: string[]) => ParsedArgs;
14
+ //# sourceMappingURL=cli-internal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-internal.d.ts","sourceRoot":"","sources":["../src/cli-internal.ts"],"names":[],"mappings":"AAyCA;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GAAU,WAAW,MAAM,EAAE,WAAW,MAAM,KAAI,OAAO,CAAC,GAAG,CA2EnF,CAAC;AAIF,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;CAC3C;AAED,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,KAAG,UAoE1C,CAAC"}
package/dist/cli.cjs ADDED
@@ -0,0 +1,343 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ const path = require("path");
4
+ const fs = require("fs");
5
+ const promises = require("fs/promises");
6
+ const child_process = require("child_process");
7
+ const glob = require("glob");
8
+ const internal = require("./internal-BJ2gdqpB.cjs");
9
+ const tar = require("tar-stream");
10
+ const zlib = require("zlib");
11
+ const addPackContentEntry = async (pack, name, content) => {
12
+ pack.entry({
13
+ name,
14
+ type: "file",
15
+ mode: 420,
16
+ mtime: /* @__PURE__ */ new Date(),
17
+ size: Buffer.byteLength(content, "utf8")
18
+ }, content);
19
+ };
20
+ const addPackFileEntry = async (pack, baseDir, path$1, stat) => {
21
+ const writer = pack.entry({
22
+ name: path$1,
23
+ mode: stat.mode,
24
+ mtime: stat.mtime,
25
+ size: stat.size
26
+ });
27
+ const stream = fs.createReadStream(path.resolve(baseDir, path$1));
28
+ stream.pipe(writer);
29
+ return new Promise((resolve2, reject) => {
30
+ stream.on("end", resolve2);
31
+ stream.on("error", reject);
32
+ writer.on("error", reject);
33
+ });
34
+ };
35
+ const packAssets = async (targetDir, outputDir) => {
36
+ var _a, _b, _c, _d;
37
+ if (!fs.existsSync(targetDir)) {
38
+ return void 0;
39
+ }
40
+ let resolvedPackageJson;
41
+ try {
42
+ resolvedPackageJson = await internal.resolveRawPackageJson(targetDir);
43
+ } catch (error) {
44
+ return void 0;
45
+ }
46
+ if (resolvedPackageJson == null ? void 0 : resolvedPackageJson.private) {
47
+ return void 0;
48
+ }
49
+ const outputFileName = `${(_b = (_a = resolvedPackageJson == null ? void 0 : resolvedPackageJson.name) == null ? void 0 : _a.replace("/", "-")) != null ? _b : "package"}-${(_c = resolvedPackageJson == null ? void 0 : resolvedPackageJson.version) != null ? _c : "0.0.0"}.tgz`;
50
+ const pack = tar.pack();
51
+ try {
52
+ const packageJsonContent = JSON.stringify(resolvedPackageJson, null, 2);
53
+ await addPackContentEntry(pack, "package.json", packageJsonContent);
54
+ const distributionFileGlobs = (_d = resolvedPackageJson == null ? void 0 : resolvedPackageJson.files) != null ? _d : ["**/*"];
55
+ const packingFilePaths = distributionFileGlobs.map((fg) => glob.glob.sync(fg, { cwd: targetDir })).flat();
56
+ for (const packingFilePath of packingFilePaths) {
57
+ const fullPath = path.resolve(targetDir, packingFilePath);
58
+ const stat = await promises.lstat(fullPath);
59
+ if (stat.isFile() && packingFilePath !== "package.json") {
60
+ await addPackFileEntry(pack, targetDir, packingFilePath, stat);
61
+ }
62
+ }
63
+ pack.finalize();
64
+ if (!fs.existsSync(outputDir)) {
65
+ await promises.mkdir(outputDir, { recursive: true });
66
+ }
67
+ const outputFile = path.resolve(outputDir, outputFileName);
68
+ const outputStream = fs.createWriteStream(outputFile);
69
+ const gzip = zlib.createGzip();
70
+ await new Promise((resolve2, reject) => {
71
+ pack.pipe(gzip).pipe(outputStream);
72
+ outputStream.on("finish", () => resolve2());
73
+ outputStream.on("error", reject);
74
+ pack.on("error", reject);
75
+ gzip.on("error", reject);
76
+ });
77
+ } finally {
78
+ pack.destroy();
79
+ }
80
+ return resolvedPackageJson;
81
+ };
82
+ const parseArgs = (argv) => {
83
+ const args = argv.slice(2);
84
+ const result = {
85
+ positional: [],
86
+ options: {}
87
+ };
88
+ if (args.length === 0) {
89
+ return result;
90
+ }
91
+ if (args[0].startsWith("-")) {
92
+ let i2 = 0;
93
+ while (i2 < args.length) {
94
+ const arg = args[i2];
95
+ if (arg.startsWith("--")) {
96
+ const optionName = arg.slice(2);
97
+ const nextArg = args[i2 + 1];
98
+ if (nextArg && !nextArg.startsWith("-")) {
99
+ result.options[optionName] = nextArg;
100
+ i2 += 2;
101
+ } else {
102
+ result.options[optionName] = true;
103
+ i2 += 1;
104
+ }
105
+ } else if (arg.startsWith("-")) {
106
+ const optionName = arg.slice(1);
107
+ result.options[optionName] = true;
108
+ i2 += 1;
109
+ } else {
110
+ result.positional.push(arg);
111
+ i2 += 1;
112
+ }
113
+ }
114
+ return result;
115
+ }
116
+ result.command = args[0];
117
+ let i = 1;
118
+ while (i < args.length) {
119
+ const arg = args[i];
120
+ if (arg.startsWith("--")) {
121
+ const optionName = arg.slice(2);
122
+ const nextArg = args[i + 1];
123
+ if (nextArg && !nextArg.startsWith("-")) {
124
+ result.options[optionName] = nextArg;
125
+ i += 2;
126
+ } else {
127
+ result.options[optionName] = true;
128
+ i += 1;
129
+ }
130
+ } else if (arg.startsWith("-")) {
131
+ const optionName = arg.slice(1);
132
+ result.options[optionName] = true;
133
+ i += 1;
134
+ } else {
135
+ result.positional.push(arg);
136
+ i += 1;
137
+ }
138
+ }
139
+ return result;
140
+ };
141
+ const showHelp = () => {
142
+ console.log(`screw-up - Easy package metadata inserter CLI [${"0.9.1"}]
143
+ Copyright (c) ${"Kouji Matsui (@kekyo@mi.kekyo.net)"}
144
+ Repository: ${"https://github.com/kekyo/screw-up.git"}
145
+ License: ${"MIT"}
146
+
147
+ Usage: screw-up <command> [options]
148
+
149
+ Commands:
150
+ pack [directory] Pack the project into a tar archive
151
+ publish [directory|package.tgz] Publish the project
152
+
153
+ Options:
154
+ -h, --help Show help
155
+
156
+ Pack Options:
157
+ --pack-destination <path> Directory to write the tarball
158
+
159
+ Publish Options:
160
+ All npm publish options are supported (e.g., --dry-run, --tag, --access, --registry)
161
+
162
+ Examples:
163
+ screw-up pack # Pack current directory
164
+ screw-up pack ./my-project # Pack specific directory
165
+ screw-up pack --pack-destination ./dist # Pack to specific output directory
166
+ screw-up publish # Publish current directory
167
+ screw-up publish ./my-project # Publish specific directory
168
+ screw-up publish package.tgz # Publish existing tarball
169
+ screw-up publish --dry-run --tag beta # Publish with npm options
170
+ `);
171
+ };
172
+ const showPackHelp = () => {
173
+ console.log(`Usage: screw-up pack [options] [directory]
174
+
175
+ Pack the project into a tar archive
176
+
177
+ Arguments:
178
+ directory Directory to pack (default: current directory)
179
+
180
+ Options:
181
+ --pack-destination <path> Directory to write the tarball
182
+ -h, --help Show help for pack command
183
+ `);
184
+ };
185
+ const showPublishHelp = () => {
186
+ console.log(`Usage: screw-up publish [options] [directory|package.tgz]
187
+
188
+ Publish the project
189
+
190
+ Arguments:
191
+ directory|package.tgz Directory to pack and publish, or existing tarball to publish
192
+
193
+ Options:
194
+ All npm publish options are supported, including:
195
+ --dry-run Perform a dry run
196
+ --tag <tag> Tag for the published version
197
+ --access <access> Access level (public or restricted)
198
+ --registry <registry> Registry URL
199
+ -h, --help Show help for publish command
200
+
201
+ Examples:
202
+ screw-up publish # Publish current directory
203
+ screw-up publish ./my-project # Publish specific directory
204
+ screw-up publish package.tgz # Publish existing tarball
205
+ screw-up publish --dry-run --tag beta # Publish with options
206
+ `);
207
+ };
208
+ const packCommand = async (args) => {
209
+ if (args.options.help || args.options.h) {
210
+ showPackHelp();
211
+ return;
212
+ }
213
+ const directory = args.positional[0];
214
+ const packDestination = args.options["pack-destination"];
215
+ const targetDir = path.resolve(directory != null ? directory : process.cwd());
216
+ const outputDir = packDestination ? path.resolve(packDestination) : process.cwd();
217
+ console.log(`[screw-up/cli]: pack: Creating archive of ${targetDir}...`);
218
+ try {
219
+ const metadata = await packAssets(targetDir, outputDir);
220
+ if (metadata) {
221
+ console.log(`[screw-up/cli]: pack: Archive created successfully: ${outputDir}`);
222
+ } else {
223
+ console.error(`[screw-up/cli]: pack: Unable to find any files to pack: ${targetDir}`);
224
+ process.exit(1);
225
+ }
226
+ } catch (error) {
227
+ console.error("[screw-up/cli]: pack: Failed to create archive:", error);
228
+ process.exit(1);
229
+ }
230
+ };
231
+ const publishCommand = async (args) => {
232
+ if (args.options.help || args.options.h) {
233
+ showPublishHelp();
234
+ return;
235
+ }
236
+ const runNpmPublish = async (tarballPath, npmOptions2 = []) => {
237
+ console.log(`[screw-up/cli]: publish: Publishing ${tarballPath} to npm...`);
238
+ const publishArgs = ["publish", tarballPath, ...npmOptions2];
239
+ if (process.env.SCREW_UP_TEST_MODE === "true") {
240
+ console.log(`[screw-up/cli]: TEST_MODE: Would execute: npm ${publishArgs.join(" ")}`);
241
+ console.log(`[screw-up/cli]: TEST_MODE: Tarball path: ${tarballPath}`);
242
+ console.log(`[screw-up/cli]: TEST_MODE: Options: ${npmOptions2.join(" ")}`);
243
+ console.log(`[screw-up/cli]: publish: Successfully published ${tarballPath}`);
244
+ return;
245
+ }
246
+ const npmProcess = child_process.spawn("npm", publishArgs, { stdio: "inherit" });
247
+ return new Promise((resolve2, reject) => {
248
+ npmProcess.on("close", (code) => {
249
+ if (code === 0) {
250
+ console.log(`[screw-up/cli]: publish: Successfully published ${tarballPath}`);
251
+ resolve2();
252
+ } else {
253
+ reject(new Error(`npm publish failed with exit code ${code}`));
254
+ }
255
+ });
256
+ npmProcess.on("error", reject);
257
+ });
258
+ };
259
+ const path$1 = args.positional[0];
260
+ const npmOptions = [];
261
+ Object.entries(args.options).forEach(([key, value]) => {
262
+ if (key === "help" || key === "h") return;
263
+ if (value === true) {
264
+ npmOptions.push(`--${key}`);
265
+ } else {
266
+ npmOptions.push(`--${key}`, value);
267
+ }
268
+ });
269
+ try {
270
+ if (!path$1) {
271
+ const targetDir = process.cwd();
272
+ const outputDir = await promises.mkdtemp("screw-up-publish-");
273
+ console.log(`[screw-up/cli]: publish: Creating archive of ${targetDir}...`);
274
+ try {
275
+ const metadata = await packAssets(targetDir, outputDir);
276
+ if (metadata) {
277
+ const archiveName = `${metadata.name}-${metadata.version}.tgz`;
278
+ const archivePath = path.join(outputDir, archiveName);
279
+ await runNpmPublish(archivePath, npmOptions);
280
+ } else {
281
+ console.error(`[screw-up/cli]: publish: Unable to find any files to pack: ${targetDir}`);
282
+ process.exit(1);
283
+ }
284
+ } finally {
285
+ await promises.rm(outputDir, { recursive: true, force: true });
286
+ }
287
+ } else if (fs.existsSync(path$1)) {
288
+ const pathStat = await promises.stat(path$1);
289
+ if (pathStat.isFile() && (path$1.endsWith(".tgz") || path$1.endsWith(".tar.gz"))) {
290
+ await runNpmPublish(path.resolve(path$1), npmOptions);
291
+ } else if (pathStat.isDirectory()) {
292
+ const targetDir = path.resolve(path$1);
293
+ const outputDir = await promises.mkdtemp("screw-up-publish-");
294
+ console.log(`[screw-up/cli]: publish: Creating archive of ${targetDir}...`);
295
+ try {
296
+ const metadata = await packAssets(targetDir, outputDir);
297
+ if (metadata) {
298
+ const archiveName = `${metadata.name}-${metadata.version}.tgz`;
299
+ const archivePath = path.join(outputDir, archiveName);
300
+ await runNpmPublish(archivePath, npmOptions);
301
+ } else {
302
+ console.error(`[screw-up/cli]: publish: Unable to find any files to pack: ${targetDir}`);
303
+ process.exit(1);
304
+ }
305
+ } finally {
306
+ await promises.rm(outputDir, { recursive: true, force: true });
307
+ }
308
+ } else {
309
+ console.error(`[screw-up/cli]: publish: Invalid path - must be a directory or .tgz/.tar.gz file: ${path$1}`);
310
+ process.exit(1);
311
+ }
312
+ } else {
313
+ console.error(`[screw-up/cli]: publish: Path does not exist: ${path$1}`);
314
+ process.exit(1);
315
+ }
316
+ } catch (error) {
317
+ console.error("[screw-up/cli]: publish: Failed to publish:", error);
318
+ process.exit(1);
319
+ }
320
+ };
321
+ const main = async () => {
322
+ const args = parseArgs(process.argv);
323
+ if (args.options.help || args.options.h || !args.command || args.command === "help" || args.command === "--help") {
324
+ showHelp();
325
+ return;
326
+ }
327
+ switch (args.command) {
328
+ case "pack":
329
+ await packCommand(args);
330
+ break;
331
+ case "publish":
332
+ await publishCommand(args);
333
+ break;
334
+ default:
335
+ console.error(`Unknown command: ${args.command}`);
336
+ console.error('Run "screw-up --help" for usage information.');
337
+ process.exit(1);
338
+ }
339
+ };
340
+ main().catch((error) => {
341
+ console.error("CLI error:", error);
342
+ process.exit(1);
343
+ });
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,342 @@
1
+ #!/usr/bin/env node
2
+ import { resolve, join } from "path";
3
+ import { existsSync, createWriteStream, createReadStream } from "fs";
4
+ import { lstat, mkdir, mkdtemp, rm, stat } from "fs/promises";
5
+ import { spawn } from "child_process";
6
+ import { glob } from "glob";
7
+ import { a as resolveRawPackageJson } from "./internal-JwF_Mrdt.js";
8
+ import tar from "tar-stream";
9
+ import zlib from "zlib";
10
+ const addPackContentEntry = async (pack, name, content) => {
11
+ pack.entry({
12
+ name,
13
+ type: "file",
14
+ mode: 420,
15
+ mtime: /* @__PURE__ */ new Date(),
16
+ size: Buffer.byteLength(content, "utf8")
17
+ }, content);
18
+ };
19
+ const addPackFileEntry = async (pack, baseDir, path, stat2) => {
20
+ const writer = pack.entry({
21
+ name: path,
22
+ mode: stat2.mode,
23
+ mtime: stat2.mtime,
24
+ size: stat2.size
25
+ });
26
+ const stream = createReadStream(resolve(baseDir, path));
27
+ stream.pipe(writer);
28
+ return new Promise((resolve2, reject) => {
29
+ stream.on("end", resolve2);
30
+ stream.on("error", reject);
31
+ writer.on("error", reject);
32
+ });
33
+ };
34
+ const packAssets = async (targetDir, outputDir) => {
35
+ var _a, _b, _c, _d;
36
+ if (!existsSync(targetDir)) {
37
+ return void 0;
38
+ }
39
+ let resolvedPackageJson;
40
+ try {
41
+ resolvedPackageJson = await resolveRawPackageJson(targetDir);
42
+ } catch (error) {
43
+ return void 0;
44
+ }
45
+ if (resolvedPackageJson == null ? void 0 : resolvedPackageJson.private) {
46
+ return void 0;
47
+ }
48
+ const outputFileName = `${(_b = (_a = resolvedPackageJson == null ? void 0 : resolvedPackageJson.name) == null ? void 0 : _a.replace("/", "-")) != null ? _b : "package"}-${(_c = resolvedPackageJson == null ? void 0 : resolvedPackageJson.version) != null ? _c : "0.0.0"}.tgz`;
49
+ const pack = tar.pack();
50
+ try {
51
+ const packageJsonContent = JSON.stringify(resolvedPackageJson, null, 2);
52
+ await addPackContentEntry(pack, "package.json", packageJsonContent);
53
+ const distributionFileGlobs = (_d = resolvedPackageJson == null ? void 0 : resolvedPackageJson.files) != null ? _d : ["**/*"];
54
+ const packingFilePaths = distributionFileGlobs.map((fg) => glob.sync(fg, { cwd: targetDir })).flat();
55
+ for (const packingFilePath of packingFilePaths) {
56
+ const fullPath = resolve(targetDir, packingFilePath);
57
+ const stat2 = await lstat(fullPath);
58
+ if (stat2.isFile() && packingFilePath !== "package.json") {
59
+ await addPackFileEntry(pack, targetDir, packingFilePath, stat2);
60
+ }
61
+ }
62
+ pack.finalize();
63
+ if (!existsSync(outputDir)) {
64
+ await mkdir(outputDir, { recursive: true });
65
+ }
66
+ const outputFile = resolve(outputDir, outputFileName);
67
+ const outputStream = createWriteStream(outputFile);
68
+ const gzip = zlib.createGzip();
69
+ await new Promise((resolve2, reject) => {
70
+ pack.pipe(gzip).pipe(outputStream);
71
+ outputStream.on("finish", () => resolve2());
72
+ outputStream.on("error", reject);
73
+ pack.on("error", reject);
74
+ gzip.on("error", reject);
75
+ });
76
+ } finally {
77
+ pack.destroy();
78
+ }
79
+ return resolvedPackageJson;
80
+ };
81
+ const parseArgs = (argv) => {
82
+ const args = argv.slice(2);
83
+ const result = {
84
+ positional: [],
85
+ options: {}
86
+ };
87
+ if (args.length === 0) {
88
+ return result;
89
+ }
90
+ if (args[0].startsWith("-")) {
91
+ let i2 = 0;
92
+ while (i2 < args.length) {
93
+ const arg = args[i2];
94
+ if (arg.startsWith("--")) {
95
+ const optionName = arg.slice(2);
96
+ const nextArg = args[i2 + 1];
97
+ if (nextArg && !nextArg.startsWith("-")) {
98
+ result.options[optionName] = nextArg;
99
+ i2 += 2;
100
+ } else {
101
+ result.options[optionName] = true;
102
+ i2 += 1;
103
+ }
104
+ } else if (arg.startsWith("-")) {
105
+ const optionName = arg.slice(1);
106
+ result.options[optionName] = true;
107
+ i2 += 1;
108
+ } else {
109
+ result.positional.push(arg);
110
+ i2 += 1;
111
+ }
112
+ }
113
+ return result;
114
+ }
115
+ result.command = args[0];
116
+ let i = 1;
117
+ while (i < args.length) {
118
+ const arg = args[i];
119
+ if (arg.startsWith("--")) {
120
+ const optionName = arg.slice(2);
121
+ const nextArg = args[i + 1];
122
+ if (nextArg && !nextArg.startsWith("-")) {
123
+ result.options[optionName] = nextArg;
124
+ i += 2;
125
+ } else {
126
+ result.options[optionName] = true;
127
+ i += 1;
128
+ }
129
+ } else if (arg.startsWith("-")) {
130
+ const optionName = arg.slice(1);
131
+ result.options[optionName] = true;
132
+ i += 1;
133
+ } else {
134
+ result.positional.push(arg);
135
+ i += 1;
136
+ }
137
+ }
138
+ return result;
139
+ };
140
+ const showHelp = () => {
141
+ console.log(`screw-up - Easy package metadata inserter CLI [${"0.9.1"}]
142
+ Copyright (c) ${"Kouji Matsui (@kekyo@mi.kekyo.net)"}
143
+ Repository: ${"https://github.com/kekyo/screw-up.git"}
144
+ License: ${"MIT"}
145
+
146
+ Usage: screw-up <command> [options]
147
+
148
+ Commands:
149
+ pack [directory] Pack the project into a tar archive
150
+ publish [directory|package.tgz] Publish the project
151
+
152
+ Options:
153
+ -h, --help Show help
154
+
155
+ Pack Options:
156
+ --pack-destination <path> Directory to write the tarball
157
+
158
+ Publish Options:
159
+ All npm publish options are supported (e.g., --dry-run, --tag, --access, --registry)
160
+
161
+ Examples:
162
+ screw-up pack # Pack current directory
163
+ screw-up pack ./my-project # Pack specific directory
164
+ screw-up pack --pack-destination ./dist # Pack to specific output directory
165
+ screw-up publish # Publish current directory
166
+ screw-up publish ./my-project # Publish specific directory
167
+ screw-up publish package.tgz # Publish existing tarball
168
+ screw-up publish --dry-run --tag beta # Publish with npm options
169
+ `);
170
+ };
171
+ const showPackHelp = () => {
172
+ console.log(`Usage: screw-up pack [options] [directory]
173
+
174
+ Pack the project into a tar archive
175
+
176
+ Arguments:
177
+ directory Directory to pack (default: current directory)
178
+
179
+ Options:
180
+ --pack-destination <path> Directory to write the tarball
181
+ -h, --help Show help for pack command
182
+ `);
183
+ };
184
+ const showPublishHelp = () => {
185
+ console.log(`Usage: screw-up publish [options] [directory|package.tgz]
186
+
187
+ Publish the project
188
+
189
+ Arguments:
190
+ directory|package.tgz Directory to pack and publish, or existing tarball to publish
191
+
192
+ Options:
193
+ All npm publish options are supported, including:
194
+ --dry-run Perform a dry run
195
+ --tag <tag> Tag for the published version
196
+ --access <access> Access level (public or restricted)
197
+ --registry <registry> Registry URL
198
+ -h, --help Show help for publish command
199
+
200
+ Examples:
201
+ screw-up publish # Publish current directory
202
+ screw-up publish ./my-project # Publish specific directory
203
+ screw-up publish package.tgz # Publish existing tarball
204
+ screw-up publish --dry-run --tag beta # Publish with options
205
+ `);
206
+ };
207
+ const packCommand = async (args) => {
208
+ if (args.options.help || args.options.h) {
209
+ showPackHelp();
210
+ return;
211
+ }
212
+ const directory = args.positional[0];
213
+ const packDestination = args.options["pack-destination"];
214
+ const targetDir = resolve(directory != null ? directory : process.cwd());
215
+ const outputDir = packDestination ? resolve(packDestination) : process.cwd();
216
+ console.log(`[screw-up/cli]: pack: Creating archive of ${targetDir}...`);
217
+ try {
218
+ const metadata = await packAssets(targetDir, outputDir);
219
+ if (metadata) {
220
+ console.log(`[screw-up/cli]: pack: Archive created successfully: ${outputDir}`);
221
+ } else {
222
+ console.error(`[screw-up/cli]: pack: Unable to find any files to pack: ${targetDir}`);
223
+ process.exit(1);
224
+ }
225
+ } catch (error) {
226
+ console.error("[screw-up/cli]: pack: Failed to create archive:", error);
227
+ process.exit(1);
228
+ }
229
+ };
230
+ const publishCommand = async (args) => {
231
+ if (args.options.help || args.options.h) {
232
+ showPublishHelp();
233
+ return;
234
+ }
235
+ const runNpmPublish = async (tarballPath, npmOptions2 = []) => {
236
+ console.log(`[screw-up/cli]: publish: Publishing ${tarballPath} to npm...`);
237
+ const publishArgs = ["publish", tarballPath, ...npmOptions2];
238
+ if (process.env.SCREW_UP_TEST_MODE === "true") {
239
+ console.log(`[screw-up/cli]: TEST_MODE: Would execute: npm ${publishArgs.join(" ")}`);
240
+ console.log(`[screw-up/cli]: TEST_MODE: Tarball path: ${tarballPath}`);
241
+ console.log(`[screw-up/cli]: TEST_MODE: Options: ${npmOptions2.join(" ")}`);
242
+ console.log(`[screw-up/cli]: publish: Successfully published ${tarballPath}`);
243
+ return;
244
+ }
245
+ const npmProcess = spawn("npm", publishArgs, { stdio: "inherit" });
246
+ return new Promise((resolve2, reject) => {
247
+ npmProcess.on("close", (code) => {
248
+ if (code === 0) {
249
+ console.log(`[screw-up/cli]: publish: Successfully published ${tarballPath}`);
250
+ resolve2();
251
+ } else {
252
+ reject(new Error(`npm publish failed with exit code ${code}`));
253
+ }
254
+ });
255
+ npmProcess.on("error", reject);
256
+ });
257
+ };
258
+ const path = args.positional[0];
259
+ const npmOptions = [];
260
+ Object.entries(args.options).forEach(([key, value]) => {
261
+ if (key === "help" || key === "h") return;
262
+ if (value === true) {
263
+ npmOptions.push(`--${key}`);
264
+ } else {
265
+ npmOptions.push(`--${key}`, value);
266
+ }
267
+ });
268
+ try {
269
+ if (!path) {
270
+ const targetDir = process.cwd();
271
+ const outputDir = await mkdtemp("screw-up-publish-");
272
+ console.log(`[screw-up/cli]: publish: Creating archive of ${targetDir}...`);
273
+ try {
274
+ const metadata = await packAssets(targetDir, outputDir);
275
+ if (metadata) {
276
+ const archiveName = `${metadata.name}-${metadata.version}.tgz`;
277
+ const archivePath = join(outputDir, archiveName);
278
+ await runNpmPublish(archivePath, npmOptions);
279
+ } else {
280
+ console.error(`[screw-up/cli]: publish: Unable to find any files to pack: ${targetDir}`);
281
+ process.exit(1);
282
+ }
283
+ } finally {
284
+ await rm(outputDir, { recursive: true, force: true });
285
+ }
286
+ } else if (existsSync(path)) {
287
+ const pathStat = await stat(path);
288
+ if (pathStat.isFile() && (path.endsWith(".tgz") || path.endsWith(".tar.gz"))) {
289
+ await runNpmPublish(resolve(path), npmOptions);
290
+ } else if (pathStat.isDirectory()) {
291
+ const targetDir = resolve(path);
292
+ const outputDir = await mkdtemp("screw-up-publish-");
293
+ console.log(`[screw-up/cli]: publish: Creating archive of ${targetDir}...`);
294
+ try {
295
+ const metadata = await packAssets(targetDir, outputDir);
296
+ if (metadata) {
297
+ const archiveName = `${metadata.name}-${metadata.version}.tgz`;
298
+ const archivePath = join(outputDir, archiveName);
299
+ await runNpmPublish(archivePath, npmOptions);
300
+ } else {
301
+ console.error(`[screw-up/cli]: publish: Unable to find any files to pack: ${targetDir}`);
302
+ process.exit(1);
303
+ }
304
+ } finally {
305
+ await rm(outputDir, { recursive: true, force: true });
306
+ }
307
+ } else {
308
+ console.error(`[screw-up/cli]: publish: Invalid path - must be a directory or .tgz/.tar.gz file: ${path}`);
309
+ process.exit(1);
310
+ }
311
+ } else {
312
+ console.error(`[screw-up/cli]: publish: Path does not exist: ${path}`);
313
+ process.exit(1);
314
+ }
315
+ } catch (error) {
316
+ console.error("[screw-up/cli]: publish: Failed to publish:", error);
317
+ process.exit(1);
318
+ }
319
+ };
320
+ const main = async () => {
321
+ const args = parseArgs(process.argv);
322
+ if (args.options.help || args.options.h || !args.command || args.command === "help" || args.command === "--help") {
323
+ showHelp();
324
+ return;
325
+ }
326
+ switch (args.command) {
327
+ case "pack":
328
+ await packCommand(args);
329
+ break;
330
+ case "publish":
331
+ await publishCommand(args);
332
+ break;
333
+ default:
334
+ console.error(`Unknown command: ${args.command}`);
335
+ console.error('Run "screw-up --help" for usage information.');
336
+ process.exit(1);
337
+ }
338
+ };
339
+ main().catch((error) => {
340
+ console.error("CLI error:", error);
341
+ process.exit(1);
342
+ });
package/dist/index.cjs CHANGED
@@ -1,85 +1,8 @@
1
1
  "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
2
3
  const promises = require("fs/promises");
3
4
  const path = require("path");
4
- const fs = require("fs");
5
- const flattenObject = (obj, prefix, map) => {
6
- for (const [key, value] of Object.entries(obj)) {
7
- if (!value)
8
- continue;
9
- const fullKey = prefix ? `${prefix}.${key}` : key;
10
- if (typeof value === "string") {
11
- map[fullKey] = value;
12
- } else if (Array.isArray(value)) {
13
- map[fullKey] = value.map((v) => String(v)).join(",");
14
- } else if (typeof value === "object") {
15
- flattenObject(value, fullKey, map);
16
- } else {
17
- map[fullKey] = String(value);
18
- }
19
- }
20
- };
21
- const readPackageMetadata = async (packagePath) => {
22
- try {
23
- const content = await promises.readFile(packagePath, "utf-8");
24
- const json = JSON.parse(content);
25
- const map = {};
26
- flattenObject(json, "", map);
27
- return map;
28
- } catch (error) {
29
- console.warn(`Failed to read package.json from ${packagePath}:`, error);
30
- return {};
31
- }
32
- };
33
- const findWorkspaceRoot = async (startPath) => {
34
- let currentPath = startPath;
35
- while (currentPath !== path.dirname(currentPath)) {
36
- const packageJsonPath = path.join(currentPath, "package.json");
37
- if (fs.existsSync(packageJsonPath)) {
38
- try {
39
- const content = await promises.readFile(packageJsonPath, "utf-8");
40
- const packageJson = JSON.parse(content);
41
- if (packageJson.workspaces || fs.existsSync(path.join(currentPath, "pnpm-workspace.yaml")) || fs.existsSync(path.join(currentPath, "lerna.json"))) {
42
- return currentPath;
43
- }
44
- } catch (error) {
45
- console.warn(`Failed to parse package.json at ${packageJsonPath}:`, error);
46
- }
47
- }
48
- currentPath = path.dirname(currentPath);
49
- }
50
- return void 0;
51
- };
52
- const mergePackageMetadata = (parentMetadata, childMetadata) => {
53
- const merged = {};
54
- for (const key in parentMetadata) {
55
- const value = parentMetadata[key];
56
- if (value !== void 0) {
57
- merged[key] = value;
58
- }
59
- }
60
- for (const key in childMetadata) {
61
- const value = childMetadata[key];
62
- if (value !== void 0) {
63
- merged[key] = value;
64
- }
65
- }
66
- return merged;
67
- };
68
- const resolvePackageMetadata = async (projectRoot) => {
69
- const workspaceRoot = await findWorkspaceRoot(projectRoot);
70
- if (!workspaceRoot) {
71
- const localPackagePath = path.join(projectRoot, "package.json");
72
- return await readPackageMetadata(localPackagePath);
73
- }
74
- const projectPackagePath = path.join(projectRoot, "package.json");
75
- const rootPackagePath = path.join(workspaceRoot, "package.json");
76
- let metadata = await readPackageMetadata(rootPackagePath);
77
- if (projectPackagePath !== rootPackagePath && fs.existsSync(projectPackagePath)) {
78
- const projectMetadata = await readPackageMetadata(projectPackagePath);
79
- metadata = mergePackageMetadata(metadata, projectMetadata);
80
- }
81
- return metadata;
82
- };
5
+ const internal = require("./internal-BJ2gdqpB.cjs");
83
6
  const generateBanner = (metadata, outputKeys) => {
84
7
  const parts = [];
85
8
  for (const key of outputKeys) {
@@ -136,7 +59,7 @@ const screwUp = (options = {}) => {
136
59
  apply: "build",
137
60
  async configResolved(config) {
138
61
  projectRoot = config.root;
139
- metadata = await resolvePackageMetadata(config.root);
62
+ metadata = await internal.resolvePackageMetadata(config.root);
140
63
  banner = generateBanner(metadata, outputKeys);
141
64
  },
142
65
  async buildStart() {
@@ -184,4 +107,5 @@ const screwUp = (options = {}) => {
184
107
  }
185
108
  };
186
109
  };
187
- module.exports = screwUp;
110
+ exports.default = screwUp;
111
+ exports.generateBanner = generateBanner;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,13 @@
1
1
  import { Plugin } from 'vite';
2
+ import { PackageMetadata } from './internal.js';
2
3
 
4
+ /**
5
+ * Generate banner string from package.json metadata
6
+ * @param metadata - Package metadata
7
+ * @param outputKeys - Array of keys to output in specified order
8
+ * @returns Banner string
9
+ */
10
+ export declare const generateBanner: (metadata: PackageMetadata, outputKeys: string[]) => string;
3
11
  /**
4
12
  * screw-up options
5
13
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAKnC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED;;;;GAIG;AACH,QAAA,MAAM,OAAO,GAAI,UAAS,cAAmB,KAAG,MAiF/C,CAAC;AAEF,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAGnC,OAAO,EAAE,eAAe,EAA0B,MAAM,eAAe,CAAC;AAExE;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,UAAU,eAAe,EAAE,YAAY,MAAM,EAAE,KAAG,MAWhF,CAAC;AA4DF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED;;;;GAIG;AACH,QAAA,MAAM,OAAO,GAAI,UAAS,cAAmB,KAAG,MAiF/C,CAAC;AAEF,eAAe,OAAO,CAAC"}
package/dist/index.js CHANGED
@@ -1,84 +1,6 @@
1
- import { readFile, readdir, writeFile, mkdir } from "fs/promises";
1
+ import { readdir, readFile, writeFile, mkdir } from "fs/promises";
2
2
  import { join, dirname } from "path";
3
- import { existsSync } from "fs";
4
- const flattenObject = (obj, prefix, map) => {
5
- for (const [key, value] of Object.entries(obj)) {
6
- if (!value)
7
- continue;
8
- const fullKey = prefix ? `${prefix}.${key}` : key;
9
- if (typeof value === "string") {
10
- map[fullKey] = value;
11
- } else if (Array.isArray(value)) {
12
- map[fullKey] = value.map((v) => String(v)).join(",");
13
- } else if (typeof value === "object") {
14
- flattenObject(value, fullKey, map);
15
- } else {
16
- map[fullKey] = String(value);
17
- }
18
- }
19
- };
20
- const readPackageMetadata = async (packagePath) => {
21
- try {
22
- const content = await readFile(packagePath, "utf-8");
23
- const json = JSON.parse(content);
24
- const map = {};
25
- flattenObject(json, "", map);
26
- return map;
27
- } catch (error) {
28
- console.warn(`Failed to read package.json from ${packagePath}:`, error);
29
- return {};
30
- }
31
- };
32
- const findWorkspaceRoot = async (startPath) => {
33
- let currentPath = startPath;
34
- while (currentPath !== dirname(currentPath)) {
35
- const packageJsonPath = join(currentPath, "package.json");
36
- if (existsSync(packageJsonPath)) {
37
- try {
38
- const content = await readFile(packageJsonPath, "utf-8");
39
- const packageJson = JSON.parse(content);
40
- if (packageJson.workspaces || existsSync(join(currentPath, "pnpm-workspace.yaml")) || existsSync(join(currentPath, "lerna.json"))) {
41
- return currentPath;
42
- }
43
- } catch (error) {
44
- console.warn(`Failed to parse package.json at ${packageJsonPath}:`, error);
45
- }
46
- }
47
- currentPath = dirname(currentPath);
48
- }
49
- return void 0;
50
- };
51
- const mergePackageMetadata = (parentMetadata, childMetadata) => {
52
- const merged = {};
53
- for (const key in parentMetadata) {
54
- const value = parentMetadata[key];
55
- if (value !== void 0) {
56
- merged[key] = value;
57
- }
58
- }
59
- for (const key in childMetadata) {
60
- const value = childMetadata[key];
61
- if (value !== void 0) {
62
- merged[key] = value;
63
- }
64
- }
65
- return merged;
66
- };
67
- const resolvePackageMetadata = async (projectRoot) => {
68
- const workspaceRoot = await findWorkspaceRoot(projectRoot);
69
- if (!workspaceRoot) {
70
- const localPackagePath = join(projectRoot, "package.json");
71
- return await readPackageMetadata(localPackagePath);
72
- }
73
- const projectPackagePath = join(projectRoot, "package.json");
74
- const rootPackagePath = join(workspaceRoot, "package.json");
75
- let metadata = await readPackageMetadata(rootPackagePath);
76
- if (projectPackagePath !== rootPackagePath && existsSync(projectPackagePath)) {
77
- const projectMetadata = await readPackageMetadata(projectPackagePath);
78
- metadata = mergePackageMetadata(metadata, projectMetadata);
79
- }
80
- return metadata;
81
- };
3
+ import { r as resolvePackageMetadata } from "./internal-JwF_Mrdt.js";
82
4
  const generateBanner = (metadata, outputKeys) => {
83
5
  const parts = [];
84
6
  for (const key of outputKeys) {
@@ -184,5 +106,6 @@ const screwUp = (options = {}) => {
184
106
  };
185
107
  };
186
108
  export {
187
- screwUp as default
109
+ screwUp as default,
110
+ generateBanner
188
111
  };
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ const fs = require("fs");
3
+ const promises = require("fs/promises");
4
+ const path = require("path");
5
+ const flattenObject = (obj, prefix, map) => {
6
+ for (const [key, value] of Object.entries(obj)) {
7
+ if (!value)
8
+ continue;
9
+ const fullKey = prefix ? `${prefix}.${key}` : key;
10
+ if (typeof value === "string") {
11
+ map[fullKey] = value;
12
+ } else if (Array.isArray(value)) {
13
+ map[fullKey] = value.map((v) => String(v)).join(",");
14
+ } else if (typeof value === "object") {
15
+ flattenObject(value, fullKey, map);
16
+ } else {
17
+ map[fullKey] = String(value);
18
+ }
19
+ }
20
+ };
21
+ const readPackageMetadata = async (packagePath) => {
22
+ try {
23
+ const content = await promises.readFile(packagePath, "utf-8");
24
+ const json = JSON.parse(content);
25
+ const map = {};
26
+ flattenObject(json, "", map);
27
+ return map;
28
+ } catch (error) {
29
+ console.warn(`Failed to read package.json from ${packagePath}:`, error);
30
+ return {};
31
+ }
32
+ };
33
+ const findWorkspaceRoot = async (startPath) => {
34
+ let currentPath = startPath;
35
+ while (currentPath !== path.dirname(currentPath)) {
36
+ const packageJsonPath = path.join(currentPath, "package.json");
37
+ if (fs.existsSync(packageJsonPath)) {
38
+ try {
39
+ const content = await promises.readFile(packageJsonPath, "utf-8");
40
+ const packageJson = JSON.parse(content);
41
+ if (packageJson.workspaces || fs.existsSync(path.join(currentPath, "pnpm-workspace.yaml")) || fs.existsSync(path.join(currentPath, "lerna.json"))) {
42
+ return currentPath;
43
+ }
44
+ } catch (error) {
45
+ console.warn(`Failed to parse package.json at ${packageJsonPath}:`, error);
46
+ }
47
+ }
48
+ currentPath = path.dirname(currentPath);
49
+ }
50
+ return void 0;
51
+ };
52
+ const mergePackageMetadata = (parentMetadata, childMetadata) => {
53
+ const merged = {};
54
+ for (const key in parentMetadata) {
55
+ const value = parentMetadata[key];
56
+ if (value !== void 0) {
57
+ merged[key] = value;
58
+ }
59
+ }
60
+ for (const key in childMetadata) {
61
+ const value = childMetadata[key];
62
+ if (value !== void 0) {
63
+ merged[key] = value;
64
+ }
65
+ }
66
+ return merged;
67
+ };
68
+ const resolvePackageMetadataT = async (projectRoot, readPackageMetadataFn, mergePackageMetadataFn) => {
69
+ const workspaceRoot = await findWorkspaceRoot(projectRoot);
70
+ if (!workspaceRoot) {
71
+ const localPackagePath = path.join(projectRoot, "package.json");
72
+ return await readPackageMetadataFn(localPackagePath);
73
+ }
74
+ const projectPackagePath = path.join(projectRoot, "package.json");
75
+ const rootPackagePath = path.join(workspaceRoot, "package.json");
76
+ const metadata = await readPackageMetadataFn(rootPackagePath);
77
+ if (projectPackagePath !== rootPackagePath && fs.existsSync(projectPackagePath)) {
78
+ const projectMetadata = await readPackageMetadataFn(projectPackagePath);
79
+ return mergePackageMetadataFn(metadata, projectMetadata);
80
+ } else {
81
+ return metadata;
82
+ }
83
+ };
84
+ const readRawPackageJson = async (packagePath) => {
85
+ try {
86
+ const content = await promises.readFile(packagePath, "utf-8");
87
+ return JSON.parse(content);
88
+ } catch (error) {
89
+ console.error(`Failed to read package.json from ${packagePath}:`, error);
90
+ throw error;
91
+ }
92
+ };
93
+ const mergeRawPackageJson = (parentPackage, childPackage) => {
94
+ const inheritableFields = [
95
+ "version",
96
+ "description",
97
+ "author",
98
+ "license",
99
+ "repository",
100
+ "keywords",
101
+ "homepage",
102
+ "bugs"
103
+ ];
104
+ const merged = { ...childPackage };
105
+ for (const field of inheritableFields) {
106
+ if (parentPackage[field] && !merged[field]) {
107
+ merged[field] = parentPackage[field];
108
+ }
109
+ }
110
+ return merged;
111
+ };
112
+ const resolvePackageMetadata = (projectRoot) => {
113
+ return resolvePackageMetadataT(projectRoot, readPackageMetadata, mergePackageMetadata);
114
+ };
115
+ const resolveRawPackageJson = (projectRoot) => {
116
+ return resolvePackageMetadataT(projectRoot, readRawPackageJson, mergeRawPackageJson);
117
+ };
118
+ exports.resolvePackageMetadata = resolvePackageMetadata;
119
+ exports.resolveRawPackageJson = resolveRawPackageJson;
@@ -0,0 +1,120 @@
1
+ import { existsSync } from "fs";
2
+ import { readFile } from "fs/promises";
3
+ import { join, dirname } from "path";
4
+ const flattenObject = (obj, prefix, map) => {
5
+ for (const [key, value] of Object.entries(obj)) {
6
+ if (!value)
7
+ continue;
8
+ const fullKey = prefix ? `${prefix}.${key}` : key;
9
+ if (typeof value === "string") {
10
+ map[fullKey] = value;
11
+ } else if (Array.isArray(value)) {
12
+ map[fullKey] = value.map((v) => String(v)).join(",");
13
+ } else if (typeof value === "object") {
14
+ flattenObject(value, fullKey, map);
15
+ } else {
16
+ map[fullKey] = String(value);
17
+ }
18
+ }
19
+ };
20
+ const readPackageMetadata = async (packagePath) => {
21
+ try {
22
+ const content = await readFile(packagePath, "utf-8");
23
+ const json = JSON.parse(content);
24
+ const map = {};
25
+ flattenObject(json, "", map);
26
+ return map;
27
+ } catch (error) {
28
+ console.warn(`Failed to read package.json from ${packagePath}:`, error);
29
+ return {};
30
+ }
31
+ };
32
+ const findWorkspaceRoot = async (startPath) => {
33
+ let currentPath = startPath;
34
+ while (currentPath !== dirname(currentPath)) {
35
+ const packageJsonPath = join(currentPath, "package.json");
36
+ if (existsSync(packageJsonPath)) {
37
+ try {
38
+ const content = await readFile(packageJsonPath, "utf-8");
39
+ const packageJson = JSON.parse(content);
40
+ if (packageJson.workspaces || existsSync(join(currentPath, "pnpm-workspace.yaml")) || existsSync(join(currentPath, "lerna.json"))) {
41
+ return currentPath;
42
+ }
43
+ } catch (error) {
44
+ console.warn(`Failed to parse package.json at ${packageJsonPath}:`, error);
45
+ }
46
+ }
47
+ currentPath = dirname(currentPath);
48
+ }
49
+ return void 0;
50
+ };
51
+ const mergePackageMetadata = (parentMetadata, childMetadata) => {
52
+ const merged = {};
53
+ for (const key in parentMetadata) {
54
+ const value = parentMetadata[key];
55
+ if (value !== void 0) {
56
+ merged[key] = value;
57
+ }
58
+ }
59
+ for (const key in childMetadata) {
60
+ const value = childMetadata[key];
61
+ if (value !== void 0) {
62
+ merged[key] = value;
63
+ }
64
+ }
65
+ return merged;
66
+ };
67
+ const resolvePackageMetadataT = async (projectRoot, readPackageMetadataFn, mergePackageMetadataFn) => {
68
+ const workspaceRoot = await findWorkspaceRoot(projectRoot);
69
+ if (!workspaceRoot) {
70
+ const localPackagePath = join(projectRoot, "package.json");
71
+ return await readPackageMetadataFn(localPackagePath);
72
+ }
73
+ const projectPackagePath = join(projectRoot, "package.json");
74
+ const rootPackagePath = join(workspaceRoot, "package.json");
75
+ const metadata = await readPackageMetadataFn(rootPackagePath);
76
+ if (projectPackagePath !== rootPackagePath && existsSync(projectPackagePath)) {
77
+ const projectMetadata = await readPackageMetadataFn(projectPackagePath);
78
+ return mergePackageMetadataFn(metadata, projectMetadata);
79
+ } else {
80
+ return metadata;
81
+ }
82
+ };
83
+ const readRawPackageJson = async (packagePath) => {
84
+ try {
85
+ const content = await readFile(packagePath, "utf-8");
86
+ return JSON.parse(content);
87
+ } catch (error) {
88
+ console.error(`Failed to read package.json from ${packagePath}:`, error);
89
+ throw error;
90
+ }
91
+ };
92
+ const mergeRawPackageJson = (parentPackage, childPackage) => {
93
+ const inheritableFields = [
94
+ "version",
95
+ "description",
96
+ "author",
97
+ "license",
98
+ "repository",
99
+ "keywords",
100
+ "homepage",
101
+ "bugs"
102
+ ];
103
+ const merged = { ...childPackage };
104
+ for (const field of inheritableFields) {
105
+ if (parentPackage[field] && !merged[field]) {
106
+ merged[field] = parentPackage[field];
107
+ }
108
+ }
109
+ return merged;
110
+ };
111
+ const resolvePackageMetadata = (projectRoot) => {
112
+ return resolvePackageMetadataT(projectRoot, readPackageMetadata, mergePackageMetadata);
113
+ };
114
+ const resolveRawPackageJson = (projectRoot) => {
115
+ return resolvePackageMetadataT(projectRoot, readRawPackageJson, mergeRawPackageJson);
116
+ };
117
+ export {
118
+ resolveRawPackageJson as a,
119
+ resolvePackageMetadata as r
120
+ };
@@ -19,30 +19,29 @@ export declare const findWorkspaceRoot: (startPath: string) => Promise<string |
19
19
  */
20
20
  export declare const mergePackageMetadata: (parentMetadata: PackageMetadata, childMetadata: PackageMetadata) => PackageMetadata;
21
21
  /**
22
- * Resolve package metadata for current project with workspace inheritance
23
- * @param projectRoot - Current project root
24
- * @returns Promise resolving to resolved package metadata
22
+ * Read and parse package.json file without flattening
23
+ * @param packagePath - Path to package.json
24
+ * @returns Promise resolving to raw package object
25
25
  */
26
- export declare const resolvePackageMetadata: (projectRoot: string) => Promise<PackageMetadata>;
26
+ export declare const readRawPackageJson: (packagePath: string) => Promise<any>;
27
27
  /**
28
- * Generate banner string from package.json metadata
29
- * @param metadata - Package metadata
30
- * @param outputKeys - Array of keys to output in specified order
31
- * @returns Banner string
28
+ * Merge raw package.json objects with inheritance (child overrides parent)
29
+ * Only inherits package metadata fields, not project-specific configurations
30
+ * @param parentPackage - Parent package object
31
+ * @param childPackage - Child package object
32
+ * @returns Merged package object with only metadata fields
32
33
  */
33
- export declare const generateBanner: (metadata: PackageMetadata, outputKeys: string[]) => string;
34
+ export declare const mergeRawPackageJson: (parentPackage: any, childPackage: any) => any;
34
35
  /**
35
- * Insert banner header at appropriate position considering shebang
36
- * @param content - The content to insert banner into
37
- * @param banner - The banner header to insert
38
- * @returns Content with banner header inserted
36
+ * Resolve package metadata for current project with workspace inheritance
37
+ * @param projectRoot - Current project root
38
+ * @returns Promise resolving to resolved package metadata
39
39
  */
40
- export declare const insertBannerHeader: (content: string, banner: string) => string;
40
+ export declare const resolvePackageMetadata: (projectRoot: string) => Promise<PackageMetadata>;
41
41
  /**
42
- * Generate TypeScript metadata file content from package metadata
43
- * @param metadata - Package metadata
44
- * @param outputKeys - Array of keys to output
45
- * @returns TypeScript file content
42
+ * Resolve raw package.json for current project with workspace inheritance
43
+ * @param projectRoot - Current project root
44
+ * @returns Promise resolving to resolved raw package.json object
46
45
  */
47
- export declare const generateMetadataFile: (metadata: PackageMetadata, outputKeys: string[]) => string;
46
+ export declare const resolveRawPackageJson: (projectRoot: string) => Promise<any>;
48
47
  //# sourceMappingURL=internal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AA2BrD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAU,aAAa,MAAM,KAAG,OAAO,CAAC,eAAe,CAWtF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAU,WAAW,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CA0BrF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAC/B,gBAAgB,eAAe,EAC/B,eAAe,eAAe,KAC7B,eAoBF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GAAU,aAAa,MAAM,KAAG,OAAO,CAAC,eAAe,CAsBzF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,UAAU,eAAe,EAAE,YAAY,MAAM,EAAE,KAAG,MAWhF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,EAAE,QAAQ,MAAM,KAAG,MAWpE,CAAC;AAYF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,UAAU,eAAe,EAAE,YAAY,MAAM,EAAE,KAAG,MAmBtF,CAAC"}
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AA2BrD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAU,aAAa,MAAM,KAAG,OAAO,CAAC,eAAe,CAWtF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAU,WAAW,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CA0BrF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAC/B,gBAAgB,eAAe,EAC/B,eAAe,eAAe,KAC7B,eAoBF,CAAC;AAqCF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAU,aAAa,MAAM,KAAG,OAAO,CAAC,GAAG,CAQzE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAAI,eAAe,GAAG,EAAE,cAAc,GAAG,KAAG,GAwB3E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GAAI,aAAa,MAAM,KAAG,OAAO,CAAC,eAAe,CAEnF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,aAAa,MAAM,KAAG,OAAO,CAAC,GAAG,CAEtE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "screw-up",
3
- "version": "0.8.1",
3
+ "version": "0.9.1",
4
4
  "description": "Simply package metadata inserter on Vite plugin",
5
5
  "keywords": [
6
6
  "vite",
@@ -27,20 +27,28 @@
27
27
  "types": "./dist/index.d.ts"
28
28
  }
29
29
  },
30
+ "bin": {
31
+ "screw-up": "./dist/cli.js"
32
+ },
30
33
  "files": [
31
34
  "dist"
32
35
  ],
33
36
  "scripts": {
34
- "build": "rv --npm . && tsc --noEmit && vite build && tsc --emitDeclarationOnly --outDir dist",
35
- "test": "rv --npm . && tsc --noEmit && vitest run"
37
+ "build": "rv --npm . && npm i && vite build",
38
+ "test": "rv --npm . && npm i && npm run build && vitest run"
36
39
  },
37
40
  "peerDependencies": {
41
+ "glob": ">=11.0.0",
42
+ "tar-stream": ">=3.0.0",
38
43
  "vite": ">=5.0.0"
39
44
  },
40
45
  "devDependencies": {
41
- "@types/node": "^20.0.0",
42
- "typescript": "^5.0.0",
43
- "vite-plugin-dts": "^3.0.0",
44
- "vitest": "^1.0.0"
46
+ "@types/node": ">=20.0.0",
47
+ "@types/tar-stream": "^3.1.4",
48
+ "dayjs": "^1.11.13",
49
+ "tar": ">=7.4.0",
50
+ "typescript": ">=5.0.0",
51
+ "vite-plugin-dts": ">=3.0.0",
52
+ "vitest": ">=1.0.0"
45
53
  }
46
54
  }