@olegkuibar/plunk 0.2.0-canary.04ff96f

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +95 -0
  3. package/dist/add-5ZRFUL6Z.mjs +258 -0
  4. package/dist/chokidar-XGAEDN45.mjs +1746 -0
  5. package/dist/chunk-34UXZ622.mjs +98 -0
  6. package/dist/chunk-4O2QOKVO.mjs +1958 -0
  7. package/dist/chunk-CSMZ6DZA.mjs +367 -0
  8. package/dist/chunk-CZM4TNAI.mjs +292 -0
  9. package/dist/chunk-EDUXIQ5W.mjs +1729 -0
  10. package/dist/chunk-GAAB2TLH.mjs +160 -0
  11. package/dist/chunk-HKNM3UWU.mjs +496 -0
  12. package/dist/chunk-I6SN7BBN.mjs +1131 -0
  13. package/dist/chunk-KYDBD2KQ.mjs +39 -0
  14. package/dist/chunk-LKQINKH4.mjs +130 -0
  15. package/dist/chunk-PUSXMPOF.mjs +82 -0
  16. package/dist/chunk-S4HJSJ32.mjs +69 -0
  17. package/dist/chunk-W3C72UKC.mjs +113 -0
  18. package/dist/chunk-WSECI6M7.mjs +85 -0
  19. package/dist/chunk-XMIZ7OUZ.mjs +26 -0
  20. package/dist/chunk-XZK5T4GK.mjs +23 -0
  21. package/dist/chunk-ZOYNYK5Y.mjs +23 -0
  22. package/dist/chunk-ZQCGJUBJ.mjs +92 -0
  23. package/dist/clean-LTR5MZTY.mjs +84 -0
  24. package/dist/cli.mjs +57 -0
  25. package/dist/dev-LFXQP6SA.mjs +194 -0
  26. package/dist/dist-DUFCZSIL.mjs +813 -0
  27. package/dist/doctor-R7ZVR7PY.mjs +230 -0
  28. package/dist/hash-worker.mjs +65 -0
  29. package/dist/index.d.ts +194 -0
  30. package/dist/index.mjs +9486 -0
  31. package/dist/init-SWCNRISY.mjs +310 -0
  32. package/dist/list-B77L2F34.mjs +119 -0
  33. package/dist/migrate-X5TIC5SS.mjs +124 -0
  34. package/dist/prompt-HTPH6HQ7.mjs +756 -0
  35. package/dist/publish-UXCLPNM6.mjs +63 -0
  36. package/dist/push-JI6HGCFG.mjs +197 -0
  37. package/dist/remove-DCR7KKD5.mjs +149 -0
  38. package/dist/restore-SUN3WGSW.mjs +124 -0
  39. package/dist/status-MESRBH54.mjs +103 -0
  40. package/dist/tailwind-source-JBBEIXIJ.mjs +89 -0
  41. package/dist/update-SKDSA673.mjs +100 -0
  42. package/dist/vite-config-BAK67JHB.mjs +128 -0
  43. package/dist/vite-plugin.d.ts +5 -0
  44. package/dist/vite-plugin.mjs +42 -0
  45. package/dist/workspace-76HJPAK2.mjs +97 -0
  46. package/package.json +96 -0
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ import{createRequire as __cr}from"node:module";globalThis.require=__cr(import.meta.url);
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
10
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
11
+ }) : x)(function(x) {
12
+ if (typeof require !== "undefined") return require.apply(this, arguments);
13
+ throw Error('Dynamic require of "' + x + '" is not supported');
14
+ });
15
+ var __commonJS = (cb, mod) => function __require2() {
16
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
27
+ // If the importer is in node compatibility mode or this is not an ESM
28
+ // file that has been converted to a CommonJS file using a Babel-
29
+ // compatible transform (i.e. "__esModule" has not been set), then set
30
+ // "default" to the CommonJS "module.exports" for node compatibility.
31
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
32
+ mod
33
+ ));
34
+
35
+ export {
36
+ __require,
37
+ __commonJS,
38
+ __toESM
39
+ };
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env node
2
+ import{createRequire as __cr}from"node:module";globalThis.require=__cr(import.meta.url);
3
+ import {
4
+ consola
5
+ } from "./chunk-I6SN7BBN.mjs";
6
+
7
+ // src/core/watcher.ts
8
+ import { spawn } from "child_process";
9
+ import { platform } from "os";
10
+ var activeChild = null;
11
+ var activeWatcher = null;
12
+ function killActiveBuild() {
13
+ if (activeChild && !activeChild.killed) {
14
+ activeChild.kill("SIGTERM");
15
+ activeChild = null;
16
+ }
17
+ }
18
+ async function startWatcher(watchDir, options, onChange) {
19
+ const { watch } = await import("./chokidar-XGAEDN45.mjs");
20
+ const patterns = options.patterns ?? ["src", "lib", "dist"];
21
+ const watchPaths = patterns.map(
22
+ (p) => p.startsWith("/") || p.includes(":") ? p : `${watchDir}/${p}`
23
+ );
24
+ const debounceMs = options.debounce ?? 100;
25
+ let coalesceTimer = null;
26
+ let running = false;
27
+ let pendingWhileRunning = false;
28
+ const scheduleFlush = () => {
29
+ if (coalesceTimer) return;
30
+ coalesceTimer = setTimeout(async () => {
31
+ coalesceTimer = null;
32
+ if (running) {
33
+ pendingWhileRunning = true;
34
+ return;
35
+ }
36
+ running = true;
37
+ try {
38
+ if (options.buildCmd) {
39
+ const success = await runBuildCommand(options.buildCmd, watchDir);
40
+ if (!success) {
41
+ consola.warn("Build failed, skipping push");
42
+ return;
43
+ }
44
+ }
45
+ await onChange();
46
+ } catch (err) {
47
+ consola.error("Push failed:", err);
48
+ } finally {
49
+ running = false;
50
+ if (pendingWhileRunning) {
51
+ pendingWhileRunning = false;
52
+ scheduleFlush();
53
+ }
54
+ }
55
+ }, debounceMs);
56
+ };
57
+ const onFileEvent = (_path) => {
58
+ if (coalesceTimer) {
59
+ clearTimeout(coalesceTimer);
60
+ coalesceTimer = null;
61
+ }
62
+ scheduleFlush();
63
+ };
64
+ const awfOption = options.buildCmd ? false : options.awaitWriteFinish ?? {
65
+ stabilityThreshold: 200,
66
+ pollInterval: 50
67
+ };
68
+ const watcher = watch(watchPaths, {
69
+ ignoreInitial: true,
70
+ ignored: [
71
+ "**/node_modules/**",
72
+ "**/.git/**",
73
+ "**/.plunk/**"
74
+ ],
75
+ awaitWriteFinish: awfOption
76
+ });
77
+ watcher.on("change", onFileEvent);
78
+ watcher.on("add", onFileEvent);
79
+ watcher.on("unlink", onFileEvent);
80
+ const watcherHandle = {
81
+ close: async () => {
82
+ if (coalesceTimer) clearTimeout(coalesceTimer);
83
+ killActiveBuild();
84
+ await watcher.close();
85
+ activeWatcher = null;
86
+ }
87
+ };
88
+ activeWatcher = watcherHandle;
89
+ const cleanup = async () => {
90
+ consola.info("Stopping watcher...");
91
+ await watcherHandle.close();
92
+ process.exit(0);
93
+ };
94
+ process.once("SIGINT", cleanup);
95
+ process.once("SIGTERM", cleanup);
96
+ consola.info(`Watching for changes in: ${patterns.join(", ")}`);
97
+ return watcherHandle;
98
+ }
99
+ function runBuildCommand(cmd, cwd) {
100
+ return new Promise((resolve) => {
101
+ const isWin = platform() === "win32";
102
+ const shell = isWin ? "cmd" : "sh";
103
+ const shellFlag = isWin ? "/c" : "-c";
104
+ consola.start(`Running: ${cmd}`);
105
+ const child = spawn(shell, [shellFlag, cmd], {
106
+ cwd,
107
+ stdio: "inherit"
108
+ });
109
+ activeChild = child;
110
+ child.on("close", (code) => {
111
+ activeChild = null;
112
+ if (code === 0) {
113
+ consola.success("Build succeeded");
114
+ resolve(true);
115
+ } else {
116
+ consola.error(`Build failed with code ${code}`);
117
+ resolve(false);
118
+ }
119
+ });
120
+ child.on("error", (err) => {
121
+ activeChild = null;
122
+ consola.error(`Build error: ${err.message}`);
123
+ resolve(false);
124
+ });
125
+ });
126
+ }
127
+
128
+ export {
129
+ startWatcher
130
+ };
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+ import{createRequire as __cr}from"node:module";globalThis.require=__cr(import.meta.url);
3
+ import {
4
+ __commonJS
5
+ } from "./chunk-KYDBD2KQ.mjs";
6
+
7
+ // node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js
8
+ var require_picocolors = __commonJS({
9
+ "node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js"(exports, module) {
10
+ "use strict";
11
+ var p = process || {};
12
+ var argv = p.argv || [];
13
+ var env = p.env || {};
14
+ var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
15
+ var formatter = (open, close, replace = open) => (input) => {
16
+ let string = "" + input, index = string.indexOf(close, open.length);
17
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
18
+ };
19
+ var replaceClose = (string, close, replace, index) => {
20
+ let result = "", cursor = 0;
21
+ do {
22
+ result += string.substring(cursor, index) + replace;
23
+ cursor = index + close.length;
24
+ index = string.indexOf(close, cursor);
25
+ } while (~index);
26
+ return result + string.substring(cursor);
27
+ };
28
+ var createColors = (enabled = isColorSupported) => {
29
+ let f = enabled ? formatter : () => String;
30
+ return {
31
+ isColorSupported: enabled,
32
+ reset: f("\x1B[0m", "\x1B[0m"),
33
+ bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
34
+ dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
35
+ italic: f("\x1B[3m", "\x1B[23m"),
36
+ underline: f("\x1B[4m", "\x1B[24m"),
37
+ inverse: f("\x1B[7m", "\x1B[27m"),
38
+ hidden: f("\x1B[8m", "\x1B[28m"),
39
+ strikethrough: f("\x1B[9m", "\x1B[29m"),
40
+ black: f("\x1B[30m", "\x1B[39m"),
41
+ red: f("\x1B[31m", "\x1B[39m"),
42
+ green: f("\x1B[32m", "\x1B[39m"),
43
+ yellow: f("\x1B[33m", "\x1B[39m"),
44
+ blue: f("\x1B[34m", "\x1B[39m"),
45
+ magenta: f("\x1B[35m", "\x1B[39m"),
46
+ cyan: f("\x1B[36m", "\x1B[39m"),
47
+ white: f("\x1B[37m", "\x1B[39m"),
48
+ gray: f("\x1B[90m", "\x1B[39m"),
49
+ bgBlack: f("\x1B[40m", "\x1B[49m"),
50
+ bgRed: f("\x1B[41m", "\x1B[49m"),
51
+ bgGreen: f("\x1B[42m", "\x1B[49m"),
52
+ bgYellow: f("\x1B[43m", "\x1B[49m"),
53
+ bgBlue: f("\x1B[44m", "\x1B[49m"),
54
+ bgMagenta: f("\x1B[45m", "\x1B[49m"),
55
+ bgCyan: f("\x1B[46m", "\x1B[49m"),
56
+ bgWhite: f("\x1B[47m", "\x1B[49m"),
57
+ blackBright: f("\x1B[90m", "\x1B[39m"),
58
+ redBright: f("\x1B[91m", "\x1B[39m"),
59
+ greenBright: f("\x1B[92m", "\x1B[39m"),
60
+ yellowBright: f("\x1B[93m", "\x1B[39m"),
61
+ blueBright: f("\x1B[94m", "\x1B[39m"),
62
+ magentaBright: f("\x1B[95m", "\x1B[39m"),
63
+ cyanBright: f("\x1B[96m", "\x1B[39m"),
64
+ whiteBright: f("\x1B[97m", "\x1B[39m"),
65
+ bgBlackBright: f("\x1B[100m", "\x1B[49m"),
66
+ bgRedBright: f("\x1B[101m", "\x1B[49m"),
67
+ bgGreenBright: f("\x1B[102m", "\x1B[49m"),
68
+ bgYellowBright: f("\x1B[103m", "\x1B[49m"),
69
+ bgBlueBright: f("\x1B[104m", "\x1B[49m"),
70
+ bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
71
+ bgCyanBright: f("\x1B[106m", "\x1B[49m"),
72
+ bgWhiteBright: f("\x1B[107m", "\x1B[49m")
73
+ };
74
+ };
75
+ module.exports = createColors();
76
+ module.exports.createColors = createColors;
77
+ }
78
+ });
79
+
80
+ export {
81
+ require_picocolors
82
+ };
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ import{createRequire as __cr}from"node:module";globalThis.require=__cr(import.meta.url);
3
+ import {
4
+ require_picocolors
5
+ } from "./chunk-PUSXMPOF.mjs";
6
+ import {
7
+ consola
8
+ } from "./chunk-I6SN7BBN.mjs";
9
+ import {
10
+ __toESM
11
+ } from "./chunk-KYDBD2KQ.mjs";
12
+
13
+ // src/utils/errors.ts
14
+ var import_picocolors = __toESM(require_picocolors(), 1);
15
+ var SUGGESTIONS = [
16
+ {
17
+ pattern: /not found in store/i,
18
+ message: "Run 'plunk publish' in the package directory first, or use --from <path>."
19
+ },
20
+ {
21
+ pattern: /is not linked/i,
22
+ message: "Run 'plunk add <package>' to link it first."
23
+ },
24
+ {
25
+ pattern: /No package\.json/i,
26
+ message: "Make sure you're in a valid package directory with a package.json."
27
+ },
28
+ {
29
+ pattern: /missing 'name'/i,
30
+ message: "Add a 'name' field to your package.json."
31
+ },
32
+ {
33
+ pattern: /missing 'version'/i,
34
+ message: "Add a 'version' field to your package.json."
35
+ },
36
+ {
37
+ pattern: /store entry missing/i,
38
+ message: "Re-publish the package with 'plunk publish'."
39
+ },
40
+ {
41
+ pattern: /EACCES|EPERM/i,
42
+ message: "Permission denied. Try running with elevated privileges or check file ownership."
43
+ },
44
+ {
45
+ pattern: /ENOSPC/i,
46
+ message: "Disk is full. Free up some space and try again."
47
+ },
48
+ {
49
+ pattern: /No publishable files/i,
50
+ message: "Check the 'files' field in package.json, or ensure the build output exists."
51
+ },
52
+ {
53
+ pattern: /private.*package/i,
54
+ message: "Use --private flag to publish private packages."
55
+ }
56
+ ];
57
+ function errorWithSuggestion(message) {
58
+ consola.error(message);
59
+ for (const { pattern, message: suggestion } of SUGGESTIONS) {
60
+ if (pattern.test(message)) {
61
+ consola.info(`${import_picocolors.default.dim("Suggestion:")} ${suggestion}`);
62
+ break;
63
+ }
64
+ }
65
+ }
66
+
67
+ export {
68
+ errorWithSuggestion
69
+ };
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+ import{createRequire as __cr}from"node:module";globalThis.require=__cr(import.meta.url);
3
+ import {
4
+ decodePackageName,
5
+ encodePackageName,
6
+ getStoreEntryPath,
7
+ getStoreMetaPath,
8
+ getStorePackagePath,
9
+ getStorePath,
10
+ isPlunkMeta
11
+ } from "./chunk-EDUXIQ5W.mjs";
12
+ import {
13
+ exists,
14
+ isNodeError,
15
+ removeDir
16
+ } from "./chunk-HKNM3UWU.mjs";
17
+ import {
18
+ consola
19
+ } from "./chunk-I6SN7BBN.mjs";
20
+
21
+ // src/core/store.ts
22
+ import { readFile, readdir } from "fs/promises";
23
+ import "path";
24
+ async function readMeta(name, version) {
25
+ const metaPath = getStoreMetaPath(name, version);
26
+ try {
27
+ const content = await readFile(metaPath, "utf-8");
28
+ const parsed = JSON.parse(content);
29
+ if (!isPlunkMeta(parsed)) {
30
+ consola.warn(`Invalid metadata for ${name}@${version}, ignoring`);
31
+ return null;
32
+ }
33
+ return parsed;
34
+ } catch (err) {
35
+ if (isNodeError(err) && err.code !== "ENOENT") {
36
+ consola.warn(`Failed to read metadata for ${name}@${version}: ${err}`);
37
+ }
38
+ return null;
39
+ }
40
+ }
41
+ async function getStoreEntry(name, version) {
42
+ const packageDir = getStorePackagePath(name, version);
43
+ const meta = await readMeta(name, version);
44
+ if (!meta) return null;
45
+ if (!await exists(packageDir)) return null;
46
+ return { name, version, packageDir, meta };
47
+ }
48
+ async function findStoreEntry(name) {
49
+ const storePath = getStorePath();
50
+ if (!await exists(storePath)) return null;
51
+ const encodedPrefix = encodePackageName(name) + "@";
52
+ const dirs = await readdir(storePath, { withFileTypes: true });
53
+ const candidates = dirs.filter(
54
+ (d) => d.isDirectory() && d.name.startsWith(encodedPrefix)
55
+ );
56
+ const results = await Promise.all(
57
+ candidates.map(async (dir) => {
58
+ const version = dir.name.slice(encodedPrefix.length);
59
+ const meta = await readMeta(name, version);
60
+ if (!meta) return null;
61
+ return {
62
+ name,
63
+ version,
64
+ packageDir: getStorePackagePath(name, version),
65
+ meta
66
+ };
67
+ })
68
+ );
69
+ const matching = results.filter((r) => r !== null);
70
+ if (matching.length === 0) return null;
71
+ matching.sort(
72
+ (a, b) => new Date(b.meta.publishedAt).getTime() - new Date(a.meta.publishedAt).getTime()
73
+ );
74
+ return matching[0];
75
+ }
76
+ async function listStoreEntries() {
77
+ const storePath = getStorePath();
78
+ if (!await exists(storePath)) return [];
79
+ const dirs = await readdir(storePath, { withFileTypes: true });
80
+ const candidates = dirs.filter((d) => {
81
+ if (!d.isDirectory()) return false;
82
+ const atIdx = d.name.lastIndexOf("@");
83
+ return atIdx > 0;
84
+ });
85
+ const results = await Promise.all(
86
+ candidates.map(async (dir) => {
87
+ const atIdx = dir.name.lastIndexOf("@");
88
+ const encodedName = dir.name.slice(0, atIdx);
89
+ const version = dir.name.slice(atIdx + 1);
90
+ const name = decodePackageName(encodedName);
91
+ const meta = await readMeta(name, version);
92
+ if (!meta) return null;
93
+ return {
94
+ name,
95
+ version,
96
+ packageDir: getStorePackagePath(name, version),
97
+ meta
98
+ };
99
+ })
100
+ );
101
+ return results.filter((r) => r !== null);
102
+ }
103
+ async function removeStoreEntry(name, version) {
104
+ await removeDir(getStoreEntryPath(name, version));
105
+ }
106
+
107
+ export {
108
+ readMeta,
109
+ getStoreEntry,
110
+ findStoreEntry,
111
+ listStoreEntries,
112
+ removeStoreEntry
113
+ };
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env node
2
+ import{createRequire as __cr}from"node:module";globalThis.require=__cr(import.meta.url);
3
+
4
+ // src/utils/nextjs-config.ts
5
+ import { readFile, writeFile } from "fs/promises";
6
+ function detectIndent(content) {
7
+ const match = content.match(/^(\s+)\S/m);
8
+ return match?.[1] || " ";
9
+ }
10
+ function parseArrayItems(str) {
11
+ const items = [];
12
+ const regex = /['"]([^'"]*)['"]/g;
13
+ let match;
14
+ while ((match = regex.exec(str)) !== null) {
15
+ items.push(match[1]);
16
+ }
17
+ return items;
18
+ }
19
+ function formatArray(items, indent) {
20
+ if (items.length === 0) return "[]";
21
+ if (items.length <= 3) {
22
+ return `[${items.map((i) => `'${i}'`).join(", ")}]`;
23
+ }
24
+ const inner = items.map((i) => `${indent}${indent}'${i}',`).join("\n");
25
+ return `[
26
+ ${inner}
27
+ ${indent}]`;
28
+ }
29
+ async function addToTranspilePackages(configPath, packageName) {
30
+ let content;
31
+ try {
32
+ content = await readFile(configPath, "utf-8");
33
+ } catch {
34
+ return { modified: false, error: "could not read config file" };
35
+ }
36
+ const indent = detectIndent(content);
37
+ const transpileRegex = /transpilePackages\s*:\s*\[([^\]]*)\]/s;
38
+ const transpileMatch = transpileRegex.exec(content);
39
+ if (transpileMatch) {
40
+ const items = parseArrayItems(transpileMatch[1]);
41
+ if (items.includes(packageName)) {
42
+ return { modified: false };
43
+ }
44
+ items.push(packageName);
45
+ const newArray = formatArray(items, indent);
46
+ const updated = content.replace(transpileRegex, `transpilePackages: ${newArray}`);
47
+ await writeFile(configPath, updated);
48
+ return { modified: true };
49
+ }
50
+ const configObjRegex = /(?:module\.exports\s*=\s*\{|export\s+default\s+\{|nextConfig\s*=\s*\{)/;
51
+ const configObjMatch = configObjRegex.exec(content);
52
+ if (configObjMatch) {
53
+ const insertPos = configObjMatch.index + configObjMatch[0].length;
54
+ const newSection = `
55
+ ${indent}transpilePackages: ['${packageName}'],`;
56
+ const updated = content.slice(0, insertPos) + newSection + content.slice(insertPos);
57
+ await writeFile(configPath, updated);
58
+ return { modified: true };
59
+ }
60
+ return { modified: false, error: "unrecognized config pattern" };
61
+ }
62
+ async function removeFromTranspilePackages(configPath, packageName) {
63
+ let content;
64
+ try {
65
+ content = await readFile(configPath, "utf-8");
66
+ } catch {
67
+ return { modified: false };
68
+ }
69
+ const indent = detectIndent(content);
70
+ const transpileRegex = /transpilePackages\s*:\s*\[([^\]]*)\]/s;
71
+ const transpileMatch = transpileRegex.exec(content);
72
+ if (!transpileMatch) return { modified: false };
73
+ const items = parseArrayItems(transpileMatch[1]);
74
+ const filtered = items.filter((i) => i !== packageName);
75
+ if (filtered.length === items.length) return { modified: false };
76
+ const newArray = formatArray(filtered, indent);
77
+ const updated = content.replace(transpileRegex, `transpilePackages: ${newArray}`);
78
+ await writeFile(configPath, updated);
79
+ return { modified: true };
80
+ }
81
+
82
+ export {
83
+ addToTranspilePackages,
84
+ removeFromTranspilePackages
85
+ };
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ import{createRequire as __cr}from"node:module";globalThis.require=__cr(import.meta.url);
3
+
4
+ // src/utils/build-detect.ts
5
+ import { readFile } from "fs/promises";
6
+ import { join } from "path";
7
+ async function detectBuildCommand(packageDir, pm) {
8
+ const runPrefix = pm === "npm" ? "npm run " : `${pm} `;
9
+ try {
10
+ const pkg = JSON.parse(
11
+ await readFile(join(packageDir, "package.json"), "utf-8")
12
+ );
13
+ const scripts = pkg.scripts || {};
14
+ for (const name of ["build", "compile", "bundle", "tsc"]) {
15
+ if (scripts[name]) {
16
+ return `${runPrefix}${name}`;
17
+ }
18
+ }
19
+ } catch {
20
+ }
21
+ return null;
22
+ }
23
+
24
+ export {
25
+ detectBuildCommand
26
+ };
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ import{createRequire as __cr}from"node:module";globalThis.require=__cr(import.meta.url);
3
+
4
+ // src/utils/timer.ts
5
+ var Timer = class {
6
+ start = performance.now();
7
+ /** Return elapsed time in ms */
8
+ elapsedMs() {
9
+ return performance.now() - this.start;
10
+ }
11
+ /** Return human-readable elapsed time (e.g., "1.2s" or "150ms") */
12
+ elapsed() {
13
+ const ms = this.elapsedMs();
14
+ if (ms >= 1e3) {
15
+ return `${(ms / 1e3).toFixed(1)}s`;
16
+ }
17
+ return `${Math.round(ms)}ms`;
18
+ }
19
+ };
20
+
21
+ export {
22
+ Timer
23
+ };
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ import{createRequire as __cr}from"node:module";globalThis.require=__cr(import.meta.url);
3
+ import {
4
+ consola,
5
+ isJsonOutput
6
+ } from "./chunk-I6SN7BBN.mjs";
7
+
8
+ // src/utils/output.ts
9
+ function output(data) {
10
+ if (isJsonOutput()) {
11
+ console.log(JSON.stringify(data, null, 2));
12
+ }
13
+ }
14
+ function suppressHumanOutput() {
15
+ if (isJsonOutput()) {
16
+ consola.level = -1;
17
+ }
18
+ }
19
+
20
+ export {
21
+ output,
22
+ suppressHumanOutput
23
+ };
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env node
2
+ import{createRequire as __cr}from"node:module";globalThis.require=__cr(import.meta.url);
3
+ import {
4
+ readConsumerState,
5
+ writeConsumerState
6
+ } from "./chunk-GAAB2TLH.mjs";
7
+ import {
8
+ require_picocolors
9
+ } from "./chunk-PUSXMPOF.mjs";
10
+ import {
11
+ getConsumerPlunkDir,
12
+ getConsumerStatePath
13
+ } from "./chunk-EDUXIQ5W.mjs";
14
+ import {
15
+ ensureDir,
16
+ exists
17
+ } from "./chunk-HKNM3UWU.mjs";
18
+ import {
19
+ consola
20
+ } from "./chunk-I6SN7BBN.mjs";
21
+ import {
22
+ __toESM
23
+ } from "./chunk-KYDBD2KQ.mjs";
24
+
25
+ // src/utils/init-helpers.ts
26
+ import { readFile, writeFile } from "fs/promises";
27
+ import { join } from "path";
28
+ var import_picocolors = __toESM(require_picocolors(), 1);
29
+ async function ensureGitignore(gitignorePath) {
30
+ let content = "";
31
+ try {
32
+ content = await readFile(gitignorePath, "utf-8");
33
+ } catch {
34
+ }
35
+ const lines = content.split("\n");
36
+ const alreadyIgnored = lines.some(
37
+ (line) => line.trim() === ".plunk/" || line.trim() === ".plunk" || line.trim() === "/.plunk/" || line.trim() === "/.plunk"
38
+ );
39
+ if (alreadyIgnored) return false;
40
+ const separator = content.length > 0 && !content.endsWith("\n") ? "\n" : "";
41
+ const section = content.length > 0 ? "\n# plunk local links\n.plunk/\n" : "# plunk local links\n.plunk/\n";
42
+ await writeFile(gitignorePath, content + separator + section);
43
+ return true;
44
+ }
45
+ async function addPostinstall(pkgPath) {
46
+ const content = await readFile(pkgPath, "utf-8");
47
+ const pkg = JSON.parse(content);
48
+ if (pkg.scripts?.postinstall) {
49
+ if (pkg.scripts.postinstall.includes("plunk")) return false;
50
+ consola.warn(
51
+ `Existing postinstall script found. Add ${import_picocolors.default.cyan("plunk restore")} manually if needed.`
52
+ );
53
+ return false;
54
+ }
55
+ if (!pkg.scripts) pkg.scripts = {};
56
+ pkg.scripts.postinstall = "plunk restore || true";
57
+ const indent = content.match(/^(\s+)"/m)?.[1] || " ";
58
+ await writeFile(pkgPath, JSON.stringify(pkg, null, indent) + "\n");
59
+ return true;
60
+ }
61
+ async function ensureConsumerInit(projectDir, pm) {
62
+ const plunkDir = getConsumerPlunkDir(projectDir);
63
+ const statePath = getConsumerStatePath(projectDir);
64
+ if (!await exists(statePath)) {
65
+ await ensureDir(plunkDir);
66
+ await writeConsumerState(projectDir, {
67
+ version: "1",
68
+ packageManager: pm,
69
+ role: "consumer",
70
+ links: {}
71
+ });
72
+ } else {
73
+ const state = await readConsumerState(projectDir);
74
+ if (!state.packageManager) {
75
+ state.packageManager = pm;
76
+ state.role = state.role ?? "consumer";
77
+ await writeConsumerState(projectDir, state);
78
+ }
79
+ }
80
+ const gitignorePath = join(projectDir, ".gitignore");
81
+ await ensureGitignore(gitignorePath);
82
+ const pkgPath = join(projectDir, "package.json");
83
+ if (await exists(pkgPath)) {
84
+ await addPostinstall(pkgPath);
85
+ }
86
+ }
87
+
88
+ export {
89
+ ensureGitignore,
90
+ addPostinstall,
91
+ ensureConsumerInit
92
+ };