@kuckit/cli 1.0.0 → 1.0.4

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/bin.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { i as generateModule, n as loadTryLoadKuckitConfig, r as addModule, t as discoverModules } from "./discover-module-B7rxN4vq.js";
2
+ import { i as generateModule, n as loadTryLoadKuckitConfig, r as addModule, t as discoverModules } from "./discover-module-B4oRIuSK.js";
3
3
  import { program } from "commander";
4
4
  import { dirname, join } from "node:path";
5
- import { chmodSync, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
5
+ import { chmodSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
6
6
  import { execSync, spawn } from "child_process";
7
7
  import { access, constants as constants$1, mkdir, readFile, unlink, writeFile } from "fs/promises";
8
8
  import { dirname as dirname$1, join as join$1 } from "path";
@@ -15,6 +15,15 @@ const CONFIG_FILES = [
15
15
  "kuckit.config.js",
16
16
  "kuckit.config.mjs"
17
17
  ];
18
+ const FRAMEWORK_PACKAGES = [
19
+ "@kuckit/sdk",
20
+ "@kuckit/sdk-react",
21
+ "@kuckit/api",
22
+ "@kuckit/db",
23
+ "@kuckit/auth",
24
+ "@kuckit/domain",
25
+ "@kuckit/contracts"
26
+ ];
18
27
  function findConfigFile(cwd) {
19
28
  let dir = cwd;
20
29
  while (dir !== dirname(dir)) {
@@ -58,6 +67,18 @@ function findPackagePath(packageName, cwd) {
58
67
  }
59
68
  return null;
60
69
  }
70
+ function scanSourceFiles(dir) {
71
+ const files = [];
72
+ try {
73
+ const entries = readdirSync(dir);
74
+ for (const entry of entries) {
75
+ const fullPath = join(dir, entry);
76
+ if (statSync(fullPath).isDirectory()) files.push(...scanSourceFiles(fullPath));
77
+ else if (entry.endsWith(".ts") || entry.endsWith(".tsx")) files.push(fullPath);
78
+ }
79
+ } catch {}
80
+ return files;
81
+ }
61
82
  function checkModuleExports(packageName, cwd) {
62
83
  const result = {
63
84
  server: false,
@@ -211,19 +232,114 @@ async function doctor(options) {
211
232
  status: "pass",
212
233
  message: "Module exports valid"
213
234
  });
214
- const sdkPackages = ["@kuckit/sdk", "@kuckit/sdk-react"];
215
- const missingSdk = [];
216
- for (const sdk of sdkPackages) if (!readPackageJson(sdk, cwd)) missingSdk.push(sdk);
217
- if (missingSdk.length > 0) checks.push({
218
- name: "sdk-installed",
235
+ const missingFramework = [];
236
+ const installedFramework = [];
237
+ for (const pkg of FRAMEWORK_PACKAGES) {
238
+ const pkgJson = readPackageJson(pkg, cwd);
239
+ if (!pkgJson) missingFramework.push(pkg);
240
+ else installedFramework.push({
241
+ name: pkg,
242
+ version: pkgJson.version
243
+ });
244
+ }
245
+ if (missingFramework.length > 0) checks.push({
246
+ name: "framework-installed",
219
247
  status: "warn",
220
- message: `SDK package(s) not found: ${missingSdk.join(", ")}`
248
+ message: `Framework package(s) not found: ${missingFramework.length}/${FRAMEWORK_PACKAGES.length}`,
249
+ details: missingFramework.map((p) => ` - ${p} (not installed)`)
221
250
  });
222
251
  else checks.push({
223
- name: "sdk-installed",
252
+ name: "framework-installed",
253
+ status: "pass",
254
+ message: `All ${FRAMEWORK_PACKAGES.length} framework packages installed`
255
+ });
256
+ const kuckitVersions = /* @__PURE__ */ new Map();
257
+ for (const { name, version } of installedFramework) if (version) kuckitVersions.set(name, version);
258
+ const uniqueVersions = new Set(kuckitVersions.values());
259
+ if (uniqueVersions.size > 1 && installedFramework.length >= 2) {
260
+ const versionParts = [...uniqueVersions].map((v) => {
261
+ const match = v.match(/^(\d+)\.(\d+)/);
262
+ return match ? `${match[1]}.${match[2]}` : v;
263
+ });
264
+ if (new Set(versionParts).size > 1) checks.push({
265
+ name: "version-compatibility",
266
+ status: "warn",
267
+ message: "Framework packages have mismatched versions",
268
+ details: [...kuckitVersions.entries()].map(([name, ver]) => ` - ${name}: ${ver}`)
269
+ });
270
+ else checks.push({
271
+ name: "version-compatibility",
272
+ status: "pass",
273
+ message: "Framework package versions are compatible"
274
+ });
275
+ } else if (installedFramework.length >= 2) checks.push({
276
+ name: "version-compatibility",
224
277
  status: "pass",
225
- message: "SDK packages installed"
278
+ message: "Framework package versions are compatible"
226
279
  });
280
+ const localImportIssues = [];
281
+ for (const packageName of installedPackages) {
282
+ const packagePath = findPackagePath(packageName, cwd);
283
+ if (!packagePath) continue;
284
+ const srcPath = join(packagePath, "src");
285
+ if (!existsSync(srcPath)) continue;
286
+ try {
287
+ const files = scanSourceFiles(srcPath);
288
+ for (const file of files) if (readFileSync(file, "utf-8").match(/from\s+['"]@(?!kuckit\/)[^'"/]+\/(api|db|auth|domain|contracts)['"]/g)) {
289
+ const relPath = file.replace(cwd, ".");
290
+ localImportIssues.push(`${packageName}: ${relPath} imports from local package instead of @kuckit/*`);
291
+ }
292
+ } catch {}
293
+ }
294
+ if (localImportIssues.length > 0) checks.push({
295
+ name: "framework-imports",
296
+ status: "warn",
297
+ message: `${localImportIssues.length} module(s) import from local packages instead of @kuckit/*`,
298
+ details: localImportIssues.slice(0, 5).map((i) => ` - ${i}`)
299
+ });
300
+ else if (installedPackages.length > 0) checks.push({
301
+ name: "framework-imports",
302
+ status: "pass",
303
+ message: "Module imports use @kuckit/* framework packages"
304
+ });
305
+ const serverModulesPath = join(cwd, "apps", "server", "src", "config", "modules.ts");
306
+ const clientModulesPath = join(cwd, "apps", "web", "src", "modules.client.ts");
307
+ if (existsSync(serverModulesPath) && existsSync(clientModulesPath)) {
308
+ const serverContent = readFileSync(serverModulesPath, "utf-8");
309
+ const clientContent = readFileSync(clientModulesPath, "utf-8");
310
+ const serverModulePattern = /from\s+['"]@[^'"]+\/([^'"]+)-module['"]/g;
311
+ const clientModulePattern = /from\s+['"]@[^'"]+\/([^'"]+)-module\/client['"]/g;
312
+ const serverModules = /* @__PURE__ */ new Set();
313
+ const clientModules = /* @__PURE__ */ new Set();
314
+ let match;
315
+ while ((match = serverModulePattern.exec(serverContent)) !== null) {
316
+ const lineStart = serverContent.lastIndexOf("\n", match.index) + 1;
317
+ if (!serverContent.slice(lineStart, match.index).includes("//")) serverModules.add(match[1]);
318
+ }
319
+ while ((match = clientModulePattern.exec(clientContent)) !== null) {
320
+ const lineStart = clientContent.lastIndexOf("\n", match.index) + 1;
321
+ if (!clientContent.slice(lineStart, match.index).includes("//")) clientModules.add(match[1]);
322
+ }
323
+ const clientOnly = [...clientModules].filter((m) => !serverModules.has(m));
324
+ const serverOnly = [...serverModules].filter((m) => !clientModules.has(m));
325
+ if (clientOnly.length > 0) checks.push({
326
+ name: "module-sync",
327
+ status: "fail",
328
+ message: `Client modules without matching server modules (will cause 404 errors)`,
329
+ details: clientOnly.map((m) => ` - ${m}-module: registered in client but not server`)
330
+ });
331
+ else if (serverOnly.length > 0) checks.push({
332
+ name: "module-sync",
333
+ status: "warn",
334
+ message: `Server modules without matching client modules`,
335
+ details: serverOnly.map((m) => ` - ${m}-module: registered in server but not client`)
336
+ });
337
+ else if (serverModules.size > 0 || clientModules.size > 0) checks.push({
338
+ name: "module-sync",
339
+ status: "pass",
340
+ message: "Server and client modules are in sync"
341
+ });
342
+ }
227
343
  const report = {
228
344
  success: checks.every((c) => c.status !== "fail"),
229
345
  checks,
@@ -519,7 +635,7 @@ async function dbStudio(options) {
519
635
 
520
636
  //#endregion
521
637
  //#region src/lib/credentials.ts
522
- const DEFAULT_SERVER_URL = "http://localhost:3000";
638
+ const DEFAULT_SERVER_URL = "https://dev-app-nyh7i73bea-uc.a.run.app/";
523
639
  const CONFIG_DIR = join(homedir(), ".kuckit");
524
640
  const CONFIG_PATH = join(CONFIG_DIR, "config.json");
525
641
  function loadConfig$8() {
@@ -1551,6 +1667,7 @@ async function infraDeploy(options) {
1551
1667
  }
1552
1668
  console.log("Configuring deployment...");
1553
1669
  await setPulumiConfig("imageUrl", imageUrl, { cwd: infraDir });
1670
+ if (config.outputs?.serviceUrl) await setPulumiConfig("appUrl", config.outputs.serviceUrl, { cwd: infraDir });
1554
1671
  if (options.preview) console.log("\nPreviewing changes...\n");
1555
1672
  else console.log("\nDeploying to Cloud Run...\n");
1556
1673
  const result = await pulumiUp({