tempest-express-sdk 0.2.0 → 0.3.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/README.md +7 -2
- package/dist/chunk-6ZKN2ELQ.js +6 -0
- package/dist/{chunk-6QNSLBL3.js.map → chunk-6ZKN2ELQ.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 +448 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +373 -4
- package/dist/index.d.ts +373 -4
- package/dist/index.js +437 -3
- package/dist/index.js.map +1 -1
- package/package.json +13 -1
- package/dist/chunk-6QNSLBL3.js +0 -6
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { VERSION } from './chunk-
|
|
1
|
+
export { VERSION } from './chunk-6ZKN2ELQ.js';
|
|
2
2
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
3
3
|
import { extendZodWithOpenApi, OpenAPIRegistry, OpenApiGeneratorV31, OpenApiGeneratorV3 } from '@asteasolutions/zod-to-openapi';
|
|
4
4
|
export { OpenAPIRegistry } from '@asteasolutions/zod-to-openapi';
|
|
@@ -6,7 +6,8 @@ import { z, ZodError } from 'zod';
|
|
|
6
6
|
export { z } from 'zod';
|
|
7
7
|
import { Model, column, sql } from 'tempest-db-js';
|
|
8
8
|
export { AsyncEngine, AsyncResult, AsyncSession, BaseRepository, Column, DeleteBuilder, InsertBuilder, Model, NoResultError, NodeSqliteDriver, PostgresDialect, RecordNotFound, SelectBuilder, SqliteDialect, SyncEngine, SyncSession, UpdateBuilder, and, belongsTo, column, columnsOf, createEngine, createSyncEngine, del, detectDialect, getDialect, hasMany, insert, join, loadRelations, not, or, parseDatabaseUrl, select, sql, update } from 'tempest-db-js';
|
|
9
|
-
import { createHash, randomBytes, timingSafeEqual, randomUUID } from 'crypto';
|
|
9
|
+
import { createHash, randomBytes, timingSafeEqual, randomUUID, createHmac } from 'crypto';
|
|
10
|
+
import { cpus, loadavg, totalmem, freemem } from 'os';
|
|
10
11
|
import { mkdir, writeFile, readFile, rm } from 'fs/promises';
|
|
11
12
|
import { join, dirname } from 'path';
|
|
12
13
|
import express2, { Router } from 'express';
|
|
@@ -6752,6 +6753,361 @@ var AttemptThrottle = class {
|
|
|
6752
6753
|
}
|
|
6753
6754
|
};
|
|
6754
6755
|
|
|
6756
|
+
// src/utils/clientIp.ts
|
|
6757
|
+
var UNKNOWN = "unknown";
|
|
6758
|
+
function getClientIp(req, options = {}) {
|
|
6759
|
+
if (options.trustedHeader) {
|
|
6760
|
+
const value = req.header(options.trustedHeader);
|
|
6761
|
+
if (value) return value.trim();
|
|
6762
|
+
}
|
|
6763
|
+
return req.socket?.remoteAddress ?? req.ip ?? UNKNOWN;
|
|
6764
|
+
}
|
|
6765
|
+
var BASE32_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
|
6766
|
+
function base32Encode(bytes) {
|
|
6767
|
+
let bits = 0;
|
|
6768
|
+
let value = 0;
|
|
6769
|
+
let out = "";
|
|
6770
|
+
for (const byte of bytes) {
|
|
6771
|
+
value = value << 8 | byte;
|
|
6772
|
+
bits += 8;
|
|
6773
|
+
while (bits >= 5) {
|
|
6774
|
+
out += BASE32_ALPHABET[value >>> bits - 5 & 31];
|
|
6775
|
+
bits -= 5;
|
|
6776
|
+
}
|
|
6777
|
+
}
|
|
6778
|
+
if (bits > 0) out += BASE32_ALPHABET[value << 5 - bits & 31];
|
|
6779
|
+
return out;
|
|
6780
|
+
}
|
|
6781
|
+
function base32Decode(secret) {
|
|
6782
|
+
const clean = secret.toUpperCase().replace(/=+$/, "").replace(/\s/g, "");
|
|
6783
|
+
let bits = 0;
|
|
6784
|
+
let value = 0;
|
|
6785
|
+
const out = [];
|
|
6786
|
+
for (const char of clean) {
|
|
6787
|
+
const index = BASE32_ALPHABET.indexOf(char);
|
|
6788
|
+
if (index === -1) continue;
|
|
6789
|
+
value = value << 5 | index;
|
|
6790
|
+
bits += 5;
|
|
6791
|
+
if (bits >= 8) {
|
|
6792
|
+
out.push(value >>> bits - 8 & 255);
|
|
6793
|
+
bits -= 8;
|
|
6794
|
+
}
|
|
6795
|
+
}
|
|
6796
|
+
return Buffer.from(out);
|
|
6797
|
+
}
|
|
6798
|
+
function hotp(secret, counter, digits) {
|
|
6799
|
+
const buffer = Buffer.alloc(8);
|
|
6800
|
+
buffer.writeUInt32BE(Math.floor(counter / 2 ** 32), 0);
|
|
6801
|
+
buffer.writeUInt32BE(counter >>> 0, 4);
|
|
6802
|
+
const digest = createHmac("sha1", secret).update(buffer).digest();
|
|
6803
|
+
const offset = digest[digest.length - 1] & 15;
|
|
6804
|
+
const binary = (digest[offset] & 127) << 24 | (digest[offset + 1] & 255) << 16 | (digest[offset + 2] & 255) << 8 | digest[offset + 3] & 255;
|
|
6805
|
+
return (binary % 10 ** digits).toString().padStart(digits, "0");
|
|
6806
|
+
}
|
|
6807
|
+
var TOTPHelper = class {
|
|
6808
|
+
issuer;
|
|
6809
|
+
step;
|
|
6810
|
+
digits;
|
|
6811
|
+
/**
|
|
6812
|
+
* @param options - Issuer label, time step and digit count.
|
|
6813
|
+
*/
|
|
6814
|
+
constructor(options) {
|
|
6815
|
+
this.issuer = options.issuer;
|
|
6816
|
+
this.step = options.step ?? 30;
|
|
6817
|
+
this.digits = options.digits ?? 6;
|
|
6818
|
+
}
|
|
6819
|
+
/**
|
|
6820
|
+
* Generate a fresh base32 secret (80 bits).
|
|
6821
|
+
*
|
|
6822
|
+
* @returns A base32-encoded TOTP secret to persist on the user row.
|
|
6823
|
+
*/
|
|
6824
|
+
generateSecret() {
|
|
6825
|
+
return base32Encode(randomBytes(10));
|
|
6826
|
+
}
|
|
6827
|
+
/**
|
|
6828
|
+
* Build the `otpauth://` provisioning URI (render as a QR code).
|
|
6829
|
+
*
|
|
6830
|
+
* @param secret - The base32 secret.
|
|
6831
|
+
* @param accountName - Identifier shown next to the issuer (e.g. the email).
|
|
6832
|
+
* @returns The `otpauth://totp/...` URI.
|
|
6833
|
+
*/
|
|
6834
|
+
provisioningUri(secret, accountName) {
|
|
6835
|
+
const label = encodeURIComponent(`${this.issuer}:${accountName}`);
|
|
6836
|
+
const params = new URLSearchParams({
|
|
6837
|
+
secret,
|
|
6838
|
+
issuer: this.issuer,
|
|
6839
|
+
algorithm: "SHA1",
|
|
6840
|
+
digits: String(this.digits),
|
|
6841
|
+
period: String(this.step)
|
|
6842
|
+
});
|
|
6843
|
+
return `otpauth://totp/${label}?${params.toString()}`;
|
|
6844
|
+
}
|
|
6845
|
+
/**
|
|
6846
|
+
* Verify a code against the secret for the current time window.
|
|
6847
|
+
*
|
|
6848
|
+
* @param secret - The base32 secret.
|
|
6849
|
+
* @param code - The submitted code.
|
|
6850
|
+
* @param window - Tolerance in steps (±). Default 1 (previous/current/next).
|
|
6851
|
+
* @returns `true` when the code matches within the window.
|
|
6852
|
+
*/
|
|
6853
|
+
verify(secret, code, window = 1) {
|
|
6854
|
+
const cleaned = code.trim().replace(/[\s-]/g, "");
|
|
6855
|
+
if (!/^\d+$/.test(cleaned) || cleaned.length !== this.digits) return false;
|
|
6856
|
+
const key = base32Decode(secret);
|
|
6857
|
+
const counter = Math.floor(Date.now() / 1e3 / this.step);
|
|
6858
|
+
for (let offset = -window; offset <= window; offset++) {
|
|
6859
|
+
if (hotp(key, counter + offset, this.digits) === cleaned) return true;
|
|
6860
|
+
}
|
|
6861
|
+
return false;
|
|
6862
|
+
}
|
|
6863
|
+
};
|
|
6864
|
+
|
|
6865
|
+
// src/utils/httpClient.ts
|
|
6866
|
+
var CircuitOpenError = class extends Error {
|
|
6867
|
+
constructor(host) {
|
|
6868
|
+
super(`Circuit breaker is open for host ${host}`);
|
|
6869
|
+
this.host = host;
|
|
6870
|
+
this.name = "CircuitOpenError";
|
|
6871
|
+
}
|
|
6872
|
+
host;
|
|
6873
|
+
};
|
|
6874
|
+
var RetryPolicy = class {
|
|
6875
|
+
/**
|
|
6876
|
+
* @param maxRetries - Additional attempts after the first. Default 2.
|
|
6877
|
+
* @param baseDelayMs - Base backoff in ms (doubles each attempt). Default 100.
|
|
6878
|
+
* @param retryOn - HTTP status codes that trigger a retry. Default 5xx + 429.
|
|
6879
|
+
*/
|
|
6880
|
+
constructor(maxRetries = 2, baseDelayMs = 100, retryOn = [429, 500, 502, 503, 504]) {
|
|
6881
|
+
this.maxRetries = maxRetries;
|
|
6882
|
+
this.baseDelayMs = baseDelayMs;
|
|
6883
|
+
this.retryOn = retryOn;
|
|
6884
|
+
}
|
|
6885
|
+
maxRetries;
|
|
6886
|
+
baseDelayMs;
|
|
6887
|
+
retryOn;
|
|
6888
|
+
/** Backoff delay in ms before `attempt` (0-indexed). */
|
|
6889
|
+
sleepFor(attempt) {
|
|
6890
|
+
return this.baseDelayMs * 2 ** attempt;
|
|
6891
|
+
}
|
|
6892
|
+
};
|
|
6893
|
+
var HTTPClient = class {
|
|
6894
|
+
baseUrl;
|
|
6895
|
+
defaultHeaders;
|
|
6896
|
+
timeoutMs;
|
|
6897
|
+
retryPolicy;
|
|
6898
|
+
breakerThreshold;
|
|
6899
|
+
breakerCooldownMs;
|
|
6900
|
+
breakers = /* @__PURE__ */ new Map();
|
|
6901
|
+
/**
|
|
6902
|
+
* @param options - Base URL, headers, timeout, retry and breaker settings.
|
|
6903
|
+
*/
|
|
6904
|
+
constructor(options = {}) {
|
|
6905
|
+
this.baseUrl = options.baseUrl ?? "";
|
|
6906
|
+
this.defaultHeaders = options.defaultHeaders ?? {};
|
|
6907
|
+
this.timeoutMs = options.timeoutMs ?? 3e4;
|
|
6908
|
+
this.retryPolicy = options.retryPolicy ?? new RetryPolicy();
|
|
6909
|
+
this.breakerThreshold = options.breakerThreshold ?? 5;
|
|
6910
|
+
this.breakerCooldownMs = options.breakerCooldownMs ?? 3e4;
|
|
6911
|
+
}
|
|
6912
|
+
resolve(url) {
|
|
6913
|
+
return this.baseUrl && !/^https?:\/\//.test(url) ? `${this.baseUrl}${url}` : url;
|
|
6914
|
+
}
|
|
6915
|
+
hostOf(url) {
|
|
6916
|
+
try {
|
|
6917
|
+
return new URL(url).host;
|
|
6918
|
+
} catch {
|
|
6919
|
+
return url;
|
|
6920
|
+
}
|
|
6921
|
+
}
|
|
6922
|
+
breakerCheck(host) {
|
|
6923
|
+
const state = this.breakers.get(host);
|
|
6924
|
+
if (state && state.openUntil > Date.now()) throw new CircuitOpenError(host);
|
|
6925
|
+
}
|
|
6926
|
+
breakerRecord(host, failed) {
|
|
6927
|
+
const state = this.breakers.get(host) ?? { failures: 0, openUntil: 0 };
|
|
6928
|
+
if (failed) {
|
|
6929
|
+
state.failures += 1;
|
|
6930
|
+
if (state.failures >= this.breakerThreshold) {
|
|
6931
|
+
state.openUntil = Date.now() + this.breakerCooldownMs;
|
|
6932
|
+
state.failures = 0;
|
|
6933
|
+
}
|
|
6934
|
+
} else {
|
|
6935
|
+
state.failures = 0;
|
|
6936
|
+
state.openUntil = 0;
|
|
6937
|
+
}
|
|
6938
|
+
this.breakers.set(host, state);
|
|
6939
|
+
}
|
|
6940
|
+
/**
|
|
6941
|
+
* Perform a request with retries and breaker protection.
|
|
6942
|
+
*
|
|
6943
|
+
* @param method - HTTP method.
|
|
6944
|
+
* @param url - Absolute URL or a path resolved against `baseUrl`.
|
|
6945
|
+
* @param init - Extra `fetch` init (headers, body, …).
|
|
6946
|
+
* @returns The `Response`.
|
|
6947
|
+
* @throws {CircuitOpenError} When the per-host breaker is open.
|
|
6948
|
+
*/
|
|
6949
|
+
async request(method, url, init = {}) {
|
|
6950
|
+
const target = this.resolve(url);
|
|
6951
|
+
const host = this.hostOf(target);
|
|
6952
|
+
this.breakerCheck(host);
|
|
6953
|
+
let lastError;
|
|
6954
|
+
for (let attempt = 0; attempt <= this.retryPolicy.maxRetries; attempt++) {
|
|
6955
|
+
const controller = new AbortController();
|
|
6956
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
6957
|
+
try {
|
|
6958
|
+
const response = await fetch(target, {
|
|
6959
|
+
...init,
|
|
6960
|
+
method,
|
|
6961
|
+
headers: { ...this.defaultHeaders, ...init.headers ?? {} },
|
|
6962
|
+
signal: controller.signal
|
|
6963
|
+
});
|
|
6964
|
+
clearTimeout(timer);
|
|
6965
|
+
if (this.retryPolicy.retryOn.includes(response.status)) {
|
|
6966
|
+
this.breakerRecord(host, true);
|
|
6967
|
+
if (attempt < this.retryPolicy.maxRetries) {
|
|
6968
|
+
await this.sleep(this.retryPolicy.sleepFor(attempt));
|
|
6969
|
+
continue;
|
|
6970
|
+
}
|
|
6971
|
+
return response;
|
|
6972
|
+
}
|
|
6973
|
+
this.breakerRecord(host, false);
|
|
6974
|
+
return response;
|
|
6975
|
+
} catch (error) {
|
|
6976
|
+
clearTimeout(timer);
|
|
6977
|
+
lastError = error;
|
|
6978
|
+
this.breakerRecord(host, true);
|
|
6979
|
+
if (attempt < this.retryPolicy.maxRetries) {
|
|
6980
|
+
await this.sleep(this.retryPolicy.sleepFor(attempt));
|
|
6981
|
+
continue;
|
|
6982
|
+
}
|
|
6983
|
+
}
|
|
6984
|
+
}
|
|
6985
|
+
throw lastError instanceof Error ? lastError : new Error("Request failed");
|
|
6986
|
+
}
|
|
6987
|
+
sleep(ms) {
|
|
6988
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
6989
|
+
}
|
|
6990
|
+
/** GET request. */
|
|
6991
|
+
get(url, init) {
|
|
6992
|
+
return this.request("GET", url, init);
|
|
6993
|
+
}
|
|
6994
|
+
/** POST request. */
|
|
6995
|
+
post(url, init) {
|
|
6996
|
+
return this.request("POST", url, init);
|
|
6997
|
+
}
|
|
6998
|
+
/** PUT request. */
|
|
6999
|
+
put(url, init) {
|
|
7000
|
+
return this.request("PUT", url, init);
|
|
7001
|
+
}
|
|
7002
|
+
/** PATCH request. */
|
|
7003
|
+
patch(url, init) {
|
|
7004
|
+
return this.request("PATCH", url, init);
|
|
7005
|
+
}
|
|
7006
|
+
/** DELETE request. */
|
|
7007
|
+
delete(url, init) {
|
|
7008
|
+
return this.request("DELETE", url, init);
|
|
7009
|
+
}
|
|
7010
|
+
};
|
|
7011
|
+
function readCpu() {
|
|
7012
|
+
const cores = cpus().length;
|
|
7013
|
+
const load1 = loadavg()[0] ?? 0;
|
|
7014
|
+
return {
|
|
7015
|
+
cores,
|
|
7016
|
+
load1,
|
|
7017
|
+
loadPercent: cores > 0 ? load1 / cores * 100 : 0
|
|
7018
|
+
};
|
|
7019
|
+
}
|
|
7020
|
+
function readMemory() {
|
|
7021
|
+
const total = totalmem();
|
|
7022
|
+
const free = freemem();
|
|
7023
|
+
const used = total - free;
|
|
7024
|
+
return {
|
|
7025
|
+
total,
|
|
7026
|
+
free,
|
|
7027
|
+
used,
|
|
7028
|
+
usedPercent: total > 0 ? used / total * 100 : 0,
|
|
7029
|
+
processRss: process.memoryUsage().rss
|
|
7030
|
+
};
|
|
7031
|
+
}
|
|
7032
|
+
function readSystem() {
|
|
7033
|
+
return {
|
|
7034
|
+
cpu: readCpu(),
|
|
7035
|
+
memory: readMemory(),
|
|
7036
|
+
uptimeSeconds: process.uptime()
|
|
7037
|
+
};
|
|
7038
|
+
}
|
|
7039
|
+
function toPrometheus(snapshot = readSystem()) {
|
|
7040
|
+
const lines = [
|
|
7041
|
+
"# HELP process_cpu_load_percent 1-minute load average as percent of cores",
|
|
7042
|
+
"# TYPE process_cpu_load_percent gauge",
|
|
7043
|
+
`process_cpu_load_percent ${snapshot.cpu.loadPercent}`,
|
|
7044
|
+
"# HELP process_memory_used_percent System memory used percent",
|
|
7045
|
+
"# TYPE process_memory_used_percent gauge",
|
|
7046
|
+
`process_memory_used_percent ${snapshot.memory.usedPercent}`,
|
|
7047
|
+
"# HELP process_memory_rss_bytes Resident set size of the process",
|
|
7048
|
+
"# TYPE process_memory_rss_bytes gauge",
|
|
7049
|
+
`process_memory_rss_bytes ${snapshot.memory.processRss}`,
|
|
7050
|
+
"# HELP process_uptime_seconds Process uptime in seconds",
|
|
7051
|
+
"# TYPE process_uptime_seconds counter",
|
|
7052
|
+
`process_uptime_seconds ${snapshot.uptimeSeconds}`
|
|
7053
|
+
];
|
|
7054
|
+
return `${lines.join("\n")}
|
|
7055
|
+
`;
|
|
7056
|
+
}
|
|
7057
|
+
var MetricsUtils = {
|
|
7058
|
+
cpu: readCpu,
|
|
7059
|
+
memory: readMemory,
|
|
7060
|
+
system: readSystem,
|
|
7061
|
+
toPrometheus
|
|
7062
|
+
};
|
|
7063
|
+
|
|
7064
|
+
// src/utils/email.ts
|
|
7065
|
+
var EmailUtils = class {
|
|
7066
|
+
/**
|
|
7067
|
+
* @param options - SMTP connection and default sender.
|
|
7068
|
+
*/
|
|
7069
|
+
constructor(options) {
|
|
7070
|
+
this.options = options;
|
|
7071
|
+
}
|
|
7072
|
+
options;
|
|
7073
|
+
transport = null;
|
|
7074
|
+
async ready() {
|
|
7075
|
+
if (this.transport) return this.transport;
|
|
7076
|
+
let nodemailer;
|
|
7077
|
+
try {
|
|
7078
|
+
const mod = await import('nodemailer');
|
|
7079
|
+
nodemailer = mod.default ?? mod;
|
|
7080
|
+
} catch (cause) {
|
|
7081
|
+
throw new Error(
|
|
7082
|
+
"EmailUtils requires the 'nodemailer' peer dependency. Install with `npm i nodemailer`.",
|
|
7083
|
+
{ cause }
|
|
7084
|
+
);
|
|
7085
|
+
}
|
|
7086
|
+
this.transport = nodemailer.createTransport({
|
|
7087
|
+
host: this.options.host,
|
|
7088
|
+
port: this.options.port ?? 587,
|
|
7089
|
+
secure: this.options.secure ?? false,
|
|
7090
|
+
...this.options.user ? { auth: { user: this.options.user, pass: this.options.password ?? "" } } : {}
|
|
7091
|
+
});
|
|
7092
|
+
return this.transport;
|
|
7093
|
+
}
|
|
7094
|
+
/**
|
|
7095
|
+
* Send an email message.
|
|
7096
|
+
*
|
|
7097
|
+
* @param message - The message (recipients, subject, body).
|
|
7098
|
+
*/
|
|
7099
|
+
async send(message) {
|
|
7100
|
+
const transport = await this.ready();
|
|
7101
|
+
await transport.sendMail({
|
|
7102
|
+
from: message.from ?? this.options.from,
|
|
7103
|
+
to: message.to,
|
|
7104
|
+
subject: message.subject,
|
|
7105
|
+
...message.text !== void 0 ? { text: message.text } : {},
|
|
7106
|
+
...message.html !== void 0 ? { html: message.html } : {}
|
|
7107
|
+
});
|
|
7108
|
+
}
|
|
7109
|
+
};
|
|
7110
|
+
|
|
6755
7111
|
// src/cache/manager.ts
|
|
6756
7112
|
var MemoryCacheManager = class {
|
|
6757
7113
|
store = /* @__PURE__ */ new Map();
|
|
@@ -7592,6 +7948,84 @@ function buildContentDisposition(filename, inline = false) {
|
|
|
7592
7948
|
return `${disposition}; filename*=UTF-8''${encoded}`;
|
|
7593
7949
|
}
|
|
7594
7950
|
|
|
7951
|
+
// src/webpush/schemas.ts
|
|
7952
|
+
var webPushKeysSchema = z.object({
|
|
7953
|
+
p256dh: z.string().openapi({ description: "Client public key (base64url)." }),
|
|
7954
|
+
auth: z.string().openapi({ description: "Client auth secret (base64url)." })
|
|
7955
|
+
}).openapi("WebPushKeys");
|
|
7956
|
+
var webPushSubscriptionSchema = z.object({
|
|
7957
|
+
endpoint: z.string().url().openapi({ description: "Push service endpoint URL." }),
|
|
7958
|
+
keys: webPushKeysSchema
|
|
7959
|
+
}).openapi("WebPushSubscription");
|
|
7960
|
+
var webPushPayloadSchema = z.object({
|
|
7961
|
+
title: z.string().openapi({ description: "Notification title." }),
|
|
7962
|
+
body: z.string().optional().openapi({ description: "Notification body." }),
|
|
7963
|
+
url: z.string().optional().openapi({ description: "URL opened on click." }),
|
|
7964
|
+
data: z.record(z.unknown()).optional().openapi({ description: "Extra data." })
|
|
7965
|
+
}).openapi("WebPushPayload");
|
|
7966
|
+
|
|
7967
|
+
// src/webpush/dispatcher.ts
|
|
7968
|
+
var WebPushError = class extends Error {
|
|
7969
|
+
constructor(message, statusCode) {
|
|
7970
|
+
super(message);
|
|
7971
|
+
this.statusCode = statusCode;
|
|
7972
|
+
this.name = "WebPushError";
|
|
7973
|
+
}
|
|
7974
|
+
statusCode;
|
|
7975
|
+
};
|
|
7976
|
+
var WebPushGoneError = class extends WebPushError {
|
|
7977
|
+
constructor(statusCode) {
|
|
7978
|
+
super("Push subscription is gone", statusCode);
|
|
7979
|
+
this.name = "WebPushGoneError";
|
|
7980
|
+
}
|
|
7981
|
+
};
|
|
7982
|
+
var cached4 = null;
|
|
7983
|
+
async function loadWebPush() {
|
|
7984
|
+
if (cached4) return cached4;
|
|
7985
|
+
try {
|
|
7986
|
+
const mod = await import('web-push');
|
|
7987
|
+
cached4 = mod.default ?? mod;
|
|
7988
|
+
} catch (cause) {
|
|
7989
|
+
throw new Error(
|
|
7990
|
+
"WebPushDispatcher requires the 'web-push' peer dependency. Install with `npm i web-push`.",
|
|
7991
|
+
{ cause }
|
|
7992
|
+
);
|
|
7993
|
+
}
|
|
7994
|
+
return cached4;
|
|
7995
|
+
}
|
|
7996
|
+
var WebPushDispatcher = class {
|
|
7997
|
+
/**
|
|
7998
|
+
* @param options - VAPID keys and subject.
|
|
7999
|
+
*/
|
|
8000
|
+
constructor(options) {
|
|
8001
|
+
this.options = options;
|
|
8002
|
+
}
|
|
8003
|
+
options;
|
|
8004
|
+
/**
|
|
8005
|
+
* Send a payload to a single subscription.
|
|
8006
|
+
*
|
|
8007
|
+
* @param subscription - The browser push subscription.
|
|
8008
|
+
* @param payload - The notification payload.
|
|
8009
|
+
* @throws {WebPushGoneError} When the subscription is expired (410/404).
|
|
8010
|
+
* @throws {WebPushError} On any other delivery failure.
|
|
8011
|
+
*/
|
|
8012
|
+
async send(subscription, payload) {
|
|
8013
|
+
const webpush = await loadWebPush();
|
|
8014
|
+
webpush.setVapidDetails(
|
|
8015
|
+
this.options.subject,
|
|
8016
|
+
this.options.publicKey,
|
|
8017
|
+
this.options.privateKey
|
|
8018
|
+
);
|
|
8019
|
+
try {
|
|
8020
|
+
await webpush.sendNotification(subscription, JSON.stringify(payload));
|
|
8021
|
+
} catch (error) {
|
|
8022
|
+
const status = error.statusCode;
|
|
8023
|
+
if (status === 404 || status === 410) throw new WebPushGoneError(status);
|
|
8024
|
+
throw new WebPushError(error.message, status);
|
|
8025
|
+
}
|
|
8026
|
+
}
|
|
8027
|
+
};
|
|
8028
|
+
|
|
7595
8029
|
// src/auth/schemas.ts
|
|
7596
8030
|
var signupSchema = z.object({
|
|
7597
8031
|
email: z.string().email().openapi({ description: "Login identifier (email)." }),
|
|
@@ -8103,6 +8537,6 @@ function runServer(app, options = {}) {
|
|
|
8103
8537
|
});
|
|
8104
8538
|
}
|
|
8105
8539
|
|
|
8106
|
-
export { AppException, AttemptThrottle, BaseController, BaseModel, BaseService, CEP_PATTERN, CNPJ_PATTERN, CPF_PATTERN, CompositeFeatureFlagBackend, ConflictException, DEFAULT_LOCALE, EnvFeatureFlagBackend, EventStream, ExpiredTokenException, FeatureFlags, ForbiddenException, HTTP_500_MARKER, InvalidTokenException, JSONLogger, JWTUtils, LocalUploadStorage, MemoryBroker, MemoryCacheManager, MemoryFeatureFlagBackend, MemorySessionStore, MemoryThrottleBackend, MessageCatalog, NotFoundException, PHONE_BR_PATTERN, PasswordUtils, REQUEST_ID_HEADER, RabbitBroker, RedisCacheManager, Region, SSEBroker, ServerSentEvent, SessionService, TaskManager, TooManyRequestsException, UF, UnauthorizedException, UserAuthService, ValidationException, WebSocketHub, attachWebSocketHub, authResponseSchema, baseAppSettingsSchema, baseAppSettingsShape, baseResponseSchema, bearerToken, buildContentDisposition, cached3 as cached, cepField, citiesByUf, cnpjField, coerceFlag, configureLogging, corsSettingsShape, cpfField, cpfOrCnpjField, createApp, createOpenApiRegistry, createdByColumn, cursorPaginationFilterSchema, cursorPaginationSchema, databaseSettingsShape, decodeCursor, defaultMessageCatalog, defineEnum, deletedAtColumn, encodeCursor, generateOpaqueToken, generateOpenApiDocument, getAuth, getConditions, getPaginationConditions, getRequestId, getState, hashOpaqueToken, isValidCep, isValidCity, isValidCnpj, isValidCpf, isValidCpfCnpj, isValidPhoneBr, isValidUf, listStates, loadSettings, loginSchema, makeAppExceptionHandler, makeAuthRouter, makeFlagGuard, makeHealthRouter, makeJwtAuthMiddleware, makeSessionMiddleware, makeUnhandledExceptionHandler, modifyDict, mountOpenApiJson, mountRedoc, mountSwaggerUi, normalizeCep, normalizeCnpj, normalizeCpf, normalizeCpfCnpj, normalizePhoneBr, normalizeUf, notFoundHandler, onlyDigits, paginationFilterSchema, paginationSchema, parseAcceptLanguage, parseCookies, phoneBrField, refreshSchema, registerExceptionHandlers, requestIdMiddleware, requireRoles, runServer, runWithRequestContext, serverSettingsShape, sessionCookie, setRequestId, signupSchema, sseResponse, statesByRegion, tableNameFor, toDict, toUtc, tokenFromUrl, tokenPairSchema, ufField, updatedByColumn, userPublicSchema, utcnow, verifyOpaqueToken, wsEnvelopeSchema };
|
|
8540
|
+
export { AppException, AttemptThrottle, BaseController, BaseModel, BaseService, CEP_PATTERN, CNPJ_PATTERN, CPF_PATTERN, CircuitOpenError, CompositeFeatureFlagBackend, ConflictException, DEFAULT_LOCALE, EmailUtils, EnvFeatureFlagBackend, EventStream, ExpiredTokenException, FeatureFlags, ForbiddenException, HTTPClient, HTTP_500_MARKER, InvalidTokenException, JSONLogger, JWTUtils, LocalUploadStorage, MemoryBroker, MemoryCacheManager, MemoryFeatureFlagBackend, MemorySessionStore, MemoryThrottleBackend, MessageCatalog, MetricsUtils, NotFoundException, PHONE_BR_PATTERN, PasswordUtils, REQUEST_ID_HEADER, RabbitBroker, RedisCacheManager, Region, RetryPolicy, SSEBroker, ServerSentEvent, SessionService, TOTPHelper, TaskManager, TooManyRequestsException, UF, UnauthorizedException, UserAuthService, ValidationException, WebPushDispatcher, WebPushError, WebPushGoneError, WebSocketHub, attachWebSocketHub, authResponseSchema, baseAppSettingsSchema, baseAppSettingsShape, baseResponseSchema, bearerToken, buildContentDisposition, cached3 as cached, cepField, citiesByUf, cnpjField, coerceFlag, configureLogging, corsSettingsShape, cpfField, cpfOrCnpjField, createApp, createOpenApiRegistry, createdByColumn, cursorPaginationFilterSchema, cursorPaginationSchema, databaseSettingsShape, decodeCursor, defaultMessageCatalog, defineEnum, deletedAtColumn, encodeCursor, generateOpaqueToken, generateOpenApiDocument, getAuth, getClientIp, getConditions, getPaginationConditions, getRequestId, getState, hashOpaqueToken, isValidCep, isValidCity, isValidCnpj, isValidCpf, isValidCpfCnpj, isValidPhoneBr, isValidUf, listStates, loadSettings, loginSchema, makeAppExceptionHandler, makeAuthRouter, makeFlagGuard, makeHealthRouter, makeJwtAuthMiddleware, makeSessionMiddleware, makeUnhandledExceptionHandler, modifyDict, mountOpenApiJson, mountRedoc, mountSwaggerUi, normalizeCep, normalizeCnpj, normalizeCpf, normalizeCpfCnpj, normalizePhoneBr, normalizeUf, notFoundHandler, onlyDigits, paginationFilterSchema, paginationSchema, parseAcceptLanguage, parseCookies, phoneBrField, refreshSchema, registerExceptionHandlers, requestIdMiddleware, requireRoles, runServer, runWithRequestContext, serverSettingsShape, sessionCookie, setRequestId, signupSchema, sseResponse, statesByRegion, tableNameFor, toDict, toUtc, tokenFromUrl, tokenPairSchema, ufField, updatedByColumn, userPublicSchema, utcnow, verifyOpaqueToken, webPushKeysSchema, webPushPayloadSchema, webPushSubscriptionSchema, wsEnvelopeSchema };
|
|
8107
8541
|
//# sourceMappingURL=index.js.map
|
|
8108
8542
|
//# sourceMappingURL=index.js.map
|