@xdbml/parse 0.5.1 → 0.6.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.
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;
@@ -328,12 +328,34 @@ export interface ChecksBlock {
328
328
  }
329
329
  export interface CheckEntry {
330
330
  kind: 'CheckEntry';
331
- /** Source text inside the backticks, no surrounding backticks. */
331
+ /** Source text inside the delimiters, without them. */
332
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';
333
340
  /** Optional settings -- typically `name:` and/or `note:`. */
334
341
  settings: Setting[];
335
342
  span: Span;
336
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
+ }
337
359
  export interface TablePartialDeclaration {
338
360
  kind: 'TablePartialDeclaration';
339
361
  name: string;
@@ -500,6 +522,12 @@ export interface Setting {
500
522
  nameSource: string;
501
523
  /** Value, if any. A pure flag like `pk` has `value: null`. */
502
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;
503
531
  span: Span;
504
532
  }
505
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 {};