pastoria 1.0.15 → 1.2.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,2 @@
1
+ export declare function runViteBuild(target: 'client' | 'server'): Promise<void>;
2
+ //# sourceMappingURL=build_command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build_command.d.ts","sourceRoot":"","sources":["../src/build_command.ts"],"names":[],"mappings":"AAIA,wBAAsB,YAAY,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,iBAW7D"}
@@ -0,0 +1,13 @@
1
+ import { build } from 'vite';
2
+ import { logInfo } from './logger.js';
3
+ import { CLIENT_BUILD, createBuildConfig, SERVER_BUILD } from './vite_plugin.js';
4
+ export async function runViteBuild(target) {
5
+ const buildType = target === 'client' ? CLIENT_BUILD : SERVER_BUILD;
6
+ logInfo(`Building ${target}...`);
7
+ await build({
8
+ ...createBuildConfig(buildType),
9
+ configFile: false,
10
+ });
11
+ logInfo(`${target} build complete!`);
12
+ }
13
+ //# sourceMappingURL=build_command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build_command.js","sourceRoot":"","sources":["../src/build_command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,MAAM,CAAC;AAC3B,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,EAAC,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAE/E,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAA2B;IAC5D,MAAM,SAAS,GAAG,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC;IAEpE,OAAO,CAAC,YAAY,MAAM,KAAK,CAAC,CAAC;IAEjC,MAAM,KAAK,CAAC;QACV,GAAG,iBAAiB,CAAC,SAAS,CAAC;QAC/B,UAAU,EAAE,KAAK;KAClB,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,MAAM,kBAAkB,CAAC,CAAC;AACvC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"devserver.d.ts","sourceRoot":"","sources":["../src/devserver.ts"],"names":[],"mappings":"AAsBA,wBAAsB,cAAc,CAAC,IAAI,EAAE;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,iBAmCxD"}
1
+ {"version":3,"file":"devserver.d.ts","sourceRoot":"","sources":["../src/devserver.ts"],"names":[],"mappings":"AAoBA,wBAAsB,cAAc,CAAC,IAAI,EAAE;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,iBAiCxD"}
package/dist/devserver.js CHANGED
@@ -2,7 +2,6 @@ import cookieParser from 'cookie-parser';
2
2
  import dotenv from 'dotenv';
3
3
  import express from 'express';
4
4
  import { readFile } from 'node:fs/promises';
5
- import { loadConfig } from 'pastoria-config';
6
5
  import pc from 'picocolors';
7
6
  import { createServer as createViteServer } from 'vite';
8
7
  import { logInfo } from './logger.js';
@@ -15,14 +14,13 @@ export async function startDevserver(opts) {
15
14
  configFile: false,
16
15
  server: { middlewareMode: true },
17
16
  });
18
- const config = await loadConfig();
19
17
  const app = express();
20
18
  app.use(cookieParser());
21
19
  app.use(vite.middlewares);
22
20
  app.use(async (req, res, next) => {
23
21
  const persistedQueries = JSON.parse(await readFile('__generated__/router/persisted_queries.json', 'utf-8'));
24
22
  const { createHandler } = (await vite.ssrLoadModule('virtual:pastoria-entry-server.tsx'));
25
- const handler = createHandler(persistedQueries, config);
23
+ const handler = createHandler(persistedQueries);
26
24
  handler(req, res, next);
27
25
  });
28
26
  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,EAAC,UAAU,EAAiB,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAC,YAAY,IAAI,gBAAgB,EAAgB,MAAM,MAAM,CAAC;AACrE,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,EAAC,YAAY,EAAE,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAcjE,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,EAAE,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QACtD,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,YAAY,IAAI,gBAAgB,EAAgB,MAAM,MAAM,CAAC;AACrE,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,EAAC,YAAY,EAAE,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAajE,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,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,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,EAAE,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QACtD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,188 @@
1
+ /**
2
+ * @fileoverview Filesystem Router Scanner
3
+ *
4
+ * This module scans the `pastoria/` directory to discover routes, pages, and API handlers
5
+ * using a filesystem-based routing convention similar to Next.js App Router.
6
+ *
7
+ * ## File Conventions
8
+ *
9
+ * - `page.tsx` - Defines a page component for a route
10
+ * - `*.page.tsx` - Defines a nested entry point (accessible via props.entryPoints)
11
+ * - `entrypoint.ts` - Manually defined entry point with custom getPreloadProps
12
+ * - `app.tsx` - Root layout component (wraps the entire app)
13
+ * - `route.ts` - API route handler (exports express.Router)
14
+ *
15
+ * ## Route Path Extraction
16
+ *
17
+ * Directory structure maps to URL routes:
18
+ * - `pastoria/page.tsx` → `/`
19
+ * - `pastoria/about/page.tsx` → `/about`
20
+ * - `pastoria/post/[slug]/page.tsx` → `/post/[slug]`
21
+ *
22
+ * Parameters are defined using square brackets: `[paramName]`
23
+ */
24
+ import { Project, SourceFile } from 'ts-morph';
25
+ /**
26
+ * Represents a route parameter extracted from the filesystem path.
27
+ */
28
+ export interface RouteParam {
29
+ /** The parameter name (e.g., "slug", "name") */
30
+ name: string;
31
+ /** Whether the parameter is optional (uses [[param]] syntax) */
32
+ optional: boolean;
33
+ }
34
+ /**
35
+ * Represents a page discovered in the filesystem.
36
+ * Pages are defined by `page.tsx` files and map to URL routes.
37
+ */
38
+ export interface FilesystemPage {
39
+ /** The URL route path (e.g., "/", "/about", "/post/[slug]", "/hello/[[name]]") */
40
+ routePath: string;
41
+ /** The filesystem path relative to project root (e.g., "pastoria/about/page.tsx") */
42
+ filePath: string;
43
+ /** Route parameters extracted from the path (e.g., ["slug"]) - names only for backwards compat */
44
+ params: string[];
45
+ /** Route parameters with optional flag (e.g., [{name: "slug", optional: false}]) */
46
+ routeParams: RouteParam[];
47
+ /**
48
+ * Queries exported from the page file.
49
+ * Maps query reference name to the Relay query type name.
50
+ * e.g., { "blogPosts": "page_BlogPostsQuery" }
51
+ */
52
+ queries: Map<string, string>;
53
+ /**
54
+ * Nested entry points discovered in the same directory.
55
+ * These are files matching `*.page.tsx` (not `page.tsx`).
56
+ * Maps entry point name to its page definition.
57
+ */
58
+ nestedEntryPoints: Map<string, FilesystemPage>;
59
+ /**
60
+ * Whether this nested entry point is optional.
61
+ * Optional entry points are defined with parentheses: `(name).page.tsx`
62
+ * They can be omitted from getPreloadProps return value.
63
+ */
64
+ optional: boolean;
65
+ /**
66
+ * Path to a custom entrypoint.ts file if one exists in the same directory.
67
+ * When present, the schema and getPreloadProps are imported from this file
68
+ * instead of being generated.
69
+ */
70
+ customEntryPointPath: string | null;
71
+ }
72
+ /**
73
+ * Represents a manually defined entry point.
74
+ * These are defined by `entrypoint.ts` files and offer more flexibility.
75
+ */
76
+ export interface FilesystemEntryPoint {
77
+ /** The URL route path */
78
+ routePath: string;
79
+ /** The filesystem path */
80
+ filePath: string;
81
+ /** Route parameters */
82
+ params: string[];
83
+ }
84
+ /**
85
+ * Represents an API route handler.
86
+ * These are defined by `route.ts` files and export express.Router instances.
87
+ */
88
+ export interface FilesystemApiRoute {
89
+ /** The URL route path (e.g., "/api/posts") */
90
+ routePath: string;
91
+ /** The filesystem path */
92
+ filePath: string;
93
+ /** Route parameters */
94
+ params: string[];
95
+ }
96
+ /**
97
+ * Complete metadata about the filesystem routing structure.
98
+ */
99
+ export interface FilesystemMetadata {
100
+ /** All discovered pages, keyed by route path */
101
+ pages: Map<string, FilesystemPage>;
102
+ /** Manually defined entry points, keyed by route path */
103
+ entryPoints: Map<string, FilesystemEntryPoint>;
104
+ /** API route handlers, keyed by route path */
105
+ apiRoutes: Map<string, FilesystemApiRoute>;
106
+ /** Path to app.tsx if it exists, null otherwise */
107
+ appRoot: string | null;
108
+ }
109
+ /**
110
+ * Extracts the route path and parameters from a filesystem path.
111
+ * Route paths preserve the `[param]` and `[[param]]` syntax from the filesystem.
112
+ *
113
+ * @example
114
+ * parseRoutePath("pastoria/post/[slug]/page.tsx")
115
+ * // Returns: { routePath: "/post/[slug]", params: ["slug"], routeParams: [{name: "slug", optional: false}] }
116
+ *
117
+ * @example
118
+ * parseRoutePath("pastoria/hello/[[name]]/page.tsx")
119
+ * // Returns: { routePath: "/hello/[[name]]", params: ["name"], routeParams: [{name: "name", optional: true}] }
120
+ *
121
+ * @example
122
+ * parseRoutePath("pastoria/about/page.tsx")
123
+ * // Returns: { routePath: "/about", params: [], routeParams: [] }
124
+ */
125
+ export declare function parseRoutePath(filePath: string): {
126
+ routePath: string;
127
+ params: string[];
128
+ routeParams: RouteParam[];
129
+ };
130
+ /**
131
+ * Converts a route path from [param]/[[param]] format to :param/:param? format for the router.
132
+ *
133
+ * @example
134
+ * toRouterPath("/post/[slug]")
135
+ * // Returns: "/post/:slug"
136
+ *
137
+ * @example
138
+ * toRouterPath("/hello/[[name]]")
139
+ * // Returns: "/hello/:name?"
140
+ */
141
+ export declare function toRouterPath(routePath: string): string;
142
+ /**
143
+ * Extracts the entry point name from a nested entry point file.
144
+ * Also detects if the entry point is optional (wrapped in parentheses).
145
+ *
146
+ * @example
147
+ * getNestedEntryPointName("pastoria/banner.page.tsx")
148
+ * // Returns: { name: "banner", optional: false }
149
+ *
150
+ * @example
151
+ * getNestedEntryPointName("pastoria/(sidebar).page.tsx")
152
+ * // Returns: { name: "sidebar", optional: true }
153
+ */
154
+ export declare function getNestedEntryPointName(filePath: string): {
155
+ name: string;
156
+ optional: boolean;
157
+ } | null;
158
+ /**
159
+ * Extracts the `queries` export from a page file.
160
+ *
161
+ * Looks for patterns like:
162
+ * ```typescript
163
+ * export const queries = {
164
+ * blogPosts: page_BlogPostsQuery,
165
+ * otherQuery: page_OtherQuery
166
+ * };
167
+ * ```
168
+ *
169
+ * @returns Map of query reference name to query type name
170
+ */
171
+ export declare function extractQueriesFromPage(sourceFile: SourceFile): Map<string, string>;
172
+ /**
173
+ * Gets the default export name from a source file.
174
+ * Used to find the component name for pages.
175
+ */
176
+ export declare function getDefaultExportName(sourceFile: SourceFile): string | null;
177
+ /**
178
+ * Scans the `pastoria/` directory and discovers all routing metadata.
179
+ *
180
+ * Uses the ts-morph Project API to discover files instead of Node fs APIs.
181
+ * This ensures we're working with the same file set that TypeScript knows about.
182
+ */
183
+ export declare function scanFilesystemRoutes(project: Project): FilesystemMetadata;
184
+ /**
185
+ * Checks if a pastoria/ directory exists with routing files.
186
+ */
187
+ export declare function hasFilesystemRoutes(project: Project): boolean;
188
+ //# sourceMappingURL=filesystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../src/filesystem.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAC,OAAO,EAAE,UAAU,EAAa,MAAM,UAAU,CAAC;AAQzD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IAEb,gEAAgE;IAChE,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;IAElB,qFAAqF;IACrF,QAAQ,EAAE,MAAM,CAAC;IAEjB,kGAAkG;IAClG,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB,oFAAoF;IACpF,WAAW,EAAE,UAAU,EAAE,CAAC;IAE1B;;;;OAIG;IACH,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE7B;;;;OAIG;IACH,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAE/C;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;;;OAIG;IACH,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAElB,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IAEjB,uBAAuB;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAElB,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IAEjB,uBAAuB;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAEnC,yDAAyD;IACzD,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAE/C,8CAA8C;IAC9C,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAE3C,mDAAmD;IACnD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B,CAqCA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,GACf;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAC,GAAG,IAAI,CAY1C;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,UAAU,GACrB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAuDrB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAqB1E;AAMD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,kBAAkB,CAyLzE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAI7D"}
@@ -0,0 +1,358 @@
1
+ /**
2
+ * @fileoverview Filesystem Router Scanner
3
+ *
4
+ * This module scans the `pastoria/` directory to discover routes, pages, and API handlers
5
+ * using a filesystem-based routing convention similar to Next.js App Router.
6
+ *
7
+ * ## File Conventions
8
+ *
9
+ * - `page.tsx` - Defines a page component for a route
10
+ * - `*.page.tsx` - Defines a nested entry point (accessible via props.entryPoints)
11
+ * - `entrypoint.ts` - Manually defined entry point with custom getPreloadProps
12
+ * - `app.tsx` - Root layout component (wraps the entire app)
13
+ * - `route.ts` - API route handler (exports express.Router)
14
+ *
15
+ * ## Route Path Extraction
16
+ *
17
+ * Directory structure maps to URL routes:
18
+ * - `pastoria/page.tsx` → `/`
19
+ * - `pastoria/about/page.tsx` → `/about`
20
+ * - `pastoria/post/[slug]/page.tsx` → `/post/[slug]`
21
+ *
22
+ * Parameters are defined using square brackets: `[paramName]`
23
+ */
24
+ import * as path from 'node:path';
25
+ import { SyntaxKind } from 'ts-morph';
26
+ import { logInfo, logWarn } from './logger.js';
27
+ import pc from 'picocolors';
28
+ // ============================================================================
29
+ // Path Parsing Utilities
30
+ // ============================================================================
31
+ /**
32
+ * Extracts the route path and parameters from a filesystem path.
33
+ * Route paths preserve the `[param]` and `[[param]]` syntax from the filesystem.
34
+ *
35
+ * @example
36
+ * parseRoutePath("pastoria/post/[slug]/page.tsx")
37
+ * // Returns: { routePath: "/post/[slug]", params: ["slug"], routeParams: [{name: "slug", optional: false}] }
38
+ *
39
+ * @example
40
+ * parseRoutePath("pastoria/hello/[[name]]/page.tsx")
41
+ * // Returns: { routePath: "/hello/[[name]]", params: ["name"], routeParams: [{name: "name", optional: true}] }
42
+ *
43
+ * @example
44
+ * parseRoutePath("pastoria/about/page.tsx")
45
+ * // Returns: { routePath: "/about", params: [], routeParams: [] }
46
+ */
47
+ export function parseRoutePath(filePath) {
48
+ // Remove the pastoria/ prefix and the filename
49
+ const relativePath = filePath
50
+ .replace(/^pastoria\//, '')
51
+ .replace(/^(page|entrypoint|route)\.(tsx?|ts)$/, '') // Handle root files
52
+ .replace(/\/(page|entrypoint|route)\.(tsx?|ts)$/, '') // Handle nested files
53
+ .replace(/\.page\.(tsx?|ts)$/, ''); // Handle nested entry points
54
+ // Handle root route
55
+ if (relativePath === '') {
56
+ return { routePath: '/', params: [], routeParams: [] };
57
+ }
58
+ const params = [];
59
+ const routeParams = [];
60
+ const segments = relativePath.split('/').filter(Boolean);
61
+ // Collect param names from [param] and [[param]] segments (keep brackets in the path)
62
+ for (const segment of segments) {
63
+ // Check for optional param first: [[param]]
64
+ const optionalMatch = segment.match(/^\[\[(.+)\]\]$/);
65
+ if (optionalMatch && optionalMatch[1]) {
66
+ params.push(optionalMatch[1]);
67
+ routeParams.push({ name: optionalMatch[1], optional: true });
68
+ continue;
69
+ }
70
+ // Check for required param: [param]
71
+ const paramMatch = segment.match(/^\[(.+)\]$/);
72
+ if (paramMatch && paramMatch[1]) {
73
+ params.push(paramMatch[1]);
74
+ routeParams.push({ name: paramMatch[1], optional: false });
75
+ }
76
+ }
77
+ const routePath = '/' + segments.join('/');
78
+ return { routePath, params, routeParams };
79
+ }
80
+ /**
81
+ * Converts a route path from [param]/[[param]] format to :param/:param? format for the router.
82
+ *
83
+ * @example
84
+ * toRouterPath("/post/[slug]")
85
+ * // Returns: "/post/:slug"
86
+ *
87
+ * @example
88
+ * toRouterPath("/hello/[[name]]")
89
+ * // Returns: "/hello/:name?"
90
+ */
91
+ export function toRouterPath(routePath) {
92
+ // First convert optional params [[param]] to :param?
93
+ let result = routePath.replace(/\[\[([^\]]+)\]\]/g, ':$1?');
94
+ // Then convert required params [param] to :param
95
+ result = result.replace(/\[([^\]]+)\]/g, ':$1');
96
+ return result;
97
+ }
98
+ /**
99
+ * Extracts the entry point name from a nested entry point file.
100
+ * Also detects if the entry point is optional (wrapped in parentheses).
101
+ *
102
+ * @example
103
+ * getNestedEntryPointName("pastoria/banner.page.tsx")
104
+ * // Returns: { name: "banner", optional: false }
105
+ *
106
+ * @example
107
+ * getNestedEntryPointName("pastoria/(sidebar).page.tsx")
108
+ * // Returns: { name: "sidebar", optional: true }
109
+ */
110
+ export function getNestedEntryPointName(filePath) {
111
+ const match = filePath.match(/\/([^/]+)\.page\.tsx?$/);
112
+ if (!match?.[1])
113
+ return null;
114
+ const rawName = match[1];
115
+ // Check if wrapped in parentheses: (name) -> optional
116
+ const optionalMatch = rawName.match(/^\(([^)]+)\)$/);
117
+ if (optionalMatch?.[1]) {
118
+ return { name: optionalMatch[1], optional: true };
119
+ }
120
+ return { name: rawName, optional: false };
121
+ }
122
+ // ============================================================================
123
+ // Query Extraction
124
+ // ============================================================================
125
+ /**
126
+ * Extracts the `queries` export from a page file.
127
+ *
128
+ * Looks for patterns like:
129
+ * ```typescript
130
+ * export const queries = {
131
+ * blogPosts: page_BlogPostsQuery,
132
+ * otherQuery: page_OtherQuery
133
+ * };
134
+ * ```
135
+ *
136
+ * @returns Map of query reference name to query type name
137
+ */
138
+ export function extractQueriesFromPage(sourceFile) {
139
+ const queries = new Map();
140
+ // Find the 'queries' export
141
+ const queriesDecl = sourceFile.getVariableDeclaration('queries');
142
+ if (!queriesDecl) {
143
+ return queries;
144
+ }
145
+ // Check if it's exported
146
+ const varStatement = queriesDecl.getParent()?.getParent();
147
+ if (!varStatement?.asKind(SyntaxKind.VariableStatement)?.isExported()) {
148
+ return queries;
149
+ }
150
+ // Get the initializer (the object literal)
151
+ const initializer = queriesDecl.getInitializer();
152
+ if (!initializer?.isKind(SyntaxKind.ObjectLiteralExpression)) {
153
+ logWarn(`Expected 'queries' to be an object literal in ${sourceFile.getFilePath()}`);
154
+ return queries;
155
+ }
156
+ // Extract each property
157
+ const objectLiteral = initializer.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
158
+ for (const prop of objectLiteral.getProperties()) {
159
+ if (prop.isKind(SyntaxKind.PropertyAssignment)) {
160
+ const propAssign = prop.asKindOrThrow(SyntaxKind.PropertyAssignment);
161
+ const keyName = propAssign.getName();
162
+ const valueNode = propAssign.getInitializer();
163
+ if (valueNode?.isKind(SyntaxKind.Identifier)) {
164
+ // The value is a reference to a query type (e.g., page_BlogPostsQuery)
165
+ const queryTypeName = valueNode.getText();
166
+ queries.set(keyName, queryTypeName);
167
+ }
168
+ else if (valueNode?.isKind(SyntaxKind.PropertyAccessExpression)) {
169
+ // Handle cases like SomeModule.QueryType
170
+ const queryTypeName = valueNode.getText();
171
+ queries.set(keyName, queryTypeName);
172
+ }
173
+ }
174
+ else if (prop.isKind(SyntaxKind.ShorthandPropertyAssignment)) {
175
+ // Handle shorthand like { blogPosts } where the key and value are the same
176
+ const shorthand = prop.asKindOrThrow(SyntaxKind.ShorthandPropertyAssignment);
177
+ const name = shorthand.getName();
178
+ queries.set(name, name);
179
+ }
180
+ }
181
+ return queries;
182
+ }
183
+ /**
184
+ * Gets the default export name from a source file.
185
+ * Used to find the component name for pages.
186
+ */
187
+ export function getDefaultExportName(sourceFile) {
188
+ // Check for: export default function Name() {}
189
+ const defaultExportSymbol = sourceFile.getDefaultExportSymbol();
190
+ if (defaultExportSymbol) {
191
+ const declarations = defaultExportSymbol.getDeclarations();
192
+ for (const decl of declarations) {
193
+ // Function declaration
194
+ if (decl.isKind(SyntaxKind.FunctionDeclaration)) {
195
+ return decl.getName() ?? null;
196
+ }
197
+ // Export assignment: export default SomeComponent
198
+ if (decl.isKind(SyntaxKind.ExportAssignment)) {
199
+ const expr = decl.getExpression();
200
+ if (expr.isKind(SyntaxKind.Identifier)) {
201
+ return expr.getText();
202
+ }
203
+ }
204
+ }
205
+ }
206
+ return null;
207
+ }
208
+ // ============================================================================
209
+ // Filesystem Scanner (using ts-morph Project)
210
+ // ============================================================================
211
+ /**
212
+ * Scans the `pastoria/` directory and discovers all routing metadata.
213
+ *
214
+ * Uses the ts-morph Project API to discover files instead of Node fs APIs.
215
+ * This ensures we're working with the same file set that TypeScript knows about.
216
+ */
217
+ export function scanFilesystemRoutes(project) {
218
+ // Add all files in pastoria/ directory to the project
219
+ project.addSourceFilesAtPaths('pastoria/**/*.{ts,tsx}');
220
+ const metadata = {
221
+ pages: new Map(),
222
+ entryPoints: new Map(),
223
+ apiRoutes: new Map(),
224
+ appRoot: null,
225
+ };
226
+ // Categorize files by type
227
+ const pageFiles = [];
228
+ const nestedEntryPointFiles = [];
229
+ const entryPointFiles = [];
230
+ const routeFiles = [];
231
+ // Get all source files and filter to pastoria/ directory
232
+ for (const sourceFile of project.getSourceFiles()) {
233
+ const absolutePath = sourceFile.getFilePath();
234
+ const relativePath = path.relative(process.cwd(), absolutePath);
235
+ // Only process files in the pastoria/ directory
236
+ if (!relativePath.startsWith('pastoria/')) {
237
+ continue;
238
+ }
239
+ const fileName = path.basename(relativePath);
240
+ // Check for app.tsx (root layout)
241
+ if (relativePath === 'pastoria/app.tsx') {
242
+ metadata.appRoot = relativePath;
243
+ logInfo('Found app root at', pc.yellow(relativePath));
244
+ continue;
245
+ }
246
+ // Check for page.tsx files (main routes)
247
+ if (fileName === 'page.tsx' || fileName === 'page.ts') {
248
+ pageFiles.push(sourceFile);
249
+ continue;
250
+ }
251
+ // Check for *.page.tsx files (nested entry points)
252
+ if (/\.page\.tsx?$/.test(fileName)) {
253
+ nestedEntryPointFiles.push(sourceFile);
254
+ continue;
255
+ }
256
+ // Check for entrypoint.ts files (manual entry points)
257
+ if (fileName === 'entrypoint.ts' || fileName === 'entrypoint.tsx') {
258
+ entryPointFiles.push(sourceFile);
259
+ continue;
260
+ }
261
+ // Check for route.ts files (API routes)
262
+ if (fileName === 'route.ts' || fileName === 'route.tsx') {
263
+ routeFiles.push(sourceFile);
264
+ continue;
265
+ }
266
+ }
267
+ // Process page files and extract metadata
268
+ for (const sourceFile of pageFiles) {
269
+ const absolutePath = sourceFile.getFilePath();
270
+ const filePath = path.relative(process.cwd(), absolutePath);
271
+ const { routePath, params, routeParams } = parseRoutePath(filePath);
272
+ const queries = extractQueriesFromPage(sourceFile);
273
+ const page = {
274
+ routePath,
275
+ filePath,
276
+ params,
277
+ routeParams,
278
+ queries,
279
+ nestedEntryPoints: new Map(),
280
+ optional: false, // Main pages are never optional
281
+ customEntryPointPath: null,
282
+ };
283
+ metadata.pages.set(routePath, page);
284
+ logInfo('Found page', pc.cyan(routePath), 'at', pc.yellow(filePath), queries.size > 0 ? `with ${queries.size} queries` : '');
285
+ }
286
+ // Associate nested entry points with their parent pages
287
+ for (const sourceFile of nestedEntryPointFiles) {
288
+ const absolutePath = sourceFile.getFilePath();
289
+ const filePath = path.relative(process.cwd(), absolutePath);
290
+ const entryPointInfo = getNestedEntryPointName(filePath);
291
+ if (!entryPointInfo)
292
+ continue;
293
+ const { name: entryPointName, optional } = entryPointInfo;
294
+ // Find the parent directory's route
295
+ const parentDir = path.dirname(filePath);
296
+ const parentPagePath = path.join(parentDir, 'page.tsx');
297
+ // Parse route from the parent directory
298
+ const { routePath: parentRoutePath } = parseRoutePath(parentPagePath);
299
+ const parentPage = metadata.pages.get(parentRoutePath);
300
+ if (!parentPage) {
301
+ logWarn(`Nested entry point ${filePath} has no parent page.tsx in ${parentDir}`);
302
+ continue;
303
+ }
304
+ const queries = extractQueriesFromPage(sourceFile);
305
+ const { params, routeParams } = parseRoutePath(filePath);
306
+ const nestedPage = {
307
+ routePath: `${parentRoutePath}#${entryPointName}`, // Internal identifier
308
+ filePath,
309
+ params,
310
+ routeParams,
311
+ queries,
312
+ nestedEntryPoints: new Map(), // Nested entry points can't have their own nested entry points
313
+ optional, // Whether this entry point can be omitted
314
+ customEntryPointPath: null, // Nested entry points can't have custom entrypoint.ts
315
+ };
316
+ parentPage.nestedEntryPoints.set(entryPointName, nestedPage);
317
+ logInfo('Found nested entry point', pc.cyan(entryPointName), optional ? pc.yellow('(optional)') : '', 'for route', pc.cyan(parentRoutePath));
318
+ }
319
+ // Associate custom entrypoint.ts files with their colocated page.tsx
320
+ for (const sourceFile of entryPointFiles) {
321
+ const absolutePath = sourceFile.getFilePath();
322
+ const filePath = path.relative(process.cwd(), absolutePath);
323
+ const { routePath } = parseRoutePath(filePath);
324
+ // Find the colocated page
325
+ const page = metadata.pages.get(routePath);
326
+ if (!page) {
327
+ logWarn(`Custom entrypoint.ts at ${filePath} has no colocated page.tsx for route ${routePath}. ` +
328
+ `Each entrypoint.ts must have a colocated page.tsx file.`);
329
+ continue;
330
+ }
331
+ // Associate the custom entrypoint with the page
332
+ page.customEntryPointPath = filePath;
333
+ logInfo('Found custom entrypoint', pc.cyan(routePath), 'at', pc.yellow(filePath));
334
+ }
335
+ // Process API route files
336
+ for (const sourceFile of routeFiles) {
337
+ const absolutePath = sourceFile.getFilePath();
338
+ const filePath = path.relative(process.cwd(), absolutePath);
339
+ const { routePath, params } = parseRoutePath(filePath);
340
+ const apiRoute = {
341
+ routePath,
342
+ filePath,
343
+ params,
344
+ };
345
+ metadata.apiRoutes.set(routePath, apiRoute);
346
+ logInfo('Found API route', pc.cyan(routePath), 'at', pc.yellow(filePath));
347
+ }
348
+ return metadata;
349
+ }
350
+ /**
351
+ * Checks if a pastoria/ directory exists with routing files.
352
+ */
353
+ export function hasFilesystemRoutes(project) {
354
+ // Try to find any source files in the pastoria/ directory
355
+ const pastoriaFiles = project.getSourceFiles('pastoria/**/*.{ts,tsx}');
356
+ return pastoriaFiles.length > 0;
357
+ }
358
+ //# sourceMappingURL=filesystem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../src/filesystem.ts"],"names":[],"mappings":"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"}
package/dist/gen.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function runCodeGeneration(): Promise<void>;
2
+ //# sourceMappingURL=gen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gen.d.ts","sourceRoot":"","sources":["../src/gen.ts"],"names":[],"mappings":"AAQA,wBAAsB,iBAAiB,kBAiBtC"}
package/dist/gen.js ADDED
@@ -0,0 +1,19 @@
1
+ import * as path from 'node:path';
2
+ import { IndentationText, Project } from 'ts-morph';
3
+ import { generatePastoriaArtifacts, generatePastoriaExports, } from './generate.js';
4
+ import { logInfo } from './logger.js';
5
+ export async function runCodeGeneration() {
6
+ const project = new Project({
7
+ tsConfigFilePath: path.join(process.cwd(), 'tsconfig.json'),
8
+ manipulationSettings: {
9
+ indentationText: IndentationText.TwoSpaces,
10
+ },
11
+ });
12
+ logInfo('Generating Pastoria artifacts...');
13
+ // Generate exports and collect metadata
14
+ const metadata = await generatePastoriaExports(project);
15
+ // Generate artifacts using cached metadata
16
+ await generatePastoriaArtifacts(project, metadata);
17
+ logInfo('Code generation complete!');
18
+ }
19
+ //# sourceMappingURL=gen.js.map