@vasp-framework/parser 0.1.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.
@@ -0,0 +1,49 @@
1
+ export var TokenType;
2
+ (function (TokenType) {
3
+ // Keywords (top-level block starters)
4
+ TokenType["KW_APP"] = "app";
5
+ TokenType["KW_AUTH"] = "auth";
6
+ TokenType["KW_ROUTE"] = "route";
7
+ TokenType["KW_PAGE"] = "page";
8
+ TokenType["KW_QUERY"] = "query";
9
+ TokenType["KW_ACTION"] = "action";
10
+ TokenType["KW_CRUD"] = "crud";
11
+ TokenType["KW_REALTIME"] = "realtime";
12
+ TokenType["KW_JOB"] = "job";
13
+ // Value-position keywords
14
+ TokenType["KW_IMPORT"] = "import";
15
+ TokenType["KW_FROM"] = "from";
16
+ // Literals
17
+ TokenType["IDENTIFIER"] = "IDENTIFIER";
18
+ TokenType["STRING"] = "STRING";
19
+ TokenType["BOOLEAN"] = "BOOLEAN";
20
+ TokenType["NUMBER"] = "NUMBER";
21
+ // Punctuation
22
+ TokenType["LBRACE"] = "{";
23
+ TokenType["RBRACE"] = "}";
24
+ TokenType["LBRACKET"] = "[";
25
+ TokenType["RBRACKET"] = "]";
26
+ TokenType["COLON"] = ":";
27
+ TokenType["COMMA"] = ",";
28
+ // Meta
29
+ TokenType["EOF"] = "EOF";
30
+ })(TokenType || (TokenType = {}));
31
+ /** Keywords that start a top-level declaration block */
32
+ export const BLOCK_KEYWORDS = new Set([
33
+ TokenType.KW_APP,
34
+ TokenType.KW_AUTH,
35
+ TokenType.KW_ROUTE,
36
+ TokenType.KW_PAGE,
37
+ TokenType.KW_QUERY,
38
+ TokenType.KW_ACTION,
39
+ TokenType.KW_CRUD,
40
+ TokenType.KW_REALTIME,
41
+ TokenType.KW_JOB,
42
+ ]);
43
+ /** All reserved keywords (cannot be used as identifiers in value position) */
44
+ export const ALL_KEYWORDS = new Set([
45
+ ...BLOCK_KEYWORDS,
46
+ TokenType.KW_IMPORT,
47
+ TokenType.KW_FROM,
48
+ ]);
49
+ //# sourceMappingURL=TokenType.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenType.js","sourceRoot":"","sources":["../../src/lexer/TokenType.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,SAgCX;AAhCD,WAAY,SAAS;IACnB,sCAAsC;IACtC,2BAAc,CAAA;IACd,6BAAgB,CAAA;IAChB,+BAAkB,CAAA;IAClB,6BAAgB,CAAA;IAChB,+BAAkB,CAAA;IAClB,iCAAoB,CAAA;IACpB,6BAAgB,CAAA;IAChB,qCAAwB,CAAA;IACxB,2BAAc,CAAA;IAEd,0BAA0B;IAC1B,iCAAoB,CAAA;IACpB,6BAAgB,CAAA;IAEhB,WAAW;IACX,sCAAyB,CAAA;IACzB,8BAAiB,CAAA;IACjB,gCAAmB,CAAA;IACnB,8BAAiB,CAAA;IAEjB,cAAc;IACd,yBAAY,CAAA;IACZ,yBAAY,CAAA;IACZ,2BAAc,CAAA;IACd,2BAAc,CAAA;IACd,wBAAW,CAAA;IACX,wBAAW,CAAA;IAEX,OAAO;IACP,wBAAW,CAAA;AACb,CAAC,EAhCW,SAAS,KAAT,SAAS,QAgCpB;AAED,wDAAwD;AACxD,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,GAAG,CAAS;IAC5C,SAAS,CAAC,MAAM;IAChB,SAAS,CAAC,OAAO;IACjB,SAAS,CAAC,QAAQ;IAClB,SAAS,CAAC,OAAO;IACjB,SAAS,CAAC,QAAQ;IAClB,SAAS,CAAC,SAAS;IACnB,SAAS,CAAC,OAAO;IACjB,SAAS,CAAC,WAAW;IACrB,SAAS,CAAC,MAAM;CACjB,CAAC,CAAA;AAEF,8EAA8E;AAC9E,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAS;IAC1C,GAAG,cAAc;IACjB,SAAS,CAAC,SAAS;IACnB,SAAS,CAAC,OAAO;CAClB,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { VaspAST } from '@vasp-framework/core';
2
+ export declare function parse(source: string, filename?: string): VaspAST;
3
+ //# sourceMappingURL=Parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Parser.d.ts","sourceRoot":"","sources":["../../src/parser/Parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAeV,OAAO,EACR,MAAM,sBAAsB,CAAA;AAM7B,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAc,GAAG,OAAO,CAGrE"}
@@ -0,0 +1,408 @@
1
+ import { ParseError } from '@vasp-framework/core';
2
+ import { Lexer } from '../lexer/Lexer.js';
3
+ import { TokenType } from '../lexer/TokenType.js';
4
+ export function parse(source, filename = 'main.vasp') {
5
+ const tokens = new Lexer(source, filename).tokenize();
6
+ return new Parser(tokens, filename).parse();
7
+ }
8
+ class Parser {
9
+ tokens;
10
+ filename;
11
+ pos = 0;
12
+ constructor(tokens, filename) {
13
+ this.tokens = tokens;
14
+ this.filename = filename;
15
+ }
16
+ // ---- Public ----
17
+ parse() {
18
+ const ast = {
19
+ app: null, // validated by SemanticValidator
20
+ routes: [],
21
+ pages: [],
22
+ queries: [],
23
+ actions: [],
24
+ cruds: [],
25
+ realtimes: [],
26
+ jobs: [],
27
+ };
28
+ while (!this.isEOF()) {
29
+ const kw = this.peek();
30
+ switch (kw.type) {
31
+ case TokenType.KW_APP:
32
+ ast.app = this.parseApp();
33
+ break;
34
+ case TokenType.KW_AUTH:
35
+ ast.auth = this.parseAuth();
36
+ break;
37
+ case TokenType.KW_ROUTE:
38
+ ast.routes.push(this.parseRoute());
39
+ break;
40
+ case TokenType.KW_PAGE:
41
+ ast.pages.push(this.parsePage());
42
+ break;
43
+ case TokenType.KW_QUERY:
44
+ ast.queries.push(this.parseQuery());
45
+ break;
46
+ case TokenType.KW_ACTION:
47
+ ast.actions.push(this.parseAction());
48
+ break;
49
+ case TokenType.KW_CRUD:
50
+ ast.cruds.push(this.parseCrud());
51
+ break;
52
+ case TokenType.KW_REALTIME:
53
+ ast.realtimes.push(this.parseRealtime());
54
+ break;
55
+ case TokenType.KW_JOB:
56
+ ast.jobs.push(this.parseJob());
57
+ break;
58
+ default:
59
+ throw this.error('E010_UNEXPECTED_TOKEN', `Unexpected token '${kw.value}' at top level`, 'Expected a declaration keyword: app, auth, route, page, query, action, crud, realtime, or job', kw.loc);
60
+ }
61
+ }
62
+ return ast;
63
+ }
64
+ // ---- Block parsers ----
65
+ parseApp() {
66
+ const loc = this.consume(TokenType.KW_APP).loc;
67
+ const name = this.consumeIdentifier();
68
+ this.consume(TokenType.LBRACE);
69
+ let title = '';
70
+ let db = 'Drizzle';
71
+ let ssr = false;
72
+ let typescript = false;
73
+ while (!this.check(TokenType.RBRACE)) {
74
+ const key = this.consumeIdentifier();
75
+ this.consume(TokenType.COLON);
76
+ switch (key.value) {
77
+ case 'title':
78
+ title = this.consumeString();
79
+ break;
80
+ case 'db':
81
+ db = this.consumeIdentifier().value;
82
+ break;
83
+ case 'ssr': {
84
+ const val = this.peek();
85
+ if (val.type === TokenType.BOOLEAN) {
86
+ ssr = this.consume(TokenType.BOOLEAN).value === 'true';
87
+ }
88
+ else if (val.type === TokenType.STRING) {
89
+ const s = this.consumeString();
90
+ if (s !== 'ssg') {
91
+ throw this.error('E011_INVALID_SSR', `Invalid ssr value "${s}"`, 'Use: false, true, or "ssg"', val.loc);
92
+ }
93
+ ssr = 'ssg';
94
+ }
95
+ else {
96
+ throw this.error('E011_INVALID_SSR', 'Invalid ssr value', 'Use: false, true, or "ssg"', val.loc);
97
+ }
98
+ break;
99
+ }
100
+ case 'typescript':
101
+ typescript = this.consume(TokenType.BOOLEAN).value === 'true';
102
+ break;
103
+ default:
104
+ throw this.error('E012_UNKNOWN_PROP', `Unknown app property '${key.value}'`, 'Valid properties: title, db, ssr, typescript', key.loc);
105
+ }
106
+ }
107
+ this.consume(TokenType.RBRACE);
108
+ return { type: 'App', name: name.value, loc, title, db, ssr, typescript };
109
+ }
110
+ parseAuth() {
111
+ const loc = this.consume(TokenType.KW_AUTH).loc;
112
+ const name = this.consumeIdentifier();
113
+ this.consume(TokenType.LBRACE);
114
+ let userEntity = '';
115
+ let methods = [];
116
+ while (!this.check(TokenType.RBRACE)) {
117
+ const key = this.consumeIdentifier();
118
+ this.consume(TokenType.COLON);
119
+ switch (key.value) {
120
+ case 'userEntity':
121
+ userEntity = this.consumeIdentifier().value;
122
+ break;
123
+ case 'methods':
124
+ methods = this.parseIdentifierArray();
125
+ break;
126
+ default:
127
+ throw this.error('E013_UNKNOWN_PROP', `Unknown auth property '${key.value}'`, 'Valid properties: userEntity, methods', key.loc);
128
+ }
129
+ }
130
+ this.consume(TokenType.RBRACE);
131
+ return { type: 'Auth', name: name.value, loc, userEntity, methods };
132
+ }
133
+ parseRoute() {
134
+ const loc = this.consume(TokenType.KW_ROUTE).loc;
135
+ const name = this.consumeIdentifier();
136
+ this.consume(TokenType.LBRACE);
137
+ let path = '';
138
+ let to = '';
139
+ while (!this.check(TokenType.RBRACE)) {
140
+ const key = this.consumeIdentifier();
141
+ this.consume(TokenType.COLON);
142
+ switch (key.value) {
143
+ case 'path':
144
+ path = this.consumeString();
145
+ break;
146
+ case 'to':
147
+ to = this.consumeIdentifier().value;
148
+ break;
149
+ default:
150
+ throw this.error('E014_UNKNOWN_PROP', `Unknown route property '${key.value}'`, 'Valid properties: path, to', key.loc);
151
+ }
152
+ }
153
+ this.consume(TokenType.RBRACE);
154
+ return { type: 'Route', name: name.value, loc, path, to };
155
+ }
156
+ parsePage() {
157
+ const loc = this.consume(TokenType.KW_PAGE).loc;
158
+ const name = this.consumeIdentifier();
159
+ this.consume(TokenType.LBRACE);
160
+ let component = null;
161
+ while (!this.check(TokenType.RBRACE)) {
162
+ const key = this.consumeIdentifier();
163
+ this.consume(TokenType.COLON);
164
+ switch (key.value) {
165
+ case 'component':
166
+ component = this.parseImportExpression();
167
+ break;
168
+ default:
169
+ throw this.error('E015_UNKNOWN_PROP', `Unknown page property '${key.value}'`, 'Valid properties: component', key.loc);
170
+ }
171
+ }
172
+ this.consume(TokenType.RBRACE);
173
+ if (!component) {
174
+ throw this.error('E016_MISSING_COMPONENT', `Page '${name.value}' is missing a component`, 'Add: component: import Foo from "@src/pages/Foo.vue"', loc);
175
+ }
176
+ return { type: 'Page', name: name.value, loc, component };
177
+ }
178
+ parseQuery() {
179
+ const loc = this.consume(TokenType.KW_QUERY).loc;
180
+ const name = this.consumeIdentifier();
181
+ this.consume(TokenType.LBRACE);
182
+ let fn = null;
183
+ let entities = [];
184
+ let auth = false;
185
+ while (!this.check(TokenType.RBRACE)) {
186
+ const key = this.consumeIdentifier();
187
+ this.consume(TokenType.COLON);
188
+ switch (key.value) {
189
+ case 'fn':
190
+ fn = this.parseImportExpression();
191
+ break;
192
+ case 'entities':
193
+ entities = this.parseIdentifierArray();
194
+ break;
195
+ case 'auth':
196
+ auth = this.consume(TokenType.BOOLEAN).value === 'true';
197
+ break;
198
+ default:
199
+ throw this.error('E017_UNKNOWN_PROP', `Unknown query property '${key.value}'`, 'Valid properties: fn, entities, auth', key.loc);
200
+ }
201
+ }
202
+ this.consume(TokenType.RBRACE);
203
+ if (!fn) {
204
+ throw this.error('E018_MISSING_FN', `Query '${name.value}' is missing fn`, 'Add: fn: import { myFn } from "@src/queries.js"', loc);
205
+ }
206
+ return { type: 'Query', name: name.value, loc, fn, entities, auth };
207
+ }
208
+ parseAction() {
209
+ const loc = this.consume(TokenType.KW_ACTION).loc;
210
+ const name = this.consumeIdentifier();
211
+ this.consume(TokenType.LBRACE);
212
+ let fn = null;
213
+ let entities = [];
214
+ let auth = false;
215
+ while (!this.check(TokenType.RBRACE)) {
216
+ const key = this.consumeIdentifier();
217
+ this.consume(TokenType.COLON);
218
+ switch (key.value) {
219
+ case 'fn':
220
+ fn = this.parseImportExpression();
221
+ break;
222
+ case 'entities':
223
+ entities = this.parseIdentifierArray();
224
+ break;
225
+ case 'auth':
226
+ auth = this.consume(TokenType.BOOLEAN).value === 'true';
227
+ break;
228
+ default:
229
+ throw this.error('E019_UNKNOWN_PROP', `Unknown action property '${key.value}'`, 'Valid properties: fn, entities, auth', key.loc);
230
+ }
231
+ }
232
+ this.consume(TokenType.RBRACE);
233
+ if (!fn) {
234
+ throw this.error('E020_MISSING_FN', `Action '${name.value}' is missing fn`, 'Add: fn: import { myFn } from "@src/actions.js"', loc);
235
+ }
236
+ return { type: 'Action', name: name.value, loc, fn, entities, auth };
237
+ }
238
+ parseCrud() {
239
+ const loc = this.consume(TokenType.KW_CRUD).loc;
240
+ const name = this.consumeIdentifier();
241
+ this.consume(TokenType.LBRACE);
242
+ let entity = '';
243
+ let operations = [];
244
+ while (!this.check(TokenType.RBRACE)) {
245
+ const key = this.consumeIdentifier();
246
+ this.consume(TokenType.COLON);
247
+ switch (key.value) {
248
+ case 'entity':
249
+ entity = this.consumeIdentifier().value;
250
+ break;
251
+ case 'operations':
252
+ operations = this.parseIdentifierArray();
253
+ break;
254
+ default:
255
+ throw this.error('E021_UNKNOWN_PROP', `Unknown crud property '${key.value}'`, 'Valid properties: entity, operations', key.loc);
256
+ }
257
+ }
258
+ this.consume(TokenType.RBRACE);
259
+ return { type: 'Crud', name: name.value, loc, entity, operations };
260
+ }
261
+ parseRealtime() {
262
+ const loc = this.consume(TokenType.KW_REALTIME).loc;
263
+ const name = this.consumeIdentifier();
264
+ this.consume(TokenType.LBRACE);
265
+ let entity = '';
266
+ let events = [];
267
+ while (!this.check(TokenType.RBRACE)) {
268
+ const key = this.consumeIdentifier();
269
+ this.consume(TokenType.COLON);
270
+ switch (key.value) {
271
+ case 'entity':
272
+ entity = this.consumeIdentifier().value;
273
+ break;
274
+ case 'events':
275
+ events = this.parseIdentifierArray();
276
+ break;
277
+ default:
278
+ throw this.error('E022_UNKNOWN_PROP', `Unknown realtime property '${key.value}'`, 'Valid properties: entity, events', key.loc);
279
+ }
280
+ }
281
+ this.consume(TokenType.RBRACE);
282
+ return { type: 'Realtime', name: name.value, loc, entity, events };
283
+ }
284
+ parseJob() {
285
+ const loc = this.consume(TokenType.KW_JOB).loc;
286
+ const name = this.consumeIdentifier();
287
+ this.consume(TokenType.LBRACE);
288
+ let executor = 'PgBoss';
289
+ let performFn = null;
290
+ let schedule;
291
+ while (!this.check(TokenType.RBRACE)) {
292
+ const key = this.consumeIdentifier();
293
+ this.consume(TokenType.COLON);
294
+ switch (key.value) {
295
+ case 'executor':
296
+ executor = this.consumeIdentifier().value;
297
+ break;
298
+ case 'perform': {
299
+ // Nested block: perform: { fn: import ... }
300
+ this.consume(TokenType.LBRACE);
301
+ while (!this.check(TokenType.RBRACE)) {
302
+ const innerKey = this.consumeIdentifier();
303
+ this.consume(TokenType.COLON);
304
+ if (innerKey.value === 'fn') {
305
+ performFn = this.parseImportExpression();
306
+ }
307
+ else {
308
+ throw this.error('E023_UNKNOWN_PROP', `Unknown perform property '${innerKey.value}'`, 'Valid properties: fn', innerKey.loc);
309
+ }
310
+ }
311
+ this.consume(TokenType.RBRACE);
312
+ break;
313
+ }
314
+ case 'schedule':
315
+ schedule = this.consumeString();
316
+ break;
317
+ default:
318
+ throw this.error('E024_UNKNOWN_PROP', `Unknown job property '${key.value}'`, 'Valid properties: executor, perform, schedule', key.loc);
319
+ }
320
+ }
321
+ this.consume(TokenType.RBRACE);
322
+ if (!performFn) {
323
+ throw this.error('E025_MISSING_PERFORM', `Job '${name.value}' is missing perform.fn`, 'Add: perform: { fn: import { myJob } from "@src/jobs.js" }', loc);
324
+ }
325
+ return {
326
+ type: 'Job',
327
+ name: name.value,
328
+ loc,
329
+ executor,
330
+ perform: { fn: performFn },
331
+ ...(schedule !== undefined ? { schedule } : {}),
332
+ };
333
+ }
334
+ // ---- Value parsers ----
335
+ /**
336
+ * Parses both import forms:
337
+ * import Foo from "@src/..." → DefaultImportExpression
338
+ * import { foo } from "@src/..." → NamedImportExpression
339
+ */
340
+ parseImportExpression() {
341
+ const loc = this.consume(TokenType.KW_IMPORT).loc;
342
+ // Named import: import { foo } from "..."
343
+ if (this.check(TokenType.LBRACE)) {
344
+ this.consume(TokenType.LBRACE);
345
+ const namedExport = this.consumeIdentifier().value;
346
+ this.consume(TokenType.RBRACE);
347
+ this.consume(TokenType.KW_FROM);
348
+ const source = this.consumeString();
349
+ return { kind: 'named', namedExport, source };
350
+ }
351
+ // Default import: import Foo from "..."
352
+ const defaultExport = this.consumeIdentifier().value;
353
+ this.consume(TokenType.KW_FROM);
354
+ const source = this.consumeString();
355
+ return { kind: 'default', defaultExport, source };
356
+ }
357
+ /** Parses: [ Foo, Bar, Baz ] */
358
+ parseIdentifierArray() {
359
+ this.consume(TokenType.LBRACKET);
360
+ const items = [];
361
+ while (!this.check(TokenType.RBRACKET)) {
362
+ items.push(this.consumeIdentifier().value);
363
+ if (this.check(TokenType.COMMA)) {
364
+ this.consume(TokenType.COMMA);
365
+ }
366
+ }
367
+ this.consume(TokenType.RBRACKET);
368
+ return items;
369
+ }
370
+ // ---- Token cursor helpers ----
371
+ peek() {
372
+ return this.tokens[this.pos] ?? { type: TokenType.EOF, value: '', loc: { line: 0, col: 0, offset: 0 } };
373
+ }
374
+ check(type) {
375
+ return this.peek().type === type;
376
+ }
377
+ isEOF() {
378
+ return this.check(TokenType.EOF);
379
+ }
380
+ consume(type) {
381
+ const tok = this.peek();
382
+ if (tok.type !== type) {
383
+ throw this.error('E030_EXPECTED_TOKEN', `Expected '${type}' but got '${tok.value || tok.type}'`, `Add the missing '${type}'`, tok.loc);
384
+ }
385
+ this.pos++;
386
+ return tok;
387
+ }
388
+ consumeIdentifier() {
389
+ const tok = this.peek();
390
+ if (tok.type !== TokenType.IDENTIFIER) {
391
+ throw this.error('E031_EXPECTED_IDENTIFIER', `Expected an identifier but got '${tok.value || tok.type}'`, 'Provide a valid name (letters, digits, underscores)', tok.loc);
392
+ }
393
+ this.pos++;
394
+ return tok;
395
+ }
396
+ consumeString() {
397
+ const tok = this.peek();
398
+ if (tok.type !== TokenType.STRING) {
399
+ throw this.error('E032_EXPECTED_STRING', `Expected a string but got '${tok.value || tok.type}'`, 'Wrap the value in double quotes: "value"', tok.loc);
400
+ }
401
+ this.pos++;
402
+ return tok.value;
403
+ }
404
+ error(code, message, hint, loc) {
405
+ return new ParseError([{ code, message, hint, ...(loc !== undefined ? { loc } : {}) }]);
406
+ }
407
+ }
408
+ //# sourceMappingURL=Parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Parser.js","sourceRoot":"","sources":["../../src/parser/Parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { VaspAST } from '@vasp-framework/core';
2
+ export declare class SemanticValidator {
3
+ private readonly diagnostics;
4
+ validate(ast: VaspAST): void;
5
+ private checkAppExists;
6
+ private checkRouteTargets;
7
+ private checkCrudOperations;
8
+ private checkRealtimeEntities;
9
+ private checkAuthMethods;
10
+ private checkQueryActionEntities;
11
+ private checkJobExecutors;
12
+ }
13
+ //# sourceMappingURL=SemanticValidator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SemanticValidator.d.ts","sourceRoot":"","sources":["../../src/validator/SemanticValidator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAGpE,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAwB;IAEpD,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAc5B,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,mBAAmB;IAuB3B,OAAO,CAAC,qBAAqB;IAwB7B,OAAO,CAAC,gBAAgB;IAsBxB,OAAO,CAAC,wBAAwB;IA4BhC,OAAO,CAAC,iBAAiB;CAY1B"}
@@ -0,0 +1,145 @@
1
+ import { ParseError, SUPPORTED_AUTH_METHODS, SUPPORTED_CRUD_OPERATIONS, SUPPORTED_REALTIME_EVENTS } from '@vasp-framework/core';
2
+ export class SemanticValidator {
3
+ diagnostics = [];
4
+ validate(ast) {
5
+ this.checkAppExists(ast);
6
+ this.checkRouteTargets(ast);
7
+ this.checkCrudOperations(ast);
8
+ this.checkRealtimeEntities(ast);
9
+ this.checkAuthMethods(ast);
10
+ this.checkQueryActionEntities(ast);
11
+ this.checkJobExecutors(ast);
12
+ if (this.diagnostics.length > 0) {
13
+ throw new ParseError(this.diagnostics);
14
+ }
15
+ }
16
+ checkAppExists(ast) {
17
+ if (!ast.app) {
18
+ this.diagnostics.push({
19
+ code: 'E100_MISSING_APP_BLOCK',
20
+ message: 'No app block found in main.vasp',
21
+ hint: 'Every Vasp project requires exactly one app { } block',
22
+ });
23
+ }
24
+ }
25
+ checkRouteTargets(ast) {
26
+ const pageNames = new Set(ast.pages.map((p) => p.name));
27
+ for (const route of ast.routes) {
28
+ if (!pageNames.has(route.to)) {
29
+ this.diagnostics.push({
30
+ code: 'E101_UNKNOWN_PAGE_REF',
31
+ message: `Route '${route.name}' references unknown page '${route.to}'`,
32
+ hint: `Add a page block named '${route.to}', or fix the 'to' value in route '${route.name}'`,
33
+ loc: route.loc,
34
+ });
35
+ }
36
+ }
37
+ }
38
+ checkCrudOperations(ast) {
39
+ for (const crud of ast.cruds) {
40
+ if (crud.operations.length === 0) {
41
+ this.diagnostics.push({
42
+ code: 'E102_EMPTY_CRUD_OPERATIONS',
43
+ message: `crud '${crud.name}' has no operations`,
44
+ hint: 'Add at least one operation: operations: [list, create, update, delete]',
45
+ loc: crud.loc,
46
+ });
47
+ }
48
+ for (const op of crud.operations) {
49
+ if (!SUPPORTED_CRUD_OPERATIONS.includes(op)) {
50
+ this.diagnostics.push({
51
+ code: 'E103_UNKNOWN_CRUD_OPERATION',
52
+ message: `Unknown crud operation '${op}' in '${crud.name}'`,
53
+ hint: `Supported operations: ${SUPPORTED_CRUD_OPERATIONS.join(', ')}`,
54
+ loc: crud.loc,
55
+ });
56
+ }
57
+ }
58
+ }
59
+ }
60
+ checkRealtimeEntities(ast) {
61
+ const crudEntities = new Set(ast.cruds.map((c) => c.entity));
62
+ for (const rt of ast.realtimes) {
63
+ if (!crudEntities.has(rt.entity)) {
64
+ this.diagnostics.push({
65
+ code: 'E104_REALTIME_ENTITY_NOT_CRUD',
66
+ message: `realtime '${rt.name}' references entity '${rt.entity}' which has no crud block`,
67
+ hint: `Add a crud block for entity '${rt.entity}', or remove the realtime block`,
68
+ loc: rt.loc,
69
+ });
70
+ }
71
+ for (const event of rt.events) {
72
+ if (!SUPPORTED_REALTIME_EVENTS.includes(event)) {
73
+ this.diagnostics.push({
74
+ code: 'E105_UNKNOWN_REALTIME_EVENT',
75
+ message: `Unknown realtime event '${event}' in '${rt.name}'`,
76
+ hint: `Supported events: ${SUPPORTED_REALTIME_EVENTS.join(', ')}`,
77
+ loc: rt.loc,
78
+ });
79
+ }
80
+ }
81
+ }
82
+ }
83
+ checkAuthMethods(ast) {
84
+ if (!ast.auth)
85
+ return;
86
+ if (ast.auth.methods.length === 0) {
87
+ this.diagnostics.push({
88
+ code: 'E106_EMPTY_AUTH_METHODS',
89
+ message: `auth '${ast.auth.name}' has no methods`,
90
+ hint: `Add at least one method: methods: [usernameAndPassword]`,
91
+ loc: ast.auth.loc,
92
+ });
93
+ }
94
+ for (const method of ast.auth.methods) {
95
+ if (!SUPPORTED_AUTH_METHODS.includes(method)) {
96
+ this.diagnostics.push({
97
+ code: 'E107_UNKNOWN_AUTH_METHOD',
98
+ message: `Unknown auth method '${method}'`,
99
+ hint: `Supported methods: ${SUPPORTED_AUTH_METHODS.join(', ')}`,
100
+ loc: ast.auth.loc,
101
+ });
102
+ }
103
+ }
104
+ }
105
+ checkQueryActionEntities(ast) {
106
+ const crudEntities = new Set(ast.cruds.map((c) => c.entity));
107
+ for (const query of ast.queries) {
108
+ for (const entity of query.entities) {
109
+ if (!crudEntities.has(entity)) {
110
+ this.diagnostics.push({
111
+ code: 'E108_UNKNOWN_ENTITY_REF',
112
+ message: `Query '${query.name}' references unknown entity '${entity}'`,
113
+ hint: `Add a crud block for entity '${entity}', or remove it from the entities list`,
114
+ loc: query.loc,
115
+ });
116
+ }
117
+ }
118
+ }
119
+ for (const action of ast.actions) {
120
+ for (const entity of action.entities) {
121
+ if (!crudEntities.has(entity)) {
122
+ this.diagnostics.push({
123
+ code: 'E109_UNKNOWN_ENTITY_REF',
124
+ message: `Action '${action.name}' references unknown entity '${entity}'`,
125
+ hint: `Add a crud block for entity '${entity}', or remove it from the entities list`,
126
+ loc: action.loc,
127
+ });
128
+ }
129
+ }
130
+ }
131
+ }
132
+ checkJobExecutors(ast) {
133
+ for (const job of ast.jobs) {
134
+ if (job.executor !== 'PgBoss') {
135
+ this.diagnostics.push({
136
+ code: 'E110_UNKNOWN_JOB_EXECUTOR',
137
+ message: `Unknown job executor '${job.executor}' in '${job.name}'`,
138
+ hint: 'Supported executors: PgBoss',
139
+ loc: job.loc,
140
+ });
141
+ }
142
+ }
143
+ }
144
+ }
145
+ //# sourceMappingURL=SemanticValidator.js.map