@reboot-dev/reboot 0.24.0 → 0.25.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/index.d.ts +62 -12
- package/index.js +256 -13
- package/package.json +6 -4
- package/rbt.js +5 -2
- package/reboot_native.cc +1186 -1389
- package/reboot_native.cjs +1 -0
- package/reboot_native.d.ts +8 -0
- package/version.d.ts +1 -1
- package/version.js +1 -1
package/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { errors_pb, IdempotencyOptions, protobuf_es, ScheduleOptions } from "@reboot-dev/reboot-api";
|
|
2
|
+
import express from "express";
|
|
2
3
|
import * as reboot_native from "./reboot_native.cjs";
|
|
3
4
|
export { reboot_native };
|
|
4
5
|
export * from "./utils/index.js";
|
|
5
|
-
type
|
|
6
|
+
type ApplicationRevision = {
|
|
6
7
|
applicationId: string;
|
|
7
8
|
};
|
|
8
9
|
export declare class Reboot {
|
|
@@ -16,10 +17,9 @@ export declare class Reboot {
|
|
|
16
17
|
}): ExternalContext;
|
|
17
18
|
start(): Promise<void>;
|
|
18
19
|
stop(): Promise<void>;
|
|
19
|
-
up(
|
|
20
|
-
tokenVerifier?: TokenVerifier;
|
|
20
|
+
up(application: Application, options?: {
|
|
21
21
|
localEnvoy?: boolean;
|
|
22
|
-
}): Promise<
|
|
22
|
+
}): Promise<ApplicationRevision>;
|
|
23
23
|
down(): Promise<void>;
|
|
24
24
|
url(): string;
|
|
25
25
|
}
|
|
@@ -48,9 +48,10 @@ export declare class Context {
|
|
|
48
48
|
static fromNativeExternal(external: any, kind: string, aborted: Promise<void>): ReaderContext | WriterContext | TransactionContext | WorkflowContext;
|
|
49
49
|
get __external(): any;
|
|
50
50
|
get auth(): Auth | null;
|
|
51
|
-
get stateId():
|
|
52
|
-
get iteration():
|
|
53
|
-
get cookie():
|
|
51
|
+
get stateId(): string;
|
|
52
|
+
get iteration(): number;
|
|
53
|
+
get cookie(): string;
|
|
54
|
+
get appInternal(): boolean;
|
|
54
55
|
generateIdempotentStateId(stateType: string, serviceName: string, method: string, idempotency: IdempotencyOptions): Promise<any>;
|
|
55
56
|
}
|
|
56
57
|
export declare class ReaderContext extends Context {
|
|
@@ -145,12 +146,38 @@ export declare abstract class Authorizer<StateType, RequestTypes> {
|
|
|
145
146
|
abstract authorize(methodName: string, context: ReaderContext, state?: StateType, request?: RequestTypes): Promise<AuthorizerDecision>;
|
|
146
147
|
_authorize?: (methodName: string, context: ReaderContext, bytesState?: Uint8Array, bytesRequest?: Uint8Array) => Promise<Uint8Array>;
|
|
147
148
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
149
|
+
export type AuthorizerCallable<StateType, RequestType> = (args: {
|
|
150
|
+
context: ReaderContext;
|
|
151
|
+
state?: StateType;
|
|
152
|
+
request?: RequestType;
|
|
153
|
+
}) => Promise<AuthorizerDecision> | AuthorizerDecision;
|
|
154
|
+
export declare abstract class AuthorizerRule<StateType, RequestType> {
|
|
155
|
+
abstract execute(args: {
|
|
156
|
+
context: ReaderContext;
|
|
157
|
+
state?: StateType;
|
|
158
|
+
request?: RequestType;
|
|
159
|
+
}): Promise<AuthorizerDecision>;
|
|
153
160
|
}
|
|
161
|
+
export declare function deny(): AuthorizerRule<protobuf_es.Message, protobuf_es.Message>;
|
|
162
|
+
export declare function allow(): AuthorizerRule<protobuf_es.Message, protobuf_es.Message>;
|
|
163
|
+
export declare function allowIf<StateType, RequestType>(args: {
|
|
164
|
+
all: AuthorizerCallable<StateType, RequestType>[];
|
|
165
|
+
any?: never;
|
|
166
|
+
}): AuthorizerRule<StateType, RequestType>;
|
|
167
|
+
export declare function allowIf<StateType, RequestType>(args: {
|
|
168
|
+
all?: never;
|
|
169
|
+
any: AuthorizerCallable<StateType, RequestType>[];
|
|
170
|
+
}): AuthorizerRule<StateType, RequestType>;
|
|
171
|
+
export declare function hasVerifiedToken({ context, }: {
|
|
172
|
+
context: ReaderContext;
|
|
173
|
+
state?: protobuf_es.Message;
|
|
174
|
+
request?: protobuf_es.Message;
|
|
175
|
+
}): errors_pb.Unauthenticated | errors_pb.Ok;
|
|
176
|
+
export declare function isAppInternal({ context, }: {
|
|
177
|
+
context: ReaderContext;
|
|
178
|
+
state?: protobuf_es.Message;
|
|
179
|
+
request?: protobuf_es.Message;
|
|
180
|
+
}): errors_pb.Unauthenticated | errors_pb.Ok;
|
|
154
181
|
export declare class Application {
|
|
155
182
|
#private;
|
|
156
183
|
constructor({ servicers, initialize, initializeBearerToken, tokenVerifier, }: {
|
|
@@ -159,7 +186,30 @@ export declare class Application {
|
|
|
159
186
|
initializeBearerToken?: string;
|
|
160
187
|
tokenVerifier?: TokenVerifier;
|
|
161
188
|
});
|
|
189
|
+
get servicers(): ServicerFactory[];
|
|
190
|
+
get tokenVerifier(): TokenVerifier;
|
|
191
|
+
get http(): Application.Http;
|
|
162
192
|
run(): Promise<any>;
|
|
193
|
+
get __external(): any;
|
|
194
|
+
}
|
|
195
|
+
export declare namespace Application {
|
|
196
|
+
namespace Http {
|
|
197
|
+
type Path = string | RegExp | (string | RegExp)[];
|
|
198
|
+
type ReqResHandler = (context: ExternalContext, req: express.Request, res: express.Response) => any;
|
|
199
|
+
type ReqResNextHandler = (context: ExternalContext, req: express.Request, res: express.Response, next: express.NextFunction) => any;
|
|
200
|
+
type ErrReqResNextHandler = (context: ExternalContext, err: any, req: express.Request, res: express.Response, next: express.NextFunction) => any;
|
|
201
|
+
type Handler = ReqResHandler | ReqResNextHandler | ErrReqResNextHandler;
|
|
202
|
+
}
|
|
203
|
+
class Http {
|
|
204
|
+
#private;
|
|
205
|
+
constructor(express: express.Application, createExternalContext: (args: {
|
|
206
|
+
name: string;
|
|
207
|
+
bearerToken?: string;
|
|
208
|
+
}) => Promise<ExternalContext>);
|
|
209
|
+
private add;
|
|
210
|
+
get(path: Http.Path, ...handlers: Http.Handler[]): void;
|
|
211
|
+
post(path: Http.Path, ...handlers: Http.Handler[]): void;
|
|
212
|
+
}
|
|
163
213
|
}
|
|
164
214
|
/**
|
|
165
215
|
* @deprecated testWithReboot is deprecated in favor of the manual start of Reboot in the test setup.
|
package/index.js
CHANGED
|
@@ -9,12 +9,13 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _Reboot_external, _ExternalContext_external, _a, _Context_external, _Context_isInternalConstructing, _ReaderContext_kind, _WriterContext_kind, _TransactionContext_kind, _WorkflowContext_kind, _Application_external;
|
|
12
|
+
var _Reboot_external, _ExternalContext_external, _a, _Context_external, _Context_isInternalConstructing, _ReaderContext_kind, _WriterContext_kind, _TransactionContext_kind, _WorkflowContext_kind, _Application_servicers, _Application_tokenVerifier, _Application_express, _Application_http, _Application_servers, _Application_createExternalContext, _Application_external;
|
|
13
13
|
import { auth_pb, errors_pb, protobuf_es, } from "@reboot-dev/reboot-api";
|
|
14
14
|
import { strict as assert } from "assert";
|
|
15
|
+
import express from "express";
|
|
16
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
15
17
|
import { fork } from "node:child_process";
|
|
16
18
|
import { test } from "node:test";
|
|
17
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
18
19
|
import * as reboot_native from "./reboot_native.cjs";
|
|
19
20
|
import { ensurePythonVenv } from "./venv.js";
|
|
20
21
|
export { reboot_native };
|
|
@@ -84,10 +85,10 @@ export class Reboot {
|
|
|
84
85
|
startedInstances.splice(indexOfTimestamp, 1);
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
|
-
async up(
|
|
88
|
+
async up(application, options) {
|
|
88
89
|
// TODO(benh): determine module and file name so that we can
|
|
89
90
|
// namespace if we have more than one implementation of servicers.
|
|
90
|
-
return await reboot_native.Reboot_up(__classPrivateFieldGet(this, _Reboot_external, "f"),
|
|
91
|
+
return await reboot_native.Reboot_up(__classPrivateFieldGet(this, _Reboot_external, "f"), application.__external, options?.localEnvoy);
|
|
91
92
|
}
|
|
92
93
|
async down() {
|
|
93
94
|
await reboot_native.Reboot_down(__classPrivateFieldGet(this, _Reboot_external, "f"));
|
|
@@ -178,6 +179,9 @@ export class Context {
|
|
|
178
179
|
get cookie() {
|
|
179
180
|
return reboot_native.Context_cookie(__classPrivateFieldGet(this, _Context_external, "f"));
|
|
180
181
|
}
|
|
182
|
+
get appInternal() {
|
|
183
|
+
return reboot_native.Context_appInternal(__classPrivateFieldGet(this, _Context_external, "f"));
|
|
184
|
+
}
|
|
181
185
|
async generateIdempotentStateId(stateType, serviceName, method, idempotency) {
|
|
182
186
|
return reboot_native.Context_generateIdempotentStateId(__classPrivateFieldGet(this, _Context_external, "f"), stateType, serviceName, method, idempotency);
|
|
183
187
|
}
|
|
@@ -324,21 +328,173 @@ export class TokenVerifier {
|
|
|
324
328
|
*/
|
|
325
329
|
export class Authorizer {
|
|
326
330
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
331
|
+
export class AuthorizerRule {
|
|
332
|
+
}
|
|
333
|
+
export function deny() {
|
|
334
|
+
return new (class extends AuthorizerRule {
|
|
335
|
+
async execute(args) {
|
|
336
|
+
return new errors_pb.PermissionDenied();
|
|
337
|
+
}
|
|
338
|
+
})();
|
|
339
|
+
}
|
|
340
|
+
export function allow() {
|
|
341
|
+
return new (class extends AuthorizerRule {
|
|
342
|
+
async execute(args) {
|
|
343
|
+
return new errors_pb.Ok();
|
|
344
|
+
}
|
|
345
|
+
})();
|
|
346
|
+
}
|
|
347
|
+
export function allowIf(args) {
|
|
348
|
+
const all = args.all;
|
|
349
|
+
const any = args.any;
|
|
350
|
+
if ((all === undefined && any === undefined) ||
|
|
351
|
+
(all !== undefined && any !== undefined)) {
|
|
352
|
+
throw new Error("Exactly one of `all` or `any` must be passed");
|
|
353
|
+
}
|
|
354
|
+
const callables = all ?? any;
|
|
355
|
+
return new (class extends AuthorizerRule {
|
|
356
|
+
async execute({ context, state, request }) {
|
|
357
|
+
// NOTE: we invoke each authorizer callable **one at a time**
|
|
358
|
+
// instead of concurrently so that:
|
|
359
|
+
//
|
|
360
|
+
// (1) We support dependency semantics for `all`, i.e.,
|
|
361
|
+
// callable's later can assume earlier callables did not
|
|
362
|
+
// return `Unauthenticated` or `PermissionDenied`.
|
|
363
|
+
//
|
|
364
|
+
// (2) We support short-circuiting`, i.e., cheaper authorizer
|
|
365
|
+
// callables can be listed first so more expensive ones
|
|
366
|
+
// aren't executed unless necessary.
|
|
367
|
+
//
|
|
368
|
+
// PLEASE KEEP SEMANTICS IN SYNC WITH PYTHON.
|
|
369
|
+
// Remember if we had any `PermissionDenied` for `any` so that
|
|
370
|
+
// we return that instead of `Unauthenticated`.
|
|
371
|
+
let denied = false;
|
|
372
|
+
for (const callable of callables) {
|
|
373
|
+
const decision = await callable({ context, state, request });
|
|
374
|
+
if (decision instanceof errors_pb.Ok) {
|
|
375
|
+
if (all !== undefined) {
|
|
376
|
+
// All callables must return `Ok`, keep checking.
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
// Only needed one `Ok` and we got it, short-circuit.
|
|
381
|
+
return decision;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
else if (decision instanceof errors_pb.Unauthenticated) {
|
|
385
|
+
if (all !== undefined) {
|
|
386
|
+
// All callables must return `Ok`, short-circuit.
|
|
387
|
+
return decision;
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
// Just need one `Ok`, keep checking.
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
else if (decision instanceof errors_pb.PermissionDenied) {
|
|
395
|
+
if (all !== undefined) {
|
|
396
|
+
// All callables must return `Ok`, short-circuit.
|
|
397
|
+
return decision;
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
// Remember that we got at least one `PermissionDenied` so
|
|
401
|
+
// we can return it later.
|
|
402
|
+
denied = true;
|
|
403
|
+
// Only need one `Ok`, keep checking.
|
|
404
|
+
continue;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
// If this was `all`, then they must have all been `Ok`!
|
|
409
|
+
if (all !== undefined) {
|
|
410
|
+
// TODO: assert !denied
|
|
411
|
+
return new errors_pb.Ok();
|
|
412
|
+
}
|
|
413
|
+
// Must be `any`, check if we got a `PermissionDenied` otherwise
|
|
414
|
+
// return `Unauthenticated`.
|
|
415
|
+
if (denied) {
|
|
416
|
+
return new errors_pb.PermissionDenied();
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
return new errors_pb.Unauthenticated();
|
|
420
|
+
}
|
|
334
421
|
}
|
|
422
|
+
})();
|
|
423
|
+
}
|
|
424
|
+
export function hasVerifiedToken({ context, }) {
|
|
425
|
+
if (!context.auth) {
|
|
426
|
+
return new errors_pb.Unauthenticated();
|
|
427
|
+
}
|
|
428
|
+
return new errors_pb.Ok();
|
|
429
|
+
}
|
|
430
|
+
export function isAppInternal({ context, }) {
|
|
431
|
+
if (context.appInternal) {
|
|
335
432
|
return new errors_pb.Ok();
|
|
336
433
|
}
|
|
434
|
+
return new errors_pb.Unauthenticated();
|
|
337
435
|
}
|
|
338
436
|
export class Application {
|
|
339
437
|
constructor({ servicers, initialize, initializeBearerToken, tokenVerifier, }) {
|
|
438
|
+
_Application_servicers.set(this, void 0);
|
|
439
|
+
_Application_tokenVerifier.set(this, void 0);
|
|
440
|
+
_Application_express.set(this, void 0);
|
|
441
|
+
_Application_http.set(this, void 0);
|
|
442
|
+
_Application_servers.set(this, void 0);
|
|
443
|
+
_Application_createExternalContext.set(this, void 0);
|
|
340
444
|
_Application_external.set(this, void 0);
|
|
341
|
-
__classPrivateFieldSet(this,
|
|
445
|
+
__classPrivateFieldSet(this, _Application_servicers, servicers, "f");
|
|
446
|
+
__classPrivateFieldSet(this, _Application_tokenVerifier, tokenVerifier, "f");
|
|
447
|
+
__classPrivateFieldSet(this, _Application_express, express(), "f");
|
|
448
|
+
// We assume that our users will want these middleware.
|
|
449
|
+
// TODO: expose `.use()` to allow users to add their own middleware.
|
|
450
|
+
__classPrivateFieldGet(this, _Application_express, "f").use(express.json());
|
|
451
|
+
__classPrivateFieldGet(this, _Application_express, "f").use(express.urlencoded({ extended: true }));
|
|
452
|
+
__classPrivateFieldSet(this, _Application_http, new Application.Http(__classPrivateFieldGet(this, _Application_express, "f"), async (args) => {
|
|
453
|
+
return await __classPrivateFieldGet(this, _Application_createExternalContext, "f").call(this, args);
|
|
454
|
+
}), "f");
|
|
455
|
+
__classPrivateFieldSet(this, _Application_servers, new Map(), "f");
|
|
456
|
+
__classPrivateFieldSet(this, _Application_external, reboot_native.Application_constructor(ExternalContext.fromNativeExternal, servicers, {
|
|
457
|
+
start: async (consensusId, port, createExternalContext) => {
|
|
458
|
+
// Store `createExternalContext` function before listening
|
|
459
|
+
// so we don't attempt to serve any traffic and try and use
|
|
460
|
+
// an `undefined` function.
|
|
461
|
+
__classPrivateFieldSet(this, _Application_createExternalContext, createExternalContext, "f");
|
|
462
|
+
let server;
|
|
463
|
+
[server, port] = await new Promise((resolve, reject) => {
|
|
464
|
+
const server = __classPrivateFieldGet(this, _Application_express, "f").listen(port ?? 0, (error) => {
|
|
465
|
+
if (error) {
|
|
466
|
+
reject(error);
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
// We requested a port so we should have an
|
|
470
|
+
// `AddressInfo` not a string representing a file
|
|
471
|
+
// descriptor path for a pipe or socket, etc.
|
|
472
|
+
const address = server.address();
|
|
473
|
+
assert(typeof address !== "string");
|
|
474
|
+
resolve([server, address.port]);
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
});
|
|
478
|
+
__classPrivateFieldGet(this, _Application_servers, "f").set(consensusId, server);
|
|
479
|
+
return port;
|
|
480
|
+
},
|
|
481
|
+
stop: async (consensusId) => {
|
|
482
|
+
const server = __classPrivateFieldGet(this, _Application_servers, "f").get(consensusId);
|
|
483
|
+
if (server !== undefined) {
|
|
484
|
+
await new Promise((resolve, reject) => {
|
|
485
|
+
server.close((err) => {
|
|
486
|
+
if (err) {
|
|
487
|
+
reject(err);
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
resolve();
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
__classPrivateFieldGet(this, _Application_servers, "f").delete(consensusId);
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
}, async (context) => {
|
|
342
498
|
if (initialize !== undefined) {
|
|
343
499
|
try {
|
|
344
500
|
await initialize(context);
|
|
@@ -354,11 +510,98 @@ export class Application {
|
|
|
354
510
|
}
|
|
355
511
|
}, initializeBearerToken, tokenVerifier), "f");
|
|
356
512
|
}
|
|
513
|
+
get servicers() {
|
|
514
|
+
return __classPrivateFieldGet(this, _Application_servicers, "f");
|
|
515
|
+
}
|
|
516
|
+
get tokenVerifier() {
|
|
517
|
+
return __classPrivateFieldGet(this, _Application_tokenVerifier, "f");
|
|
518
|
+
}
|
|
519
|
+
get http() {
|
|
520
|
+
return __classPrivateFieldGet(this, _Application_http, "f");
|
|
521
|
+
}
|
|
357
522
|
async run() {
|
|
358
523
|
return await reboot_native.Application_run(__classPrivateFieldGet(this, _Application_external, "f"));
|
|
359
524
|
}
|
|
525
|
+
get __external() {
|
|
526
|
+
return __classPrivateFieldGet(this, _Application_external, "f");
|
|
527
|
+
}
|
|
360
528
|
}
|
|
361
|
-
_Application_external = new WeakMap();
|
|
529
|
+
_Application_servicers = new WeakMap(), _Application_tokenVerifier = new WeakMap(), _Application_express = new WeakMap(), _Application_http = new WeakMap(), _Application_servers = new WeakMap(), _Application_createExternalContext = new WeakMap(), _Application_external = new WeakMap();
|
|
530
|
+
(function (Application) {
|
|
531
|
+
var _Http_express, _Http_createExternalContext;
|
|
532
|
+
class Http {
|
|
533
|
+
constructor(express, createExternalContext) {
|
|
534
|
+
_Http_express.set(this, void 0);
|
|
535
|
+
_Http_createExternalContext.set(this, void 0);
|
|
536
|
+
__classPrivateFieldSet(this, _Http_express, express, "f");
|
|
537
|
+
__classPrivateFieldSet(this, _Http_createExternalContext, createExternalContext, "f");
|
|
538
|
+
}
|
|
539
|
+
add(method, path, handlers) {
|
|
540
|
+
const methods = {
|
|
541
|
+
GET: (path, ...handlers) => __classPrivateFieldGet(this, _Http_express, "f").get(path, ...handlers),
|
|
542
|
+
POST: (path, ...handlers) => __classPrivateFieldGet(this, _Http_express, "f").post(path, ...handlers),
|
|
543
|
+
};
|
|
544
|
+
const createExternalContext = (name, authorization) => {
|
|
545
|
+
let bearerToken = undefined;
|
|
546
|
+
if (authorization !== undefined) {
|
|
547
|
+
const parts = authorization.split(" ");
|
|
548
|
+
if (parts.length === 2 && parts[0].toLowerCase() === "bearer") {
|
|
549
|
+
bearerToken = parts[1];
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return __classPrivateFieldGet(this, _Http_createExternalContext, "f").call(this, {
|
|
553
|
+
name,
|
|
554
|
+
bearerToken,
|
|
555
|
+
});
|
|
556
|
+
};
|
|
557
|
+
methods[method](path, ...handlers.map((handler) => {
|
|
558
|
+
// Express allows for three different kinds of handlers, a
|
|
559
|
+
// "normal" handler that takes two args, `req` and `res`, a
|
|
560
|
+
// "middlware" handler that takes three args, `req, `res`,
|
|
561
|
+
// and `next`, and an "error" handler that takes four args
|
|
562
|
+
// `err`, `req`, `res`, and `next`. To the best of our
|
|
563
|
+
// understanding they determine what arguments to pass to
|
|
564
|
+
// handlers based on how many arguments the handler takes,
|
|
565
|
+
// and so that is exactly what we do below as well, except
|
|
566
|
+
// accounting for an extra first arg for the
|
|
567
|
+
// `ExternalContext`.
|
|
568
|
+
switch (handler.length) {
|
|
569
|
+
// (context, req, res) => ...
|
|
570
|
+
case 3:
|
|
571
|
+
return async (req, res) => {
|
|
572
|
+
const context = await createExternalContext(`HTTP ${method} '${req.path}'`, req.header("Authorization"));
|
|
573
|
+
// @ts-ignore
|
|
574
|
+
handler(context, req, res);
|
|
575
|
+
};
|
|
576
|
+
// (context, req, res, next) => ...
|
|
577
|
+
case 4:
|
|
578
|
+
return async (req, res, next) => {
|
|
579
|
+
const context = await createExternalContext(`HTTP ${method} '${req.path}'`, req.header("Authorization"));
|
|
580
|
+
// @ts-ignore
|
|
581
|
+
handler(context, req, res, next);
|
|
582
|
+
};
|
|
583
|
+
// (context, err, req, res, next) => ...
|
|
584
|
+
case 5:
|
|
585
|
+
return async (err, req, res, next) => {
|
|
586
|
+
const context = await createExternalContext(`HTTP ${method} '${req.path}'`, req.header("Authorization"));
|
|
587
|
+
handler(context, err, req, res, next);
|
|
588
|
+
};
|
|
589
|
+
default:
|
|
590
|
+
throw new Error(`HTTP ${method} handler for '${path}' has unexpected ` +
|
|
591
|
+
`number of arguments`);
|
|
592
|
+
}
|
|
593
|
+
}));
|
|
594
|
+
}
|
|
595
|
+
get(path, ...handlers) {
|
|
596
|
+
this.add("GET", path, handlers);
|
|
597
|
+
}
|
|
598
|
+
post(path, ...handlers) {
|
|
599
|
+
this.add("POST", path, handlers);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
_Http_express = new WeakMap(), _Http_createExternalContext = new WeakMap();
|
|
603
|
+
Application.Http = Http;
|
|
604
|
+
})(Application || (Application = {}));
|
|
362
605
|
/**
|
|
363
606
|
* @deprecated testWithReboot is deprecated in favor of the manual start of Reboot in the test setup.
|
|
364
607
|
*/
|
package/package.json
CHANGED
|
@@ -3,18 +3,19 @@
|
|
|
3
3
|
"@bufbuild/protobuf": "1.3.2",
|
|
4
4
|
"@bufbuild/protoplugin": "1.3.2",
|
|
5
5
|
"@bufbuild/protoc-gen-es": "1.3.2",
|
|
6
|
-
"@reboot-dev/reboot-api": "0.
|
|
6
|
+
"@reboot-dev/reboot-api": "0.25.0",
|
|
7
7
|
"chalk": "^4.1.2",
|
|
8
8
|
"node-addon-api": "^7.0.0",
|
|
9
9
|
"node-gyp": ">=10.2.0",
|
|
10
10
|
"uuid": "^9.0.1",
|
|
11
11
|
"which-pm-runs": "^1.1.0",
|
|
12
12
|
"extensionless": "^1.9.9",
|
|
13
|
-
"esbuild": "^0.
|
|
13
|
+
"esbuild": "^0.25.0",
|
|
14
|
+
"express": "^5.1.0"
|
|
14
15
|
},
|
|
15
16
|
"type": "module",
|
|
16
17
|
"name": "@reboot-dev/reboot",
|
|
17
|
-
"version": "0.
|
|
18
|
+
"version": "0.25.0",
|
|
18
19
|
"description": "npm package for Reboot",
|
|
19
20
|
"scripts": {
|
|
20
21
|
"postinstall": "rbt || exit 0",
|
|
@@ -24,7 +25,8 @@
|
|
|
24
25
|
"devDependencies": {
|
|
25
26
|
"typescript": ">=4.9.5",
|
|
26
27
|
"@types/node": "20.11.5",
|
|
27
|
-
"@types/uuid": "^9.0.4"
|
|
28
|
+
"@types/uuid": "^9.0.4",
|
|
29
|
+
"@types/express": "^5.0.1"
|
|
28
30
|
},
|
|
29
31
|
"bin": {
|
|
30
32
|
"rbt": "./rbt.js",
|
package/rbt.js
CHANGED
|
@@ -27,13 +27,16 @@ function addExtensionlessToNodeOptions() {
|
|
|
27
27
|
// If we have one of those two versions then we can pre import
|
|
28
28
|
// `extensionless/register` to use the `module.register()` function,
|
|
29
29
|
// otherwise we need to fall back to `--experimental-loader`.
|
|
30
|
-
if (major
|
|
30
|
+
if (major >= 21 ||
|
|
31
31
|
(major == 20 && minor >= 6) ||
|
|
32
32
|
(major == 18 && minor >= 19)) {
|
|
33
33
|
process.env.NODE_OPTIONS += "--import=extensionless/register";
|
|
34
34
|
}
|
|
35
35
|
else {
|
|
36
|
-
|
|
36
|
+
throw new Error(`The current version of Node.js is not supported.
|
|
37
|
+
Supported versions are:
|
|
38
|
+
* greater than or equal to 20.6
|
|
39
|
+
* greater than or equal to 18.19 but less than 19`);
|
|
37
40
|
}
|
|
38
41
|
}
|
|
39
42
|
async function main() {
|