@luckystack/devkit 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3440,8 +3440,8 @@ var scanFunctionsFolder = async (dir, rootDir, basePath = []) => {
3440
3440
 
3441
3441
  // src/hotReload.ts
3442
3442
  import { watch } from "chokidar";
3443
- import fs9 from "fs";
3444
- import path12 from "path";
3443
+ import fs10 from "fs";
3444
+ import path13 from "path";
3445
3445
 
3446
3446
  // src/templateInjector.ts
3447
3447
  import fs7 from "fs";
@@ -4264,9 +4264,34 @@ var findDependentRouteFiles = (changedFilePath) => {
4264
4264
  return affectedRoutes;
4265
4265
  };
4266
4266
 
4267
+ // src/prismaClientCheck.ts
4268
+ import fs9 from "fs";
4269
+ import path12 from "path";
4270
+ import { spawn } from "child_process";
4271
+ import { ROOT_DIR as ROOT_DIR6, tryCatch as tryCatch2 } from "@luckystack/core";
4272
+ var GENERATED_CLIENT_DIR = path12.join(ROOT_DIR6, "node_modules", ".prisma", "client");
4273
+ var DEFAULT_SCHEMA_PATH = path12.join(ROOT_DIR6, "prisma", "schema.prisma");
4274
+ var isPrismaClientMissing = () => fs9.existsSync(DEFAULT_SCHEMA_PATH) && !fs9.existsSync(GENERATED_CLIENT_DIR);
4275
+ var runPrismaGenerate = async () => tryCatch2(
4276
+ () => new Promise((resolve, reject) => {
4277
+ const child = spawn("npx", ["prisma", "generate"], {
4278
+ cwd: ROOT_DIR6,
4279
+ stdio: "inherit",
4280
+ //? `npx` resolves to `npx.cmd` on Windows, which requires shell
4281
+ //? invocation to be found on PATH. Dev-only, fixed argv (no user
4282
+ //? input interpolated), so the shell is not an injection surface.
4283
+ shell: process.platform === "win32"
4284
+ });
4285
+ child.on("error", reject);
4286
+ child.on("exit", (code) => {
4287
+ resolve(code ?? 0);
4288
+ });
4289
+ })
4290
+ );
4291
+
4267
4292
  // src/hotReload.ts
4268
- import { tryCatch as tryCatch2, getProjectConfig, getLocaleReloader } from "@luckystack/core";
4269
- var normalizeFsPath = (value) => path12.resolve(value).replaceAll("\\", "/");
4293
+ import { tryCatch as tryCatch3, getProjectConfig, getLocaleReloader } from "@luckystack/core";
4294
+ var normalizeFsPath = (value) => path13.resolve(value).replaceAll("\\", "/");
4270
4295
  var isGeneratedPath = (normalizedPath) => {
4271
4296
  return normalizedPath.includes("apiTypes.generated.ts") || normalizedPath.includes("apiDocs.generated.json");
4272
4297
  };
@@ -4278,7 +4303,7 @@ var createTypeMapQueue = () => {
4278
4303
  const startedAt = Date.now();
4279
4304
  setImmediate(() => {
4280
4305
  void (async () => {
4281
- const [err] = await tryCatch2(() => {
4306
+ const [err] = await tryCatch3(() => {
4282
4307
  generateTypeMapFile({ quiet: true });
4283
4308
  });
4284
4309
  if (err) {
@@ -4474,7 +4499,7 @@ var setupWatchers = () => {
4474
4499
  if (shouldInjectTemplate(filePath, { isNewFile: true })) {
4475
4500
  if (isSyncServerFile(normalizedPath)) {
4476
4501
  const clientPath = getPairedSyncFile(normalizedPath);
4477
- if (clientPath && fs9.existsSync(clientPath) && !isEmptyFile(clientPath)) {
4502
+ if (clientPath && fs10.existsSync(clientPath) && !isEmptyFile(clientPath)) {
4478
4503
  const clientInputTypes = extractClientInputFromFile(clientPath);
4479
4504
  if (clientInputTypes) {
4480
4505
  await injectServerTemplateWithClientInput(filePath, clientInputTypes);
@@ -4637,7 +4662,7 @@ var setupWatchers = () => {
4637
4662
  scheduleReload("sync", async () => {
4638
4663
  if (isSyncServerFile(normalizedPath)) {
4639
4664
  const clientPath = getPairedSyncFile(normalizedPath);
4640
- if (clientPath && fs9.existsSync(clientPath)) {
4665
+ if (clientPath && fs10.existsSync(clientPath)) {
4641
4666
  const pagePath = extractSyncPagePath2(normalizedPath);
4642
4667
  const syncName = extractSyncName2(normalizedPath);
4643
4668
  const clientInputTypes = extractClientInputFromGeneratedTypes(pagePath, syncName);
@@ -4667,11 +4692,21 @@ var setupWatchers = () => {
4667
4692
  mountWatchers(safeHandleAdd, safeHandleChange, safeHandleDelete, handleFunctionChange);
4668
4693
  setImmediate(() => {
4669
4694
  void (async () => {
4670
- const [err] = await tryCatch2(() => {
4695
+ if (isPrismaClientMissing()) {
4696
+ console.log(`[HotReload] @prisma/client not generated yet \u2014 running prisma generate (no DB needed)\u2026`, "blue");
4697
+ const [generateErr, exitCode] = await runPrismaGenerate();
4698
+ if (generateErr || exitCode !== 0) {
4699
+ console.log(`[HotReload] prisma generate failed${generateErr ? `: ${String(generateErr)}` : ` (exit code ${String(exitCode)})`} \u2014 run \`npm run prisma:generate\` manually and restart`, "red");
4700
+ } else {
4701
+ console.log(`[HotReload] prisma generate complete`, "green");
4702
+ }
4703
+ }
4704
+ const [err] = await tryCatch3(() => {
4671
4705
  generateTypeMapFile({ quiet: true });
4672
4706
  });
4673
4707
  if (err) {
4674
- console.log(`[HotReload] initial type map generation failed: ${String(err)}`, "red");
4708
+ const hint = isPrismaClientMissing() ? "\n \u2192 This usually means @prisma/client is not generated. Run `npm run prisma:generate` and restart." : "";
4709
+ console.log(`[HotReload] initial type map generation failed: ${String(err)}${hint}`, "red");
4675
4710
  } else {
4676
4711
  console.log(`[HotReload] type map ready in background`, "green");
4677
4712
  }