@stacksjs/actions 0.70.88 → 0.70.91
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/dist/action.d.ts +149 -0
- package/dist/action.js +78 -0
- package/dist/actions.d.ts +2 -0
- package/dist/actions.js +2 -0
- package/dist/add.d.ts +6 -0
- package/dist/add.js +20 -0
- package/dist/ai/request-model-access.d.ts +1 -0
- package/dist/ai/request-model-access.js +10 -0
- package/dist/auth/client.d.ts +1 -0
- package/dist/auth/client.js +44 -0
- package/dist/auth/prune.d.ts +1 -0
- package/dist/auth/prune.js +35 -0
- package/dist/auth/setup.d.ts +1 -0
- package/dist/auth/setup.js +322 -0
- package/dist/auth/token.d.ts +1 -0
- package/dist/auth/token.js +10 -0
- package/dist/blog-admin.d.ts +55 -0
- package/dist/blog-admin.js +156 -0
- package/dist/blog.d.ts +30 -0
- package/dist/blog.js +398 -0
- package/dist/build/cli.d.ts +1 -0
- package/dist/build/cli.js +6 -0
- package/dist/build/component-libs.d.ts +1 -0
- package/dist/build/component-libs.js +7 -0
- package/dist/build/core.d.ts +1 -0
- package/dist/build/core.js +55 -0
- package/dist/build/desktop.d.ts +1 -0
- package/dist/build/desktop.js +5 -0
- package/dist/build/docs.d.ts +1 -0
- package/dist/build/docs.js +5 -0
- package/dist/build/frontend-static.d.ts +16 -0
- package/dist/build/frontend-static.js +124 -0
- package/dist/build/server.d.ts +1 -0
- package/dist/build/server.js +6 -0
- package/dist/build/stacks.d.ts +1 -0
- package/dist/build/stacks.js +8 -0
- package/dist/build/views.d.ts +1 -0
- package/dist/build/views.js +11 -0
- package/dist/build.d.ts +9 -0
- package/dist/build.js +64 -0
- package/dist/bump.d.ts +1 -0
- package/dist/bump.js +163 -0
- package/dist/cdn/invalidate-cache.d.ts +1 -0
- package/dist/cdn/invalidate-cache.js +0 -0
- package/dist/changelog.d.ts +9 -0
- package/dist/changelog.js +27 -0
- package/dist/check/ports.d.ts +1 -0
- package/dist/check/ports.js +16 -0
- package/dist/clean.d.ts +1 -0
- package/dist/clean.js +4 -0
- package/dist/commit.d.ts +3 -0
- package/dist/commit.js +12 -0
- package/dist/copy-types.d.ts +1 -0
- package/dist/copy-types.js +10 -0
- package/dist/database/seed.d.ts +1 -0
- package/dist/database/seed.js +26 -0
- package/dist/deploy/create-receipt-rule.d.ts +1 -0
- package/dist/deploy/create-receipt-rule.js +36 -0
- package/dist/deploy/index.d.ts +1 -0
- package/dist/deploy/index.js +1574 -0
- package/dist/dev/api.d.ts +1 -0
- package/dist/dev/api.js +94 -0
- package/dist/dev/components.d.ts +1 -0
- package/dist/dev/components.js +7 -0
- package/dist/dev/dashboard-globals.d.ts +4 -0
- package/dist/dev/dashboard-globals.js +89 -0
- package/dist/dev/dashboard-utils.d.ts +150 -0
- package/dist/dev/dashboard-utils.js +380 -0
- package/dist/dev/dashboard.d.ts +22 -0
- package/dist/dev/dashboard.js +435 -0
- package/dist/dev/desktop.d.ts +1 -0
- package/dist/dev/desktop.js +5 -0
- package/dist/dev/docs.d.ts +1 -0
- package/dist/dev/docs.js +24 -0
- package/dist/dev/index.d.ts +10 -0
- package/dist/dev/index.js +29 -0
- package/dist/dev/migrate-watcher.d.ts +1 -0
- package/dist/dev/migrate-watcher.js +74 -0
- package/dist/dev/system-tray.d.ts +1 -0
- package/dist/dev/system-tray.js +5 -0
- package/dist/dev/views.d.ts +1 -0
- package/dist/dev/views.js +147 -0
- package/dist/discover-packages.d.ts +18 -0
- package/dist/discover-packages.js +32 -0
- package/dist/domains/add.d.ts +1 -0
- package/dist/domains/add.js +61 -0
- package/dist/domains/purchase.d.ts +1 -0
- package/dist/domains/purchase.js +66 -0
- package/dist/domains/remove.d.ts +1 -0
- package/dist/domains/remove.js +24 -0
- package/dist/examples.d.ts +5 -0
- package/dist/examples.js +34 -0
- package/dist/find-projects.d.ts +1 -0
- package/dist/find-projects.js +16 -0
- package/dist/fresh.d.ts +1 -0
- package/dist/fresh.js +17 -0
- package/dist/generate/action-types.d.ts +1 -0
- package/dist/generate/action-types.js +13 -0
- package/dist/generate/component-meta.d.ts +1 -0
- package/dist/generate/component-meta.js +9 -0
- package/dist/generate/custom-cli-file.d.ts +1 -0
- package/dist/generate/custom-cli-file.js +21 -0
- package/dist/generate/env-files.d.ts +1 -0
- package/dist/generate/env-files.js +66 -0
- package/dist/generate/ide-helpers.d.ts +1 -0
- package/dist/generate/ide-helpers.js +8 -0
- package/dist/generate/index.d.ts +36 -0
- package/dist/generate/index.js +158 -0
- package/dist/generate/lib-entries.d.ts +1 -0
- package/dist/generate/lib-entries.js +16 -0
- package/dist/generate/pantry-file.d.ts +1 -0
- package/dist/generate/pantry-file.js +46 -0
- package/dist/generate/symlink-core.d.ts +1 -0
- package/dist/generate/symlink-core.js +2 -0
- package/dist/generate/types.d.ts +1 -0
- package/dist/generate/types.js +3 -0
- package/dist/generate/vscode-custom-data.d.ts +1 -0
- package/dist/generate/vscode-custom-data.js +9 -0
- package/dist/generate/web-types.d.ts +1 -0
- package/dist/generate/web-types.js +0 -0
- package/dist/helpers/component-meta.d.ts +26 -0
- package/dist/helpers/component-meta.js +295 -0
- package/dist/helpers/index.d.ts +4 -0
- package/dist/helpers/index.js +1 -0
- package/dist/helpers/lib-entries.d.ts +12 -0
- package/dist/helpers/lib-entries.js +73 -0
- package/dist/helpers/package-json.d.ts +2 -0
- package/dist/helpers/package-json.js +74 -0
- package/dist/helpers/utils.d.ts +23 -0
- package/dist/helpers/utils.js +105 -0
- package/dist/helpers/vscode-custom-data.d.ts +3 -0
- package/dist/helpers/vscode-custom-data.js +30 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.js +50 -0
- package/dist/key-generate.d.ts +1 -0
- package/dist/key-generate.js +24 -0
- package/dist/lint/fix.d.ts +1 -0
- package/dist/lint/fix.js +4 -0
- package/dist/lint/index.d.ts +1 -0
- package/dist/lint/index.js +4 -0
- package/dist/lint/lint.d.ts +14 -0
- package/dist/lint/lint.js +34 -0
- package/dist/make-command.d.ts +10 -0
- package/dist/make-command.js +95 -0
- package/dist/make-job.d.ts +5 -0
- package/dist/make-job.js +154 -0
- package/dist/make-policy.d.ts +10 -0
- package/dist/make-policy.js +142 -0
- package/dist/make-resource.d.ts +10 -0
- package/dist/make-resource.js +142 -0
- package/dist/make.d.ts +52 -0
- package/dist/make.js +328 -0
- package/dist/migrate/database.d.ts +1 -0
- package/dist/migrate/database.js +16 -0
- package/dist/migrate/fresh.d.ts +1 -0
- package/dist/migrate/fresh.js +31 -0
- package/dist/orm/base.d.ts +1 -0
- package/dist/orm/base.js +0 -0
- package/dist/orm/test.d.ts +1 -0
- package/dist/orm/test.js +0 -0
- package/dist/prepublish.d.ts +1 -0
- package/dist/prepublish.js +16 -0
- package/dist/queue/clear.d.ts +1 -0
- package/dist/queue/clear.js +42 -0
- package/dist/queue/dlq-purge.d.ts +1 -0
- package/dist/queue/dlq-purge.js +28 -0
- package/dist/queue/dlq-retry.d.ts +1 -0
- package/dist/queue/dlq-retry.js +35 -0
- package/dist/queue/dlq.d.ts +1 -0
- package/dist/queue/dlq.js +55 -0
- package/dist/queue/failed.d.ts +1 -0
- package/dist/queue/failed.js +69 -0
- package/dist/queue/flush.d.ts +1 -0
- package/dist/queue/flush.js +49 -0
- package/dist/queue/inspect.d.ts +1 -0
- package/dist/queue/inspect.js +154 -0
- package/dist/queue/list.d.ts +1 -0
- package/dist/queue/list.js +69 -0
- package/dist/queue/monitor.d.ts +1 -0
- package/dist/queue/monitor.js +95 -0
- package/dist/queue/pause.d.ts +1 -0
- package/dist/queue/pause.js +28 -0
- package/dist/queue/quarantine.d.ts +1 -0
- package/dist/queue/quarantine.js +42 -0
- package/dist/queue/resume.d.ts +1 -0
- package/dist/queue/resume.js +27 -0
- package/dist/queue/retry.d.ts +1 -0
- package/dist/queue/retry.js +41 -0
- package/dist/queue/schedule-list.d.ts +1 -0
- package/dist/queue/schedule-list.js +33 -0
- package/dist/queue/schedule.d.ts +1 -0
- package/dist/queue/schedule.js +12 -0
- package/dist/queue/status.d.ts +1 -0
- package/dist/queue/status.js +68 -0
- package/dist/queue/table.d.ts +1 -0
- package/dist/queue/table.js +10 -0
- package/dist/queue/unquarantine.d.ts +1 -0
- package/dist/queue/unquarantine.js +27 -0
- package/dist/queue/work.d.ts +1 -0
- package/dist/queue/work.js +57 -0
- package/dist/release.d.ts +1 -0
- package/dist/release.js +21 -0
- package/dist/route/list.d.ts +1 -0
- package/dist/route/list.js +78 -0
- package/dist/run-action.d.ts +2 -0
- package/dist/run-action.js +1 -0
- package/dist/saas/setup.d.ts +1 -0
- package/dist/saas/setup.js +9 -0
- package/dist/scaffold-crud.d.ts +25 -0
- package/dist/scaffold-crud.js +211 -0
- package/dist/schedule/run.d.ts +1 -0
- package/dist/schedule/run.js +7 -0
- package/dist/search/flush.d.ts +1 -0
- package/dist/search/flush.js +10 -0
- package/dist/search/import.d.ts +1 -0
- package/dist/search/import.js +10 -0
- package/dist/search/settings-list.d.ts +1 -0
- package/dist/search/settings-list.js +10 -0
- package/dist/search/settings.d.ts +1 -0
- package/dist/search/settings.js +9 -0
- package/dist/serve/api.d.ts +1 -0
- package/dist/serve/api.js +35 -0
- package/dist/setup/index.d.ts +1 -0
- package/dist/setup/index.js +1 -0
- package/dist/setup/ssl.d.ts +38 -0
- package/dist/setup/ssl.js +271 -0
- package/dist/stacks.d.ts +4 -0
- package/dist/stacks.js +265 -0
- package/dist/templates.d.ts +28 -0
- package/dist/templates.js +301 -0
- package/dist/test/feature.d.ts +1 -0
- package/dist/test/feature.js +11 -0
- package/dist/test/index.d.ts +1 -0
- package/dist/test/index.js +11 -0
- package/dist/test/ui.d.ts +1 -0
- package/dist/test/ui.js +4 -0
- package/dist/test/unit.d.ts +1 -0
- package/dist/test/unit.js +11 -0
- package/dist/typecheck.d.ts +1 -0
- package/dist/typecheck.js +4 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.js +16 -0
- package/dist/upgrade/binary.d.ts +1 -0
- package/dist/upgrade/binary.js +29 -0
- package/dist/upgrade/bun.d.ts +1 -0
- package/dist/upgrade/bun.js +0 -0
- package/dist/upgrade/dependencies.d.ts +1 -0
- package/dist/upgrade/dependencies.js +0 -0
- package/dist/upgrade/framework-utils.d.ts +150 -0
- package/dist/upgrade/framework-utils.js +193 -0
- package/dist/upgrade/framework.d.ts +1 -0
- package/dist/upgrade/framework.js +310 -0
- package/dist/upgrade/index.d.ts +1 -0
- package/dist/upgrade/index.js +17 -0
- package/dist/upgrade/packages.d.ts +14 -0
- package/dist/upgrade/packages.js +99 -0
- package/dist/upgrade/shell.d.ts +1 -0
- package/dist/upgrade/shell.js +41 -0
- package/dist/upgrade.d.ts +7 -0
- package/dist/upgrade.js +38 -0
- package/package.json +16 -16
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
export function resolveUpgradeContext(options, currentChannel) {
|
|
6
|
+
const targetVersion = options.version;
|
|
7
|
+
if (targetVersion)
|
|
8
|
+
return { channel: "stable", ref: targetVersion.startsWith("v") ? targetVersion : `v${targetVersion}`, targetVersion };
|
|
9
|
+
if (options.canary)
|
|
10
|
+
return { channel: "canary", ref: "main" };
|
|
11
|
+
if (options.stable)
|
|
12
|
+
return { channel: "stable", ref: "stable" };
|
|
13
|
+
if (currentChannel === "canary")
|
|
14
|
+
return { channel: "canary", ref: "main" };
|
|
15
|
+
return { channel: "stable", ref: "stable" };
|
|
16
|
+
}
|
|
17
|
+
export function buildTemplateString(ref, subPath = "storage/framework/core") {
|
|
18
|
+
return `github:stacksjs/stacks#${ref}/${subPath}`;
|
|
19
|
+
}
|
|
20
|
+
export function readVersion(pkgPath) {
|
|
21
|
+
try {
|
|
22
|
+
if (existsSync(pkgPath))
|
|
23
|
+
return JSON.parse(readFileSync(pkgPath, "utf-8")).version || null;
|
|
24
|
+
} catch {}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
export function readChannel(channelFilePath) {
|
|
28
|
+
try {
|
|
29
|
+
if (existsSync(channelFilePath)) {
|
|
30
|
+
if (readFileSync(channelFilePath, "utf-8").trim() === "canary")
|
|
31
|
+
return "canary";
|
|
32
|
+
}
|
|
33
|
+
} catch {}
|
|
34
|
+
return "stable";
|
|
35
|
+
}
|
|
36
|
+
export function writeChannel(channelFilePath, ch) {
|
|
37
|
+
try {
|
|
38
|
+
writeFileSync(channelFilePath, ch, "utf-8");
|
|
39
|
+
} catch {}
|
|
40
|
+
}
|
|
41
|
+
export function readSyncedVersion(versionFilePath) {
|
|
42
|
+
try {
|
|
43
|
+
if (existsSync(versionFilePath)) {
|
|
44
|
+
const content = readFileSync(versionFilePath, "utf-8").trim(), [ch, sha] = content.split(/\s+/);
|
|
45
|
+
if ((ch === "stable" || ch === "canary") && sha && /^[0-9a-f]{40}$/i.test(sha))
|
|
46
|
+
return { channel: ch, sha: sha.toLowerCase() };
|
|
47
|
+
}
|
|
48
|
+
} catch {}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
export function writeSyncedVersion(versionFilePath, ch, sha) {
|
|
52
|
+
try {
|
|
53
|
+
writeFileSync(versionFilePath, `${ch} ${sha}`, "utf-8");
|
|
54
|
+
} catch {}
|
|
55
|
+
}
|
|
56
|
+
export function shouldShortCircuit(args) {
|
|
57
|
+
const { force, targetVersion, remoteSha, synced, channel } = args;
|
|
58
|
+
if (force || targetVersion)
|
|
59
|
+
return !1;
|
|
60
|
+
if (!remoteSha || !synced)
|
|
61
|
+
return !1;
|
|
62
|
+
return synced.channel === channel && synced.sha === remoteSha.toLowerCase();
|
|
63
|
+
}
|
|
64
|
+
export function resolveUpgradeMessage(ctx, currentChannel, isStableFlag) {
|
|
65
|
+
if (ctx.targetVersion)
|
|
66
|
+
return `Installing Stacks v${ctx.targetVersion.replace(/^v/, "")}...`;
|
|
67
|
+
if (ctx.channel === "canary")
|
|
68
|
+
return "Upgrading to the latest canary build...";
|
|
69
|
+
if (isStableFlag && currentChannel === "canary")
|
|
70
|
+
return "Switching back to the latest stable release...";
|
|
71
|
+
return "Upgrading to the latest version...";
|
|
72
|
+
}
|
|
73
|
+
export function resolveSuccessMessage(ctx, currentVersion, newVersion, currentChannel, force) {
|
|
74
|
+
if (ctx.targetVersion) {
|
|
75
|
+
const pinned = ctx.targetVersion.replace(/^v/, "");
|
|
76
|
+
if (currentVersion === pinned && !force)
|
|
77
|
+
return `Stacks is already at v${pinned}`;
|
|
78
|
+
if (currentVersion)
|
|
79
|
+
return `Installed Stacks v${pinned} (was v${currentVersion})`;
|
|
80
|
+
return `Installed Stacks v${pinned}`;
|
|
81
|
+
}
|
|
82
|
+
if (currentVersion && newVersion && currentVersion === newVersion && !force) {
|
|
83
|
+
if (ctx.channel === "canary")
|
|
84
|
+
return `Stacks is already up to date (canary ${currentVersion})`;
|
|
85
|
+
return `Stacks is already up to date (v${currentVersion})`;
|
|
86
|
+
}
|
|
87
|
+
if (currentVersion && newVersion) {
|
|
88
|
+
const from = currentChannel === "canary" ? `canary ${currentVersion}` : `v${currentVersion}`, to = ctx.channel === "canary" ? `canary ${newVersion}` : `v${newVersion}`;
|
|
89
|
+
return `Upgraded Stacks from ${from} to ${to}`;
|
|
90
|
+
}
|
|
91
|
+
if (newVersion)
|
|
92
|
+
return `Upgraded Stacks to ${ctx.channel === "canary" ? `canary ${newVersion}` : `v${newVersion}`}`;
|
|
93
|
+
return `Upgraded Stacks to ${ctx.ref} (latest)`;
|
|
94
|
+
}
|
|
95
|
+
export const MANAGED_PATHS = [
|
|
96
|
+
{
|
|
97
|
+
localPath: "storage/framework/core",
|
|
98
|
+
subPath: "storage/framework/core",
|
|
99
|
+
label: "core",
|
|
100
|
+
skip: ["node_modules", "dist", "bun.lock", ".DS_Store"]
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
localPath: "storage/framework/defaults",
|
|
104
|
+
subPath: "storage/framework/defaults",
|
|
105
|
+
label: "defaults",
|
|
106
|
+
skip: ["node_modules", "dist", ".DS_Store", ".discovered-models.json"]
|
|
107
|
+
},
|
|
108
|
+
{ localPath: "buddy", subPath: "buddy", label: "buddy", isFile: !0 },
|
|
109
|
+
{ localPath: "bootstrap", subPath: "bootstrap", label: "bootstrap", isFile: !0 }
|
|
110
|
+
];
|
|
111
|
+
export function detectLocalStacks(projectRoot) {
|
|
112
|
+
const candidates = [
|
|
113
|
+
process.env.STACKS_LOCAL_PATH,
|
|
114
|
+
resolve(projectRoot, "..", "stacks"),
|
|
115
|
+
resolve(projectRoot, "..", "..", "stacks"),
|
|
116
|
+
resolve(homedir(), "Code", "stacks"),
|
|
117
|
+
resolve(homedir(), "code", "stacks"),
|
|
118
|
+
resolve(homedir(), "projects", "stacks"),
|
|
119
|
+
resolve(homedir(), "src", "stacks")
|
|
120
|
+
];
|
|
121
|
+
for (const candidate of candidates) {
|
|
122
|
+
if (!candidate)
|
|
123
|
+
continue;
|
|
124
|
+
const marker = join(candidate, "storage", "framework", "core", "buddy", "package.json");
|
|
125
|
+
try {
|
|
126
|
+
if (existsSync(marker) && resolve(candidate) !== resolve(projectRoot))
|
|
127
|
+
return resolve(candidate);
|
|
128
|
+
} catch {}
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
export async function snapshotTree(root, skip = []) {
|
|
133
|
+
const out = new Map;
|
|
134
|
+
if (!existsSync(root))
|
|
135
|
+
return out;
|
|
136
|
+
const skipSet = new Set(skip), stack = [{ abs: root, rel: "" }], hashJobs = [];
|
|
137
|
+
while (stack.length > 0) {
|
|
138
|
+
const { abs, rel } = stack.pop();
|
|
139
|
+
let entries;
|
|
140
|
+
try {
|
|
141
|
+
entries = readdirSync(abs);
|
|
142
|
+
} catch {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
for (const name of entries) {
|
|
146
|
+
if (skipSet.has(name))
|
|
147
|
+
continue;
|
|
148
|
+
const childAbs = join(abs, name), childRel = rel ? `${rel}/${name}` : name;
|
|
149
|
+
let info;
|
|
150
|
+
try {
|
|
151
|
+
info = statSync(childAbs);
|
|
152
|
+
} catch {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
if (info.isDirectory())
|
|
156
|
+
stack.push({ abs: childAbs, rel: childRel });
|
|
157
|
+
else if (info.isFile()) {
|
|
158
|
+
const size = info.size;
|
|
159
|
+
hashJobs.push((async () => {
|
|
160
|
+
const hash = await hashFile(childAbs);
|
|
161
|
+
out.set(childRel, { size, hash });
|
|
162
|
+
})());
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
await Promise.all(hashJobs);
|
|
167
|
+
return out;
|
|
168
|
+
}
|
|
169
|
+
export function diffSnapshots(before, after) {
|
|
170
|
+
let added = 0, changed = 0, unchanged = 0;
|
|
171
|
+
for (const [rel, info] of after) {
|
|
172
|
+
const prev = before.get(rel);
|
|
173
|
+
if (!prev)
|
|
174
|
+
added++;
|
|
175
|
+
else if (prev.size !== info.size || prev.hash !== info.hash)
|
|
176
|
+
changed++;
|
|
177
|
+
else
|
|
178
|
+
unchanged++;
|
|
179
|
+
}
|
|
180
|
+
let removed = 0;
|
|
181
|
+
for (const rel of before.keys())
|
|
182
|
+
if (!after.has(rel))
|
|
183
|
+
removed++;
|
|
184
|
+
return { added, changed, removed, unchanged };
|
|
185
|
+
}
|
|
186
|
+
async function hashFile(absPath) {
|
|
187
|
+
try {
|
|
188
|
+
const buf = await Bun.file(absPath).arrayBuffer();
|
|
189
|
+
return Bun.hash(buf);
|
|
190
|
+
} catch {
|
|
191
|
+
return 0n;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, rmSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { parseOptions } from "@stacksjs/cli";
|
|
5
|
+
import { downloadTemplate } from "@stacksjs/gitit";
|
|
6
|
+
import { path as p } from "@stacksjs/path";
|
|
7
|
+
import { ExitCode } from "@stacksjs/types";
|
|
8
|
+
import {
|
|
9
|
+
buildTemplateString,
|
|
10
|
+
detectLocalStacks,
|
|
11
|
+
diffSnapshots,
|
|
12
|
+
MANAGED_PATHS,
|
|
13
|
+
readChannel,
|
|
14
|
+
readSyncedVersion,
|
|
15
|
+
readVersion,
|
|
16
|
+
resolveSuccessMessage,
|
|
17
|
+
resolveUpgradeContext,
|
|
18
|
+
resolveUpgradeMessage,
|
|
19
|
+
shouldShortCircuit,
|
|
20
|
+
snapshotTree,
|
|
21
|
+
writeChannel,
|
|
22
|
+
writeSyncedVersion
|
|
23
|
+
} from "./framework-utils";
|
|
24
|
+
const options = parseOptions(), projectRoot = p.projectPath();
|
|
25
|
+
if (!existsSync(p.projectPath("storage/framework/core"))) {
|
|
26
|
+
const { upgradeStacksPackages } = await import("./packages");
|
|
27
|
+
await upgradeStacksPackages(projectRoot, {
|
|
28
|
+
version: options.version,
|
|
29
|
+
canary: options.canary,
|
|
30
|
+
stable: options.stable,
|
|
31
|
+
force: options.force,
|
|
32
|
+
dryRun: options.dryRun,
|
|
33
|
+
noPostinstall: options.noPostinstall ?? options.postinstall === !1
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const channelFile = join(projectRoot, ".stacks-channel"), versionFile = join(projectRoot, ".stacks-version"), currentChannel = readChannel(channelFile), ctx = resolveUpgradeContext(options, currentChannel), corePkgPath = p.projectPath("storage/framework/core/buddy/package.json"), currentVersion = readVersion(corePkgPath), explicitLocal = options.from ? p.projectPath(options.from) : null, detectedLocal = explicitLocal ?? detectLocalStacks(projectRoot), usingLocal = !!detectedLocal;
|
|
37
|
+
console.log(resolveUpgradeMessage(ctx, currentChannel, !!options.stable));
|
|
38
|
+
console.log(usingLocal ? ` source: local checkout at ${detectedLocal}` : ` source: github:stacksjs/stacks#${ctx.ref}`);
|
|
39
|
+
if (!options.force) {
|
|
40
|
+
const dirty = await detectDirtyManagedPaths(projectRoot);
|
|
41
|
+
if (dirty.length > 0) {
|
|
42
|
+
console.warn(`
|
|
43
|
+
\u26A0 The following framework-managed paths have uncommitted changes:`);
|
|
44
|
+
for (const path of dirty)
|
|
45
|
+
console.warn(` - ${path}`);
|
|
46
|
+
console.warn(`
|
|
47
|
+
Aborting to avoid clobbering your edits.`);
|
|
48
|
+
console.warn(` Re-run with --force to overwrite, or commit / stash the changes first.
|
|
49
|
+
`);
|
|
50
|
+
process.exit(ExitCode.FatalError);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
let resolvedRemoteSha = null;
|
|
54
|
+
if (!options.force && !ctx.targetVersion) {
|
|
55
|
+
resolvedRemoteSha = await getRemoteSha(ctx, usingLocal, detectedLocal);
|
|
56
|
+
const synced = readSyncedVersion(versionFile);
|
|
57
|
+
if (shouldShortCircuit({ force: !!options.force, targetVersion: ctx.targetVersion, remoteSha: resolvedRemoteSha, synced, channel: ctx.channel })) {
|
|
58
|
+
console.log(`\u2714 Already on the latest ${ctx.channel} (${resolvedRemoteSha.slice(0, 7)}).`);
|
|
59
|
+
process.exit(ExitCode.Success);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const ownPath = p.frameworkPath("core/actions/src/upgrade/framework.ts"), ownHashBefore = await hashFileOrZero(ownPath), aggregate = { added: 0, changed: 0, removed: 0, unchanged: 0 }, perPath = [];
|
|
63
|
+
try {
|
|
64
|
+
for (const managed of MANAGED_PATHS) {
|
|
65
|
+
const localTarget = join(projectRoot, managed.localPath), before = managed.isFile ? await singleFileSnapshot(localTarget) : await snapshotTree(localTarget, managed.skip);
|
|
66
|
+
if (usingLocal && detectedLocal)
|
|
67
|
+
await syncFromLocal(detectedLocal, managed, localTarget);
|
|
68
|
+
else {
|
|
69
|
+
if (managed.isFile)
|
|
70
|
+
continue;
|
|
71
|
+
await syncFromGitHub(ctx.ref, managed, localTarget, !!options.force);
|
|
72
|
+
}
|
|
73
|
+
const after = managed.isFile ? await singleFileSnapshot(localTarget) : await snapshotTree(localTarget, managed.skip), summary = diffSnapshots(before, after);
|
|
74
|
+
aggregate.added += summary.added;
|
|
75
|
+
aggregate.changed += summary.changed;
|
|
76
|
+
aggregate.removed += summary.removed;
|
|
77
|
+
aggregate.unchanged += summary.unchanged;
|
|
78
|
+
perPath.push({ managed, summary });
|
|
79
|
+
}
|
|
80
|
+
if (!usingLocal)
|
|
81
|
+
await syncRootFilesFromGitHub(ctx.ref);
|
|
82
|
+
} catch (err) {
|
|
83
|
+
console.error("\u2718 Failed to upgrade Stacks framework:", err?.message || err);
|
|
84
|
+
process.exit(ExitCode.FatalError);
|
|
85
|
+
}
|
|
86
|
+
const newVersion = readVersion(corePkgPath), ownHashAfter = await hashFileOrZero(ownPath), alreadyRestarted = process.argv.includes("--__restarted");
|
|
87
|
+
if (ownHashBefore !== 0n && ownHashAfter !== 0n && ownHashBefore !== ownHashAfter && !alreadyRestarted) {
|
|
88
|
+
console.log(`Upgrade pulled a newer version of the upgrade action \u2014 re-running once to pick up new sync paths and hooks.
|
|
89
|
+
`);
|
|
90
|
+
const args = process.argv.slice(2).filter((a) => a !== "--__restarted"), code = await Bun.spawn({
|
|
91
|
+
cmd: [process.argv[0] || "bun", ownPath, ...args, "--__restarted"],
|
|
92
|
+
cwd: projectRoot,
|
|
93
|
+
stdout: "inherit",
|
|
94
|
+
stderr: "inherit"
|
|
95
|
+
}).exited;
|
|
96
|
+
process.exit(code ?? 0);
|
|
97
|
+
}
|
|
98
|
+
if (!ctx.targetVersion) {
|
|
99
|
+
writeChannel(channelFile, ctx.channel);
|
|
100
|
+
if (!resolvedRemoteSha)
|
|
101
|
+
resolvedRemoteSha = await getRemoteSha(ctx, usingLocal, detectedLocal);
|
|
102
|
+
if (resolvedRemoteSha)
|
|
103
|
+
writeSyncedVersion(versionFile, ctx.channel, resolvedRemoteSha);
|
|
104
|
+
}
|
|
105
|
+
console.log(`\u2714 ${resolveSuccessMessage(ctx, currentVersion, newVersion, currentChannel, !!options.force)}`);
|
|
106
|
+
console.log("Sync summary:");
|
|
107
|
+
for (const { managed, summary } of perPath)
|
|
108
|
+
if (managed.isFile) {
|
|
109
|
+
const moved = summary.added + summary.changed > 0;
|
|
110
|
+
console.log(` ${managed.label.padEnd(10)} ${moved ? "updated" : "unchanged"}`);
|
|
111
|
+
} else if (summary.added + summary.changed + summary.removed === 0)
|
|
112
|
+
console.log(` ${managed.label.padEnd(10)} unchanged (${summary.unchanged} files)`);
|
|
113
|
+
else
|
|
114
|
+
console.log(` ${managed.label.padEnd(10)} +${summary.added} ~${summary.changed} -${summary.removed} (${summary.unchanged} unchanged)`);
|
|
115
|
+
const runHooks = !options.noPostinstall && options.postinstall !== !1;
|
|
116
|
+
if (runHooks)
|
|
117
|
+
await runPostSyncHooks({ aggregate, perPath, projectRoot });
|
|
118
|
+
if (ctx.channel === "canary" && !ctx.targetVersion)
|
|
119
|
+
console.warn("\u26A0 Canary builds may contain bugs or breaking changes. Not recommended for production.");
|
|
120
|
+
process.exit(ExitCode.Success);
|
|
121
|
+
async function detectDirtyManagedPaths(root) {
|
|
122
|
+
const gitDir = join(root, ".git");
|
|
123
|
+
if (!existsSync(gitDir))
|
|
124
|
+
return [];
|
|
125
|
+
try {
|
|
126
|
+
const proc = Bun.spawn({
|
|
127
|
+
cmd: ["git", "-C", root, "status", "--porcelain", "--", ...MANAGED_PATHS.map((m) => m.localPath)],
|
|
128
|
+
stdout: "pipe",
|
|
129
|
+
stderr: "pipe"
|
|
130
|
+
}), output = await new Response(proc.stdout).text();
|
|
131
|
+
await proc.exited;
|
|
132
|
+
return output.split(`
|
|
133
|
+
`).filter((line) => line.length > 0).map((line) => line.slice(3));
|
|
134
|
+
} catch {
|
|
135
|
+
return [];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async function getRemoteSha(context, fromLocal, stacksRoot) {
|
|
139
|
+
const SHA_RE = /^[0-9a-f]{40}$/i;
|
|
140
|
+
try {
|
|
141
|
+
if (fromLocal && stacksRoot) {
|
|
142
|
+
const proc = Bun.spawn({
|
|
143
|
+
cmd: ["git", "-C", stacksRoot, "rev-parse", context.ref],
|
|
144
|
+
stdout: "pipe",
|
|
145
|
+
stderr: "pipe"
|
|
146
|
+
}), out = (await new Response(proc.stdout).text()).trim();
|
|
147
|
+
if (await proc.exited === 0 && SHA_RE.test(out))
|
|
148
|
+
return out.toLowerCase();
|
|
149
|
+
const head = Bun.spawn({
|
|
150
|
+
cmd: ["git", "-C", stacksRoot, "rev-parse", "HEAD"],
|
|
151
|
+
stdout: "pipe",
|
|
152
|
+
stderr: "pipe"
|
|
153
|
+
}), h = (await new Response(head.stdout).text()).trim();
|
|
154
|
+
return await head.exited === 0 && SHA_RE.test(h) ? h.toLowerCase() : null;
|
|
155
|
+
}
|
|
156
|
+
const proc = Bun.spawn({
|
|
157
|
+
cmd: ["git", "ls-remote", "https://github.com/stacksjs/stacks.git", `refs/heads/${context.ref}`],
|
|
158
|
+
stdout: "pipe",
|
|
159
|
+
stderr: "pipe"
|
|
160
|
+
}), out = await new Response(proc.stdout).text();
|
|
161
|
+
if (await proc.exited !== 0)
|
|
162
|
+
return null;
|
|
163
|
+
const m = out.match(/^([0-9a-f]{40})\s/i);
|
|
164
|
+
return m?.[1] ? m[1].toLowerCase() : null;
|
|
165
|
+
} catch {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
async function hashFileOrZero(absPath) {
|
|
170
|
+
try {
|
|
171
|
+
if (!existsSync(absPath))
|
|
172
|
+
return 0n;
|
|
173
|
+
const buf = await Bun.file(absPath).arrayBuffer();
|
|
174
|
+
return Bun.hash(buf);
|
|
175
|
+
} catch {
|
|
176
|
+
return 0n;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async function singleFileSnapshot(absPath) {
|
|
180
|
+
const out = new Map;
|
|
181
|
+
if (!existsSync(absPath))
|
|
182
|
+
return out;
|
|
183
|
+
try {
|
|
184
|
+
const file = Bun.file(absPath);
|
|
185
|
+
if (file.size > 0) {
|
|
186
|
+
const buf = await file.arrayBuffer();
|
|
187
|
+
out.set("self", { size: file.size, hash: Bun.hash(buf) });
|
|
188
|
+
}
|
|
189
|
+
} catch {}
|
|
190
|
+
return out;
|
|
191
|
+
}
|
|
192
|
+
async function syncFromLocal(stacksRoot, managed, localTarget) {
|
|
193
|
+
const src = join(stacksRoot, managed.subPath);
|
|
194
|
+
if (!existsSync(src)) {
|
|
195
|
+
console.warn(` skip ${managed.label}: source missing at ${src}`);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (managed.isFile) {
|
|
199
|
+
mkdirSync(dirname(localTarget), { recursive: !0 });
|
|
200
|
+
copyFileSync(src, localTarget);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
mkdirSync(localTarget, { recursive: !0 });
|
|
204
|
+
cpSync(src, localTarget, {
|
|
205
|
+
recursive: !0,
|
|
206
|
+
force: !0,
|
|
207
|
+
filter: (source) => {
|
|
208
|
+
if (!managed.skip)
|
|
209
|
+
return !0;
|
|
210
|
+
const name = source.split("/").pop() || "";
|
|
211
|
+
return !managed.skip.includes(name);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
async function syncFromGitHub(ref, managed, localTarget, force) {
|
|
216
|
+
const template = buildTemplateString(ref, managed.subPath);
|
|
217
|
+
await downloadTemplate(template, {
|
|
218
|
+
dir: localTarget,
|
|
219
|
+
force: !0,
|
|
220
|
+
forceClean: !1,
|
|
221
|
+
preferOffline: !force
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
async function syncRootFilesFromGitHub(ref) {
|
|
225
|
+
const tmpDir = p.projectPath(".tmp-upgrade");
|
|
226
|
+
try {
|
|
227
|
+
await downloadTemplate(`github:stacksjs/stacks#${ref}`, {
|
|
228
|
+
dir: tmpDir,
|
|
229
|
+
force: !0,
|
|
230
|
+
forceClean: !0,
|
|
231
|
+
preferOffline: !0,
|
|
232
|
+
silent: !0
|
|
233
|
+
});
|
|
234
|
+
for (const managed of MANAGED_PATHS) {
|
|
235
|
+
if (!managed.isFile)
|
|
236
|
+
continue;
|
|
237
|
+
const src = join(tmpDir, managed.subPath), dest = p.projectPath(managed.localPath);
|
|
238
|
+
try {
|
|
239
|
+
if (existsSync(src) && existsSync(dest))
|
|
240
|
+
copyFileSync(src, dest);
|
|
241
|
+
} catch {}
|
|
242
|
+
}
|
|
243
|
+
} catch {} finally {
|
|
244
|
+
if (existsSync(tmpDir))
|
|
245
|
+
rmSync(tmpDir, { recursive: !0, force: !0 });
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
async function runPostSyncHooks(args) {
|
|
249
|
+
const { aggregate, perPath, projectRoot } = args;
|
|
250
|
+
if (aggregate.added + aggregate.changed + aggregate.removed === 0) {
|
|
251
|
+
console.log("Nothing changed \u2014 skipping post-sync hooks.");
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
console.log("Regenerating auto-import manifest...");
|
|
255
|
+
try {
|
|
256
|
+
const { generateAutoImportFiles } = await import("@stacksjs/server");
|
|
257
|
+
await generateAutoImportFiles();
|
|
258
|
+
} catch (err) {
|
|
259
|
+
console.warn(` auto-imports failed (non-fatal): ${err?.message || err}`);
|
|
260
|
+
}
|
|
261
|
+
if (perPath.some((entry) => {
|
|
262
|
+
const { managed, summary } = entry;
|
|
263
|
+
if (managed.isFile)
|
|
264
|
+
return !1;
|
|
265
|
+
if (managed.label !== "core" && managed.label !== "defaults")
|
|
266
|
+
return !1;
|
|
267
|
+
if (summary.added + summary.changed === 0)
|
|
268
|
+
return !1;
|
|
269
|
+
return pkgJsonInTree(join(projectRoot, managed.localPath));
|
|
270
|
+
})) {
|
|
271
|
+
console.log("Running `bun install` to refresh dependencies...");
|
|
272
|
+
try {
|
|
273
|
+
const code = await Bun.spawn({
|
|
274
|
+
cmd: [process.argv[0] || "bun", "install"],
|
|
275
|
+
cwd: projectRoot,
|
|
276
|
+
stdout: "inherit",
|
|
277
|
+
stderr: "inherit"
|
|
278
|
+
}).exited;
|
|
279
|
+
if (code !== 0)
|
|
280
|
+
console.warn(` bun install exited with code ${code} (non-fatal)`);
|
|
281
|
+
} catch (err) {
|
|
282
|
+
console.warn(` bun install failed (non-fatal): ${err?.message || err}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
const migrationsDir = join(projectRoot, "database", "migrations");
|
|
286
|
+
if (existsSync(migrationsDir)) {
|
|
287
|
+
console.log("Running pending migrations...");
|
|
288
|
+
try {
|
|
289
|
+
const migrateScript = p.frameworkPath("core/buddy/src/cli.ts"), code = await Bun.spawn({
|
|
290
|
+
cmd: [process.argv[0] || "bun", migrateScript, "migrate"],
|
|
291
|
+
cwd: projectRoot,
|
|
292
|
+
stdout: "inherit",
|
|
293
|
+
stderr: "inherit"
|
|
294
|
+
}).exited;
|
|
295
|
+
if (code !== 0)
|
|
296
|
+
console.warn(` migrate exited with code ${code} (non-fatal \u2014 DB may not be set up yet)`);
|
|
297
|
+
} catch (err) {
|
|
298
|
+
console.warn(` migrate failed (non-fatal): ${err?.message || err}`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
function pkgJsonInTree(dir) {
|
|
303
|
+
try {
|
|
304
|
+
if (!existsSync(dir))
|
|
305
|
+
return !1;
|
|
306
|
+
return readFileSync(join(dir, "package.json"), "utf-8").length > 0;
|
|
307
|
+
} catch {
|
|
308
|
+
return existsSync(dir);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { parseArgs } from "@stacksjs/cli";
|
|
3
|
+
import { Action } from "@stacksjs/enums";
|
|
4
|
+
import { ExitCode } from "@stacksjs/types";
|
|
5
|
+
import { runAction } from "../helpers";
|
|
6
|
+
const options = parseArgs();
|
|
7
|
+
if (options?.framework || options?.all)
|
|
8
|
+
await runAction(Action.UpgradeFramework, options);
|
|
9
|
+
if (options?.dependencies || options?.all)
|
|
10
|
+
await runAction(Action.UpgradeDeps, options);
|
|
11
|
+
if (options?.bun || options?.all)
|
|
12
|
+
await runAction(Action.UpgradeBun, options);
|
|
13
|
+
if (options?.shell || options?.all)
|
|
14
|
+
await runAction(Action.UpgradeShell, options);
|
|
15
|
+
if (options?.binary || options?.all)
|
|
16
|
+
await runAction(Action.UpgradeBinary, options);
|
|
17
|
+
process.exit(ExitCode.Success);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upgrade a node_modules app to a published framework version. Called by the
|
|
3
|
+
* framework upgrade script when no vendored `storage/framework/core` exists.
|
|
4
|
+
* Handles resolution, package.json rewrite, and reinstall; then `process.exit`s.
|
|
5
|
+
*/
|
|
6
|
+
export declare function upgradeStacksPackages(projectRoot: string, options: PackageUpgradeOptions): Promise<never>;
|
|
7
|
+
export declare interface PackageUpgradeOptions {
|
|
8
|
+
version?: string
|
|
9
|
+
canary?: boolean
|
|
10
|
+
stable?: boolean
|
|
11
|
+
force?: boolean
|
|
12
|
+
dryRun?: boolean
|
|
13
|
+
noPostinstall?: boolean
|
|
14
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { runCommand } from "@stacksjs/cli";
|
|
5
|
+
async function resolveTarget(options) {
|
|
6
|
+
const res = await fetch("https://registry.npmjs.org/stacks").catch(() => null);
|
|
7
|
+
if (!res || !res.ok)
|
|
8
|
+
throw Error("Could not reach the npm registry to resolve the target `stacks` version.");
|
|
9
|
+
const meta = await res.json(), distTags = meta["dist-tags"] ?? {}, versions = meta.versions ?? {};
|
|
10
|
+
let version;
|
|
11
|
+
if (options.version) {
|
|
12
|
+
if (!versions[options.version])
|
|
13
|
+
throw Error(`stacks@${options.version} was not found on the npm registry.`);
|
|
14
|
+
version = options.version;
|
|
15
|
+
} else {
|
|
16
|
+
const tag = options.canary ? "canary" : "latest", resolved = distTags[tag];
|
|
17
|
+
if (!resolved)
|
|
18
|
+
throw Error(`The \`${tag}\` dist-tag is not published for \`stacks\`.`);
|
|
19
|
+
version = resolved;
|
|
20
|
+
}
|
|
21
|
+
const coreDeps = new Set(Object.keys(versions[version]?.dependencies ?? {}));
|
|
22
|
+
return { version, coreDeps };
|
|
23
|
+
}
|
|
24
|
+
function applyBumps(pkg, target, coreDeps) {
|
|
25
|
+
const changes = [], isLockstep = (name) => name === "stacks" || name.startsWith("@stacksjs/") && coreDeps.has(name);
|
|
26
|
+
for (const field of ["dependencies", "devDependencies"]) {
|
|
27
|
+
const deps = pkg[field];
|
|
28
|
+
if (!deps)
|
|
29
|
+
continue;
|
|
30
|
+
for (const [name, spec] of Object.entries(deps)) {
|
|
31
|
+
if (!isLockstep(name))
|
|
32
|
+
continue;
|
|
33
|
+
const next = `${/^[\^~]/.test(spec) ? spec[0] : /^\d/.test(spec) ? "" : "^"}${target}`;
|
|
34
|
+
if (spec !== next) {
|
|
35
|
+
changes.push({ name, from: spec, to: next });
|
|
36
|
+
deps[name] = next;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return changes;
|
|
41
|
+
}
|
|
42
|
+
export async function upgradeStacksPackages(projectRoot, options) {
|
|
43
|
+
const pkgPath = join(projectRoot, "package.json");
|
|
44
|
+
if (!existsSync(pkgPath)) {
|
|
45
|
+
console.error("No package.json found \u2014 nothing to upgrade.");
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
const raw = readFileSync(pkgPath, "utf-8"), pkg = JSON.parse(raw), current = pkg.dependencies?.stacks ?? pkg.devDependencies?.stacks, { version: target, coreDeps } = await resolveTarget(options).catch((err) => {
|
|
49
|
+
console.error(`\u2717 ${err.message}`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
});
|
|
52
|
+
console.log(`
|
|
53
|
+
Upgrading the Stacks framework${options.canary ? " (canary)" : ""} \u2192 ${target}`);
|
|
54
|
+
if (current)
|
|
55
|
+
console.log(` current \`stacks\` constraint: ${current}
|
|
56
|
+
`);
|
|
57
|
+
const changes = applyBumps(pkg, target, coreDeps);
|
|
58
|
+
if (changes.length === 0 && !options.force) {
|
|
59
|
+
console.log(`\u2714 Already up to date \u2014 every framework dependency matches the target.
|
|
60
|
+
`);
|
|
61
|
+
process.exit(0);
|
|
62
|
+
}
|
|
63
|
+
if (changes.length > 0) {
|
|
64
|
+
console.log(" The following dependencies will be updated:");
|
|
65
|
+
const width = Math.max(...changes.map((c) => c.name.length));
|
|
66
|
+
for (const c of changes)
|
|
67
|
+
console.log(` ${c.name.padEnd(width)} ${c.from} \u2192 ${c.to}`);
|
|
68
|
+
console.log("");
|
|
69
|
+
}
|
|
70
|
+
if (options.dryRun) {
|
|
71
|
+
console.log(` --dry-run: no files were written and nothing was installed.
|
|
72
|
+
`);
|
|
73
|
+
process.exit(0);
|
|
74
|
+
}
|
|
75
|
+
if (changes.length > 0) {
|
|
76
|
+
const trailing = raw.endsWith(`
|
|
77
|
+
`) ? `
|
|
78
|
+
` : "";
|
|
79
|
+
writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}${trailing}`);
|
|
80
|
+
console.log("\u2714 Updated package.json");
|
|
81
|
+
}
|
|
82
|
+
const frameworkPkgs = ["stacks", ...[...coreDeps].filter((n) => n.startsWith("@stacksjs/"))];
|
|
83
|
+
if (options.noPostinstall) {
|
|
84
|
+
console.log(" --no-postinstall: skipping install. Run this to pull the new versions:");
|
|
85
|
+
console.log(` bun update ${frameworkPkgs.slice(0, 3).join(" ")} \u2026
|
|
86
|
+
`);
|
|
87
|
+
process.exit(0);
|
|
88
|
+
}
|
|
89
|
+
console.log(` Installing\u2026
|
|
90
|
+
`);
|
|
91
|
+
if ((await runCommand(`bun update ${frameworkPkgs.join(" ")}`, { cwd: projectRoot })).isErr) {
|
|
92
|
+
console.error("\n\u2717 The install step failed. Your package.json was updated \u2014 resolve the error and re-run `bun update`.\n");
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
console.log(`
|
|
96
|
+
\u2714 Upgraded to stacks@${target}. Review the changelog: https://github.com/stacksjs/stacks/releases/tag/v${target}
|
|
97
|
+
`);
|
|
98
|
+
process.exit(0);
|
|
99
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { $ } from "bun";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import { italic, runCommand } from "@stacksjs/cli";
|
|
4
|
+
import { log } from "@stacksjs/logging";
|
|
5
|
+
import { path as p } from "@stacksjs/path";
|
|
6
|
+
import { writeFile } from "@stacksjs/storage";
|
|
7
|
+
import { ExitCode } from "@stacksjs/types";
|
|
8
|
+
const homePath = (await $`echo $HOME`.text()).trim(), zshrcPath = p.join(homePath, ".zshrc"), pluginPath = p.shellPath("src/buddy.plugin.zsh"), customPath = p.join(homePath, ".oh-my-zsh/custom/plugins/buddy/");
|
|
9
|
+
log.info(`Setting up Oh My Zsh via ${zshrcPath}...`);
|
|
10
|
+
$.cwd(p.dirname(zshrcPath));
|
|
11
|
+
let data = await $`cat ${p.basename(zshrcPath)}`.text();
|
|
12
|
+
const pluginLineRegex = /^(?!#).*plugins=\(([^)]+)\)/m, match = data.match(pluginLineRegex);
|
|
13
|
+
if (match) {
|
|
14
|
+
const plugins = match[1]?.split(/\s+/).filter(Boolean);
|
|
15
|
+
if (!plugins) {
|
|
16
|
+
log.error("Maybe the plugins line in your .zshrc file could not be found? If this continues being an issue, please reach out to us on Discord.");
|
|
17
|
+
process.exit(ExitCode.FatalError);
|
|
18
|
+
}
|
|
19
|
+
if (!plugins.includes("buddy")) {
|
|
20
|
+
plugins.push("buddy");
|
|
21
|
+
const newPluginLine = `plugins=(
|
|
22
|
+
${plugins.map((plugin) => plugin.trim()).join(`
|
|
23
|
+
`)}
|
|
24
|
+
)`;
|
|
25
|
+
data = data.replace(pluginLineRegex, newPluginLine);
|
|
26
|
+
await writeFile(zshrcPath, data);
|
|
27
|
+
log.info(`Copying buddy zsh plugin ${pluginPath} to ${customPath}...`);
|
|
28
|
+
await runCommand(`mkdir -p ${customPath}`);
|
|
29
|
+
await runCommand(`cp -rf ${pluginPath} ${customPath}`);
|
|
30
|
+
log.success("Copied buddy zsh plugin");
|
|
31
|
+
} else {
|
|
32
|
+
log.info("Buddy is already set up");
|
|
33
|
+
log.info("Ensuring `buddy` is updated...");
|
|
34
|
+
await runCommand(`cp -rf ${pluginPath} ${customPath}`);
|
|
35
|
+
log.success("Updated buddy zsh plugin to latest version");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
log.success("Oh My Zsh Setup Complete");
|
|
39
|
+
log.info(italic("To see changes reflect, you may need to open a new terminal window"));
|
|
40
|
+
if (process.env.TERM_PROGRAM === "vscode")
|
|
41
|
+
log.info("\u2318\u21E7P terminal.create.new.terminal");
|