@xdbml/parse 0.1.0-poc.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 ADDED
@@ -0,0 +1,565 @@
1
+ /**
2
+ * xDBML AST node types.
3
+ *
4
+ * The AST is intentionally narrow: each node carries only what's needed
5
+ * to round-trip xDBML source and to feed a downstream lowering pass
6
+ * (DDL emitters, JSON Schema emitters, etc.). Generic open-vocabulary
7
+ * settings are kept as Setting nodes rather than promoted to typed
8
+ * fields, because the spec leaves the settings vocabulary open.
9
+ */
10
+ export interface Position {
11
+ /** 1-indexed line number */
12
+ line: number;
13
+ /** 1-indexed column number */
14
+ column: number;
15
+ /** 0-indexed byte offset into the source */
16
+ offset: number;
17
+ }
18
+ export interface Span {
19
+ start: Position;
20
+ end: Position;
21
+ }
22
+ export interface XDbmlDocument {
23
+ kind: 'XDbmlDocument';
24
+ /** Present when the document opens with `xdbml: 0.1`. DBML-compat documents have this undefined. */
25
+ version?: VersionDeclaration;
26
+ experimental?: ExperimentalDeclaration;
27
+ statements: TopLevelStatement[];
28
+ span: Span;
29
+ }
30
+ export interface VersionDeclaration {
31
+ kind: 'VersionDeclaration';
32
+ /** The literal source text, e.g. "0.1" or "0.1.0". Semver shape validated at parse. */
33
+ version: string;
34
+ span: Span;
35
+ }
36
+ export interface ExperimentalDeclaration {
37
+ kind: 'ExperimentalDeclaration';
38
+ features: string[];
39
+ span: Span;
40
+ }
41
+ export type TopLevelStatement = ProjectDeclaration | ContainerDeclaration | EntityDeclaration | TypeDeclaration | EdgeDeclaration | ViewDeclaration | EnumDeclaration | RefDeclaration | TablePartialDeclaration | TableGroupDeclaration | NoteDeclaration | TopLevelRecordsDeclaration | ModuleImportDirective;
42
+ export interface ProjectDeclaration {
43
+ kind: 'ProjectDeclaration';
44
+ name: string;
45
+ body: ProjectBodyItem[];
46
+ span: Span;
47
+ }
48
+ export type ProjectBodyItem = Setting | NoteBlock;
49
+ export interface ContainerDeclaration {
50
+ kind: 'ContainerDeclaration';
51
+ keyword: ContainerKeyword;
52
+ name: string;
53
+ settings: Setting[];
54
+ body: ContainerBodyItem[];
55
+ span: Span;
56
+ }
57
+ export type ContainerKeyword = 'Container' | 'Schema' | 'Database' | 'Keyspace' | 'Namespace' | 'Dataset' | 'Bucket';
58
+ export type ContainerBodyItem = EntityDeclaration | EdgeDeclaration | ViewDeclaration | EnumDeclaration | NoteBlock | ModuleImportDirective;
59
+ export interface EntityDeclaration {
60
+ kind: 'EntityDeclaration';
61
+ keyword: EntityKeyword;
62
+ /** May be `container.entity` form when declared schema-qualified */
63
+ name: string;
64
+ /** Optional `as Alias` */
65
+ alias?: string;
66
+ settings: Setting[];
67
+ body: EntityBodyItem[];
68
+ span: Span;
69
+ }
70
+ export type EntityKeyword = 'Table' | 'Entity' | 'Collection' | 'Record';
71
+ export type EntityBodyItem = FieldDeclaration | IndexesBlock | ChecksBlock | NoteBlock | PartialInjection | RecordsBlock;
72
+ export interface FieldDeclaration {
73
+ kind: 'FieldDeclaration';
74
+ name: string;
75
+ /** True when the name came from a quoted identifier ("first name") */
76
+ nameQuoted: boolean;
77
+ type: TypeExpression;
78
+ settings: Setting[];
79
+ span: Span;
80
+ }
81
+ export type TypeExpression = ScalarType | ObjectType | ArrayType | TupleType | MapType | SetType | UnionType | OneOfType | AnyOfType | AllOfType | JsonType | NamedTypeReference;
82
+ export interface ScalarType {
83
+ kind: 'ScalarType';
84
+ /** The base name: `int`, `varchar`, `decimal`, `objectId`, `Decimal128`, etc. */
85
+ name: string;
86
+ /** `(p, s)` parameters, e.g. for `decimal(19, 4)`. Numbers preserved as strings to keep round-trip fidelity. */
87
+ params?: string[];
88
+ span: Span;
89
+ }
90
+ export interface NamedTypeReference {
91
+ kind: 'NamedTypeReference';
92
+ name: string;
93
+ span: Span;
94
+ }
95
+ export interface ObjectType {
96
+ kind: 'ObjectType';
97
+ /** Captures whether the source used `object`, `struct`, or `record` */
98
+ keyword: 'object' | 'struct' | 'record';
99
+ fields: (FieldDeclaration | NoteBlock | PartialInjection)[];
100
+ span: Span;
101
+ }
102
+ export interface ArrayType {
103
+ kind: 'ArrayType';
104
+ keyword: 'array' | 'list';
105
+ /** The element type when the array is homogeneous (`array [varchar]`). */
106
+ elementType?: TypeExpression;
107
+ /** When the array body uses `name type` form, e.g. `array [line_item object {...}]`, this carries the element name. */
108
+ elementName?: string;
109
+ /** Optional settings applied to the element type itself (rare). */
110
+ elementSettings?: Setting[];
111
+ span: Span;
112
+ }
113
+ export interface TupleType {
114
+ kind: 'TupleType';
115
+ /** Positional elements with `[N] name type` */
116
+ elements: TupleElement[];
117
+ span: Span;
118
+ }
119
+ export interface TupleElement {
120
+ kind: 'TupleElement';
121
+ position: number;
122
+ name: string;
123
+ type: TypeExpression;
124
+ settings: Setting[];
125
+ span: Span;
126
+ }
127
+ export interface MapType {
128
+ kind: 'MapType';
129
+ keyword: 'map' | 'dict' | 'dictionary';
130
+ keyType: TypeExpression;
131
+ valueType: TypeExpression;
132
+ span: Span;
133
+ }
134
+ export interface SetType {
135
+ kind: 'SetType';
136
+ elementType: TypeExpression;
137
+ span: Span;
138
+ }
139
+ export interface UnionType {
140
+ kind: 'UnionType';
141
+ members: (ScalarType | NamedTypeReference | NullTypeLiteral)[];
142
+ span: Span;
143
+ }
144
+ export interface NullTypeLiteral {
145
+ kind: 'NullTypeLiteral';
146
+ span: Span;
147
+ }
148
+ export interface OneOfType {
149
+ kind: 'OneOfType';
150
+ alternatives: PolymorphicAlternative[];
151
+ settings: Setting[];
152
+ span: Span;
153
+ }
154
+ export interface AnyOfType {
155
+ kind: 'AnyOfType';
156
+ alternatives: PolymorphicAlternative[];
157
+ settings: Setting[];
158
+ span: Span;
159
+ }
160
+ export interface AllOfType {
161
+ kind: 'AllOfType';
162
+ alternatives: PolymorphicAlternative[];
163
+ settings: Setting[];
164
+ span: Span;
165
+ }
166
+ export interface PolymorphicAlternative {
167
+ kind: 'PolymorphicAlternative';
168
+ name: string;
169
+ type: TypeExpression;
170
+ settings: Setting[];
171
+ span: Span;
172
+ }
173
+ export interface JsonType {
174
+ kind: 'JsonType';
175
+ /** `json`, `jsonb`, or `variant` */
176
+ keyword: 'json' | 'jsonb' | 'variant';
177
+ /** Optional schema block; absence = opaque JSON column */
178
+ fields?: (FieldDeclaration | NoteBlock | PartialInjection)[];
179
+ span: Span;
180
+ }
181
+ export interface TypeDeclaration {
182
+ kind: 'TypeDeclaration';
183
+ name: string;
184
+ /**
185
+ * v0.2 scalar form (spec §14.7): when present, this Type is an alias
186
+ * for the given type expression rather than an object-shaped record.
187
+ * Examples:
188
+ *
189
+ * Type Email varchar [pattern: '...', tags: ['pii']]
190
+ * Type Percentage decimal(5,2) [minimum: 0, maximum: 100]
191
+ *
192
+ * When `scalarBase` is set, `body` is empty and `settings` carries the
193
+ * full field-level validation surface (pattern, length bounds, range
194
+ * bounds, AI-readiness tags, notes, x_* custom properties).
195
+ *
196
+ * When `scalarBase` is undefined, the Type uses the v0.1 object form
197
+ * (`Type Name { ...fields }`) and `body` carries the field declarations.
198
+ *
199
+ * Both forms can be used in the same file. Consumers that care about
200
+ * which form was used look at this field.
201
+ */
202
+ scalarBase?: TypeExpression;
203
+ settings: Setting[];
204
+ body: (FieldDeclaration | NoteBlock | PartialInjection)[];
205
+ span: Span;
206
+ }
207
+ export interface EdgeDeclaration {
208
+ kind: 'EdgeDeclaration';
209
+ name: string;
210
+ settings: Setting[];
211
+ body: EntityBodyItem[];
212
+ span: Span;
213
+ }
214
+ export interface ViewDeclaration {
215
+ kind: 'ViewDeclaration';
216
+ name: string;
217
+ settings: Setting[];
218
+ body: ViewBodyItem[];
219
+ span: Span;
220
+ }
221
+ export type ViewBodyItem = FieldDeclaration | NoteBlock | SourceQueryItem;
222
+ export interface SourceQueryItem {
223
+ kind: 'SourceQueryItem';
224
+ /** The raw query string. Opaque to the parser. */
225
+ query: string;
226
+ span: Span;
227
+ }
228
+ export interface EnumDeclaration {
229
+ kind: 'EnumDeclaration';
230
+ /** Source casing of `enum` or `Enum`; both are valid. */
231
+ keywordCasing: string;
232
+ name: string;
233
+ values: EnumValue[];
234
+ span: Span;
235
+ }
236
+ export interface EnumValue {
237
+ kind: 'EnumValue';
238
+ name: string;
239
+ nameQuoted: boolean;
240
+ settings: Setting[];
241
+ span: Span;
242
+ }
243
+ export interface RefDeclaration {
244
+ kind: 'RefDeclaration';
245
+ /** Optional named ref */
246
+ name?: string;
247
+ spec: RefSpec;
248
+ settings: Setting[];
249
+ span: Span;
250
+ }
251
+ export interface RefSpec {
252
+ kind: 'RefSpec';
253
+ source: RefEndpoint;
254
+ operator: CardinalityOperator;
255
+ target: RefEndpoint;
256
+ span: Span;
257
+ }
258
+ export type CardinalityOperator = '<' | '>' | '-' | '<>';
259
+ export interface RefEndpoint {
260
+ kind: 'RefEndpoint';
261
+ /**
262
+ * The dotted path. Composite FK form `customers.(id, country_code)` is
263
+ * captured by `compositeFields` being non-empty.
264
+ */
265
+ path: PathSegment[];
266
+ compositeFields?: string[];
267
+ span: Span;
268
+ }
269
+ export type PathSegment = PathField | PathArrayIndex | PathArrayWildcard | PathMapKey;
270
+ export interface PathField {
271
+ kind: 'PathField';
272
+ name: string;
273
+ /** True for `.alternative_name` selectors through polymorphism */
274
+ isAlternativeSelector?: boolean;
275
+ span: Span;
276
+ }
277
+ export interface PathArrayIndex {
278
+ kind: 'PathArrayIndex';
279
+ index: number;
280
+ span: Span;
281
+ }
282
+ export interface PathArrayWildcard {
283
+ kind: 'PathArrayWildcard';
284
+ span: Span;
285
+ }
286
+ export interface PathMapKey {
287
+ kind: 'PathMapKey';
288
+ key: string;
289
+ span: Span;
290
+ }
291
+ export interface IndexesBlock {
292
+ kind: 'IndexesBlock';
293
+ entries: IndexEntry[];
294
+ span: Span;
295
+ }
296
+ export interface IndexEntry {
297
+ kind: 'IndexEntry';
298
+ /** When this is a composite index, multiple components; otherwise one. */
299
+ components: IndexComponent[];
300
+ settings: Setting[];
301
+ span: Span;
302
+ }
303
+ export type IndexComponent = IndexPathComponent | IndexExpressionComponent;
304
+ export interface IndexPathComponent {
305
+ kind: 'IndexPathComponent';
306
+ path: PathSegment[];
307
+ span: Span;
308
+ }
309
+ export interface IndexExpressionComponent {
310
+ kind: 'IndexExpressionComponent';
311
+ /** Source text inside the backticks, no surrounding backticks */
312
+ expression: string;
313
+ span: Span;
314
+ }
315
+ export interface ChecksBlock {
316
+ kind: 'ChecksBlock';
317
+ entries: CheckEntry[];
318
+ span: Span;
319
+ }
320
+ export interface CheckEntry {
321
+ kind: 'CheckEntry';
322
+ /** Source text inside the backticks, no surrounding backticks. */
323
+ expression: string;
324
+ /** Optional settings -- typically `name:` and/or `note:`. */
325
+ settings: Setting[];
326
+ span: Span;
327
+ }
328
+ export interface TablePartialDeclaration {
329
+ kind: 'TablePartialDeclaration';
330
+ name: string;
331
+ settings: Setting[];
332
+ body: EntityBodyItem[];
333
+ span: Span;
334
+ }
335
+ export interface TableGroupDeclaration {
336
+ kind: 'TableGroupDeclaration';
337
+ name: string;
338
+ settings: Setting[];
339
+ members: string[];
340
+ span: Span;
341
+ }
342
+ export interface PartialInjection {
343
+ kind: 'PartialInjection';
344
+ /** Identifier after the `~`. */
345
+ partialName: string;
346
+ span: Span;
347
+ }
348
+ export interface RecordsBlock {
349
+ kind: 'RecordsBlock';
350
+ rows: RecordRow[];
351
+ span: Span;
352
+ }
353
+ export interface RecordRow {
354
+ kind: 'RecordRow';
355
+ values: SettingValue[];
356
+ span: Span;
357
+ }
358
+ export interface TopLevelRecordsDeclaration {
359
+ kind: 'TopLevelRecordsDeclaration';
360
+ /**
361
+ * The entity being populated. Dotted form for cross-container references
362
+ * such as `core.users`. Stored as the source-text dotted path; no
363
+ * resolution is performed at parse time.
364
+ */
365
+ entityRef: string;
366
+ /** The explicit column list. Required for the top-level form. */
367
+ columns: string[];
368
+ rows: RecordRow[];
369
+ span: Span;
370
+ }
371
+ export interface NoteDeclaration {
372
+ kind: 'NoteDeclaration';
373
+ name?: string;
374
+ body: string;
375
+ span: Span;
376
+ }
377
+ /** Inline `Note: '...'` or `Note { '''...''' }` form */
378
+ export interface NoteBlock {
379
+ kind: 'NoteBlock';
380
+ body: string;
381
+ span: Span;
382
+ }
383
+ export interface ModuleImportDirective {
384
+ kind: 'ModuleImportDirective';
385
+ /**
386
+ * Directive mode:
387
+ * - `'reuse'`: transitive (visible to files that further import this file).
388
+ * The recommended default per spec §26.4.
389
+ * - `'use'`: non-transitive (private to this file).
390
+ */
391
+ mode: 'use' | 'reuse';
392
+ /** What to import: everything (`*`) or a selective list. */
393
+ spec: ImportSpec;
394
+ /**
395
+ * The relative path string from the `from` clause, with quotes stripped.
396
+ * Stored as-is; path resolution happens at name-resolution time (P5+).
397
+ */
398
+ from: string;
399
+ /**
400
+ * Optional metadata settings appearing between `from '...'` and the
401
+ * clone block. In v0.2 phase 1, only `cloned_at` is defined; the parser
402
+ * is permissive and stores any settings here.
403
+ */
404
+ settings: Setting[];
405
+ /**
406
+ * The embedded clone block. When present, this is the authoritative
407
+ * content for the import. When absent (reference-only directive), the
408
+ * parser must resolve the `from` path at parse time (P5+).
409
+ */
410
+ clone?: CloneBlock;
411
+ span: Span;
412
+ }
413
+ /** Selective vs import-all distinction. */
414
+ export type ImportSpec = {
415
+ kind: 'ImportAll';
416
+ } | {
417
+ kind: 'ImportList';
418
+ items: ImportItem[];
419
+ };
420
+ /**
421
+ * A single import item in a selective `{ ... }` list:
422
+ *
423
+ * entity core.dim_customer
424
+ * type Email as PII_Email
425
+ * field core.dim_customer.email
426
+ *
427
+ * The element type is one of the keywords from §26.3 (table, entity,
428
+ * collection, record, enum, tablepartial, note, schema, container,
429
+ * tablegroup, type, edge, view, diagramview, field). Stored lowercased.
430
+ *
431
+ * The source path follows xDBML's standard dotted form. Container.Entity
432
+ * for an entity inside a Container; Container.Entity.Field for a field.
433
+ */
434
+ export interface ImportItem {
435
+ kind: 'ImportItem';
436
+ /** Lowercased element type keyword. */
437
+ elementType: string;
438
+ /** Dotted source path. */
439
+ sourcePath: string;
440
+ /** Optional rename in the current file's namespace. */
441
+ alias?: string;
442
+ span: Span;
443
+ }
444
+ /**
445
+ * A clone block embedding the imported declarations directly. For non-field
446
+ * imports the clone contains TopLevelStatement nodes (the natural shape of
447
+ * an entity, type, container, etc. clone). Field imports are not supported
448
+ * in P4 -- when they land, this type may grow to a wider union.
449
+ *
450
+ * Per spec §26.6, the clone contains exactly the imported declaration(s),
451
+ * without surrounding wrappers from the source file. For an entity clone
452
+ * the content is the EntityDeclaration alone (no container wrapper); for a
453
+ * container clone the content is the ContainerDeclaration including its
454
+ * intrinsic entities.
455
+ */
456
+ export interface CloneBlock {
457
+ kind: 'CloneBlock';
458
+ /**
459
+ * Statements that the importing file pulls in from the source. Most are
460
+ * top-level shapes (Entity, Type, Enum, Container, etc.). The one
461
+ * exception is `FieldDeclaration`: when the parent directive imports
462
+ * one or more fields via `field <path>` items (spec §26.8), each field
463
+ * appears here as a bare FieldDeclaration with no entity wrapper.
464
+ * The `flatten()` pass lifts each bare field into a synthetic
465
+ * TypeDeclaration at file scope so downstream consumers see a normal
466
+ * Named Type.
467
+ */
468
+ statements: (TopLevelStatement | FieldDeclaration)[];
469
+ span: Span;
470
+ }
471
+ export interface Setting {
472
+ kind: 'Setting';
473
+ /** Setting name, lowercased for canonical comparison. Source casing is preserved in `nameSource`. */
474
+ name: string;
475
+ nameSource: string;
476
+ /** Value, if any. A pure flag like `pk` has `value: null`. */
477
+ value: SettingValue | null;
478
+ span: Span;
479
+ }
480
+ export type SettingValue = StringValue | NumberValue | BooleanValue | NullValue | IdentifierValue | ExpressionValue | ListValue | RefValue;
481
+ export interface StringValue {
482
+ kind: 'StringValue';
483
+ /** The string content with surrounding quotes already stripped */
484
+ value: string;
485
+ /** Triple-quoted multi-line string */
486
+ multiline: boolean;
487
+ span: Span;
488
+ }
489
+ export interface NumberValue {
490
+ kind: 'NumberValue';
491
+ value: string;
492
+ span: Span;
493
+ }
494
+ export interface BooleanValue {
495
+ kind: 'BooleanValue';
496
+ value: boolean;
497
+ span: Span;
498
+ }
499
+ export interface NullValue {
500
+ kind: 'NullValue';
501
+ span: Span;
502
+ }
503
+ export interface IdentifierValue {
504
+ kind: 'IdentifierValue';
505
+ /** A bare or dotted identifier used as a value, e.g. `Oracle`, `cascade`, `set null`. */
506
+ value: string;
507
+ span: Span;
508
+ }
509
+ export interface ExpressionValue {
510
+ kind: 'ExpressionValue';
511
+ /** Source text inside backticks, no surrounding backticks */
512
+ expression: string;
513
+ span: Span;
514
+ }
515
+ export interface ListValue {
516
+ kind: 'ListValue';
517
+ items: SettingValue[];
518
+ span: Span;
519
+ }
520
+ /** An inline `ref: > target.field` setting carries a small ref spec. */
521
+ export interface RefValue {
522
+ kind: 'RefValue';
523
+ operator: CardinalityOperator;
524
+ target: RefEndpoint;
525
+ span: Span;
526
+ }
527
+ export interface ParseOptions {
528
+ /**
529
+ * The absolute or canonical path of the file being parsed. Used as the
530
+ * base directory for relative `from './...'` paths in `use`/`reuse`
531
+ * directives. If undefined, relative paths in directives can only be
532
+ * resolved when they're already absolute (rare). For files loaded via
533
+ * `readFile`, the parser passes the resolved path automatically.
534
+ */
535
+ filePath?: string;
536
+ /**
537
+ * Synchronous file reader. Called by the parser when it needs to resolve
538
+ * a reference-only module directive. The argument is a resolved, stable
539
+ * key: an absolute path for local sources, or a normalized `https://` URL
540
+ * for remote (v0.3) sources (when a directive's `from` is a URL, or a
541
+ * relative reference inside a remote module resolves to one). The function
542
+ * should return the source text for that key, or throw if it is missing
543
+ * or unreadable.
544
+ *
545
+ * Because this reader is synchronous, a host that supports remote sources
546
+ * must return the fetched text from a cache it populated beforehand. The
547
+ * network fetch, and its SSRF / redirect / size / timeout obligations
548
+ * (spec §26.14.5), live in the host's resolver, not in the parser.
549
+ *
550
+ * If absent, reference-only directives fall back to the P4 rejection
551
+ * with a clear "no resolver available" message. Clone-block-bearing
552
+ * directives still work without a resolver because their content is
553
+ * embedded in the importing file.
554
+ */
555
+ readFile?: (pathOrUrl: string) => string;
556
+ /**
557
+ * Maximum recursion depth when resolving directives. Each `from` traversal
558
+ * deepens the stack by one; circular imports trigger the cycle-detection
559
+ * path BEFORE this counter increases (cycles produce a parsed directive
560
+ * with an empty clone, not a depth-limit error). The default (8) is
561
+ * generous for realistic module graphs and small enough to keep the
562
+ * stack bounded under pathological inputs.
563
+ */
564
+ maxDepth?: number;
565
+ }
package/dist/ast.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * xDBML AST node types.
3
+ *
4
+ * The AST is intentionally narrow: each node carries only what's needed
5
+ * to round-trip xDBML source and to feed a downstream lowering pass
6
+ * (DDL emitters, JSON Schema emitters, etc.). Generic open-vocabulary
7
+ * settings are kept as Setting nodes rather than promoted to typed
8
+ * fields, because the spec leaves the settings vocabulary open.
9
+ */
10
+ export {};
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @xdbml/parse -- proof-of-concept parser for xDBML v0.1 and v0.2.
3
+ *
4
+ * Public API:
5
+ *
6
+ * parse(source, options?): XDbmlDocument
7
+ * Parse an xDBML document. Returns a fully-typed AST. Passing
8
+ * `options.readFile` enables cross-file `use`/`reuse` resolution
9
+ * (see ParseOptions for details).
10
+ *
11
+ * tokenize(source): Token[]
12
+ * Tokenize the source without parsing. Useful for syntax highlighting.
13
+ *
14
+ * flatten(doc): XDbmlDocument
15
+ * Produce a flattened view of a document where ModuleImportDirective
16
+ * nodes have been replaced by their clone-block content. Useful for
17
+ * downstream consumers that don't care about module provenance.
18
+ *
19
+ * resolveNames(doc): ResolutionResult
20
+ * Run the name-resolution pass. Returns a symbol table for queries
21
+ * and a list of diagnostics (unresolved references, name conflicts).
22
+ * The AST is not mutated. Flattens the input internally.
23
+ *
24
+ * The parser is DBML-3.13.6 compatible: a document without an `xdbml: ...`
25
+ * version header still parses, and DBML constructs are preserved.
26
+ */
27
+ export * from './ast.ts';
28
+ export { tokenize, TokenKind, LexError } from './lexer.ts';
29
+ export type { Token } from './lexer.ts';
30
+ export { parse, Parser, ParseError } from './parser.ts';
31
+ export { flatten } from './module-resolver.ts';
32
+ export { classifyModuleSource, isUrlKey, ModuleSourceError, } from './module-resolver.ts';
33
+ export type { ModuleSource } from './module-resolver.ts';
34
+ export { resolveNames, SymbolTable } from './name-resolver.ts';
35
+ export type { Diagnostic, DiagnosticCode, ResolutionResult, SymbolEntry, SymbolKind, } from './name-resolver.ts';
36
+ export { xdbmlLanguageConfig, xdbmlMonarchTokensProvider, } from './monarch.ts';
37
+ export type { XDbmlLanguageConfiguration, XDbmlMonarchLanguage, } from './monarch.ts';
package/dist/index.js ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @xdbml/parse -- proof-of-concept parser for xDBML v0.1 and v0.2.
3
+ *
4
+ * Public API:
5
+ *
6
+ * parse(source, options?): XDbmlDocument
7
+ * Parse an xDBML document. Returns a fully-typed AST. Passing
8
+ * `options.readFile` enables cross-file `use`/`reuse` resolution
9
+ * (see ParseOptions for details).
10
+ *
11
+ * tokenize(source): Token[]
12
+ * Tokenize the source without parsing. Useful for syntax highlighting.
13
+ *
14
+ * flatten(doc): XDbmlDocument
15
+ * Produce a flattened view of a document where ModuleImportDirective
16
+ * nodes have been replaced by their clone-block content. Useful for
17
+ * downstream consumers that don't care about module provenance.
18
+ *
19
+ * resolveNames(doc): ResolutionResult
20
+ * Run the name-resolution pass. Returns a symbol table for queries
21
+ * and a list of diagnostics (unresolved references, name conflicts).
22
+ * The AST is not mutated. Flattens the input internally.
23
+ *
24
+ * The parser is DBML-3.13.6 compatible: a document without an `xdbml: ...`
25
+ * version header still parses, and DBML constructs are preserved.
26
+ */
27
+ export * from "./ast.js";
28
+ export { tokenize, TokenKind, LexError } from "./lexer.js";
29
+ export { parse, Parser, ParseError } from "./parser.js";
30
+ export { flatten } from "./module-resolver.js";
31
+ export { classifyModuleSource, isUrlKey, ModuleSourceError, } from "./module-resolver.js";
32
+ export { resolveNames, SymbolTable } from "./name-resolver.js";
33
+ export { xdbmlLanguageConfig, xdbmlMonarchTokensProvider, } from "./monarch.js";
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Shared keyword vocabulary for xDBML tokenizers and highlighters.
3
+ *
4
+ * This module is the single source of truth for the keyword lists
5
+ * that drive syntax highlighting across multiple surfaces:
6
+ *
7
+ * - parser/src/monarch.ts the playground's in-editor highlighter
8
+ * - tools/textmate/... the TextMate grammar for VS Code,
9
+ * Shiki (xdbml.org code blocks, Claude
10
+ * chat code blocks, etc.), and GitHub
11
+ *
12
+ * The grammar in grammar/xDBML.g4 is the language's canonical
13
+ * specification; this file mirrors its keyword vocabulary in a form
14
+ * convenient for consumers. A keyword-consistency test (in
15
+ * parser/test/) asserts that every keyword listed here is recognized
16
+ * by the parser.
17
+ *
18
+ * When adding a keyword to xDBML:
19
+ * 1. Update the grammar in grammar/xDBML.g4
20
+ * 2. Update parser/src/parser.ts if the parser needs to recognize it
21
+ * 3. Add it to the right array below
22
+ * 4. Re-run the TextMate grammar build script
23
+ * (tools/textmate/scripts/build.mjs)
24
+ * 5. Run `npm test` in the parser package to verify all three
25
+ * consumers see the keyword
26
+ *
27
+ * All keywords here are case-insensitive in xDBML. Stored in
28
+ * lower-case as the canonical form; matchers should be case-insensitive.
29
+ */
30
+ export declare const CONTAINER_KEYWORDS: readonly ["container", "schema", "database", "keyspace", "namespace", "dataset", "bucket"];
31
+ export declare const ENTITY_KEYWORDS: readonly ["table", "entity", "collection", "record"];
32
+ /**
33
+ * The full set of declaration keywords. Includes containers,
34
+ * entities, and other top-level constructs.
35
+ */
36
+ export declare const DECLARATION_KEYWORDS: readonly ["project", "container", "schema", "database", "keyspace", "namespace", "dataset", "bucket", "table", "entity", "collection", "record", "type", "edge", "view", "enum", "ref", "note", "tablepartial", "tablegroup", "diagramview"];
37
+ export declare const STRUCTURAL_TYPE_KEYWORDS: readonly ["object", "struct", "array", "list", "map", "dict", "dictionary", "set", "json", "jsonb", "variant"];
38
+ export declare const POLYMORPHISM_KEYWORDS: readonly ["union", "oneof", "anyof", "allof"];
39
+ export declare const SCALAR_TYPES: readonly ["tinyint", "smallint", "mediumint", "int", "integer", "bigint", "int32", "int64", "float", "double", "decimal", "dec", "numeric", "real", "bit", "bool", "boolean", "char", "varchar", "varchar2", "nvarchar", "nvarchar2", "nchar", "text", "mediumtext", "longtext", "string", "ntext", "binary", "varbinary", "blob", "mediumblob", "longblob", "tinyblob", "tinytext", "json", "jsonb", "variant", "xml", "date", "time", "datetime", "datetime2", "timestamp", "timestamptz", "year", "uuid", "inet6", "money", "smallmoney", "enum"];
40
+ export declare const BSON_TYPES: readonly ["objectid", "decimal128", "bindata", "minkey", "maxkey", "symbol", "regex", "long", "double"];
41
+ export declare const SETTING_FLAGS: readonly ["pk", "primary", "key", "unique", "null", "not", "required", "increment", "inactive"];
42
+ export declare const SETTING_KEYS: readonly ["note", "default", "ref", "name", "color", "headercolor", "as", "check", "type", "target", "targets", "database_type", "source", "source_cardinality", "target_cardinality", "min_source", "max_source", "min_target", "max_target", "undirected", "discriminator", "source_query", "materialized", "refresh_schedule", "refresh_on", "source_database", "storage_options", "pattern", "format", "minlength", "maxlength", "minimum", "maximum", "exclusiveminimum", "exclusivemaximum", "multipleof", "minitems", "maxitems", "uniqueitems", "minproperties", "maxproperties", "synonyms", "business_term", "granularity", "tags", "delete", "update", "indexes", "checks", "replication", "location", "default_charset", "cloned_at"];
43
+ export declare const GRANULARITY_VALUES: readonly ["year", "quarter", "month", "week", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond"];
44
+ export declare const DIRECTIVE_KEYWORDS: readonly ["xdbml", "experimental"];
45
+ export declare const MODULE_KEYWORDS: readonly ["use", "reuse", "from", "as"];