@fougere/core 0.1.0-alpha.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.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +21 -0
  3. package/dist/binding.d.ts +63 -0
  4. package/dist/binding.d.ts.map +1 -0
  5. package/dist/binding.js +107 -0
  6. package/dist/binding.js.map +1 -0
  7. package/dist/boot.d.ts +38 -0
  8. package/dist/boot.d.ts.map +1 -0
  9. package/dist/boot.js +53 -0
  10. package/dist/boot.js.map +1 -0
  11. package/dist/bootstrap.d.ts +4 -0
  12. package/dist/bootstrap.d.ts.map +1 -0
  13. package/dist/bootstrap.js +825 -0
  14. package/dist/bootstrap.js.map +1 -0
  15. package/dist/builtins/config.d.ts +4 -0
  16. package/dist/builtins/config.d.ts.map +1 -0
  17. package/dist/builtins/config.js +6 -0
  18. package/dist/builtins/config.js.map +1 -0
  19. package/dist/builtins/logger.d.ts +28 -0
  20. package/dist/builtins/logger.d.ts.map +1 -0
  21. package/dist/builtins/logger.js +76 -0
  22. package/dist/builtins/logger.js.map +1 -0
  23. package/dist/call.d.ts +172 -0
  24. package/dist/call.d.ts.map +1 -0
  25. package/dist/call.js +209 -0
  26. package/dist/call.js.map +1 -0
  27. package/dist/collector.d.ts +28 -0
  28. package/dist/collector.d.ts.map +1 -0
  29. package/dist/collector.js +32 -0
  30. package/dist/collector.js.map +1 -0
  31. package/dist/config-loader.d.ts +59 -0
  32. package/dist/config-loader.d.ts.map +1 -0
  33. package/dist/config-loader.js +97 -0
  34. package/dist/config-loader.js.map +1 -0
  35. package/dist/contract.d.ts +43 -0
  36. package/dist/contract.d.ts.map +1 -0
  37. package/dist/contract.js +29 -0
  38. package/dist/contract.js.map +1 -0
  39. package/dist/crud.d.ts +61 -0
  40. package/dist/crud.d.ts.map +1 -0
  41. package/dist/crud.js +85 -0
  42. package/dist/crud.js.map +1 -0
  43. package/dist/define.d.ts +8 -0
  44. package/dist/define.d.ts.map +1 -0
  45. package/dist/define.js +9 -0
  46. package/dist/define.js.map +1 -0
  47. package/dist/egress.d.ts +78 -0
  48. package/dist/egress.d.ts.map +1 -0
  49. package/dist/egress.js +185 -0
  50. package/dist/egress.js.map +1 -0
  51. package/dist/emit.d.ts +51 -0
  52. package/dist/emit.d.ts.map +1 -0
  53. package/dist/emit.js +57 -0
  54. package/dist/emit.js.map +1 -0
  55. package/dist/errors.d.ts +22 -0
  56. package/dist/errors.d.ts.map +1 -0
  57. package/dist/errors.js +74 -0
  58. package/dist/errors.js.map +1 -0
  59. package/dist/frond-config.d.ts +80 -0
  60. package/dist/frond-config.d.ts.map +1 -0
  61. package/dist/frond-config.js +32 -0
  62. package/dist/frond-config.js.map +1 -0
  63. package/dist/graph.d.ts +33 -0
  64. package/dist/graph.d.ts.map +1 -0
  65. package/dist/graph.js +142 -0
  66. package/dist/graph.js.map +1 -0
  67. package/dist/handler-parser.d.ts +82 -0
  68. package/dist/handler-parser.d.ts.map +1 -0
  69. package/dist/handler-parser.js +505 -0
  70. package/dist/handler-parser.js.map +1 -0
  71. package/dist/imports.d.ts +22 -0
  72. package/dist/imports.d.ts.map +1 -0
  73. package/dist/imports.js +80 -0
  74. package/dist/imports.js.map +1 -0
  75. package/dist/index.d.ts +43 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +37 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/invocation.d.ts +20 -0
  80. package/dist/invocation.d.ts.map +1 -0
  81. package/dist/invocation.js +15 -0
  82. package/dist/invocation.js.map +1 -0
  83. package/dist/middleware/error-handler.d.ts +15 -0
  84. package/dist/middleware/error-handler.d.ts.map +1 -0
  85. package/dist/middleware/error-handler.js +29 -0
  86. package/dist/middleware/error-handler.js.map +1 -0
  87. package/dist/middleware/logger.d.ts +14 -0
  88. package/dist/middleware/logger.d.ts.map +1 -0
  89. package/dist/middleware/logger.js +25 -0
  90. package/dist/middleware/logger.js.map +1 -0
  91. package/dist/middleware.d.ts +75 -0
  92. package/dist/middleware.d.ts.map +1 -0
  93. package/dist/middleware.js +89 -0
  94. package/dist/middleware.js.map +1 -0
  95. package/dist/operation.d.ts +87 -0
  96. package/dist/operation.d.ts.map +1 -0
  97. package/dist/operation.js +95 -0
  98. package/dist/operation.js.map +1 -0
  99. package/dist/orm.d.ts +96 -0
  100. package/dist/orm.d.ts.map +1 -0
  101. package/dist/orm.js +33 -0
  102. package/dist/orm.js.map +1 -0
  103. package/dist/presenter.d.ts +63 -0
  104. package/dist/presenter.d.ts.map +1 -0
  105. package/dist/presenter.js +72 -0
  106. package/dist/presenter.js.map +1 -0
  107. package/dist/remote.d.ts +48 -0
  108. package/dist/remote.d.ts.map +1 -0
  109. package/dist/remote.js +135 -0
  110. package/dist/remote.js.map +1 -0
  111. package/dist/repository.d.ts +55 -0
  112. package/dist/repository.d.ts.map +1 -0
  113. package/dist/repository.js +26 -0
  114. package/dist/repository.js.map +1 -0
  115. package/dist/scan-cache.d.ts +10 -0
  116. package/dist/scan-cache.d.ts.map +1 -0
  117. package/dist/scan-cache.js +92 -0
  118. package/dist/scan-cache.js.map +1 -0
  119. package/dist/scanner.d.ts +34 -0
  120. package/dist/scanner.d.ts.map +1 -0
  121. package/dist/scanner.js +595 -0
  122. package/dist/scanner.js.map +1 -0
  123. package/dist/seed.d.ts +28 -0
  124. package/dist/seed.d.ts.map +1 -0
  125. package/dist/seed.js +110 -0
  126. package/dist/seed.js.map +1 -0
  127. package/dist/types.d.ts +387 -0
  128. package/dist/types.d.ts.map +1 -0
  129. package/dist/types.js +2 -0
  130. package/dist/types.js.map +1 -0
  131. package/dist/verify.d.ts +57 -0
  132. package/dist/verify.d.ts.map +1 -0
  133. package/dist/verify.js +147 -0
  134. package/dist/verify.js.map +1 -0
  135. package/package.json +47 -0
@@ -0,0 +1,595 @@
1
+ import { readdir, readFile } from 'node:fs/promises';
2
+ import { existsSync } from 'node:fs';
3
+ import { join, dirname, basename, resolve as resolvePath } from 'node:path';
4
+ import { pathToFileURL } from 'node:url';
5
+ import { ANONYMOUS_SCHEMA_NAME } from '@fougere/schema';
6
+ import { cardinalityOf } from './operation.js';
7
+ import { parseAllHandlerMethods, parsePresenterMethods, parseConstructorParams } from './handler-parser.js';
8
+ import { hashFile, getCached, setCached, flushCache, setCacheRoot } from './scan-cache.js';
9
+ import { loadFrondConfig } from './frond-config.js';
10
+ import { emitKeyOf } from './emit.js';
11
+ import { getPresenterTarget, getPresenterFields, getPresenterViews } from './presenter.js';
12
+ import { getRepositoryTarget } from './repository.js';
13
+ import { ormKeyOf } from './orm.js';
14
+ import { getCollectorTarget } from './collector.js';
15
+ const defaultLoader = async (filePath) => await import(pathToFileURL(filePath).href);
16
+ let activeLoader = defaultLoader;
17
+ /** Override the module loader used by the scanner (e.g. for jiti/tsx support). */
18
+ export function setModuleLoader(loader) {
19
+ activeLoader = loader;
20
+ }
21
+ /** Used by config-loader to load fougere.config.ts via the same TS-aware loader. */
22
+ export function getModuleLoader() {
23
+ return activeLoader;
24
+ }
25
+ // FS
26
+ /**
27
+ * What this scan run could not do. Reset by {@link scanProject}, which owns a run.
28
+ *
29
+ * Module-scoped like the loader and the cache root above: the scanner already has
30
+ * a notion of "the current run", and threading a collector through twenty call
31
+ * sites would state the same thing more loudly and less clearly.
32
+ */
33
+ let diagnostics = [];
34
+ function record(d) {
35
+ diagnostics.push(d);
36
+ }
37
+ /**
38
+ * An absent convention directory is the ordinary case — a frond without
39
+ * `presenters/` is not a defect. Anything else (permissions, an I/O error, a path
40
+ * that is not a directory) means the scan did not look, and answering `[]` says
41
+ * it did. One `catch` used to conflate the two.
42
+ */
43
+ async function readEntries(path) {
44
+ try {
45
+ return await readdir(path, { withFileTypes: true });
46
+ }
47
+ catch (cause) {
48
+ if (cause?.code === 'ENOENT')
49
+ return [];
50
+ record({
51
+ severity: 'blocking',
52
+ code: 'directory-unreadable',
53
+ filePath: path,
54
+ // The path is NOT repeated here: `filePath` carries it, and a renderer that
55
+ // prints both wraps an absolute path twice into an unreadable box.
56
+ message: 'Could not read this directory — anything it declares is missing from '
57
+ + 'the app, and nothing downstream can tell that from an empty directory.',
58
+ cause,
59
+ });
60
+ return [];
61
+ }
62
+ }
63
+ async function dirs(path) {
64
+ const entries = await readEntries(path);
65
+ return entries.filter((e) => e.isDirectory()).map((e) => e.name);
66
+ }
67
+ async function files(path) {
68
+ const entries = await readEntries(path);
69
+ return entries
70
+ .filter((e) => e.isFile() && (e.name.endsWith('.ts') || e.name.endsWith('.js')))
71
+ .map((e) => join(path, e.name));
72
+ }
73
+ // Module
74
+ async function loadModule(filePath) {
75
+ return await activeLoader(filePath);
76
+ }
77
+ async function loadDefault(filePath) {
78
+ const mod = await loadModule(filePath);
79
+ return mod.default;
80
+ }
81
+ async function loadClass(filePath) {
82
+ const ctor = await loadDefault(filePath);
83
+ if (typeof ctor !== 'function' || !ctor.prototype)
84
+ throw new Error(`${filePath}: default export is not a class`);
85
+ return ctor;
86
+ }
87
+ function isEntityClass(value) {
88
+ return typeof value === 'function' && 'getFields' in value;
89
+ }
90
+ // Workspace
91
+ /** Walk up from project root to find the monorepo root (pnpm-workspace.yaml + packages/). */
92
+ function findWorkspaceRoot(from) {
93
+ let dir = resolvePath(from);
94
+ while (dir !== dirname(dir)) {
95
+ if (existsSync(join(dir, 'pnpm-workspace.yaml')) && existsSync(join(dir, 'packages')))
96
+ return dir;
97
+ dir = dirname(dir);
98
+ }
99
+ return resolvePath(from); // fallback: use project root itself
100
+ }
101
+ // Convention
102
+ /** Directories whose classes register as providers — two spellings, one behaviour. */
103
+ const PROVIDER_DIRS = ['services', 'repositories'];
104
+ /**
105
+ * The frond vocabulary — every directory {@link scanFrond} reads. A frond directory says
106
+ * nothing else, which is why this list is what a reader needs to bound one: the Nuxt
107
+ * module watches these for the root frond (watching the root itself would match every
108
+ * write), and a flat app's tsconfig lists them instead of `["."]`, which would swallow
109
+ * `app/` and `nuxt.config.ts`.
110
+ */
111
+ export const FROND_DIRS = [
112
+ 'entities', 'handlers', 'presenters', 'collectors', 'seeds', ...PROVIDER_DIRS,
113
+ ];
114
+ export { toRegistrationName } from './contract.js';
115
+ import { toRegistrationName } from './contract.js';
116
+ /**
117
+ * Strip the 'Handler' suffix → the name the handler answers to. 'PostHandler' → 'post'.
118
+ *
119
+ * Nothing here checks that an entity carries the result, and nothing should: a handler
120
+ * about no stored row is ordinary. The old name of this function — `toEntityName` — is
121
+ * what let "one façade per entity" be repeated until it read as a rule.
122
+ */
123
+ function toAddress(className) {
124
+ const base = className.endsWith('Handler') ? className.slice(0, -7) : className;
125
+ return base[0].toLowerCase() + base.slice(1);
126
+ }
127
+ // Scan
128
+ /**
129
+ * The container key a constructor parameter asks for — derived from its TYPE, not from
130
+ * how the type was spelled.
131
+ *
132
+ * `deps` used to be `p.type.name`, so the key WAS the alias's name: `type ListOrm =
133
+ * EntityOrm<List>` resolved only because someone had spelled it exactly like the
134
+ * registration key (`ListOrm`), while `type ListRepo = EntityOrm<List>` — the same type —
135
+ * typechecked and died at boot on `'ListRepo' is not registered`. And `EntityOrm<List>`
136
+ * written out in full asked for `'EntityOrm'`, which nothing registers.
137
+ *
138
+ * `EntityOrm<X>` names X's storage, so that is the key. The generic argument was already
139
+ * parsed (`ParsedType.generics`) and thrown away. Anything else keeps its own name: a
140
+ * plain service IS designated by its class name.
141
+ */
142
+ function depKeyOf(type) {
143
+ // `Facade<PostHandler>` — the second port, read exactly like the first. The type names
144
+ // what arrives: not the handler (its methods take positional arguments and it is never
145
+ // injected), but the door built in front of it. Same key whether that door is the local
146
+ // façade or a doublure, which is what makes the topology invisible from a signature.
147
+ const facadeOf = type.name === 'Facade' ? type.generics?.[0]?.name : undefined;
148
+ if (facadeOf)
149
+ return toRegistrationName(facadeOf);
150
+ // `Emit<PostPublished>` — the third port, and the only one that names a SUBJECT rather
151
+ // than an interlocutor. Read like the other two: the type names what arrives, here a
152
+ // function that announces. Who receives it is not in the signature and never will be.
153
+ const factOf = type.name === 'Emit' ? type.generics?.[0]?.name : undefined;
154
+ if (factOf)
155
+ return emitKeyOf(factOf);
156
+ const target = type.name === 'EntityOrm' ? type.generics?.[0]?.name : undefined;
157
+ if (!target)
158
+ return type.name;
159
+ return ormKeyOf(target);
160
+ }
161
+ /** Cached parseConstructorParams — skips TS loading when cache is warm. */
162
+ async function cachedCtorParams(filePath) {
163
+ const hash = hashFile(filePath);
164
+ const key = filePath + ':ctor';
165
+ const cached = getCached(key, hash);
166
+ if (cached)
167
+ return cached;
168
+ const params = await parseConstructorParams(filePath);
169
+ setCached(key, hash, params);
170
+ return params;
171
+ }
172
+ /** Cached parsePresenterMethods — skips TS loading when cache is warm. */
173
+ async function cachedPresenterMethods(filePath) {
174
+ const hash = hashFile(filePath);
175
+ const key = filePath + ':presenter';
176
+ const cached = getCached(key, hash);
177
+ if (cached)
178
+ return cached;
179
+ const methods = await parsePresenterMethods(filePath);
180
+ setCached(key, hash, methods);
181
+ return methods;
182
+ }
183
+ async function toProvider(filePath) {
184
+ const ctor = await loadClass(filePath);
185
+ const params = await cachedCtorParams(filePath);
186
+ const deps = params.map((p) => depKeyOf(p.type));
187
+ // A repository inherits its constructor from `Repository(Entity)`, so the file
188
+ // declares none and the scan reads no parameter. The mixin knows which entity it
189
+ // was built for and says so at runtime — same escape as `Crud.__ops`, and the same
190
+ // reason: what a prefab fabricates, only the prefab can describe.
191
+ const target = getRepositoryTarget(ctor);
192
+ if (target && deps.length === 0) {
193
+ deps.push(`${toRegistrationName(target.name).replace(/^./, (c) => c.toUpperCase())}Orm`);
194
+ }
195
+ return { name: toRegistrationName(ctor.name), ctor, deps, filePath };
196
+ }
197
+ async function toEntityEntry(filePath) {
198
+ const exported = await loadDefault(filePath);
199
+ if (!isEntityClass(exported))
200
+ return null;
201
+ const runtimeName = exported.name;
202
+ // A derivation returned directly (`export default User.extend(...)`) carries the
203
+ // factory's own name, which the schema package stamps and exports. The file is then
204
+ // the declaration site and therefore the only name the author actually supplied;
205
+ // named classes keep winning.
206
+ const declaredName = runtimeName && runtimeName !== ANONYMOUS_SCHEMA_NAME
207
+ ? runtimeName
208
+ : basename(filePath).replace(/\.[^.]+$/, '');
209
+ const name = toRegistrationName(declaredName);
210
+ return { name, entityClass: exported, filePath };
211
+ }
212
+ /**
213
+ * Resolve a ParsedType to a runtime schema if available in module exports.
214
+ * Handles arrays, generics (uses base name), and simple references.
215
+ */
216
+ function resolveSchema(type, moduleExports) {
217
+ // For arrays, resolve the element type
218
+ const name = type.array ? type.name : type.name;
219
+ // For generics like Pagination<Post>, also check inner types
220
+ if (type.generics) {
221
+ for (const g of type.generics) {
222
+ const resolved = moduleExports[g.name];
223
+ if (resolved && typeof resolved === 'function' && 'getFields' in resolved) {
224
+ // `Partial<X>` in a signature IS the patch declaration (Crud.update) —
225
+ // project it onto the schema view instead of dropping the wrapper, so
226
+ // the facade validates in patch mode (absent field → untouched).
227
+ if (type.name === 'Partial' && 'partial' in resolved && typeof resolved.partial === 'function') {
228
+ return resolved.partial();
229
+ }
230
+ return resolved;
231
+ }
232
+ }
233
+ }
234
+ const resolved = moduleExports[name];
235
+ if (resolved && typeof resolved === 'function' && 'getFields' in resolved) {
236
+ return resolved;
237
+ }
238
+ return undefined;
239
+ }
240
+ /**
241
+ * Parse ALL method signatures for unified binding.
242
+ *
243
+ * Resolves schemas for all params (not just the first) and stores
244
+ * full signatures for the binding algorithm.
245
+ */
246
+ async function inferOperations(filePath, moduleExports, projectRoot) {
247
+ const map = new Map();
248
+ let parsed;
249
+ try {
250
+ const hash = hashFile(filePath);
251
+ const cacheKey = filePath + ':all' + (projectRoot ? ':inherited' : '');
252
+ const cached = getCached(cacheKey, hash);
253
+ if (cached) {
254
+ parsed = cached;
255
+ }
256
+ else {
257
+ parsed = await parseAllHandlerMethods(filePath, projectRoot);
258
+ setCached(cacheKey, hash, parsed);
259
+ }
260
+ }
261
+ catch (cause) {
262
+ // The handler still gets a façade — its methods exist at runtime — but with no
263
+ // contract: no binding plan, no input schema, no doc sentence. It used to
264
+ // return the empty map, so the app served a stranger's idea of the handler and
265
+ // said nothing. The operations are gone; the sentence saying so is not.
266
+ record({
267
+ severity: 'blocking',
268
+ code: 'handler-parse-failed',
269
+ filePath,
270
+ message: 'Could not parse this handler — its operations carry no contract, so the '
271
+ + 'façade serves them unbound. Not the same as a handler with no operation.',
272
+ cause,
273
+ });
274
+ return map;
275
+ }
276
+ /**
277
+ * A base class the parse could not open — an installed package, typically, whose
278
+ * source is not in the workspace. Its operations are missing from this façade, and
279
+ * the scan cannot tell whether there were any.
280
+ *
281
+ * A warning, not a refusal: an installed base class with no operation is perfectly
282
+ * ordinary, and the boot has no way to decide between the two. So it names the
283
+ * clause and stops there. Stating the contract in `frond.config.ts` is the answer
284
+ * — the third producer, which creates an op neither other producer found — and it
285
+ * silences this by making the op exist.
286
+ */
287
+ for (const base of parsed.unresolvedHeritage) {
288
+ record({
289
+ severity: 'warning',
290
+ code: 'heritage-unresolved',
291
+ filePath,
292
+ message: `Could not resolve 'extends ${base}' — any operation it declares is absent `
293
+ + `from this façade, and the scan cannot tell that from a base class with none. `
294
+ + `State the contract in frond.config.ts to put it back.`,
295
+ });
296
+ }
297
+ for (const method of parsed.methods) {
298
+ // The contract is what carries the description; `signature` is the raw material it
299
+ // was read from. Leaving it only on the signature meant every consumer had to know
300
+ // to look one level down, and only the façade did.
301
+ const meta = {
302
+ signature: method,
303
+ ...(method.description && { description: method.description }),
304
+ };
305
+ // Resolve schemas for all params
306
+ for (const param of method.params) {
307
+ const schema = resolveSchema(param.type, moduleExports);
308
+ if (schema && !meta.input)
309
+ meta.input = schema;
310
+ }
311
+ if (method.returnType) {
312
+ meta.output = resolveSchema(method.returnType, moduleExports);
313
+ // `output` is the shape of one row; this says how many rows come back.
314
+ meta.cardinality = cardinalityOf(method.returnType);
315
+ }
316
+ map.set(method.name, meta);
317
+ }
318
+ return map;
319
+ }
320
+ async function toHandlerEntry(filePath, entityByClassName, projectRoot, surface) {
321
+ const mod = await loadModule(filePath);
322
+ const ctor = mod.default;
323
+ if (typeof ctor !== 'function' || !ctor.prototype)
324
+ throw new Error(`${filePath}: default export is not a class`);
325
+ // Augment module exports with known entity classes so resolveSchema
326
+ // can find them when T is substituted (e.g. T → Post after parsing Crud(Post))
327
+ const augmented = { ...mod };
328
+ for (const [className, entityClass] of entityByClassName) {
329
+ if (!(className in augmented))
330
+ augmented[className] = entityClass;
331
+ }
332
+ const address = toAddress(ctor.name);
333
+ const operations = await inferOperations(filePath, augmented, projectRoot);
334
+ const ctorParams = await cachedCtorParams(filePath);
335
+ const deps = ctorParams.map((p) => depKeyOf(p.type));
336
+ // Read output override from Crud(Entity, Output) — static __output property
337
+ const __entity = ctor.__entity;
338
+ const __output = ctor.__output;
339
+ const outputOverride = __output && __entity && __output !== __entity ? __output : undefined;
340
+ return {
341
+ name: toRegistrationName(ctor.name),
342
+ address,
343
+ ctor: ctor,
344
+ operations,
345
+ deps,
346
+ filePath,
347
+ outputOverride,
348
+ surface,
349
+ };
350
+ }
351
+ /** Strip '.seed' suffix → entity name. 'Author.seed.ts' → 'author'. */
352
+ function toSeedEntityName(fileName) {
353
+ const base = fileName.replace(/\.seed\.(ts|js)$/, '').replace(/\.(ts|js)$/, '');
354
+ return base[0].toLowerCase() + base.slice(1);
355
+ }
356
+ async function toSeedEntry(filePath) {
357
+ const data = await loadDefault(filePath);
358
+ if (Array.isArray(data) || typeof data === 'function') {
359
+ const fileName = filePath.split('/').pop();
360
+ return { entityName: toSeedEntityName(fileName), data: data, filePath };
361
+ }
362
+ return null;
363
+ }
364
+ async function toPresenterEntry(filePath) {
365
+ const ctor = await loadClass(filePath);
366
+ const target = getPresenterTarget(ctor);
367
+ if (!target)
368
+ return null;
369
+ const entityName = toRegistrationName(target.name);
370
+ const fields = getPresenterFields(ctor);
371
+ const presenterParams = await cachedCtorParams(filePath);
372
+ const deps = presenterParams.map((p) => depKeyOf(p.type));
373
+ // Parse method return types from source
374
+ let fieldMeta = [];
375
+ try {
376
+ const parsed = await cachedPresenterMethods(filePath);
377
+ fieldMeta = parsed.map((m) => ({
378
+ name: m.name,
379
+ returnType: m.returnType?.name,
380
+ // One array level IS the page — the method answers one value per row. What is left
381
+ // over is the field's own arity: `string[]` a scalar per row, `string[][]` a list.
382
+ list: (m.returnType?.arrayDepth ?? 0) > 1,
383
+ nullable: m.returnType?.nullable,
384
+ // Everything after the rows is bound like a handler's argument.
385
+ params: m.params.slice(1),
386
+ }));
387
+ }
388
+ catch { /* parse failure — fall back to untyped */ }
389
+ // Declared at runtime on the class, so it survives a scan that resolved nothing.
390
+ return { entityName, ctor, fields, fieldMeta, views: getPresenterViews(ctor), deps, filePath };
391
+ }
392
+ async function toCollectorEntry(filePath) {
393
+ const ctor = await loadClass(filePath);
394
+ const target = getCollectorTarget(ctor);
395
+ if (!target)
396
+ return null;
397
+ const entityName = toRegistrationName(target.name);
398
+ const collectorParams = await cachedCtorParams(filePath);
399
+ const deps = collectorParams.map((p) => depKeyOf(p.type));
400
+ return { entityName, ctor, deps, filePath };
401
+ }
402
+ async function scanFrond(frondPath, name, source, projectRoot) {
403
+ const providers = [];
404
+ const entities = [];
405
+ const handlers = [];
406
+ const presenters = [];
407
+ const collectors = [];
408
+ const seeds = [];
409
+ // Scan services/ and repositories/ — both land in the same provider list.
410
+ for (const dir of PROVIDER_DIRS) {
411
+ const paths = await files(join(frondPath, dir));
412
+ providers.push(...await Promise.all(paths.map((f) => toProvider(f))));
413
+ }
414
+ // Scan entities/
415
+ const entityPaths = await files(join(frondPath, 'entities'));
416
+ const entityEntries = await Promise.all(entityPaths.map((f) => toEntityEntry(f)));
417
+ entities.push(...entityEntries.filter((e) => e !== null));
418
+ // Build entity class map for schema resolution in handlers (T → entity class)
419
+ const entityByClassName = new Map(entities.map((e) => [e.entityClass.name, e.entityClass]));
420
+ // Scan handlers/ (root = default surface, subdirectories = named surfaces)
421
+ const handlerPaths = await files(join(frondPath, 'handlers'));
422
+ handlers.push(...await Promise.all(handlerPaths.map((f) => toHandlerEntry(f, entityByClassName, projectRoot))));
423
+ const surfaceDirs = await dirs(join(frondPath, 'handlers'));
424
+ for (const surfaceName of surfaceDirs) {
425
+ const surfacePaths = await files(join(frondPath, 'handlers', surfaceName));
426
+ handlers.push(...await Promise.all(surfacePaths.map((f) => toHandlerEntry(f, entityByClassName, projectRoot, surfaceName))));
427
+ }
428
+ // Scan presenters/
429
+ const presenterPaths = await files(join(frondPath, 'presenters'));
430
+ const presenterEntries = await Promise.all(presenterPaths.map((f) => toPresenterEntry(f)));
431
+ presenters.push(...presenterEntries.filter((p) => p !== null));
432
+ // Scan collectors/
433
+ const collectorPaths = await files(join(frondPath, 'collectors'));
434
+ const collectorEntries = await Promise.all(collectorPaths.map((f) => toCollectorEntry(f)));
435
+ collectors.push(...collectorEntries.filter((c) => c !== null));
436
+ // Scan seeds/
437
+ const seedPaths = await files(join(frondPath, 'seeds'));
438
+ const seedEntries = await Promise.all(seedPaths.map((f) => toSeedEntry(f)));
439
+ seeds.push(...seedEntries.filter((s) => s !== null));
440
+ // Mark exposed entries: frond.config.ts takes precedence, then @expose decorator
441
+ const frondConfig = await loadFrondConfig(frondPath);
442
+ if (frondConfig?.expose) {
443
+ const exposeSet = new Set(frondConfig.expose);
444
+ for (const e of entities) {
445
+ e.exposed = exposeSet.has(e.entityClass.name);
446
+ }
447
+ for (const h of handlers) {
448
+ h.exposed = exposeSet.has(h.ctor.name);
449
+ }
450
+ }
451
+ else {
452
+ // Fallback: check @expose decorator, default to true (expose everything unless explicitly hidden)
453
+ for (const e of entities) {
454
+ e.exposed = e.entityClass.__exposed !== false;
455
+ }
456
+ for (const h of handlers) {
457
+ h.exposed = h.ctor.__exposed !== false;
458
+ }
459
+ }
460
+ // Flatten per-op config overrides: the only thing that needs flattening is the handler
461
+ // CLASS, which becomes its name (that is the DI key). Everything else — the surface keys
462
+ // AND the contract keys (`input`, `binding`) — travels verbatim, so a slot added to
463
+ // OperationOverride reaches its reader without a stop here. Enumerating keys by hand is
464
+ // what used to silently drop whatever was added last (the same invariant `cloneField`
465
+ // holds one layer down).
466
+ const operationsOverrides = frondConfig?.operations
467
+ ? Object.fromEntries(Object.entries(frondConfig.operations).map(([opName, { handler, ...rest }]) => [
468
+ opName,
469
+ { ...rest, handlerName: handler?.name },
470
+ ]))
471
+ : undefined;
472
+ return {
473
+ name,
474
+ source,
475
+ providers,
476
+ entities,
477
+ handlers,
478
+ presenters,
479
+ collectors,
480
+ seeds,
481
+ surfaces: frondConfig?.surfaces,
482
+ operationsOverrides,
483
+ };
484
+ }
485
+ /**
486
+ * The frond's name — the directory, unless its `package.json` renames it. One rule for a
487
+ * frond under `fronds/` and for the root frond alike, so the root needs no second spelling.
488
+ *
489
+ * Carrying the convention is what makes a frond; the key never marked anything and
490
+ * nothing read it. It earns its keep as the one thing the directory cannot say: that
491
+ * `fronds/blog-v2/` serves the frond still called `blog` — so a rename on disk does not
492
+ * rename the entity keys, the `@frond/*` import or a `remotes:` entry.
493
+ */
494
+ async function frondNameOf(frondPath, dirName) {
495
+ try {
496
+ const pkg = JSON.parse(await readFile(join(frondPath, 'package.json'), 'utf8'));
497
+ const declared = pkg.fougere?.frond;
498
+ return typeof declared === 'string' && declared.length > 0 ? declared : dirName;
499
+ }
500
+ catch {
501
+ return dirName;
502
+ }
503
+ }
504
+ /**
505
+ * A frond is a directory carrying the convention, and the project root is one such
506
+ * directory — so a single-domain app writes `entities/` next to `app/` and never names
507
+ * anything. `fronds/` is not the definition, it is where the OTHERS live: the root frond
508
+ * stays put when a second domain appears, which is what makes flattening free instead of
509
+ * a deferred move.
510
+ *
511
+ * `entities/` is the test, not "any convention directory". `services/` and `repositories/`
512
+ * are ordinary top-level names in projects that never heard of Fougere, and a domain
513
+ * without a single entity is not a domain.
514
+ */
515
+ async function rootFrondOf(root, workspaceRoot) {
516
+ if ((await files(join(root, 'entities'))).length === 0)
517
+ return null;
518
+ const name = await frondNameOf(root, basename(resolvePath(root)));
519
+ return scanFrond(root, name, { path: root, package: `@frond/${name}` }, workspaceRoot);
520
+ }
521
+ /**
522
+ * `@frond/<name>` → the directory it names, for every frond of a project.
523
+ *
524
+ * The framework states this convention — `FrondSource.package` has always spelled it, and
525
+ * `fougere sync` writes it into a consumer's tsconfig — and until now its own reader could
526
+ * not resolve it. The Nuxt module registered a Vite alias, so a `.vue` page could import
527
+ * `@frond/blog/entities/Post`, while the SCAN loaded sources through a bare jiti: a frond
528
+ * naming its neighbour got `Cannot find module '@frond/user/entities/User.js'`. So the one
529
+ * form that survives a split was the one form that did not run.
530
+ *
531
+ * Hand it to the module loader — `createJiti(url, { alias: await frondAliases(root) })` —
532
+ * and the named form resolves everywhere the framework reads. A directory listing and a
533
+ * `package.json` read, no parsing: it is deliberately callable BEFORE the loader exists,
534
+ * which is what makes the chicken-and-egg go away.
535
+ */
536
+ export async function frondAliases(root) {
537
+ const frondsDir = join(root, 'fronds');
538
+ const aliases = {};
539
+ // The root itself is a frond when it carries `entities/` — same rule as the scan.
540
+ if ((await files(join(root, 'entities'))).length > 0) {
541
+ aliases[`@frond/${await frondNameOf(root, basename(resolvePath(root)))}`] = resolvePath(root);
542
+ }
543
+ for (const dir of await dirs(frondsDir)) {
544
+ const path = join(frondsDir, dir);
545
+ aliases[`@frond/${await frondNameOf(path, dir)}`] = resolvePath(path);
546
+ }
547
+ /**
548
+ * A SYNCED frond answers to the same name.
549
+ *
550
+ * `fougere sync` writes `.fougere/remotes/<name>/` and registers it in `remotes.json`,
551
+ * which the Nuxt module already reads to alias `@frond/<name>`. Doing it here too is
552
+ * what makes the convention mean ONE thing: a consumer writes `@frond/blog/entities/Post`
553
+ * and never learns whether that frond is on this disk or was fetched from a card.
554
+ *
555
+ * A local frond wins a name collision — its source is the truth, a synced copy is a
556
+ * mirror of somebody else's.
557
+ */
558
+ try {
559
+ const registry = JSON.parse(await readFile(join(root, '.fougere', 'remotes.json'), 'utf8'));
560
+ for (const [name, entry] of Object.entries(registry)) {
561
+ if (typeof entry?.path !== 'string' || aliases[`@frond/${name}`])
562
+ continue;
563
+ aliases[`@frond/${name}`] = resolvePath(entry.path);
564
+ }
565
+ }
566
+ catch {
567
+ // No registry, or an unreadable one: nothing was synced here. Not this function's
568
+ // complaint — `sync` owns that file and reports on it.
569
+ }
570
+ return aliases;
571
+ }
572
+ export async function scanProject(root, filter) {
573
+ setCacheRoot(root);
574
+ // A run owns its findings: two scans in one process (a test suite, a watcher)
575
+ // must not inherit each other's.
576
+ diagnostics = [];
577
+ const frondsDir = join(root, 'fronds');
578
+ const dirNames = await dirs(frondsDir);
579
+ // Resolve workspace root (parent of packages/) for package import resolution
580
+ // For monorepo: root is the project dir (e.g. demos/nuxt-blog), workspace root is the repo root
581
+ const workspaceRoot = findWorkspaceRoot(root);
582
+ const [rootFrond, under] = await Promise.all([
583
+ rootFrondOf(root, workspaceRoot),
584
+ Promise.all(dirNames.map(async (dir) => {
585
+ const name = await frondNameOf(join(frondsDir, dir), dir);
586
+ return scanFrond(join(frondsDir, dir), name, { path: join(frondsDir, dir), package: `@frond/${name}` }, workspaceRoot);
587
+ })),
588
+ ]);
589
+ // The app's own domain first, then the ones it took in.
590
+ const all = rootFrond ? [rootFrond, ...under] : under;
591
+ const fronds = filter ? all.filter((f) => filter.includes(f.name)) : all;
592
+ flushCache();
593
+ return { fronds, diagnostics };
594
+ }
595
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
package/dist/seed.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ import type { App, FrondDescriptor, SeedEntry } from './types.js';
2
+ /**
3
+ * Seeds in dependency order — a `ref()` target is planted before its referrer.
4
+ *
5
+ * The order is a fact about the entity graph, not about the surface running the seeds,
6
+ * so it is stated once here. The Nuxt module read it off a pairwise comparator (which
7
+ * `Array.sort` cannot make transitive: `a` before `b` and `b` before `c` never implies
8
+ * `a` before `c`), and `boot()` had no order at all — the same fact, told twice and
9
+ * wrong both times. A list seeded before its owner failed on the foreign key, and the
10
+ * driver's error named neither the entity nor the file.
11
+ *
12
+ * Kahn, like `orderTables` in `@fougere/schema-sql` — the same shape one level up: there
13
+ * the nodes are tables and the edges FK columns, here they are seeds and the edges the
14
+ * `one` relations of the entities they target. A cycle cannot be satisfied by ordering,
15
+ * so its remaining seeds keep their scan order and land last: the driver refuses what is
16
+ * genuinely impossible, and everything acyclic around it still gets planted.
17
+ */
18
+ export declare function orderSeeds(fronds: FrondDescriptor[]): SeedEntry[];
19
+ /**
20
+ * Plant a set of seeds, in the order given. Reports what it did, one line per entity.
21
+ *
22
+ * The one seeding loop. `boot()` had one and the Nuxt module generated a second into its
23
+ * Nitro plugin, which had drifted: no ORM fallback, so an entity with no façade was
24
+ * skipped there and planted here. Two answers to "how does a row get in at boot" is one
25
+ * too many, and the second was the one running in the browser.
26
+ */
27
+ export declare function runSeeds(app: App, seeds: SeedEntry[], report?: (message: string) => void): Promise<void>;
28
+ //# sourceMappingURL=seed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../src/seed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,eAAe,EAAE,SAAS,EAAe,MAAM,YAAY,CAAC;AAE/E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,SAAS,EAAE,CAyCjE;AAQD;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,SAAS,EAAE,EAClB,MAAM,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAe,GAC3C,OAAO,CAAC,IAAI,CAAC,CA+Bf"}