@vistagenic/vista 0.2.1 → 0.2.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.
Files changed (38) hide show
  1. package/LICENSE +21 -0
  2. package/bin/vista.js +30 -20
  3. package/dist/bin/build-rsc.js +6 -4
  4. package/dist/bin/generate.d.ts +7 -0
  5. package/dist/bin/generate.js +248 -0
  6. package/dist/config.d.ts +19 -0
  7. package/dist/config.js +62 -4
  8. package/dist/server/engine.js +23 -57
  9. package/dist/server/rsc-engine.js +21 -48
  10. package/dist/server/static-generator.js +98 -0
  11. package/dist/server/structure-validator.js +1 -1
  12. package/dist/server/typed-api-runtime.d.ts +16 -0
  13. package/dist/server/typed-api-runtime.js +336 -0
  14. package/dist/stack/client/create-client.d.ts +2 -0
  15. package/dist/stack/client/create-client.js +195 -0
  16. package/dist/stack/client/error.d.ts +18 -0
  17. package/dist/stack/client/error.js +22 -0
  18. package/dist/stack/client/index.d.ts +9 -0
  19. package/dist/stack/client/index.js +13 -0
  20. package/dist/stack/client/types.d.ts +39 -0
  21. package/dist/stack/client/types.js +2 -0
  22. package/dist/stack/index.d.ts +32 -0
  23. package/dist/stack/index.js +45 -0
  24. package/dist/stack/server/executor.d.ts +36 -0
  25. package/dist/stack/server/executor.js +174 -0
  26. package/dist/stack/server/index.d.ts +10 -0
  27. package/dist/stack/server/index.js +23 -0
  28. package/dist/stack/server/merge-routers.d.ts +2 -0
  29. package/dist/stack/server/merge-routers.js +80 -0
  30. package/dist/stack/server/procedure.d.ts +18 -0
  31. package/dist/stack/server/procedure.js +58 -0
  32. package/dist/stack/server/router.d.ts +9 -0
  33. package/dist/stack/server/router.js +80 -0
  34. package/dist/stack/server/serialization.d.ts +9 -0
  35. package/dist/stack/server/serialization.js +119 -0
  36. package/dist/stack/server/types.d.ts +100 -0
  37. package/dist/stack/server/types.js +2 -0
  38. package/package.json +11 -2
@@ -0,0 +1,195 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createVistaClient = createVistaClient;
4
+ const serialization_1 = require("../server/serialization");
5
+ const error_1 = require("./error");
6
+ function resolveFetchImpl(fetchImpl) {
7
+ if (fetchImpl) {
8
+ return fetchImpl;
9
+ }
10
+ if (typeof fetch !== 'function') {
11
+ throw new Error('Global fetch is not available. Provide a fetch implementation via createVistaClient({ fetch }).');
12
+ }
13
+ return fetch;
14
+ }
15
+ function normalizeBaseUrl(baseUrl) {
16
+ if (!baseUrl) {
17
+ return '';
18
+ }
19
+ return baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
20
+ }
21
+ function normalizePath(path) {
22
+ if (!path) {
23
+ return '/';
24
+ }
25
+ return path.startsWith('/') ? path : `/${path}`;
26
+ }
27
+ function toQueryParams(input, serialization) {
28
+ const params = new URLSearchParams();
29
+ if (input === undefined || input === null) {
30
+ return params;
31
+ }
32
+ const serializedInput = (0, serialization_1.serializeWithMode)(input, serialization);
33
+ if (typeof serializedInput !== 'object' ||
34
+ serializedInput === null ||
35
+ Array.isArray(serializedInput)) {
36
+ params.set('input', String(serializedInput));
37
+ return params;
38
+ }
39
+ for (const [key, value] of Object.entries(serializedInput)) {
40
+ if (value === undefined) {
41
+ continue;
42
+ }
43
+ if (value === null) {
44
+ params.set(key, 'null');
45
+ continue;
46
+ }
47
+ if (Array.isArray(value)) {
48
+ for (const entry of value) {
49
+ params.append(key, typeof entry === 'object' ? JSON.stringify(entry) : String(entry));
50
+ }
51
+ continue;
52
+ }
53
+ if (typeof value === 'object') {
54
+ params.set(key, JSON.stringify(value));
55
+ continue;
56
+ }
57
+ params.set(key, String(value));
58
+ }
59
+ return params;
60
+ }
61
+ async function resolveHeaders(headers) {
62
+ if (!headers) {
63
+ return new Headers();
64
+ }
65
+ const value = typeof headers === 'function' ? await headers() : headers;
66
+ return new Headers(value);
67
+ }
68
+ async function parseErrorResponse(response) {
69
+ const contentType = response.headers.get('content-type') ?? '';
70
+ if (contentType.includes('application/json')) {
71
+ try {
72
+ const json = await response.json();
73
+ const message = (json && typeof json.error === 'string' && json.error) ||
74
+ (json && typeof json.message === 'string' && json.message) ||
75
+ response.statusText ||
76
+ `Request failed with status ${response.status}`;
77
+ return { message, details: json };
78
+ }
79
+ catch {
80
+ // Fall through to text parsing.
81
+ }
82
+ }
83
+ try {
84
+ const text = await response.text();
85
+ if (text) {
86
+ return { message: text };
87
+ }
88
+ }
89
+ catch {
90
+ // ignore
91
+ }
92
+ return {
93
+ message: response.statusText || `Request failed with status ${response.status}`,
94
+ };
95
+ }
96
+ async function parseSuccessResponse(response, serialization) {
97
+ if (response.status === 204) {
98
+ return undefined;
99
+ }
100
+ const contentType = response.headers.get('content-type') ?? '';
101
+ if (!contentType.includes('application/json')) {
102
+ return response.text();
103
+ }
104
+ const json = await response.json();
105
+ return (0, serialization_1.deserializeWithMode)(json, serialization);
106
+ }
107
+ function buildRequestUrl(baseUrl, path, query) {
108
+ const normalizedPath = normalizePath(path);
109
+ const rawUrl = baseUrl ? `${baseUrl}${normalizedPath}` : normalizedPath;
110
+ const queryString = query?.toString();
111
+ if (!queryString) {
112
+ return rawUrl;
113
+ }
114
+ return `${rawUrl}${rawUrl.includes('?') ? '&' : '?'}${queryString}`;
115
+ }
116
+ async function requestRoute(options) {
117
+ const requestHeaders = await resolveHeaders(options.headers);
118
+ const normalizedPath = normalizePath(options.path);
119
+ let url = buildRequestUrl(options.baseUrl, normalizedPath);
120
+ const requestInit = {
121
+ method: options.method,
122
+ headers: requestHeaders,
123
+ };
124
+ if (options.method === 'GET') {
125
+ const query = toQueryParams(options.input, options.serialization);
126
+ url = buildRequestUrl(options.baseUrl, normalizedPath, query);
127
+ }
128
+ else {
129
+ if (!requestHeaders.has('content-type')) {
130
+ requestHeaders.set('content-type', 'application/json');
131
+ }
132
+ requestInit.body = JSON.stringify((0, serialization_1.serializeWithMode)(options.input, options.serialization));
133
+ }
134
+ const response = await options.fetchImpl(url, requestInit);
135
+ if (!response.ok) {
136
+ const parsedError = await parseErrorResponse(response);
137
+ throw new error_1.VistaClientError({
138
+ status: response.status,
139
+ message: parsedError.message,
140
+ path: normalizedPath,
141
+ method: options.method,
142
+ url,
143
+ response,
144
+ details: parsedError.details,
145
+ });
146
+ }
147
+ return (await parseSuccessResponse(response, options.serialization));
148
+ }
149
+ function assertPath(path) {
150
+ if (!path || typeof path !== 'string') {
151
+ throw new Error('Route path must be a non-empty string.');
152
+ }
153
+ }
154
+ function createVistaClient(options = {}) {
155
+ const fetchImpl = resolveFetchImpl(options.fetch);
156
+ const baseUrl = normalizeBaseUrl(options.baseUrl);
157
+ const serialization = options.serialization ?? 'json';
158
+ function $url(path, ...args) {
159
+ const routePath = String(path);
160
+ assertPath(routePath);
161
+ const query = toQueryParams(args[0], serialization);
162
+ return buildRequestUrl(baseUrl, routePath, query);
163
+ }
164
+ async function $get(path, ...args) {
165
+ const routePath = String(path);
166
+ assertPath(routePath);
167
+ return requestRoute({
168
+ fetchImpl,
169
+ method: 'GET',
170
+ baseUrl,
171
+ path: routePath,
172
+ input: args[0],
173
+ serialization,
174
+ headers: options.headers,
175
+ });
176
+ }
177
+ async function $post(path, ...args) {
178
+ const routePath = String(path);
179
+ assertPath(routePath);
180
+ return requestRoute({
181
+ fetchImpl,
182
+ method: 'POST',
183
+ baseUrl,
184
+ path: routePath,
185
+ input: args[0],
186
+ serialization,
187
+ headers: options.headers,
188
+ });
189
+ }
190
+ return {
191
+ $url,
192
+ $get,
193
+ $post,
194
+ };
195
+ }
@@ -0,0 +1,18 @@
1
+ export interface VistaClientErrorInit {
2
+ status: number;
3
+ message: string;
4
+ path: string;
5
+ method: 'GET' | 'POST';
6
+ url: string;
7
+ response?: Response;
8
+ details?: unknown;
9
+ }
10
+ export declare class VistaClientError extends Error {
11
+ status: number;
12
+ path: string;
13
+ method: 'GET' | 'POST';
14
+ url: string;
15
+ response?: Response;
16
+ details?: unknown;
17
+ constructor(init: VistaClientErrorInit);
18
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VistaClientError = void 0;
4
+ class VistaClientError extends Error {
5
+ status;
6
+ path;
7
+ method;
8
+ url;
9
+ response;
10
+ details;
11
+ constructor(init) {
12
+ super(init.message);
13
+ this.name = 'VistaClientError';
14
+ this.status = init.status;
15
+ this.path = init.path;
16
+ this.method = init.method;
17
+ this.url = init.url;
18
+ this.response = init.response;
19
+ this.details = init.details;
20
+ }
21
+ }
22
+ exports.VistaClientError = VistaClientError;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Package entry for `@vistagenic/vista/stack/client`.
3
+ *
4
+ * Example:
5
+ * import { createVistaClient } from '@vistagenic/vista/stack/client'
6
+ */
7
+ export { createVistaClient } from './create-client';
8
+ export { VistaClientError } from './error';
9
+ export type { AppRouterLike, ClientRoutes, CreateVistaClientOptions, GetRoutePath, OptionalInputArg, PostRoutePath, RouteInput, RouteOutput, RoutePath, VistaClient, VistaFetch, } from './types';
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VistaClientError = exports.createVistaClient = void 0;
4
+ /**
5
+ * Package entry for `@vistagenic/vista/stack/client`.
6
+ *
7
+ * Example:
8
+ * import { createVistaClient } from '@vistagenic/vista/stack/client'
9
+ */
10
+ var create_client_1 = require("./create-client");
11
+ Object.defineProperty(exports, "createVistaClient", { enumerable: true, get: function () { return create_client_1.createVistaClient; } });
12
+ var error_1 = require("./error");
13
+ Object.defineProperty(exports, "VistaClientError", { enumerable: true, get: function () { return error_1.VistaClientError; } });
@@ -0,0 +1,39 @@
1
+ import type { FlatRouteMap, OperationType, ProcedureRecord, StackRouter, StackSerializationMode } from '../server/types';
2
+ type NormalizeRoutePathKey<TPath extends string> = TPath extends `/${string}` ? TPath : `/${TPath}`;
3
+ export type OperationRouteMap<TValue> = {
4
+ [TPath in Extract<keyof TValue, string> as TValue[TPath] extends OperationType<any, any, any, any> ? NormalizeRoutePathKey<TPath> : never]: Extract<TValue[TPath], OperationType<any, any, any, any>>;
5
+ };
6
+ export type AppRouterLike = StackRouter<ProcedureRecord, any, any> | {
7
+ routes: unknown;
8
+ } | object;
9
+ export type ClientRoutes<TAppRouter> = TAppRouter extends StackRouter<infer TProcedures, any, any> ? FlatRouteMap<TProcedures> : TAppRouter extends {
10
+ routes: infer TRoutes;
11
+ } ? OperationRouteMap<TRoutes> : OperationRouteMap<TAppRouter>;
12
+ type NormalizedClientRoutes<TRoutes> = OperationRouteMap<TRoutes>;
13
+ export type RoutePath<TRoutes> = Extract<keyof NormalizedClientRoutes<TRoutes>, string>;
14
+ export type GetRoutePath<TRoutes> = {
15
+ [TPath in RoutePath<TRoutes>]: NormalizedClientRoutes<TRoutes>[TPath] extends {
16
+ type: 'get';
17
+ } ? TPath : never;
18
+ }[RoutePath<TRoutes>];
19
+ export type PostRoutePath<TRoutes> = {
20
+ [TPath in RoutePath<TRoutes>]: NormalizedClientRoutes<TRoutes>[TPath] extends {
21
+ type: 'post';
22
+ } ? TPath : never;
23
+ }[RoutePath<TRoutes>];
24
+ export type RouteInput<TRoutes, TPath extends RoutePath<TRoutes>> = NormalizedClientRoutes<TRoutes>[TPath] extends OperationType<infer TInput, any, any, any> ? TInput : never;
25
+ export type RouteOutput<TRoutes, TPath extends RoutePath<TRoutes>> = NormalizedClientRoutes<TRoutes>[TPath] extends OperationType<any, infer TOutput, any, any> ? TOutput : never;
26
+ export type OptionalInputArg<TInput> = [TInput] extends [void] ? [input?: undefined] : [input: TInput];
27
+ export type VistaFetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
28
+ export interface CreateVistaClientOptions {
29
+ baseUrl?: string;
30
+ fetch?: VistaFetch;
31
+ serialization?: StackSerializationMode;
32
+ headers?: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);
33
+ }
34
+ export interface VistaClient<TRoutes> {
35
+ $url<TPath extends RoutePath<TRoutes>>(path: TPath, ...args: OptionalInputArg<RouteInput<TRoutes, TPath>>): string;
36
+ $get<TPath extends GetRoutePath<TRoutes>>(path: TPath, ...args: OptionalInputArg<RouteInput<TRoutes, TPath>>): Promise<RouteOutput<TRoutes, TPath>>;
37
+ $post<TPath extends PostRoutePath<TRoutes>>(path: TPath, ...args: OptionalInputArg<RouteInput<TRoutes, TPath>>): Promise<RouteOutput<TRoutes, TPath>>;
38
+ }
39
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,32 @@
1
+ import { mergeRouters as mergeStackRouters } from './server/merge-routers';
2
+ import { type ProcedureBuilder } from './server/procedure';
3
+ import { type CreateRouterOptions } from './server/router';
4
+ import { type StackSerializer } from './server/serialization';
5
+ import type { MiddlewareFunction, ProcedureRecord, StackRouter, StackSerializationMode } from './server/types';
6
+ /**
7
+ * Package entry for `@vistagenic/vista/stack`.
8
+ *
9
+ * Example:
10
+ * import { vstack } from '@vistagenic/vista/stack'
11
+ * const v = vstack.init()
12
+ */
13
+ export interface VStackInitOptions {
14
+ serialization?: StackSerializationMode;
15
+ }
16
+ export interface VStackInstance<TCtx, TEnv> {
17
+ procedure: ProcedureBuilder<TCtx, TEnv>;
18
+ middleware<TCurrentCtx extends TCtx, TOutput extends Record<string, unknown> = {}>(handler: MiddlewareFunction<TCurrentCtx, TOutput, TEnv>): MiddlewareFunction<TCurrentCtx, TOutput, TEnv>;
19
+ router<TProcedures extends ProcedureRecord>(procedures: TProcedures, options?: CreateRouterOptions<TEnv>): StackRouter<TProcedures, TCtx, TEnv>;
20
+ mergeRouters: typeof mergeStackRouters;
21
+ serializer: StackSerializer;
22
+ options: Required<VStackInitOptions>;
23
+ }
24
+ export declare function initStack<TCtx extends Record<string, unknown> = {}, TEnv = unknown>(options?: VStackInitOptions): VStackInstance<TCtx, TEnv>;
25
+ export declare const vstack: {
26
+ init: typeof initStack;
27
+ };
28
+ /**
29
+ * Re-export server stack primitives from `@vistagenic/vista/stack`.
30
+ */
31
+ export type { CreateRouterOptions } from './server/router';
32
+ export * from './server';
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.vstack = void 0;
18
+ exports.initStack = initStack;
19
+ const merge_routers_1 = require("./server/merge-routers");
20
+ const procedure_1 = require("./server/procedure");
21
+ const router_1 = require("./server/router");
22
+ const serialization_1 = require("./server/serialization");
23
+ function initStack(options = {}) {
24
+ const normalizedOptions = {
25
+ serialization: options.serialization ?? 'json',
26
+ };
27
+ return {
28
+ procedure: (0, procedure_1.createProcedureBuilder)(),
29
+ middleware(handler) {
30
+ return handler;
31
+ },
32
+ router(procedures, routerOptions) {
33
+ return (0, router_1.createRouter)(procedures, routerOptions);
34
+ },
35
+ mergeRouters(...routers) {
36
+ return (0, merge_routers_1.mergeRouters)(...routers);
37
+ },
38
+ serializer: (0, serialization_1.createSerializer)(normalizedOptions.serialization),
39
+ options: normalizedOptions,
40
+ };
41
+ }
42
+ exports.vstack = {
43
+ init: initStack,
44
+ };
45
+ __exportStar(require("./server"), exports);
@@ -0,0 +1,36 @@
1
+ import type { MiddlewareFunction, OperationType, ProcedureRecord, StackExecutionContext, StackRequestLike, StackResponseToolkit, StackRouter, StackSerializationMode } from './types';
2
+ export declare class StackRouteNotFoundError extends Error {
3
+ status: number;
4
+ constructor(path: string);
5
+ }
6
+ export declare class StackMethodNotAllowedError extends Error {
7
+ status: number;
8
+ constructor(path: string, method: string);
9
+ }
10
+ export declare class StackValidationError extends Error {
11
+ status: number;
12
+ cause: unknown;
13
+ constructor(message: string, cause?: unknown);
14
+ }
15
+ export declare function createResponseToolkit(mode?: StackSerializationMode): StackResponseToolkit;
16
+ export declare function runMiddlewareChain<TCtx, TEnv>(middlewares: MiddlewareFunction<any, any, TEnv>[], context: TCtx, env: TEnv, req: StackRequestLike, c: StackResponseToolkit): Promise<TCtx>;
17
+ export interface ExecuteOperationOptions<TCtx, TEnv> extends StackExecutionContext<TCtx, TEnv> {
18
+ middlewares?: MiddlewareFunction<any, any, TEnv>[];
19
+ serialization?: StackSerializationMode;
20
+ }
21
+ export declare function executeOperation<TCtx, TInput, TOutput, TEnv>(operation: OperationType<TInput, TOutput, TCtx, TEnv>, options: ExecuteOperationOptions<TCtx, TEnv>): Promise<TOutput>;
22
+ export interface ExecuteRouteOptions<TCtx, TEnv> {
23
+ path: string;
24
+ method: string;
25
+ req: StackRequestLike;
26
+ ctx: TCtx;
27
+ env: TEnv;
28
+ serialization?: StackSerializationMode;
29
+ }
30
+ export interface ExecuteRouteResult<TData = unknown> {
31
+ path: string;
32
+ method: string;
33
+ data: TData;
34
+ serializedData: unknown;
35
+ }
36
+ export declare function executeRoute<TProcedures extends ProcedureRecord, TCtx, TEnv>(router: StackRouter<TProcedures, TCtx, TEnv>, options: ExecuteRouteOptions<TCtx, TEnv>): Promise<ExecuteRouteResult>;
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StackValidationError = exports.StackMethodNotAllowedError = exports.StackRouteNotFoundError = void 0;
4
+ exports.createResponseToolkit = createResponseToolkit;
5
+ exports.runMiddlewareChain = runMiddlewareChain;
6
+ exports.executeOperation = executeOperation;
7
+ exports.executeRoute = executeRoute;
8
+ const serialization_1 = require("./serialization");
9
+ const router_1 = require("./router");
10
+ function isObjectRecord(value) {
11
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
12
+ }
13
+ function normalizeResponseInit(init) {
14
+ if (typeof init === 'number') {
15
+ return { status: init };
16
+ }
17
+ return init ?? {};
18
+ }
19
+ class StackRouteNotFoundError extends Error {
20
+ status = 404;
21
+ constructor(path) {
22
+ super(`No typed API route found for "${path}"`);
23
+ this.name = 'StackRouteNotFoundError';
24
+ }
25
+ }
26
+ exports.StackRouteNotFoundError = StackRouteNotFoundError;
27
+ class StackMethodNotAllowedError extends Error {
28
+ status = 405;
29
+ constructor(path, method) {
30
+ super(`Method "${method.toUpperCase()}" is not allowed for "${path}"`);
31
+ this.name = 'StackMethodNotAllowedError';
32
+ }
33
+ }
34
+ exports.StackMethodNotAllowedError = StackMethodNotAllowedError;
35
+ class StackValidationError extends Error {
36
+ status = 400;
37
+ cause;
38
+ constructor(message, cause) {
39
+ super(message);
40
+ this.name = 'StackValidationError';
41
+ this.cause = cause;
42
+ }
43
+ }
44
+ exports.StackValidationError = StackValidationError;
45
+ function createResponseToolkit(mode = 'json') {
46
+ return {
47
+ json(data, init) {
48
+ const payload = (0, serialization_1.serializeWithMode)(data, 'json');
49
+ return Response.json(payload, normalizeResponseInit(init));
50
+ },
51
+ text(data, init) {
52
+ return new Response(String(data), normalizeResponseInit(init));
53
+ },
54
+ superjson(data, init) {
55
+ const payload = {
56
+ mode: 'superjson',
57
+ data: (0, serialization_1.serializeWithMode)(data, 'superjson'),
58
+ };
59
+ return Response.json(payload, normalizeResponseInit(init));
60
+ },
61
+ };
62
+ }
63
+ async function runMiddlewareChain(middlewares, context, env, req, c) {
64
+ const executeAt = async (index, currentContext) => {
65
+ if (index >= middlewares.length) {
66
+ return currentContext;
67
+ }
68
+ const middleware = middlewares[index];
69
+ let nextCalled = false;
70
+ let nextContextPromise;
71
+ const next = async (extension = {}) => {
72
+ if (nextCalled) {
73
+ throw new Error('next() can only be called once per middleware');
74
+ }
75
+ nextCalled = true;
76
+ const mergedContext = isObjectRecord(extension) && isObjectRecord(currentContext)
77
+ ? { ...currentContext, ...extension }
78
+ : currentContext;
79
+ nextContextPromise = executeAt(index + 1, mergedContext);
80
+ return nextContextPromise;
81
+ };
82
+ const result = await middleware({
83
+ ctx: currentContext,
84
+ env,
85
+ req,
86
+ c,
87
+ next,
88
+ });
89
+ if (nextCalled) {
90
+ const downstreamContext = await nextContextPromise;
91
+ if (isObjectRecord(result) && isObjectRecord(downstreamContext)) {
92
+ return { ...downstreamContext, ...result };
93
+ }
94
+ return downstreamContext;
95
+ }
96
+ if (isObjectRecord(result) && isObjectRecord(currentContext)) {
97
+ return executeAt(index + 1, { ...currentContext, ...result });
98
+ }
99
+ return executeAt(index + 1, currentContext);
100
+ };
101
+ return (await executeAt(0, context));
102
+ }
103
+ function resolveRawInput(operation, req) {
104
+ if (operation.type === 'get') {
105
+ if (req.query !== undefined) {
106
+ return req.query;
107
+ }
108
+ return req.body;
109
+ }
110
+ if (req.body !== undefined) {
111
+ return req.body;
112
+ }
113
+ return req.query;
114
+ }
115
+ function resolveInput(operation, req, serialization) {
116
+ const rawInput = resolveRawInput(operation, req);
117
+ const input = (0, serialization_1.deserializeWithMode)(rawInput, serialization);
118
+ if (!operation.schema) {
119
+ return input;
120
+ }
121
+ try {
122
+ return operation.schema.parse(input);
123
+ }
124
+ catch (error) {
125
+ throw new StackValidationError('Invalid typed API input', error);
126
+ }
127
+ }
128
+ async function executeOperation(operation, options) {
129
+ const middlewareChain = [...(options.middlewares ?? []), ...operation.middlewares];
130
+ const finalContext = await runMiddlewareChain(middlewareChain, options.ctx, options.env, options.req, options.c);
131
+ const input = resolveInput(operation, options.req, options.serialization ?? 'json');
132
+ return operation.handler({
133
+ ctx: finalContext,
134
+ input,
135
+ env: options.env,
136
+ req: options.req,
137
+ c: options.c,
138
+ });
139
+ }
140
+ function hasPath(routes, path) {
141
+ return Object.prototype.hasOwnProperty.call(routes, path);
142
+ }
143
+ async function executeRoute(router, options) {
144
+ const normalizedPath = (0, router_1.normalizeStackRoutePath)(options.path);
145
+ const normalizedMethod = String(options.method).toLowerCase();
146
+ const routes = router.routes;
147
+ const candidateRoute = routes[normalizedPath];
148
+ if (!candidateRoute) {
149
+ throw new StackRouteNotFoundError(normalizedPath);
150
+ }
151
+ if (candidateRoute.type !== normalizedMethod) {
152
+ if (hasPath(routes, normalizedPath)) {
153
+ throw new StackMethodNotAllowedError(normalizedPath, normalizedMethod);
154
+ }
155
+ throw new StackRouteNotFoundError(normalizedPath);
156
+ }
157
+ const serialization = options.serialization ?? 'json';
158
+ const responseToolkit = createResponseToolkit(serialization);
159
+ const payload = await executeOperation(candidateRoute, {
160
+ ctx: options.ctx,
161
+ env: options.env,
162
+ req: options.req,
163
+ c: responseToolkit,
164
+ middlewares: router.metadata.globalMiddlewares,
165
+ serialization,
166
+ });
167
+ const serializedData = (0, serialization_1.serializeWithMode)(payload, serialization);
168
+ return {
169
+ path: normalizedPath,
170
+ method: normalizedMethod,
171
+ data: (0, serialization_1.deserializeWithMode)(payload, serialization),
172
+ serializedData,
173
+ };
174
+ }
@@ -0,0 +1,10 @@
1
+ export { createProcedureBuilder, isOperation } from './procedure';
2
+ export type { ProcedureBuilder } from './procedure';
3
+ export { createRouter, normalizeStackRoutePath } from './router';
4
+ export type { CreateRouterOptions } from './router';
5
+ export { mergeRouters } from './merge-routers';
6
+ export { createResponseToolkit, executeOperation, executeRoute, runMiddlewareChain, StackMethodNotAllowedError, StackRouteNotFoundError, StackValidationError, } from './executor';
7
+ export type { ExecuteOperationOptions, ExecuteRouteOptions, ExecuteRouteResult, } from './executor';
8
+ export { createSerializer, deserializeWithMode, serializeWithMode, } from './serialization';
9
+ export type { StackSerializer } from './serialization';
10
+ export type { FlatRouteMap, GetOperation, InferMiddlewareOutput, InferSchemaInput, MaybePromise, MiddlewareFunction, MiddlewareParams, NormalizeMiddlewareResult, OperationType, PostOperation, Prettify, ProcedureHandler, ProcedureHandlerParams, ProcedureNode, ProcedureRecord, ResolvedRoute, RouterMetadata, SchemaLike, StackErrorHandler, StackErrorWithStatus, StackExecutionContext, StackRequestLike, StackResponseToolkit, StackRouter, StackSerializationMode, } from './types';
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.serializeWithMode = exports.deserializeWithMode = exports.createSerializer = exports.StackValidationError = exports.StackRouteNotFoundError = exports.StackMethodNotAllowedError = exports.runMiddlewareChain = exports.executeRoute = exports.executeOperation = exports.createResponseToolkit = exports.mergeRouters = exports.normalizeStackRoutePath = exports.createRouter = exports.isOperation = exports.createProcedureBuilder = void 0;
4
+ var procedure_1 = require("./procedure");
5
+ Object.defineProperty(exports, "createProcedureBuilder", { enumerable: true, get: function () { return procedure_1.createProcedureBuilder; } });
6
+ Object.defineProperty(exports, "isOperation", { enumerable: true, get: function () { return procedure_1.isOperation; } });
7
+ var router_1 = require("./router");
8
+ Object.defineProperty(exports, "createRouter", { enumerable: true, get: function () { return router_1.createRouter; } });
9
+ Object.defineProperty(exports, "normalizeStackRoutePath", { enumerable: true, get: function () { return router_1.normalizeStackRoutePath; } });
10
+ var merge_routers_1 = require("./merge-routers");
11
+ Object.defineProperty(exports, "mergeRouters", { enumerable: true, get: function () { return merge_routers_1.mergeRouters; } });
12
+ var executor_1 = require("./executor");
13
+ Object.defineProperty(exports, "createResponseToolkit", { enumerable: true, get: function () { return executor_1.createResponseToolkit; } });
14
+ Object.defineProperty(exports, "executeOperation", { enumerable: true, get: function () { return executor_1.executeOperation; } });
15
+ Object.defineProperty(exports, "executeRoute", { enumerable: true, get: function () { return executor_1.executeRoute; } });
16
+ Object.defineProperty(exports, "runMiddlewareChain", { enumerable: true, get: function () { return executor_1.runMiddlewareChain; } });
17
+ Object.defineProperty(exports, "StackMethodNotAllowedError", { enumerable: true, get: function () { return executor_1.StackMethodNotAllowedError; } });
18
+ Object.defineProperty(exports, "StackRouteNotFoundError", { enumerable: true, get: function () { return executor_1.StackRouteNotFoundError; } });
19
+ Object.defineProperty(exports, "StackValidationError", { enumerable: true, get: function () { return executor_1.StackValidationError; } });
20
+ var serialization_1 = require("./serialization");
21
+ Object.defineProperty(exports, "createSerializer", { enumerable: true, get: function () { return serialization_1.createSerializer; } });
22
+ Object.defineProperty(exports, "deserializeWithMode", { enumerable: true, get: function () { return serialization_1.deserializeWithMode; } });
23
+ Object.defineProperty(exports, "serializeWithMode", { enumerable: true, get: function () { return serialization_1.serializeWithMode; } });
@@ -0,0 +1,2 @@
1
+ import type { ProcedureRecord, StackRouter } from './types';
2
+ export declare function mergeRouters(...routers: Array<StackRouter<ProcedureRecord, any, any>>): StackRouter<ProcedureRecord, any, any>;