@ultimat3/cli 27.0.0 → 27.2.0

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": "@ultimat3/cli",
3
- "version": "27.0.0",
3
+ "version": "27.2.0",
4
4
  "description": "The `x` binary: new, dev, build, verify, generate, db, mcp, doctor, deploy",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -39,33 +39,33 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "@babel/core": "^8.0.1",
42
- "@ultimat3/action": "27.0.0",
43
- "@ultimat3/admin": "27.0.0",
44
- "@ultimat3/ai": "27.0.0",
45
- "@ultimat3/auth": "27.0.0",
46
- "@ultimat3/cache": "27.0.0",
47
- "@ultimat3/core": "27.0.0",
48
- "@ultimat3/db": "27.0.0",
49
- "@ultimat3/entity": "27.0.0",
50
- "@ultimat3/flags": "27.0.0",
51
- "@ultimat3/http": "27.0.0",
52
- "@ultimat3/i18n": "27.0.0",
53
- "@ultimat3/jobs": "27.0.0",
54
- "@ultimat3/mail": "27.0.0",
55
- "@ultimat3/manifest": "27.0.0",
56
- "@ultimat3/mcp": "27.0.0",
57
- "@ultimat3/money": "27.0.0",
58
- "@ultimat3/notify": "27.0.0",
59
- "@ultimat3/policy": "27.0.0",
60
- "@ultimat3/pwa": "27.0.0",
61
- "@ultimat3/query": "27.0.0",
62
- "@ultimat3/realtime": "27.0.0",
63
- "@ultimat3/render": "27.0.0",
64
- "@ultimat3/schema": "27.0.0",
65
- "@ultimat3/seo": "27.0.0",
66
- "@ultimat3/storage": "27.0.0",
67
- "@ultimat3/testing": "27.0.0",
68
- "@ultimat3/time": "27.0.0",
42
+ "@ultimat3/action": "27.2.0",
43
+ "@ultimat3/admin": "27.2.0",
44
+ "@ultimat3/ai": "27.2.0",
45
+ "@ultimat3/auth": "27.2.0",
46
+ "@ultimat3/cache": "27.2.0",
47
+ "@ultimat3/core": "27.2.0",
48
+ "@ultimat3/db": "27.2.0",
49
+ "@ultimat3/entity": "27.2.0",
50
+ "@ultimat3/flags": "27.2.0",
51
+ "@ultimat3/http": "27.2.0",
52
+ "@ultimat3/i18n": "27.2.0",
53
+ "@ultimat3/jobs": "27.2.0",
54
+ "@ultimat3/mail": "27.2.0",
55
+ "@ultimat3/manifest": "27.2.0",
56
+ "@ultimat3/mcp": "27.2.0",
57
+ "@ultimat3/money": "27.2.0",
58
+ "@ultimat3/notify": "27.2.0",
59
+ "@ultimat3/policy": "27.2.0",
60
+ "@ultimat3/pwa": "27.2.0",
61
+ "@ultimat3/query": "27.2.0",
62
+ "@ultimat3/realtime": "27.2.0",
63
+ "@ultimat3/render": "27.2.0",
64
+ "@ultimat3/schema": "27.2.0",
65
+ "@ultimat3/seo": "27.2.0",
66
+ "@ultimat3/storage": "27.2.0",
67
+ "@ultimat3/testing": "27.2.0",
68
+ "@ultimat3/time": "27.2.0",
69
69
  "babel-preset-solid": "^1.9.15"
70
70
  }
71
71
  }
package/src/budgets.ts CHANGED
@@ -86,7 +86,9 @@ const jsBudgetOf = (route: RouteFact): number | null => parseByteBudget(route.bu
86
86
  export type RouteFileOf = (url: string) => string | undefined;
87
87
 
88
88
  const declaredFileOf: RouteFileOf = (url) =>
89
- describePages().find((route) => route.path === url && route.mount === undefined)?.file;
89
+ describePages().find(
90
+ (route) => route.path === url && (route.mount === undefined || route.mount.claimed === true),
91
+ )?.file;
90
92
 
91
93
  const KB = 1024;
92
94
 
@@ -305,6 +305,17 @@ async function builtOutputs(
305
305
  return outputs;
306
306
  }
307
307
 
308
+ /**
309
+ * The entry's own file, added to sources the map resolved into the root. A pure re-export island
310
+ * (`export { mountMenu as mount } from '../shared/menu'`) emits no code of its own, so its source
311
+ * map names only what it re-exports: the store then recorded nothing that changes when the entry
312
+ * is edited, and `writeIslandStore` refused it as a map whose paths left the root. A map that
313
+ * resolved NOTHING into the root stays empty — that is the cwd failure, and it is still refused.
314
+ */
315
+ function withOwnFile(file: string, sources: SourcePaths): SourcePaths {
316
+ return sources.length === 0 || sources.includes(file) ? sources : [...sources, file].sort();
317
+ }
318
+
308
319
  /** The linked outputs, as the chunk table: the entries in `files` order, their chunks attached. */
309
320
  function entryChunks(
310
321
  files: readonly string[],
@@ -345,7 +356,7 @@ function entryChunks(
345
356
  // different files at one address. `bytes` is measured on THAT code, never on this build's.
346
357
  ...stableChunk(file, entry.identity, entry.code),
347
358
  imports: closure(entry.imports),
348
- sources: sources.get(entry.path) ?? [],
359
+ sources: withOwnFile(file, sources.get(entry.path) ?? []),
349
360
  });
350
361
  }
351
362
  return chunks;
@@ -7,7 +7,7 @@ import type { AdminApp, AdminRouteConfig } from '@ultimat3/admin';
7
7
  import type { Route, RouteMeta } from '@ultimat3/http';
8
8
  import { asCtx, html, redirect, routeNotFound } from '@ultimat3/http';
9
9
  import type { RouteEntry } from '@ultimat3/render';
10
- import { compilePattern } from '@ultimat3/render';
10
+ import { compilePattern, routeFor } from '@ultimat3/render';
11
11
  import { renderSsr } from '@ultimat3/render/server';
12
12
  import type { DocumentOptions } from './document-options';
13
13
  import { routeDocument } from './runtime-render';
@@ -120,6 +120,9 @@ const isRecord = (value: unknown): value is Readonly<Record<string, unknown>> =>
120
120
 
121
121
  const METHODS: readonly ('GET' | 'POST')[] = ['GET', 'POST'];
122
122
 
123
+ /** A file route on a mounted path exists only by a claim the mount accepted (`registerRoute`). */
124
+ const claimed = (path: string): boolean => routeFor(path) !== undefined;
125
+
123
126
  /**
124
127
  * Two paths per admin and two methods on each: the base path itself (the dashboard) and one
125
128
  * catch-all under it. The admin's own table is matched INSIDE the handler, against the table as
@@ -131,7 +134,11 @@ const METHODS: readonly ('GET' | 'POST')[] = ['GET', 'POST'];
131
134
  export function adminMountRoutes(options: AdminMountOptions): readonly Route[] {
132
135
  return [...declared().keys()].flatMap((base) =>
133
136
  [base, `${base}/*rest`].flatMap((path) =>
134
- METHODS.map(
137
+ // The dashboard's GET, when an app file claimed it (`claimAdminRoute`): the file's route
138
+ // serves it, and two GETs on one path is X_ROUTE_CONFLICT. A claimed path UNDER the base
139
+ // needs nothing here — a static or param segment outranks the catch-all — and every POST
140
+ // stays the admin's. Only a claim the admin issued can put a file on a mounted path.
141
+ METHODS.filter((method) => !(method === 'GET' && path === base && claimed(base))).map(
135
142
  (method): Route => ({
136
143
  method,
137
144
  path,