pastoria 1.0.5 → 1.0.7

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # pastoria
2
2
 
3
+ ## 1.0.7
4
+
5
+ ### Patch Changes
6
+
7
+ - Move generated persisted queries output
8
+
9
+ ## 1.0.6
10
+
11
+ ### Patch Changes
12
+
13
+ - d81851d: Added a custom GraphQL server to remove the Yoga dependency
14
+
3
15
  ## 1.0.5
4
16
 
5
17
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,YAAY,EACZ,KAAK,uBAAuB,EAE7B,MAAM,MAAM,CAAC;AA8Ed,eAAO,MAAM,YAAY,EAAE,uBAK1B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,uBAM1B,CAAC;AAEF,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,uBAAuB,GAChC,YAAY,CAqBd;AAED,wBAAsB,WAAW,kBAUhC"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,YAAY,EACZ,KAAK,uBAAuB,EAE7B,MAAM,MAAM,CAAC;AA0Gd,eAAO,MAAM,YAAY,EAAE,uBAK1B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,uBAM1B,CAAC;AAEF,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,uBAAuB,GAChC,YAAY,CAyBd;AAED,wBAAsB,WAAW,kBAUhC"}
package/dist/build.js CHANGED
@@ -1,22 +1,33 @@
1
1
  import react from '@vitejs/plugin-react';
2
2
  import tailwindcss from '@tailwindcss/vite';
3
+ import { access } from 'node:fs/promises';
4
+ import * as path from 'node:path';
3
5
  import { cjsInterop } from 'vite-plugin-cjs-interop';
4
6
  import { build, } from 'vite';
5
- // TODO: Only emit `App` code if _app exits.
6
- const PASTORIA_CLIENT_ENTRY = `// Generated by Pastoria.
7
+ function generateClientEntry(hasAppRoot) {
8
+ const appImport = hasAppRoot
9
+ ? `import {App} from '#genfiles/router/app_root';`
10
+ : '';
11
+ const appValue = hasAppRoot ? 'App' : 'null';
12
+ return `// Generated by Pastoria.
7
13
  import {createRouterApp} from '#genfiles/router/router';
8
- import {App} from '#src/pages/_app';
14
+ ${appImport}
9
15
  import {hydrateRoot} from 'react-dom/client';
10
16
 
11
17
  async function main() {
12
18
  const RouterApp = await createRouterApp();
13
- hydrateRoot(document, <RouterApp App={App} />);
19
+ hydrateRoot(document, <RouterApp App={${appValue}} />);
14
20
  }
15
21
 
16
22
  main();
17
23
  `;
18
- // TODO: Remove hard-coded context import here.
19
- const PASTORIA_ENTRY_SERVER = `// Generated by Pastoria.
24
+ }
25
+ function generateServerEntry(hasAppRoot) {
26
+ const appImport = hasAppRoot
27
+ ? `import {App} from '#genfiles/router/app_root';`
28
+ : '';
29
+ const appValue = hasAppRoot ? 'App' : 'null';
30
+ return `// Generated by Pastoria.
20
31
  import {JSResource} from '#genfiles/router/js_resource';
21
32
  import {
22
33
  listRoutes,
@@ -24,9 +35,10 @@ import {
24
35
  router__loadEntryPoint,
25
36
  } from '#genfiles/router/router';
26
37
  import {getSchema} from '#genfiles/schema/schema';
27
- import {Context} from '#src/lib/server/context';
28
- import {App} from '#src/pages/_app';
38
+ import {Context} from '#genfiles/router/context';
39
+ ${appImport}
29
40
  import {GraphQLSchema, specifiedDirectives} from 'graphql';
41
+ import {PastoriaConfig} from 'pastoria-config';
30
42
  import {createRouterHandler} from 'pastoria-runtime/server';
31
43
  import type {Manifest} from 'vite';
32
44
 
@@ -38,6 +50,7 @@ const schema = new GraphQLSchema({
38
50
 
39
51
  export function createHandler(
40
52
  persistedQueries: Record<string, string>,
53
+ config: Required<PastoriaConfig>,
41
54
  manifest?: Manifest,
42
55
  ) {
43
56
  return createRouterHandler(
@@ -45,14 +58,16 @@ export function createHandler(
45
58
  JSResource.srcOfModuleId,
46
59
  router__loadEntryPoint,
47
60
  router__createAppFromEntryPoint,
48
- App,
61
+ ${appValue},
49
62
  schema,
50
- () => new Context(),
63
+ (req) => Context.createFromRequest(req),
51
64
  persistedQueries,
65
+ config,
52
66
  manifest,
53
67
  );
54
68
  }
55
69
  `;
70
+ }
56
71
  function pastoriaEntryPlugin() {
57
72
  const clientEntryModuleId = 'virtual:pastoria-entry-client.tsx';
58
73
  const serverEntryModuleId = 'virtual:pastoria-entry-server.tsx';
@@ -66,12 +81,21 @@ function pastoriaEntryPlugin() {
66
81
  return serverEntryModuleId;
67
82
  }
68
83
  },
69
- load(id) {
84
+ async load(id) {
85
+ const appRootPath = path.join(process.cwd(), '__generated__/router/app_root.ts');
86
+ let hasAppRoot = false;
87
+ try {
88
+ await access(appRootPath);
89
+ hasAppRoot = true;
90
+ }
91
+ catch {
92
+ hasAppRoot = false;
93
+ }
70
94
  if (id === clientEntryModuleId) {
71
- return PASTORIA_CLIENT_ENTRY;
95
+ return generateClientEntry(hasAppRoot);
72
96
  }
73
97
  else if (id === serverEntryModuleId) {
74
- return PASTORIA_ENTRY_SERVER;
98
+ return generateServerEntry(hasAppRoot);
75
99
  }
76
100
  },
77
101
  };
@@ -101,7 +125,11 @@ export function createBuildConfig(buildEnv) {
101
125
  plugins: [
102
126
  pastoriaEntryPlugin(),
103
127
  tailwindcss(),
104
- react({ babel: { plugins: ['relay'] } }),
128
+ react({
129
+ babel: {
130
+ plugins: [['babel-plugin-react-compiler', {}], 'relay'],
131
+ },
132
+ }),
105
133
  cjsInterop({
106
134
  dependencies: ['react-relay', 'react-relay/hooks', 'relay-runtime'],
107
135
  }),
package/dist/build.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,sBAAsB,CAAC;AACzC,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAC,UAAU,EAAC,MAAM,yBAAyB,CAAC;AACnD,OAAO,EACL,KAAK,GAIN,MAAM,MAAM,CAAC;AAEd,4CAA4C;AAC5C,MAAM,qBAAqB,GAAG;;;;;;;;;;;CAW7B,CAAC;AAEF,+CAA+C;AAC/C,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoC7B,CAAC;AAEF,SAAS,mBAAmB;IAC1B,MAAM,mBAAmB,GAAG,mCAAmC,CAAC;IAChE,MAAM,mBAAmB,GAAG,mCAAmC,CAAC;IAEhE,OAAO;QACL,IAAI,EAAE,gBAAgB;QACtB,SAAS,CAAC,EAAE;YACV,IAAI,EAAE,KAAK,mBAAmB,EAAE,CAAC;gBAC/B,OAAO,mBAAmB,CAAC,CAAC,kEAAkE;YAChG,CAAC;iBAAM,IAAI,EAAE,KAAK,mBAAmB,EAAE,CAAC;gBACtC,OAAO,mBAAmB,CAAC;YAC7B,CAAC;QACH,CAAC;QACD,IAAI,CAAC,EAAE;YACL,IAAI,EAAE,KAAK,mBAAmB,EAAE,CAAC;gBAC/B,OAAO,qBAAqB,CAAC;YAC/B,CAAC;iBAAM,IAAI,EAAE,KAAK,mBAAmB,EAAE,CAAC;gBACtC,OAAO,qBAAqB,CAAC;YAC/B,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAA4B;IACnD,MAAM,EAAE,aAAa;IACrB,aAAa,EAAE;QACb,KAAK,EAAE,mCAAmC;KAC3C;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAA4B;IACnD,MAAM,EAAE,aAAa;IACrB,GAAG,EAAE,IAAI;IACT,aAAa,EAAE;QACb,KAAK,EAAE,mCAAmC;KAC3C;CACF,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAC/B,QAAiC;IAEjC,OAAO;QACL,OAAO,EAAE,QAAiB;QAC1B,KAAK,EAAE;YACL,GAAG,QAAQ;YACX,iBAAiB,EAAE,CAAC;YACpB,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,IAAI;SAClB;QACD,OAAO,EAAE;YACP,mBAAmB,EAAE;YACrB,WAAW,EAAE;YACb,KAAK,CAAC,EAAC,KAAK,EAAE,EAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAC,EAAC,CAAC;YACpC,UAAU,CAAC;gBACT,YAAY,EAAE,CAAC,aAAa,EAAE,mBAAmB,EAAE,eAAe,CAAC;aACpE,CAAC;SACH;QACD,GAAG,EAAE;YACH,UAAU,EAAE,CAAC,kBAAkB,CAAC;SACjC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC;QAC9B,GAAG,iBAAiB,CAAC,YAAY,CAAC;QAClC,UAAU,EAAE,KAAK;KAClB,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC;QAC9B,GAAG,iBAAiB,CAAC,YAAY,CAAC;QAClC,UAAU,EAAE,KAAK;KAClB,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,sBAAsB,CAAC;AACzC,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAC,UAAU,EAAC,MAAM,yBAAyB,CAAC;AACnD,OAAO,EACL,KAAK,GAIN,MAAM,MAAM,CAAC;AAEd,SAAS,mBAAmB,CAAC,UAAmB;IAC9C,MAAM,SAAS,GAAG,UAAU;QAC1B,CAAC,CAAC,gDAAgD;QAClD,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IAE7C,OAAO;;EAEP,SAAS;;;;;0CAK+B,QAAQ;;;;CAIjD,CAAC;AACF,CAAC;AAED,SAAS,mBAAmB,CAAC,UAAmB;IAC9C,MAAM,SAAS,GAAG,UAAU;QAC1B,CAAC,CAAC,gDAAgD;QAClD,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IAE7C,OAAO;;;;;;;;;EASP,SAAS;;;;;;;;;;;;;;;;;;;;;;MAsBL,QAAQ;;;;;;;;CAQb,CAAC;AACF,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,mBAAmB,GAAG,mCAAmC,CAAC;IAChE,MAAM,mBAAmB,GAAG,mCAAmC,CAAC;IAEhE,OAAO;QACL,IAAI,EAAE,gBAAgB;QACtB,SAAS,CAAC,EAAE;YACV,IAAI,EAAE,KAAK,mBAAmB,EAAE,CAAC;gBAC/B,OAAO,mBAAmB,CAAC,CAAC,kEAAkE;YAChG,CAAC;iBAAM,IAAI,EAAE,KAAK,mBAAmB,EAAE,CAAC;gBACtC,OAAO,mBAAmB,CAAC;YAC7B,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE;YACX,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAC3B,OAAO,CAAC,GAAG,EAAE,EACb,kCAAkC,CACnC,CAAC;YAEF,IAAI,UAAU,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;gBAC1B,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;YAAC,MAAM,CAAC;gBACP,UAAU,GAAG,KAAK,CAAC;YACrB,CAAC;YAED,IAAI,EAAE,KAAK,mBAAmB,EAAE,CAAC;gBAC/B,OAAO,mBAAmB,CAAC,UAAU,CAAC,CAAC;YACzC,CAAC;iBAAM,IAAI,EAAE,KAAK,mBAAmB,EAAE,CAAC;gBACtC,OAAO,mBAAmB,CAAC,UAAU,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAA4B;IACnD,MAAM,EAAE,aAAa;IACrB,aAAa,EAAE;QACb,KAAK,EAAE,mCAAmC;KAC3C;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAA4B;IACnD,MAAM,EAAE,aAAa;IACrB,GAAG,EAAE,IAAI;IACT,aAAa,EAAE;QACb,KAAK,EAAE,mCAAmC;KAC3C;CACF,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAC/B,QAAiC;IAEjC,OAAO;QACL,OAAO,EAAE,QAAiB;QAC1B,KAAK,EAAE;YACL,GAAG,QAAQ;YACX,iBAAiB,EAAE,CAAC;YACpB,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,IAAI;SAClB;QACD,OAAO,EAAE;YACP,mBAAmB,EAAE;YACrB,WAAW,EAAE;YACb,KAAK,CAAC;gBACJ,KAAK,EAAE;oBACL,OAAO,EAAE,CAAC,CAAC,6BAA6B,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC;iBACxD;aACF,CAAC;YACF,UAAU,CAAC;gBACT,YAAY,EAAE,CAAC,aAAa,EAAE,mBAAmB,EAAE,eAAe,CAAC;aACpE,CAAC;SACH;QACD,GAAG,EAAE;YACH,UAAU,EAAE,CAAC,kBAAkB,CAAC;SACjC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC;QAC9B,GAAG,iBAAiB,CAAC,YAAY,CAAC;QAClC,UAAU,EAAE,KAAK;KAClB,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC;QAC9B,GAAG,iBAAiB,CAAC,YAAY,CAAC;QAClC,UAAU,EAAE,KAAK;KAClB,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"devserver.d.ts","sourceRoot":"","sources":["../src/devserver.ts"],"names":[],"mappings":"AAmBA,wBAAsB,cAAc,CAAC,IAAI,EAAE;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,iBAiCxD"}
1
+ {"version":3,"file":"devserver.d.ts","sourceRoot":"","sources":["../src/devserver.ts"],"names":[],"mappings":"AAqBA,wBAAsB,cAAc,CAAC,IAAI,EAAE;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,iBAmCxD"}
package/dist/devserver.js CHANGED
@@ -3,6 +3,7 @@ import dotenv from 'dotenv';
3
3
  import express from 'express';
4
4
  import { readFile } from 'node:fs/promises';
5
5
  import pc from 'picocolors';
6
+ import { loadConfig } from 'pastoria-config';
6
7
  import { createServer as createViteServer } from 'vite';
7
8
  import { CLIENT_BUILD, createBuildConfig } from './build.js';
8
9
  export async function startDevserver(opts) {
@@ -13,13 +14,14 @@ export async function startDevserver(opts) {
13
14
  configFile: false,
14
15
  server: { middlewareMode: true },
15
16
  });
17
+ const config = await loadConfig();
16
18
  const app = express();
17
19
  app.use(cookieParser());
18
20
  app.use(vite.middlewares);
19
21
  app.use(async (req, res, next) => {
20
- const persistedQueries = JSON.parse(await readFile('__generated__/persisted_queries.json', 'utf-8'));
22
+ const persistedQueries = JSON.parse(await readFile('__generated__/router/persisted_queries.json', 'utf-8'));
21
23
  const { createHandler } = (await vite.ssrLoadModule('virtual:pastoria-entry-server.tsx'));
22
- const handler = createHandler(persistedQueries);
24
+ const handler = createHandler(persistedQueries, config);
23
25
  handler(req, res, next);
24
26
  });
25
27
  app.listen(Number(opts.port), (err) => {
@@ -1 +1 @@
1
- {"version":3,"file":"devserver.js","sourceRoot":"","sources":["../src/devserver.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAC;AACzC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAC,YAAY,IAAI,gBAAgB,EAAgB,MAAM,MAAM,CAAC;AACrE,OAAO,EAAC,YAAY,EAAE,iBAAiB,EAAC,MAAM,YAAY,CAAC;AAa3D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAoB;IACvD,MAAM,CAAC,MAAM,EAAE,CAAC;IAEhB,MAAM,WAAW,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC;QAClC,GAAG,WAAW;QACd,UAAU,EAAE,KAAK;QACjB,MAAM,EAAE,EAAC,cAAc,EAAE,IAAI,EAAC;KAC/B,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;IACxB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1B,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC/B,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CACjC,MAAM,QAAQ,CAAC,sCAAsC,EAAE,OAAO,CAAC,CAChE,CAAC;QAEF,MAAM,EAAC,aAAa,EAAC,GAAG,CAAC,MAAM,IAAI,CAAC,aAAa,CAC/C,mCAAmC,CACpC,CAAgB,CAAC;QAElB,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE;QACpC,IAAI,GAAG,EAAE,CAAC;YACR,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"devserver.js","sourceRoot":"","sources":["../src/devserver.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAC;AACzC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAC,UAAU,EAAiB,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAC,YAAY,IAAI,gBAAgB,EAAgB,MAAM,MAAM,CAAC;AACrE,OAAO,EAAC,YAAY,EAAE,iBAAiB,EAAC,MAAM,YAAY,CAAC;AAc3D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAoB;IACvD,MAAM,CAAC,MAAM,EAAE,CAAC;IAEhB,MAAM,WAAW,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC;QAClC,GAAG,WAAW;QACd,UAAU,EAAE,KAAK;QACjB,MAAM,EAAE,EAAC,cAAc,EAAE,IAAI,EAAC;KAC/B,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAElC,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;IACxB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1B,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC/B,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CACjC,MAAM,QAAQ,CAAC,6CAA6C,EAAE,OAAO,CAAC,CACvE,CAAC;QAEF,MAAM,EAAC,aAAa,EAAC,GAAG,CAAC,MAAM,IAAI,CAAC,aAAa,CAC/C,mCAAmC,CACpC,CAAgB,CAAC;QAElB,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE;QACpC,IAAI,GAAG,EAAE,CAAC;YACR,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -6,16 +6,20 @@
6
6
  *
7
7
  * How it works:
8
8
  * 1. Scans all TypeScript files in the project for exported functions/classes
9
- * 2. Looks for JSDoc tags: @route, @resource, and @param
10
- * 3. Generates three files from templates:
9
+ * 2. Looks for JSDoc tags: @route, @resource, @appRoot, and @param
10
+ * 3. Looks for exported classes that extend PastoriaRootContext for GraphQL context
11
+ * 4. Generates files from templates:
11
12
  * - js_resource.ts: Resource configuration for lazy loading
12
13
  * - router.tsx: Client-side router with type-safe routes
13
- * - server_router.ts: Server-side router configuration
14
+ * - app_root.ts: Re-export of the app root component (if @appRoot is found)
15
+ * - context.ts: Re-export of user's context class, or generate a default one
14
16
  *
15
17
  * Usage:
16
18
  * - Add @route <route-name> to functions to create routes
17
19
  * - Add @param <name> <type> to document route parameters
18
20
  * - Add @resource <resource-name> to exports for lazy loading
21
+ * - Add @appRoot to a component to designate it as the application root wrapper
22
+ * - Add @gqlContext to a class extending PastoriaRootContext to provide a custom GraphQL context
19
23
  *
20
24
  * The generator automatically creates Zod schemas for route parameters based on
21
25
  * TypeScript types, enabling runtime validation and type safety.
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAoJH,wBAAsB,yBAAyB,kBA2G9C"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AA6OH,wBAAsB,yBAAyB,kBA6L9C"}
package/dist/generate.js CHANGED
@@ -6,16 +6,20 @@
6
6
  *
7
7
  * How it works:
8
8
  * 1. Scans all TypeScript files in the project for exported functions/classes
9
- * 2. Looks for JSDoc tags: @route, @resource, and @param
10
- * 3. Generates three files from templates:
9
+ * 2. Looks for JSDoc tags: @route, @resource, @appRoot, and @param
10
+ * 3. Looks for exported classes that extend PastoriaRootContext for GraphQL context
11
+ * 4. Generates files from templates:
11
12
  * - js_resource.ts: Resource configuration for lazy loading
12
13
  * - router.tsx: Client-side router with type-safe routes
13
- * - server_router.ts: Server-side router configuration
14
+ * - app_root.ts: Re-export of the app root component (if @appRoot is found)
15
+ * - context.ts: Re-export of user's context class, or generate a default one
14
16
  *
15
17
  * Usage:
16
18
  * - Add @route <route-name> to functions to create routes
17
19
  * - Add @param <name> <type> to document route parameters
18
20
  * - Add @resource <resource-name> to exports for lazy loading
21
+ * - Add @appRoot to a component to designate it as the application root wrapper
22
+ * - Add @gqlContext to a class extending PastoriaRootContext to provide a custom GraphQL context
19
23
  *
20
24
  * The generator automatically creates Zod schemas for route parameters based on
21
25
  * TypeScript types, enabling runtime validation and type safety.
@@ -28,6 +32,8 @@ const JS_RESOURCE_FILENAME = '__generated__/router/js_resource.ts';
28
32
  const JS_RESOURCE_TEMPLATE = path.join(import.meta.dirname, '../templates/js_resource.ts');
29
33
  const ROUTER_FILENAME = '__generated__/router/router.tsx';
30
34
  const ROUTER_TEMPLATE = path.join(import.meta.dirname, '../templates/router.tsx');
35
+ const APP_ROOT_FILENAME = '__generated__/router/app_root.ts';
36
+ const CONTEXT_FILENAME = '__generated__/router/context.ts';
31
37
  async function loadRouterFiles(project) {
32
38
  async function loadSourceFile(fileName, templateFileName) {
33
39
  const template = await readFile(templateFileName, 'utf-8');
@@ -47,11 +53,23 @@ async function loadRouterFiles(project) {
47
53
  ]);
48
54
  return { jsResource, router };
49
55
  }
56
+ // Regex to quickly check if a file contains any Pastoria JSDoc tags
57
+ const PASTORIA_TAG_REGEX = /@(route|resource|appRoot|param|gqlContext)\b/;
50
58
  function collectRouterNodes(project) {
51
59
  const resources = [];
52
60
  const routes = [];
61
+ let appRoot = null;
62
+ let gqlContext = null;
53
63
  function visitRouterNodes(sourceFile) {
54
- // TODO: Skip sourceFile if a pastora JSDoc tag isn't used at all.
64
+ // Skip generated files
65
+ if (sourceFile.getFilePath().includes('__generated__')) {
66
+ return;
67
+ }
68
+ // Skip files that don't contain any Pastoria JSDoc tags
69
+ const fileText = sourceFile.getFullText();
70
+ if (!PASTORIA_TAG_REGEX.test(fileText)) {
71
+ return;
72
+ }
55
73
  sourceFile.getExportSymbols().forEach((symbol) => {
56
74
  let routerResource = null;
57
75
  let routerRoute = null;
@@ -89,6 +107,55 @@ function collectRouterNodes(project) {
89
107
  }
90
108
  }
91
109
  }
110
+ else {
111
+ // Handle tags without comments (like @appRoot, @gqlContext)
112
+ switch (tag.tagName.getText()) {
113
+ case 'appRoot': {
114
+ if (appRoot != null) {
115
+ console.warn(pc.yellow('Warning:'), 'Multiple @appRoot tags found. Using the first one.');
116
+ }
117
+ else {
118
+ appRoot = {
119
+ sourceFile,
120
+ symbol,
121
+ };
122
+ }
123
+ break;
124
+ }
125
+ case 'gqlContext': {
126
+ // Check if this class extends PastoriaRootContext
127
+ const declarations = symbol.getDeclarations();
128
+ let extendsPastoriaRootContext = false;
129
+ for (const decl of declarations) {
130
+ if (decl.isKind(SyntaxKind.ClassDeclaration)) {
131
+ const classDecl = decl.asKindOrThrow(SyntaxKind.ClassDeclaration);
132
+ const extendsClause = classDecl.getExtends();
133
+ if (extendsClause != null) {
134
+ const baseClassName = extendsClause
135
+ .getExpression()
136
+ .getText();
137
+ if (baseClassName === 'PastoriaRootContext') {
138
+ extendsPastoriaRootContext = true;
139
+ break;
140
+ }
141
+ }
142
+ }
143
+ }
144
+ if (extendsPastoriaRootContext) {
145
+ if (gqlContext != null) {
146
+ console.warn(pc.yellow('Warning:'), 'Multiple classes with @gqlContext extending PastoriaRootContext found. Using the first one.');
147
+ }
148
+ else {
149
+ gqlContext = {
150
+ sourceFile,
151
+ symbol,
152
+ };
153
+ }
154
+ }
155
+ break;
156
+ }
157
+ }
158
+ }
92
159
  }
93
160
  symbol
94
161
  .getDeclarations()
@@ -101,7 +168,7 @@ function collectRouterNodes(project) {
101
168
  });
102
169
  }
103
170
  project.getSourceFiles().forEach(visitRouterNodes);
104
- return { resources, routes };
171
+ return { resources, routes, appRoot, gqlContext };
105
172
  }
106
173
  function zodSchemaOfType(tc, t) {
107
174
  if (t.getFlags() & TypeFlags.String) {
@@ -142,6 +209,61 @@ export async function generatePastoriaArtifacts() {
142
209
  const tc = project.getTypeChecker().compilerObject;
143
210
  const routerFiles = await loadRouterFiles(project);
144
211
  const routerNodes = collectRouterNodes(project);
212
+ // Generate app_root.ts if @appRoot tag is found
213
+ const appRoot = routerNodes.appRoot;
214
+ if (appRoot != null) {
215
+ const appRootSourceFile = appRoot.sourceFile;
216
+ const appRootSymbol = appRoot.symbol;
217
+ const filePath = path.relative(targetDir, appRootSourceFile.getFilePath());
218
+ const appRootFile = project.createSourceFile(APP_ROOT_FILENAME, '', {
219
+ overwrite: true,
220
+ });
221
+ const moduleSpecifier = appRootFile.getRelativePathAsModuleSpecifierTo(appRootSourceFile.getFilePath());
222
+ appRootFile.addStatements(`/*
223
+ * This file was generated by \`pastoria\`.
224
+ * Do not modify this file directly.
225
+ */
226
+
227
+ export {${appRootSymbol.getName()} as App} from '${moduleSpecifier}';
228
+ `);
229
+ await appRootFile.save();
230
+ console.log('Created app root for', pc.green(appRootSymbol.getName()), 'exported from', pc.yellow(filePath));
231
+ }
232
+ // Generate context.ts
233
+ const gqlContext = routerNodes.gqlContext;
234
+ const contextFile = project.createSourceFile(CONTEXT_FILENAME, '', {
235
+ overwrite: true,
236
+ });
237
+ if (gqlContext != null) {
238
+ const contextSourceFile = gqlContext.sourceFile;
239
+ const contextSymbol = gqlContext.symbol;
240
+ const filePath = path.relative(targetDir, contextSourceFile.getFilePath());
241
+ const moduleSpecifier = contextFile.getRelativePathAsModuleSpecifierTo(contextSourceFile.getFilePath());
242
+ contextFile.addStatements(`/*
243
+ * This file was generated by \`pastoria\`.
244
+ * Do not modify this file directly.
245
+ */
246
+
247
+ export {${contextSymbol.getName()} as Context} from '${moduleSpecifier}';
248
+ `);
249
+ console.log('Created GraphQL context for', pc.green(contextSymbol.getName()), 'exported from', pc.yellow(filePath));
250
+ }
251
+ else {
252
+ contextFile.addStatements(`/*
253
+ * This file was generated by \`pastoria\`.
254
+ * Do not modify this file directly.
255
+ */
256
+
257
+ import {PastoriaRootContext} from 'pastoria-runtime/server';
258
+
259
+ /**
260
+ * @gqlContext
261
+ */
262
+ export class Context extends PastoriaRootContext {}
263
+ `);
264
+ console.log('No @gqlContext found, generating default', pc.green('Context'));
265
+ }
266
+ await contextFile.save();
145
267
  const resourceConf = routerFiles.jsResource
146
268
  .getVariableDeclarationOrThrow('RESOURCE_CONF')
147
269
  .getInitializerIfKindOrThrow(SyntaxKind.AsExpression)
@@ -1 +1 @@
1
- {"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAC,OAAO,IAAI,EAAE,EAAC,MAAM,YAAY,CAAC;AACzC,OAAO,EAAC,OAAO,EAAsB,UAAU,EAAE,EAAE,EAAE,SAAS,EAAC,MAAM,UAAU,CAAC;AAEhF,MAAM,oBAAoB,GAAG,qCAAqC,CAAC;AACnE,MAAM,oBAAoB,GAAG,IAAI,CAAC,IAAI,CACpC,MAAM,CAAC,IAAI,CAAC,OAAO,EACnB,6BAA6B,CAC9B,CAAC;AAEF,MAAM,eAAe,GAAG,iCAAiC,CAAC;AAC1D,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAC/B,MAAM,CAAC,IAAI,CAAC,OAAO,EACnB,yBAAyB,CAC1B,CAAC;AAEF,MAAM,iBAAiB,GAAG,kCAAkC,CAAC;AAC7D,MAAM,gBAAgB,GAAG,iCAAiC,CAAC;AAE3D,KAAK,UAAU,eAAe,CAAC,OAAgB;IAC7C,KAAK,UAAU,cAAc,CAAC,QAAgB,EAAE,gBAAwB;QACtE,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAC3D,MAAM,cAAc,GAAG;;qEAE0C,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;;;CAGnG,CAAC;QACE,OAAO,OAAO,CAAC,gBAAgB,CAAC,QAAQ,EAAE,cAAc,GAAG,QAAQ,EAAE;YACnE,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC7C,cAAc,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;QAC1D,cAAc,CAAC,eAAe,EAAE,eAAe,CAAC;KACjD,CAAC,CAAC;IAEH,OAAO,EAAC,UAAU,EAAE,MAAM,EAAU,CAAC;AACvC,CAAC;AAyBD,oEAAoE;AACpE,MAAM,kBAAkB,GAAG,8CAA8C,CAAC;AAE1E,SAAS,kBAAkB,CAAC,OAAgB;IAM1C,MAAM,SAAS,GAAqB,EAAE,CAAC;IACvC,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,IAAI,OAAO,GAAmB,IAAI,CAAC;IACnC,IAAI,UAAU,GAAsB,IAAI,CAAC;IAEzC,SAAS,gBAAgB,CAAC,UAAsB;QAC9C,uBAAuB;QACvB,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;YACvD,OAAO;QACT,CAAC;QAED,wDAAwD;QACxD,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;QAC1C,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvC,OAAO;QACT,CAAC;QAED,UAAU,CAAC,gBAAgB,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YAC/C,IAAI,cAAc,GAAG,IAA6B,CAAC;YACnD,IAAI,WAAW,GAAG,IAA0B,CAAC;YAC7C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAmB,CAAC;YAE/C,SAAS,cAAc,CAAC,GAA2B;gBACjD,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;oBACpB,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;gBACpC,CAAC;qBAAM,IAAI,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;oBACvC,MAAM,QAAQ,GAAG,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC;oBAC1C,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,cAAc,CAAC;oBAEnD,MAAM,IAAI,GACR,QAAQ,IAAI,IAAI;wBACd,CAAC,CAAC,EAAE,CAAC,cAAc,EAAE;wBACrB,CAAC,CAAC,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;oBAEvC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;gBAC5C,CAAC;qBAAM,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;oBAC3C,QAAQ,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;wBAC9B,KAAK,OAAO,CAAC,CAAC,CAAC;4BACb,WAAW,GAAG;gCACZ,SAAS,EAAE,GAAG,CAAC,OAAO;gCACtB,UAAU;gCACV,MAAM;gCACN,MAAM,EAAE,WAAW;6BACpB,CAAC;4BACF,MAAM;wBACR,CAAC;wBACD,KAAK,UAAU,CAAC,CAAC,CAAC;4BAChB,cAAc,GAAG;gCACf,YAAY,EAAE,GAAG,CAAC,OAAO;gCACzB,UAAU;gCACV,MAAM;6BACP,CAAC;4BACF,MAAM;wBACR,CAAC;oBACH,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,4DAA4D;oBAC5D,QAAQ,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;wBAC9B,KAAK,SAAS,CAAC,CAAC,CAAC;4BACf,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;gCACpB,OAAO,CAAC,IAAI,CACV,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EACrB,oDAAoD,CACrD,CAAC;4BACJ,CAAC;iCAAM,CAAC;gCACN,OAAO,GAAG;oCACR,UAAU;oCACV,MAAM;iCACP,CAAC;4BACJ,CAAC;4BACD,MAAM;wBACR,CAAC;wBACD,KAAK,YAAY,CAAC,CAAC,CAAC;4BAClB,kDAAkD;4BAClD,MAAM,YAAY,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;4BAC9C,IAAI,0BAA0B,GAAG,KAAK,CAAC;4BAEvC,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;gCAChC,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;oCAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAClC,UAAU,CAAC,gBAAgB,CAC5B,CAAC;oCACF,MAAM,aAAa,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC;oCAC7C,IAAI,aAAa,IAAI,IAAI,EAAE,CAAC;wCAC1B,MAAM,aAAa,GAAG,aAAa;6CAChC,aAAa,EAAE;6CACf,OAAO,EAAE,CAAC;wCACb,IAAI,aAAa,KAAK,qBAAqB,EAAE,CAAC;4CAC5C,0BAA0B,GAAG,IAAI,CAAC;4CAClC,MAAM;wCACR,CAAC;oCACH,CAAC;gCACH,CAAC;4BACH,CAAC;4BAED,IAAI,0BAA0B,EAAE,CAAC;gCAC/B,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;oCACvB,OAAO,CAAC,IAAI,CACV,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EACrB,6FAA6F,CAC9F,CAAC;gCACJ,CAAC;qCAAM,CAAC;oCACN,UAAU,GAAG;wCACX,UAAU;wCACV,MAAM;qCACP,CAAC;gCACJ,CAAC;4BACH,CAAC;4BACD,MAAM;wBACR,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAED,MAAM;iBACH,eAAe,EAAE;iBACjB,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;iBAChE,OAAO,CAAC,cAAc,CAAC,CAAC;YAE3B,IAAI,WAAW,IAAI,IAAI;gBAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAClD,IAAI,cAAc,IAAI,IAAI;gBAAE,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACnD,OAAO,EAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAC,CAAC;AAClD,CAAC;AAED,SAAS,eAAe,CAAC,EAAkB,EAAE,CAAU;IACrD,IAAI,CAAC,CAAC,QAAQ,EAAE,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;QACpC,OAAO,qDAAqD,CAAC;IAC/D,CAAC;SAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;QAC3C,OAAO,2BAA2B,CAAC;IACrC,CAAC;SAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;QACzC,OAAO,6DAA6D,CAAC;IACvE,CAAC;SAAM,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QACvB,MAAM,sBAAsB,GAC1B,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YACpB,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAErD,IAAI,sBAAsB,EAAE,CAAC;YAC3B,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CACvC,CAAC;YAEH,OAAO,oBAAoB,eAAe,CAAC,EAAE,EAAE,eAAe,CAAC,iDAAiD,CAAC;QACnH,CAAC;aAAM,CAAC;YACN,OAAO,YAAY,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QACjF,CAAC;IACH,CAAC;SAAM,IAAI,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,EAAE,CAAC,gBAAgB,CAAC,CAAqB,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,MAAM,YAAY,GAChB,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAE7D,OAAO,WAAW,YAAY,GAAG,CAAC;IACpC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB;IAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;QAC1B,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC;KACxD,CAAC,CAAC;IAEH,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,cAAc,CAAC;IACnD,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;IACnD,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAEhD,gDAAgD;IAChD,MAAM,OAAO,GAAmB,WAAW,CAAC,OAAO,CAAC;IACpD,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACpB,MAAM,iBAAiB,GAAe,OAAO,CAAC,UAAU,CAAC;QACzD,MAAM,aAAa,GAAW,OAAO,CAAC,MAAM,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3E,MAAM,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,EAAE,EAAE;YAClE,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;QAEH,MAAM,eAAe,GAAG,WAAW,CAAC,kCAAkC,CACpE,iBAAiB,CAAC,WAAW,EAAE,CAChC,CAAC;QAEF,WAAW,CAAC,aAAa,CAAC;;;;;UAKpB,aAAa,CAAC,OAAO,EAAE,kBAAkB,eAAe;CACjE,CAAC,CAAC;QAEC,MAAM,WAAW,CAAC,IAAI,EAAE,CAAC;QAEzB,OAAO,CAAC,GAAG,CACT,sBAAsB,EACtB,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,EACjC,eAAe,EACf,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CACpB,CAAC;IACJ,CAAC;IAED,sBAAsB;IACtB,MAAM,UAAU,GAAsB,WAAW,CAAC,UAAU,CAAC;IAC7D,MAAM,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,EAAE,EAAE;QACjE,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;IAEH,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,iBAAiB,GAAe,UAAU,CAAC,UAAU,CAAC;QAC5D,MAAM,aAAa,GAAW,UAAU,CAAC,MAAM,CAAC;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3E,MAAM,eAAe,GAAG,WAAW,CAAC,kCAAkC,CACpE,iBAAiB,CAAC,WAAW,EAAE,CAChC,CAAC;QAEF,WAAW,CAAC,aAAa,CAAC;;;;;UAKpB,aAAa,CAAC,OAAO,EAAE,sBAAsB,eAAe;CACrE,CAAC,CAAC;QAEC,OAAO,CAAC,GAAG,CACT,6BAA6B,EAC7B,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,EACjC,eAAe,EACf,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CACpB,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,WAAW,CAAC,aAAa,CAAC;;;;;;;;;;;CAW7B,CAAC,CAAC;QAEC,OAAO,CAAC,GAAG,CACT,0CAA0C,EAC1C,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CACpB,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,CAAC,IAAI,EAAE,CAAC;IAEzB,MAAM,YAAY,GAAG,WAAW,CAAC,UAAU;SACxC,6BAA6B,CAAC,eAAe,CAAC;SAC9C,2BAA2B,CAAC,UAAU,CAAC,YAAY,CAAC;SACpD,0BAA0B,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;IAElE,YAAY,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;IACjD,KAAK,MAAM,EAAC,YAAY,EAAE,UAAU,EAAE,MAAM,EAAC,IAAI,WAAW,CAAC,SAAS,EAAE,CAAC;QACvE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;QACxE,MAAM,eAAe,GACnB,WAAW,CAAC,UAAU,CAAC,kCAAkC,CACvD,UAAU,CAAC,WAAW,EAAE,CACzB,CAAC;QAEJ,YAAY,CAAC,qBAAqB,CAAC;YACjC,IAAI,EAAE,IAAI,YAAY,GAAG;YACzB,WAAW,EAAE,CAAC,MAAM,EAAE,EAAE;gBACtB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;oBAChB,MAAM;yBACH,SAAS,CAAC,SAAS,QAAQ,IAAI,CAAC;yBAChC,SAAS,CACR,yBAAyB,eAAe,kBAAkB,MAAM,CAAC,OAAO,EAAE,GAAG,CAC9E,CAAC;gBACN,CAAC,CAAC,CAAC;YACL,CAAC;SACF,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CACT,kBAAkB,EAClB,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,EACrB,KAAK,EACL,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,EAC1B,eAAe,EACf,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CACpB,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM;SAClC,6BAA6B,CAAC,aAAa,CAAC;SAC5C,2BAA2B,CAAC,UAAU,CAAC,YAAY,CAAC;SACpD,0BAA0B,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;IAElE,UAAU,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;IAE/C,IAAI,qBAAqB,GAAG,CAAC,CAAC;IAC9B,KAAK,MAAM,EAAC,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAC,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;QACzE,MAAM,WAAW,GAAG,IAAI,qBAAqB,EAAE,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;QACxE,MAAM,eAAe,GACnB,WAAW,CAAC,MAAM,CAAC,kCAAkC,CACnD,UAAU,CAAC,WAAW,EAAE,CACzB,CAAC;QAEJ,WAAW,CAAC,MAAM,CAAC,oBAAoB,CAAC;YACtC,eAAe;YACf,YAAY,EAAE;gBACZ;oBACE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE;oBACtB,KAAK,EAAE,WAAW;iBACnB;aACF;SACF,CAAC,CAAC;QAEH,UAAU,CAAC,qBAAqB,CAAC;YAC/B,IAAI,EAAE,IAAI,SAAS,GAAG;YACtB,WAAW,EAAE,CAAC,MAAM,EAAE,EAAE;gBACtB,MAAM;qBACH,KAAK,CAAC,GAAG,CAAC;qBACV,MAAM,CAAC,GAAG,EAAE;oBACX,MAAM,CAAC,SAAS,CAAC,eAAe,WAAW,GAAG,CAAC,CAAC;oBAChD,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;wBACtB,MAAM,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;oBAC3C,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;wBACvC,KAAK,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;4BACxD,MAAM,CAAC,SAAS,CACd,KAAK,SAAS,KAAK,eAAe,CAAC,EAAE,EAAE,SAAS,CAAC,GAAG,CACrD,CAAC;wBACJ,CAAC;wBAED,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBACzB,CAAC;gBACH,CAAC,CAAC;qBACD,KAAK,CAAC,YAAY,CAAC,CAAC;YACzB,CAAC;SACF,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CACT,eAAe,EACf,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAClB,KAAK,EACL,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,EAC1B,eAAe,EACf,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CACpB,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAChF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pastoria",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Pastoria Development CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -12,6 +12,7 @@
12
12
  "dependencies": {
13
13
  "@tailwindcss/vite": "^4.1.14",
14
14
  "@vitejs/plugin-react": "^5.0.4",
15
+ "babel-plugin-react-compiler": "^1.0.0",
15
16
  "commander": "^14.0.1",
16
17
  "cookie-parser": "^1.4.7",
17
18
  "dotenv": "^16.6.1",
@@ -25,13 +26,17 @@
25
26
  "@types/cookie-parser": "^1.4.9",
26
27
  "@types/express": "^5.0.3",
27
28
  "@types/node": "^22.12.0",
28
- "@types/react": "^19.1.2",
29
- "@types/react-dom": "^19.1.3",
29
+ "@types/react": "^19.2.0",
30
+ "@types/react-dom": "^19.2.0",
30
31
  "@types/react-relay": "^18.2.1",
31
32
  "typescript": "^5.9.2",
32
33
  "radix3": "^1.1.2",
33
34
  "zod": "^3.25.76",
34
- "pastoria-runtime": "1.0.3"
35
+ "pastoria-config": "1.0.0",
36
+ "pastoria-runtime": "1.0.7"
37
+ },
38
+ "peerDependencies": {
39
+ "pastoria-config": "1.0.0"
35
40
  },
36
41
  "scripts": {
37
42
  "build": "tsc",
package/src/build.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import react from '@vitejs/plugin-react';
2
2
  import tailwindcss from '@tailwindcss/vite';
3
+ import {access} from 'node:fs/promises';
4
+ import * as path from 'node:path';
3
5
  import {cjsInterop} from 'vite-plugin-cjs-interop';
4
6
  import {
5
7
  build,
@@ -8,22 +10,33 @@ import {
8
10
  type Plugin,
9
11
  } from 'vite';
10
12
 
11
- // TODO: Only emit `App` code if _app exits.
12
- const PASTORIA_CLIENT_ENTRY = `// Generated by Pastoria.
13
+ function generateClientEntry(hasAppRoot: boolean): string {
14
+ const appImport = hasAppRoot
15
+ ? `import {App} from '#genfiles/router/app_root';`
16
+ : '';
17
+ const appValue = hasAppRoot ? 'App' : 'null';
18
+
19
+ return `// Generated by Pastoria.
13
20
  import {createRouterApp} from '#genfiles/router/router';
14
- import {App} from '#src/pages/_app';
21
+ ${appImport}
15
22
  import {hydrateRoot} from 'react-dom/client';
16
23
 
17
24
  async function main() {
18
25
  const RouterApp = await createRouterApp();
19
- hydrateRoot(document, <RouterApp App={App} />);
26
+ hydrateRoot(document, <RouterApp App={${appValue}} />);
20
27
  }
21
28
 
22
29
  main();
23
30
  `;
31
+ }
24
32
 
25
- // TODO: Remove hard-coded context import here.
26
- const PASTORIA_ENTRY_SERVER = `// Generated by Pastoria.
33
+ function generateServerEntry(hasAppRoot: boolean): string {
34
+ const appImport = hasAppRoot
35
+ ? `import {App} from '#genfiles/router/app_root';`
36
+ : '';
37
+ const appValue = hasAppRoot ? 'App' : 'null';
38
+
39
+ return `// Generated by Pastoria.
27
40
  import {JSResource} from '#genfiles/router/js_resource';
28
41
  import {
29
42
  listRoutes,
@@ -31,9 +44,10 @@ import {
31
44
  router__loadEntryPoint,
32
45
  } from '#genfiles/router/router';
33
46
  import {getSchema} from '#genfiles/schema/schema';
34
- import {Context} from '#src/lib/server/context';
35
- import {App} from '#src/pages/_app';
47
+ import {Context} from '#genfiles/router/context';
48
+ ${appImport}
36
49
  import {GraphQLSchema, specifiedDirectives} from 'graphql';
50
+ import {PastoriaConfig} from 'pastoria-config';
37
51
  import {createRouterHandler} from 'pastoria-runtime/server';
38
52
  import type {Manifest} from 'vite';
39
53
 
@@ -45,6 +59,7 @@ const schema = new GraphQLSchema({
45
59
 
46
60
  export function createHandler(
47
61
  persistedQueries: Record<string, string>,
62
+ config: Required<PastoriaConfig>,
48
63
  manifest?: Manifest,
49
64
  ) {
50
65
  return createRouterHandler(
@@ -52,14 +67,16 @@ export function createHandler(
52
67
  JSResource.srcOfModuleId,
53
68
  router__loadEntryPoint,
54
69
  router__createAppFromEntryPoint,
55
- App,
70
+ ${appValue},
56
71
  schema,
57
- () => new Context(),
72
+ (req) => Context.createFromRequest(req),
58
73
  persistedQueries,
74
+ config,
59
75
  manifest,
60
76
  );
61
77
  }
62
78
  `;
79
+ }
63
80
 
64
81
  function pastoriaEntryPlugin(): Plugin {
65
82
  const clientEntryModuleId = 'virtual:pastoria-entry-client.tsx';
@@ -74,11 +91,24 @@ function pastoriaEntryPlugin(): Plugin {
74
91
  return serverEntryModuleId;
75
92
  }
76
93
  },
77
- load(id) {
94
+ async load(id) {
95
+ const appRootPath = path.join(
96
+ process.cwd(),
97
+ '__generated__/router/app_root.ts',
98
+ );
99
+
100
+ let hasAppRoot = false;
101
+ try {
102
+ await access(appRootPath);
103
+ hasAppRoot = true;
104
+ } catch {
105
+ hasAppRoot = false;
106
+ }
107
+
78
108
  if (id === clientEntryModuleId) {
79
- return PASTORIA_CLIENT_ENTRY;
109
+ return generateClientEntry(hasAppRoot);
80
110
  } else if (id === serverEntryModuleId) {
81
- return PASTORIA_ENTRY_SERVER;
111
+ return generateServerEntry(hasAppRoot);
82
112
  }
83
113
  },
84
114
  };
@@ -113,7 +143,11 @@ export function createBuildConfig(
113
143
  plugins: [
114
144
  pastoriaEntryPlugin(),
115
145
  tailwindcss(),
116
- react({babel: {plugins: ['relay']}}),
146
+ react({
147
+ babel: {
148
+ plugins: [['babel-plugin-react-compiler', {}], 'relay'],
149
+ },
150
+ }),
117
151
  cjsInterop({
118
152
  dependencies: ['react-relay', 'react-relay/hooks', 'relay-runtime'],
119
153
  }),
package/src/devserver.ts CHANGED
@@ -3,6 +3,7 @@ import dotenv from 'dotenv';
3
3
  import express from 'express';
4
4
  import {readFile} from 'node:fs/promises';
5
5
  import pc from 'picocolors';
6
+ import {loadConfig, PastoriaConfig} from 'pastoria-config';
6
7
  import {createServer as createViteServer, type Manifest} from 'vite';
7
8
  import {CLIENT_BUILD, createBuildConfig} from './build.js';
8
9
 
@@ -13,6 +14,7 @@ interface PersistedQueries {
13
14
  interface ServerEntry {
14
15
  createHandler(
15
16
  persistedQueries: PersistedQueries,
17
+ config: Required<PastoriaConfig>,
16
18
  manifest?: Manifest,
17
19
  ): express.Router;
18
20
  }
@@ -27,19 +29,21 @@ export async function startDevserver(opts: {port: string}) {
27
29
  server: {middlewareMode: true},
28
30
  });
29
31
 
32
+ const config = await loadConfig();
33
+
30
34
  const app = express();
31
35
  app.use(cookieParser());
32
36
  app.use(vite.middlewares);
33
37
  app.use(async (req, res, next) => {
34
38
  const persistedQueries = JSON.parse(
35
- await readFile('__generated__/persisted_queries.json', 'utf-8'),
39
+ await readFile('__generated__/router/persisted_queries.json', 'utf-8'),
36
40
  );
37
41
 
38
42
  const {createHandler} = (await vite.ssrLoadModule(
39
43
  'virtual:pastoria-entry-server.tsx',
40
44
  )) as ServerEntry;
41
45
 
42
- const handler = createHandler(persistedQueries);
46
+ const handler = createHandler(persistedQueries, config);
43
47
  handler(req, res, next);
44
48
  });
45
49
 
package/src/generate.ts CHANGED
@@ -6,16 +6,20 @@
6
6
  *
7
7
  * How it works:
8
8
  * 1. Scans all TypeScript files in the project for exported functions/classes
9
- * 2. Looks for JSDoc tags: @route, @resource, and @param
10
- * 3. Generates three files from templates:
9
+ * 2. Looks for JSDoc tags: @route, @resource, @appRoot, and @param
10
+ * 3. Looks for exported classes that extend PastoriaRootContext for GraphQL context
11
+ * 4. Generates files from templates:
11
12
  * - js_resource.ts: Resource configuration for lazy loading
12
13
  * - router.tsx: Client-side router with type-safe routes
13
- * - server_router.ts: Server-side router configuration
14
+ * - app_root.ts: Re-export of the app root component (if @appRoot is found)
15
+ * - context.ts: Re-export of user's context class, or generate a default one
14
16
  *
15
17
  * Usage:
16
18
  * - Add @route <route-name> to functions to create routes
17
19
  * - Add @param <name> <type> to document route parameters
18
20
  * - Add @resource <resource-name> to exports for lazy loading
21
+ * - Add @appRoot to a component to designate it as the application root wrapper
22
+ * - Add @gqlContext to a class extending PastoriaRootContext to provide a custom GraphQL context
19
23
  *
20
24
  * The generator automatically creates Zod schemas for route parameters based on
21
25
  * TypeScript types, enabling runtime validation and type safety.
@@ -38,6 +42,9 @@ const ROUTER_TEMPLATE = path.join(
38
42
  '../templates/router.tsx',
39
43
  );
40
44
 
45
+ const APP_ROOT_FILENAME = '__generated__/router/app_root.ts';
46
+ const CONTEXT_FILENAME = '__generated__/router/context.ts';
47
+
41
48
  async function loadRouterFiles(project: Project) {
42
49
  async function loadSourceFile(fileName: string, templateFileName: string) {
43
50
  const template = await readFile(templateFileName, 'utf-8');
@@ -73,12 +80,42 @@ type RouterRoute = {
73
80
  params: Map<string, ts.Type>;
74
81
  };
75
82
 
76
- function collectRouterNodes(project: Project) {
83
+ type AppRoot = {
84
+ sourceFile: SourceFile;
85
+ symbol: Symbol;
86
+ };
87
+
88
+ type GqlContext = {
89
+ sourceFile: SourceFile;
90
+ symbol: Symbol;
91
+ };
92
+
93
+ // Regex to quickly check if a file contains any Pastoria JSDoc tags
94
+ const PASTORIA_TAG_REGEX = /@(route|resource|appRoot|param|gqlContext)\b/;
95
+
96
+ function collectRouterNodes(project: Project): {
97
+ resources: RouterResource[];
98
+ routes: RouterRoute[];
99
+ appRoot: AppRoot | null;
100
+ gqlContext: GqlContext | null;
101
+ } {
77
102
  const resources: RouterResource[] = [];
78
103
  const routes: RouterRoute[] = [];
104
+ let appRoot: AppRoot | null = null;
105
+ let gqlContext: GqlContext | null = null;
79
106
 
80
107
  function visitRouterNodes(sourceFile: SourceFile) {
81
- // TODO: Skip sourceFile if a pastora JSDoc tag isn't used at all.
108
+ // Skip generated files
109
+ if (sourceFile.getFilePath().includes('__generated__')) {
110
+ return;
111
+ }
112
+
113
+ // Skip files that don't contain any Pastoria JSDoc tags
114
+ const fileText = sourceFile.getFullText();
115
+ if (!PASTORIA_TAG_REGEX.test(fileText)) {
116
+ return;
117
+ }
118
+
82
119
  sourceFile.getExportSymbols().forEach((symbol) => {
83
120
  let routerResource = null as RouterResource | null;
84
121
  let routerRoute = null as RouterRoute | null;
@@ -117,6 +154,62 @@ function collectRouterNodes(project: Project) {
117
154
  break;
118
155
  }
119
156
  }
157
+ } else {
158
+ // Handle tags without comments (like @appRoot, @gqlContext)
159
+ switch (tag.tagName.getText()) {
160
+ case 'appRoot': {
161
+ if (appRoot != null) {
162
+ console.warn(
163
+ pc.yellow('Warning:'),
164
+ 'Multiple @appRoot tags found. Using the first one.',
165
+ );
166
+ } else {
167
+ appRoot = {
168
+ sourceFile,
169
+ symbol,
170
+ };
171
+ }
172
+ break;
173
+ }
174
+ case 'gqlContext': {
175
+ // Check if this class extends PastoriaRootContext
176
+ const declarations = symbol.getDeclarations();
177
+ let extendsPastoriaRootContext = false;
178
+
179
+ for (const decl of declarations) {
180
+ if (decl.isKind(SyntaxKind.ClassDeclaration)) {
181
+ const classDecl = decl.asKindOrThrow(
182
+ SyntaxKind.ClassDeclaration,
183
+ );
184
+ const extendsClause = classDecl.getExtends();
185
+ if (extendsClause != null) {
186
+ const baseClassName = extendsClause
187
+ .getExpression()
188
+ .getText();
189
+ if (baseClassName === 'PastoriaRootContext') {
190
+ extendsPastoriaRootContext = true;
191
+ break;
192
+ }
193
+ }
194
+ }
195
+ }
196
+
197
+ if (extendsPastoriaRootContext) {
198
+ if (gqlContext != null) {
199
+ console.warn(
200
+ pc.yellow('Warning:'),
201
+ 'Multiple classes with @gqlContext extending PastoriaRootContext found. Using the first one.',
202
+ );
203
+ } else {
204
+ gqlContext = {
205
+ sourceFile,
206
+ symbol,
207
+ };
208
+ }
209
+ }
210
+ break;
211
+ }
212
+ }
120
213
  }
121
214
  }
122
215
 
@@ -131,7 +224,7 @@ function collectRouterNodes(project: Project) {
131
224
  }
132
225
 
133
226
  project.getSourceFiles().forEach(visitRouterNodes);
134
- return {resources, routes} as const;
227
+ return {resources, routes, appRoot, gqlContext};
135
228
  }
136
229
 
137
230
  function zodSchemaOfType(tc: ts.TypeChecker, t: ts.Type): string {
@@ -177,6 +270,88 @@ export async function generatePastoriaArtifacts() {
177
270
  const routerFiles = await loadRouterFiles(project);
178
271
  const routerNodes = collectRouterNodes(project);
179
272
 
273
+ // Generate app_root.ts if @appRoot tag is found
274
+ const appRoot: AppRoot | null = routerNodes.appRoot;
275
+ if (appRoot != null) {
276
+ const appRootSourceFile: SourceFile = appRoot.sourceFile;
277
+ const appRootSymbol: Symbol = appRoot.symbol;
278
+ const filePath = path.relative(targetDir, appRootSourceFile.getFilePath());
279
+ const appRootFile = project.createSourceFile(APP_ROOT_FILENAME, '', {
280
+ overwrite: true,
281
+ });
282
+
283
+ const moduleSpecifier = appRootFile.getRelativePathAsModuleSpecifierTo(
284
+ appRootSourceFile.getFilePath(),
285
+ );
286
+
287
+ appRootFile.addStatements(`/*
288
+ * This file was generated by \`pastoria\`.
289
+ * Do not modify this file directly.
290
+ */
291
+
292
+ export {${appRootSymbol.getName()} as App} from '${moduleSpecifier}';
293
+ `);
294
+
295
+ await appRootFile.save();
296
+
297
+ console.log(
298
+ 'Created app root for',
299
+ pc.green(appRootSymbol.getName()),
300
+ 'exported from',
301
+ pc.yellow(filePath),
302
+ );
303
+ }
304
+
305
+ // Generate context.ts
306
+ const gqlContext: GqlContext | null = routerNodes.gqlContext;
307
+ const contextFile = project.createSourceFile(CONTEXT_FILENAME, '', {
308
+ overwrite: true,
309
+ });
310
+
311
+ if (gqlContext != null) {
312
+ const contextSourceFile: SourceFile = gqlContext.sourceFile;
313
+ const contextSymbol: Symbol = gqlContext.symbol;
314
+ const filePath = path.relative(targetDir, contextSourceFile.getFilePath());
315
+ const moduleSpecifier = contextFile.getRelativePathAsModuleSpecifierTo(
316
+ contextSourceFile.getFilePath(),
317
+ );
318
+
319
+ contextFile.addStatements(`/*
320
+ * This file was generated by \`pastoria\`.
321
+ * Do not modify this file directly.
322
+ */
323
+
324
+ export {${contextSymbol.getName()} as Context} from '${moduleSpecifier}';
325
+ `);
326
+
327
+ console.log(
328
+ 'Created GraphQL context for',
329
+ pc.green(contextSymbol.getName()),
330
+ 'exported from',
331
+ pc.yellow(filePath),
332
+ );
333
+ } else {
334
+ contextFile.addStatements(`/*
335
+ * This file was generated by \`pastoria\`.
336
+ * Do not modify this file directly.
337
+ */
338
+
339
+ import {PastoriaRootContext} from 'pastoria-runtime/server';
340
+
341
+ /**
342
+ * @gqlContext
343
+ */
344
+ export class Context extends PastoriaRootContext {}
345
+ `);
346
+
347
+ console.log(
348
+ 'No @gqlContext found, generating default',
349
+ pc.green('Context'),
350
+ );
351
+ }
352
+
353
+ await contextFile.save();
354
+
180
355
  const resourceConf = routerFiles.jsResource
181
356
  .getVariableDeclarationOrThrow('RESOURCE_CONF')
182
357
  .getInitializerIfKindOrThrow(SyntaxKind.AsExpression)
package/tsconfig.json CHANGED
@@ -13,7 +13,8 @@
13
13
  "esModuleInterop": true,
14
14
  "skipLibCheck": true,
15
15
  "forceConsistentCasingInFileNames": true,
16
- "jsx": "react-jsx"
16
+ "jsx": "react-jsx",
17
+ "noUncheckedIndexedAccess": true
17
18
  },
18
19
  "include": ["src/**/*"],
19
20
  "exclude": ["node_modules", "dist"]