nomkit 0.0.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/LICENSE.txt +21 -0
- package/dist/_virtual/_rolldown/runtime.js +27 -0
- package/dist/adapters/index.d.ts +15 -0
- package/dist/adapters/index.js +6 -0
- package/dist/cli/commands/push.d.ts +6 -0
- package/dist/cli/commands/push.js +143 -0
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.js +18 -0
- package/dist/cli/lib/collection_sync.d.ts +107 -0
- package/dist/cli/lib/collection_sync.js +158 -0
- package/dist/cli/lib/config_loader.d.ts +15 -0
- package/dist/cli/lib/config_loader.js +43 -0
- package/dist/cli/lib/hash.d.ts +22 -0
- package/dist/cli/lib/hash.js +63 -0
- package/dist/cli/lib/migrations.d.ts +6 -0
- package/dist/cli/lib/migrations.js +17 -0
- package/dist/client/index.d.ts +13 -0
- package/dist/client/index.js +34 -0
- package/dist/core/nomba_api/banks.d.ts +14 -0
- package/dist/core/nomba_api/banks.js +0 -0
- package/dist/core/nomba_api/charge-tokenized-card.d.ts +33 -0
- package/dist/core/nomba_api/charge-tokenized-card.js +0 -0
- package/dist/core/nomba_api/checkout.d.ts +44 -0
- package/dist/core/nomba_api/checkout.js +0 -0
- package/dist/core/nomba_api/get_checkout.d.ts +57 -0
- package/dist/core/nomba_api/get_checkout.js +0 -0
- package/dist/core/nomba_api/index.d.ts +313 -0
- package/dist/core/nomba_api/index.js +179 -0
- package/dist/core/nomba_api/lib/utils.d.ts +235 -0
- package/dist/core/nomba_api/lib/utils.js +313 -0
- package/dist/core/nomba_api/list-tokenized-cards.d.ts +24 -0
- package/dist/core/nomba_api/list-tokenized-cards.js +0 -0
- package/dist/core/nomba_api/token-manager/index.d.ts +51 -0
- package/dist/core/nomba_api/token-manager/index.js +109 -0
- package/dist/core/pg_db/index.d.ts +108 -0
- package/dist/core/pg_db/index.js +76 -0
- package/dist/core/pg_db/migrations/20260703085901_wealthy_blacklash/migration.sql +120 -0
- package/dist/core/pg_db/migrations/20260703085901_wealthy_blacklash/snapshot.json +1616 -0
- package/dist/core/pg_db/relations.d.ts +46 -0
- package/dist/core/pg_db/relations.js +83 -0
- package/dist/core/pg_db/schema.d.ts +1138 -0
- package/dist/core/pg_db/schema.js +124 -0
- package/dist/endpoints/customers/api.js +51 -0
- package/dist/endpoints/entitlements/api.js +42 -0
- package/dist/endpoints/routes.d.ts +15 -0
- package/dist/endpoints/routes.js +15 -0
- package/dist/endpoints/subscriptions/api.js +263 -0
- package/dist/endpoints/subscriptions/utils.js +105 -0
- package/dist/endpoints/webhooks/invoice/api.js +28 -0
- package/dist/endpoints/webhooks/nomba/api.js +76 -0
- package/dist/endpoints/webhooks/nomba/utils.js +36 -0
- package/dist/index.d.ts +204 -0
- package/dist/index.js +175 -0
- package/dist/lib/utils.d.ts +21 -0
- package/dist/lib/utils.js +41 -0
- package/dist/node_modules/.pnpm/@better-fetch_fetch@1.3.1/node_modules/@better-fetch/fetch/dist/index.js +475 -0
- package/dist/package.js +4 -0
- package/dist/queue/backends/pglite/backend.d.ts +43 -0
- package/dist/queue/backends/pglite/backend.js +33 -0
- package/dist/queue/backends/pglite/index.d.ts +4 -0
- package/dist/queue/backends/pglite/index.js +4 -0
- package/dist/queue/backends/pglite/migrations/schema.d.ts +4 -0
- package/dist/queue/backends/pglite/migrations/schema.js +37 -0
- package/dist/queue/backends/pglite/notification-channel.d.ts +17 -0
- package/dist/queue/backends/pglite/notification-channel.js +61 -0
- package/dist/queue/backends/pglite/repository.d.ts +38 -0
- package/dist/queue/backends/pglite/repository.js +299 -0
- package/dist/queue/backends/redis/index.d.ts +7 -0
- package/dist/queue/backends/redis/index.js +1 -0
- package/dist/queue/client/index.d.ts +12 -0
- package/dist/queue/client/index.js +31 -0
- package/dist/queue/endpoints/api.d.ts +53 -0
- package/dist/queue/endpoints/api.js +45 -0
- package/dist/queue/endpoints/routes.d.ts +32 -0
- package/dist/queue/endpoints/routes.js +5 -0
- package/dist/queue/init.d.ts +27 -0
- package/dist/queue/init.js +31 -0
- package/dist/queue/lib/billing.d.ts +25 -0
- package/dist/queue/lib/billing.js +87 -0
- package/dist/queue/lib/utils.d.ts +30 -0
- package/dist/queue/lib/utils.js +35 -0
- package/package.json +71 -0
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
//#region ../node_modules/.pnpm/@better-fetch+fetch@1.3.1/node_modules/@better-fetch/fetch/dist/index.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
4
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
5
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
configurable: true,
|
|
11
|
+
writable: true,
|
|
12
|
+
value
|
|
13
|
+
}) : obj[key] = value;
|
|
14
|
+
var __spreadValues = (a, b) => {
|
|
15
|
+
for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]);
|
|
16
|
+
if (__getOwnPropSymbols) {
|
|
17
|
+
for (var prop of __getOwnPropSymbols(b)) if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]);
|
|
18
|
+
}
|
|
19
|
+
return a;
|
|
20
|
+
};
|
|
21
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
22
|
+
var BetterFetchError = class extends Error {
|
|
23
|
+
constructor(status, statusText, error) {
|
|
24
|
+
super(statusText || status.toString(), { cause: error });
|
|
25
|
+
this.status = status;
|
|
26
|
+
this.statusText = statusText;
|
|
27
|
+
this.error = error;
|
|
28
|
+
Error.captureStackTrace(this, this.constructor);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
var initializePlugins = async (url, options) => {
|
|
32
|
+
var _a, _b, _c, _d, _e, _f;
|
|
33
|
+
let opts = options || {};
|
|
34
|
+
const hooks = {
|
|
35
|
+
onRequest: [options == null ? void 0 : options.onRequest],
|
|
36
|
+
onResponse: [options == null ? void 0 : options.onResponse],
|
|
37
|
+
onSuccess: [options == null ? void 0 : options.onSuccess],
|
|
38
|
+
onError: [options == null ? void 0 : options.onError],
|
|
39
|
+
onRetry: [options == null ? void 0 : options.onRetry]
|
|
40
|
+
};
|
|
41
|
+
if (!options || !(options == null ? void 0 : options.plugins)) return {
|
|
42
|
+
url,
|
|
43
|
+
options: opts,
|
|
44
|
+
hooks
|
|
45
|
+
};
|
|
46
|
+
for (const plugin of (options == null ? void 0 : options.plugins) || []) {
|
|
47
|
+
if (plugin.init) {
|
|
48
|
+
const pluginRes = await ((_a = plugin.init) == null ? void 0 : _a.call(plugin, url.toString(), options));
|
|
49
|
+
opts = pluginRes.options || opts;
|
|
50
|
+
url = pluginRes.url;
|
|
51
|
+
}
|
|
52
|
+
hooks.onRequest.push((_b = plugin.hooks) == null ? void 0 : _b.onRequest);
|
|
53
|
+
hooks.onResponse.push((_c = plugin.hooks) == null ? void 0 : _c.onResponse);
|
|
54
|
+
hooks.onSuccess.push((_d = plugin.hooks) == null ? void 0 : _d.onSuccess);
|
|
55
|
+
hooks.onError.push((_e = plugin.hooks) == null ? void 0 : _e.onError);
|
|
56
|
+
hooks.onRetry.push((_f = plugin.hooks) == null ? void 0 : _f.onRetry);
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
url,
|
|
60
|
+
options: opts,
|
|
61
|
+
hooks
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
var LinearRetryStrategy = class {
|
|
65
|
+
constructor(options) {
|
|
66
|
+
this.options = options;
|
|
67
|
+
}
|
|
68
|
+
shouldAttemptRetry(attempt, response) {
|
|
69
|
+
if (this.options.shouldRetry) return Promise.resolve(attempt < this.options.attempts && this.options.shouldRetry(response));
|
|
70
|
+
return Promise.resolve(attempt < this.options.attempts);
|
|
71
|
+
}
|
|
72
|
+
getDelay() {
|
|
73
|
+
return this.options.delay;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
var ExponentialRetryStrategy = class {
|
|
77
|
+
constructor(options) {
|
|
78
|
+
this.options = options;
|
|
79
|
+
}
|
|
80
|
+
shouldAttemptRetry(attempt, response) {
|
|
81
|
+
if (this.options.shouldRetry) return Promise.resolve(attempt < this.options.attempts && this.options.shouldRetry(response));
|
|
82
|
+
return Promise.resolve(attempt < this.options.attempts);
|
|
83
|
+
}
|
|
84
|
+
getDelay(attempt) {
|
|
85
|
+
return Math.min(this.options.maxDelay, this.options.baseDelay * 2 ** attempt);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
function createRetryStrategy(options) {
|
|
89
|
+
if (typeof options === "number") return new LinearRetryStrategy({
|
|
90
|
+
type: "linear",
|
|
91
|
+
attempts: options,
|
|
92
|
+
delay: 1e3
|
|
93
|
+
});
|
|
94
|
+
switch (options.type) {
|
|
95
|
+
case "linear": return new LinearRetryStrategy(options);
|
|
96
|
+
case "exponential": return new ExponentialRetryStrategy(options);
|
|
97
|
+
default: throw new Error("Invalid retry strategy");
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
var getAuthHeader = async (options) => {
|
|
101
|
+
const headers = {};
|
|
102
|
+
const getValue = async (value) => typeof value === "function" ? await value() : value;
|
|
103
|
+
if (options == null ? void 0 : options.auth) {
|
|
104
|
+
if (options.auth.type === "Bearer") {
|
|
105
|
+
const token = await getValue(options.auth.token);
|
|
106
|
+
if (!token) return headers;
|
|
107
|
+
headers["authorization"] = `Bearer ${token}`;
|
|
108
|
+
} else if (options.auth.type === "Basic") {
|
|
109
|
+
const [username, password] = await Promise.all([getValue(options.auth.username), getValue(options.auth.password)]);
|
|
110
|
+
if (!username || !password) return headers;
|
|
111
|
+
headers["authorization"] = `Basic ${btoa(`${username}:${password}`)}`;
|
|
112
|
+
} else if (options.auth.type === "Custom") {
|
|
113
|
+
const [prefix, value] = await Promise.all([getValue(options.auth.prefix), getValue(options.auth.value)]);
|
|
114
|
+
if (!value) return headers;
|
|
115
|
+
headers["authorization"] = `${prefix != null ? prefix : ""} ${value}`;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return headers;
|
|
119
|
+
};
|
|
120
|
+
var JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;
|
|
121
|
+
function detectResponseType(request) {
|
|
122
|
+
const _contentType = request.headers.get("content-type");
|
|
123
|
+
const textTypes = /* @__PURE__ */ new Set([
|
|
124
|
+
"image/svg",
|
|
125
|
+
"application/xml",
|
|
126
|
+
"application/xhtml",
|
|
127
|
+
"application/html"
|
|
128
|
+
]);
|
|
129
|
+
if (!_contentType) return "json";
|
|
130
|
+
const contentType = _contentType.split(";").shift() || "";
|
|
131
|
+
if (JSON_RE.test(contentType)) return "json";
|
|
132
|
+
if (textTypes.has(contentType) || contentType.startsWith("text/")) return "text";
|
|
133
|
+
return "blob";
|
|
134
|
+
}
|
|
135
|
+
function isJSONParsable(value) {
|
|
136
|
+
try {
|
|
137
|
+
JSON.parse(value);
|
|
138
|
+
return true;
|
|
139
|
+
} catch (error) {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function isJSONSerializable(value) {
|
|
144
|
+
if (value === void 0) return false;
|
|
145
|
+
const t = typeof value;
|
|
146
|
+
if (t === "string" || t === "number" || t === "boolean" || t === null) return true;
|
|
147
|
+
if (t !== "object") return false;
|
|
148
|
+
if (Array.isArray(value)) return true;
|
|
149
|
+
if (value.buffer) return false;
|
|
150
|
+
return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function";
|
|
151
|
+
}
|
|
152
|
+
function jsonParse(text) {
|
|
153
|
+
try {
|
|
154
|
+
return JSON.parse(text);
|
|
155
|
+
} catch (error) {
|
|
156
|
+
return text;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function isFunction(value) {
|
|
160
|
+
return typeof value === "function";
|
|
161
|
+
}
|
|
162
|
+
function getFetch(options) {
|
|
163
|
+
if (options == null ? void 0 : options.customFetchImpl) return options.customFetchImpl;
|
|
164
|
+
if (typeof globalThis !== "undefined" && isFunction(globalThis.fetch)) return globalThis.fetch;
|
|
165
|
+
if (typeof window !== "undefined" && isFunction(window.fetch)) return window.fetch;
|
|
166
|
+
throw new Error("No fetch implementation found");
|
|
167
|
+
}
|
|
168
|
+
function mergeHeaders(...sources) {
|
|
169
|
+
const merged = {};
|
|
170
|
+
for (const source of sources) {
|
|
171
|
+
if (!source) continue;
|
|
172
|
+
if (source instanceof Headers) source.forEach((value, key) => {
|
|
173
|
+
merged[key] = value;
|
|
174
|
+
});
|
|
175
|
+
else {
|
|
176
|
+
const entries = Array.isArray(source) ? source : Object.entries(source);
|
|
177
|
+
for (const [key, value] of entries) if (value !== null && value !== void 0) merged[key] = value;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return merged;
|
|
181
|
+
}
|
|
182
|
+
async function getHeaders(opts) {
|
|
183
|
+
const headers = new Headers(mergeHeaders(opts == null ? void 0 : opts.headers, await getAuthHeader(opts)));
|
|
184
|
+
if (!headers.has("content-type")) {
|
|
185
|
+
const contentType = detectContentType(opts == null ? void 0 : opts.body);
|
|
186
|
+
if (contentType) headers.set("content-type", contentType);
|
|
187
|
+
}
|
|
188
|
+
return headers;
|
|
189
|
+
}
|
|
190
|
+
function detectContentType(body) {
|
|
191
|
+
if (isJSONSerializable(body)) return "application/json";
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
function getMediaType(headers) {
|
|
195
|
+
const contentType = headers.get("content-type");
|
|
196
|
+
return contentType ? contentType.split(";")[0].trim().toLowerCase() : null;
|
|
197
|
+
}
|
|
198
|
+
function getBody(options, headers) {
|
|
199
|
+
const { body } = options;
|
|
200
|
+
if (!body) return null;
|
|
201
|
+
if (!isJSONSerializable(body)) return body;
|
|
202
|
+
if (typeof body === "string") return body;
|
|
203
|
+
if (getMediaType(headers) === "application/x-www-form-urlencoded") return new URLSearchParams(body).toString();
|
|
204
|
+
return JSON.stringify(body);
|
|
205
|
+
}
|
|
206
|
+
function getMethod(url, options) {
|
|
207
|
+
var _a;
|
|
208
|
+
if (options == null ? void 0 : options.method) return options.method.toUpperCase();
|
|
209
|
+
if (url.startsWith("@")) {
|
|
210
|
+
const pMethod = (_a = url.split("@")[1]) == null ? void 0 : _a.split("/")[0];
|
|
211
|
+
if (!methods.includes(pMethod)) return (options == null ? void 0 : options.body) ? "POST" : "GET";
|
|
212
|
+
return pMethod.toUpperCase();
|
|
213
|
+
}
|
|
214
|
+
return (options == null ? void 0 : options.body) ? "POST" : "GET";
|
|
215
|
+
}
|
|
216
|
+
function getTimeout(options, controller) {
|
|
217
|
+
let abortTimeout;
|
|
218
|
+
if (!(options == null ? void 0 : options.signal) && (options == null ? void 0 : options.timeout)) abortTimeout = setTimeout(() => controller == null ? void 0 : controller.abort(), options == null ? void 0 : options.timeout);
|
|
219
|
+
return {
|
|
220
|
+
abortTimeout,
|
|
221
|
+
clearTimeout: () => {
|
|
222
|
+
if (abortTimeout) clearTimeout(abortTimeout);
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
var ValidationError = class _ValidationError extends Error {
|
|
227
|
+
constructor(issues, message) {
|
|
228
|
+
super(message || JSON.stringify(issues, null, 2));
|
|
229
|
+
this.issues = issues;
|
|
230
|
+
Object.setPrototypeOf(this, _ValidationError.prototype);
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
async function parseStandardSchema(schema, input) {
|
|
234
|
+
const result = await schema["~standard"].validate(input);
|
|
235
|
+
if (result.issues) throw new ValidationError(result.issues);
|
|
236
|
+
return result.value;
|
|
237
|
+
}
|
|
238
|
+
var methods = [
|
|
239
|
+
"get",
|
|
240
|
+
"post",
|
|
241
|
+
"put",
|
|
242
|
+
"patch",
|
|
243
|
+
"delete"
|
|
244
|
+
];
|
|
245
|
+
var applySchemaPlugin = (config) => ({
|
|
246
|
+
id: "apply-schema",
|
|
247
|
+
name: "Apply Schema",
|
|
248
|
+
version: "1.0.0",
|
|
249
|
+
async init(url, options) {
|
|
250
|
+
var _a, _b, _c, _d;
|
|
251
|
+
const schema = ((_b = (_a = config.plugins) == null ? void 0 : _a.find((plugin) => {
|
|
252
|
+
var _a2;
|
|
253
|
+
return ((_a2 = plugin.schema) == null ? void 0 : _a2.config) ? url.startsWith(plugin.schema.config.baseURL || "") || url.startsWith(plugin.schema.config.prefix || "") : false;
|
|
254
|
+
})) == null ? void 0 : _b.schema) || config.schema;
|
|
255
|
+
if (schema) {
|
|
256
|
+
let urlKey = url;
|
|
257
|
+
if ((_c = schema.config) == null ? void 0 : _c.prefix) {
|
|
258
|
+
if (urlKey.startsWith(schema.config.prefix)) {
|
|
259
|
+
urlKey = urlKey.replace(schema.config.prefix, "");
|
|
260
|
+
if (schema.config.baseURL) url = url.replace(schema.config.prefix, schema.config.baseURL);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if ((_d = schema.config) == null ? void 0 : _d.baseURL) {
|
|
264
|
+
if (urlKey.startsWith(schema.config.baseURL)) urlKey = urlKey.replace(schema.config.baseURL, "");
|
|
265
|
+
}
|
|
266
|
+
if (urlKey.startsWith("/") && urlKey.charAt(1) === "@") urlKey = urlKey.substring(1);
|
|
267
|
+
const keySchema = schema.schema[urlKey];
|
|
268
|
+
if (keySchema) {
|
|
269
|
+
let validatedHeaders = options == null ? void 0 : options.headers;
|
|
270
|
+
if (keySchema.headers && !(options == null ? void 0 : options.disableValidation)) {
|
|
271
|
+
const normalizedHeaders = {};
|
|
272
|
+
if (options == null ? void 0 : options.headers) {
|
|
273
|
+
if (options.headers instanceof Headers) options.headers.forEach((value, key) => {
|
|
274
|
+
normalizedHeaders[key.toLowerCase()] = value;
|
|
275
|
+
});
|
|
276
|
+
else if (typeof options.headers === "object") {
|
|
277
|
+
for (const [key, value] of Object.entries(options.headers)) if (value !== null && value !== void 0) normalizedHeaders[key.toLowerCase()] = value;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
const validated = await parseStandardSchema(keySchema.headers, normalizedHeaders);
|
|
281
|
+
const finalHeaders = {};
|
|
282
|
+
for (const [key, value] of Object.entries(validated)) finalHeaders[key.toLowerCase()] = value;
|
|
283
|
+
validatedHeaders = finalHeaders;
|
|
284
|
+
}
|
|
285
|
+
let opts = __spreadProps(__spreadValues({}, options), {
|
|
286
|
+
method: keySchema.method,
|
|
287
|
+
output: keySchema.output,
|
|
288
|
+
headers: validatedHeaders
|
|
289
|
+
});
|
|
290
|
+
if (!(options == null ? void 0 : options.disableValidation)) opts = __spreadProps(__spreadValues({}, opts), {
|
|
291
|
+
body: keySchema.input ? await parseStandardSchema(keySchema.input, options == null ? void 0 : options.body) : options == null ? void 0 : options.body,
|
|
292
|
+
params: keySchema.params ? await parseStandardSchema(keySchema.params, options == null ? void 0 : options.params) : options == null ? void 0 : options.params,
|
|
293
|
+
query: keySchema.query ? await parseStandardSchema(keySchema.query, options == null ? void 0 : options.query) : options == null ? void 0 : options.query
|
|
294
|
+
});
|
|
295
|
+
return {
|
|
296
|
+
url,
|
|
297
|
+
options: opts
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
url,
|
|
303
|
+
options
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
var createFetch = (config) => {
|
|
308
|
+
async function $fetch(url, options) {
|
|
309
|
+
const opts = __spreadProps(__spreadValues(__spreadValues({}, config), options), {
|
|
310
|
+
headers: mergeHeaders(config == null ? void 0 : config.headers, options == null ? void 0 : options.headers),
|
|
311
|
+
plugins: [
|
|
312
|
+
...(config == null ? void 0 : config.plugins) || [],
|
|
313
|
+
applySchemaPlugin(config || {}),
|
|
314
|
+
...(options == null ? void 0 : options.plugins) || []
|
|
315
|
+
]
|
|
316
|
+
});
|
|
317
|
+
if (config == null ? void 0 : config.catchAllError) try {
|
|
318
|
+
return await betterFetch(url, opts);
|
|
319
|
+
} catch (error) {
|
|
320
|
+
return {
|
|
321
|
+
data: null,
|
|
322
|
+
error: {
|
|
323
|
+
status: 500,
|
|
324
|
+
statusText: "Fetch Error",
|
|
325
|
+
message: "Fetch related error. Captured by catchAllError option. See error property for more details.",
|
|
326
|
+
error
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
return await betterFetch(url, opts);
|
|
331
|
+
}
|
|
332
|
+
return $fetch;
|
|
333
|
+
};
|
|
334
|
+
var isReservedPathSegment = (value) => value === "." || value === "..";
|
|
335
|
+
function encodePathSegment(segment, pathParams) {
|
|
336
|
+
let pathSegment = segment;
|
|
337
|
+
for (const [key, value] of pathParams) pathSegment = pathSegment.replace(key, value);
|
|
338
|
+
if (isReservedPathSegment(pathSegment)) throw new TypeError("Path parameters cannot be reserved path segments");
|
|
339
|
+
return encodeURIComponent(pathSegment);
|
|
340
|
+
}
|
|
341
|
+
function getURL2(url, option) {
|
|
342
|
+
const { baseURL, params, query } = option || {
|
|
343
|
+
query: {},
|
|
344
|
+
params: {},
|
|
345
|
+
baseURL: ""
|
|
346
|
+
};
|
|
347
|
+
let basePath = url.startsWith("http") ? url.split("/").slice(0, 3).join("/") : baseURL || "";
|
|
348
|
+
if (url.startsWith("@")) {
|
|
349
|
+
const m = url.toString().split("@")[1].split("/")[0];
|
|
350
|
+
if (methods.includes(m)) url = url.replace(`@${m}/`, "/");
|
|
351
|
+
}
|
|
352
|
+
if (!basePath.endsWith("/")) basePath += "/";
|
|
353
|
+
let [path, urlQuery] = url.replace(basePath, "").split("?");
|
|
354
|
+
const queryParams = new URLSearchParams(urlQuery);
|
|
355
|
+
for (const [key, value] of Object.entries(query || {})) {
|
|
356
|
+
if (value == null) continue;
|
|
357
|
+
let serializedValue;
|
|
358
|
+
if (typeof value === "string") serializedValue = value;
|
|
359
|
+
else if (Array.isArray(value)) {
|
|
360
|
+
for (const val of value) queryParams.append(key, val);
|
|
361
|
+
continue;
|
|
362
|
+
} else serializedValue = JSON.stringify(value);
|
|
363
|
+
queryParams.set(key, serializedValue);
|
|
364
|
+
}
|
|
365
|
+
const pathParams = /* @__PURE__ */ new Map();
|
|
366
|
+
if (params) if (Array.isArray(params)) {
|
|
367
|
+
const paramPaths = path.split("/").filter((p) => p.startsWith(":"));
|
|
368
|
+
for (const [index, key] of paramPaths.entries()) {
|
|
369
|
+
const value = params[index];
|
|
370
|
+
pathParams.set(key, String(value));
|
|
371
|
+
}
|
|
372
|
+
} else for (const [key, value] of Object.entries(params)) pathParams.set(`:${key}`, String(value));
|
|
373
|
+
path = path.split("/").map((segment) => encodePathSegment(segment, pathParams)).join("/");
|
|
374
|
+
path = path.replace(/^\/+/, "");
|
|
375
|
+
let queryParamString = queryParams.toString();
|
|
376
|
+
queryParamString = queryParamString.length > 0 ? `?${queryParamString}`.replace(/\+/g, "%20") : "";
|
|
377
|
+
if (!basePath.startsWith("http")) return `${basePath}${path}${queryParamString}`;
|
|
378
|
+
return new URL(`${path}${queryParamString}`, basePath);
|
|
379
|
+
}
|
|
380
|
+
var betterFetch = async (url, options) => {
|
|
381
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
382
|
+
const { hooks, url: __url, options: opts } = await initializePlugins(url, options);
|
|
383
|
+
const fetch = getFetch(opts);
|
|
384
|
+
const controller = new AbortController();
|
|
385
|
+
const signal = (_a = opts.signal) != null ? _a : controller.signal;
|
|
386
|
+
const _url = getURL2(__url, opts);
|
|
387
|
+
const headers = await getHeaders(opts);
|
|
388
|
+
const body = getBody(opts, headers);
|
|
389
|
+
const method = getMethod(__url, opts);
|
|
390
|
+
const context = __spreadProps(__spreadValues({}, opts), {
|
|
391
|
+
url: _url,
|
|
392
|
+
headers,
|
|
393
|
+
body,
|
|
394
|
+
method,
|
|
395
|
+
signal
|
|
396
|
+
});
|
|
397
|
+
for (const onRequest of hooks.onRequest) if (onRequest) {
|
|
398
|
+
const res = await onRequest(context);
|
|
399
|
+
if (typeof res === "object" && res !== null) Object.assign(context, res);
|
|
400
|
+
}
|
|
401
|
+
if ("pipeTo" in context && typeof context.pipeTo === "function" || typeof ((_b = options == null ? void 0 : options.body) == null ? void 0 : _b.pipe) === "function") {
|
|
402
|
+
if (!("duplex" in context)) context.duplex = "half";
|
|
403
|
+
}
|
|
404
|
+
const { clearTimeout: clearTimeout2 } = getTimeout(opts, controller);
|
|
405
|
+
let response = await fetch(context.url, context);
|
|
406
|
+
clearTimeout2();
|
|
407
|
+
const responseContext = {
|
|
408
|
+
response,
|
|
409
|
+
request: context
|
|
410
|
+
};
|
|
411
|
+
for (const onResponse of hooks.onResponse) if (onResponse) {
|
|
412
|
+
const r = await onResponse(__spreadProps(__spreadValues({}, responseContext), { response: ((_c = options == null ? void 0 : options.hookOptions) == null ? void 0 : _c.cloneResponse) ? response.clone() : response }));
|
|
413
|
+
if (r instanceof Response) response = r;
|
|
414
|
+
else if (typeof r === "object" && r !== null) response = r.response;
|
|
415
|
+
}
|
|
416
|
+
if (response.ok) {
|
|
417
|
+
if (!(context.method !== "HEAD")) return {
|
|
418
|
+
data: "",
|
|
419
|
+
error: null
|
|
420
|
+
};
|
|
421
|
+
const responseType = detectResponseType(response);
|
|
422
|
+
const successContext = {
|
|
423
|
+
data: null,
|
|
424
|
+
response,
|
|
425
|
+
request: context
|
|
426
|
+
};
|
|
427
|
+
if (responseType === "json" || responseType === "text") {
|
|
428
|
+
const text = await response.text();
|
|
429
|
+
successContext.data = await ((_d = context.jsonParser) != null ? _d : jsonParse)(text);
|
|
430
|
+
} else successContext.data = await response[responseType]();
|
|
431
|
+
if (context == null ? void 0 : context.output) {
|
|
432
|
+
if (context.output && !context.disableValidation) successContext.data = await parseStandardSchema(context.output, successContext.data);
|
|
433
|
+
}
|
|
434
|
+
for (const onSuccess of hooks.onSuccess) if (onSuccess) await onSuccess(__spreadProps(__spreadValues({}, successContext), { response: ((_e = options == null ? void 0 : options.hookOptions) == null ? void 0 : _e.cloneResponse) ? response.clone() : response }));
|
|
435
|
+
if (options == null ? void 0 : options.throw) return successContext.data;
|
|
436
|
+
return {
|
|
437
|
+
data: successContext.data,
|
|
438
|
+
error: null
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
const parser = (_f = options == null ? void 0 : options.jsonParser) != null ? _f : jsonParse;
|
|
442
|
+
const responseText = await response.text();
|
|
443
|
+
const isJSONResponse = isJSONParsable(responseText);
|
|
444
|
+
const errorObject = isJSONResponse ? await parser(responseText) : null;
|
|
445
|
+
const errorContext = {
|
|
446
|
+
response,
|
|
447
|
+
responseText,
|
|
448
|
+
request: context,
|
|
449
|
+
error: __spreadProps(__spreadValues({}, errorObject), {
|
|
450
|
+
status: response.status,
|
|
451
|
+
statusText: response.statusText
|
|
452
|
+
})
|
|
453
|
+
};
|
|
454
|
+
for (const onError of hooks.onError) if (onError) await onError(__spreadProps(__spreadValues({}, errorContext), { response: ((_g = options == null ? void 0 : options.hookOptions) == null ? void 0 : _g.cloneResponse) ? response.clone() : response }));
|
|
455
|
+
if (options == null ? void 0 : options.retry) {
|
|
456
|
+
const retryStrategy = createRetryStrategy(options.retry);
|
|
457
|
+
const _retryAttempt = (_h = options.retryAttempt) != null ? _h : 0;
|
|
458
|
+
if (await retryStrategy.shouldAttemptRetry(_retryAttempt, response)) {
|
|
459
|
+
for (const onRetry of hooks.onRetry) if (onRetry) await onRetry(responseContext);
|
|
460
|
+
const delay = retryStrategy.getDelay(_retryAttempt);
|
|
461
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
462
|
+
return await betterFetch(url, __spreadProps(__spreadValues({}, options), { retryAttempt: _retryAttempt + 1 }));
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (options == null ? void 0 : options.throw) throw new BetterFetchError(response.status, response.statusText, isJSONResponse ? errorObject : responseText);
|
|
466
|
+
return {
|
|
467
|
+
data: null,
|
|
468
|
+
error: __spreadProps(__spreadValues({}, errorObject), {
|
|
469
|
+
status: response.status,
|
|
470
|
+
statusText: response.statusText
|
|
471
|
+
})
|
|
472
|
+
};
|
|
473
|
+
};
|
|
474
|
+
//#endregion
|
|
475
|
+
export { BetterFetchError, ValidationError, applySchemaPlugin, betterFetch, createFetch, createRetryStrategy, detectContentType, detectResponseType, getBody, getFetch, getHeaders, getMethod, getTimeout, initializePlugins, isFunction, isJSONParsable, isJSONSerializable, jsonParse, mergeHeaders, methods, parseStandardSchema };
|
package/dist/package.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { PgliteRepository, PgliteRepositoryOptions } from "./repository.js";
|
|
2
|
+
import { PgliteNotificationChannel } from "./notification-channel.js";
|
|
3
|
+
import { AgendaBackend } from "agenda";
|
|
4
|
+
import { PGlite } from "@electric-sql/pglite";
|
|
5
|
+
|
|
6
|
+
//#region queue/backends/pglite/backend.d.ts
|
|
7
|
+
interface PGliteBackendOptions extends PgliteRepositoryOptions {
|
|
8
|
+
/** An existing PGlite instance. If omitted, one is created from `dataDir`. */
|
|
9
|
+
db?: PGlite;
|
|
10
|
+
/**
|
|
11
|
+
* Use 'memory://' for an ephemeral in-memory database, a filesystem
|
|
12
|
+
* path (e.g. './data/agenda') to persist to disk in Node.
|
|
13
|
+
*
|
|
14
|
+
* @default
|
|
15
|
+
* "memory://agenda"
|
|
16
|
+
*/
|
|
17
|
+
dataDir?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Provide real-time notifications via PGlite's (single-process) LISTEN/NOTIFY
|
|
20
|
+
* instead of falling back to polling.
|
|
21
|
+
*
|
|
22
|
+
* @default true
|
|
23
|
+
*/
|
|
24
|
+
notifications?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Agenda v6 backend backed by PGlite (embedded, WASM Postgres).
|
|
28
|
+
*
|
|
29
|
+
* For a multi-process cluster, use the
|
|
30
|
+
* official `@agendajs/postgres-backend` against a real Postgres server.
|
|
31
|
+
*/
|
|
32
|
+
declare class PGliteBackend implements AgendaBackend {
|
|
33
|
+
readonly name = "PGlite";
|
|
34
|
+
readonly repository: PgliteRepository;
|
|
35
|
+
readonly notificationChannel?: PgliteNotificationChannel;
|
|
36
|
+
readonly ownsConnection: boolean;
|
|
37
|
+
private readonly db;
|
|
38
|
+
constructor(options?: PGliteBackendOptions);
|
|
39
|
+
connect(): Promise<void>;
|
|
40
|
+
disconnect(): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { PGliteBackend, PGliteBackendOptions };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { PgliteRepository } from "./repository.js";
|
|
2
|
+
import { PgliteNotificationChannel } from "./notification-channel.js";
|
|
3
|
+
import { PGlite } from "@electric-sql/pglite";
|
|
4
|
+
//#region queue/backends/pglite/backend.ts
|
|
5
|
+
/**
|
|
6
|
+
* Agenda v6 backend backed by PGlite (embedded, WASM Postgres).
|
|
7
|
+
*
|
|
8
|
+
* For a multi-process cluster, use the
|
|
9
|
+
* official `@agendajs/postgres-backend` against a real Postgres server.
|
|
10
|
+
*/
|
|
11
|
+
var PGliteBackend = class {
|
|
12
|
+
name = "PGlite";
|
|
13
|
+
repository;
|
|
14
|
+
notificationChannel;
|
|
15
|
+
ownsConnection;
|
|
16
|
+
db;
|
|
17
|
+
constructor(options = {}) {
|
|
18
|
+
this.ownsConnection = !options.db;
|
|
19
|
+
this.db = options.db ?? new PGlite(options.dataDir ?? "memory://agenda");
|
|
20
|
+
this.repository = new PgliteRepository(this.db, options);
|
|
21
|
+
if (options.notifications !== false) this.notificationChannel = new PgliteNotificationChannel(this.db);
|
|
22
|
+
}
|
|
23
|
+
async connect() {
|
|
24
|
+
await this.repository.connect();
|
|
25
|
+
if (this.notificationChannel) await this.notificationChannel.connect();
|
|
26
|
+
}
|
|
27
|
+
async disconnect() {
|
|
28
|
+
if (this.notificationChannel) await this.notificationChannel.disconnect();
|
|
29
|
+
if (this.ownsConnection) await this.db.close();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
|
33
|
+
export { PGliteBackend };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { PgliteRepository, PgliteRepositoryOptions } from "./repository.js";
|
|
2
|
+
import { PgliteNotificationChannel } from "./notification-channel.js";
|
|
3
|
+
import { PGliteBackend, PGliteBackendOptions } from "./backend.js";
|
|
4
|
+
export { PGliteBackend, type PGliteBackendOptions as PgliteBackendOptions, PgliteNotificationChannel, PgliteRepository, type PgliteRepositoryOptions };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region queue/backends/pglite/migrations/schema.ts
|
|
2
|
+
function migratePGlite(table) {
|
|
3
|
+
return `
|
|
4
|
+
CREATE TABLE IF NOT EXISTS "${table}" (
|
|
5
|
+
id TEXT PRIMARY KEY DEFAULT (gen_random_uuid())::text,
|
|
6
|
+
name TEXT NOT NULL,
|
|
7
|
+
type TEXT,
|
|
8
|
+
priority INTEGER NOT NULL DEFAULT 0,
|
|
9
|
+
next_run_at TIMESTAMPTZ,
|
|
10
|
+
last_modified_by TEXT,
|
|
11
|
+
locked_at TIMESTAMPTZ,
|
|
12
|
+
last_finished_at TIMESTAMPTZ,
|
|
13
|
+
last_run_at TIMESTAMPTZ,
|
|
14
|
+
repeat_interval TEXT,
|
|
15
|
+
repeat_timezone TEXT,
|
|
16
|
+
repeat_at TEXT,
|
|
17
|
+
data JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
18
|
+
is_unique JSONB,
|
|
19
|
+
unique_opts JSONB,
|
|
20
|
+
last_error JSONB,
|
|
21
|
+
fail_reason TEXT,
|
|
22
|
+
fail_count INTEGER NOT NULL DEFAULT 0,
|
|
23
|
+
failed_at TIMESTAMPTZ,
|
|
24
|
+
disabled BOOLEAN NOT NULL DEFAULT FALSE,
|
|
25
|
+
progress DOUBLE PRECISION,
|
|
26
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
27
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
CREATE INDEX IF NOT EXISTS "${table}_name_idx" ON "${table}" (name);
|
|
31
|
+
CREATE INDEX IF NOT EXISTS "${table}_next_run_at_idx" ON "${table}" (next_run_at);
|
|
32
|
+
CREATE INDEX IF NOT EXISTS "${table}_locked_at_idx" ON "${table}" (locked_at);
|
|
33
|
+
CREATE INDEX IF NOT EXISTS "${table}_data_idx" ON "${table}" USING GIN (data);
|
|
34
|
+
`;
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { migratePGlite };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BaseNotificationChannel, JobNotification } from "agenda";
|
|
2
|
+
import { PGlite } from "@electric-sql/pglite";
|
|
3
|
+
|
|
4
|
+
//#region queue/backends/pglite/notification-channel.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Real-time notifications for the PGlite backend using NOTIFY/LISTEN.
|
|
7
|
+
*/
|
|
8
|
+
declare class PgliteNotificationChannel extends BaseNotificationChannel {
|
|
9
|
+
private readonly db;
|
|
10
|
+
private unlisten;
|
|
11
|
+
constructor(db: PGlite);
|
|
12
|
+
connect(): Promise<void>;
|
|
13
|
+
disconnect(): Promise<void>;
|
|
14
|
+
publish(notification: JobNotification): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { PgliteNotificationChannel };
|