@prisma-next/framework-components 0.12.0-dev.9 → 0.13.0-dev.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.
Files changed (63) hide show
  1. package/dist/authoring.d.mts +2 -2
  2. package/dist/authoring.mjs +2 -2
  3. package/dist/{codec-BFOsuHKK.d.mts → codec-DCQAerzB.d.mts} +1 -1
  4. package/dist/{codec-BFOsuHKK.d.mts.map → codec-DCQAerzB.d.mts.map} +1 -1
  5. package/dist/codec.d.mts +1 -1
  6. package/dist/codec.d.mts.map +1 -1
  7. package/dist/components.d.mts +1 -1
  8. package/dist/components.mjs +1 -1
  9. package/dist/components.mjs.map +1 -1
  10. package/dist/control.d.mts +85 -13
  11. package/dist/control.d.mts.map +1 -1
  12. package/dist/control.mjs +89 -7
  13. package/dist/control.mjs.map +1 -1
  14. package/dist/{emission-types-CMv_053d.d.mts → emission-types-vfpSTe63.d.mts} +2 -2
  15. package/dist/{emission-types-CMv_053d.d.mts.map → emission-types-vfpSTe63.d.mts.map} +1 -1
  16. package/dist/emission.d.mts +3 -3
  17. package/dist/execution.d.mts +1 -1
  18. package/dist/execution.d.mts.map +1 -1
  19. package/dist/execution.mjs +1 -1
  20. package/dist/{framework-authoring-DcEZ5Lin.mjs → framework-authoring-CnwPJCO4.mjs} +76 -5
  21. package/dist/framework-authoring-CnwPJCO4.mjs.map +1 -0
  22. package/dist/framework-authoring-R0TYCkvG.d.mts +380 -0
  23. package/dist/framework-authoring-R0TYCkvG.d.mts.map +1 -0
  24. package/dist/{framework-components-CuoUhyB5.d.mts → framework-components-DDQXmW0b.d.mts} +6 -5
  25. package/dist/{framework-components-CuoUhyB5.d.mts.map → framework-components-DDQXmW0b.d.mts.map} +1 -1
  26. package/dist/{framework-components-FdqmlGUj.mjs → framework-components-DbCS57go.mjs} +1 -1
  27. package/dist/{framework-components-FdqmlGUj.mjs.map → framework-components-DbCS57go.mjs.map} +1 -1
  28. package/dist/ir.d.mts +20 -18
  29. package/dist/ir.d.mts.map +1 -1
  30. package/dist/ir.mjs +17 -14
  31. package/dist/ir.mjs.map +1 -1
  32. package/dist/{psl-ast-BDXL7iCg.d.mts → psl-ast-Cn50B-UG.d.mts} +90 -18
  33. package/dist/psl-ast-Cn50B-UG.d.mts.map +1 -0
  34. package/dist/psl-ast.d.mts +37 -2
  35. package/dist/psl-ast.d.mts.map +1 -0
  36. package/dist/psl-ast.mjs +222 -4
  37. package/dist/psl-ast.mjs.map +1 -1
  38. package/dist/runtime.d.mts +1 -1
  39. package/dist/runtime.d.mts.map +1 -1
  40. package/dist/runtime.mjs.map +1 -1
  41. package/dist/{types-import-spec-BxI5cSQy.d.mts → types-import-spec-DRKzrJ20.d.mts} +1 -1
  42. package/dist/{types-import-spec-BxI5cSQy.d.mts.map → types-import-spec-DRKzrJ20.d.mts.map} +1 -1
  43. package/dist/utils.mjs.map +1 -1
  44. package/package.json +9 -9
  45. package/src/control/control-instances.ts +15 -5
  46. package/src/control/control-migration-types.ts +20 -2
  47. package/src/control/control-result-types.ts +4 -1
  48. package/src/control/control-stack.ts +123 -4
  49. package/src/control/psl-ast.ts +234 -34
  50. package/src/control/psl-extension-block-validator.ts +324 -0
  51. package/src/control/verifier-disposition.ts +62 -0
  52. package/src/exports/authoring.ts +16 -0
  53. package/src/exports/control.ts +7 -0
  54. package/src/exports/psl-ast.ts +2 -0
  55. package/src/ir/namespace.ts +15 -13
  56. package/src/ir/storage.ts +8 -7
  57. package/src/shared/framework-authoring.ts +215 -2
  58. package/src/shared/framework-components.ts +2 -0
  59. package/src/shared/psl-extension-block.ts +184 -0
  60. package/dist/framework-authoring-BPPe9C9D.d.mts +0 -183
  61. package/dist/framework-authoring-BPPe9C9D.d.mts.map +0 -1
  62. package/dist/framework-authoring-DcEZ5Lin.mjs.map +0 -1
  63. package/dist/psl-ast-BDXL7iCg.d.mts.map +0 -1
@@ -7,8 +7,10 @@ import {
7
7
  isColumnDefaultLiteralInputValue,
8
8
  isExecutionMutationDefaultValue,
9
9
  } from '@prisma-next/contract/types';
10
+ import { blindCast } from '@prisma-next/utils/casts';
10
11
  import { ifDefined } from '@prisma-next/utils/defined';
11
12
  import type { Type } from 'arktype';
13
+ import type { PslBlockParam } from './psl-extension-block';
12
14
 
13
15
  export type AuthoringArgRef = {
14
16
  readonly kind: 'arg';
@@ -157,10 +159,55 @@ export type AuthoringEntityTypeNamespace = {
157
159
  readonly [name: string]: AuthoringEntityTypeDescriptor | AuthoringEntityTypeNamespace;
158
160
  };
159
161
 
162
+ /**
163
+ * Declarative descriptor for an extension-contributed top-level PSL block.
164
+ *
165
+ * An extension registers one of these per keyword it contributes. The
166
+ * framework owns the generic parser, validator, and printer — no
167
+ * parsing or printing code runs from the extension.
168
+ *
169
+ * - `keyword` is the PSL top-level identifier this descriptor claims
170
+ * (`policy_select`, `role`, …).
171
+ * - `discriminator` is the routing key used by the printer dispatch and
172
+ * the `entityTypes` lowering factory lookup. Convention:
173
+ * `<target-or-family>-<kind>` (`postgres-policy-select`).
174
+ * - `name.required` declares whether the block must have a name token
175
+ * after the keyword. Currently always `true` — anonymous blocks are
176
+ * not part of the closed-grammar premise — but the field is explicit
177
+ * so the type can evolve without a breaking change.
178
+ * - `parameters` maps parameter names to their value-kind descriptors
179
+ * (`ref` / `value` / `option` / `list`). The generic parser and
180
+ * validator interpret these; the extension supplies no parser or
181
+ * printer function.
182
+ */
183
+ export interface AuthoringPslBlockDescriptor {
184
+ readonly kind: 'pslBlock';
185
+ readonly keyword: string;
186
+ readonly discriminator: string;
187
+ readonly name: { readonly required: boolean };
188
+ readonly parameters: Record<string, PslBlockParam>;
189
+ }
190
+
191
+ export type AuthoringPslBlockDescriptorNamespace = {
192
+ readonly [name: string]: AuthoringPslBlockDescriptor | AuthoringPslBlockDescriptorNamespace;
193
+ };
194
+
160
195
  export interface AuthoringContributions {
161
196
  readonly type?: AuthoringTypeNamespace;
162
197
  readonly field?: AuthoringFieldNamespace;
163
198
  readonly entityTypes?: AuthoringEntityTypeNamespace;
199
+ /**
200
+ * Registry of declarative block descriptors this contribution registers,
201
+ * keyed by arbitrary path segments. Each leaf is an
202
+ * {@link AuthoringPslBlockDescriptor} that claims a PSL top-level keyword.
203
+ * The framework owns the generic parser, validator, and printer; the
204
+ * contribution supplies only these declarative descriptors.
205
+ *
206
+ * Contrast with the parsed block nodes themselves, which live in a
207
+ * namespace's `entries` under their discriminator key; this field holds the
208
+ * registry of descriptors that teach the parser how to read those blocks.
209
+ */
210
+ readonly pslBlockDescriptors?: AuthoringPslBlockDescriptorNamespace;
164
211
  }
165
212
 
166
213
  export function isAuthoringArgRef(value: unknown): value is AuthoringArgRef {
@@ -228,6 +275,42 @@ export function isAuthoringEntityTypeDescriptor(
228
275
  return typeof factory === 'function' || template !== undefined;
229
276
  }
230
277
 
278
+ export function isAuthoringPslBlockDescriptor(
279
+ value: unknown,
280
+ ): value is AuthoringPslBlockDescriptor {
281
+ if (typeof value !== 'object' || value === null) {
282
+ return false;
283
+ }
284
+ const record = blindCast<
285
+ Record<string, unknown>,
286
+ 'type-guard probing an unknown candidate-descriptor object for known property names'
287
+ >(value);
288
+ if (record['kind'] !== 'pslBlock') {
289
+ return false;
290
+ }
291
+ const keyword = record['keyword'];
292
+ if (typeof keyword !== 'string' || keyword.length === 0) {
293
+ return false;
294
+ }
295
+ const discriminator = record['discriminator'];
296
+ if (typeof discriminator !== 'string' || discriminator.length === 0) {
297
+ return false;
298
+ }
299
+ const name = record['name'];
300
+ if (typeof name !== 'object' || name === null) {
301
+ return false;
302
+ }
303
+ const nameRecord = blindCast<
304
+ Record<string, unknown>,
305
+ 'type-guard probing the name property of a candidate pslBlock descriptor'
306
+ >(name);
307
+ if (typeof nameRecord['required'] !== 'boolean') {
308
+ return false;
309
+ }
310
+ const parameters = record['parameters'];
311
+ return typeof parameters === 'object' && parameters !== null && !Array.isArray(parameters);
312
+ }
313
+
231
314
  /**
232
315
  * Returns true when `namespace` is a non-leaf key in `contributions.field`.
233
316
  *
@@ -341,10 +424,127 @@ function collectAuthoringLeafPaths(
341
424
  return paths;
342
425
  }
343
426
 
427
+ interface AuthoringLeafEntry {
428
+ readonly path: string;
429
+ readonly discriminator: string;
430
+ }
431
+
432
+ function collectAuthoringLeafDiscriminators(
433
+ namespace: Readonly<Record<string, unknown>>,
434
+ isLeaf: (value: unknown) => boolean,
435
+ label: string,
436
+ path: readonly string[] = [],
437
+ ): AuthoringLeafEntry[] {
438
+ const entries: AuthoringLeafEntry[] = [];
439
+ for (const [key, value] of Object.entries(namespace)) {
440
+ const currentPath = [...path, key];
441
+ if (isLeaf(value)) {
442
+ const record = blindCast<
443
+ Record<string, unknown>,
444
+ 'discriminator extraction from a leaf already validated by isLeaf'
445
+ >(value);
446
+ const discriminator = record['discriminator'];
447
+ if (typeof discriminator === 'string' && discriminator.length > 0) {
448
+ entries.push({ path: currentPath.join('.'), discriminator });
449
+ }
450
+ continue;
451
+ }
452
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
453
+ const record = blindCast<
454
+ Readonly<Record<string, unknown>>,
455
+ 'walker inspects a non-leaf value for descriptor-shaped keys before recursing'
456
+ >(value);
457
+ // A value carrying descriptor-shaped keys (`kind`/`keyword`/`discriminator`)
458
+ // but failing `isAuthoringPslBlockDescriptor` (e.g. missing `parameters`) is
459
+ // a malformed declarative descriptor. Descending into it as a sub-namespace
460
+ // would silently skip it, so a half-built contribution would pass validation.
461
+ // Reject it at load time instead, naming the path and what's wrong.
462
+ //
463
+ // A valid sub-namespace whose key happens to be named `kind`, `keyword`, or
464
+ // `discriminator` (but which does not look like a descriptor overall) must
465
+ // still descend normally — the check requires descriptor-shaped keys present
466
+ // AND the leaf guard rejecting it.
467
+ if (
468
+ (record['kind'] !== undefined ||
469
+ record['keyword'] !== undefined ||
470
+ record['discriminator'] !== undefined) &&
471
+ !isLeaf(value)
472
+ ) {
473
+ const hasKind = record['kind'] === 'pslBlock';
474
+ const hasKeyword = typeof record['keyword'] === 'string';
475
+ const hasDiscriminator = typeof record['discriminator'] === 'string';
476
+ if (hasKind || (hasKeyword && hasDiscriminator)) {
477
+ throw new Error(
478
+ `Malformed authoring ${label} contribution at "${currentPath.join('.')}". The value carries descriptor keys (kind/keyword/discriminator) but does not satisfy the ${label} descriptor shape. Fix the contribution so it is a complete descriptor, or remove the stray keys if it was meant to be a sub-namespace.`,
479
+ );
480
+ }
481
+ }
482
+ entries.push(...collectAuthoringLeafDiscriminators(record, isLeaf, label, currentPath));
483
+ }
484
+ }
485
+ return entries;
486
+ }
487
+
488
+ /**
489
+ * Throws when two or more entries in the same namespace share a discriminator.
490
+ * Duplicate discriminators within a namespace make dispatch ambiguous — the
491
+ * lowering factory lookup dispatches by discriminator, so one would silently
492
+ * shadow the other. Catch duplicates before building any dispatch map.
493
+ */
494
+ function assertUniqueDiscriminators(entries: readonly AuthoringLeafEntry[], label: string): void {
495
+ const seen = new Map<string, string>();
496
+ for (const { path, discriminator } of entries) {
497
+ const existing = seen.get(discriminator);
498
+ if (existing !== undefined) {
499
+ throw new Error(
500
+ `Duplicate ${label} discriminator "${discriminator}" registered at both "${existing}" and "${path}". Each ${label} contribution must use a unique discriminator.`,
501
+ );
502
+ }
503
+ seen.set(discriminator, path);
504
+ }
505
+ }
506
+
507
+ /**
508
+ * Every `pslBlockDescriptors` entry needs a matching `entityTypes` factory
509
+ * (same discriminator): the parser would otherwise produce an AST node
510
+ * nothing can lower to an IR class instance. The link is one-directional
511
+ * — an `entityTypes` factory may stand alone (e.g. `enum`, reachable from
512
+ * the TypeScript builder without any PSL block).
513
+ */
514
+ function assertPslBlocksHaveFactories(
515
+ entityTypeNamespace: AuthoringEntityTypeNamespace,
516
+ pslBlockNamespace: AuthoringPslBlockDescriptorNamespace,
517
+ ): void {
518
+ const blockEntries = collectAuthoringLeafDiscriminators(
519
+ pslBlockNamespace,
520
+ isAuthoringPslBlockDescriptor,
521
+ 'pslBlock',
522
+ );
523
+ const entityEntries = collectAuthoringLeafDiscriminators(
524
+ entityTypeNamespace,
525
+ isAuthoringEntityTypeDescriptor,
526
+ 'entityType',
527
+ );
528
+
529
+ assertUniqueDiscriminators(blockEntries, 'pslBlock');
530
+ assertUniqueDiscriminators(entityEntries, 'entityType');
531
+
532
+ const entityDiscriminators = new Set(entityEntries.map((entry) => entry.discriminator));
533
+
534
+ for (const block of blockEntries) {
535
+ if (!entityDiscriminators.has(block.discriminator)) {
536
+ throw new Error(
537
+ `Incomplete extension contribution: pslBlock helper "${block.path}" registers discriminator "${block.discriminator}" but no entityType contribution shares that discriminator. An extension-contributed PSL block requires a matching entityType factory so the parsed AST node can lower to an IR class instance; add an entityType helper with discriminator "${block.discriminator}".`,
538
+ );
539
+ }
540
+ }
541
+ }
542
+
344
543
  export function assertNoCrossRegistryCollisions(
345
544
  typeNamespace: AuthoringTypeNamespace,
346
545
  fieldNamespace: AuthoringFieldNamespace,
347
546
  entityTypeNamespace: AuthoringEntityTypeNamespace = {},
547
+ pslBlockNamespace: AuthoringPslBlockDescriptorNamespace = {},
348
548
  ): void {
349
549
  const typePaths = new Set(
350
550
  collectAuthoringLeafPaths(typeNamespace, isAuthoringTypeConstructorDescriptor),
@@ -360,20 +560,33 @@ export function assertNoCrossRegistryCollisions(
360
560
  // `mergeHelperNamespaces` in composed-authoring-helpers.ts), which throws
361
561
  // on same-path registrations within any single registry before this check
362
562
  // runs. This function only handles the cross-registry case.
563
+ //
564
+ // Cross-registry collisions are checked among `type` / `field` /
565
+ // `entityTypes` only — these three are user-facing helper paths that PSL
566
+ // must resolve unambiguously. `pslBlockDescriptors` is an internal
567
+ // framework index consumed by parser and printer dispatch, not a
568
+ // user-facing helper path; the natural authoring pattern is the same
569
+ // path key in `entityTypes` and `pslBlockDescriptors` for a single
570
+ // contribution. The block→factory link is enforced by
571
+ // `assertPslBlocksHaveFactories` via the discriminator string, not by path.
572
+ const ambiguityHint =
573
+ 'Register each path in only one of authoringContributions.field / authoringContributions.type / authoringContributions.entityTypes.';
363
574
  for (const fieldPath of fieldPaths) {
364
575
  if (typePaths.has(fieldPath)) {
365
576
  throw new Error(
366
- `Ambiguous authoring registry path "${fieldPath}". The same path is registered as both a type constructor and a field preset; PSL resolution would be ambiguous. Register each path in only one of authoringContributions.field / authoringContributions.type / authoringContributions.entityTypes.`,
577
+ `Ambiguous authoring registry path "${fieldPath}". The same path is registered as both a type constructor and a field preset; PSL resolution would be ambiguous. ${ambiguityHint}`,
367
578
  );
368
579
  }
369
580
  }
370
581
  for (const entityPath of entityPaths) {
371
582
  if (typePaths.has(entityPath) || fieldPaths.has(entityPath)) {
372
583
  throw new Error(
373
- `Ambiguous authoring registry path "${entityPath}". The same path is registered as an entity contribution AND as a type constructor or field preset; PSL resolution would be ambiguous. Register each path in only one of authoringContributions.field / authoringContributions.type / authoringContributions.entityTypes.`,
584
+ `Ambiguous authoring registry path "${entityPath}". The same path is registered as an entity contribution AND as a type constructor or field preset; PSL resolution would be ambiguous. ${ambiguityHint}`,
374
585
  );
375
586
  }
376
587
  }
588
+
589
+ assertPslBlocksHaveFactories(entityTypeNamespace, pslBlockNamespace);
377
590
  }
378
591
 
379
592
  export function resolveAuthoringTemplateValue(
@@ -227,6 +227,8 @@ export type TargetPackRef<
227
227
  TTargetId extends string = string,
228
228
  > = PackRefBase<'target', TFamilyId> & {
229
229
  readonly targetId: TTargetId;
230
+ /** The namespace a bare (un-namespaced) entity name resolves to for this target (e.g. Postgres `'public'`). */
231
+ readonly defaultNamespaceId: string;
230
232
  };
231
233
 
232
234
  export type AdapterPackRef<
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Shape-only types for the PSL source-position primitives, diagnostic
3
+ * codes, extension-block descriptor vocabulary, and the uniform
4
+ * extension-block AST node base.
5
+ *
6
+ * These live in the shared plane so an extension's authoring descriptor
7
+ * (`AuthoringPslBlockDescriptor` in `framework-authoring`) can reference
8
+ * them without crossing the shared → migration-plane boundary. The
9
+ * migration-plane `psl-ast.ts` re-exports everything here for consumers
10
+ * that import PSL AST types from the control entrypoint.
11
+ */
12
+
13
+ export interface PslPosition {
14
+ readonly offset: number;
15
+ readonly line: number;
16
+ readonly column: number;
17
+ }
18
+
19
+ export interface PslSpan {
20
+ readonly start: PslPosition;
21
+ readonly end: PslPosition;
22
+ }
23
+
24
+ export type PslDiagnosticCode =
25
+ | 'PSL_UNTERMINATED_BLOCK'
26
+ | 'PSL_UNSUPPORTED_TOP_LEVEL_BLOCK'
27
+ | 'PSL_INVALID_NAMESPACE_BLOCK'
28
+ | 'PSL_INVALID_ATTRIBUTE_SYNTAX'
29
+ | 'PSL_INVALID_MODEL_MEMBER'
30
+ | 'PSL_UNSUPPORTED_MODEL_ATTRIBUTE'
31
+ | 'PSL_UNSUPPORTED_FIELD_ATTRIBUTE'
32
+ | 'PSL_INVALID_RELATION_ATTRIBUTE'
33
+ | 'PSL_INVALID_REFERENTIAL_ACTION'
34
+ | 'PSL_INVALID_DEFAULT_VALUE'
35
+ | 'PSL_INVALID_ENUM_MEMBER'
36
+ | 'PSL_INVALID_TYPES_MEMBER'
37
+ | 'PSL_INVALID_QUALIFIED_TYPE'
38
+ /**
39
+ * A malformed line inside an extension-contributed top-level block body, or
40
+ * a structurally invalid element inside a `list` parameter value.
41
+ *
42
+ * Replaces the overloaded `PSL_UNSUPPORTED_TOP_LEVEL_BLOCK` code that the
43
+ * generic framework parser previously used for these two parse-error sites
44
+ * inside extension blocks — keeping `PSL_UNSUPPORTED_TOP_LEVEL_BLOCK` for
45
+ * its original meaning (an unknown keyword at the top level) and giving
46
+ * extension-block parse errors their own code.
47
+ */
48
+ | 'PSL_INVALID_EXTENSION_BLOCK_MEMBER'
49
+ /**
50
+ * An unknown parameter key in an extension-contributed block — a key present
51
+ * in the source block but absent from the descriptor's `parameters` map.
52
+ */
53
+ | 'PSL_EXTENSION_UNKNOWN_PARAMETER'
54
+ /**
55
+ * A required parameter declared in the descriptor is absent from the parsed block.
56
+ */
57
+ | 'PSL_EXTENSION_MISSING_REQUIRED_PARAMETER'
58
+ /**
59
+ * An `option`-kind parameter value is not one of the allowed tokens listed
60
+ * in the descriptor's `values` array.
61
+ */
62
+ | 'PSL_EXTENSION_OPTION_OUT_OF_SET'
63
+ /**
64
+ * A `value`-kind parameter's raw text is not a valid JSON literal, or the
65
+ * parsed JSON value was rejected by the codec's `decodeJson` method, or the
66
+ * codec id is not registered in the lookup.
67
+ */
68
+ | 'PSL_EXTENSION_INVALID_VALUE'
69
+ /**
70
+ * A `ref`-kind parameter identifier does not resolve to a declared entity of
71
+ * the required `refKind` within the declared scope.
72
+ */
73
+ | 'PSL_EXTENSION_UNRESOLVED_REF';
74
+
75
+ /**
76
+ * Descriptor vocabulary for a single parameter on a declared block.
77
+ *
78
+ * Four kinds:
79
+ * - `ref` — the parameter value is an identifier that must resolve to a
80
+ * declared entity of `refKind` within the declared `scope`.
81
+ * - `value` — the parameter value is a PSL literal parsed and printed
82
+ * through the codec identified by `codecId`.
83
+ * - `option` — the parameter value is one of the literal tokens in `values`.
84
+ * Not a codec; not persisted data. A closed authoring-time constraint only.
85
+ * - `list` — a bracketed list whose elements each match the `of` descriptor.
86
+ */
87
+ export type PslBlockParam =
88
+ | PslBlockParamRef
89
+ | PslBlockParamValue
90
+ | PslBlockParamOption
91
+ | PslBlockParamList;
92
+
93
+ export interface PslBlockParamRef {
94
+ readonly kind: 'ref';
95
+ readonly refKind: string;
96
+ readonly scope: 'same-namespace' | 'same-space' | 'cross-space';
97
+ readonly required?: boolean;
98
+ }
99
+
100
+ export interface PslBlockParamValue {
101
+ readonly kind: 'value';
102
+ readonly codecId: string;
103
+ readonly required?: boolean;
104
+ }
105
+
106
+ export interface PslBlockParamOption {
107
+ readonly kind: 'option';
108
+ readonly values: readonly string[];
109
+ readonly required?: boolean;
110
+ }
111
+
112
+ export interface PslBlockParamList {
113
+ readonly kind: 'list';
114
+ readonly of: PslBlockParam;
115
+ readonly required?: boolean;
116
+ }
117
+
118
+ /**
119
+ * The parsed representation of a single parameter value on a uniform
120
+ * extension-block AST node. Mirrors the `PslBlockParam` descriptor
121
+ * vocabulary:
122
+ *
123
+ * - `ref` → `PslExtensionBlockParamRef` — a raw identifier string
124
+ * (resolution runs in the validator, not the parser).
125
+ * - `value` → `PslExtensionBlockParamValue` — a raw PSL literal string
126
+ * (codec validation runs in the validator).
127
+ * - `option` → `PslExtensionBlockParamOption` — the chosen token.
128
+ * - `list` → `PslExtensionBlockParamList` — ordered list of the above.
129
+ *
130
+ * These shapes are intentionally minimal. The validator and lowering refine
131
+ * and consume them; the generic framework parser produces them.
132
+ */
133
+ export type PslExtensionBlockParamValue =
134
+ | PslExtensionBlockParamRef
135
+ | PslExtensionBlockParamScalarValue
136
+ | PslExtensionBlockParamOption
137
+ | PslExtensionBlockParamList;
138
+
139
+ export interface PslExtensionBlockParamRef {
140
+ readonly kind: 'ref';
141
+ readonly identifier: string;
142
+ readonly span: PslSpan;
143
+ }
144
+
145
+ export interface PslExtensionBlockParamScalarValue {
146
+ readonly kind: 'value';
147
+ readonly raw: string;
148
+ readonly span: PslSpan;
149
+ }
150
+
151
+ export interface PslExtensionBlockParamOption {
152
+ readonly kind: 'option';
153
+ readonly token: string;
154
+ readonly span: PslSpan;
155
+ }
156
+
157
+ export interface PslExtensionBlockParamList {
158
+ readonly kind: 'list';
159
+ readonly items: readonly PslExtensionBlockParamValue[];
160
+ readonly span: PslSpan;
161
+ }
162
+
163
+ /**
164
+ * Base shape for a uniform extension-contributed top-level PSL block
165
+ * node, as produced by the generic framework parser and consumed by the
166
+ * validator and lowering factory.
167
+ *
168
+ * - `kind` is the routing discriminant, equal to the descriptor's
169
+ * `discriminator`. The framework parser sets this to
170
+ * `descriptor.discriminator` for every block it parses.
171
+ * - `name` is the block's declared name (the identifier after the keyword).
172
+ * - `parameters` is the descriptor-driven parameter map. Keys are
173
+ * parameter names from the descriptor; values are the parsed parameter
174
+ * representations. Only parameters present in the source are included
175
+ * — absence of a required parameter is a validator concern, not a
176
+ * parser concern.
177
+ * - `span` covers the full block from keyword to closing brace.
178
+ */
179
+ export interface PslExtensionBlock {
180
+ readonly kind: string;
181
+ readonly name: string;
182
+ readonly parameters: Record<string, PslExtensionBlockParamValue>;
183
+ readonly span: PslSpan;
184
+ }
@@ -1,183 +0,0 @@
1
- import { ColumnDefault, ExecutionMutationDefaultPhases } from "@prisma-next/contract/types";
2
- import { Type } from "arktype";
3
-
4
- //#region src/shared/framework-authoring.d.ts
5
- type AuthoringArgRef = {
6
- readonly kind: 'arg';
7
- readonly index: number;
8
- readonly path?: readonly string[];
9
- readonly default?: AuthoringTemplateValue;
10
- };
11
- type AuthoringTemplateValue = string | number | boolean | null | AuthoringArgRef | readonly AuthoringTemplateValue[] | {
12
- readonly [key: string]: AuthoringTemplateValue;
13
- };
14
- interface AuthoringArgumentDescriptorCommon {
15
- readonly name?: string;
16
- readonly optional?: boolean;
17
- }
18
- type AuthoringArgumentDescriptor = AuthoringArgumentDescriptorCommon & ({
19
- readonly kind: 'string';
20
- } | {
21
- readonly kind: 'boolean';
22
- } | {
23
- readonly kind: 'number';
24
- readonly integer?: boolean;
25
- readonly minimum?: number;
26
- readonly maximum?: number;
27
- } | {
28
- readonly kind: 'stringArray';
29
- } | {
30
- readonly kind: 'object';
31
- readonly properties: Record<string, AuthoringArgumentDescriptor>;
32
- });
33
- interface AuthoringStorageTypeTemplate {
34
- readonly codecId: string;
35
- readonly nativeType: AuthoringTemplateValue;
36
- readonly typeParams?: Record<string, AuthoringTemplateValue>;
37
- }
38
- interface AuthoringTypeConstructorDescriptor {
39
- readonly kind: 'typeConstructor';
40
- readonly args?: readonly AuthoringArgumentDescriptor[];
41
- readonly output: AuthoringStorageTypeTemplate;
42
- }
43
- interface AuthoringColumnDefaultTemplateLiteral {
44
- readonly kind: 'literal';
45
- readonly value: AuthoringTemplateValue;
46
- }
47
- interface AuthoringColumnDefaultTemplateFunction {
48
- readonly kind: 'function';
49
- readonly expression: AuthoringTemplateValue;
50
- }
51
- type AuthoringColumnDefaultTemplate = AuthoringColumnDefaultTemplateLiteral | AuthoringColumnDefaultTemplateFunction;
52
- interface AuthoringExecutionDefaultsTemplate {
53
- readonly onCreate?: AuthoringTemplateValue;
54
- readonly onUpdate?: AuthoringTemplateValue;
55
- }
56
- interface AuthoringFieldPresetOutput extends AuthoringStorageTypeTemplate {
57
- readonly nullable?: boolean;
58
- readonly default?: AuthoringColumnDefaultTemplate;
59
- readonly executionDefaults?: AuthoringExecutionDefaultsTemplate;
60
- readonly id?: boolean;
61
- readonly unique?: boolean;
62
- }
63
- interface AuthoringFieldPresetDescriptor {
64
- readonly kind: 'fieldPreset';
65
- readonly args?: readonly AuthoringArgumentDescriptor[];
66
- readonly output: AuthoringFieldPresetOutput;
67
- }
68
- type AuthoringTypeNamespace = {
69
- readonly [name: string]: AuthoringTypeConstructorDescriptor | AuthoringTypeNamespace;
70
- };
71
- type AuthoringFieldNamespace = {
72
- readonly [name: string]: AuthoringFieldPresetDescriptor | AuthoringFieldNamespace;
73
- };
74
- /**
75
- * Context surfaced to entity-type factories at call time. Currently a
76
- * placeholder — sharpened as concrete consumers (enum, namespace, …)
77
- * discover what the factory actually needs to read (codec lookup,
78
- * namespace registry, …).
79
- */
80
- interface AuthoringEntityContext {
81
- readonly family: string;
82
- readonly target: string;
83
- }
84
- interface AuthoringEntityTypeTemplateOutput {
85
- readonly template: AuthoringTemplateValue;
86
- }
87
- /**
88
- * Default `Input = never` is load-bearing for pack-bag-driven type
89
- * narrowing. Factory parameter positions are contravariant, so a pack
90
- * literal declaring `factory: (input: DemoEntityInput) => DemoEntity`
91
- * is only assignable to the base descriptor's factory shape if the
92
- * base's input is `never` (the bottom of the contravariant position).
93
- * The concrete input/output types are recovered at the helper-derivation
94
- * site via `EntityHelperFunction<Descriptor>`'s conditional inference,
95
- * which reads them from the pack's `as const` literal factory signature
96
- * — the base widening does not erase the literal because `satisfies`
97
- * does not widen the declared type.
98
- */
99
- interface AuthoringEntityTypeFactoryOutput<Input = never, Output = unknown> {
100
- readonly factory: (input: Input, ctx: AuthoringEntityContext) => Output;
101
- }
102
- interface AuthoringEntityTypeDescriptor<Input = never, Output = unknown> {
103
- readonly kind: 'entity';
104
- readonly discriminator: string;
105
- readonly args?: readonly AuthoringArgumentDescriptor[];
106
- readonly output: AuthoringEntityTypeTemplateOutput | AuthoringEntityTypeFactoryOutput<Input, Output>;
107
- /**
108
- * arktype schema fragment for one entry whose envelope `kind` matches
109
- * this descriptor's {@link discriminator}. The family validator composes
110
- * contributed fragments into the per-namespace entry schema at
111
- * validator construction time so the structural check covers
112
- * pack-introduced kinds without the family core hard-coding the schema.
113
- *
114
- * Hydration uses {@link AuthoringEntityTypeFactoryOutput.factory}
115
- * directly — the wire shape conforms structurally to the factory's
116
- * `Input` after `validatorSchema` validates it.
117
- */
118
- readonly validatorSchema?: Type<unknown>;
119
- }
120
- type AuthoringEntityTypeNamespace = {
121
- readonly [name: string]: AuthoringEntityTypeDescriptor | AuthoringEntityTypeNamespace;
122
- };
123
- interface AuthoringContributions {
124
- readonly type?: AuthoringTypeNamespace;
125
- readonly field?: AuthoringFieldNamespace;
126
- readonly entityTypes?: AuthoringEntityTypeNamespace;
127
- }
128
- declare function isAuthoringArgRef(value: unknown): value is AuthoringArgRef;
129
- declare function isAuthoringTypeConstructorDescriptor(value: unknown): value is AuthoringTypeConstructorDescriptor;
130
- declare function isAuthoringFieldPresetDescriptor(value: unknown): value is AuthoringFieldPresetDescriptor;
131
- declare function isAuthoringEntityTypeDescriptor(value: unknown): value is AuthoringEntityTypeDescriptor;
132
- /**
133
- * Returns true when `namespace` is a non-leaf key in `contributions.field`.
134
- *
135
- * `AuthoringFieldNamespace` permits a leaf descriptor at any depth — including
136
- * the root — so a top-level `field: { Foo: { kind: 'fieldPreset', ... } }`
137
- * registration must NOT be treated as a "namespace" with sub-paths. Callers
138
- * use this predicate to gate dot-namespaced lookups (e.g. PSL `@Foo.bar`).
139
- */
140
- declare function hasRegisteredFieldNamespace(contributions: AuthoringContributions | undefined, namespace: string): boolean;
141
- /**
142
- * Merges `source` into `target` recursively at the descriptor-namespace
143
- * level. `leafGuard` decides which values are descriptors (terminal
144
- * merge points; same-path registrations across components are reported
145
- * as duplicates) versus sub-namespaces (recursion targets).
146
- *
147
- * Path segments are validated against prototype-pollution names
148
- * (`__proto__`, `constructor`, `prototype`). A value that is neither a
149
- * recognized leaf nor a plain object — e.g. a malformed descriptor
150
- * where the canonical leaf guard rejected it for missing `output` —
151
- * is reported as an invalid contribution rather than recursed into,
152
- * which would either silently mangle state or infinite-loop on
153
- * primitive properties.
154
- *
155
- * Within-registry duplicate detection is this walker's job;
156
- * cross-registry detection runs separately via
157
- * `assertNoCrossRegistryCollisions` after merging completes.
158
- */
159
- declare function mergeAuthoringNamespaces(target: Record<string, unknown>, source: Record<string, unknown>, path: readonly string[], leafGuard: (value: unknown) => boolean, label: string): void;
160
- declare function assertNoCrossRegistryCollisions(typeNamespace: AuthoringTypeNamespace, fieldNamespace: AuthoringFieldNamespace, entityTypeNamespace?: AuthoringEntityTypeNamespace): void;
161
- declare function resolveAuthoringTemplateValue(template: AuthoringTemplateValue, args: readonly unknown[]): unknown;
162
- declare function validateAuthoringHelperArguments(helperPath: string, descriptors: readonly AuthoringArgumentDescriptor[] | undefined, args: readonly unknown[]): void;
163
- declare function instantiateAuthoringTypeConstructor(descriptor: AuthoringTypeConstructorDescriptor, args: readonly unknown[]): {
164
- readonly codecId: string;
165
- readonly nativeType: string;
166
- readonly typeParams?: Record<string, unknown>;
167
- };
168
- declare function instantiateAuthoringEntityType(helperPath: string, descriptor: AuthoringEntityTypeDescriptor, args: readonly unknown[], ctx: AuthoringEntityContext): unknown;
169
- declare function instantiateAuthoringFieldPreset(descriptor: AuthoringFieldPresetDescriptor, args: readonly unknown[]): {
170
- readonly descriptor: {
171
- readonly codecId: string;
172
- readonly nativeType: string;
173
- readonly typeParams?: Record<string, unknown>;
174
- };
175
- readonly nullable: boolean;
176
- readonly default?: ColumnDefault;
177
- readonly executionDefaults?: ExecutionMutationDefaultPhases;
178
- readonly id: boolean;
179
- readonly unique: boolean;
180
- };
181
- //#endregion
182
- export { isAuthoringEntityTypeDescriptor as C, resolveAuthoringTemplateValue as D, mergeAuthoringNamespaces as E, validateAuthoringHelperArguments as O, isAuthoringArgRef as S, isAuthoringTypeConstructorDescriptor as T, assertNoCrossRegistryCollisions as _, AuthoringEntityContext as a, instantiateAuthoringFieldPreset as b, AuthoringEntityTypeNamespace as c, AuthoringFieldPresetDescriptor as d, AuthoringFieldPresetOutput as f, AuthoringTypeNamespace as g, AuthoringTypeConstructorDescriptor as h, AuthoringContributions as i, AuthoringEntityTypeTemplateOutput as l, AuthoringTemplateValue as m, AuthoringArgumentDescriptor as n, AuthoringEntityTypeDescriptor as o, AuthoringStorageTypeTemplate as p, AuthoringColumnDefaultTemplate as r, AuthoringEntityTypeFactoryOutput as s, AuthoringArgRef as t, AuthoringFieldNamespace as u, hasRegisteredFieldNamespace as v, isAuthoringFieldPresetDescriptor as w, instantiateAuthoringTypeConstructor as x, instantiateAuthoringEntityType as y };
183
- //# sourceMappingURL=framework-authoring-BPPe9C9D.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"framework-authoring-BPPe9C9D.d.mts","names":[],"sources":["../src/shared/framework-authoring.ts"],"mappings":"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"}