@hype-stack/cli 0.5.13 → 0.5.15
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/{cli-Cm8dj5Gp.js → cli-Ck7P--h6.js} +459 -396
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/template.d.ts.map +1 -1
- package/dist/config/bin.js +1 -1
- package/dist/constants/themes.d.ts.map +1 -1
- package/dist/core/apply-radius.d.ts +28 -0
- package/dist/core/apply-radius.d.ts.map +1 -0
- package/dist/core/codemods.d.ts +6 -0
- package/dist/core/codemods.d.ts.map +1 -1
- package/dist/core/installer.d.ts.map +1 -1
- package/dist/core/post-setup.d.ts +7 -0
- package/dist/core/post-setup.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/themes.js +1 -21
- package/dist/types/types.d.ts +14 -0
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@ import { Prompt as O } from "@clack/core";
|
|
|
13
13
|
import { styleText as k } from "node:util";
|
|
14
14
|
import { downloadTemplate as ee } from "giget";
|
|
15
15
|
//#region src/constants/constants.ts
|
|
16
|
-
var A = "0.5.
|
|
16
|
+
var A = "0.5.15", te = "gh:BetterTyped/hype-stack", ne = "stack.json", re = "/schema/stack.json", j = "https://api.hype-stack.dev", M = "HYPE_STACK_API_URL", N = "https://www.hype-stack.dev", ie = /^[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$/, P = [
|
|
17
17
|
{
|
|
18
18
|
value: "cursor",
|
|
19
19
|
label: "Cursor",
|
|
@@ -3014,15 +3014,17 @@ var xi = "import { type LucideIcon } from \"lucide-react\";\n\n/* --------------
|
|
|
3014
3014
|
secondary: "secondaryNav",
|
|
3015
3015
|
tertiary: "tertiaryNav",
|
|
3016
3016
|
settings: "settingsNav"
|
|
3017
|
-
};
|
|
3018
|
-
async function Ci(e) {
|
|
3019
|
-
let { entries: t, paths: n, projectRoot: r, slot: i = "frontend" } = e, a = Jr(i, n), o = T.resolve(r, a, "src/constants/nav.constants.ts"), s;
|
|
3020
|
-
await Y(o) ? s = await y.readFile(o, "utf-8") : (await y.mkdir(T.dirname(o), { recursive: !0 }), s = xi);
|
|
3021
|
-
for (let e of t) s.includes(`label: "${e.label}"`) || (s = Ei(s, e));
|
|
3022
|
-
for (let e of t.toReversed()) s.includes(`label: "${e.label}"`) || (s = Oi(s, e));
|
|
3023
|
-
await y.writeFile(o, s, "utf-8");
|
|
3024
|
-
}
|
|
3017
|
+
}, Ci = new Set(["primary", "secondary"]);
|
|
3025
3018
|
async function wi(e) {
|
|
3019
|
+
let { entries: t, paths: n, projectRoot: r, slot: i = "frontend", override: a = !1 } = e, o = Jr(i, n), s = T.resolve(r, o, "src/constants/nav.constants.ts"), c;
|
|
3020
|
+
await Y(s) ? c = await y.readFile(s, "utf-8") : (await y.mkdir(T.dirname(s), { recursive: !0 }), c = xi);
|
|
3021
|
+
for (let e of t) !a && c.includes(`label: "${e.label}"`) || (c = Di(c, e));
|
|
3022
|
+
if (a) for (let e of t) c.includes(`label: "${e.label}"`) && (c = ji(c, e));
|
|
3023
|
+
for (let e of t) Ci.has(e.group) && (c.includes(`label: "${e.label}"`) || (c = ki(c, e, "append")));
|
|
3024
|
+
for (let e of t.toReversed()) Ci.has(e.group) || c.includes(`label: "${e.label}"`) || (c = ki(c, e, "prepend"));
|
|
3025
|
+
await y.writeFile(s, c, "utf-8");
|
|
3026
|
+
}
|
|
3027
|
+
async function Ti(e) {
|
|
3026
3028
|
let { postLoginRedirect: t, paths: n, projectRoot: r, slot: i = "frontend" } = e, a = Jr(i, n), o = T.resolve(r, a, "src/features/auth/constants/auth.constants.ts");
|
|
3027
3029
|
if (!await Y(o)) return;
|
|
3028
3030
|
let s = await y.readFile(o, "utf-8"), c = /export const POST_LOGIN_REDIRECT_PATH = "[^"]*";/;
|
|
@@ -3030,17 +3032,17 @@ async function wi(e) {
|
|
|
3030
3032
|
let l = s.replace(c, `export const POST_LOGIN_REDIRECT_PATH = "${t}";`);
|
|
3031
3033
|
await y.writeFile(o, l, "utf-8");
|
|
3032
3034
|
}
|
|
3033
|
-
function
|
|
3035
|
+
function Ei(e) {
|
|
3034
3036
|
let t = [e.icon];
|
|
3035
3037
|
if (e.items) for (let n of e.items) t.includes(n.icon) || t.push(n.icon);
|
|
3036
3038
|
return t;
|
|
3037
3039
|
}
|
|
3038
|
-
function
|
|
3039
|
-
let n =
|
|
3040
|
-
for (let e of n) r =
|
|
3040
|
+
function Di(e, t) {
|
|
3041
|
+
let n = Ei(t), r = e;
|
|
3042
|
+
for (let e of n) r = Oi(r, e);
|
|
3041
3043
|
return r;
|
|
3042
3044
|
}
|
|
3043
|
-
function
|
|
3045
|
+
function Oi(e, t) {
|
|
3044
3046
|
let n = e.match(/import \{([^}]+)\} from "lucide-react";/);
|
|
3045
3047
|
if (!n) return e;
|
|
3046
3048
|
let r = n[1].split(",").map((e) => e.trim()).filter(Boolean);
|
|
@@ -3048,21 +3050,31 @@ function Di(e, t) {
|
|
|
3048
3050
|
let i = r.findIndex((e) => e.startsWith("type "));
|
|
3049
3051
|
return i === -1 ? r.push(t) : r.splice(i, 0, t), e.replace(n[0], `import { ${r.join(", ")} } from "lucide-react";`);
|
|
3050
3052
|
}
|
|
3051
|
-
function
|
|
3052
|
-
let
|
|
3053
|
-
if (!
|
|
3054
|
-
let
|
|
3055
|
-
if (!
|
|
3056
|
-
let
|
|
3057
|
-
return
|
|
3053
|
+
function ki(e, t, n) {
|
|
3054
|
+
let r = Si[t.group];
|
|
3055
|
+
if (!r) return e;
|
|
3056
|
+
let i = Mi(t), a = RegExp(`export const ${r}: NavEntry\\[\\] = \\[`), o = e.match(a);
|
|
3057
|
+
if (!o) return e;
|
|
3058
|
+
let s = e.indexOf(o[0]) + o[0].length, c = Ai(e, s - 1);
|
|
3059
|
+
return c === -1 ? e : e.slice(s, c).trim() === "" ? e.slice(0, s) + "\n" + i + "\n" + e.slice(s) : n === "append" ? e.slice(0, c) + i + "\n" + e.slice(c) : e.slice(0, s) + "\n" + i + e.slice(s);
|
|
3058
3060
|
}
|
|
3059
|
-
function
|
|
3061
|
+
function Ai(e, t) {
|
|
3060
3062
|
let n = 0;
|
|
3061
3063
|
for (let r = t; r < e.length; r++) if (e[r] === "[") n++;
|
|
3062
3064
|
else if (e[r] === "]" && (n--, n === 0)) return r;
|
|
3063
3065
|
return -1;
|
|
3064
3066
|
}
|
|
3065
|
-
function
|
|
3067
|
+
function ji(e, t) {
|
|
3068
|
+
let n = e.indexOf(`label: "${t.label}"`);
|
|
3069
|
+
if (n === -1) return e;
|
|
3070
|
+
let r = e.lastIndexOf("{", n);
|
|
3071
|
+
if (r === -1) return e;
|
|
3072
|
+
let i = ci(e, r);
|
|
3073
|
+
if (i === -1) return e;
|
|
3074
|
+
let a = Mi(t).trimStart().replace(/,\s*$/, "");
|
|
3075
|
+
return e.slice(0, r) + a + e.slice(i + 1);
|
|
3076
|
+
}
|
|
3077
|
+
function Mi(e) {
|
|
3066
3078
|
let t = [];
|
|
3067
3079
|
if (t.push(" {"), t.push(` label: "${e.label}",`), t.push(` icon: ${e.icon},`), e.to && t.push(` to: "${e.to}",`), e.params && t.push(` params: ${e.params},`), e.items && e.items.length > 0) {
|
|
3068
3080
|
t.push(" items: [");
|
|
@@ -3078,14 +3090,14 @@ function Ai(e) {
|
|
|
3078
3090
|
} else t.push(" items: [],");
|
|
3079
3091
|
return t.push(" },"), t.join("\n");
|
|
3080
3092
|
}
|
|
3081
|
-
async function
|
|
3093
|
+
async function Ni(e, t, n) {
|
|
3082
3094
|
let r = Z("{{backend.features}}", t), i = T.resolve(n, r, "organizations/modules/setup-organization/steps/index.ts");
|
|
3083
3095
|
if (!await Y(i)) return;
|
|
3084
3096
|
let a = await y.readFile(i, "utf-8");
|
|
3085
|
-
for (let t of e) a.includes(`from "${t.from}"`) || (a =
|
|
3097
|
+
for (let t of e) a.includes(`from "${t.from}"`) || (a = Pi(a, t), a = Fi(a, t));
|
|
3086
3098
|
await y.writeFile(i, a, "utf-8");
|
|
3087
3099
|
}
|
|
3088
|
-
function
|
|
3100
|
+
function Pi(e, t) {
|
|
3089
3101
|
let n = `import { ${t.import} } from "${t.from}";`, r = e.lastIndexOf("import ");
|
|
3090
3102
|
if (r !== -1) {
|
|
3091
3103
|
let t = e.indexOf("\n", e.indexOf(";", r));
|
|
@@ -3093,38 +3105,38 @@ function Mi(e, t) {
|
|
|
3093
3105
|
}
|
|
3094
3106
|
return e.indexOf("type "), n + "\n\n" + e;
|
|
3095
3107
|
}
|
|
3096
|
-
function
|
|
3108
|
+
function Fi(e, t) {
|
|
3097
3109
|
let n = ` { id: "${t.id}", execute: (ctx) => ${t.import}(ctx) },`, r = e.match(/export const steps:\s*Step\[\]\s*=\s*\[/);
|
|
3098
3110
|
if (!r) return e;
|
|
3099
|
-
let i = e.indexOf(r[0]) + r[0].length, a =
|
|
3111
|
+
let i = e.indexOf(r[0]) + r[0].length, a = Ii(e, i - 1);
|
|
3100
3112
|
return a === -1 ? e : e.slice(i, a).trim() === "" ? e.slice(0, a) + "\n" + n + "\n" + e.slice(a) : e.slice(0, a) + n + "\n" + e.slice(a);
|
|
3101
3113
|
}
|
|
3102
|
-
function
|
|
3114
|
+
function Ii(e, t) {
|
|
3103
3115
|
let n = 0;
|
|
3104
3116
|
for (let r = t; r < e.length; r++) if (e[r] === "[") n++;
|
|
3105
3117
|
else if (e[r] === "]" && (n--, n === 0)) return r;
|
|
3106
3118
|
return -1;
|
|
3107
3119
|
}
|
|
3108
|
-
var
|
|
3109
|
-
async function
|
|
3110
|
-
await
|
|
3120
|
+
var Li = "import { type ComponentType } from \"react\";\n\nexport type NavbarAction = {\n id: string;\n component: ComponentType;\n};\n\nexport const navbarActions: NavbarAction[] = [];\n\nexport const userMenuActions: NavbarAction[] = [];\n";
|
|
3121
|
+
async function Ri(e) {
|
|
3122
|
+
await Bi({
|
|
3111
3123
|
...e,
|
|
3112
3124
|
arrayName: "navbarActions"
|
|
3113
3125
|
});
|
|
3114
3126
|
}
|
|
3115
|
-
async function
|
|
3116
|
-
await
|
|
3127
|
+
async function zi(e) {
|
|
3128
|
+
await Bi({
|
|
3117
3129
|
...e,
|
|
3118
3130
|
arrayName: "userMenuActions"
|
|
3119
3131
|
});
|
|
3120
3132
|
}
|
|
3121
|
-
async function
|
|
3133
|
+
async function Bi({ actions: e, arrayName: t, paths: n, projectRoot: r, slot: i }) {
|
|
3122
3134
|
let a = Jr(i, n), o = T.resolve(r, a, "src/constants/navbar-actions.tsx"), s;
|
|
3123
|
-
await Y(o) ? s = await y.readFile(o, "utf-8") : (await y.mkdir(T.dirname(o), { recursive: !0 }), s =
|
|
3124
|
-
for (let n of e) s =
|
|
3135
|
+
await Y(o) ? s = await y.readFile(o, "utf-8") : (await y.mkdir(T.dirname(o), { recursive: !0 }), s = Li);
|
|
3136
|
+
for (let n of e) s = Vi(s, n), s = Hi(s, n, t);
|
|
3125
3137
|
await y.writeFile(o, s, "utf-8");
|
|
3126
3138
|
}
|
|
3127
|
-
function
|
|
3139
|
+
function Vi(e, t) {
|
|
3128
3140
|
let n = `import { ${t.import} } from "${t.from}";`;
|
|
3129
3141
|
if (e.includes(n)) return e;
|
|
3130
3142
|
let r = e.lastIndexOf("import ");
|
|
@@ -3132,38 +3144,38 @@ function zi(e, t) {
|
|
|
3132
3144
|
let i = e.indexOf("\n", r);
|
|
3133
3145
|
return i === -1 ? e + "\n" + n : e.slice(0, i + 1) + n + "\n" + e.slice(i + 1);
|
|
3134
3146
|
}
|
|
3135
|
-
function
|
|
3147
|
+
function Hi(e, t, n) {
|
|
3136
3148
|
let r = e.match(RegExp(`export const ${n}:\\s*NavbarAction\\[\\]\\s*=\\s*\\[`));
|
|
3137
3149
|
if (!r) return e;
|
|
3138
|
-
let i = e.indexOf(r[0]) + r[0].length, a =
|
|
3150
|
+
let i = e.indexOf(r[0]) + r[0].length, a = Ui(e, i - 1);
|
|
3139
3151
|
if (a === -1) return e;
|
|
3140
3152
|
let o = e.slice(i, a);
|
|
3141
3153
|
if (o.includes(`id: "${t.id}"`)) return e;
|
|
3142
3154
|
let s = ` { id: "${t.id}", component: ${t.import} },`;
|
|
3143
3155
|
return o.trim() === "" ? e.slice(0, a) + "\n" + s + "\n" + e.slice(a) : e.slice(0, a) + s + "\n" + e.slice(a);
|
|
3144
3156
|
}
|
|
3145
|
-
function
|
|
3157
|
+
function Ui(e, t) {
|
|
3146
3158
|
let n = 0;
|
|
3147
3159
|
for (let r = t; r < e.length; r++) if (e[r] === "[") n++;
|
|
3148
3160
|
else if (e[r] === "]" && (n--, n === 0)) return r;
|
|
3149
3161
|
return -1;
|
|
3150
3162
|
}
|
|
3151
|
-
var
|
|
3163
|
+
var Wi = new Set([
|
|
3152
3164
|
".ts",
|
|
3153
3165
|
".tsx",
|
|
3154
3166
|
".js",
|
|
3155
3167
|
".jsx"
|
|
3156
3168
|
]);
|
|
3157
|
-
async function
|
|
3169
|
+
async function Gi(e) {
|
|
3158
3170
|
let { files: t, paths: n, projectRoot: r, projectName: i } = e;
|
|
3159
3171
|
if (i === "hype-stack") return;
|
|
3160
3172
|
let a = `@${i}/`;
|
|
3161
3173
|
await Promise.all(t.map(async (e) => {
|
|
3162
3174
|
let t = Br(e.target, n, r), i = await y.stat(t).catch(() => null);
|
|
3163
|
-
i?.isDirectory() ? await
|
|
3175
|
+
i?.isDirectory() ? await Ji(t, a) : i?.isFile() && Wi.has(T.extname(t)) && await Yi(t, a);
|
|
3164
3176
|
}));
|
|
3165
3177
|
}
|
|
3166
|
-
var
|
|
3178
|
+
var Ki = new Set([
|
|
3167
3179
|
".git",
|
|
3168
3180
|
"node_modules",
|
|
3169
3181
|
"dist",
|
|
@@ -3172,20 +3184,20 @@ var Wi = new Set([
|
|
|
3172
3184
|
".next",
|
|
3173
3185
|
"coverage"
|
|
3174
3186
|
]);
|
|
3175
|
-
async function
|
|
3176
|
-
t !== "hype-stack" && await
|
|
3187
|
+
async function qi(e, t) {
|
|
3188
|
+
t !== "hype-stack" && await Ji(e, `@${t}/`);
|
|
3177
3189
|
}
|
|
3178
|
-
async function
|
|
3190
|
+
async function Ji(e, t) {
|
|
3179
3191
|
let n = await y.readdir(e, { withFileTypes: !0 });
|
|
3180
3192
|
await Promise.all(n.map(async (n) => {
|
|
3181
3193
|
let r = T.join(e, n.name);
|
|
3182
3194
|
if (n.isDirectory()) {
|
|
3183
|
-
if (
|
|
3184
|
-
await
|
|
3185
|
-
} else n.isFile() &&
|
|
3195
|
+
if (Ki.has(n.name)) return;
|
|
3196
|
+
await Ji(r, t);
|
|
3197
|
+
} else n.isFile() && Wi.has(T.extname(n.name)) && await Yi(r, t);
|
|
3186
3198
|
}));
|
|
3187
3199
|
}
|
|
3188
|
-
async function
|
|
3200
|
+
async function Yi(e, t) {
|
|
3189
3201
|
let n = await y.readFile(e, "utf-8");
|
|
3190
3202
|
if (!n.includes(Gr)) return;
|
|
3191
3203
|
let r = qr(n, t);
|
|
@@ -3193,22 +3205,22 @@ async function qi(e, t) {
|
|
|
3193
3205
|
}
|
|
3194
3206
|
//#endregion
|
|
3195
3207
|
//#region src/core/installer.ts
|
|
3196
|
-
function
|
|
3208
|
+
function Xi(e, t) {
|
|
3197
3209
|
return e.slot ? t ? t.includes(e.slot) : e.slot === "frontend" : !0;
|
|
3198
3210
|
}
|
|
3199
|
-
async function
|
|
3211
|
+
async function Zi(e, t) {
|
|
3200
3212
|
if ((await y.stat(e)).isDirectory()) {
|
|
3201
3213
|
await y.mkdir(t, { recursive: !0 });
|
|
3202
3214
|
let n = await y.readdir(e, { withFileTypes: !0 });
|
|
3203
|
-
for (let r of n) await
|
|
3215
|
+
for (let r of n) await Zi(T.join(e, r.name), T.join(t, r.name));
|
|
3204
3216
|
} else await y.mkdir(T.dirname(t), { recursive: !0 }), await y.copyFile(e, t);
|
|
3205
3217
|
}
|
|
3206
|
-
async function
|
|
3218
|
+
async function Qi(e) {
|
|
3207
3219
|
let { src: t, dest: n, projectRoot: r, skip: i } = e;
|
|
3208
3220
|
if ((await y.stat(t)).isDirectory()) {
|
|
3209
3221
|
await y.mkdir(n, { recursive: !0 });
|
|
3210
3222
|
let e = await y.readdir(t, { withFileTypes: !0 });
|
|
3211
|
-
return (await Promise.all(e.map((e) =>
|
|
3223
|
+
return (await Promise.all(e.map((e) => Qi({
|
|
3212
3224
|
src: T.join(t, e.name),
|
|
3213
3225
|
dest: T.join(n, e.name),
|
|
3214
3226
|
projectRoot: r,
|
|
@@ -3217,7 +3229,7 @@ async function Xi(e) {
|
|
|
3217
3229
|
}
|
|
3218
3230
|
return i.has(t) ? [] : (await y.mkdir(T.dirname(n), { recursive: !0 }), await y.copyFile(t, n), [T.relative(r, n)]);
|
|
3219
3231
|
}
|
|
3220
|
-
async function
|
|
3232
|
+
async function $i(e) {
|
|
3221
3233
|
let { file: t, packDir: n, paths: r, projectRoot: i } = e, a = Vr(t.source, n), o = Br(t.target, r, i);
|
|
3222
3234
|
return {
|
|
3223
3235
|
sourcePath: a,
|
|
@@ -3226,8 +3238,8 @@ async function Zi(e) {
|
|
|
3226
3238
|
targetExists: await Y(o) || await lr(o)
|
|
3227
3239
|
};
|
|
3228
3240
|
}
|
|
3229
|
-
async function
|
|
3230
|
-
let { file: t, packDir: n, paths: r, projectRoot: i } = e, { sourcePath: a, targetPath: o, sourceExists: s, targetExists: c } = await
|
|
3241
|
+
async function ea(e) {
|
|
3242
|
+
let { file: t, packDir: n, paths: r, projectRoot: i } = e, { sourcePath: a, targetPath: o, sourceExists: s, targetExists: c } = await $i({
|
|
3231
3243
|
file: t,
|
|
3232
3244
|
packDir: n,
|
|
3233
3245
|
paths: r,
|
|
@@ -3242,8 +3254,8 @@ async function Qi(e) {
|
|
|
3242
3254
|
default: return `${t.target}: Unknown strategy: ${String(t.strategy)}`;
|
|
3243
3255
|
}
|
|
3244
3256
|
}
|
|
3245
|
-
async function
|
|
3246
|
-
let { file: t, packDir: n, paths: r, projectRoot: i, force: a, overwrite: o } = e, { sourcePath: s, targetPath: c, sourceExists: l, targetExists: u } = await
|
|
3257
|
+
async function ta(e) {
|
|
3258
|
+
let { file: t, packDir: n, paths: r, projectRoot: i, force: a, overwrite: o } = e, { sourcePath: s, targetPath: c, sourceExists: l, targetExists: u } = await $i({
|
|
3247
3259
|
file: t,
|
|
3248
3260
|
packDir: n,
|
|
3249
3261
|
paths: r,
|
|
@@ -3261,7 +3273,7 @@ async function $i(e) {
|
|
|
3261
3273
|
status: "skipped",
|
|
3262
3274
|
path: t.target,
|
|
3263
3275
|
reason: "Already exists"
|
|
3264
|
-
} : (await
|
|
3276
|
+
} : (await Zi(s, c), {
|
|
3265
3277
|
status: "installed",
|
|
3266
3278
|
path: t.target
|
|
3267
3279
|
});
|
|
@@ -3270,16 +3282,16 @@ async function $i(e) {
|
|
|
3270
3282
|
status: "skipped",
|
|
3271
3283
|
path: t.target,
|
|
3272
3284
|
reason: "Already exists (skip-if-exists)"
|
|
3273
|
-
} : (await
|
|
3285
|
+
} : (await Zi(s, c), {
|
|
3274
3286
|
status: "installed",
|
|
3275
3287
|
path: t.target
|
|
3276
3288
|
});
|
|
3277
|
-
case "override": return await
|
|
3289
|
+
case "override": return await Zi(s, c), {
|
|
3278
3290
|
status: "installed",
|
|
3279
3291
|
path: t.target
|
|
3280
3292
|
};
|
|
3281
3293
|
case "merge": {
|
|
3282
|
-
if (!u) return await
|
|
3294
|
+
if (!u) return await Zi(s, c), {
|
|
3283
3295
|
status: "installed",
|
|
3284
3296
|
path: t.target
|
|
3285
3297
|
};
|
|
@@ -3309,15 +3321,15 @@ async function $i(e) {
|
|
|
3309
3321
|
};
|
|
3310
3322
|
}
|
|
3311
3323
|
}
|
|
3312
|
-
async function
|
|
3324
|
+
async function na(e) {
|
|
3313
3325
|
let { packs: t, config: n, projectRoot: r, slotsByPack: i } = e, a = n.paths;
|
|
3314
3326
|
if (!a) throw Error("stack.json is missing 'paths' configuration. Run 'npx @hype-stack/cli init' to set it up.");
|
|
3315
3327
|
let o = [], s = /* @__PURE__ */ new Set();
|
|
3316
3328
|
for (let e of t) {
|
|
3317
3329
|
let t = i?.get(e.manifest.name);
|
|
3318
3330
|
for (let n of e.manifest.files) {
|
|
3319
|
-
if (n.strategy !== "create" || !
|
|
3320
|
-
let { targetPath: i, targetExists: c } = await
|
|
3331
|
+
if (n.strategy !== "create" || !Xi(n, t)) continue;
|
|
3332
|
+
let { targetPath: i, targetExists: c } = await $i({
|
|
3321
3333
|
file: n,
|
|
3322
3334
|
packDir: e.packDir,
|
|
3323
3335
|
paths: a,
|
|
@@ -3332,13 +3344,13 @@ async function ea(e) {
|
|
|
3332
3344
|
}
|
|
3333
3345
|
return o;
|
|
3334
3346
|
}
|
|
3335
|
-
async function
|
|
3347
|
+
async function ra(e) {
|
|
3336
3348
|
let { manifest: t, config: n, projectRoot: r, force: i, packDir: a, slots: o } = e, s = n.paths;
|
|
3337
3349
|
if (!s) throw Error("stack.json is missing 'paths' configuration. Run 'npx @hype-stack/cli init' to set it up.");
|
|
3338
3350
|
let c = [];
|
|
3339
3351
|
for (let e of t.files) {
|
|
3340
|
-
if (!
|
|
3341
|
-
let t = await
|
|
3352
|
+
if (!Xi(e, o)) continue;
|
|
3353
|
+
let t = await ea({
|
|
3342
3354
|
file: e,
|
|
3343
3355
|
packDir: a,
|
|
3344
3356
|
paths: s,
|
|
@@ -3349,16 +3361,16 @@ async function ta(e) {
|
|
|
3349
3361
|
}
|
|
3350
3362
|
return c;
|
|
3351
3363
|
}
|
|
3352
|
-
async function
|
|
3364
|
+
async function ia(e) {
|
|
3353
3365
|
let { manifest: t, config: n, projectRoot: r, force: i, overwrite: a, packDir: o, slots: s } = e, c = n.paths;
|
|
3354
3366
|
if (!c) throw Error("stack.json is missing 'paths' configuration. Run 'npx @hype-stack/cli init' to set it up.");
|
|
3355
3367
|
let l = {
|
|
3356
3368
|
installed: [],
|
|
3357
3369
|
skipped: [],
|
|
3358
3370
|
errors: []
|
|
3359
|
-
}, u = t.files.filter((e) =>
|
|
3371
|
+
}, u = t.files.filter((e) => Xi(e, s));
|
|
3360
3372
|
for (let e of u) {
|
|
3361
|
-
let t = await
|
|
3373
|
+
let t = await ta({
|
|
3362
3374
|
file: e,
|
|
3363
3375
|
packDir: o,
|
|
3364
3376
|
paths: c,
|
|
@@ -3378,40 +3390,40 @@ async function na(e) {
|
|
|
3378
3390
|
break;
|
|
3379
3391
|
}
|
|
3380
3392
|
}
|
|
3381
|
-
await
|
|
3393
|
+
await Gi({
|
|
3382
3394
|
files: u,
|
|
3383
3395
|
paths: c,
|
|
3384
3396
|
projectRoot: r,
|
|
3385
3397
|
projectName: n.name
|
|
3386
3398
|
}), t.env && t.env.length > 0 && await Yr(t.env, c, r), t.routes && t.routes.length > 0 && await ti(t.routes, c, r), t.context && t.context.length > 0 && await ii(t.context, c, r), t.sockets && t.sockets.length > 0 && await fi(t.sockets, c, r), t.sdkConfigurations && t.sdkConfigurations.length > 0 && await gi(t.sdkConfigurations, c, r), t.enums && t.enums.length > 0 && await ui(t.enums, c, r), t.frontendRoutes && t.frontendRoutes.length > 0 && await yi(t.frontendRoutes, c, r);
|
|
3387
3399
|
let d = s && s.length > 0 ? s : ["frontend"];
|
|
3388
|
-
for (let e of d) t.nav && t.nav.length > 0 && await
|
|
3400
|
+
for (let e of d) t.nav && t.nav.length > 0 && await wi({
|
|
3389
3401
|
entries: t.nav,
|
|
3390
3402
|
paths: c,
|
|
3391
3403
|
projectRoot: r,
|
|
3392
3404
|
slot: e
|
|
3393
|
-
}), t.navbarActions && t.navbarActions.length > 0 && await
|
|
3405
|
+
}), t.navbarActions && t.navbarActions.length > 0 && await Ri({
|
|
3394
3406
|
actions: t.navbarActions,
|
|
3395
3407
|
paths: c,
|
|
3396
3408
|
projectRoot: r,
|
|
3397
3409
|
slot: e
|
|
3398
|
-
}), t.userMenuActions && t.userMenuActions.length > 0 && await
|
|
3410
|
+
}), t.userMenuActions && t.userMenuActions.length > 0 && await zi({
|
|
3399
3411
|
actions: t.userMenuActions,
|
|
3400
3412
|
paths: c,
|
|
3401
3413
|
projectRoot: r,
|
|
3402
3414
|
slot: e
|
|
3403
3415
|
});
|
|
3404
|
-
return t.onboardingSteps && t.onboardingSteps.length > 0 && await
|
|
3416
|
+
return t.onboardingSteps && t.onboardingSteps.length > 0 && await Ni(t.onboardingSteps, c, r), t.postLoginRedirect && await Ti({
|
|
3405
3417
|
postLoginRedirect: t.postLoginRedirect,
|
|
3406
3418
|
paths: c,
|
|
3407
3419
|
projectRoot: r,
|
|
3408
3420
|
slot: d[0]
|
|
3409
3421
|
}), l;
|
|
3410
3422
|
}
|
|
3411
|
-
async function
|
|
3423
|
+
async function aa(e) {
|
|
3412
3424
|
let { packs: t, config: n, projectRoot: r, force: i, overwrite: a, slotsByPack: o } = e, s = [];
|
|
3413
3425
|
for (let e of t) {
|
|
3414
|
-
let t = o?.get(e.manifest.name), a = await
|
|
3426
|
+
let t = o?.get(e.manifest.name), a = await ra({
|
|
3415
3427
|
manifest: e.manifest,
|
|
3416
3428
|
config: n,
|
|
3417
3429
|
projectRoot: r,
|
|
@@ -3431,7 +3443,7 @@ async function ra(e) {
|
|
|
3431
3443
|
};
|
|
3432
3444
|
let c = [], l = [], u = [], d = [], f = n;
|
|
3433
3445
|
for (let e of t) {
|
|
3434
|
-
let t = o?.get(e.manifest.name), n = await
|
|
3446
|
+
let t = o?.get(e.manifest.name), n = await ia({
|
|
3435
3447
|
manifest: e.manifest,
|
|
3436
3448
|
config: f,
|
|
3437
3449
|
projectRoot: r,
|
|
@@ -3440,7 +3452,7 @@ async function ra(e) {
|
|
|
3440
3452
|
packDir: e.packDir,
|
|
3441
3453
|
slots: t
|
|
3442
3454
|
});
|
|
3443
|
-
c.push(...n.installed), l.push(...n.skipped), u.push(...n.errors), f = await
|
|
3455
|
+
c.push(...n.installed), l.push(...n.skipped), u.push(...n.errors), f = await oa(f, e.manifest, r), d.push(e.manifest.name);
|
|
3444
3456
|
}
|
|
3445
3457
|
return {
|
|
3446
3458
|
installed: c,
|
|
@@ -3451,7 +3463,7 @@ async function ra(e) {
|
|
|
3451
3463
|
config: f
|
|
3452
3464
|
};
|
|
3453
3465
|
}
|
|
3454
|
-
async function
|
|
3466
|
+
async function oa(e, t, n) {
|
|
3455
3467
|
let r = typeof t == "string" ? t : t.name, i = typeof t == "string" ? [] : Dr(t.env), a = Or([...e.onboarding?.envSections ?? [], ...i]), o = {
|
|
3456
3468
|
...e,
|
|
3457
3469
|
installedPacks: [...e.installedPacks ?? [], r],
|
|
@@ -3462,7 +3474,7 @@ async function ia(e, t, n) {
|
|
|
3462
3474
|
};
|
|
3463
3475
|
return await Nr(n, o), o;
|
|
3464
3476
|
}
|
|
3465
|
-
async function
|
|
3477
|
+
async function sa(e) {
|
|
3466
3478
|
let { manifest: t, config: n, projectRoot: r, templateDir: i } = e, a = n.paths;
|
|
3467
3479
|
if (!a) throw Error("stack.json is missing 'paths' configuration. Run 'npx @hype-stack/cli init' to set it up.");
|
|
3468
3480
|
let o = [], s = [], c = t.files.filter((e) => e.strategy === "merge"), l = new Set(c.map((e) => Vr(e.source, i))), u = T.join(i, "files");
|
|
@@ -3472,7 +3484,7 @@ async function aa(e) {
|
|
|
3472
3484
|
if (!t.isDirectory()) continue;
|
|
3473
3485
|
let e = a[t.name]?.root;
|
|
3474
3486
|
if (!e) continue;
|
|
3475
|
-
let n = await
|
|
3487
|
+
let n = await Qi({
|
|
3476
3488
|
src: T.join(u, t.name),
|
|
3477
3489
|
dest: T.resolve(r, e),
|
|
3478
3490
|
projectRoot: r,
|
|
@@ -3482,7 +3494,7 @@ async function aa(e) {
|
|
|
3482
3494
|
}
|
|
3483
3495
|
}
|
|
3484
3496
|
for (let e of c) {
|
|
3485
|
-
let t = await
|
|
3497
|
+
let t = await ta({
|
|
3486
3498
|
file: e,
|
|
3487
3499
|
packDir: i,
|
|
3488
3500
|
paths: a,
|
|
@@ -3493,11 +3505,12 @@ async function aa(e) {
|
|
|
3493
3505
|
t.status === "installed" ? o.push(t.path) : t.status === "error" && s.push(`${t.path}: ${t.reason}`);
|
|
3494
3506
|
}
|
|
3495
3507
|
let d = T.join(Br("{{frontend.root}}", a, r), "src", "routes"), f = T.join(d, "(public)", "index.tsx"), p = T.join(d, "(private)", "index.tsx");
|
|
3496
|
-
return await Y(f) && await Y(p) && await y.rm(p, { force: !0 }), t.frontendRoutes && t.frontendRoutes.length > 0 && await yi(t.frontendRoutes, a, r), t.nav && t.nav.length > 0 && await
|
|
3508
|
+
return await Y(f) && await Y(p) && await y.rm(p, { force: !0 }), t.frontendRoutes && t.frontendRoutes.length > 0 && await yi(t.frontendRoutes, a, r), t.nav && t.nav.length > 0 && await wi({
|
|
3497
3509
|
entries: t.nav,
|
|
3498
3510
|
paths: a,
|
|
3499
|
-
projectRoot: r
|
|
3500
|
-
|
|
3511
|
+
projectRoot: r,
|
|
3512
|
+
override: !0
|
|
3513
|
+
}), t.postLoginRedirect && await Ti({
|
|
3501
3514
|
postLoginRedirect: t.postLoginRedirect,
|
|
3502
3515
|
paths: a,
|
|
3503
3516
|
projectRoot: r
|
|
@@ -3508,32 +3521,32 @@ async function aa(e) {
|
|
|
3508
3521
|
}
|
|
3509
3522
|
//#endregion
|
|
3510
3523
|
//#region src/core/pack-categories.ts
|
|
3511
|
-
var
|
|
3524
|
+
var ca = [
|
|
3512
3525
|
"starter",
|
|
3513
3526
|
"layout",
|
|
3514
3527
|
"feature"
|
|
3515
|
-
],
|
|
3528
|
+
], la = {
|
|
3516
3529
|
starter: "Starter",
|
|
3517
3530
|
layout: "Layout",
|
|
3518
3531
|
feature: "Features"
|
|
3519
|
-
},
|
|
3520
|
-
function
|
|
3532
|
+
}, ua = new Set(["starter", "layout"]), da = "starter-saas-betterauth", fa = "layout-basic";
|
|
3533
|
+
function pa(e, t = {}) {
|
|
3521
3534
|
let n = [];
|
|
3522
|
-
for (let r of
|
|
3535
|
+
for (let r of ca) {
|
|
3523
3536
|
let i = e.filter((e) => e.category === r);
|
|
3524
3537
|
if (i.length === 0) continue;
|
|
3525
|
-
let a =
|
|
3538
|
+
let a = ua.has(r) ? "single" : "multiple";
|
|
3526
3539
|
if (r === "layout") {
|
|
3527
|
-
n.push(
|
|
3540
|
+
n.push(ha("frontend", i)), t.adminAvailable && n.push(ha("admin", i));
|
|
3528
3541
|
continue;
|
|
3529
3542
|
}
|
|
3530
3543
|
if (r === "starter") {
|
|
3531
|
-
n.push(
|
|
3544
|
+
n.push(ma(i));
|
|
3532
3545
|
continue;
|
|
3533
3546
|
}
|
|
3534
3547
|
n.push({
|
|
3535
3548
|
category: r,
|
|
3536
|
-
label:
|
|
3549
|
+
label: la[r],
|
|
3537
3550
|
mode: a,
|
|
3538
3551
|
packs: i,
|
|
3539
3552
|
preselect: null
|
|
@@ -3541,36 +3554,36 @@ function da(e, t = {}) {
|
|
|
3541
3554
|
}
|
|
3542
3555
|
return n;
|
|
3543
3556
|
}
|
|
3544
|
-
function
|
|
3545
|
-
let t = e.some((e) => e.name ===
|
|
3557
|
+
function ma(e) {
|
|
3558
|
+
let t = e.some((e) => e.name === da);
|
|
3546
3559
|
return {
|
|
3547
3560
|
category: "starter",
|
|
3548
|
-
label:
|
|
3561
|
+
label: la.starter,
|
|
3549
3562
|
mode: "single",
|
|
3550
3563
|
packs: e,
|
|
3551
|
-
preselect: t ?
|
|
3564
|
+
preselect: t ? da : null
|
|
3552
3565
|
};
|
|
3553
3566
|
}
|
|
3554
|
-
function
|
|
3555
|
-
let n = t.some((e) => e.name ===
|
|
3567
|
+
function ha(e, t) {
|
|
3568
|
+
let n = t.some((e) => e.name === fa);
|
|
3556
3569
|
return {
|
|
3557
3570
|
category: "layout",
|
|
3558
3571
|
label: e === "admin" ? "Admin Layout" : "Layout",
|
|
3559
3572
|
mode: "single",
|
|
3560
3573
|
packs: t,
|
|
3561
|
-
preselect: n ?
|
|
3574
|
+
preselect: n ? fa : null,
|
|
3562
3575
|
slot: e
|
|
3563
3576
|
};
|
|
3564
3577
|
}
|
|
3565
3578
|
//#endregion
|
|
3566
3579
|
//#region src/core/post-setup.ts
|
|
3567
|
-
async function
|
|
3580
|
+
async function ga() {
|
|
3568
3581
|
return (await J("docker", ["info"], { cwd: process.cwd() })).exitCode === 0;
|
|
3569
3582
|
}
|
|
3570
|
-
async function
|
|
3583
|
+
async function _a(e) {
|
|
3571
3584
|
return Y(`${e}/apps/backend/.env`);
|
|
3572
3585
|
}
|
|
3573
|
-
async function
|
|
3586
|
+
async function va(e, t, n) {
|
|
3574
3587
|
let r = n ? `Start services with ${L.command("docker compose up -d")}?` : `Docker is not running. Start services with ${L.command("docker compose up -d")}?`, i = t ? !0 : await s.confirm({
|
|
3575
3588
|
message: r,
|
|
3576
3589
|
initialValue: !0
|
|
@@ -3583,13 +3596,41 @@ async function ga(e, t, n) {
|
|
|
3583
3596
|
"up",
|
|
3584
3597
|
"-d"
|
|
3585
3598
|
], { cwd: `${e}/apps/backend` });
|
|
3586
|
-
return o.exitCode === 0 ? (a.stop(L.success("Docker services started")), !0) : (a.error("Failed to start Docker services"),
|
|
3599
|
+
return o.exitCode === 0 ? (a.stop(L.success("Docker services started")), !0) : (a.error("Failed to start Docker services"), Ca(o), !1);
|
|
3587
3600
|
}
|
|
3588
|
-
function
|
|
3601
|
+
function ya(e) {
|
|
3589
3602
|
let t = (e.stderr || e.stdout).trim();
|
|
3590
3603
|
t && s.log.warn(L.muted(t));
|
|
3591
3604
|
}
|
|
3592
|
-
|
|
3605
|
+
function ba(e) {
|
|
3606
|
+
return /is already in use by container|Conflict\. The container name/i.test(e) ? "container" : /port is already allocated|address already in use|Bind for .+ failed|failed to (?:bind|set up) .*port/i.test(e) ? "port" : null;
|
|
3607
|
+
}
|
|
3608
|
+
function xa(e) {
|
|
3609
|
+
return e.match(/container name "\/?([^"]+)"/i)?.[1] ?? null;
|
|
3610
|
+
}
|
|
3611
|
+
function Sa(e) {
|
|
3612
|
+
return e.match(/Bind for [^:]*:(\d{2,5})/i)?.[1] ?? e.match(/:(\d{2,5})(?:->|\b)[^\n]*(?:already allocated|already in use)/i)?.[1] ?? null;
|
|
3613
|
+
}
|
|
3614
|
+
function Ca(e) {
|
|
3615
|
+
let t = (e.stderr || e.stdout).trim(), n = ba(t);
|
|
3616
|
+
if (!n) {
|
|
3617
|
+
t && s.log.warn(L.muted(t));
|
|
3618
|
+
return;
|
|
3619
|
+
}
|
|
3620
|
+
if (n === "container") {
|
|
3621
|
+
let e = xa(t);
|
|
3622
|
+
s.log.warn(L.muted(`${e ? `Container ${L.command(e)}` : "One of this project's containers"} is already running, most likely from another Hype Stack project. The template uses fixed container names, so two projects can't run their services at the same time.`));
|
|
3623
|
+
} else {
|
|
3624
|
+
let e = Sa(t);
|
|
3625
|
+
s.log.warn(L.muted(`${e ? `Host port ${L.command(e)}` : "A host port this project needs"} is already taken, most likely by another Hype Stack project. The template uses fixed ports, so two projects can't run their services at the same time.`));
|
|
3626
|
+
}
|
|
3627
|
+
z([
|
|
3628
|
+
`${L.command("docker ps")} ${L.muted("see what's already running")}`,
|
|
3629
|
+
`${L.command("docker compose down")} ${L.muted("run in the other project's apps/backend to free its services")}`,
|
|
3630
|
+
L.muted("then re-run this command and start Docker again")
|
|
3631
|
+
].join("\n"), "Free up Docker, then retry"), t && s.log.warn(L.muted(t));
|
|
3632
|
+
}
|
|
3633
|
+
async function wa(e, t = 15, n = 2e3) {
|
|
3593
3634
|
for (let r = 0; r < t; r++) {
|
|
3594
3635
|
if ((await J("docker", [
|
|
3595
3636
|
"compose",
|
|
@@ -3604,8 +3645,8 @@ async function va(e, t = 15, n = 2e3) {
|
|
|
3604
3645
|
}
|
|
3605
3646
|
return !1;
|
|
3606
3647
|
}
|
|
3607
|
-
var
|
|
3608
|
-
async function
|
|
3648
|
+
var Ta = "Database schema is up to date";
|
|
3649
|
+
async function Ea(e) {
|
|
3609
3650
|
let t = await J("pnpm", [
|
|
3610
3651
|
"--filter",
|
|
3611
3652
|
"@internal/backend",
|
|
@@ -3614,9 +3655,9 @@ async function ba(e) {
|
|
|
3614
3655
|
"migrate",
|
|
3615
3656
|
"status"
|
|
3616
3657
|
], { cwd: e });
|
|
3617
|
-
return t.exitCode === 0 ? `${t.stdout}\n${t.stderr}`.includes(
|
|
3658
|
+
return t.exitCode === 0 ? `${t.stdout}\n${t.stderr}`.includes(Ta) : !1;
|
|
3618
3659
|
}
|
|
3619
|
-
async function
|
|
3660
|
+
async function Da(e) {
|
|
3620
3661
|
let t = s.spinner();
|
|
3621
3662
|
t.start("Running database migrations...");
|
|
3622
3663
|
let n = await J("pnpm", [
|
|
@@ -3624,15 +3665,15 @@ async function xa(e) {
|
|
|
3624
3665
|
"@internal/backend",
|
|
3625
3666
|
"migration:latest"
|
|
3626
3667
|
], { cwd: e });
|
|
3627
|
-
return n.exitCode === 0 ? (t.stop(L.success("Database migrations applied")), !0) : (t.error("Migrations failed"),
|
|
3668
|
+
return n.exitCode === 0 ? (t.stop(L.success("Database migrations applied")), !0) : (t.error("Migrations failed"), ya(n), s.log.warn(L.muted("Run `pnpm --filter @internal/backend migration:latest` manually to apply migrations.")), !1);
|
|
3628
3669
|
}
|
|
3629
|
-
async function
|
|
3630
|
-
if (!await
|
|
3670
|
+
async function Oa(e, t, n = {}) {
|
|
3671
|
+
if (!await va(e, t, await ga())) return !1;
|
|
3631
3672
|
let r = s.spinner();
|
|
3632
|
-
return r.start("Waiting for Postgres to be ready..."), await
|
|
3673
|
+
return r.start("Waiting for Postgres to be ready..."), await wa(e, n.postgresMaxAttempts ?? 15, n.postgresCheckIntervalMs ?? 2e3) ? (r.stop(L.success("Postgres is ready")), !0) : (r.error("Postgres health check timed out"), s.log.warn(L.muted("Run migrations manually once Postgres is ready: pnpm --filter @internal/backend migration:latest")), !1);
|
|
3633
3674
|
}
|
|
3634
|
-
async function
|
|
3635
|
-
if (!await
|
|
3675
|
+
async function ka(e, t, n = {}) {
|
|
3676
|
+
if (!await Oa(e, t, n)) return;
|
|
3636
3677
|
let r = t ? !0 : await s.confirm({
|
|
3637
3678
|
message: `Run database migrations with ${L.command("prisma migrate deploy")}?`,
|
|
3638
3679
|
initialValue: !0
|
|
@@ -3641,21 +3682,21 @@ async function Ca(e, t, n = {}) {
|
|
|
3641
3682
|
s.log.info(L.muted("Skipping database migrations."));
|
|
3642
3683
|
return;
|
|
3643
3684
|
}
|
|
3644
|
-
await
|
|
3685
|
+
await Da(e);
|
|
3645
3686
|
}
|
|
3646
|
-
async function
|
|
3647
|
-
if (!await
|
|
3687
|
+
async function Aa(e, t, n = {}) {
|
|
3688
|
+
if (!await _a(e)) {
|
|
3648
3689
|
s.log.warn(`${L.path(".env")} not found in ${L.path("apps/backend")}. Skipping Docker and migrations - configure it first.`);
|
|
3649
3690
|
return;
|
|
3650
3691
|
}
|
|
3651
|
-
await
|
|
3692
|
+
await ka(e, t, n);
|
|
3652
3693
|
}
|
|
3653
|
-
async function
|
|
3654
|
-
return await
|
|
3694
|
+
async function ja(e, t, n = {}) {
|
|
3695
|
+
return await _a(e) ? Oa(e, t, n) : (s.log.warn(`${L.path(".env")} not found in ${L.path("apps/backend")}. Skipping Docker - configure it first.`), !1);
|
|
3655
3696
|
}
|
|
3656
3697
|
//#endregion
|
|
3657
3698
|
//#region src/core/resolve.ts
|
|
3658
|
-
function
|
|
3699
|
+
function Ma(e) {
|
|
3659
3700
|
let t = /* @__PURE__ */ new Map();
|
|
3660
3701
|
for (let n of e) t.set(n.name, {
|
|
3661
3702
|
name: n.name,
|
|
@@ -3663,7 +3704,7 @@ function Ea(e) {
|
|
|
3663
3704
|
});
|
|
3664
3705
|
return t;
|
|
3665
3706
|
}
|
|
3666
|
-
function
|
|
3707
|
+
function Na(e, t, n = /* @__PURE__ */ new Set()) {
|
|
3667
3708
|
let r = /* @__PURE__ */ new Set();
|
|
3668
3709
|
function i(e) {
|
|
3669
3710
|
if (n.has(e)) return [];
|
|
@@ -3677,10 +3718,10 @@ function Da(e, t, n = /* @__PURE__ */ new Set()) {
|
|
|
3677
3718
|
}
|
|
3678
3719
|
return i(e);
|
|
3679
3720
|
}
|
|
3680
|
-
function
|
|
3721
|
+
function Pa(e, t, n = []) {
|
|
3681
3722
|
let r = new Set(n), i = new Set(n), a = [];
|
|
3682
3723
|
for (let n of e) {
|
|
3683
|
-
let e =
|
|
3724
|
+
let e = Na(n, t, new Set(i));
|
|
3684
3725
|
for (let t of e) i.has(t) || (i.add(t), a.push(t));
|
|
3685
3726
|
}
|
|
3686
3727
|
return {
|
|
@@ -3688,7 +3729,7 @@ function Oa(e, t, n = []) {
|
|
|
3688
3729
|
alreadyInstalled: e.filter((e) => r.has(e))
|
|
3689
3730
|
};
|
|
3690
3731
|
}
|
|
3691
|
-
function
|
|
3732
|
+
function Fa(e) {
|
|
3692
3733
|
let { order: t, graph: n, isLocked: r, installed: i = [] } = e, a = new Set(i), o = /* @__PURE__ */ new Set();
|
|
3693
3734
|
for (let e of t) {
|
|
3694
3735
|
let t = n.get(e)?.dependencies.some((e) => !a.has(e) && o.has(e)) ?? !1;
|
|
@@ -3701,7 +3742,7 @@ function ka(e) {
|
|
|
3701
3742
|
}
|
|
3702
3743
|
//#endregion
|
|
3703
3744
|
//#region src/core/variants.ts
|
|
3704
|
-
function
|
|
3745
|
+
function Ia(e, t = {}) {
|
|
3705
3746
|
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map();
|
|
3706
3747
|
for (let i of e) {
|
|
3707
3748
|
let e = t[i.family] ?? i.default;
|
|
@@ -3713,14 +3754,14 @@ function Aa(e, t = {}) {
|
|
|
3713
3754
|
familyOf: r
|
|
3714
3755
|
};
|
|
3715
3756
|
}
|
|
3716
|
-
function
|
|
3757
|
+
function La(e, t, n) {
|
|
3717
3758
|
return [...e.map((e) => n.chosen.get(e.family) ?? e.default), ...t];
|
|
3718
3759
|
}
|
|
3719
|
-
function
|
|
3760
|
+
function Ra(e, t) {
|
|
3720
3761
|
let n = t.familyOf.get(e);
|
|
3721
3762
|
return n ? t.chosen.get(n) ?? e : e;
|
|
3722
3763
|
}
|
|
3723
|
-
function
|
|
3764
|
+
function za(e, t) {
|
|
3724
3765
|
let n = /* @__PURE__ */ new Map();
|
|
3725
3766
|
for (let t of e) t.family && n.set(t.name, t.family);
|
|
3726
3767
|
let r = new Set(t), i = /* @__PURE__ */ new Map();
|
|
@@ -3736,65 +3777,65 @@ function Na(e, t) {
|
|
|
3736
3777
|
familyOf: n
|
|
3737
3778
|
};
|
|
3738
3779
|
}
|
|
3739
|
-
function
|
|
3780
|
+
function Ba(e, t) {
|
|
3740
3781
|
return e.map((e) => ({
|
|
3741
3782
|
...e,
|
|
3742
|
-
dependencies: e.dependencies.map((e) =>
|
|
3783
|
+
dependencies: e.dependencies.map((e) => Ra(e, t))
|
|
3743
3784
|
}));
|
|
3744
3785
|
}
|
|
3745
3786
|
//#endregion
|
|
3746
3787
|
//#region src/ui/banner.ts
|
|
3747
|
-
var
|
|
3788
|
+
var Va = [
|
|
3748
3789
|
" ██╗ ██╗ ██╗ ██╗ ██████╗ ███████╗",
|
|
3749
3790
|
" ██║ ██║ ╚██╗ ██╔╝ ██╔══██╗ ██╔════╝",
|
|
3750
3791
|
" ███████║ ╚████╔╝ ██████╔╝ █████╗ ",
|
|
3751
3792
|
" ██╔══██║ ╚██╔╝ ██╔═══╝ ██╔══╝ ",
|
|
3752
3793
|
" ██║ ██║ ██║ ██║ ███████╗",
|
|
3753
3794
|
" ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝"
|
|
3754
|
-
],
|
|
3795
|
+
], Ha = [
|
|
3755
3796
|
" ███████╗ ████████╗ █████╗ ██████╗ ██╗ ██╗",
|
|
3756
3797
|
" ██╔════╝ ╚══██╔══╝ ██╔══██╗ ██╔════╝ ██║ ██╔╝",
|
|
3757
3798
|
" ███████╗ ██║ ███████║ ██║ █████╔╝ ",
|
|
3758
3799
|
" ╚════██║ ██║ ██╔══██║ ██║ ██╔═██╗ ",
|
|
3759
3800
|
" ███████║ ██║ ██║ ██║ ╚██████╗ ██║ ██╗",
|
|
3760
3801
|
" ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝"
|
|
3761
|
-
],
|
|
3802
|
+
], Ua = [
|
|
3762
3803
|
253,
|
|
3763
3804
|
176,
|
|
3764
3805
|
21
|
|
3765
|
-
],
|
|
3806
|
+
], Wa = [
|
|
3766
3807
|
245,
|
|
3767
3808
|
76,
|
|
3768
3809
|
2
|
|
3769
|
-
],
|
|
3810
|
+
], Ga = 5, Ka = [
|
|
3770
3811
|
17,
|
|
3771
3812
|
103,
|
|
3772
3813
|
248
|
|
3773
|
-
],
|
|
3814
|
+
], qa = [
|
|
3774
3815
|
42,
|
|
3775
3816
|
160,
|
|
3776
3817
|
250
|
|
3777
|
-
],
|
|
3778
|
-
function
|
|
3818
|
+
], Ja = .2;
|
|
3819
|
+
function Ya() {
|
|
3779
3820
|
console.log();
|
|
3780
|
-
for (let e of Se(
|
|
3781
|
-
start:
|
|
3782
|
-
end:
|
|
3783
|
-
angle:
|
|
3821
|
+
for (let e of Se(Va, {
|
|
3822
|
+
start: Ua,
|
|
3823
|
+
end: Wa,
|
|
3824
|
+
angle: Ga
|
|
3784
3825
|
})) console.log(b.bold(e));
|
|
3785
|
-
for (let e of Se(
|
|
3786
|
-
start:
|
|
3787
|
-
end:
|
|
3788
|
-
angle:
|
|
3826
|
+
for (let e of Se(Ha, {
|
|
3827
|
+
start: Ka,
|
|
3828
|
+
end: qa,
|
|
3829
|
+
angle: Ja
|
|
3789
3830
|
})) console.log(b.bold(e));
|
|
3790
3831
|
console.log(), console.log(` ${R.spark} ${b.dim("v" + A)} ${b.dim("·")} ${be("Ship web + desktop apps from one codebase")}`), console.log();
|
|
3791
3832
|
}
|
|
3792
|
-
function
|
|
3833
|
+
function Xa() {
|
|
3793
3834
|
console.log(), console.log(` ${R.bolt} ${_e.orange("Hype")}${_e.skyBlue("Stack")} ${b.dim("v" + A)}`), console.log();
|
|
3794
3835
|
}
|
|
3795
3836
|
//#endregion
|
|
3796
3837
|
//#region src/ui/pack-multiselect.ts
|
|
3797
|
-
var
|
|
3838
|
+
var Za = class extends O {
|
|
3798
3839
|
options;
|
|
3799
3840
|
cursor = 0;
|
|
3800
3841
|
selected;
|
|
@@ -3898,44 +3939,64 @@ var Ga = class extends O {
|
|
|
3898
3939
|
}
|
|
3899
3940
|
}
|
|
3900
3941
|
};
|
|
3901
|
-
function
|
|
3902
|
-
return new
|
|
3942
|
+
function Qa(e) {
|
|
3943
|
+
return new Za(e).prompt();
|
|
3903
3944
|
}
|
|
3904
3945
|
//#endregion
|
|
3905
3946
|
//#region src/utils/naming.ts
|
|
3906
|
-
function
|
|
3947
|
+
function $a(e) {
|
|
3907
3948
|
return e.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
3908
3949
|
}
|
|
3909
|
-
function
|
|
3950
|
+
function eo(e) {
|
|
3910
3951
|
return e.split(/[-_]/).filter(Boolean).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join(" ");
|
|
3911
3952
|
}
|
|
3912
3953
|
//#endregion
|
|
3913
3954
|
//#region src/utils/validate.ts
|
|
3914
|
-
function
|
|
3955
|
+
function to(e) {
|
|
3915
3956
|
if (!e.trim()) return "Project name cannot be empty";
|
|
3916
3957
|
if (e.length > 214) return "Project name is too long (max 214 characters)";
|
|
3917
|
-
let t =
|
|
3958
|
+
let t = $a(e);
|
|
3918
3959
|
if (!ie.test(t)) return "Project name must contain at least one letter or number";
|
|
3919
3960
|
}
|
|
3920
3961
|
//#endregion
|
|
3921
3962
|
//#region src/core/apply-mode.ts
|
|
3922
|
-
var
|
|
3923
|
-
function
|
|
3924
|
-
return e.replace(
|
|
3963
|
+
var no = "src/hooks/use-theme.ts", ro = /(\bexport\s+const\s+defaultTheme\s*=\s*)(["'])(?:light|dark)\2/;
|
|
3964
|
+
function io(e, t) {
|
|
3965
|
+
return e.replace(ro, (e, n, r) => `${n}${r}${t}${r}`);
|
|
3925
3966
|
}
|
|
3926
|
-
async function
|
|
3927
|
-
let n = T.resolve(e,
|
|
3967
|
+
async function ao(e, t) {
|
|
3968
|
+
let n = T.resolve(e, no), r;
|
|
3928
3969
|
try {
|
|
3929
3970
|
r = await y.readFile(n, "utf-8");
|
|
3930
3971
|
} catch {
|
|
3931
3972
|
return !1;
|
|
3932
3973
|
}
|
|
3933
|
-
let i =
|
|
3974
|
+
let i = io(r, t);
|
|
3975
|
+
return i === r || await y.writeFile(n, i, "utf-8"), !0;
|
|
3976
|
+
}
|
|
3977
|
+
//#endregion
|
|
3978
|
+
//#region src/core/apply-radius.ts
|
|
3979
|
+
var oo = /(^[ \t]*--radius(?![\w-])[ \t]*:[ \t]*)([^;\n]*);/gm;
|
|
3980
|
+
function so(e) {
|
|
3981
|
+
return /^[0-9]*\.?[0-9]+(rem|em|px)$/.test(e.trim());
|
|
3982
|
+
}
|
|
3983
|
+
function co(e, t) {
|
|
3984
|
+
return e.replace(oo, (e, n) => `${n}${t};`);
|
|
3985
|
+
}
|
|
3986
|
+
var lo = "assets/styles.css";
|
|
3987
|
+
async function uo(e, t) {
|
|
3988
|
+
let n = T.resolve(e, lo), r;
|
|
3989
|
+
try {
|
|
3990
|
+
r = await y.readFile(n, "utf-8");
|
|
3991
|
+
} catch {
|
|
3992
|
+
return !1;
|
|
3993
|
+
}
|
|
3994
|
+
let i = co(r, t);
|
|
3934
3995
|
return i === r || await y.writeFile(n, i, "utf-8"), !0;
|
|
3935
3996
|
}
|
|
3936
3997
|
//#endregion
|
|
3937
3998
|
//#region src/core/apply-theme.ts
|
|
3938
|
-
function
|
|
3999
|
+
function fo(e, t) {
|
|
3939
4000
|
let n = 0;
|
|
3940
4001
|
for (; n < e.length;) {
|
|
3941
4002
|
let r = e.indexOf(t, n);
|
|
@@ -3958,46 +4019,46 @@ function eo(e, t) {
|
|
|
3958
4019
|
}
|
|
3959
4020
|
return null;
|
|
3960
4021
|
}
|
|
3961
|
-
function
|
|
4022
|
+
function po(e, t) {
|
|
3962
4023
|
let n = e;
|
|
3963
4024
|
for (let [e, r] of Object.entries(t)) {
|
|
3964
|
-
let t = RegExp(`(^[ \\t]*--${
|
|
4025
|
+
let t = RegExp(`(^[ \\t]*--${mo(e)}[ \\t]*:[ \\t]*)([^;\\n]*);`, "m");
|
|
3965
4026
|
n = n.replace(t, (e, t) => `${t}${r};`);
|
|
3966
4027
|
}
|
|
3967
4028
|
return n;
|
|
3968
4029
|
}
|
|
3969
|
-
function
|
|
4030
|
+
function mo(e) {
|
|
3970
4031
|
return e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3971
4032
|
}
|
|
3972
|
-
function
|
|
3973
|
-
let n =
|
|
4033
|
+
function ho(e, t) {
|
|
4034
|
+
let n = fo(e, ":root"), r = fo(e, ".dark"), i = e;
|
|
3974
4035
|
if (n) {
|
|
3975
4036
|
let e = i.slice(0, n.bodyStart), r = i.slice(n.bodyStart, n.bodyEnd), a = i.slice(n.bodyEnd);
|
|
3976
|
-
i = e +
|
|
4037
|
+
i = e + po(r, t.light) + a;
|
|
3977
4038
|
}
|
|
3978
4039
|
if (r) {
|
|
3979
|
-
let e =
|
|
4040
|
+
let e = fo(i, ".dark");
|
|
3980
4041
|
if (e) {
|
|
3981
4042
|
let n = i.slice(0, e.bodyStart), r = i.slice(e.bodyStart, e.bodyEnd), a = i.slice(e.bodyEnd);
|
|
3982
|
-
i = n +
|
|
4043
|
+
i = n + po(r, t.dark) + a;
|
|
3983
4044
|
}
|
|
3984
4045
|
}
|
|
3985
4046
|
return i;
|
|
3986
4047
|
}
|
|
3987
|
-
var
|
|
3988
|
-
async function
|
|
3989
|
-
let n = T.resolve(e,
|
|
4048
|
+
var go = "assets/styles.css";
|
|
4049
|
+
async function _o(e, t) {
|
|
4050
|
+
let n = T.resolve(e, go), r;
|
|
3990
4051
|
try {
|
|
3991
4052
|
r = await y.readFile(n, "utf-8");
|
|
3992
4053
|
} catch {
|
|
3993
4054
|
return !1;
|
|
3994
4055
|
}
|
|
3995
|
-
let i =
|
|
4056
|
+
let i = ho(r, t);
|
|
3996
4057
|
return i === r || await y.writeFile(n, i, "utf-8"), !0;
|
|
3997
4058
|
}
|
|
3998
4059
|
//#endregion
|
|
3999
4060
|
//#region src/core/clone.ts
|
|
4000
|
-
async function
|
|
4061
|
+
async function vo(e) {
|
|
4001
4062
|
let t = await ee(te, {
|
|
4002
4063
|
dir: e,
|
|
4003
4064
|
force: !0
|
|
@@ -4009,7 +4070,7 @@ async function oo(e) {
|
|
|
4009
4070
|
}
|
|
4010
4071
|
//#endregion
|
|
4011
4072
|
//#region src/core/editor-config.ts
|
|
4012
|
-
function
|
|
4073
|
+
function yo(e) {
|
|
4013
4074
|
let t = {
|
|
4014
4075
|
globs: [],
|
|
4015
4076
|
alwaysApply: !1
|
|
@@ -4044,10 +4105,10 @@ function so(e) {
|
|
|
4044
4105
|
content: i
|
|
4045
4106
|
};
|
|
4046
4107
|
}
|
|
4047
|
-
function
|
|
4108
|
+
function bo(e) {
|
|
4048
4109
|
return e.frontmatter.globs.length > 0 ? `---\npaths:\n${e.frontmatter.globs.map((e) => ` - "${e}"`).join("\n")}\n---\n\n${e.content}` : e.content;
|
|
4049
4110
|
}
|
|
4050
|
-
function
|
|
4111
|
+
function xo(e) {
|
|
4051
4112
|
let t;
|
|
4052
4113
|
t = e.frontmatter.alwaysApply ? "always_on" : e.frontmatter.globs.length > 0 ? "glob" : "model_decision";
|
|
4053
4114
|
let n = [`trigger: ${t}`];
|
|
@@ -4057,30 +4118,30 @@ function lo(e) {
|
|
|
4057
4118
|
}
|
|
4058
4119
|
return e.frontmatter.description && n.push(`description: ${e.frontmatter.description}`), `---\n${n.join("\n")}\n---\n\n${e.content}`;
|
|
4059
4120
|
}
|
|
4060
|
-
function
|
|
4121
|
+
function So(e) {
|
|
4061
4122
|
return e.frontmatter.globs.length > 0 ? `---\napplyTo: "${e.frontmatter.globs.join(", ")}"\n---\n\n${e.content}` : e.content;
|
|
4062
4123
|
}
|
|
4063
|
-
var
|
|
4124
|
+
var Co = {
|
|
4064
4125
|
claude: {
|
|
4065
4126
|
rulesDir: ".claude/rules",
|
|
4066
4127
|
extension: ".md",
|
|
4067
|
-
convert:
|
|
4128
|
+
convert: bo
|
|
4068
4129
|
},
|
|
4069
4130
|
windsurf: {
|
|
4070
4131
|
rulesDir: ".windsurf/rules",
|
|
4071
4132
|
extension: ".md",
|
|
4072
|
-
convert:
|
|
4133
|
+
convert: xo
|
|
4073
4134
|
},
|
|
4074
4135
|
copilot: {
|
|
4075
4136
|
rulesDir: ".github/instructions",
|
|
4076
4137
|
extension: ".instructions.md",
|
|
4077
|
-
convert:
|
|
4138
|
+
convert: So
|
|
4078
4139
|
}
|
|
4079
4140
|
};
|
|
4080
|
-
async function
|
|
4141
|
+
async function wo(e) {
|
|
4081
4142
|
let t = T.join(e, oe), n = (await y.readdir(t, { withFileTypes: !0 }).catch(() => [])).filter((e) => e.isFile() && e.name.endsWith(".mdc"));
|
|
4082
4143
|
return await Promise.all(n.map(async (e) => {
|
|
4083
|
-
let n = T.join(t, e.name), { frontmatter: r, content: i } =
|
|
4144
|
+
let n = T.join(t, e.name), { frontmatter: r, content: i } = yo(await y.readFile(n, "utf-8"));
|
|
4084
4145
|
return {
|
|
4085
4146
|
frontmatter: r,
|
|
4086
4147
|
content: i,
|
|
@@ -4088,9 +4149,9 @@ async function po(e) {
|
|
|
4088
4149
|
};
|
|
4089
4150
|
}));
|
|
4090
4151
|
}
|
|
4091
|
-
async function
|
|
4152
|
+
async function To(e, t) {
|
|
4092
4153
|
if (t === "cursor") return;
|
|
4093
|
-
let n =
|
|
4154
|
+
let n = Co[t], r = await wo(e), i = T.join(e, n.rulesDir);
|
|
4094
4155
|
await y.mkdir(i, { recursive: !0 }), await Promise.all(r.map((e) => {
|
|
4095
4156
|
let t = n.convert(e), r = e.filename.replace(/\.mdc$/, n.extension);
|
|
4096
4157
|
return y.writeFile(T.join(i, r), t, "utf-8");
|
|
@@ -4098,21 +4159,21 @@ async function mo(e, t) {
|
|
|
4098
4159
|
}
|
|
4099
4160
|
//#endregion
|
|
4100
4161
|
//#region src/core/env-files.ts
|
|
4101
|
-
var
|
|
4162
|
+
var Eo = [
|
|
4102
4163
|
"apps",
|
|
4103
4164
|
"packages",
|
|
4104
4165
|
"libs",
|
|
4105
4166
|
"shared"
|
|
4106
4167
|
];
|
|
4107
|
-
async function
|
|
4108
|
-
let t = await
|
|
4168
|
+
async function Do(e) {
|
|
4169
|
+
let t = await Oo(e);
|
|
4109
4170
|
return (await Promise.all(t.map(async (t) => {
|
|
4110
4171
|
let n = T.join(T.dirname(t), ".env");
|
|
4111
4172
|
return await Y(n) ? null : (await y.copyFile(t, n), T.relative(e, n));
|
|
4112
4173
|
}))).filter((e) => e !== null).sort();
|
|
4113
4174
|
}
|
|
4114
|
-
async function
|
|
4115
|
-
let t = [T.join(e, ".env.example")], n = await Promise.all(
|
|
4175
|
+
async function Oo(e) {
|
|
4176
|
+
let t = [T.join(e, ".env.example")], n = await Promise.all(Eo.map(async (t) => {
|
|
4116
4177
|
let n = T.join(e, t);
|
|
4117
4178
|
return (await y.readdir(n, { withFileTypes: !0 }).catch(() => [])).filter((e) => e.isDirectory()).map((e) => T.join(n, e.name, ".env.example"));
|
|
4118
4179
|
}));
|
|
@@ -4120,11 +4181,11 @@ async function _o(e) {
|
|
|
4120
4181
|
}
|
|
4121
4182
|
//#endregion
|
|
4122
4183
|
//#region src/core/post-clone.ts
|
|
4123
|
-
var Q = "@hype-stack/",
|
|
4124
|
-
async function
|
|
4184
|
+
var Q = "@hype-stack/", ko = "hype-stack", Ao = "@hype-stack/cli";
|
|
4185
|
+
async function jo(e) {
|
|
4125
4186
|
await mr(T.join(e, ".git"));
|
|
4126
4187
|
}
|
|
4127
|
-
async function
|
|
4188
|
+
async function Mo(e) {
|
|
4128
4189
|
await J("git", ["init"], { cwd: e }), await J("git", ["add", "."], { cwd: e }), await J("git", [
|
|
4129
4190
|
"-c",
|
|
4130
4191
|
"user.name=Hype Stack CLI",
|
|
@@ -4135,19 +4196,19 @@ async function xo(e) {
|
|
|
4135
4196
|
"Initial commit from Hype Stack CLI"
|
|
4136
4197
|
], { cwd: e });
|
|
4137
4198
|
}
|
|
4138
|
-
async function
|
|
4139
|
-
let n = `@${t}/`, r = await
|
|
4199
|
+
async function No(e, t) {
|
|
4200
|
+
let n = `@${t}/`, r = await Vo(e);
|
|
4140
4201
|
for (let e of r) {
|
|
4141
4202
|
let t = await dr(e);
|
|
4142
4203
|
if (!t) continue;
|
|
4143
4204
|
let r = !1;
|
|
4144
|
-
t.name?.startsWith(Q) && (t.name = t.name.replace(Q, n), r = !0),
|
|
4205
|
+
t.name?.startsWith(Q) && (t.name = t.name.replace(Q, n), r = !0), Ro(t.dependencies, n) && (r = !0), Ro(t.devDependencies, n) && (r = !0), t.nx && zo(t.nx, n) && (r = !0);
|
|
4145
4206
|
let i = await y.readFile(e, "utf-8"), a = qr(i, n);
|
|
4146
4207
|
a === i ? r && await fr(e, t) : await y.writeFile(e, a, "utf-8");
|
|
4147
4208
|
}
|
|
4148
|
-
await
|
|
4209
|
+
await qi(e, t), await Io(e, t), await Bo(e, t);
|
|
4149
4210
|
}
|
|
4150
|
-
var
|
|
4211
|
+
var Po = new Set([
|
|
4151
4212
|
".git",
|
|
4152
4213
|
"node_modules",
|
|
4153
4214
|
"dist",
|
|
@@ -4155,10 +4216,10 @@ var Co = new Set([
|
|
|
4155
4216
|
".nx",
|
|
4156
4217
|
".next",
|
|
4157
4218
|
"coverage"
|
|
4158
|
-
]),
|
|
4159
|
-
async function
|
|
4160
|
-
if (t ===
|
|
4161
|
-
let n = await
|
|
4219
|
+
]), Fo = /^(docker-compose|compose)(\.[\w.-]+)?\.ya?ml$/;
|
|
4220
|
+
async function Io(e, t) {
|
|
4221
|
+
if (t === ko) return;
|
|
4222
|
+
let n = await Lo(e);
|
|
4162
4223
|
await Promise.all(n.map(async (e) => {
|
|
4163
4224
|
let n = await y.readFile(e, "utf-8").catch(() => null);
|
|
4164
4225
|
if (!n || !/^name:[ \t]*hype-stack/m.test(n)) return;
|
|
@@ -4166,23 +4227,23 @@ async function To(e, t) {
|
|
|
4166
4227
|
await y.writeFile(e, r, "utf-8");
|
|
4167
4228
|
}));
|
|
4168
4229
|
}
|
|
4169
|
-
async function
|
|
4230
|
+
async function Lo(e) {
|
|
4170
4231
|
let t = await y.readdir(e, { withFileTypes: !0 }).catch(() => []);
|
|
4171
4232
|
return (await Promise.all(t.map(async (t) => {
|
|
4172
4233
|
let n = T.join(e, t.name);
|
|
4173
|
-
return t.isDirectory() ?
|
|
4234
|
+
return t.isDirectory() ? Po.has(t.name) ? [] : Lo(n) : t.isFile() && Fo.test(t.name) ? [n] : [];
|
|
4174
4235
|
}))).flat();
|
|
4175
4236
|
}
|
|
4176
|
-
function
|
|
4237
|
+
function Ro(e, t) {
|
|
4177
4238
|
if (!e) return !1;
|
|
4178
4239
|
let n = !1;
|
|
4179
|
-
for (let r of Object.keys(e)) if (r !==
|
|
4240
|
+
for (let r of Object.keys(e)) if (r !== Ao && r.startsWith(Q)) {
|
|
4180
4241
|
let i = r.replace(Q, t);
|
|
4181
4242
|
e[i] = e[r], delete e[r], n = !0;
|
|
4182
4243
|
}
|
|
4183
4244
|
return n;
|
|
4184
4245
|
}
|
|
4185
|
-
function
|
|
4246
|
+
function zo(e, t) {
|
|
4186
4247
|
if (!e) return !1;
|
|
4187
4248
|
let n = !1;
|
|
4188
4249
|
if (e.implicitDependencies &&= e.implicitDependencies.map((e) => e.startsWith(Q) ? (n = !0, e.replace(Q, t)) : e), e.targets) {
|
|
@@ -4190,13 +4251,13 @@ function Oo(e, t) {
|
|
|
4190
4251
|
}
|
|
4191
4252
|
return n;
|
|
4192
4253
|
}
|
|
4193
|
-
async function
|
|
4254
|
+
async function Bo(e, t) {
|
|
4194
4255
|
let n = T.join(e, "packages/enums/src/app/index.ts"), r = await y.readFile(n, "utf-8").catch(() => null);
|
|
4195
4256
|
if (!r) return;
|
|
4196
|
-
let i =
|
|
4257
|
+
let i = eo(t), a = r.replaceAll(`id: "${ko}"`, `id: "${t}"`).replaceAll(`name: "${ko}"`, `name: "${t}"`).replace(/name: "Hype Stack"/, `name: "${i}"`).replace(/description: ".*?"/, `description: "${i} application"`);
|
|
4197
4258
|
await y.writeFile(n, a, "utf-8");
|
|
4198
4259
|
}
|
|
4199
|
-
async function
|
|
4260
|
+
async function Vo(e) {
|
|
4200
4261
|
let t = [], n = T.join(e, "package.json");
|
|
4201
4262
|
(await y.stat(n).catch(() => null))?.isFile() && t.push(n);
|
|
4202
4263
|
for (let n of [
|
|
@@ -4216,7 +4277,7 @@ async function Ao(e) {
|
|
|
4216
4277
|
}
|
|
4217
4278
|
//#endregion
|
|
4218
4279
|
//#region src/core/readme.ts
|
|
4219
|
-
var
|
|
4280
|
+
var Ho = {
|
|
4220
4281
|
cursor: {
|
|
4221
4282
|
label: "Cursor",
|
|
4222
4283
|
rulesDir: ".cursor/rules"
|
|
@@ -4233,21 +4294,21 @@ var jo = {
|
|
|
4233
4294
|
label: "GitHub Copilot",
|
|
4234
4295
|
rulesDir: ".github/instructions"
|
|
4235
4296
|
}
|
|
4236
|
-
},
|
|
4297
|
+
}, Uo = {
|
|
4237
4298
|
backend: "Hono API server (Postgres, Prisma, Kysely, Valkey cache, WorkOS auth)",
|
|
4238
4299
|
frontend: "React + Vite app talking to the backend through the typed HyperFetch SDK"
|
|
4239
|
-
},
|
|
4300
|
+
}, Wo = {
|
|
4240
4301
|
enums: "Shared enums and app config used across apps",
|
|
4241
4302
|
cli: "Project tooling and code generators"
|
|
4242
4303
|
};
|
|
4243
|
-
function
|
|
4304
|
+
function Go(e, t) {
|
|
4244
4305
|
return Object.entries(e).toSorted(([e], [t]) => e.localeCompare(t)).map(([e, n]) => {
|
|
4245
4306
|
let r = t[e];
|
|
4246
4307
|
return r ? `- \`${n}\` - ${r}` : `- \`${n}\``;
|
|
4247
4308
|
});
|
|
4248
4309
|
}
|
|
4249
|
-
function
|
|
4250
|
-
let { projectName: t, editor: n, workspace: r } = e, i =
|
|
4310
|
+
function Ko(e) {
|
|
4311
|
+
let { projectName: t, editor: n, workspace: r } = e, i = eo(t), a = Ho[n], o = !!r.apps.backend, s = Go(r.apps, Uo), c = Go(r.packages, Wo), l = [];
|
|
4251
4312
|
s.length > 0 && l.push(...s), c.length > 0 && l.push(...c), l.push("- `stack.json` - Hype Stack workspace config (apps, paths, installed packs)");
|
|
4252
4313
|
let u = [];
|
|
4253
4314
|
u.push(`# ${i}`), u.push([
|
|
@@ -4350,13 +4411,13 @@ function Fo(e) {
|
|
|
4350
4411
|
"stays useful."
|
|
4351
4412
|
].join("\n")), u.join("\n\n") + "\n";
|
|
4352
4413
|
}
|
|
4353
|
-
async function
|
|
4414
|
+
async function qo(e, t) {
|
|
4354
4415
|
let n = T.join(e, "README.md");
|
|
4355
|
-
await y.writeFile(n,
|
|
4416
|
+
await y.writeFile(n, Ko(t), "utf-8");
|
|
4356
4417
|
}
|
|
4357
4418
|
//#endregion
|
|
4358
4419
|
//#region src/core/tracking.ts
|
|
4359
|
-
async function
|
|
4420
|
+
async function Jo(e) {
|
|
4360
4421
|
try {
|
|
4361
4422
|
let t = {
|
|
4362
4423
|
"X-Device-Id": er(),
|
|
@@ -4370,7 +4431,7 @@ async function Lo(e) {
|
|
|
4370
4431
|
}
|
|
4371
4432
|
//#endregion
|
|
4372
4433
|
//#region src/core/npm-deps.ts
|
|
4373
|
-
function
|
|
4434
|
+
function Yo(e, t) {
|
|
4374
4435
|
let n = [], r = [];
|
|
4375
4436
|
if (!e) return {
|
|
4376
4437
|
errors: n,
|
|
@@ -4401,7 +4462,7 @@ function Ro(e, t) {
|
|
|
4401
4462
|
operations: r
|
|
4402
4463
|
};
|
|
4403
4464
|
}
|
|
4404
|
-
function
|
|
4465
|
+
function Xo(e) {
|
|
4405
4466
|
let t = {};
|
|
4406
4467
|
for (let n of e) if (n) for (let [e, r] of Object.entries(n)) t[e] = {
|
|
4407
4468
|
...t[e],
|
|
@@ -4409,7 +4470,7 @@ function zo(e) {
|
|
|
4409
4470
|
};
|
|
4410
4471
|
return t;
|
|
4411
4472
|
}
|
|
4412
|
-
async function
|
|
4473
|
+
async function Zo(e, t, n = J) {
|
|
4413
4474
|
let r = [];
|
|
4414
4475
|
for (let i of e) {
|
|
4415
4476
|
let e = T.join(t, i.relativeDir);
|
|
@@ -4445,14 +4506,14 @@ async function Bo(e, t, n = J) {
|
|
|
4445
4506
|
function $(e) {
|
|
4446
4507
|
return e instanceof Error ? e.message : String(e);
|
|
4447
4508
|
}
|
|
4448
|
-
async function
|
|
4509
|
+
async function Qo(e, t, n) {
|
|
4449
4510
|
let r = e.filter((e) => e.tier === "paid" && !t.has(e.name)).map((e) => e.name);
|
|
4450
4511
|
return r.length === 0 ? {} : Wr(r, n).catch(() => ({}));
|
|
4451
4512
|
}
|
|
4452
|
-
function
|
|
4513
|
+
function $o(e, t) {
|
|
4453
4514
|
return e === "free" ? L.success("free") : e === "owned" ? L.accent("owned") : `${L.highlight(`$${t}`)} ${L.muted("locked")}`;
|
|
4454
4515
|
}
|
|
4455
|
-
async function
|
|
4516
|
+
async function es(e, t, n) {
|
|
4456
4517
|
let r = e.filter((e) => t(e)), i = e.filter((e) => !t(e));
|
|
4457
4518
|
i.length > 0 && s.log.warning(`Skipping ${i.join(", ")} because ${i.length === 1 ? "it depends" : "they depend"} on a pack you don't own yet.`), await sr(r.map((e) => n.get(e)).filter((e) => e !== void 0).map((e) => ({
|
|
4458
4519
|
name: e.name,
|
|
@@ -4460,7 +4521,7 @@ async function Uo(e, t, n) {
|
|
|
4460
4521
|
price: e.price
|
|
4461
4522
|
})));
|
|
4462
4523
|
}
|
|
4463
|
-
function
|
|
4524
|
+
function ts(e, t) {
|
|
4464
4525
|
z([
|
|
4465
4526
|
"These packs will be installed, in order:",
|
|
4466
4527
|
"",
|
|
@@ -4470,7 +4531,7 @@ function Wo(e, t) {
|
|
|
4470
4531
|
})
|
|
4471
4532
|
].join("\n"), "Install Plan");
|
|
4472
4533
|
}
|
|
4473
|
-
async function
|
|
4534
|
+
async function ns(e, t) {
|
|
4474
4535
|
let n = [];
|
|
4475
4536
|
for (let r of e) {
|
|
4476
4537
|
let e = await Rr(r), i = await zr(r, t);
|
|
@@ -4482,18 +4543,18 @@ async function Go(e, t) {
|
|
|
4482
4543
|
}
|
|
4483
4544
|
return n;
|
|
4484
4545
|
}
|
|
4485
|
-
async function
|
|
4486
|
-
let { prepared: t, paths: n, cwd: r, spinner: i } = e, a =
|
|
4546
|
+
async function rs(e) {
|
|
4547
|
+
let { prepared: t, paths: n, cwd: r, spinner: i } = e, a = Yo(Xo(t.map((e) => e.manifest.dependencies_npm)), n);
|
|
4487
4548
|
if (a.errors.length > 0) {
|
|
4488
4549
|
for (let e of a.errors) s.log.error(e);
|
|
4489
4550
|
return;
|
|
4490
4551
|
}
|
|
4491
4552
|
if (a.operations.length === 0) return;
|
|
4492
4553
|
i.start("Installing npm dependencies...");
|
|
4493
|
-
let o = await
|
|
4554
|
+
let o = await Zo(a.operations, r);
|
|
4494
4555
|
if (i.stop(o.ok ? "npm dependencies installed" : "npm dependency installation failed"), !o.ok) for (let e of o.errors) s.log.error(e);
|
|
4495
4556
|
}
|
|
4496
|
-
function
|
|
4557
|
+
function is() {
|
|
4497
4558
|
Te([{
|
|
4498
4559
|
command: "npx @hype-stack/cli onboard",
|
|
4499
4560
|
hint: "(set up env vars + run migrations)"
|
|
@@ -4502,7 +4563,7 @@ function qo() {
|
|
|
4502
4563
|
hint: "(start frontend + backend)"
|
|
4503
4564
|
}]);
|
|
4504
4565
|
}
|
|
4505
|
-
function
|
|
4566
|
+
function as(e) {
|
|
4506
4567
|
if (e.length === 0) return;
|
|
4507
4568
|
let t = e.map((e) => {
|
|
4508
4569
|
let t = e.replace(/^\{\{[^}]+\}\}\//, "");
|
|
@@ -4510,10 +4571,10 @@ function Jo(e) {
|
|
|
4510
4571
|
});
|
|
4511
4572
|
s.note(t.join("\n"), "Skipped (already exist)");
|
|
4512
4573
|
}
|
|
4513
|
-
async function
|
|
4574
|
+
async function os(e) {
|
|
4514
4575
|
let { prepared: t, config: n, cwd: r, force: i, yes: a, slotsByPack: o } = e, c = /* @__PURE__ */ new Set();
|
|
4515
4576
|
if (i) return c;
|
|
4516
|
-
let l = await
|
|
4577
|
+
let l = await na({
|
|
4517
4578
|
packs: t,
|
|
4518
4579
|
config: n,
|
|
4519
4580
|
projectRoot: r,
|
|
@@ -4540,7 +4601,7 @@ async function Yo(e) {
|
|
|
4540
4601
|
}
|
|
4541
4602
|
//#endregion
|
|
4542
4603
|
//#region src/ui/swatch.ts
|
|
4543
|
-
function
|
|
4604
|
+
function ss(e) {
|
|
4544
4605
|
let t = e.trim().match(/^oklch\(([^)]+)\)$/i);
|
|
4545
4606
|
if (!t) return null;
|
|
4546
4607
|
let n = t[1].trim().split(/\s+/);
|
|
@@ -4559,56 +4620,56 @@ function Xo(e) {
|
|
|
4559
4620
|
h: a
|
|
4560
4621
|
};
|
|
4561
4622
|
}
|
|
4562
|
-
function
|
|
4623
|
+
function cs(e) {
|
|
4563
4624
|
return Math.min(255, Math.max(0, Math.round(e)));
|
|
4564
4625
|
}
|
|
4565
|
-
function
|
|
4626
|
+
function ls(e) {
|
|
4566
4627
|
return e <= .0031308 ? 12.92 * e : 1.055 * e ** (1 / 2.4) - .055;
|
|
4567
4628
|
}
|
|
4568
|
-
function
|
|
4629
|
+
function us({ l: e, c: t, h: n }) {
|
|
4569
4630
|
let r = n * Math.PI / 180, i = t * Math.cos(r), a = t * Math.sin(r), o = e + .3963377774 * i + .2158037573 * a, s = e - .1055613458 * i - .0638541728 * a, c = e - .0894841775 * i - 1.291485548 * a, l = o ** 3, u = s ** 3, d = c ** 3, f = 4.0767416621 * l - 3.3077115913 * u + .2309699292 * d, p = -1.2684380042 * l + 2.6097570613 * u - .3413193965 * d, m = -.0041960863 * l - .7034186147 * u + 1.7076146937 * d;
|
|
4570
4631
|
return [
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4632
|
+
cs(ls(f) * 255),
|
|
4633
|
+
cs(ls(p) * 255),
|
|
4634
|
+
cs(ls(m) * 255)
|
|
4574
4635
|
];
|
|
4575
4636
|
}
|
|
4576
|
-
var
|
|
4577
|
-
function
|
|
4637
|
+
var ds = "\x1B[49m";
|
|
4638
|
+
function fs(e, t) {
|
|
4578
4639
|
let n = e[t];
|
|
4579
4640
|
if (!n) return b.dim(" ");
|
|
4580
|
-
let r =
|
|
4641
|
+
let r = ss(n);
|
|
4581
4642
|
if (!r) return b.dim(" ");
|
|
4582
|
-
let [i, a, o] =
|
|
4583
|
-
return `\x1b[48;2;${i};${a};${o}m ${
|
|
4643
|
+
let [i, a, o] = us(r);
|
|
4644
|
+
return `\x1b[48;2;${i};${a};${o}m ${ds}`;
|
|
4584
4645
|
}
|
|
4585
|
-
var
|
|
4646
|
+
var ps = [
|
|
4586
4647
|
"primary",
|
|
4587
4648
|
"secondary",
|
|
4588
4649
|
"accent"
|
|
4589
4650
|
];
|
|
4590
|
-
function
|
|
4591
|
-
return
|
|
4651
|
+
function ms(e) {
|
|
4652
|
+
return ps.map((t) => fs(e, t)).join("");
|
|
4592
4653
|
}
|
|
4593
|
-
function
|
|
4594
|
-
return `${
|
|
4654
|
+
function hs(e) {
|
|
4655
|
+
return `${ms(e.light)} ${b.dim("·")} ${ms(e.dark)}`;
|
|
4595
4656
|
}
|
|
4596
4657
|
//#endregion
|
|
4597
4658
|
//#region src/commands/create.ts
|
|
4598
|
-
async function
|
|
4599
|
-
e.skipBanner ||
|
|
4659
|
+
async function gs(e) {
|
|
4660
|
+
e.skipBanner || Ya(), s.intro(L.brandBold("Create a new Hype Stack project"));
|
|
4600
4661
|
let o = e.yes === !0, c, l;
|
|
4601
4662
|
if (o && e.name) {
|
|
4602
|
-
let t =
|
|
4603
|
-
t && (s.log.error(t), B()), l = e.name, c =
|
|
4663
|
+
let t = to(e.name);
|
|
4664
|
+
t && (s.log.error(t), B()), l = e.name, c = $a(e.name);
|
|
4604
4665
|
} else {
|
|
4605
4666
|
let t = await s.text({
|
|
4606
4667
|
message: "What is your project named?",
|
|
4607
4668
|
placeholder: "my-app",
|
|
4608
4669
|
initialValue: e.name ?? "",
|
|
4609
|
-
validate: (e) =>
|
|
4670
|
+
validate: (e) => to(e ?? "")
|
|
4610
4671
|
});
|
|
4611
|
-
s.isCancel(t) && B(), l = t, c =
|
|
4672
|
+
s.isCancel(t) && B(), l = t, c = $a(l);
|
|
4612
4673
|
}
|
|
4613
4674
|
l.trim() !== c && s.log.info(L.muted(`Using "${L.highlight(c)}" as the project name`));
|
|
4614
4675
|
let u;
|
|
@@ -4652,7 +4713,7 @@ async function as(e) {
|
|
|
4652
4713
|
message: "Pick a color theme",
|
|
4653
4714
|
options: r.map((e) => ({
|
|
4654
4715
|
value: e.name,
|
|
4655
|
-
label: `${
|
|
4716
|
+
label: `${hs(e)} ${e.label}`
|
|
4656
4717
|
})),
|
|
4657
4718
|
initialValue: h
|
|
4658
4719
|
});
|
|
@@ -4670,31 +4731,31 @@ async function as(e) {
|
|
|
4670
4731
|
(s.isCancel(e) || !e) && B();
|
|
4671
4732
|
}
|
|
4672
4733
|
let _ = s.spinner();
|
|
4673
|
-
_.start("Cloning Hype Stack template..."), await
|
|
4734
|
+
_.start("Cloning Hype Stack template..."), await vo(d), _.stop(L.success("Template cloned"));
|
|
4674
4735
|
let v = s.spinner();
|
|
4675
|
-
v.start("Setting up project..."), await
|
|
4736
|
+
v.start("Setting up project..."), await jo(d), await No(d, c), await To(d, p);
|
|
4676
4737
|
let y = await Pr(d), b = Ir(c, y);
|
|
4677
|
-
await Nr(d, b), await
|
|
4738
|
+
await Nr(d, b), await qo(d, {
|
|
4678
4739
|
projectName: c,
|
|
4679
4740
|
editor: p,
|
|
4680
4741
|
workspace: y
|
|
4681
4742
|
});
|
|
4682
4743
|
let x = T.resolve(d, b.paths?.frontend.root ?? "apps/frontend");
|
|
4683
|
-
a(g) && (await
|
|
4744
|
+
a(g) && (await _o(x, i(g)) || s.log.warn(L.muted(`Could not find ${L.path("assets/styles.css")} to apply the ${g} theme`))), e.radius !== void 0 && so(e.radius) && (await uo(x, e.radius) || s.log.warn(L.muted(`Could not find ${L.path("assets/styles.css")} to set the corner radius`))), await ao(x, e.defaultMode === "dark" || e.defaultMode === "light" ? e.defaultMode : "light") || s.log.warn(L.muted(`Could not find ${L.path("src/hooks/use-theme.ts")} to set the default color mode`)), v.stop(L.success("Project configured"));
|
|
4684
4745
|
let S = s.spinner();
|
|
4685
4746
|
S.start("Installing dependencies..."), (await J("pnpm", ["install"], { cwd: d })).exitCode === 0 ? S.stop(L.success("Dependencies installed")) : (S.stop(L.warning("Dependencies installed with warnings")), s.log.warn(L.muted("You may need to run `pnpm install` manually to resolve issues.")));
|
|
4686
4747
|
let C = s.spinner();
|
|
4687
|
-
C.start("Initializing git repository..."), await
|
|
4748
|
+
C.start("Initializing git repository..."), await Mo(d), C.stop(L.success("Git repository initialized with clean history"));
|
|
4688
4749
|
let w = s.spinner();
|
|
4689
4750
|
w.start("Creating .env files from examples...");
|
|
4690
|
-
let E = await
|
|
4751
|
+
let E = await Do(d);
|
|
4691
4752
|
if (E.length > 0) {
|
|
4692
4753
|
let e = E.length;
|
|
4693
4754
|
w.stop(L.success(`Created ${e} .env file${e === 1 ? "" : "s"} from examples`));
|
|
4694
4755
|
} else w.stop(L.muted("No .env.example files to copy"));
|
|
4695
4756
|
s.log.success(`${L.brandBold("Hype Stack")} project ${L.highlight(c)} is ready!`);
|
|
4696
|
-
let D = T.relative(process.cwd(), d) || ".", O = [
|
|
4697
|
-
E.length > 0 ? O.push(`Review your ${L.path(".env")} files and fill in any secrets`) : O.push(`Copy ${L.path(".env.example")} to ${L.path(".env")} and configure`), Te(O);
|
|
4757
|
+
let D = T.relative(process.cwd(), d) || ".", O = [{ command: L.command(`cd ${D}`) }];
|
|
4758
|
+
E.length > 0 ? O.push({ command: `Review your ${L.path(".env")} files and fill in any secrets` }) : O.push({ command: `Copy ${L.path(".env.example")} to ${L.path(".env")} and configure` }), Te(O);
|
|
4698
4759
|
let k = e.setup === !1;
|
|
4699
4760
|
if (e.deferSetup) s.log.info(L.muted("Docker and migrations will run after your packs are installed."));
|
|
4700
4761
|
else {
|
|
@@ -4702,15 +4763,15 @@ async function as(e) {
|
|
|
4702
4763
|
message: "Would you like to start Docker services and run database migrations now?",
|
|
4703
4764
|
initialValue: !0
|
|
4704
4765
|
}));
|
|
4705
|
-
s.isCancel(e) && B(), e ? await
|
|
4766
|
+
s.isCancel(e) && B(), e ? await Aa(d, o) : s.log.info(L.muted("Docker and migrations can run later via `npx @hype-stack/cli onboard`.")), is();
|
|
4706
4767
|
}
|
|
4707
|
-
return await
|
|
4768
|
+
return await Jo("project_create"), s.outro(L.muted("Happy building!")), d;
|
|
4708
4769
|
}
|
|
4709
4770
|
//#endregion
|
|
4710
4771
|
//#region src/commands/init.ts
|
|
4711
|
-
async function
|
|
4772
|
+
async function _s(e) {
|
|
4712
4773
|
let t = e.cwd ?? process.cwd(), n = e.silent ?? !1;
|
|
4713
|
-
if (n || (
|
|
4774
|
+
if (n || (Xa(), s.intro(L.brandBold("Initialize Hype Stack configuration"))), !await Lr(t)) {
|
|
4714
4775
|
s.log.error(`This doesn't look like a Hype Stack project. ${L.muted("Expected apps/ directory and package.json")}`), s.outro(L.muted(`Run ${L.command("npx @hype-stack/cli create")} to scaffold a new project.`));
|
|
4715
4776
|
return;
|
|
4716
4777
|
}
|
|
@@ -4747,26 +4808,27 @@ async function os(e) {
|
|
|
4747
4808
|
message: "Project name for stack.json?",
|
|
4748
4809
|
placeholder: i,
|
|
4749
4810
|
initialValue: i,
|
|
4750
|
-
validate: (e) =>
|
|
4811
|
+
validate: (e) => to(e ?? "")
|
|
4751
4812
|
});
|
|
4752
|
-
s.isCancel(e) && B(), a =
|
|
4813
|
+
s.isCancel(e) && B(), a = $a(e);
|
|
4753
4814
|
}
|
|
4754
4815
|
await Nr(t, Ir(a, r)), n || (s.log.success(`${L.path("stack.json")} written successfully`), s.outro(L.muted("Your project is mapped and ready for Hype Stack CLI commands.")));
|
|
4755
4816
|
}
|
|
4756
|
-
async function
|
|
4817
|
+
async function vs(e, t = {}, n) {
|
|
4757
4818
|
if (await Mr(e)) return {
|
|
4758
4819
|
projectRoot: e,
|
|
4759
4820
|
scaffolded: !1
|
|
4760
4821
|
};
|
|
4761
|
-
let r = t.runInit ?? ((e) =>
|
|
4822
|
+
let r = t.runInit ?? ((e) => _s({
|
|
4762
4823
|
cwd: e,
|
|
4763
4824
|
silent: !0
|
|
4764
|
-
})), i = t.runCreate ?? ((e, t) =>
|
|
4825
|
+
})), i = t.runCreate ?? ((e, t) => gs({
|
|
4765
4826
|
parentDirectory: e,
|
|
4766
4827
|
deferSetup: !0,
|
|
4767
4828
|
skipBanner: !0,
|
|
4768
4829
|
defaultTheme: t?.defaultTheme,
|
|
4769
|
-
defaultMode: t?.defaultMode
|
|
4830
|
+
defaultMode: t?.defaultMode,
|
|
4831
|
+
radius: t?.radius
|
|
4770
4832
|
}));
|
|
4771
4833
|
if (await Lr(e)) {
|
|
4772
4834
|
s.log.warn(`No ${L.path("stack.json")} found in ${L.path(e)}.`);
|
|
@@ -4801,10 +4863,10 @@ async function ss(e, t = {}, n) {
|
|
|
4801
4863
|
}
|
|
4802
4864
|
//#endregion
|
|
4803
4865
|
//#region src/commands/compose.ts
|
|
4804
|
-
async function
|
|
4866
|
+
async function ys(e = {}) {
|
|
4805
4867
|
let t = e.cwd ?? process.cwd();
|
|
4806
|
-
|
|
4807
|
-
let n = await
|
|
4868
|
+
Ya();
|
|
4869
|
+
let n = await vs(t), r = n?.projectRoot ?? null, i = n?.scaffolded ?? !1, a;
|
|
4808
4870
|
try {
|
|
4809
4871
|
a = await jr(r ?? t);
|
|
4810
4872
|
} catch (e) {
|
|
@@ -4822,13 +4884,13 @@ async function cs(e = {}) {
|
|
|
4822
4884
|
c.stop("Failed to load packs"), s.cancel(`Could not reach Hype Stack. Check your connection and try again.\n${$(e)}`), process.exit(1);
|
|
4823
4885
|
}
|
|
4824
4886
|
c.stop("Packs loaded");
|
|
4825
|
-
let u = a.installedPacks ?? [], d = new Set(u), f = new Map(l.map((e) => [e.name, e])), p = e.licenseKey ?? a.licenseKey ?? null, m = (await Xn(F()))?.token ?? null, h = await
|
|
4887
|
+
let u = a.installedPacks ?? [], d = new Set(u), f = new Map(l.map((e) => [e.name, e])), p = e.licenseKey ?? a.licenseKey ?? null, m = (await Xn(F()))?.token ?? null, h = await Qo(l, d, {
|
|
4826
4888
|
token: m,
|
|
4827
4889
|
key: p
|
|
4828
4890
|
}), g = (e) => {
|
|
4829
4891
|
let t = f.get(e);
|
|
4830
4892
|
return !t || t.tier === "free" ? "free" : h[e]?.owned ? "owned" : "locked";
|
|
4831
|
-
}, _ = (e) => !d.has(e) && g(e) === "locked", v = await
|
|
4893
|
+
}, _ = (e) => !d.has(e) && g(e) === "locked", v = await bs({
|
|
4832
4894
|
packs: l,
|
|
4833
4895
|
installedSet: d,
|
|
4834
4896
|
stateOf: g,
|
|
@@ -4839,9 +4901,9 @@ async function cs(e = {}) {
|
|
|
4839
4901
|
s.outro(L.muted("No packs selected. Nothing to do."));
|
|
4840
4902
|
return;
|
|
4841
4903
|
}
|
|
4842
|
-
let b =
|
|
4904
|
+
let b = Cs(v), x = ws(v), S = za(l, b), C = Ma(Ba(l, S)), w;
|
|
4843
4905
|
try {
|
|
4844
|
-
w =
|
|
4906
|
+
w = Pa(b, C, u);
|
|
4845
4907
|
} catch (e) {
|
|
4846
4908
|
s.cancel($(e)), process.exit(1);
|
|
4847
4909
|
}
|
|
@@ -4849,7 +4911,7 @@ async function cs(e = {}) {
|
|
|
4849
4911
|
z(`${w.alreadyInstalled.join(", ")} already installed.`, "Nothing to do"), s.outro(L.muted("Your selection is already part of the project."));
|
|
4850
4912
|
return;
|
|
4851
4913
|
}
|
|
4852
|
-
let T =
|
|
4914
|
+
let T = Fa({
|
|
4853
4915
|
order: w.order,
|
|
4854
4916
|
graph: C,
|
|
4855
4917
|
isLocked: _,
|
|
@@ -4857,28 +4919,28 @@ async function cs(e = {}) {
|
|
|
4857
4919
|
});
|
|
4858
4920
|
if (T.blocked.length > 0 && !m && !p) {
|
|
4859
4921
|
let e = await or();
|
|
4860
|
-
e && (m = e, h = await
|
|
4922
|
+
e && (m = e, h = await Qo(l, d, {
|
|
4861
4923
|
token: m,
|
|
4862
4924
|
key: p
|
|
4863
|
-
}), T =
|
|
4925
|
+
}), T = Fa({
|
|
4864
4926
|
order: w.order,
|
|
4865
4927
|
graph: C,
|
|
4866
4928
|
isLocked: _,
|
|
4867
4929
|
installed: u
|
|
4868
4930
|
}));
|
|
4869
4931
|
}
|
|
4870
|
-
if (T.blocked.length > 0 && await
|
|
4932
|
+
if (T.blocked.length > 0 && await es(T.blocked, _, f), T.installable.length === 0) {
|
|
4871
4933
|
s.outro(L.muted("Nothing left to install once locked packs are removed."));
|
|
4872
4934
|
return;
|
|
4873
4935
|
}
|
|
4874
|
-
if (
|
|
4936
|
+
if (ts(T.installable, f), !e.yes) {
|
|
4875
4937
|
let e = await s.confirm({ message: `Install ${T.installable.length} pack${T.installable.length === 1 ? "" : "s"}?` });
|
|
4876
4938
|
(s.isCancel(e) || !e) && (s.cancel("Installation cancelled."), process.exit(0));
|
|
4877
4939
|
}
|
|
4878
4940
|
c.start("Downloading packs...");
|
|
4879
4941
|
let E;
|
|
4880
4942
|
try {
|
|
4881
|
-
E = await
|
|
4943
|
+
E = await ns(T.installable, {
|
|
4882
4944
|
token: m,
|
|
4883
4945
|
key: p
|
|
4884
4946
|
});
|
|
@@ -4886,7 +4948,7 @@ async function cs(e = {}) {
|
|
|
4886
4948
|
c.stop("Download failed"), s.cancel($(e)), process.exit(1);
|
|
4887
4949
|
}
|
|
4888
4950
|
c.stop(`Downloaded ${E.length} pack${E.length === 1 ? "" : "s"}`);
|
|
4889
|
-
let D = await
|
|
4951
|
+
let D = await os({
|
|
4890
4952
|
prepared: E,
|
|
4891
4953
|
config: a,
|
|
4892
4954
|
cwd: o,
|
|
@@ -4896,7 +4958,7 @@ async function cs(e = {}) {
|
|
|
4896
4958
|
});
|
|
4897
4959
|
try {
|
|
4898
4960
|
c.start("Installing pack files...");
|
|
4899
|
-
let t = await
|
|
4961
|
+
let t = await aa({
|
|
4900
4962
|
packs: E,
|
|
4901
4963
|
config: a,
|
|
4902
4964
|
projectRoot: o,
|
|
@@ -4909,22 +4971,22 @@ async function cs(e = {}) {
|
|
|
4909
4971
|
for (let e of t.errors) s.log.error(e);
|
|
4910
4972
|
s.cancel("No files were written. Fix the errors above (or pass --force for existing files) and try again."), process.exit(1);
|
|
4911
4973
|
}
|
|
4912
|
-
c.stop("Files installed"), t.installed.length > 0 && s.log.success(`${L.highlight(String(t.installed.length))} files installed`), t.skipped.length > 0 && (s.log.warning(`${t.skipped.length} files skipped (use --force to overwrite)`),
|
|
4974
|
+
c.stop("Files installed"), t.installed.length > 0 && s.log.success(`${L.highlight(String(t.installed.length))} files installed`), t.skipped.length > 0 && (s.log.warning(`${t.skipped.length} files skipped (use --force to overwrite)`), as(t.skipped));
|
|
4913
4975
|
for (let e of t.errors) s.log.error(e);
|
|
4914
|
-
await
|
|
4976
|
+
await rs({
|
|
4915
4977
|
prepared: E,
|
|
4916
4978
|
paths: a.paths,
|
|
4917
4979
|
cwd: o,
|
|
4918
4980
|
spinner: c
|
|
4919
4981
|
});
|
|
4920
4982
|
let n;
|
|
4921
|
-
i && (n = await
|
|
4983
|
+
i && (n = await ja(o, e.yes ?? !1)), await _r({
|
|
4922
4984
|
projectRoot: o,
|
|
4923
4985
|
paths: a.paths,
|
|
4924
4986
|
skipPrompts: e.yes ?? !1,
|
|
4925
4987
|
dbReady: n,
|
|
4926
4988
|
freshScaffold: i
|
|
4927
|
-
}),
|
|
4989
|
+
}), is(), s.outro(L.brand(`Installed ${t.appliedPacks.join(", ")}.`));
|
|
4928
4990
|
} finally {
|
|
4929
4991
|
await Promise.all(E.map((e) => y.rm(e.packDir, {
|
|
4930
4992
|
recursive: !0,
|
|
@@ -4932,10 +4994,10 @@ async function cs(e = {}) {
|
|
|
4932
4994
|
})));
|
|
4933
4995
|
}
|
|
4934
4996
|
}
|
|
4935
|
-
async function
|
|
4997
|
+
async function bs(e) {
|
|
4936
4998
|
let { packs: t, installedSet: n, stateOf: r, options: i, adminAvailable: a } = e;
|
|
4937
4999
|
if (i.packs && i.packs.length > 0) {
|
|
4938
|
-
let e = i.packs.map(
|
|
5000
|
+
let e = i.packs.map(Ss), n = e.filter((e) => !t.some((t) => t.name === e.name));
|
|
4939
5001
|
return n.length > 0 && (s.cancel(`Unknown pack${n.length === 1 ? "" : "s"}: ${n.map((e) => e.name).join(", ")}`), process.exit(1)), e;
|
|
4940
5002
|
}
|
|
4941
5003
|
let o = t.filter((e) => n.has(e.name));
|
|
@@ -4944,13 +5006,13 @@ async function ls(e) {
|
|
|
4944
5006
|
if (c.length === 0) return s.outro(L.muted("Every available pack is already installed.")), [];
|
|
4945
5007
|
let l = le();
|
|
4946
5008
|
z(c.map((e) => ` ${R.arrow} ${L.highlight(e.displayName)} ${ve(`${l}/packs/${e.name}`)}`).join("\n"), "Browse packs");
|
|
4947
|
-
let u =
|
|
5009
|
+
let u = pa(c, { adminAvailable: a }), d = [];
|
|
4948
5010
|
for (let e of u) {
|
|
4949
5011
|
let t = e.packs.map((e) => {
|
|
4950
5012
|
let t = r(e.name);
|
|
4951
5013
|
return {
|
|
4952
5014
|
value: e.name,
|
|
4953
|
-
label: `${e.displayName} ${
|
|
5015
|
+
label: `${e.displayName} ${$o(t, e.price)}`,
|
|
4954
5016
|
hint: e.description
|
|
4955
5017
|
};
|
|
4956
5018
|
});
|
|
@@ -4967,7 +5029,7 @@ async function ls(e) {
|
|
|
4967
5029
|
});
|
|
4968
5030
|
continue;
|
|
4969
5031
|
}
|
|
4970
|
-
let n = await
|
|
5032
|
+
let n = await Qa({
|
|
4971
5033
|
message: `Select ${e.label.toLowerCase()} to add (optional)`,
|
|
4972
5034
|
options: t,
|
|
4973
5035
|
required: !1
|
|
@@ -4977,20 +5039,20 @@ async function ls(e) {
|
|
|
4977
5039
|
}
|
|
4978
5040
|
return d;
|
|
4979
5041
|
}
|
|
4980
|
-
var
|
|
4981
|
-
function
|
|
4982
|
-
let t = e.match(
|
|
5042
|
+
var xs = /@(frontend|admin)$/;
|
|
5043
|
+
function Ss(e) {
|
|
5044
|
+
let t = e.match(xs);
|
|
4983
5045
|
return t ? {
|
|
4984
5046
|
name: e.slice(0, -t[0].length),
|
|
4985
5047
|
slot: t[1]
|
|
4986
5048
|
} : { name: e };
|
|
4987
5049
|
}
|
|
4988
|
-
function
|
|
5050
|
+
function Cs(e) {
|
|
4989
5051
|
let t = /* @__PURE__ */ new Set(), n = [];
|
|
4990
5052
|
for (let r of e) t.has(r.name) || (t.add(r.name), n.push(r.name));
|
|
4991
5053
|
return n;
|
|
4992
5054
|
}
|
|
4993
|
-
function
|
|
5055
|
+
function ws(e) {
|
|
4994
5056
|
let t = /* @__PURE__ */ new Map();
|
|
4995
5057
|
for (let n of e) {
|
|
4996
5058
|
if (!n.slot) continue;
|
|
@@ -5001,8 +5063,8 @@ function ps(e) {
|
|
|
5001
5063
|
}
|
|
5002
5064
|
//#endregion
|
|
5003
5065
|
//#region src/commands/login.ts
|
|
5004
|
-
async function
|
|
5005
|
-
|
|
5066
|
+
async function Ts() {
|
|
5067
|
+
Xa(), s.intro(L.brandBold("Log in to Hype Stack")), s.log.step("Opening your browser to sign in...");
|
|
5006
5068
|
let e;
|
|
5007
5069
|
try {
|
|
5008
5070
|
e = await ar({ onUrl: (e) => {
|
|
@@ -5015,8 +5077,8 @@ async function ms() {
|
|
|
5015
5077
|
}
|
|
5016
5078
|
//#endregion
|
|
5017
5079
|
//#region src/commands/logout.ts
|
|
5018
|
-
async function
|
|
5019
|
-
|
|
5080
|
+
async function Es() {
|
|
5081
|
+
Xa(), s.intro(L.brandBold("Log out of Hype Stack"));
|
|
5020
5082
|
let e = F(), t = await Xn(e);
|
|
5021
5083
|
if (!t) {
|
|
5022
5084
|
s.outro(L.muted("You're not logged in."));
|
|
@@ -5026,7 +5088,7 @@ async function hs() {
|
|
|
5026
5088
|
}
|
|
5027
5089
|
//#endregion
|
|
5028
5090
|
//#region src/core/onboard-env.ts
|
|
5029
|
-
function
|
|
5091
|
+
function Ds(e) {
|
|
5030
5092
|
let t = [], n = "";
|
|
5031
5093
|
for (let r of e.split(/\r?\n/)) {
|
|
5032
5094
|
let e = r.trim();
|
|
@@ -5052,14 +5114,14 @@ function gs(e) {
|
|
|
5052
5114
|
}
|
|
5053
5115
|
return t;
|
|
5054
5116
|
}
|
|
5055
|
-
function
|
|
5117
|
+
function Os(e) {
|
|
5056
5118
|
let t = e.trim();
|
|
5057
5119
|
if (t === "") return "";
|
|
5058
5120
|
if (t.length <= 4) return "•".repeat(t.length);
|
|
5059
5121
|
let n = Math.min(t.length - 4, 8);
|
|
5060
5122
|
return `${"•".repeat(n)}${t.slice(-4)}`;
|
|
5061
5123
|
}
|
|
5062
|
-
function
|
|
5124
|
+
function ks(e, t, n) {
|
|
5063
5125
|
let r = e.split(/\r?\n/), i = !1, a = r.map((e) => {
|
|
5064
5126
|
if (i) return e;
|
|
5065
5127
|
let r = e.trim();
|
|
@@ -5069,22 +5131,22 @@ function vs(e, t, n) {
|
|
|
5069
5131
|
});
|
|
5070
5132
|
return i ? a.join("\n") : e + `${e.length > 0 && !e.endsWith("\n") ? "\n" : ""}${t}=${n}\n`;
|
|
5071
5133
|
}
|
|
5072
|
-
async function
|
|
5134
|
+
async function As(e) {
|
|
5073
5135
|
return await Y(e) ? y.readFile(e, "utf-8") : "";
|
|
5074
5136
|
}
|
|
5075
|
-
async function
|
|
5137
|
+
async function js(e) {
|
|
5076
5138
|
let t = T.join(T.dirname(e), ".env");
|
|
5077
5139
|
return await Y(t) || await y.copyFile(e, t), t;
|
|
5078
5140
|
}
|
|
5079
|
-
async function
|
|
5080
|
-
let r =
|
|
5141
|
+
async function Ms(e, t, n) {
|
|
5142
|
+
let r = ks(await As(e), t, n);
|
|
5081
5143
|
await y.writeFile(e, r, "utf-8");
|
|
5082
5144
|
}
|
|
5083
5145
|
//#endregion
|
|
5084
5146
|
//#region src/commands/onboard.ts
|
|
5085
|
-
async function
|
|
5147
|
+
async function Ns(e = {}) {
|
|
5086
5148
|
let t = e.cwd ?? process.cwd();
|
|
5087
|
-
|
|
5149
|
+
Ya(), s.intro(L.brandBold("Onboard your stack"));
|
|
5088
5150
|
let n;
|
|
5089
5151
|
try {
|
|
5090
5152
|
n = await jr(t);
|
|
@@ -5092,19 +5154,19 @@ async function Ss(e = {}) {
|
|
|
5092
5154
|
n = null;
|
|
5093
5155
|
}
|
|
5094
5156
|
n || (s.cancel(`${L.path("stack.json")} not found. Run ${L.command("npx @hype-stack/cli init")} first.`), process.exit(1));
|
|
5095
|
-
let r = n.installedPacks ?? [], i = n.onboarding?.envSections ?? [], a = await
|
|
5157
|
+
let r = n.installedPacks ?? [], i = n.onboarding?.envSections ?? [], a = await Oo(t);
|
|
5096
5158
|
a.length === 0 && s.log.warn(L.muted("No .env.example files found; skipping env setup."));
|
|
5097
|
-
for (let n of a) await
|
|
5159
|
+
for (let n of a) await Ps({
|
|
5098
5160
|
examplePath: n,
|
|
5099
5161
|
projectRoot: t,
|
|
5100
5162
|
skipPrompts: e.yes ?? !1,
|
|
5101
5163
|
installedEnvSections: i
|
|
5102
5164
|
});
|
|
5103
5165
|
let o = Ar(r);
|
|
5104
|
-
o.length > 0 && z(o.map((e) => ` ${L.muted("·")} ${e}`).join("\n"), "Tips"), e.skipMigrations || await
|
|
5166
|
+
o.length > 0 && z(o.map((e) => ` ${L.muted("·")} ${e}`).join("\n"), "Tips"), e.skipMigrations || await Ls(t, e.yes ?? !1), s.outro(L.brand(`All set. Run ${L.command("pnpm dev")} to start your app.`));
|
|
5105
5167
|
}
|
|
5106
|
-
async function
|
|
5107
|
-
let { examplePath: t, projectRoot: n, skipPrompts: r, installedEnvSections: i } = e, a = T.relative(n, t) || t, o = await
|
|
5168
|
+
async function Ps(e) {
|
|
5169
|
+
let { examplePath: t, projectRoot: n, skipPrompts: r, installedEnvSections: i } = e, a = T.relative(n, t) || t, o = await js(t), c = await As(o), l = Ds(await y.readFile(t, "utf-8")), u = L.path(a);
|
|
5108
5170
|
s.log.step(`Env: ${u}`);
|
|
5109
5171
|
for (let e of l) {
|
|
5110
5172
|
if (e.vars.length === 0) continue;
|
|
@@ -5120,7 +5182,7 @@ async function Cs(e) {
|
|
|
5120
5182
|
s.log.info(`${L.label(n.key)} ${L.muted("skipped (non-interactive)")}`);
|
|
5121
5183
|
continue;
|
|
5122
5184
|
}
|
|
5123
|
-
let e =
|
|
5185
|
+
let e = Os(Fs(c, n.key)), i = await s.text({
|
|
5124
5186
|
message: `${L.label(n.key)}`,
|
|
5125
5187
|
placeholder: e ? `${e} ${L.muted("(Enter keeps this)")}` : t.hint
|
|
5126
5188
|
});
|
|
@@ -5130,31 +5192,31 @@ async function Cs(e) {
|
|
|
5130
5192
|
s.log.info(L.muted(`${n.key} unchanged.`));
|
|
5131
5193
|
continue;
|
|
5132
5194
|
}
|
|
5133
|
-
await
|
|
5195
|
+
await Ms(o, n.key, a), s.log.success(`${n.key} saved`);
|
|
5134
5196
|
}
|
|
5135
5197
|
}
|
|
5136
5198
|
}
|
|
5137
|
-
function
|
|
5199
|
+
function Fs(e, t) {
|
|
5138
5200
|
for (let n of e.split(/\r?\n/)) {
|
|
5139
|
-
let e = n.match(RegExp(`^${
|
|
5201
|
+
let e = n.match(RegExp(`^${Is(t)}\\s*=\\s*(.*)$`));
|
|
5140
5202
|
if (e) return e[1].trim();
|
|
5141
5203
|
}
|
|
5142
5204
|
return "";
|
|
5143
5205
|
}
|
|
5144
|
-
function
|
|
5206
|
+
function Is(e) {
|
|
5145
5207
|
return e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5146
5208
|
}
|
|
5147
|
-
async function
|
|
5148
|
-
if (!await
|
|
5209
|
+
async function Ls(e, t) {
|
|
5210
|
+
if (!await ga() && !await va(e, t, !1)) {
|
|
5149
5211
|
s.log.info(L.muted(`Start services later with ${L.command("docker compose up -d")} (in apps/backend), then ${L.command("pnpm --filter @internal/backend migration:latest")}.`));
|
|
5150
5212
|
return;
|
|
5151
5213
|
}
|
|
5152
5214
|
let n = s.spinner();
|
|
5153
|
-
if (n.start("Waiting for Postgres to be ready..."), !await
|
|
5215
|
+
if (n.start("Waiting for Postgres to be ready..."), !await wa(e)) {
|
|
5154
5216
|
n.error("Postgres health check timed out"), s.log.warn(L.muted(`Run migrations manually once Postgres is ready: ${L.command("pnpm --filter @internal/backend migration:latest")}`));
|
|
5155
5217
|
return;
|
|
5156
5218
|
}
|
|
5157
|
-
if (n.stop(L.success("Postgres is ready")), await
|
|
5219
|
+
if (n.stop(L.success("Postgres is ready")), await Ea(e)) {
|
|
5158
5220
|
s.log.info(L.muted("Migrations already applied, skipping."));
|
|
5159
5221
|
return;
|
|
5160
5222
|
}
|
|
@@ -5166,20 +5228,20 @@ async function Es(e, t) {
|
|
|
5166
5228
|
s.log.info(L.muted("Skipping database migrations."));
|
|
5167
5229
|
return;
|
|
5168
5230
|
}
|
|
5169
|
-
await
|
|
5231
|
+
await Da(e);
|
|
5170
5232
|
}
|
|
5171
5233
|
//#endregion
|
|
5172
5234
|
//#region src/core/templates.ts
|
|
5173
|
-
var
|
|
5235
|
+
var Rs = q.createRequest()({
|
|
5174
5236
|
endpoint: "/templates/list",
|
|
5175
5237
|
method: "GET"
|
|
5176
5238
|
});
|
|
5177
|
-
async function
|
|
5178
|
-
let { data: e, error: t } = await
|
|
5239
|
+
async function zs() {
|
|
5240
|
+
let { data: e, error: t } = await Rs.send();
|
|
5179
5241
|
if (t || !e) throw Error(`Failed to fetch template list: ${String(t)}`);
|
|
5180
5242
|
return e.templates;
|
|
5181
5243
|
}
|
|
5182
|
-
async function
|
|
5244
|
+
async function Bs(e) {
|
|
5183
5245
|
let { data: t, error: n, status: r } = await q.createRequest()({
|
|
5184
5246
|
endpoint: `/templates/${encodeURIComponent(e)}/manifest`,
|
|
5185
5247
|
method: "GET"
|
|
@@ -5188,7 +5250,7 @@ async function ks(e) {
|
|
|
5188
5250
|
if (n || !t) throw Error(`Failed to load manifest for template "${e}": ${String(n)}`);
|
|
5189
5251
|
return t;
|
|
5190
5252
|
}
|
|
5191
|
-
async function
|
|
5253
|
+
async function Vs(e, t = {}) {
|
|
5192
5254
|
let n = q.createRequest()({
|
|
5193
5255
|
endpoint: `/templates/${encodeURIComponent(e)}/download`,
|
|
5194
5256
|
method: "POST"
|
|
@@ -5216,9 +5278,9 @@ async function As(e, t = {}) {
|
|
|
5216
5278
|
}
|
|
5217
5279
|
//#endregion
|
|
5218
5280
|
//#region src/commands/template.ts
|
|
5219
|
-
async function
|
|
5281
|
+
async function Hs(t = {}) {
|
|
5220
5282
|
let n = t.cwd ?? process.cwd();
|
|
5221
|
-
|
|
5283
|
+
Ya();
|
|
5222
5284
|
let r = s.spinner();
|
|
5223
5285
|
r.start("Loading packs...");
|
|
5224
5286
|
let o;
|
|
@@ -5230,7 +5292,7 @@ async function js(t = {}) {
|
|
|
5230
5292
|
r.stop("Packs loaded"), r.start("Loading templates...");
|
|
5231
5293
|
let c;
|
|
5232
5294
|
try {
|
|
5233
|
-
c = await
|
|
5295
|
+
c = await zs();
|
|
5234
5296
|
} catch (e) {
|
|
5235
5297
|
r.stop("Failed to load templates"), s.cancel(`Could not reach Hype Stack. Check your connection and try again.\n${$(e)}`), process.exit(1);
|
|
5236
5298
|
}
|
|
@@ -5253,13 +5315,14 @@ async function js(t = {}) {
|
|
|
5253
5315
|
u || (r.stop("Template not found"), s.cancel(`Template "${l}" not found. Available: ${c.map((e) => e.id).join(", ") || "(none)"}`), process.exit(1)), r.stop(`Template: ${u.name}`);
|
|
5254
5316
|
let d;
|
|
5255
5317
|
try {
|
|
5256
|
-
d = await
|
|
5318
|
+
d = await Bs(u.id);
|
|
5257
5319
|
} catch (e) {
|
|
5258
5320
|
s.cancel($(e)), process.exit(1);
|
|
5259
5321
|
}
|
|
5260
|
-
let f = await
|
|
5322
|
+
let f = await vs(n, {}, {
|
|
5261
5323
|
defaultTheme: d.theme,
|
|
5262
|
-
defaultMode: d.defaultMode
|
|
5324
|
+
defaultMode: d.defaultMode,
|
|
5325
|
+
radius: d.radius
|
|
5263
5326
|
}), p = f?.projectRoot ?? null, m = f?.scaffolded ?? !1, h;
|
|
5264
5327
|
try {
|
|
5265
5328
|
h = await jr(p ?? n);
|
|
@@ -5269,16 +5332,16 @@ async function js(t = {}) {
|
|
|
5269
5332
|
h || (s.cancel(p ? `Could not read ${L.path("stack.json")}. Run 'npx @hype-stack/cli init' to regenerate it, then run 'npx @hype-stack/cli template' again.` : `No ${L.path("stack.json")}. Run 'npx @hype-stack/cli init' first, then 'npx @hype-stack/cli template'.`), process.exit(1)), h.paths || (s.cancel(`${L.path("stack.json")} is missing ${L.path("paths")}. Run 'npx @hype-stack/cli init' again to regenerate it.`), process.exit(1));
|
|
5270
5333
|
let g = p ?? n;
|
|
5271
5334
|
s.intro(L.brandBold("Install a template"));
|
|
5272
|
-
let _ = h.installedPacks ?? [], v = new Set(_), b = new Map(o.map((e) => [e.name, e])), x = t.licenseKey ?? h.licenseKey ?? null, S = (await Xn(F()))?.token ?? null, C = await
|
|
5335
|
+
let _ = h.installedPacks ?? [], v = new Set(_), b = new Map(o.map((e) => [e.name, e])), x = t.licenseKey ?? h.licenseKey ?? null, S = (await Xn(F()))?.token ?? null, C = await Us(u, t.variants, t.yes ?? !1), w = Ia(u.slots, C), E = La(u.slots, u.packs, w), D = await Ws({
|
|
5273
5336
|
packs: o,
|
|
5274
5337
|
templatePacks: E,
|
|
5275
5338
|
installedSet: v,
|
|
5276
5339
|
options: t
|
|
5277
5340
|
}), O = [...E, ...D.filter((e) => !E.includes(e))], k = O.filter((e) => !b.has(e));
|
|
5278
5341
|
k.length > 0 && (s.cancel(`Unknown pack${k.length === 1 ? "" : "s"}: ${k.join(", ")}`), process.exit(1));
|
|
5279
|
-
let ee =
|
|
5342
|
+
let ee = Ba(o, w), A = Ma(ee), te;
|
|
5280
5343
|
try {
|
|
5281
|
-
te =
|
|
5344
|
+
te = Pa(O, A, _);
|
|
5282
5345
|
} catch (e) {
|
|
5283
5346
|
s.cancel($(e)), process.exit(1);
|
|
5284
5347
|
}
|
|
@@ -5286,13 +5349,13 @@ async function js(t = {}) {
|
|
|
5286
5349
|
s.outro(L.muted("Every pack in this template is already installed."));
|
|
5287
5350
|
return;
|
|
5288
5351
|
}
|
|
5289
|
-
let ne = await
|
|
5352
|
+
let ne = await Qo(ee, v, {
|
|
5290
5353
|
token: S,
|
|
5291
5354
|
key: x
|
|
5292
5355
|
}), re = (e) => {
|
|
5293
5356
|
let t = b.get(e);
|
|
5294
5357
|
return !t || t.tier === "free" ? "free" : ne[e]?.owned ? "owned" : "locked";
|
|
5295
|
-
}, j = (e) => !v.has(e) && re(e) === "locked", M =
|
|
5358
|
+
}, j = (e) => !v.has(e) && re(e) === "locked", M = Fa({
|
|
5296
5359
|
order: te.order,
|
|
5297
5360
|
graph: A,
|
|
5298
5361
|
isLocked: j,
|
|
@@ -5300,28 +5363,28 @@ async function js(t = {}) {
|
|
|
5300
5363
|
});
|
|
5301
5364
|
if (M.blocked.length > 0 && !S && !x) {
|
|
5302
5365
|
let e = await or();
|
|
5303
|
-
e && (S = e, ne = await
|
|
5366
|
+
e && (S = e, ne = await Qo(ee, v, {
|
|
5304
5367
|
token: S,
|
|
5305
5368
|
key: x
|
|
5306
|
-
}), M =
|
|
5369
|
+
}), M = Fa({
|
|
5307
5370
|
order: te.order,
|
|
5308
5371
|
graph: A,
|
|
5309
5372
|
isLocked: j,
|
|
5310
5373
|
installed: _
|
|
5311
5374
|
}));
|
|
5312
5375
|
}
|
|
5313
|
-
if (M.blocked.length > 0 && await
|
|
5376
|
+
if (M.blocked.length > 0 && await es(M.blocked, j, b), M.installable.length === 0) {
|
|
5314
5377
|
s.outro(L.muted("Nothing left to install once locked packs are removed."));
|
|
5315
5378
|
return;
|
|
5316
5379
|
}
|
|
5317
|
-
if (
|
|
5380
|
+
if (ts(M.installable, b), !t.yes) {
|
|
5318
5381
|
let e = await s.confirm({ message: `Install template ${L.brandBold(u.name)} (${M.installable.length} pack${M.installable.length === 1 ? "" : "s"})?` });
|
|
5319
5382
|
(s.isCancel(e) || !e) && (s.cancel("Installation cancelled."), process.exit(0));
|
|
5320
5383
|
}
|
|
5321
5384
|
r.start("Downloading packs...");
|
|
5322
5385
|
let N;
|
|
5323
5386
|
try {
|
|
5324
|
-
N = await
|
|
5387
|
+
N = await ns(M.installable, {
|
|
5325
5388
|
token: S,
|
|
5326
5389
|
key: x
|
|
5327
5390
|
});
|
|
@@ -5329,7 +5392,7 @@ async function js(t = {}) {
|
|
|
5329
5392
|
r.stop("Download failed"), s.cancel($(e)), process.exit(1);
|
|
5330
5393
|
}
|
|
5331
5394
|
r.stop(`Downloaded ${N.length} pack${N.length === 1 ? "" : "s"}`);
|
|
5332
|
-
let ie = await
|
|
5395
|
+
let ie = await os({
|
|
5333
5396
|
prepared: N,
|
|
5334
5397
|
config: h,
|
|
5335
5398
|
cwd: g,
|
|
@@ -5338,7 +5401,7 @@ async function js(t = {}) {
|
|
|
5338
5401
|
}), P = null;
|
|
5339
5402
|
try {
|
|
5340
5403
|
r.start("Installing pack files...");
|
|
5341
|
-
let n = await
|
|
5404
|
+
let n = await aa({
|
|
5342
5405
|
packs: N,
|
|
5343
5406
|
config: h,
|
|
5344
5407
|
projectRoot: g,
|
|
@@ -5350,15 +5413,15 @@ async function js(t = {}) {
|
|
|
5350
5413
|
for (let e of n.errors) s.log.error(e);
|
|
5351
5414
|
s.cancel("No files were written. Fix the errors above (or pass --force for existing files) and try again."), process.exit(1);
|
|
5352
5415
|
}
|
|
5353
|
-
r.stop("Files installed"), n.installed.length > 0 && s.log.success(`${L.highlight(String(n.installed.length))} files installed`), n.skipped.length > 0 && (s.log.warning(`${n.skipped.length} files skipped (use --force to overwrite)`),
|
|
5416
|
+
r.stop("Files installed"), n.installed.length > 0 && s.log.success(`${L.highlight(String(n.installed.length))} files installed`), n.skipped.length > 0 && (s.log.warning(`${n.skipped.length} files skipped (use --force to overwrite)`), as(n.skipped));
|
|
5354
5417
|
for (let e of n.errors) s.log.error(e);
|
|
5355
5418
|
r.start("Applying template overrides...");
|
|
5356
|
-
let o = await
|
|
5419
|
+
let o = await Vs(u.id, {
|
|
5357
5420
|
token: S,
|
|
5358
5421
|
licenseKey: x
|
|
5359
5422
|
});
|
|
5360
5423
|
o.status === "denied" && (r.stop("Template download denied"), s.cancel(`Access to template "${u.id}" was denied (${o.reason}). Try 'npx @hype-stack/cli login' or check your license.`), process.exit(1)), P = o.templateDir;
|
|
5361
|
-
let c = await
|
|
5424
|
+
let c = await sa({
|
|
5362
5425
|
manifest: d,
|
|
5363
5426
|
config: h,
|
|
5364
5427
|
projectRoot: g,
|
|
@@ -5368,11 +5431,11 @@ async function js(t = {}) {
|
|
|
5368
5431
|
for (let e of c.errors) s.log.error(e);
|
|
5369
5432
|
if (!m) {
|
|
5370
5433
|
let t = T.resolve(g, h.paths?.frontend.root ?? "apps/frontend"), n = d.theme ?? "zinc-mono";
|
|
5371
|
-
a(n) && (await
|
|
5434
|
+
a(n) && (await _o(t, i(n)) ? s.log.success(`Applied the ${i(n).label} theme`) : s.log.warning(L.muted(`Could not find ${L.path("assets/styles.css")} to apply the theme`))), d.radius !== void 0 && so(d.radius) && (await uo(t, d.radius) ? s.log.success(`Set the corner radius to ${d.radius}`) : s.log.warning(L.muted(`Could not find ${L.path("assets/styles.css")} to set the corner radius`)));
|
|
5372
5435
|
let r = d.defaultMode === "dark" || d.defaultMode === "light" ? d.defaultMode : e;
|
|
5373
|
-
await
|
|
5436
|
+
await ao(t, r) ? s.log.success(`Default color mode set to ${r}`) : s.log.warning(L.muted(`Could not find ${L.path("src/hooks/use-theme.ts")} to set the default color mode`));
|
|
5374
5437
|
}
|
|
5375
|
-
await
|
|
5438
|
+
await Gs({
|
|
5376
5439
|
prepared: N,
|
|
5377
5440
|
templateNpm: d.dependencies_npm,
|
|
5378
5441
|
paths: h.paths,
|
|
@@ -5380,13 +5443,13 @@ async function js(t = {}) {
|
|
|
5380
5443
|
spinner: r
|
|
5381
5444
|
});
|
|
5382
5445
|
let l;
|
|
5383
|
-
m && (l = await
|
|
5446
|
+
m && (l = await ja(g, t.yes ?? !1)), await _r({
|
|
5384
5447
|
projectRoot: g,
|
|
5385
5448
|
paths: h.paths,
|
|
5386
5449
|
skipPrompts: t.yes ?? !1,
|
|
5387
5450
|
dbReady: l,
|
|
5388
5451
|
freshScaffold: m
|
|
5389
|
-
}),
|
|
5452
|
+
}), is(), s.outro(L.brand(`Installed template ${u.name}.`));
|
|
5390
5453
|
} finally {
|
|
5391
5454
|
await Promise.all(N.map((e) => y.rm(e.packDir, {
|
|
5392
5455
|
recursive: !0,
|
|
@@ -5397,7 +5460,7 @@ async function js(t = {}) {
|
|
|
5397
5460
|
});
|
|
5398
5461
|
}
|
|
5399
5462
|
}
|
|
5400
|
-
async function
|
|
5463
|
+
async function Us(e, t, n) {
|
|
5401
5464
|
let r = {};
|
|
5402
5465
|
for (let i of e.slots) {
|
|
5403
5466
|
if (t?.[i.family]) {
|
|
@@ -5421,7 +5484,7 @@ async function Ms(e, t, n) {
|
|
|
5421
5484
|
}
|
|
5422
5485
|
return r;
|
|
5423
5486
|
}
|
|
5424
|
-
async function
|
|
5487
|
+
async function Ws(e) {
|
|
5425
5488
|
let { packs: t, templatePacks: n, installedSet: r, options: i } = e, a = new Set(n);
|
|
5426
5489
|
if (i.packs && i.packs.length > 0) {
|
|
5427
5490
|
let e = i.packs.filter((e) => !t.some((t) => t.name === e));
|
|
@@ -5432,7 +5495,7 @@ async function Ns(e) {
|
|
|
5432
5495
|
if (o.length === 0) return [];
|
|
5433
5496
|
let c = le();
|
|
5434
5497
|
z(o.map((e) => ` ${R.arrow} ${L.highlight(e.displayName)} ${ve(`${c}/packs/${e.name}`)}`).join("\n"), "Browse packs");
|
|
5435
|
-
let l = await
|
|
5498
|
+
let l = await Qa({
|
|
5436
5499
|
message: "Add extra packs on top of the template (optional)",
|
|
5437
5500
|
options: o.map((e) => ({
|
|
5438
5501
|
value: e.name,
|
|
@@ -5443,25 +5506,25 @@ async function Ns(e) {
|
|
|
5443
5506
|
});
|
|
5444
5507
|
return m(l) && (s.cancel("Cancelled."), process.exit(0)), l;
|
|
5445
5508
|
}
|
|
5446
|
-
async function
|
|
5447
|
-
let { prepared: t, templateNpm: n, paths: r, cwd: i, spinner: a } = e, o =
|
|
5509
|
+
async function Gs(e) {
|
|
5510
|
+
let { prepared: t, templateNpm: n, paths: r, cwd: i, spinner: a } = e, o = Xo(t.map((e) => e.manifest.dependencies_npm)), c = Yo(n ? Xo([o, n]) : o, r);
|
|
5448
5511
|
if (c.errors.length > 0) {
|
|
5449
5512
|
for (let e of c.errors) s.log.error(e);
|
|
5450
5513
|
return;
|
|
5451
5514
|
}
|
|
5452
5515
|
if (c.operations.length === 0) return;
|
|
5453
5516
|
a.start("Installing npm dependencies...");
|
|
5454
|
-
let l = await
|
|
5517
|
+
let l = await Zo(c.operations, i);
|
|
5455
5518
|
if (a.stop(l.ok ? "npm dependencies installed" : "npm dependency installation failed"), !l.ok) for (let e of l.errors) s.log.error(e);
|
|
5456
5519
|
}
|
|
5457
5520
|
//#endregion
|
|
5458
5521
|
//#region src/cli.ts
|
|
5459
|
-
function
|
|
5522
|
+
function Ks(e) {
|
|
5460
5523
|
if (!e) return;
|
|
5461
5524
|
let t = e.split(",").map((e) => e.trim()).filter((e) => e.length > 0);
|
|
5462
5525
|
return t.length > 0 ? t : void 0;
|
|
5463
5526
|
}
|
|
5464
|
-
function
|
|
5527
|
+
function qs(e) {
|
|
5465
5528
|
if (!e) return;
|
|
5466
5529
|
let t = {};
|
|
5467
5530
|
for (let n of e.split(",")) {
|
|
@@ -5470,10 +5533,10 @@ function Is(e) {
|
|
|
5470
5533
|
}
|
|
5471
5534
|
return Object.keys(t).length > 0 ? t : void 0;
|
|
5472
5535
|
}
|
|
5473
|
-
function
|
|
5536
|
+
function Js() {
|
|
5474
5537
|
let e = new o();
|
|
5475
5538
|
return e.name("hype-stack").description("Build with Hype Stack -- templates, components, modules, and more").version(A, "-v, --version"), e.command("create").description("Create a new Hype Stack project").option("-n, --name <name>", "Project name").option("-d, --directory <path>", "Target directory").option("-e, --editor <editor>", "Code editor (cursor, claude, windsurf, copilot)").option("-t, --theme <theme>", "Color theme (default, slate, rose, emerald, violet, amber, ocean, zinc-mono, crimson, midnight)").option("--no-install", "Skip dependency installation").option("--no-setup", "Skip Docker services and database migrations after create").option("-y, --yes", "Skip confirmation prompts (requires --name)").action(async (e) => {
|
|
5476
|
-
await
|
|
5539
|
+
await gs({
|
|
5477
5540
|
name: e.name,
|
|
5478
5541
|
directory: e.directory,
|
|
5479
5542
|
install: e.install,
|
|
@@ -5483,38 +5546,38 @@ function Ls() {
|
|
|
5483
5546
|
setup: e.setup
|
|
5484
5547
|
});
|
|
5485
5548
|
}), e.command("init").description("Initialize stack.json in the current project").action(async () => {
|
|
5486
|
-
await
|
|
5549
|
+
await _s({});
|
|
5487
5550
|
}), e.command("onboard").description("Set up env vars, run migrations, and get the start command").option("-y, --yes", "Skip prompts, accept defaults").option("--skip-migrations", "Skip Docker services and database migrations").option("--cwd <path>", "Working directory").action(async (e) => {
|
|
5488
|
-
await
|
|
5551
|
+
await Ns({
|
|
5489
5552
|
cwd: e.cwd,
|
|
5490
5553
|
yes: e.yes,
|
|
5491
5554
|
skipMigrations: e.skipMigrations
|
|
5492
5555
|
});
|
|
5493
5556
|
}), e.command("compose").description("Choose feature packs to add to your project").option("--packs <list>", "Comma-separated pack names (non-interactive). Append @frontend or @admin to a layout pack to target that app shell, e.g. layout-basic@frontend,layout-native-app-shell@admin").option("--force", "Overwrite existing files").option("-y, --yes", "Skip confirmation prompts").option("-k, --key <key>", "License key").option("--license-key <key>", "License key (alias for --key)").option("--cwd <path>", "Working directory").action(async (e) => {
|
|
5494
|
-
await
|
|
5495
|
-
packs:
|
|
5557
|
+
await ys({
|
|
5558
|
+
packs: Ks(e.packs),
|
|
5496
5559
|
force: e.force,
|
|
5497
5560
|
yes: e.yes,
|
|
5498
5561
|
licenseKey: e.key ?? e.licenseKey,
|
|
5499
5562
|
cwd: e.cwd
|
|
5500
5563
|
});
|
|
5501
5564
|
}), e.command("template").description("Install a template by id, with starter/layout variant swaps and extra packs on top").argument("[id]", "Template id (omit to pick interactively)").option("--variants <map>", "Preselect slot variants, e.g. starter-saas=starter-saas-better-auth,layout=layout-basic").option("--packs <list>", "Extra packs to add on top of the template (comma-separated)").option("--force", "Overwrite existing files").option("-y, --yes", "Skip confirmation prompts (requires <id>)").option("-k, --key <key>", "License key").option("--license-key <key>", "License key (alias for --key)").option("--cwd <path>", "Working directory").action(async (e, t) => {
|
|
5502
|
-
await
|
|
5565
|
+
await Hs({
|
|
5503
5566
|
templateId: e,
|
|
5504
|
-
variants:
|
|
5505
|
-
packs:
|
|
5567
|
+
variants: qs(t.variants),
|
|
5568
|
+
packs: Ks(t.packs),
|
|
5506
5569
|
force: t.force,
|
|
5507
5570
|
yes: t.yes,
|
|
5508
5571
|
licenseKey: t.key ?? t.licenseKey,
|
|
5509
5572
|
cwd: t.cwd
|
|
5510
5573
|
});
|
|
5511
5574
|
}), e.command("login").description("Log in via your browser to install packs your organization owns").action(async () => {
|
|
5512
|
-
await
|
|
5575
|
+
await Ts();
|
|
5513
5576
|
}), e.command("logout").description("Log out and remove the saved CLI token").action(async () => {
|
|
5514
|
-
await
|
|
5577
|
+
await Es();
|
|
5515
5578
|
}), e.command("auth").description("Alias for `login`").action(async () => {
|
|
5516
|
-
await
|
|
5579
|
+
await Ts();
|
|
5517
5580
|
}), e;
|
|
5518
5581
|
}
|
|
5519
5582
|
//#endregion
|
|
5520
|
-
export {
|
|
5583
|
+
export { vs as a, ys as i, Es as n, _s as o, Ts as r, gs as s, Js as t };
|