@vasp-framework/generator 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.
Files changed (63) hide show
  1. package/README.md +59 -0
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/GeneratorContext.d.ts +29 -0
  4. package/dist/GeneratorContext.d.ts.map +1 -0
  5. package/dist/GeneratorContext.js +39 -0
  6. package/dist/GeneratorContext.js.map +1 -0
  7. package/dist/generate.d.ts +3 -0
  8. package/dist/generate.d.ts.map +1 -0
  9. package/dist/generate.js +42 -0
  10. package/dist/generate.js.map +1 -0
  11. package/dist/generators/AuthGenerator.d.ts +5 -0
  12. package/dist/generators/AuthGenerator.d.ts.map +1 -0
  13. package/dist/generators/AuthGenerator.js +36 -0
  14. package/dist/generators/AuthGenerator.js.map +1 -0
  15. package/dist/generators/BackendGenerator.d.ts +5 -0
  16. package/dist/generators/BackendGenerator.d.ts.map +1 -0
  17. package/dist/generators/BackendGenerator.js +15 -0
  18. package/dist/generators/BackendGenerator.js.map +1 -0
  19. package/dist/generators/BaseGenerator.d.ts +13 -0
  20. package/dist/generators/BaseGenerator.d.ts.map +1 -0
  21. package/dist/generators/BaseGenerator.js +46 -0
  22. package/dist/generators/BaseGenerator.js.map +1 -0
  23. package/dist/generators/CrudGenerator.d.ts +5 -0
  24. package/dist/generators/CrudGenerator.d.ts.map +1 -0
  25. package/dist/generators/CrudGenerator.js +21 -0
  26. package/dist/generators/CrudGenerator.js.map +1 -0
  27. package/dist/generators/DrizzleSchemaGenerator.d.ts +5 -0
  28. package/dist/generators/DrizzleSchemaGenerator.d.ts.map +1 -0
  29. package/dist/generators/DrizzleSchemaGenerator.js +8 -0
  30. package/dist/generators/DrizzleSchemaGenerator.js.map +1 -0
  31. package/dist/generators/FrontendGenerator.d.ts +13 -0
  32. package/dist/generators/FrontendGenerator.d.ts.map +1 -0
  33. package/dist/generators/FrontendGenerator.js +141 -0
  34. package/dist/generators/FrontendGenerator.js.map +1 -0
  35. package/dist/generators/JobGenerator.d.ts +5 -0
  36. package/dist/generators/JobGenerator.d.ts.map +1 -0
  37. package/dist/generators/JobGenerator.js +25 -0
  38. package/dist/generators/JobGenerator.js.map +1 -0
  39. package/dist/generators/QueryActionGenerator.d.ts +6 -0
  40. package/dist/generators/QueryActionGenerator.d.ts.map +1 -0
  41. package/dist/generators/QueryActionGenerator.js +36 -0
  42. package/dist/generators/QueryActionGenerator.js.map +1 -0
  43. package/dist/generators/RealtimeGenerator.d.ts +5 -0
  44. package/dist/generators/RealtimeGenerator.d.ts.map +1 -0
  45. package/dist/generators/RealtimeGenerator.js +24 -0
  46. package/dist/generators/RealtimeGenerator.js.map +1 -0
  47. package/dist/generators/ScaffoldGenerator.d.ts +6 -0
  48. package/dist/generators/ScaffoldGenerator.d.ts.map +1 -0
  49. package/dist/generators/ScaffoldGenerator.js +99 -0
  50. package/dist/generators/ScaffoldGenerator.js.map +1 -0
  51. package/dist/index.d.ts +3 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +3 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/template/TemplateEngine.d.ts +30 -0
  56. package/dist/template/TemplateEngine.d.ts.map +1 -0
  57. package/dist/template/TemplateEngine.js +119 -0
  58. package/dist/template/TemplateEngine.js.map +1 -0
  59. package/dist/utils/fs.d.ts +5 -0
  60. package/dist/utils/fs.d.ts.map +1 -0
  61. package/dist/utils/fs.js +12 -0
  62. package/dist/utils/fs.js.map +1 -0
  63. package/package.json +38 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DrizzleSchemaGenerator.js","sourceRoot":"","sources":["../../src/generators/DrizzleSchemaGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,MAAM,OAAO,sBAAuB,SAAQ,aAAa;IACvD,GAAG;QACD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;QACpD,IAAI,CAAC,KAAK,CACR,kBAAkB,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,EAChC,IAAI,CAAC,MAAM,CAAC,2BAA2B,CAAC,CACzC,CAAA;IACH,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import { BaseGenerator } from './BaseGenerator.js';
2
+ export declare class FrontendGenerator extends BaseGenerator {
3
+ run(): void;
4
+ private generateSpa;
5
+ private generateSsr;
6
+ /** Converts a Vasp route path to a Nuxt pages/ file name.
7
+ * "/" → "index.vue", "/about" → "about.vue", "/users/:id" → "users/[id].vue" */
8
+ private routePathToNuxtFile;
9
+ private buildPagesMap;
10
+ private extractComponentName;
11
+ private scaffoldVuePage;
12
+ }
13
+ //# sourceMappingURL=FrontendGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FrontendGenerator.d.ts","sourceRoot":"","sources":["../../src/generators/FrontendGenerator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,qBAAa,iBAAkB,SAAQ,aAAa;IAClD,GAAG,IAAI,IAAI;IAUX,OAAO,CAAC,WAAW;IAoDnB,OAAO,CAAC,WAAW;IAoEnB;qFACiF;IACjF,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,eAAe;CASxB"}
@@ -0,0 +1,141 @@
1
+ import { DEFAULT_BACKEND_PORT, DEFAULT_SPA_PORT } from '@vasp-framework/core';
2
+ import { existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { BaseGenerator } from './BaseGenerator.js';
5
+ export class FrontendGenerator extends BaseGenerator {
6
+ run() {
7
+ this.ctx.logger.info(`Generating frontend (${this.ctx.mode} / ${this.ctx.ext})...`);
8
+ if (this.ctx.isSpa) {
9
+ this.generateSpa();
10
+ }
11
+ else {
12
+ this.generateSsr();
13
+ }
14
+ }
15
+ generateSpa() {
16
+ const { ext, ast } = this.ctx;
17
+ const data = {
18
+ backendPort: DEFAULT_BACKEND_PORT,
19
+ frontendPort: DEFAULT_SPA_PORT,
20
+ };
21
+ // Static files
22
+ this.write(`index.html`, this.render(`spa/${ext}/index.html.hbs`));
23
+ this.write(`vite.config.${ext}`, this.render(`spa/${ext}/vite.config.${ext}.hbs`, data));
24
+ // Vue app entry
25
+ this.write(`src/main.${ext}`, this.render(`spa/${ext}/src/main.${ext}.hbs`));
26
+ this.write(`src/App.vue`, this.render(`spa/${ext}/src/App.vue.hbs`));
27
+ // Router — build page component source map
28
+ const pagesMap = this.buildPagesMap();
29
+ this.write(`src/router/index.${ext}`, this.render(`spa/${ext}/src/router/index.${ext}.hbs`, { pagesMap }));
30
+ // Vasp plugin
31
+ this.write(`src/vasp/plugin.${ext}`, this.render(`spa/${ext}/src/vasp/plugin.${ext}.hbs`));
32
+ // Client SDK
33
+ this.write(`src/vasp/client/index.${ext}`, this.render(`spa/${ext}/src/vasp/client/index.${ext}.hbs`));
34
+ if (ast.queries.length > 0) {
35
+ this.write(`src/vasp/client/queries.${ext}`, this.render(`spa/${ext}/src/vasp/client/queries.${ext}.hbs`));
36
+ }
37
+ if (ast.actions.length > 0) {
38
+ this.write(`src/vasp/client/actions.${ext}`, this.render(`spa/${ext}/src/vasp/client/actions.${ext}.hbs`));
39
+ }
40
+ // TS-only: generate types.ts from entity schema + query/action signatures
41
+ if (this.ctx.isTypeScript && (ast.queries.length > 0 || ast.actions.length > 0 || ast.cruds.length > 0)) {
42
+ this.write(`src/vasp/client/types.ts`, this.render(`spa/ts/src/vasp/client/types.ts.hbs`));
43
+ }
44
+ // Scaffold empty page files if they don't exist
45
+ for (const page of ast.pages) {
46
+ const comp = page.component;
47
+ const src = comp.kind === 'default' ? comp.source : comp.source;
48
+ const relativePath = src.replace('@src/', 'src/');
49
+ const fullPath = join(this.ctx.outputDir, relativePath);
50
+ if (!existsSync(fullPath)) {
51
+ const pageName = comp.kind === 'default' ? comp.defaultExport : comp.namedExport;
52
+ this.write(relativePath, this.scaffoldVuePage(pageName));
53
+ }
54
+ }
55
+ }
56
+ generateSsr() {
57
+ const { ext, ast } = this.ctx;
58
+ const backendPort = DEFAULT_BACKEND_PORT;
59
+ const data = { backendPort };
60
+ // Nuxt config
61
+ this.write(`nuxt.config.${ext}`, this.render(`ssr/${ext}/nuxt.config.${ext}.hbs`, data));
62
+ // Root app component
63
+ this.write(`app.vue`, this.render(`ssr/${ext}/app.vue.hbs`));
64
+ // Dual-transport plugins
65
+ this.write(`plugins/vasp.server.${ext}`, this.render(`ssr/${ext}/plugins/vasp.server.${ext}.hbs`));
66
+ this.write(`plugins/vasp.client.${ext}`, this.render(`ssr/${ext}/plugins/vasp.client.${ext}.hbs`));
67
+ // Composables
68
+ this.write(`composables/useVasp.${ext}`, this.render(`ssr/${ext}/composables/useVasp.${ext}.hbs`));
69
+ // Auth composable + middleware (only when auth block present)
70
+ if (ast.auth) {
71
+ this.write(`composables/useAuth.${ext}`, this.render(`ssr/${ext}/composables/useAuth.${ext}.hbs`));
72
+ this.write(`middleware/auth.${ext}`, this.render(`ssr/${ext}/middleware/auth.${ext}.hbs`));
73
+ }
74
+ // Generate Nuxt pages from Vasp routes
75
+ const pagesMap = this.buildPagesMap();
76
+ for (const route of ast.routes) {
77
+ const pageFile = this.routePathToNuxtFile(route.path);
78
+ const componentSource = pagesMap[route.to];
79
+ if (!componentSource)
80
+ continue;
81
+ const componentName = this.extractComponentName(componentSource);
82
+ this.write(`pages/${pageFile}`, this.render(`ssr/${ext}/_page.vue.hbs`, { componentName, componentSource }));
83
+ }
84
+ // Auth login/register pages
85
+ if (ast.auth) {
86
+ this.write(`pages/login.vue`, this.render(`ssr/${ext}/_page.vue.hbs`, {
87
+ componentName: 'LoginPage',
88
+ componentSource: '@src/pages/Login.vue',
89
+ }));
90
+ this.write(`pages/register.vue`, this.render(`ssr/${ext}/_page.vue.hbs`, {
91
+ componentName: 'RegisterPage',
92
+ componentSource: '@src/pages/Register.vue',
93
+ }));
94
+ }
95
+ // Scaffold empty src/pages/ component files if they don't exist
96
+ for (const page of ast.pages) {
97
+ const comp = page.component;
98
+ const src = comp.kind === 'default' ? comp.source : comp.source;
99
+ const relativePath = src.replace('@src/', 'src/');
100
+ const fullPath = join(this.ctx.outputDir, relativePath);
101
+ if (!existsSync(fullPath)) {
102
+ const pageName = comp.kind === 'default' ? comp.defaultExport : comp.namedExport;
103
+ this.write(relativePath, this.scaffoldVuePage(pageName));
104
+ }
105
+ }
106
+ }
107
+ /** Converts a Vasp route path to a Nuxt pages/ file name.
108
+ * "/" → "index.vue", "/about" → "about.vue", "/users/:id" → "users/[id].vue" */
109
+ routePathToNuxtFile(path) {
110
+ if (path === '/')
111
+ return 'index.vue';
112
+ // Replace Express-style :param with Nuxt [param]
113
+ const normalized = path
114
+ .replace(/^\//, '')
115
+ .replace(/:([^/]+)/g, '[$1]');
116
+ return `${normalized}.vue`;
117
+ }
118
+ buildPagesMap() {
119
+ const map = {};
120
+ for (const page of this.ctx.ast.pages) {
121
+ const src = page.component.kind === 'default' ? page.component.source : page.component.source;
122
+ map[page.name] = src;
123
+ }
124
+ return map;
125
+ }
126
+ extractComponentName(source) {
127
+ // "@src/pages/Home.vue" → "Home"
128
+ const basename = source.split('/').pop() ?? source;
129
+ return basename.replace(/\.vue$/, '');
130
+ }
131
+ scaffoldVuePage(name) {
132
+ return `<template>
133
+ <div>
134
+ <h1>${name}</h1>
135
+ <p>Edit this page in src/pages/</p>
136
+ </div>
137
+ </template>
138
+ `;
139
+ }
140
+ }
141
+ //# sourceMappingURL=FrontendGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FrontendGenerator.js","sourceRoot":"","sources":["../../src/generators/FrontendGenerator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { BaseGenerator } from './BaseGenerator.js';
2
+ export declare class JobGenerator extends BaseGenerator {
3
+ run(): void;
4
+ }
5
+ //# sourceMappingURL=JobGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobGenerator.d.ts","sourceRoot":"","sources":["../../src/generators/JobGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAGlD,qBAAa,YAAa,SAAQ,aAAa;IAC7C,GAAG,IAAI,IAAI;CA8BZ"}
@@ -0,0 +1,25 @@
1
+ import { BaseGenerator } from './BaseGenerator.js';
2
+ import { toCamelCase } from '../template/TemplateEngine.js';
3
+ export class JobGenerator extends BaseGenerator {
4
+ run() {
5
+ const { ast, ext } = this.ctx;
6
+ if (ast.jobs.length === 0)
7
+ return;
8
+ this.ctx.logger.info('Generating background jobs...');
9
+ // PgBoss singleton
10
+ this.write(`server/jobs/boss.${ext}`, this.render('shared/jobs/boss.hbs'));
11
+ // One worker file per job
12
+ for (const job of ast.jobs) {
13
+ const fn = job.perform.fn;
14
+ const namedExport = fn.kind === 'named' ? fn.namedExport : fn.defaultExport;
15
+ this.write(`server/jobs/${toCamelCase(job.name)}.${ext}`, this.render('shared/jobs/_job.hbs', {
16
+ name: job.name,
17
+ namedExport,
18
+ fnSource: fn.source,
19
+ }));
20
+ // HTTP endpoint to schedule this job
21
+ this.write(`server/routes/jobs/${toCamelCase(job.name)}Schedule.${ext}`, this.render('shared/server/routes/jobs/_schedule.hbs', { name: job.name }));
22
+ }
23
+ }
24
+ }
25
+ //# sourceMappingURL=JobGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobGenerator.js","sourceRoot":"","sources":["../../src/generators/JobGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAE3D,MAAM,OAAO,YAAa,SAAQ,aAAa;IAC7C,GAAG;QACD,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAA;QAC7B,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAEjC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAA;QAErD,mBAAmB;QACnB,IAAI,CAAC,KAAK,CAAC,oBAAoB,GAAG,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAA;QAE1E,0BAA0B;QAC1B,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YAC3B,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,CAAA;YACzB,MAAM,WAAW,GAAG,EAAE,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAA;YAE3E,IAAI,CAAC,KAAK,CACR,eAAe,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,EAC7C,IAAI,CAAC,MAAM,CAAC,sBAAsB,EAAE;gBAClC,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,WAAW;gBACX,QAAQ,EAAE,EAAE,CAAC,MAAM;aACpB,CAAC,CACH,CAAA;YAED,qCAAqC;YACrC,IAAI,CAAC,KAAK,CACR,sBAAsB,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,GAAG,EAAE,EAC5D,IAAI,CAAC,MAAM,CAAC,yCAAyC,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAC3E,CAAA;QACH,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ import { BaseGenerator } from './BaseGenerator.js';
2
+ export declare class QueryActionGenerator extends BaseGenerator {
3
+ run(): void;
4
+ private camel;
5
+ }
6
+ //# sourceMappingURL=QueryActionGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryActionGenerator.d.ts","sourceRoot":"","sources":["../../src/generators/QueryActionGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,qBAAa,oBAAqB,SAAQ,aAAa;IACrD,GAAG,IAAI,IAAI;IAwCX,OAAO,CAAC,KAAK;CAId"}
@@ -0,0 +1,36 @@
1
+ import { BaseGenerator } from './BaseGenerator.js';
2
+ export class QueryActionGenerator extends BaseGenerator {
3
+ run() {
4
+ const { ast, ext } = this.ctx;
5
+ if (ast.queries.length > 0 || ast.actions.length > 0) {
6
+ this.ctx.logger.info('Generating query/action routes...');
7
+ }
8
+ for (const query of ast.queries) {
9
+ const fn = query.fn;
10
+ const namedExport = fn.kind === 'named' ? fn.namedExport : fn.defaultExport;
11
+ const fnSource = fn.source;
12
+ this.write(`server/routes/queries/${this.camel(query.name)}.${ext}`, this.render('shared/server/routes/queries/_query.hbs', {
13
+ name: query.name,
14
+ namedExport,
15
+ fnSource,
16
+ requiresAuth: query.auth,
17
+ }));
18
+ }
19
+ for (const action of ast.actions) {
20
+ const fn = action.fn;
21
+ const namedExport = fn.kind === 'named' ? fn.namedExport : fn.defaultExport;
22
+ const fnSource = fn.source;
23
+ this.write(`server/routes/actions/${this.camel(action.name)}.${ext}`, this.render('shared/server/routes/actions/_action.hbs', {
24
+ name: action.name,
25
+ namedExport,
26
+ fnSource,
27
+ requiresAuth: action.auth,
28
+ }));
29
+ }
30
+ }
31
+ camel(str) {
32
+ return str.replace(/[-_\s]+(.)/g, (_, c) => c.toUpperCase())
33
+ .replace(/^./, (c) => c.toLowerCase());
34
+ }
35
+ }
36
+ //# sourceMappingURL=QueryActionGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryActionGenerator.js","sourceRoot":"","sources":["../../src/generators/QueryActionGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,MAAM,OAAO,oBAAqB,SAAQ,aAAa;IACrD,GAAG;QACD,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAA;QAE7B,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAA;QAC3D,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAChC,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAA;YACnB,MAAM,WAAW,GAAG,EAAE,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAA;YAC3E,MAAM,QAAQ,GAAG,EAAE,CAAC,MAAM,CAAA;YAE1B,IAAI,CAAC,KAAK,CACR,yBAAyB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,EACxD,IAAI,CAAC,MAAM,CAAC,yCAAyC,EAAE;gBACrD,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,WAAW;gBACX,QAAQ;gBACR,YAAY,EAAE,KAAK,CAAC,IAAI;aACzB,CAAC,CACH,CAAA;QACH,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YACjC,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAA;YACpB,MAAM,WAAW,GAAG,EAAE,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAA;YAC3E,MAAM,QAAQ,GAAG,EAAE,CAAC,MAAM,CAAA;YAE1B,IAAI,CAAC,KAAK,CACR,yBAAyB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,EACzD,IAAI,CAAC,MAAM,CAAC,0CAA0C,EAAE;gBACtD,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,WAAW;gBACX,QAAQ;gBACR,YAAY,EAAE,MAAM,CAAC,IAAI;aAC1B,CAAC,CACH,CAAA;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,GAAW;QACvB,OAAO,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAS,EAAE,EAAE,CAAE,CAAY,CAAC,WAAW,EAAE,CAAC;aAC7E,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAA;IAC1C,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ import { BaseGenerator } from './BaseGenerator.js';
2
+ export declare class RealtimeGenerator extends BaseGenerator {
3
+ run(): void;
4
+ }
5
+ //# sourceMappingURL=RealtimeGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RealtimeGenerator.d.ts","sourceRoot":"","sources":["../../src/generators/RealtimeGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAGlD,qBAAa,iBAAkB,SAAQ,aAAa;IAClD,GAAG,IAAI,IAAI;CA+BZ"}
@@ -0,0 +1,24 @@
1
+ import { BaseGenerator } from './BaseGenerator.js';
2
+ import { toCamelCase } from '../template/TemplateEngine.js';
3
+ export class RealtimeGenerator extends BaseGenerator {
4
+ run() {
5
+ const { ast, ext } = this.ctx;
6
+ if (ast.realtimes.length === 0)
7
+ return;
8
+ this.ctx.logger.info('Generating realtime WebSocket channels...');
9
+ // Server: one file per channel + index barrel
10
+ for (const rt of ast.realtimes) {
11
+ this.write(`server/routes/realtime/${toCamelCase(rt.name)}.${ext}`, this.render('shared/server/routes/realtime/_channel.hbs', {
12
+ name: rt.name,
13
+ entity: rt.entity,
14
+ events: rt.events,
15
+ }));
16
+ }
17
+ this.write(`server/routes/realtime/index.${ext}`, this.render('shared/server/routes/realtime/index.hbs'));
18
+ // Client: useRealtime composable — SPA only (SSR realtime via WebSocket is handled client-side natively)
19
+ if (this.ctx.isSpa) {
20
+ this.write(`src/vasp/client/realtime.${ext}`, this.render(`spa/${ext}/src/vasp/client/realtime.${ext}.hbs`));
21
+ }
22
+ }
23
+ }
24
+ //# sourceMappingURL=RealtimeGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RealtimeGenerator.js","sourceRoot":"","sources":["../../src/generators/RealtimeGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAE3D,MAAM,OAAO,iBAAkB,SAAQ,aAAa;IAClD,GAAG;QACD,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAA;QAC7B,IAAI,GAAG,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAEtC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAA;QAEjE,8CAA8C;QAC9C,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC,KAAK,CACR,0BAA0B,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,EACvD,IAAI,CAAC,MAAM,CAAC,4CAA4C,EAAE;gBACxD,IAAI,EAAE,EAAE,CAAC,IAAI;gBACb,MAAM,EAAE,EAAE,CAAC,MAAM;gBACjB,MAAM,EAAE,EAAE,CAAC,MAAM;aAClB,CAAC,CACH,CAAA;QACH,CAAC;QAED,IAAI,CAAC,KAAK,CACR,gCAAgC,GAAG,EAAE,EACrC,IAAI,CAAC,MAAM,CAAC,yCAAyC,CAAC,CACvD,CAAA;QAED,yGAAyG;QACzG,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YACnB,IAAI,CAAC,KAAK,CACR,4BAA4B,GAAG,EAAE,EACjC,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,6BAA6B,GAAG,MAAM,CAAC,CAC9D,CAAA;QACH,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ import { BaseGenerator } from './BaseGenerator.js';
2
+ export declare class ScaffoldGenerator extends BaseGenerator {
3
+ run(): void;
4
+ private generateMainVasp;
5
+ }
6
+ //# sourceMappingURL=ScaffoldGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScaffoldGenerator.d.ts","sourceRoot":"","sources":["../../src/generators/ScaffoldGenerator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAIlD,qBAAa,iBAAkB,SAAQ,aAAa;IAClD,GAAG,IAAI,IAAI;IAsDX,OAAO,CAAC,gBAAgB;CA8EzB"}
@@ -0,0 +1,99 @@
1
+ import { ensureDir } from '../utils/fs.js';
2
+ import { join } from 'node:path';
3
+ import { BaseGenerator } from './BaseGenerator.js';
4
+ import { VASP_VERSION } from '@vasp-framework/core';
5
+ import { DEFAULT_BACKEND_PORT, DEFAULT_SPA_PORT, DEFAULT_SSR_PORT } from '@vasp-framework/core';
6
+ export class ScaffoldGenerator extends BaseGenerator {
7
+ run() {
8
+ this.ctx.logger.info('Scaffolding project structure...');
9
+ // Create directory skeleton
10
+ const dirs = [
11
+ 'src/pages',
12
+ 'src/components',
13
+ 'src/lib',
14
+ 'drizzle',
15
+ 'server/routes/queries',
16
+ 'server/routes/actions',
17
+ 'server/db',
18
+ 'tests',
19
+ ...(this.ctx.isSpa
20
+ ? ['src/vasp/client']
21
+ : ['composables', 'plugins', 'pages', 'middleware']),
22
+ ];
23
+ for (const dir of dirs) {
24
+ ensureDir(join(this.ctx.outputDir, dir));
25
+ }
26
+ const frontendPort = this.ctx.isSpa ? DEFAULT_SPA_PORT : DEFAULT_SSR_PORT;
27
+ // package.json
28
+ const pkgContent = this.render('shared/package.json.hbs', {
29
+ vaspVersion: VASP_VERSION,
30
+ backendPort: DEFAULT_BACKEND_PORT,
31
+ frontendPort,
32
+ authMethods: this.ctx.ast.auth?.methods ?? [],
33
+ });
34
+ this.write('package.json', pkgContent);
35
+ // bunfig.toml
36
+ this.write('bunfig.toml', this.render('shared/bunfig.toml.hbs'));
37
+ // .gitignore
38
+ this.write('.gitignore', this.render('shared/.gitignore.hbs'));
39
+ // .env.example
40
+ this.write('.env.example', this.render('shared/.env.example.hbs', {
41
+ backendPort: DEFAULT_BACKEND_PORT,
42
+ frontendPort,
43
+ authMethods: this.ctx.ast.auth?.methods ?? [],
44
+ }));
45
+ // tsconfig.json — only when typescript: true
46
+ if (this.ctx.isTypeScript) {
47
+ this.write('tsconfig.json', this.render('shared/tsconfig.json.hbs'));
48
+ }
49
+ // main.vasp (copy the source)
50
+ this.write('main.vasp', this.generateMainVasp());
51
+ }
52
+ generateMainVasp() {
53
+ // The user's main.vasp is placed at the project root as-is during `vasp new`
54
+ // During scaffold, we generate a clean version based on the parsed AST
55
+ const { ast } = this.ctx;
56
+ const ext = this.ctx.ext;
57
+ const lines = [
58
+ `app ${ast.app.name} {`,
59
+ ` title: "${ast.app.title}"`,
60
+ ` db: ${ast.app.db}`,
61
+ ` ssr: ${typeof ast.app.ssr === 'string' ? `"${ast.app.ssr}"` : ast.app.ssr}`,
62
+ ` typescript: ${ast.app.typescript}`,
63
+ `}`,
64
+ '',
65
+ ];
66
+ if (ast.auth) {
67
+ lines.push(`auth ${ast.auth.name} {`, ` userEntity: ${ast.auth.userEntity}`, ` methods: [ ${ast.auth.methods.join(', ')} ]`, `}`, '');
68
+ }
69
+ for (const route of ast.routes) {
70
+ lines.push(`route ${route.name} {`, ` path: "${route.path}"`, ` to: ${route.to}`, `}`, '');
71
+ }
72
+ for (const page of ast.pages) {
73
+ const comp = page.component;
74
+ const importStr = comp.kind === 'default'
75
+ ? `import ${comp.defaultExport} from "${comp.source}"`
76
+ : `import { ${comp.namedExport} } from "${comp.source}"`;
77
+ lines.push(`page ${page.name} {`, ` component: ${importStr}`, `}`, '');
78
+ }
79
+ for (const query of ast.queries) {
80
+ const fn = query.fn;
81
+ const fnStr = fn.kind === 'named'
82
+ ? `import { ${fn.namedExport} } from "${fn.source}"`
83
+ : `import ${fn.defaultExport} from "${fn.source}"`;
84
+ lines.push(`query ${query.name} {`, ` fn: ${fnStr}`, ` entities: [${query.entities.join(', ')}]`, `}`, '');
85
+ }
86
+ for (const action of ast.actions) {
87
+ const fn = action.fn;
88
+ const fnStr = fn.kind === 'named'
89
+ ? `import { ${fn.namedExport} } from "${fn.source}"`
90
+ : `import ${fn.defaultExport} from "${fn.source}"`;
91
+ lines.push(`action ${action.name} {`, ` fn: ${fnStr}`, ` entities: [${action.entities.join(', ')}]`, `}`, '');
92
+ }
93
+ for (const crud of ast.cruds) {
94
+ lines.push(`crud ${crud.name} {`, ` entity: ${crud.entity}`, ` operations: [${crud.operations.join(', ')}]`, `}`, '');
95
+ }
96
+ return lines.join('\n');
97
+ }
98
+ }
99
+ //# sourceMappingURL=ScaffoldGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScaffoldGenerator.js","sourceRoot":"","sources":["../../src/generators/ScaffoldGenerator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { generate } from './generate.js';
2
+ export type { GeneratorContext } from './GeneratorContext.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ // Phase 2: Generator public API
2
+ export { generate } from './generate.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,30 @@
1
+ export declare class TemplateEngine {
2
+ private readonly cache;
3
+ private readonly hbs;
4
+ constructor();
5
+ /**
6
+ * Pre-compile all .hbs files found under a directory tree.
7
+ * Call this once per generation run to warm the cache.
8
+ */
9
+ loadDirectory(dir: string): void;
10
+ /**
11
+ * Render a template by its key (relative path from the template root).
12
+ */
13
+ render(key: string, data: Record<string, unknown>): string;
14
+ /**
15
+ * Render an inline Handlebars string (used for testing helpers).
16
+ */
17
+ renderString(source: string, data: Record<string, unknown>): string;
18
+ /**
19
+ * Returns true if a template key exists in the cache.
20
+ */
21
+ has(key: string): boolean;
22
+ /** All loaded template keys */
23
+ keys(): string[];
24
+ private registerHelpers;
25
+ private walkHbs;
26
+ }
27
+ export declare function toCamelCase(str: string): string;
28
+ export declare function toPascalCase(str: string): string;
29
+ export declare function toKebabCase(str: string): string;
30
+ //# sourceMappingURL=TemplateEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateEngine.d.ts","sourceRoot":"","sources":["../../src/template/TemplateEngine.ts"],"names":[],"mappings":"AAOA,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsC;IAC5D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAmB;;IAOvC;;;OAGG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAYhC;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM;IAQ1D;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM;IAInE;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,+BAA+B;IAC/B,IAAI,IAAI,MAAM,EAAE;IAMhB,OAAO,CAAC,eAAe;IAkCvB,OAAO,CAAC,OAAO;CAiBhB;AAID,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM/C"}
@@ -0,0 +1,119 @@
1
+ import { GeneratorError } from '@vasp-framework/core';
2
+ import Handlebars from 'handlebars';
3
+ import { readFileSync, readdirSync, statSync } from 'node:fs';
4
+ import { extname, join, relative } from 'node:path';
5
+ export class TemplateEngine {
6
+ cache = new Map();
7
+ hbs;
8
+ constructor() {
9
+ this.hbs = Handlebars.create();
10
+ this.registerHelpers();
11
+ }
12
+ /**
13
+ * Pre-compile all .hbs files found under a directory tree.
14
+ * Call this once per generation run to warm the cache.
15
+ */
16
+ loadDirectory(dir) {
17
+ this.walkHbs(dir, (filePath) => {
18
+ const key = relative(dir, filePath);
19
+ const source = readFileSync(filePath, 'utf8');
20
+ try {
21
+ this.cache.set(key, this.hbs.compile(source));
22
+ }
23
+ catch (err) {
24
+ throw new GeneratorError(`Failed to compile template ${key}: ${String(err)}`, 'TemplateEngine');
25
+ }
26
+ });
27
+ }
28
+ /**
29
+ * Render a template by its key (relative path from the template root).
30
+ */
31
+ render(key, data) {
32
+ const tmpl = this.cache.get(key);
33
+ if (!tmpl) {
34
+ throw new GeneratorError(`Template not found: '${key}'`, 'TemplateEngine');
35
+ }
36
+ return tmpl(data);
37
+ }
38
+ /**
39
+ * Render an inline Handlebars string (used for testing helpers).
40
+ */
41
+ renderString(source, data) {
42
+ return this.hbs.compile(source)(data);
43
+ }
44
+ /**
45
+ * Returns true if a template key exists in the cache.
46
+ */
47
+ has(key) {
48
+ return this.cache.has(key);
49
+ }
50
+ /** All loaded template keys */
51
+ keys() {
52
+ return [...this.cache.keys()];
53
+ }
54
+ // ---- Helpers ----
55
+ registerHelpers() {
56
+ this.hbs.registerHelper('camelCase', (str) => toCamelCase(str));
57
+ this.hbs.registerHelper('pascalCase', (str) => toPascalCase(str));
58
+ this.hbs.registerHelper('kebabCase', (str) => toKebabCase(str));
59
+ this.hbs.registerHelper('lowerCase', (str) => str.toLowerCase());
60
+ this.hbs.registerHelper('upperCase', (str) => str.toUpperCase());
61
+ this.hbs.registerHelper('join', (arr, sep) => {
62
+ if (!Array.isArray(arr))
63
+ return '';
64
+ return arr.join(typeof sep === 'string' ? sep : ', ');
65
+ });
66
+ /** Rewrites @src/foo.js → @src/foo.ts when isTypeScript is true */
67
+ this.hbs.registerHelper('importPath', (source, ext) => {
68
+ if (ext === 'ts' && source.endsWith('.js')) {
69
+ return source.slice(0, -3) + '.ts';
70
+ }
71
+ return source;
72
+ });
73
+ /** eq helper for {{#if (eq a b)}} */
74
+ this.hbs.registerHelper('eq', (a, b) => a === b);
75
+ /** includes helper: {{#if (includes arr item)}} */
76
+ this.hbs.registerHelper('includes', (arr, item) => Array.isArray(arr) && arr.includes(item));
77
+ /** importName: extracts the exported name from an ImportExpression */
78
+ this.hbs.registerHelper('importName', (imp) => {
79
+ return imp.kind === 'default' ? (imp.defaultExport ?? '') : (imp.namedExport ?? '');
80
+ });
81
+ }
82
+ walkHbs(dir, fn) {
83
+ let entries;
84
+ try {
85
+ entries = readdirSync(dir);
86
+ }
87
+ catch {
88
+ return; // directory doesn't exist yet — skip silently
89
+ }
90
+ for (const entry of entries) {
91
+ const full = join(dir, entry);
92
+ const stat = statSync(full);
93
+ if (stat.isDirectory()) {
94
+ this.walkHbs(full, fn);
95
+ }
96
+ else if (extname(full) === '.hbs') {
97
+ fn(full);
98
+ }
99
+ }
100
+ }
101
+ }
102
+ // ---- String transform utilities ----
103
+ export function toCamelCase(str) {
104
+ return str
105
+ .replace(/[-_\s]+(.)/g, (_, c) => c.toUpperCase())
106
+ .replace(/^./, (c) => c.toLowerCase());
107
+ }
108
+ export function toPascalCase(str) {
109
+ const camel = toCamelCase(str);
110
+ return camel.charAt(0).toUpperCase() + camel.slice(1);
111
+ }
112
+ export function toKebabCase(str) {
113
+ return str
114
+ .replace(/([A-Z])/g, '-$1')
115
+ .replace(/[\s_]+/g, '-')
116
+ .toLowerCase()
117
+ .replace(/^-/, '');
118
+ }
119
+ //# sourceMappingURL=TemplateEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateEngine.js","sourceRoot":"","sources":["../../src/template/TemplateEngine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** Write a file, creating parent directories as needed. */
2
+ export declare function writeFile(filePath: string, content: string): void;
3
+ /** Create a directory (and all parents). */
4
+ export declare function ensureDir(dir: string): void;
5
+ //# sourceMappingURL=fs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"AAGA,2DAA2D;AAC3D,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAGjE;AAED,4CAA4C;AAC5C,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE3C"}