encore.dev 1.44.9 → 1.45.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.
- package/api/mod.ts +189 -9
- package/api/stream.ts +68 -0
- package/dist/api/mod.d.ts +95 -0
- package/dist/api/mod.js +106 -0
- package/dist/api/mod.js.map +1 -1
- package/dist/api/stream.d.ts +21 -0
- package/dist/api/stream.js +57 -0
- package/dist/api/stream.js.map +1 -0
- package/dist/internal/appinit/mod.d.ts +17 -1
- package/dist/internal/appinit/mod.js +95 -55
- package/dist/internal/appinit/mod.js.map +1 -1
- package/dist/internal/runtime/napi/napi.cjs +1 -1
- package/dist/internal/runtime/napi/napi.d.cts +1 -0
- package/dist/req_meta.d.ts +2 -0
- package/dist/req_meta.js +4 -3
- package/dist/req_meta.js.map +1 -1
- package/dist/service/mod.d.ts +2 -0
- package/dist/service/mod.js.map +1 -1
- package/dist/storage/sqldb/database.d.ts +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/internal/appinit/mod.ts +162 -59
- package/internal/runtime/napi/napi.cjs +1 -1
- package/internal/runtime/napi/napi.d.cts +1 -0
- package/package.json +1 -1
- package/req_meta.ts +7 -3
- package/service/mod.ts +5 -1
- package/storage/sqldb/database.ts +1 -1
package/internal/appinit/mod.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { Gateway } from "../../api/gateway";
|
|
2
|
+
import { Middleware, MiddlewareRequest, HandlerResponse } from "../../api/mod";
|
|
3
|
+
import { IterableSocket, IterableStream, Sink } from "../../api/stream";
|
|
2
4
|
import { RawRequest, RawResponse } from "../api/node_http";
|
|
3
5
|
import { setCurrentRequest } from "../reqtrack/mod";
|
|
4
6
|
import * as runtime from "../runtime/mod";
|
|
5
7
|
|
|
6
|
-
export type Handler =
|
|
8
|
+
export type Handler = {
|
|
9
|
+
apiRoute: runtime.ApiRoute;
|
|
10
|
+
middlewares: Middleware[];
|
|
11
|
+
endpointOptions: EndpointOptions;
|
|
12
|
+
};
|
|
7
13
|
|
|
8
14
|
export function registerHandlers(handlers: Handler[]) {
|
|
9
15
|
runtime.RT.registerHandlers(handlers.map((h) => transformHandler(h)));
|
|
@@ -22,104 +28,201 @@ export async function run() {
|
|
|
22
28
|
return runtime.RT.runForever();
|
|
23
29
|
}
|
|
24
30
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
interface EndpointOptions {
|
|
32
|
+
expose: boolean;
|
|
33
|
+
auth: boolean;
|
|
34
|
+
isRaw: boolean;
|
|
35
|
+
isStream: boolean;
|
|
36
|
+
}
|
|
31
37
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
export interface InternalHandlerResponse {
|
|
39
|
+
payload: any;
|
|
40
|
+
extraHeaders?: Record<string, string | string[]>;
|
|
41
|
+
}
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
// recursively calls all middlewares
|
|
44
|
+
async function invokeMiddlewareChain(
|
|
45
|
+
req: MiddlewareRequest,
|
|
46
|
+
chain: Middleware[],
|
|
47
|
+
handler: () => Promise<any>
|
|
48
|
+
): Promise<InternalHandlerResponse> {
|
|
49
|
+
const execute = async (
|
|
50
|
+
index: number,
|
|
51
|
+
req: MiddlewareRequest
|
|
52
|
+
): Promise<HandlerResponse> => {
|
|
53
|
+
const currentMiddleware = chain.at(index);
|
|
54
|
+
|
|
55
|
+
// no more middlewares, execute the handler
|
|
56
|
+
if (currentMiddleware === undefined) {
|
|
57
|
+
return new HandlerResponse(await handler());
|
|
43
58
|
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
59
|
|
|
47
|
-
|
|
48
|
-
|
|
60
|
+
// execute current middleware
|
|
61
|
+
return currentMiddleware(req, (req) => {
|
|
62
|
+
return execute(index + 1, req);
|
|
63
|
+
});
|
|
64
|
+
};
|
|
49
65
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
66
|
+
return (await execute(0, req)).__internalToResponse();
|
|
67
|
+
}
|
|
53
68
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
69
|
+
// calculate what middlewares should run for an endpoint
|
|
70
|
+
function calculateMiddlewareChain(
|
|
71
|
+
endpointOptions: EndpointOptions,
|
|
72
|
+
ms: Middleware[]
|
|
73
|
+
): Middleware[] {
|
|
74
|
+
let middlewares = [];
|
|
75
|
+
|
|
76
|
+
for (const m of ms) {
|
|
77
|
+
if (m.options === undefined || m.options.target === undefined) {
|
|
78
|
+
middlewares.push(m);
|
|
79
|
+
} else {
|
|
80
|
+
const target = m.options.target;
|
|
81
|
+
// check if options are set and if they match the endpoint options
|
|
82
|
+
if (target.auth !== undefined && target.auth !== endpointOptions.auth) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
60
85
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
86
|
+
if (
|
|
87
|
+
target.expose !== undefined &&
|
|
88
|
+
target.expose !== endpointOptions.expose
|
|
89
|
+
) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
64
92
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
break;
|
|
93
|
+
if (
|
|
94
|
+
target.isRaw !== undefined &&
|
|
95
|
+
target.isRaw !== endpointOptions.isRaw
|
|
96
|
+
) {
|
|
97
|
+
continue;
|
|
71
98
|
}
|
|
99
|
+
|
|
100
|
+
if (
|
|
101
|
+
target.isStream !== undefined &&
|
|
102
|
+
target.isStream !== endpointOptions.isStream
|
|
103
|
+
) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
middlewares.push(m);
|
|
72
108
|
}
|
|
73
109
|
}
|
|
110
|
+
|
|
111
|
+
return middlewares;
|
|
74
112
|
}
|
|
75
113
|
|
|
76
|
-
function transformHandler(h: Handler):
|
|
77
|
-
|
|
114
|
+
function transformHandler(h: Handler): runtime.ApiRoute {
|
|
115
|
+
const middlewares = calculateMiddlewareChain(
|
|
116
|
+
h.endpointOptions,
|
|
117
|
+
h.middlewares
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
if (h.apiRoute.streamingResponse || h.apiRoute.streamingRequest) {
|
|
78
121
|
return {
|
|
79
|
-
...h,
|
|
122
|
+
...h.apiRoute,
|
|
80
123
|
// req is the upgrade request.
|
|
81
124
|
// stream is either a bidirectional stream, in stream or out stream.
|
|
82
|
-
handler: (
|
|
125
|
+
handler: (
|
|
126
|
+
req: runtime.Request,
|
|
127
|
+
stream: runtime.Sink | runtime.Stream | runtime.Socket
|
|
128
|
+
) => {
|
|
83
129
|
setCurrentRequest(req);
|
|
84
130
|
|
|
85
131
|
// make readable streams async iterators
|
|
86
|
-
|
|
87
|
-
stream
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
132
|
+
const streamArg: IterableStream | IterableSocket | Sink =
|
|
133
|
+
stream instanceof runtime.Stream
|
|
134
|
+
? new IterableStream(stream)
|
|
135
|
+
: stream instanceof runtime.Socket
|
|
136
|
+
? new IterableSocket(stream)
|
|
137
|
+
: new Sink(stream);
|
|
138
|
+
|
|
139
|
+
if (middlewares.length === 0) {
|
|
140
|
+
const payload = req.payload();
|
|
141
|
+
return toResponse(
|
|
142
|
+
payload !== null
|
|
143
|
+
? h.apiRoute.handler(payload, streamArg)
|
|
144
|
+
: h.apiRoute.handler(streamArg)
|
|
145
|
+
);
|
|
91
146
|
}
|
|
92
147
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
148
|
+
const handler = async () => {
|
|
149
|
+
// handshake payload
|
|
150
|
+
const payload = req.payload();
|
|
151
|
+
return payload !== null
|
|
152
|
+
? h.apiRoute.handler(payload, streamArg)
|
|
153
|
+
: h.apiRoute.handler(streamArg);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const mwRequest = new MiddlewareRequest(
|
|
157
|
+
streamArg,
|
|
158
|
+
undefined,
|
|
159
|
+
undefined
|
|
160
|
+
);
|
|
161
|
+
return invokeMiddlewareChain(mwRequest, middlewares, handler);
|
|
98
162
|
}
|
|
99
163
|
};
|
|
100
164
|
}
|
|
101
165
|
|
|
102
|
-
if (h.raw) {
|
|
166
|
+
if (h.apiRoute.raw) {
|
|
103
167
|
return {
|
|
104
|
-
...h,
|
|
168
|
+
...h.apiRoute,
|
|
105
169
|
handler: (
|
|
106
170
|
req: runtime.Request,
|
|
107
171
|
resp: runtime.ResponseWriter,
|
|
108
172
|
body: runtime.BodyReader
|
|
109
173
|
) => {
|
|
110
174
|
setCurrentRequest(req);
|
|
175
|
+
|
|
111
176
|
const rawReq = new RawRequest(req, body);
|
|
112
177
|
const rawResp = new RawResponse(rawReq, resp);
|
|
113
|
-
|
|
178
|
+
|
|
179
|
+
if (middlewares.length === 0) {
|
|
180
|
+
return toResponse(h.apiRoute.handler(rawReq, rawResp));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const handler = async () => {
|
|
184
|
+
return h.apiRoute.handler(rawReq, rawResp);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const mwRequest = new MiddlewareRequest(undefined, rawReq, rawResp);
|
|
188
|
+
return invokeMiddlewareChain(mwRequest, middlewares, handler);
|
|
114
189
|
}
|
|
115
190
|
};
|
|
116
191
|
}
|
|
192
|
+
|
|
117
193
|
return {
|
|
118
|
-
...h,
|
|
194
|
+
...h.apiRoute,
|
|
119
195
|
handler: (req: runtime.Request) => {
|
|
120
196
|
setCurrentRequest(req);
|
|
121
|
-
|
|
122
|
-
|
|
197
|
+
|
|
198
|
+
if (middlewares.length === 0) {
|
|
199
|
+
const payload = req.payload();
|
|
200
|
+
return toResponse(
|
|
201
|
+
payload !== null ? h.apiRoute.handler(payload) : h.apiRoute.handler()
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const handler = async () => {
|
|
206
|
+
const payload = req.payload();
|
|
207
|
+
return payload !== null
|
|
208
|
+
? h.apiRoute.handler(payload)
|
|
209
|
+
: h.apiRoute.handler();
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const mwRequest = new MiddlewareRequest(undefined, undefined, undefined);
|
|
213
|
+
return invokeMiddlewareChain(mwRequest, middlewares, handler);
|
|
123
214
|
}
|
|
124
215
|
};
|
|
125
216
|
}
|
|
217
|
+
|
|
218
|
+
function toResponse(
|
|
219
|
+
payload: any
|
|
220
|
+
): InternalHandlerResponse | Promise<InternalHandlerResponse> {
|
|
221
|
+
if (payload instanceof Promise) {
|
|
222
|
+
return payload.then((payload) => {
|
|
223
|
+
return new HandlerResponse(payload).__internalToResponse();
|
|
224
|
+
});
|
|
225
|
+
} else {
|
|
226
|
+
return new HandlerResponse(payload).__internalToResponse();
|
|
227
|
+
}
|
|
228
|
+
}
|
package/package.json
CHANGED
package/req_meta.ts
CHANGED
|
@@ -10,6 +10,9 @@ export interface APIDesc {
|
|
|
10
10
|
|
|
11
11
|
/** Whether the endpoint is a raw endpoint. */
|
|
12
12
|
raw: boolean;
|
|
13
|
+
|
|
14
|
+
/** Whether the endpoint requires auth. */
|
|
15
|
+
auth: boolean;
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
export type Method =
|
|
@@ -153,7 +156,7 @@ export function currentRequest(): RequestMeta | undefined {
|
|
|
153
156
|
const meta = req.meta();
|
|
154
157
|
|
|
155
158
|
const base: BaseRequestMeta = {
|
|
156
|
-
trace: meta.trace
|
|
159
|
+
trace: meta.trace
|
|
157
160
|
};
|
|
158
161
|
|
|
159
162
|
if (meta.apiCall) {
|
|
@@ -163,13 +166,14 @@ export function currentRequest(): RequestMeta | undefined {
|
|
|
163
166
|
service: meta.apiCall.api.service,
|
|
164
167
|
endpoint: meta.apiCall.api.endpoint,
|
|
165
168
|
raw: meta.apiCall.api.raw,
|
|
169
|
+
auth: meta.apiCall.api.requiresAuth
|
|
166
170
|
},
|
|
167
171
|
method: meta.apiCall.method as Method,
|
|
168
172
|
path: meta.apiCall.path,
|
|
169
173
|
pathAndQuery: meta.apiCall.pathAndQuery,
|
|
170
174
|
pathParams: meta.apiCall.pathParams ?? {},
|
|
171
175
|
parsedPayload: meta.apiCall.parsedPayload,
|
|
172
|
-
headers: meta.apiCall.headers
|
|
176
|
+
headers: meta.apiCall.headers
|
|
173
177
|
};
|
|
174
178
|
return { ...base, ...api };
|
|
175
179
|
} else if (meta.pubsubMessage) {
|
|
@@ -180,7 +184,7 @@ export function currentRequest(): RequestMeta | undefined {
|
|
|
180
184
|
subscription: meta.pubsubMessage.subscription,
|
|
181
185
|
messageId: meta.pubsubMessage.id,
|
|
182
186
|
deliveryAttempt: meta.pubsubMessage.deliveryAttempt,
|
|
183
|
-
parsedPayload: meta.pubsubMessage.parsedPayload
|
|
187
|
+
parsedPayload: meta.pubsubMessage.parsedPayload
|
|
184
188
|
};
|
|
185
189
|
return { ...base, ...msg };
|
|
186
190
|
} else {
|
package/service/mod.ts
CHANGED
|
@@ -19,7 +19,7 @@ const driverName = "node-pg";
|
|
|
19
19
|
export type Row = Record<string, any>;
|
|
20
20
|
|
|
21
21
|
/** Represents a type that can be used in query template literals */
|
|
22
|
-
export type Primitive = string | number | boolean | Buffer | null;
|
|
22
|
+
export type Primitive = string | number | boolean | Buffer | Date | null;
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Constructing a new database object will result in Encore provisioning a database with
|