pastoria 1.0.1 → 1.0.3

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.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix package.json bin config
8
+
9
+ ## 1.0.2
10
+
11
+ ### Patch Changes
12
+
13
+ - Remove usage of experimentalStripTypes
14
+
3
15
  ## 1.0.1
4
16
 
5
17
  ### Patch Changes
@@ -0,0 +1,39 @@
1
+ import { type BuildEnvironmentOptions, type Plugin } from 'vite';
2
+ export declare const CLIENT_BUILD: BuildEnvironmentOptions;
3
+ export declare const SERVER_BUILD: BuildEnvironmentOptions;
4
+ export declare function createBuildConfig(buildEnv: BuildEnvironmentOptions): {
5
+ appType: "custom";
6
+ build: {
7
+ assetsInlineLimit: number;
8
+ manifest: boolean;
9
+ ssrManifest: boolean;
10
+ target?: "baseline-widely-available" | import("vite").EsbuildTransformOptions["target"] | false;
11
+ polyfillModulePreload?: boolean;
12
+ modulePreload?: boolean | import("vite").ModulePreloadOptions;
13
+ outDir?: string;
14
+ assetsDir?: string;
15
+ cssCodeSplit?: boolean;
16
+ cssTarget?: import("vite").EsbuildTransformOptions["target"] | false;
17
+ cssMinify?: boolean | "esbuild" | "lightningcss";
18
+ sourcemap?: boolean | "inline" | "hidden";
19
+ minify?: boolean | "terser" | "esbuild";
20
+ terserOptions?: import("vite").TerserOptions;
21
+ rollupOptions?: import("rollup").RollupOptions;
22
+ commonjsOptions?: import("vite").RollupCommonJSOptions;
23
+ dynamicImportVarsOptions?: import("vite").RollupDynamicImportVarsOptions;
24
+ write?: boolean;
25
+ emptyOutDir?: boolean | null;
26
+ copyPublicDir?: boolean;
27
+ lib?: import("vite").LibraryOptions | false;
28
+ ssr?: boolean | string;
29
+ ssrEmitAssets?: boolean;
30
+ emitAssets?: boolean;
31
+ reportCompressedSize?: boolean;
32
+ chunkSizeWarningLimit?: number;
33
+ watch?: import("rollup").WatcherOptions | null;
34
+ createEnvironment?: (name: string, config: import("vite").ResolvedConfig) => Promise<import("vite").BuildEnvironment> | import("vite").BuildEnvironment;
35
+ };
36
+ plugins: (Plugin<any> | Plugin<any>[])[];
37
+ };
38
+ export declare function createBuild(): Promise<void>;
39
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAGA,OAAO,EAAQ,KAAK,uBAAuB,EAAE,KAAK,MAAM,EAAC,MAAM,MAAM,CAAC;AA8EtE,eAAO,MAAM,YAAY,EAAE,uBAK1B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,uBAM1B,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBlE;AAED,wBAAsB,WAAW,kBAUhC"}
package/dist/build.js ADDED
@@ -0,0 +1,121 @@
1
+ import react from '@vitejs/plugin-react';
2
+ import tailwindcss from '@tailwindcss/vite';
3
+ import { cjsInterop } from 'vite-plugin-cjs-interop';
4
+ import { build } from 'vite';
5
+ // TODO: Only emit `App` code if _app exits.
6
+ const PASTORIA_CLIENT_ENTRY = `// Generated by Pastoria.
7
+ import {createRouterApp} from '#genfiles/router/router';
8
+ import {App} from '#src/pages/_app';
9
+ import {hydrateRoot} from 'react-dom/client';
10
+
11
+ async function main() {
12
+ const RouterApp = await createRouterApp();
13
+ hydrateRoot(document, <RouterApp App={App} />);
14
+ }
15
+
16
+ main();
17
+ `;
18
+ // TODO: Remove hard-coded context import here.
19
+ const PASTORIA_ENTRY_SERVER = `// Generated by Pastoria.
20
+ import {JSResource} from '#genfiles/router/js_resource';
21
+ import {
22
+ listRoutes,
23
+ router__createAppFromEntryPoint,
24
+ router__loadEntryPoint,
25
+ } from '#genfiles/router/router';
26
+ import {getSchema} from '#genfiles/schema/schema';
27
+ import {Context} from '#src/lib/server/context';
28
+ import {App} from '#src/pages/_app';
29
+ import {GraphQLSchema, specifiedDirectives} from 'graphql';
30
+ import {createRouterHandler} from 'pastoria-runtime/server';
31
+ import type {Manifest} from 'vite';
32
+
33
+ const schemaConfig = getSchema().toConfig();
34
+ const schema = new GraphQLSchema({
35
+ ...schemaConfig,
36
+ directives: [...specifiedDirectives, ...schemaConfig.directives],
37
+ });
38
+
39
+ export function createHandler(
40
+ persistedQueries: Record<string, string>,
41
+ manifest?: Manifest,
42
+ ) {
43
+ return createRouterHandler(
44
+ listRoutes(),
45
+ JSResource.srcOfModuleId,
46
+ router__loadEntryPoint,
47
+ router__createAppFromEntryPoint,
48
+ App,
49
+ schema,
50
+ () => new Context(),
51
+ persistedQueries,
52
+ manifest,
53
+ );
54
+ }
55
+ `;
56
+ function pastoriaEntryPlugin() {
57
+ const clientEntryModuleId = 'virtual:pastoria-entry-client.tsx';
58
+ const serverEntryModuleId = 'virtual:pastoria-entry-server.tsx';
59
+ return {
60
+ name: 'pastoria-entry',
61
+ resolveId(id) {
62
+ if (id === clientEntryModuleId) {
63
+ return clientEntryModuleId; // Return without \0 prefix so React plugin can see .tsx extension
64
+ }
65
+ else if (id === serverEntryModuleId) {
66
+ return serverEntryModuleId;
67
+ }
68
+ },
69
+ load(id) {
70
+ if (id === clientEntryModuleId) {
71
+ return PASTORIA_CLIENT_ENTRY;
72
+ }
73
+ else if (id === serverEntryModuleId) {
74
+ return PASTORIA_ENTRY_SERVER;
75
+ }
76
+ },
77
+ };
78
+ }
79
+ export const CLIENT_BUILD = {
80
+ outDir: 'dist/client',
81
+ rollupOptions: {
82
+ input: 'virtual:pastoria-entry-client.tsx',
83
+ },
84
+ };
85
+ export const SERVER_BUILD = {
86
+ outDir: 'dist/server',
87
+ ssr: true,
88
+ rollupOptions: {
89
+ input: 'virtual:pastoria-entry-server.tsx',
90
+ },
91
+ };
92
+ export function createBuildConfig(buildEnv) {
93
+ return {
94
+ appType: 'custom',
95
+ build: {
96
+ ...buildEnv,
97
+ assetsInlineLimit: 0,
98
+ manifest: true,
99
+ ssrManifest: true,
100
+ },
101
+ plugins: [
102
+ pastoriaEntryPlugin(),
103
+ tailwindcss(),
104
+ react({ babel: { plugins: ['relay'] } }),
105
+ cjsInterop({
106
+ dependencies: ['react-relay', 'react-relay/hooks', 'relay-runtime'],
107
+ }),
108
+ ],
109
+ };
110
+ }
111
+ export async function createBuild() {
112
+ const clientBuild = await build({
113
+ ...createBuildConfig(CLIENT_BUILD),
114
+ configFile: false,
115
+ });
116
+ const serverBuild = await build({
117
+ ...createBuildConfig(SERVER_BUILD),
118
+ configFile: false,
119
+ });
120
+ }
121
+ //# sourceMappingURL=build.js.map
@@ -0,0 +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,EAAC,KAAK,EAA4C,MAAM,MAAM,CAAC;AAEtE,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,CAAC,QAAiC;IACjE,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;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"}
@@ -0,0 +1,4 @@
1
+ export declare function startDevserver(opts: {
2
+ port: string;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=devserver.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,34 @@
1
+ import cookieParser from 'cookie-parser';
2
+ import dotenv from 'dotenv';
3
+ import express from 'express';
4
+ import { readFile } from 'node:fs/promises';
5
+ import pc from 'picocolors';
6
+ import { createServer as createViteServer } from 'vite';
7
+ import { CLIENT_BUILD, createBuildConfig } from './build';
8
+ export async function startDevserver(opts) {
9
+ dotenv.config();
10
+ const buildConfig = createBuildConfig(CLIENT_BUILD);
11
+ const vite = await createViteServer({
12
+ ...buildConfig,
13
+ configFile: false,
14
+ server: { middlewareMode: true },
15
+ });
16
+ const app = express();
17
+ app.use(cookieParser());
18
+ app.use(vite.middlewares);
19
+ app.use(async (req, res, next) => {
20
+ const persistedQueries = JSON.parse(await readFile('__generated__/persisted_queries.json', 'utf-8'));
21
+ const { createHandler } = (await vite.ssrLoadModule('virtual:pastoria-entry-server.tsx'));
22
+ const handler = createHandler(persistedQueries);
23
+ handler(req, res, next);
24
+ });
25
+ app.listen(Number(opts.port), (err) => {
26
+ if (err) {
27
+ console.error(err);
28
+ }
29
+ else {
30
+ console.log(pc.cyan(`Listening on port ${opts.port}!`));
31
+ }
32
+ });
33
+ }
34
+ //# sourceMappingURL=devserver.js.map
@@ -0,0 +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,SAAS,CAAC;AAaxD,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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @fileoverview Router Code Generator
3
+ *
4
+ * This script generates type-safe router configuration files by scanning TypeScript
5
+ * source code for JSDoc annotations. It's part of the "Pastoria" routing framework.
6
+ *
7
+ * How it works:
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:
11
+ * - js_resource.ts: Resource configuration for lazy loading
12
+ * - router.tsx: Client-side router with type-safe routes
13
+ * - server_router.ts: Server-side router configuration
14
+ *
15
+ * Usage:
16
+ * - Add @route <route-name> to functions to create routes
17
+ * - Add @param <name> <type> to document route parameters
18
+ * - Add @resource <resource-name> to exports for lazy loading
19
+ *
20
+ * The generator automatically creates Zod schemas for route parameters based on
21
+ * TypeScript types, enabling runtime validation and type safety.
22
+ */
23
+ export declare function generatePastoriaArtifacts(): Promise<void>;
24
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAoJH,wBAAsB,yBAAyB,kBA2G9C"}
@@ -0,0 +1,209 @@
1
+ /**
2
+ * @fileoverview Router Code Generator
3
+ *
4
+ * This script generates type-safe router configuration files by scanning TypeScript
5
+ * source code for JSDoc annotations. It's part of the "Pastoria" routing framework.
6
+ *
7
+ * How it works:
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:
11
+ * - js_resource.ts: Resource configuration for lazy loading
12
+ * - router.tsx: Client-side router with type-safe routes
13
+ * - server_router.ts: Server-side router configuration
14
+ *
15
+ * Usage:
16
+ * - Add @route <route-name> to functions to create routes
17
+ * - Add @param <name> <type> to document route parameters
18
+ * - Add @resource <resource-name> to exports for lazy loading
19
+ *
20
+ * The generator automatically creates Zod schemas for route parameters based on
21
+ * TypeScript types, enabling runtime validation and type safety.
22
+ */
23
+ import { readFile } from 'node:fs/promises';
24
+ import * as path from 'node:path';
25
+ import { default as pc } from 'picocolors';
26
+ import { Project, SyntaxKind, ts, TypeFlags } from 'ts-morph';
27
+ const JS_RESOURCE_FILENAME = '__generated__/router/js_resource.ts';
28
+ const JS_RESOURCE_TEMPLATE = path.join(import.meta.dirname, '../templates/js_resource.ts');
29
+ const ROUTER_FILENAME = '__generated__/router/router.tsx';
30
+ const ROUTER_TEMPLATE = path.join(import.meta.dirname, '../templates/router.tsx');
31
+ async function loadRouterFiles(project) {
32
+ async function loadSourceFile(fileName, templateFileName) {
33
+ const template = await readFile(templateFileName, 'utf-8');
34
+ const warningComment = `/*
35
+ * This file was generated by \`pastoria\`.
36
+ * Do not modify this file directly. Instead, edit the template at ${path.basename(templateFileName)}.
37
+ */
38
+
39
+ `;
40
+ return project.createSourceFile(fileName, warningComment + template, {
41
+ overwrite: true,
42
+ });
43
+ }
44
+ const [jsResource, router] = await Promise.all([
45
+ loadSourceFile(JS_RESOURCE_FILENAME, JS_RESOURCE_TEMPLATE),
46
+ loadSourceFile(ROUTER_FILENAME, ROUTER_TEMPLATE),
47
+ ]);
48
+ return { jsResource, router };
49
+ }
50
+ function collectRouterNodes(project) {
51
+ const resources = [];
52
+ const routes = [];
53
+ function visitRouterNodes(sourceFile) {
54
+ // TODO: Skip sourceFile if a pastora JSDoc tag isn't used at all.
55
+ sourceFile.getExportSymbols().forEach((symbol) => {
56
+ let routerResource = null;
57
+ let routerRoute = null;
58
+ const routeParams = new Map();
59
+ function visitJSDocTags(tag) {
60
+ if (ts.isJSDoc(tag)) {
61
+ tag.tags?.forEach(visitJSDocTags);
62
+ }
63
+ else if (ts.isJSDocParameterTag(tag)) {
64
+ const typeNode = tag.typeExpression?.type;
65
+ const tc = project.getTypeChecker().compilerObject;
66
+ const type = typeNode == null
67
+ ? tc.getUnknownType()
68
+ : tc.getTypeFromTypeNode(typeNode);
69
+ routeParams.set(tag.name.getText(), type);
70
+ }
71
+ else if (typeof tag.comment === 'string') {
72
+ switch (tag.tagName.getText()) {
73
+ case 'route': {
74
+ routerRoute = {
75
+ routeName: tag.comment,
76
+ sourceFile,
77
+ symbol,
78
+ params: routeParams,
79
+ };
80
+ break;
81
+ }
82
+ case 'resource': {
83
+ routerResource = {
84
+ resourceName: tag.comment,
85
+ sourceFile,
86
+ symbol,
87
+ };
88
+ break;
89
+ }
90
+ }
91
+ }
92
+ }
93
+ symbol
94
+ .getDeclarations()
95
+ .flatMap((decl) => ts.getJSDocCommentsAndTags(decl.compilerNode))
96
+ .forEach(visitJSDocTags);
97
+ if (routerRoute != null)
98
+ routes.push(routerRoute);
99
+ if (routerResource != null)
100
+ resources.push(routerResource);
101
+ });
102
+ }
103
+ project.getSourceFiles().forEach(visitRouterNodes);
104
+ return { resources, routes };
105
+ }
106
+ function zodSchemaOfType(tc, t) {
107
+ if (t.getFlags() & TypeFlags.String) {
108
+ return `z.pipe(z.string(), z.transform(decodeURIComponent))`;
109
+ }
110
+ else if (t.getFlags() & TypeFlags.Number) {
111
+ return `z.coerce.number<number>()`;
112
+ }
113
+ else if (t.getFlags() & TypeFlags.Null) {
114
+ return `z.preprocess(s => s == null ? undefined : s, z.undefined())`;
115
+ }
116
+ else if (t.isUnion()) {
117
+ const isRepresentingOptional = t.types.length === 2 &&
118
+ t.types.some((s) => s.getFlags() & TypeFlags.Null);
119
+ if (isRepresentingOptional) {
120
+ const nonOptionalType = t.types.find((s) => !(s.getFlags() & TypeFlags.Null));
121
+ return `z.pipe(z.nullish(${zodSchemaOfType(tc, nonOptionalType)}), z.transform(s => s == null ? undefined : s))`;
122
+ }
123
+ else {
124
+ return `z.union([${t.types.map((it) => zodSchemaOfType(tc, it)).join(', ')}])`;
125
+ }
126
+ }
127
+ else if (tc.isArrayLikeType(t)) {
128
+ const typeArg = tc.getTypeArguments(t)[0];
129
+ const argZodSchema = typeArg == null ? `z.any()` : zodSchemaOfType(tc, typeArg);
130
+ return `z.array(${argZodSchema})`;
131
+ }
132
+ else {
133
+ console.log('Could not handle type:', tc.typeToString(t));
134
+ return `z.any()`;
135
+ }
136
+ }
137
+ export async function generatePastoriaArtifacts() {
138
+ const targetDir = process.cwd();
139
+ const project = new Project({
140
+ tsConfigFilePath: path.join(targetDir, 'tsconfig.json'),
141
+ });
142
+ const tc = project.getTypeChecker().compilerObject;
143
+ const routerFiles = await loadRouterFiles(project);
144
+ const routerNodes = collectRouterNodes(project);
145
+ const resourceConf = routerFiles.jsResource
146
+ .getVariableDeclarationOrThrow('RESOURCE_CONF')
147
+ .getInitializerIfKindOrThrow(SyntaxKind.AsExpression)
148
+ .getExpressionIfKindOrThrow(SyntaxKind.ObjectLiteralExpression);
149
+ resourceConf.getPropertyOrThrow('noop').remove();
150
+ for (const { resourceName, sourceFile, symbol } of routerNodes.resources) {
151
+ const filePath = path.relative(process.cwd(), sourceFile.getFilePath());
152
+ const moduleSpecifier = routerFiles.jsResource.getRelativePathAsModuleSpecifierTo(sourceFile.getFilePath());
153
+ resourceConf.addPropertyAssignment({
154
+ name: `"${resourceName}"`,
155
+ initializer: (writer) => {
156
+ writer.block(() => {
157
+ writer
158
+ .writeLine(`src: "${filePath}",`)
159
+ .writeLine(`loader: () => import("${moduleSpecifier}").then(m => m.${symbol.getName()})`);
160
+ });
161
+ },
162
+ });
163
+ console.log('Created resource', pc.cyan(resourceName), 'for', pc.green(symbol.getName()), 'exported from', pc.yellow(filePath));
164
+ }
165
+ const routerConf = routerFiles.router
166
+ .getVariableDeclarationOrThrow('ROUTER_CONF')
167
+ .getInitializerIfKindOrThrow(SyntaxKind.AsExpression)
168
+ .getExpressionIfKindOrThrow(SyntaxKind.ObjectLiteralExpression);
169
+ routerConf.getPropertyOrThrow('noop').remove();
170
+ let entryPointImportIndex = 0;
171
+ for (const { routeName, sourceFile, symbol, params } of routerNodes.routes) {
172
+ const importAlias = `e${entryPointImportIndex++}`;
173
+ const filePath = path.relative(process.cwd(), sourceFile.getFilePath());
174
+ const moduleSpecifier = routerFiles.router.getRelativePathAsModuleSpecifierTo(sourceFile.getFilePath());
175
+ routerFiles.router.addImportDeclaration({
176
+ moduleSpecifier,
177
+ namedImports: [
178
+ {
179
+ name: symbol.getName(),
180
+ alias: importAlias,
181
+ },
182
+ ],
183
+ });
184
+ routerConf.addPropertyAssignment({
185
+ name: `"${routeName}"`,
186
+ initializer: (writer) => {
187
+ writer
188
+ .write('{')
189
+ .indent(() => {
190
+ writer.writeLine(`entrypoint: ${importAlias},`);
191
+ if (params.size === 0) {
192
+ writer.writeLine(`schema: z.object({})`);
193
+ }
194
+ else {
195
+ writer.writeLine(`schema: z.object({`);
196
+ for (const [paramName, paramType] of Array.from(params)) {
197
+ writer.writeLine(` ${paramName}: ${zodSchemaOfType(tc, paramType)},`);
198
+ }
199
+ writer.writeLine('})');
200
+ }
201
+ })
202
+ .write('} as const');
203
+ },
204
+ });
205
+ console.log('Created route', pc.cyan(routeName), 'for', pc.green(symbol.getName()), 'exported from', pc.yellow(filePath));
206
+ }
207
+ await Promise.all([routerFiles.jsResource.save(), routerFiles.router.save()]);
208
+ }
209
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ import { program } from 'commander';
3
+ import { readFile } from 'node:fs/promises';
4
+ import * as path from 'node:path';
5
+ import { createBuild } from './build';
6
+ import { startDevserver } from './devserver';
7
+ import { generatePastoriaArtifacts } from './generate';
8
+ async function main() {
9
+ const packageData = JSON.parse(await readFile(path.join(import.meta.dirname, '../package.json'), 'utf-8'));
10
+ program
11
+ .name('pastoria')
12
+ .description(packageData.description)
13
+ .version(packageData.version);
14
+ program
15
+ .command('gen')
16
+ .description('Run Pastoria code generation')
17
+ .action(generatePastoriaArtifacts);
18
+ program
19
+ .command('dev')
20
+ .description('Start the pastoria devserver')
21
+ .option('--port <port>', 'Port the devserver will listen on', '3000')
22
+ .action(startDevserver);
23
+ program
24
+ .command('build')
25
+ .description('Creates a production build of the project')
26
+ .action(createBuild);
27
+ program.parseAsync();
28
+ }
29
+ main().catch(console.error);
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAClC,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAC,WAAW,EAAC,MAAM,SAAS,CAAC;AACpC,OAAO,EAAC,cAAc,EAAC,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAC,yBAAyB,EAAC,MAAM,YAAY,CAAC;AAErD,KAAK,UAAU,IAAI;IACjB,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC5B,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAC3E,CAAC;IAEF,OAAO;SACJ,IAAI,CAAC,UAAU,CAAC;SAChB,WAAW,CAAC,WAAW,CAAC,WAAW,CAAC;SACpC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAEhC,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,8BAA8B,CAAC;SAC3C,MAAM,CAAC,yBAAyB,CAAC,CAAC;IAErC,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,8BAA8B,CAAC;SAC3C,MAAM,CAAC,eAAe,EAAE,mCAAmC,EAAE,MAAM,CAAC;SACpE,MAAM,CAAC,cAAc,CAAC,CAAC;IAE1B,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,2CAA2C,CAAC;SACxD,MAAM,CAAC,WAAW,CAAC,CAAC;IAEvB,OAAO,CAAC,UAAU,EAAE,CAAC;AACvB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "pastoria",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Pastoria Development CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
7
9
  "bin": {
8
- "pastoria": "src/index.mts"
10
+ "pastoria": "./dist/index.js"
9
11
  },
10
12
  "dependencies": {
11
13
  "@tailwindcss/vite": "^4.1.14",
@@ -20,11 +22,14 @@
20
22
  "vite-plugin-cjs-interop": "^2.3.0"
21
23
  },
22
24
  "devDependencies": {
25
+ "@types/cookie-parser": "^1.4.9",
26
+ "@types/express": "^5.0.3",
23
27
  "@types/node": "^22.12.0",
24
28
  "typescript": "^5.9.2",
25
- "pastoria-runtime": "1.0.1"
29
+ "pastoria-runtime": "1.0.2"
26
30
  },
27
31
  "scripts": {
32
+ "build": "tsc",
28
33
  "check:types": "tsc --noEmit"
29
34
  }
30
35
  }
@@ -4,7 +4,7 @@ import express from 'express';
4
4
  import {readFile} from 'node:fs/promises';
5
5
  import pc from 'picocolors';
6
6
  import {createServer as createViteServer, type Manifest} from 'vite';
7
- import {CLIENT_BUILD, createBuildConfig} from './build.mts';
7
+ import {CLIENT_BUILD, createBuildConfig} from './build';
8
8
 
9
9
  interface PersistedQueries {
10
10
  [hash: string]: string;
@@ -28,13 +28,13 @@ import {Project, SourceFile, Symbol, SyntaxKind, ts, TypeFlags} from 'ts-morph';
28
28
 
29
29
  const JS_RESOURCE_FILENAME = '__generated__/router/js_resource.ts';
30
30
  const JS_RESOURCE_TEMPLATE = path.join(
31
- path.dirname(new URL(import.meta.url).pathname),
31
+ import.meta.dirname,
32
32
  '../templates/js_resource.ts',
33
33
  );
34
34
 
35
35
  const ROUTER_FILENAME = '__generated__/router/router.tsx';
36
36
  const ROUTER_TEMPLATE = path.join(
37
- path.dirname(new URL(import.meta.url).pathname),
37
+ import.meta.dirname,
38
38
  '../templates/router.tsx',
39
39
  );
40
40
 
package/src/index.ts ADDED
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {program} from 'commander';
4
+ import {readFile} from 'node:fs/promises';
5
+ import * as path from 'node:path';
6
+ import {createBuild} from './build';
7
+ import {startDevserver} from './devserver';
8
+ import {generatePastoriaArtifacts} from './generate';
9
+
10
+ async function main() {
11
+ const packageData = JSON.parse(
12
+ await readFile(path.join(import.meta.dirname, '../package.json'), 'utf-8'),
13
+ );
14
+
15
+ program
16
+ .name('pastoria')
17
+ .description(packageData.description)
18
+ .version(packageData.version);
19
+
20
+ program
21
+ .command('gen')
22
+ .description('Run Pastoria code generation')
23
+ .action(generatePastoriaArtifacts);
24
+
25
+ program
26
+ .command('dev')
27
+ .description('Start the pastoria devserver')
28
+ .option('--port <port>', 'Port the devserver will listen on', '3000')
29
+ .action(startDevserver);
30
+
31
+ program
32
+ .command('build')
33
+ .description('Creates a production build of the project')
34
+ .action(createBuild);
35
+
36
+ program.parseAsync();
37
+ }
38
+
39
+ main().catch(console.error);
package/tsconfig.json CHANGED
@@ -1,18 +1,19 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "allowSyntheticDefaultImports": true,
4
+ "module": "ES2022",
5
+ "lib": ["ES2022", "DOM"],
6
+ "moduleResolution": "bundler",
7
+ "outDir": "./dist",
8
+ "rootDir": "./src",
9
+ "declaration": true,
10
+ "declarationMap": true,
11
+ "sourceMap": true,
12
+ "strict": true,
7
13
  "esModuleInterop": true,
8
- "strict": false,
9
14
  "skipLibCheck": true,
10
15
  "forceConsistentCasingInFileNames": true,
11
- "downlevelIteration": true,
12
- "types": ["node"],
13
- "lib": ["ES2022"],
14
- "noEmit": true,
15
- "allowImportingTsExtensions": true
16
+ "jsx": "react-jsx"
16
17
  },
17
18
  "include": ["src/**/*"],
18
19
  "exclude": ["node_modules", "dist"]
package/src/index.mts DELETED
@@ -1,30 +0,0 @@
1
- #!/usr/bin/env node --experimental-strip-types
2
-
3
- import {program} from 'commander';
4
- import packageData from '../package.json' with {type: 'json'};
5
- import {generatePastoriaArtifacts} from './generate.mts';
6
- import {startDevserver} from './devserver.mts';
7
- import {createBuild} from './build.mts';
8
-
9
- program
10
- .name('pastoria')
11
- .description(packageData.description)
12
- .version(packageData.version);
13
-
14
- program
15
- .command('gen')
16
- .description('Run Pastoria code generation')
17
- .action(generatePastoriaArtifacts);
18
-
19
- program
20
- .command('dev')
21
- .description('Start the pastoria devserver')
22
- .option('--port <port>', 'Port the devserver will listen on', '3000')
23
- .action(startDevserver);
24
-
25
- program
26
- .command('build')
27
- .description('Creates a production build of the project')
28
- .action(createBuild);
29
-
30
- program.parseAsync();
File without changes