@xdbml/parse 0.5.0 → 0.6.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/dist/ast.d.ts CHANGED
@@ -68,7 +68,7 @@ export interface EntityDeclaration {
68
68
  span: Span;
69
69
  }
70
70
  export type EntityKeyword = 'Table' | 'Entity' | 'Collection' | 'Record';
71
- export type EntityBodyItem = FieldDeclaration | IndexesBlock | ChecksBlock | NoteBlock | PartialInjection | RecordsBlock;
71
+ export type EntityBodyItem = FieldDeclaration | IndexesBlock | ChecksBlock | ConstraintsBlock | NoteBlock | PartialInjection | RecordsBlock;
72
72
  export interface FieldDeclaration {
73
73
  kind: 'FieldDeclaration';
74
74
  name: string;
@@ -81,7 +81,11 @@ export interface FieldDeclaration {
81
81
  export type TypeExpression = ScalarType | ObjectType | ArrayType | TupleType | MapType | SetType | UnionType | OneOfType | AnyOfType | AllOfType | JsonType | NamedTypeReference;
82
82
  export interface ScalarType {
83
83
  kind: 'ScalarType';
84
- /** The base name: `int`, `varchar`, `decimal`, `objectId`, `Decimal128`, etc. */
84
+ /**
85
+ * The base name: `int`, `varchar`, `decimal`, `objectId`, `Decimal128`,
86
+ * etc. May be qualified, `core.job_status`, when it names an Enum
87
+ * declared in a container (spec §16).
88
+ */
85
89
  name: string;
86
90
  /** `(p, s)` parameters, e.g. for `decimal(19, 4)`. Numbers preserved as strings to keep round-trip fidelity. */
87
91
  params?: string[];
@@ -229,6 +233,11 @@ export interface EnumDeclaration {
229
233
  kind: 'EnumDeclaration';
230
234
  /** Source casing of `enum` or `Enum`; both are valid. */
231
235
  keywordCasing: string;
236
+ /**
237
+ * May be `container.enum` form when declared schema-qualified at the
238
+ * top level (`enum core.job_status`); the resolver files it under that
239
+ * container, like an Enum declared inside the Container block.
240
+ */
232
241
  name: string;
233
242
  values: EnumValue[];
234
243
  span: Span;
@@ -319,12 +328,34 @@ export interface ChecksBlock {
319
328
  }
320
329
  export interface CheckEntry {
321
330
  kind: 'CheckEntry';
322
- /** Source text inside the backticks, no surrounding backticks. */
331
+ /** Source text inside the delimiters, without them. */
323
332
  expression: string;
333
+ /**
334
+ * How the source wrote the expression (spec §10.5, v0.6): in backticks,
335
+ * or in single or triple quotes. Both mean the same check; the raw AST
336
+ * keeps the form. Absent on entries built by older code paths, which
337
+ * only ever read backticks.
338
+ */
339
+ delimiter?: 'backtick' | 'quote';
324
340
  /** Optional settings -- typically `name:` and/or `note:`. */
325
341
  settings: Setting[];
326
342
  span: Span;
327
343
  }
344
+ export interface ConstraintsBlock {
345
+ kind: 'ConstraintsBlock';
346
+ entries: ConstraintEntry[];
347
+ span: Span;
348
+ }
349
+ export type ConstraintEntry = KeyConstraintEntry | CheckEntry;
350
+ export interface KeyConstraintEntry {
351
+ kind: 'KeyConstraintEntry';
352
+ /** One path per key field, in key order. */
353
+ fields: PathSegment[][];
354
+ /** True when the source wrote the fields in parentheses. */
355
+ parenthesized: boolean;
356
+ settings: Setting[];
357
+ span: Span;
358
+ }
328
359
  export interface TablePartialDeclaration {
329
360
  kind: 'TablePartialDeclaration';
330
361
  name: string;
@@ -491,6 +522,12 @@ export interface Setting {
491
522
  nameSource: string;
492
523
  /** Value, if any. A pure flag like `pk` has `value: null`. */
493
524
  value: SettingValue | null;
525
+ /**
526
+ * True on a setting the parser added rather than read: `not null` on a
527
+ * primary key field of a v0.6 document (spec §10.4). Its span is the
528
+ * field's span.
529
+ */
530
+ implied?: true;
494
531
  span: Span;
495
532
  }
496
533
  export type SettingValue = StringValue | NumberValue | BooleanValue | NullValue | IdentifierValue | ExpressionValue | ListValue | RefValue;
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Constraints (spec §10, new in v0.6) and referenced keys (spec §11.17).
3
+ *
4
+ * Three jobs:
5
+ *
6
+ * 1. `bodyConstraints()` / `entityConstraints()` gather every key and
7
+ * check of an entity into one list, whatever form declared it: a line
8
+ * in `constraints { }` or `checks { }`, `[pk]` / `[unique]` on a
9
+ * field, a `pk` entry in `indexes`, a field-level `check:`. This is
10
+ * the Constraint node of spec §28.6, and what the renderer and the
11
+ * playground read, so a consumer finds the primary key in one place.
12
+ *
13
+ * 2. `markPrimaryKeyNotNull()` adds an implied `not null` to each
14
+ * primary key field of a v0.6 document (spec §10.4). The parser calls
15
+ * it once the document is built.
16
+ *
17
+ * 3. `checkConstraints()` reports the conditions of spec §10.10 and the
18
+ * referenced-key rule of spec §11.17. Conditions on constructs that
19
+ * earlier versions and DBML accept are errors in a document declaring
20
+ * 0.6 or later and warnings otherwise, so a document stays valid under
21
+ * the version it declares.
22
+ */
23
+ import type { EntityBodyItem, PathSegment, Span, XDbmlDocument } from './ast.ts';
24
+ import type { Diagnostic } from './name-resolver.ts';
25
+ /** Where a constraint was declared. The raw AST keeps the form; this list does not. */
26
+ export type ConstraintSource = 'constraints' | 'checks' | 'inline' | 'indexes' | 'field-check';
27
+ export interface KeyConstraint {
28
+ kind: 'key';
29
+ keyKind: 'primary' | 'unique';
30
+ /** Dotted field paths, in key order. */
31
+ fields: string[];
32
+ name?: string;
33
+ note?: string;
34
+ source: ConstraintSource;
35
+ span: Span;
36
+ }
37
+ export interface CheckConstraint {
38
+ kind: 'check';
39
+ expression: string;
40
+ name?: string;
41
+ note?: string;
42
+ /** For a field-level `check:`, the field it sits on. */
43
+ field?: string;
44
+ source: ConstraintSource;
45
+ span: Span;
46
+ }
47
+ export type Constraint = KeyConstraint | CheckConstraint;
48
+ type Body = ReadonlyArray<EntityBodyItem>;
49
+ /** Dotted form of a key or index path; only field segments carry names. */
50
+ export declare function keyPathString(path: ReadonlyArray<PathSegment>): string;
51
+ /**
52
+ * The constraints one body declares itself, TablePartial injections left
53
+ * out. `quotedFieldChecks` reads a quoted field-level `check:` as a check
54
+ * (v0.6 §10.5); in earlier versions a quoted value there is a string.
55
+ */
56
+ export declare function bodyConstraints(body: Body, quotedFieldChecks?: boolean): Constraint[];
57
+ /**
58
+ * Every constraint of an entity (or edge, or partial): its own, plus those
59
+ * of the TablePartials it injects. One primary key results: the entity's
60
+ * own when it declares one, otherwise the last injected partial's (§10.4,
61
+ * following the conflict resolution of §17.1).
62
+ */
63
+ export declare function entityConstraints(decl: {
64
+ body: Body;
65
+ }, doc: XDbmlDocument): Constraint[];
66
+ /** The primary key of an entity, or undefined. */
67
+ export declare function primaryKey(decl: {
68
+ body: Body;
69
+ }, doc: XDbmlDocument): KeyConstraint | undefined;
70
+ /**
71
+ * Add an implied `not null` to every field of the primary key of each
72
+ * entity, edge and partial the document declares itself, unless the field
73
+ * states its nullability. `null` on a primary key field is left in place
74
+ * for checkConstraints to report. Keys naming a partial's field from the
75
+ * injecting entity are not marked: the field belongs to the partial.
76
+ */
77
+ export declare function markPrimaryKeyNotNull(doc: XDbmlDocument): void;
78
+ /** True for a target name the §11.17 rule covers. Unlisted names are not relational. */
79
+ export declare function isRelationalTarget(name: string): boolean;
80
+ export declare function checkConstraints(doc: XDbmlDocument): Diagnostic[];
81
+ export {};