tempest-express-sdk 0.31.0 → 0.32.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/dist/{chunk-LQTN22TI.js → chunk-VLNTZE7Q.js} +3 -3
- package/dist/{chunk-LQTN22TI.js.map → chunk-VLNTZE7Q.js.map} +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/index.cjs +248 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +267 -2
- package/dist/index.d.ts +267 -2
- package/dist/index.js +244 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -16086,6 +16086,239 @@ function makeMetricsRouter(options = {}) {
|
|
|
16086
16086
|
});
|
|
16087
16087
|
return router;
|
|
16088
16088
|
}
|
|
16089
|
+
var PERSPECTIVE_EXTENSION = "x-tempest-perspective";
|
|
16090
|
+
var ASYNCAPI_VERSION = "3.0.0";
|
|
16091
|
+
function actionFor(direction) {
|
|
16092
|
+
return direction === "clientToServer" ? "receive" : "send";
|
|
16093
|
+
}
|
|
16094
|
+
var AsyncApiRegistry = class {
|
|
16095
|
+
/** Channels by `name`. */
|
|
16096
|
+
channels = /* @__PURE__ */ new Map();
|
|
16097
|
+
/** Messages by `name`. */
|
|
16098
|
+
messages = /* @__PURE__ */ new Map();
|
|
16099
|
+
/** Operations, in registration order. */
|
|
16100
|
+
operations = [];
|
|
16101
|
+
/**
|
|
16102
|
+
* Register the connection a socket is served on.
|
|
16103
|
+
*
|
|
16104
|
+
* @param channel - The channel definition.
|
|
16105
|
+
* @returns This registry, for chaining.
|
|
16106
|
+
* @throws Error When `name` is already registered.
|
|
16107
|
+
*/
|
|
16108
|
+
registerChannel(channel) {
|
|
16109
|
+
if (this.channels.has(channel.name)) {
|
|
16110
|
+
throw new Error(`AsyncAPI channel "${channel.name}" is already registered.`);
|
|
16111
|
+
}
|
|
16112
|
+
this.channels.set(channel.name, channel);
|
|
16113
|
+
return this;
|
|
16114
|
+
}
|
|
16115
|
+
/**
|
|
16116
|
+
* Register one frame the socket carries.
|
|
16117
|
+
*
|
|
16118
|
+
* @param message - The message definition.
|
|
16119
|
+
* @returns This registry, for chaining.
|
|
16120
|
+
* @throws Error When `name` is already registered.
|
|
16121
|
+
*/
|
|
16122
|
+
registerMessage(message) {
|
|
16123
|
+
if (this.messages.has(message.name)) {
|
|
16124
|
+
throw new Error(`AsyncAPI message "${message.name}" is already registered.`);
|
|
16125
|
+
}
|
|
16126
|
+
this.messages.set(message.name, message);
|
|
16127
|
+
return this;
|
|
16128
|
+
}
|
|
16129
|
+
/**
|
|
16130
|
+
* Register a set of messages travelling one way on one channel.
|
|
16131
|
+
*
|
|
16132
|
+
* @param operation - The operation definition.
|
|
16133
|
+
* @returns This registry, for chaining.
|
|
16134
|
+
* @throws Error When `name` is already registered.
|
|
16135
|
+
*/
|
|
16136
|
+
registerOperation(operation) {
|
|
16137
|
+
if (this.operations.some((existing) => existing.name === operation.name)) {
|
|
16138
|
+
throw new Error(`AsyncAPI operation "${operation.name}" is already registered.`);
|
|
16139
|
+
}
|
|
16140
|
+
this.operations.push(operation);
|
|
16141
|
+
return this;
|
|
16142
|
+
}
|
|
16143
|
+
/**
|
|
16144
|
+
* Render the AsyncAPI document.
|
|
16145
|
+
*
|
|
16146
|
+
* @param options - The `info` block, optional servers and default content
|
|
16147
|
+
* type.
|
|
16148
|
+
* @returns The document, JSON-serializable.
|
|
16149
|
+
* @throws Error When an operation names a channel or a message that was
|
|
16150
|
+
* never registered. A dangling `$ref` produces a document that validates
|
|
16151
|
+
* structurally and generates a client missing the frame, so it fails
|
|
16152
|
+
* here instead.
|
|
16153
|
+
*/
|
|
16154
|
+
generate(options) {
|
|
16155
|
+
this.assertReferencesResolve();
|
|
16156
|
+
const schemas = this.renderPayloads();
|
|
16157
|
+
const messages = this.renderMessages();
|
|
16158
|
+
const channels = this.renderChannels(schemas);
|
|
16159
|
+
const operations = this.renderOperations();
|
|
16160
|
+
return {
|
|
16161
|
+
asyncapi: ASYNCAPI_VERSION,
|
|
16162
|
+
[PERSPECTIVE_EXTENSION]: "server",
|
|
16163
|
+
info: {
|
|
16164
|
+
title: options.info.title,
|
|
16165
|
+
version: options.info.version,
|
|
16166
|
+
...options.info.description !== void 0 ? { description: options.info.description } : {}
|
|
16167
|
+
},
|
|
16168
|
+
...options.servers !== void 0 ? { servers: options.servers } : {},
|
|
16169
|
+
defaultContentType: options.defaultContentType ?? "application/json",
|
|
16170
|
+
channels,
|
|
16171
|
+
operations,
|
|
16172
|
+
components: { messages, schemas }
|
|
16173
|
+
};
|
|
16174
|
+
}
|
|
16175
|
+
/**
|
|
16176
|
+
* Fail when an operation points at something that was never registered.
|
|
16177
|
+
*
|
|
16178
|
+
* @throws Error Naming the operation and what it could not resolve.
|
|
16179
|
+
*/
|
|
16180
|
+
assertReferencesResolve() {
|
|
16181
|
+
for (const operation of this.operations) {
|
|
16182
|
+
if (!this.channels.has(operation.channel)) {
|
|
16183
|
+
throw new Error(
|
|
16184
|
+
`AsyncAPI operation "${operation.name}" refers to channel "${operation.channel}", which is not registered.`
|
|
16185
|
+
);
|
|
16186
|
+
}
|
|
16187
|
+
for (const message of operation.messages) {
|
|
16188
|
+
if (!this.messages.has(message)) {
|
|
16189
|
+
throw new Error(
|
|
16190
|
+
`AsyncAPI operation "${operation.name}" refers to message "${message}", which is not registered.`
|
|
16191
|
+
);
|
|
16192
|
+
}
|
|
16193
|
+
}
|
|
16194
|
+
}
|
|
16195
|
+
}
|
|
16196
|
+
/**
|
|
16197
|
+
* Render every payload schema through the OpenAPI generator.
|
|
16198
|
+
*
|
|
16199
|
+
* @returns Component schemas keyed by message name, plus any handshake
|
|
16200
|
+
* schema a channel declared.
|
|
16201
|
+
*
|
|
16202
|
+
* AsyncAPI 3 payloads are JSON Schema, and `generateComponents` emits
|
|
16203
|
+
* exactly that from the Zod objects already validating at runtime. Reusing
|
|
16204
|
+
* it is what keeps the document from describing a shape the server would
|
|
16205
|
+
* reject.
|
|
16206
|
+
*/
|
|
16207
|
+
renderPayloads() {
|
|
16208
|
+
const registry = createOpenApiRegistry();
|
|
16209
|
+
for (const message of this.messages.values()) {
|
|
16210
|
+
registry.register(message.name, message.schema);
|
|
16211
|
+
}
|
|
16212
|
+
for (const channel of this.channels.values()) {
|
|
16213
|
+
if (channel.handshakeHeaders !== void 0) {
|
|
16214
|
+
registry.register(`${channel.name}Headers`, channel.handshakeHeaders);
|
|
16215
|
+
}
|
|
16216
|
+
if (channel.handshakeQuery !== void 0) {
|
|
16217
|
+
registry.register(`${channel.name}Query`, channel.handshakeQuery);
|
|
16218
|
+
}
|
|
16219
|
+
}
|
|
16220
|
+
const components = new zodToOpenapi.OpenApiGeneratorV31(registry.definitions).generateComponents();
|
|
16221
|
+
const schemas = components.components?.schemas ?? {};
|
|
16222
|
+
return schemas;
|
|
16223
|
+
}
|
|
16224
|
+
/**
|
|
16225
|
+
* Render `components.messages`.
|
|
16226
|
+
*
|
|
16227
|
+
* @returns Message objects keyed by name, each pointing at its payload.
|
|
16228
|
+
*/
|
|
16229
|
+
renderMessages() {
|
|
16230
|
+
const rendered = {};
|
|
16231
|
+
for (const [name, message] of this.messages) {
|
|
16232
|
+
rendered[name] = {
|
|
16233
|
+
name,
|
|
16234
|
+
contentType: message.contentType ?? "application/json",
|
|
16235
|
+
...message.summary !== void 0 ? { summary: message.summary } : {},
|
|
16236
|
+
...message.description !== void 0 ? { description: message.description } : {},
|
|
16237
|
+
payload: { $ref: `#/components/schemas/${name}` }
|
|
16238
|
+
};
|
|
16239
|
+
}
|
|
16240
|
+
return rendered;
|
|
16241
|
+
}
|
|
16242
|
+
/**
|
|
16243
|
+
* Render `channels`, each listing every message it can carry.
|
|
16244
|
+
*
|
|
16245
|
+
* @param schemas - The rendered component schemas, to inline the
|
|
16246
|
+
* handshake ones into the binding.
|
|
16247
|
+
* @returns Channel objects keyed by name.
|
|
16248
|
+
*
|
|
16249
|
+
* The handshake schemas are **inlined** rather than `$ref`-ed. The
|
|
16250
|
+
* specification types the binding's `headers` and `query` as
|
|
16251
|
+
* `oneOf: [Schema, Reference]`, and a bare `{"$ref": ...}` object
|
|
16252
|
+
* satisfies both branches — so `oneOf` sees two matches and the document
|
|
16253
|
+
* fails validation against AsyncAPI's own JSON Schema. Measured: the same
|
|
16254
|
+
* binding with the schema inlined validates clean.
|
|
16255
|
+
*
|
|
16256
|
+
* A channel lists every registered message rather than only those its own
|
|
16257
|
+
* operations use: the specification requires an operation's `messages` to
|
|
16258
|
+
* be a subset of its channel's, and with one connection per document the
|
|
16259
|
+
* distinction buys nothing.
|
|
16260
|
+
*/
|
|
16261
|
+
renderChannels(schemas) {
|
|
16262
|
+
const everyMessage = {};
|
|
16263
|
+
for (const name of this.messages.keys()) {
|
|
16264
|
+
everyMessage[name] = { $ref: `#/components/messages/${name}` };
|
|
16265
|
+
}
|
|
16266
|
+
const rendered = {};
|
|
16267
|
+
for (const [name, channel] of this.channels) {
|
|
16268
|
+
const bindings = {
|
|
16269
|
+
bindingVersion: "0.1.0",
|
|
16270
|
+
method: "GET"
|
|
16271
|
+
};
|
|
16272
|
+
if (channel.handshakeHeaders !== void 0) {
|
|
16273
|
+
bindings.headers = schemas[`${name}Headers`];
|
|
16274
|
+
}
|
|
16275
|
+
if (channel.handshakeQuery !== void 0) {
|
|
16276
|
+
bindings.query = schemas[`${name}Query`];
|
|
16277
|
+
}
|
|
16278
|
+
rendered[name] = {
|
|
16279
|
+
address: channel.address,
|
|
16280
|
+
...channel.title !== void 0 ? { title: channel.title } : {},
|
|
16281
|
+
...channel.description !== void 0 ? { description: channel.description } : {},
|
|
16282
|
+
messages: everyMessage,
|
|
16283
|
+
bindings: { ws: bindings }
|
|
16284
|
+
};
|
|
16285
|
+
}
|
|
16286
|
+
return rendered;
|
|
16287
|
+
}
|
|
16288
|
+
/**
|
|
16289
|
+
* Render `operations`, translating each direction into an `action`.
|
|
16290
|
+
*
|
|
16291
|
+
* @returns Operation objects keyed by name.
|
|
16292
|
+
*/
|
|
16293
|
+
renderOperations() {
|
|
16294
|
+
const rendered = {};
|
|
16295
|
+
for (const operation of this.operations) {
|
|
16296
|
+
rendered[operation.name] = {
|
|
16297
|
+
action: actionFor(operation.direction),
|
|
16298
|
+
channel: { $ref: `#/channels/${operation.channel}` },
|
|
16299
|
+
...operation.summary !== void 0 ? { summary: operation.summary } : {},
|
|
16300
|
+
...operation.description !== void 0 ? { description: operation.description } : {},
|
|
16301
|
+
messages: operation.messages.map((message) => ({
|
|
16302
|
+
$ref: `#/channels/${operation.channel}/messages/${message}`
|
|
16303
|
+
}))
|
|
16304
|
+
};
|
|
16305
|
+
}
|
|
16306
|
+
return rendered;
|
|
16307
|
+
}
|
|
16308
|
+
};
|
|
16309
|
+
function createAsyncApiRegistry() {
|
|
16310
|
+
return new AsyncApiRegistry();
|
|
16311
|
+
}
|
|
16312
|
+
function generateAsyncApiDocument(registry, options) {
|
|
16313
|
+
return registry.generate(options);
|
|
16314
|
+
}
|
|
16315
|
+
|
|
16316
|
+
// src/asyncapi/mount.ts
|
|
16317
|
+
function mountAsyncApiJson(app, path, document) {
|
|
16318
|
+
app.get(path, (_req, res) => {
|
|
16319
|
+
res.json(document);
|
|
16320
|
+
});
|
|
16321
|
+
}
|
|
16089
16322
|
var logger4 = new JSONLogger("tempest_express_sdk.api.server");
|
|
16090
16323
|
function corsMiddleware(origins) {
|
|
16091
16324
|
const allowAll = origins === "*";
|
|
@@ -16134,6 +16367,14 @@ async function createApp(options = {}) {
|
|
|
16134
16367
|
mountRedoc(app, redocPath ?? "/redoc", specPath, redoc ?? {});
|
|
16135
16368
|
}
|
|
16136
16369
|
}
|
|
16370
|
+
if (options.asyncapi) {
|
|
16371
|
+
const { registry, jsonPath, ...genOptions } = options.asyncapi;
|
|
16372
|
+
mountAsyncApiJson(
|
|
16373
|
+
app,
|
|
16374
|
+
jsonPath ?? "/asyncapi.json",
|
|
16375
|
+
generateAsyncApiDocument(registry, genOptions)
|
|
16376
|
+
);
|
|
16377
|
+
}
|
|
16137
16378
|
registerExceptionHandlers(app, {
|
|
16138
16379
|
...options.errorHandling,
|
|
16139
16380
|
...options.catalog !== void 0 ? { catalog: options.catalog } : {}
|
|
@@ -17026,7 +17267,7 @@ async function withTestDatabase(models, fn) {
|
|
|
17026
17267
|
}
|
|
17027
17268
|
|
|
17028
17269
|
// src/version.ts
|
|
17029
|
-
var VERSION = "0.
|
|
17270
|
+
var VERSION = "0.32.0";
|
|
17030
17271
|
|
|
17031
17272
|
Object.defineProperty(exports, "OpenAPIRegistry", {
|
|
17032
17273
|
enumerable: true,
|
|
@@ -17185,6 +17426,7 @@ Object.defineProperty(exports, "update", {
|
|
|
17185
17426
|
get: function () { return tempestDbJs.update; }
|
|
17186
17427
|
});
|
|
17187
17428
|
exports.ADMIN_CSS = ADMIN_CSS;
|
|
17429
|
+
exports.ASYNCAPI_VERSION = ASYNCAPI_VERSION;
|
|
17188
17430
|
exports.ActivationService = ActivationService;
|
|
17189
17431
|
exports.AdminJsonSite = AdminJsonSite;
|
|
17190
17432
|
exports.AdminModel = AdminModel;
|
|
@@ -17192,6 +17434,7 @@ exports.AdminPermission = AdminPermission;
|
|
|
17192
17434
|
exports.AdminSessionStore = AdminSessionStore;
|
|
17193
17435
|
exports.AdminSite = AdminSite;
|
|
17194
17436
|
exports.AppException = AppException;
|
|
17437
|
+
exports.AsyncApiRegistry = AsyncApiRegistry;
|
|
17195
17438
|
exports.AttemptThrottle = AttemptThrottle;
|
|
17196
17439
|
exports.AuditAction = AuditAction;
|
|
17197
17440
|
exports.BaseAuditLogModel = BaseAuditLogModel;
|
|
@@ -17253,6 +17496,7 @@ exports.OAuthError = OAuthError;
|
|
|
17253
17496
|
exports.OIDCProvider = OIDCProvider;
|
|
17254
17497
|
exports.OutboxRelay = OutboxRelay;
|
|
17255
17498
|
exports.OutboxStatus = OutboxStatus;
|
|
17499
|
+
exports.PERSPECTIVE_EXTENSION = PERSPECTIVE_EXTENSION;
|
|
17256
17500
|
exports.PHONE_BR_PATTERN = PHONE_BR_PATTERN;
|
|
17257
17501
|
exports.PasswordResetService = PasswordResetService;
|
|
17258
17502
|
exports.PasswordUtils = PasswordUtils;
|
|
@@ -17324,6 +17568,7 @@ exports.corsSettingsShape = corsSettingsShape;
|
|
|
17324
17568
|
exports.cpfField = cpfField;
|
|
17325
17569
|
exports.cpfOrCnpjField = cpfOrCnpjField;
|
|
17326
17570
|
exports.createApp = createApp;
|
|
17571
|
+
exports.createAsyncApiRegistry = createAsyncApiRegistry;
|
|
17327
17572
|
exports.createOpenApiRegistry = createOpenApiRegistry;
|
|
17328
17573
|
exports.createTestDatabase = createTestDatabase;
|
|
17329
17574
|
exports.createdByColumn = createdByColumn;
|
|
@@ -17349,6 +17594,7 @@ exports.foreignKeyLabel = foreignKeyLabel;
|
|
|
17349
17594
|
exports.foreignKeyTable = foreignKeyTable;
|
|
17350
17595
|
exports.formatCellValue = formatCellValue;
|
|
17351
17596
|
exports.formatFieldValue = formatFieldValue;
|
|
17597
|
+
exports.generateAsyncApiDocument = generateAsyncApiDocument;
|
|
17352
17598
|
exports.generateCsrfToken = generateCsrfToken;
|
|
17353
17599
|
exports.generateOAuthState = generateOAuthState;
|
|
17354
17600
|
exports.generateOpaqueToken = generateOpaqueToken;
|
|
@@ -17409,6 +17655,7 @@ exports.mfaCodeSchema = mfaCodeSchema;
|
|
|
17409
17655
|
exports.mfaEnrollResponseSchema = mfaEnrollResponseSchema;
|
|
17410
17656
|
exports.minioSettingsShape = minioSettingsShape;
|
|
17411
17657
|
exports.modifyDict = modifyDict;
|
|
17658
|
+
exports.mountAsyncApiJson = mountAsyncApiJson;
|
|
17412
17659
|
exports.mountOpenApiJson = mountOpenApiJson;
|
|
17413
17660
|
exports.mountRedoc = mountRedoc;
|
|
17414
17661
|
exports.mountSwaggerUi = mountSwaggerUi;
|