@beignet/cli 0.0.19 → 0.0.20

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beignet/cli",
3
- "version": "0.0.19",
3
+ "version": "0.0.20",
4
4
  "type": "module",
5
5
  "description": "CLI for creating and maintaining Beignet apps.",
6
6
  "main": "./dist/lib.js",
@@ -66,7 +66,7 @@
66
66
  "typescript": "^5.3.0"
67
67
  },
68
68
  "dependencies": {
69
- "@beignet/core": "^0.0.19",
69
+ "@beignet/core": "^0.0.20",
70
70
  "@clack/prompts": "^1.5.1",
71
71
  "@modelcontextprotocol/sdk": "^1.29.0",
72
72
  "@stricli/core": "^1.2.7",
package/src/config.ts CHANGED
@@ -176,6 +176,30 @@ export function directoryPath(filePath: string): string {
176
176
  return normalizePath(filePath).replaceAll(/^\/+|\/+$/g, "");
177
177
  }
178
178
 
179
+ /**
180
+ * Infer the app source root from app-context.ts placement.
181
+ *
182
+ * Default apps put app-context.ts at the project root, while src-layout apps
183
+ * configure it as src/app-context.ts. Client setup follows that same root.
184
+ */
185
+ export function appRootPath(config: ResolvedBeignetConfig): string {
186
+ const appRoot = directoryPath(path.posix.dirname(config.paths.appContext));
187
+ return appRoot === "." ? "" : appRoot;
188
+ }
189
+
190
+ export function clientDirPath(config: ResolvedBeignetConfig): string {
191
+ const appRoot = appRootPath(config);
192
+ return path.posix.join(appRoot, "client");
193
+ }
194
+
195
+ export function clientIndexPath(config: ResolvedBeignetConfig): string {
196
+ return path.posix.join(clientDirPath(config), "index.ts");
197
+ }
198
+
199
+ export function clientFormsPath(config: ResolvedBeignetConfig): string {
200
+ return path.posix.join(clientDirPath(config), "forms.ts");
201
+ }
202
+
179
203
  const configFileNames = [
180
204
  "beignet.config.ts",
181
205
  "beignet.config.json",
package/src/inspect.ts CHANGED
@@ -8,6 +8,9 @@ import {
8
8
  import { createPainter } from "./ansi.js";
9
9
  import {
10
10
  type BeignetConfig,
11
+ clientDirPath,
12
+ clientFormsPath,
13
+ clientIndexPath,
11
14
  directoryPath,
12
15
  loadBeignetConfig,
13
16
  normalizePath,
@@ -1362,13 +1365,16 @@ async function inspectCanonicalConformance(
1362
1365
  const packageJson = await readPackageJson(targetDir, files);
1363
1366
  const installedPackages = installedPackageNames(packageJson);
1364
1367
  const featuresPath = directoryPath(config.paths.features);
1368
+ const clientDir = clientDirPath(config);
1369
+ const clientIndex = clientIndexPath(config);
1370
+ const clientForms = clientFormsPath(config);
1365
1371
  const hasClientSurface =
1366
1372
  files.some(
1367
1373
  (file) =>
1368
1374
  file.startsWith(`${featuresPath}/`) &&
1369
1375
  (file.includes("/components/") || file.includes("/client/")),
1370
1376
  ) ||
1371
- files.some((file) => file.startsWith("client/")) ||
1377
+ files.some((file) => file.startsWith(`${clientDir}/`)) ||
1372
1378
  [
1373
1379
  "@beignet/react-query",
1374
1380
  "@beignet/react-hook-form",
@@ -1406,20 +1412,18 @@ async function inspectCanonicalConformance(
1406
1412
 
1407
1413
  if (hasClientSurface) {
1408
1414
  requiredFiles.push({
1409
- file: "client/index.ts",
1410
- reason:
1411
- "client/index.ts should own the typed client and frontend adapter setup.",
1415
+ file: clientIndex,
1416
+ reason: `${clientIndex} should own the typed client and frontend adapter setup.`,
1412
1417
  });
1413
1418
  }
1414
1419
 
1415
1420
  if (
1416
1421
  installedPackages.has("@beignet/react-hook-form") ||
1417
- files.includes("client/forms.ts")
1422
+ files.includes(clientForms)
1418
1423
  ) {
1419
1424
  requiredFiles.push({
1420
- file: "client/forms.ts",
1421
- reason:
1422
- "client/forms.ts should own React Hook Form adapter setup when form helpers are used.",
1425
+ file: clientForms,
1426
+ reason: `${clientForms} should own React Hook Form adapter setup when form helpers are used.`,
1423
1427
  });
1424
1428
  }
1425
1429
 
package/src/lint.ts CHANGED
@@ -3,6 +3,7 @@ import path from "node:path";
3
3
  import { createPainter } from "./ansi.js";
4
4
  import {
5
5
  type BeignetConfig,
6
+ clientDirPath,
6
7
  directoryPath,
7
8
  loadBeignetConfig,
8
9
  normalizePath,
@@ -946,7 +947,7 @@ function runtimeBoundaryRootKind(
946
947
  if (layer === "contract") return "contract";
947
948
  if (layer === "client") return "client";
948
949
  if (hasUseClientDirective(source)) return "client";
949
- if (isGeneratedClientAdapter(file)) return "client";
950
+ if (isGeneratedClientAdapter(file, config)) return "client";
950
951
  return undefined;
951
952
  }
952
953
 
@@ -960,13 +961,13 @@ function hasUseClientDirective(source: string): boolean {
960
961
  );
961
962
  }
962
963
 
963
- function isGeneratedClientAdapter(file: string): boolean {
964
- return (
965
- file === "client/index.ts" ||
966
- file === "client/api-client.ts" ||
967
- file === "client/rhf.ts" ||
968
- file === "client/rq.ts" ||
969
- file === "client/uploads.ts"
964
+ function isGeneratedClientAdapter(
965
+ file: string,
966
+ config: ResolvedBeignetConfig,
967
+ ): boolean {
968
+ const clientDir = clientDirPath(config);
969
+ return ["index.ts", "api-client.ts", "rhf.ts", "rq.ts", "uploads.ts"].some(
970
+ (adapterFile) => file === path.posix.join(clientDir, adapterFile),
970
971
  );
971
972
  }
972
973
 
@@ -1174,7 +1175,7 @@ function classifyPath(
1174
1175
  return "infra";
1175
1176
  }
1176
1177
  if (isUnder(normalizedPath, portsDir)) return "port";
1177
- if (isUnder(normalizedPath, "client")) return "client";
1178
+ if (isUnder(normalizedPath, clientDirPath(config))) return "client";
1178
1179
  if (isUnder(normalizedPath, "components")) return "component";
1179
1180
  if (isUnder(normalizedPath, legacySharedDomainPath(config))) return "domain";
1180
1181
  if (isUnder(normalizedPath, "lib")) return "lib";
package/src/make.ts CHANGED
@@ -4,6 +4,7 @@ import path from "node:path";
4
4
  import type { MakeFeatureAddon } from "./choices.js";
5
5
  import {
6
6
  type BeignetConfig,
7
+ clientIndexPath,
7
8
  directoryPath,
8
9
  loadBeignetConfig,
9
10
  normalizePath,
@@ -5842,12 +5843,6 @@ function featureUiIndexFilePath(
5842
5843
  return path.join(featureUiDir(names, config), "index.ts");
5843
5844
  }
5844
5845
 
5845
- function clientIndexPath(config: ResolvedBeignetConfig): string {
5846
- const appRoot = path.posix.dirname(config.paths.appContext);
5847
-
5848
- return path.join(appRoot === "." ? "" : appRoot, "client/index.ts");
5849
- }
5850
-
5851
5846
  function usesFeatureOwnedContracts(config: ResolvedBeignetConfig): boolean {
5852
5847
  return (
5853
5848
  directoryPath(config.paths.contracts) ===