tempest-express-sdk 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/README.md +1 -1
- package/dist/{chunk-6KJTKSG5.js → chunk-TIW2KPT2.js} +3 -3
- package/dist/{chunk-6KJTKSG5.js.map → chunk-TIW2KPT2.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 +398 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +281 -119
- package/dist/index.d.ts +281 -119
- package/dist/index.js +396 -77
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { z, looseBoolean, toDict, PasswordUtils } from './chunk-
|
|
2
|
-
export { PasswordUtils, VERSION, baseAppSettingsSchema, baseAppSettingsShape, baseResponseSchema, centsField, corsSettingsShape, databaseSettingsShape, looseBoolean as envBoolean, hexColorField, latitudeField, loadSettings, longitudeField, looseBoolean, nonEmptyStrField, nonNegativeFloatField, nonNegativeIntField, percentField, portField, positiveFloatField, positiveIntField, priceField, ratingField, ratioField, serverSettingsShape, slugField, toDict, z } from './chunk-
|
|
1
|
+
import { z, looseBoolean, toDict, PasswordUtils } from './chunk-TIW2KPT2.js';
|
|
2
|
+
export { PasswordUtils, VERSION, baseAppSettingsSchema, baseAppSettingsShape, baseResponseSchema, centsField, corsSettingsShape, databaseSettingsShape, looseBoolean as envBoolean, hexColorField, latitudeField, loadSettings, longitudeField, looseBoolean, nonEmptyStrField, nonNegativeFloatField, nonNegativeIntField, percentField, portField, positiveFloatField, positiveIntField, priceField, ratingField, ratioField, serverSettingsShape, slugField, toDict, z } from './chunk-TIW2KPT2.js';
|
|
3
3
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
4
4
|
import { Model, column, sql, BaseRepository, RecordNotFound, detectDialect, columnsOf, NodeSqliteDriver, AsyncEngine, or, and } from 'tempest-db-js';
|
|
5
5
|
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';
|
|
@@ -9317,6 +9317,21 @@ var MessagingHub = class {
|
|
|
9317
9317
|
}
|
|
9318
9318
|
};
|
|
9319
9319
|
|
|
9320
|
+
// src/admin/actions.ts
|
|
9321
|
+
function slugify(label) {
|
|
9322
|
+
return label.normalize("NFD").replace(/\p{M}/gu, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "action";
|
|
9323
|
+
}
|
|
9324
|
+
function adminAction(options, handler) {
|
|
9325
|
+
const name = options.name ?? slugify(options.label);
|
|
9326
|
+
if (name === "") throw new Error("adminAction requires a non-empty name or label");
|
|
9327
|
+
return {
|
|
9328
|
+
name,
|
|
9329
|
+
label: options.label,
|
|
9330
|
+
handler,
|
|
9331
|
+
dangerous: options.dangerous ?? false
|
|
9332
|
+
};
|
|
9333
|
+
}
|
|
9334
|
+
|
|
9320
9335
|
// src/admin/columns.ts
|
|
9321
9336
|
function humanizeField(name) {
|
|
9322
9337
|
return name.replace(/[_-]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").trim().split(/\s+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
@@ -9397,6 +9412,9 @@ function filterForColumn(column6) {
|
|
|
9397
9412
|
}
|
|
9398
9413
|
return { kind: "text", options: [] };
|
|
9399
9414
|
}
|
|
9415
|
+
function foreignKeyTable(column6) {
|
|
9416
|
+
return column6.reference?.table ?? null;
|
|
9417
|
+
}
|
|
9400
9418
|
function isSearchableColumn(column6) {
|
|
9401
9419
|
const { kind } = column6.type;
|
|
9402
9420
|
return kind === "varchar" || kind === "text" || kind === "char";
|
|
@@ -9433,6 +9451,7 @@ var AdminModel = class {
|
|
|
9433
9451
|
canEdit;
|
|
9434
9452
|
/** Whether the delete action is exposed. */
|
|
9435
9453
|
canDelete;
|
|
9454
|
+
actions = /* @__PURE__ */ new Map();
|
|
9436
9455
|
slugOverride;
|
|
9437
9456
|
listDisplayOverride;
|
|
9438
9457
|
verboseNameOverride;
|
|
@@ -9457,6 +9476,14 @@ var AdminModel = class {
|
|
|
9457
9476
|
this.canCreate = options.canCreate ?? true;
|
|
9458
9477
|
this.canEdit = options.canEdit ?? true;
|
|
9459
9478
|
this.canDelete = options.canDelete ?? true;
|
|
9479
|
+
for (const action of options.actions ?? []) {
|
|
9480
|
+
if (this.actions.has(action.name)) {
|
|
9481
|
+
throw new Error(
|
|
9482
|
+
`Duplicate admin action name "${action.name}" on ${this.model.tablename}`
|
|
9483
|
+
);
|
|
9484
|
+
}
|
|
9485
|
+
this.actions.set(action.name, action);
|
|
9486
|
+
}
|
|
9460
9487
|
const known = new Set(this.columnNames());
|
|
9461
9488
|
for (const [option, names] of [
|
|
9462
9489
|
["listDisplay", this.listDisplayOverride ?? []],
|
|
@@ -9559,6 +9586,25 @@ var AdminModel = class {
|
|
|
9559
9586
|
const skip = /* @__PURE__ */ new Set([...this.readonlyFields, ...NEVER_EDITABLE]);
|
|
9560
9587
|
return this.columnNames().filter((name) => !skip.has(name));
|
|
9561
9588
|
}
|
|
9589
|
+
/**
|
|
9590
|
+
* Return the registered custom actions, in declaration order.
|
|
9591
|
+
*
|
|
9592
|
+
* @returns The actions passed via `actions` (empty when none). The model
|
|
9593
|
+
* type is erased here, the way {@link AdminSite} erases it when it stores a
|
|
9594
|
+
* configuration — a registry keyed by slug cannot stay generic.
|
|
9595
|
+
*/
|
|
9596
|
+
customActions() {
|
|
9597
|
+
return [...this.actions.values()];
|
|
9598
|
+
}
|
|
9599
|
+
/**
|
|
9600
|
+
* Look a custom action up by name.
|
|
9601
|
+
*
|
|
9602
|
+
* @param name - The action identifier (its submitted form value).
|
|
9603
|
+
* @returns The action, or `null` when nothing matches.
|
|
9604
|
+
*/
|
|
9605
|
+
getAction(name) {
|
|
9606
|
+
return this.actions.get(name) ?? null;
|
|
9607
|
+
}
|
|
9562
9608
|
/**
|
|
9563
9609
|
* Build a repository for this model bound to a session.
|
|
9564
9610
|
*
|
|
@@ -9600,10 +9646,12 @@ function buildFormFields(admin, options = {}) {
|
|
|
9600
9646
|
const columns = adminColumns(admin.model);
|
|
9601
9647
|
const values = options.values ?? {};
|
|
9602
9648
|
const errors = options.errors ?? {};
|
|
9649
|
+
const foreignKeys = options.foreignKeyOptions ?? {};
|
|
9603
9650
|
return admin.editableFieldNames().flatMap((name) => {
|
|
9604
9651
|
const column6 = columns[name];
|
|
9605
9652
|
if (column6 === void 0) return [];
|
|
9606
|
-
const
|
|
9653
|
+
const related = foreignKeys[name];
|
|
9654
|
+
const spec = related === void 0 ? widgetForColumn(column6) : { widget: "select", step: null, options: related };
|
|
9607
9655
|
const raw = name in values ? values[name] : literalDefault(column6);
|
|
9608
9656
|
return [
|
|
9609
9657
|
{
|
|
@@ -9653,7 +9701,7 @@ function coerceValue(column6, widget, raw) {
|
|
|
9653
9701
|
throw new Error("Enter valid JSON.");
|
|
9654
9702
|
}
|
|
9655
9703
|
case "select": {
|
|
9656
|
-
const allowed = meta.values ?? [];
|
|
9704
|
+
const allowed = kind === "enum" ? meta.values ?? [] : [];
|
|
9657
9705
|
if (allowed.length > 0 && !allowed.includes(raw)) {
|
|
9658
9706
|
throw new Error(`Choose one of: ${allowed.join(", ")}.`);
|
|
9659
9707
|
}
|
|
@@ -9701,6 +9749,28 @@ function formatCellValue(value) {
|
|
|
9701
9749
|
if (typeof value === "object") return JSON.stringify(value);
|
|
9702
9750
|
return String(value);
|
|
9703
9751
|
}
|
|
9752
|
+
function foreignKeyFields(admin) {
|
|
9753
|
+
const columns = adminColumns(admin.model);
|
|
9754
|
+
const out = {};
|
|
9755
|
+
for (const name of admin.editableFieldNames()) {
|
|
9756
|
+
const column6 = columns[name];
|
|
9757
|
+
if (column6 === void 0) continue;
|
|
9758
|
+
const table = foreignKeyTable(column6);
|
|
9759
|
+
if (table !== null) out[name] = table;
|
|
9760
|
+
}
|
|
9761
|
+
return out;
|
|
9762
|
+
}
|
|
9763
|
+
function foreignKeyLabel(admin, row) {
|
|
9764
|
+
for (const field of admin.searchFields) {
|
|
9765
|
+
const value = row[field];
|
|
9766
|
+
if (typeof value === "string" && value !== "") return value;
|
|
9767
|
+
}
|
|
9768
|
+
for (const field of ["name", "title", "email", "label", "reference"]) {
|
|
9769
|
+
const value = row[field];
|
|
9770
|
+
if (typeof value === "string" && value !== "") return value;
|
|
9771
|
+
}
|
|
9772
|
+
return String(row[admin.identityField] ?? "");
|
|
9773
|
+
}
|
|
9704
9774
|
|
|
9705
9775
|
// src/admin/auth.ts
|
|
9706
9776
|
var UserModelAuthBackend = class {
|
|
@@ -11838,15 +11908,40 @@ function renderFilter(filter) {
|
|
|
11838
11908
|
return `<label><span>${escapeHtml(filter.label)}</span><input type="text" name="${escapeHtml(name)}" value="${escapeHtml(filter.value)}"></label>`;
|
|
11839
11909
|
}
|
|
11840
11910
|
function renderListPage(context, view) {
|
|
11911
|
+
const bulk = view.bulkActions.length > 0 && context.session !== null;
|
|
11912
|
+
const checkColumn = bulk ? 1 : 0;
|
|
11841
11913
|
const headers = view.columns.map((column6) => {
|
|
11842
11914
|
const state = view.sort[column6];
|
|
11843
11915
|
if (state === void 0) return `<th>${escapeHtml(column6)}</th>`;
|
|
11844
11916
|
const arrow = state.active ? state.ascending ? "\u25B2" : "\u25BC" : "\u2195";
|
|
11845
11917
|
return `<th><a class="tempest-sort${state.active ? " tempest-sort--active" : ""}" href="${escapeHtml(state.url)}"><span>${escapeHtml(column6)}</span><span class="tempest-sort__arrow" aria-hidden="true">${arrow}</span></a></th>`;
|
|
11846
11918
|
}).join("");
|
|
11847
|
-
const rows = view.rows.length > 0 ? view.rows.map(
|
|
11848
|
-
|
|
11849
|
-
|
|
11919
|
+
const rows = view.rows.length > 0 ? view.rows.map((row) => {
|
|
11920
|
+
const check = bulk ? `<td class="tempest-admin-list__check"><input type="checkbox" name="ids" value="${escapeHtml(row.identity)}" data-row-check aria-label="Select row"></td>` : "";
|
|
11921
|
+
const cells = row.cells.map((cell) => `<td>${escapeHtml(cell)}</td>`).join("");
|
|
11922
|
+
return `<tr>${check}${cells}<td><a href="${escapeHtml(row.url)}">View</a></td></tr>`;
|
|
11923
|
+
}).join("") : `<tr><td colspan="${view.columns.length + 1 + checkColumn}">No records.</td></tr>`;
|
|
11924
|
+
const bulkBar = bulk ? `<form method="post" action="${escapeHtml(view.bulkUrl)}" class="tempest-admin-bulk" onsubmit="return confirm('Apply the selected action to the checked rows?');">
|
|
11925
|
+
<input type="hidden" name="csrf_token" value="${escapeHtml(context.session?.csrfToken)}">
|
|
11926
|
+
<div class="tempest-admin-bulk__bar">
|
|
11927
|
+
<select name="action" aria-label="Bulk action">
|
|
11928
|
+
${view.bulkActions.map(
|
|
11929
|
+
(action) => `<option value="${escapeHtml(action.value)}">${escapeHtml(action.label)}${action.dangerous ? " \u26A0" : ""}</option>`
|
|
11930
|
+
).join("")}
|
|
11931
|
+
</select>
|
|
11932
|
+
<button type="submit">Apply to selected</button>
|
|
11933
|
+
</div>` : "";
|
|
11934
|
+
const selectAllScript = bulk ? `<script>
|
|
11935
|
+
(function () {
|
|
11936
|
+
var master = document.querySelector('[data-select-all]');
|
|
11937
|
+
if (!master) return;
|
|
11938
|
+
master.addEventListener('change', function () {
|
|
11939
|
+
document.querySelectorAll('[data-row-check]').forEach(function (box) {
|
|
11940
|
+
box.checked = master.checked;
|
|
11941
|
+
});
|
|
11942
|
+
});
|
|
11943
|
+
})();
|
|
11944
|
+
</script>` : "";
|
|
11850
11945
|
const hasControls = view.searchable || view.filters.length > 0;
|
|
11851
11946
|
const body = `<section class="tempest-admin-list">
|
|
11852
11947
|
<header class="tempest-admin-list__header">
|
|
@@ -11861,14 +11956,19 @@ function renderListPage(context, view) {
|
|
|
11861
11956
|
</form>
|
|
11862
11957
|
<div class="tempest-admin-list__actions">
|
|
11863
11958
|
${view.newUrl !== null ? `<a class="tempest-admin-list__new" href="${escapeHtml(view.newUrl)}">+ New</a>` : ""}
|
|
11959
|
+
<a href="${escapeHtml(view.exportCsvUrl)}">Export CSV</a>
|
|
11960
|
+
<a href="${escapeHtml(view.exportJsonUrl)}">Export JSON</a>
|
|
11864
11961
|
</div>
|
|
11865
11962
|
</div>
|
|
11963
|
+
${bulkBar}
|
|
11866
11964
|
<div class="tempest-admin-table-wrap">
|
|
11867
11965
|
<table class="tempest-admin-list__table">
|
|
11868
|
-
<thead><tr>${headers}<th>Actions</th></tr></thead>
|
|
11966
|
+
<thead><tr>${bulk ? '<th class="tempest-admin-list__check"><input type="checkbox" data-select-all aria-label="Select all"></th>' : ""}${headers}<th>Actions</th></tr></thead>
|
|
11869
11967
|
<tbody>${rows}</tbody>
|
|
11870
11968
|
</table>
|
|
11871
11969
|
</div>
|
|
11970
|
+
${bulk ? "</form>" : ""}
|
|
11971
|
+
${selectAllScript}
|
|
11872
11972
|
${view.pages > 1 ? `<nav class="tempest-admin-list__pagination" aria-label="Pagination">
|
|
11873
11973
|
${view.prevUrl !== null ? `<a href="${escapeHtml(view.prevUrl)}">\u2190 Prev</a>` : ""}
|
|
11874
11974
|
<span>Page ${escapeHtml(view.page)} of ${escapeHtml(view.pages)}</span>
|
|
@@ -11962,11 +12062,16 @@ function renderFormPage(context, view) {
|
|
|
11962
12062
|
return renderLayout(context, `${heading} \xB7 ${context.site.title}`, body);
|
|
11963
12063
|
}
|
|
11964
12064
|
var logger2 = new JSONLogger("tempest_express_sdk.admin.router");
|
|
12065
|
+
var FK_OPTION_CAP = 1e3;
|
|
12066
|
+
var FLASH_MAX_LENGTH = 300;
|
|
11965
12067
|
var FLASH_MESSAGES = {
|
|
11966
12068
|
created: { text: "Record created.", level: "success" },
|
|
11967
12069
|
updated: { text: "Record updated.", level: "success" },
|
|
11968
12070
|
deleted: { text: "Record deleted.", level: "success" }
|
|
11969
12071
|
};
|
|
12072
|
+
async function runCustomAction(action, context) {
|
|
12073
|
+
return await action.handler(context) ?? null;
|
|
12074
|
+
}
|
|
11970
12075
|
function queryString(value) {
|
|
11971
12076
|
if (typeof value === "string") return value.trim();
|
|
11972
12077
|
if (Array.isArray(value) && typeof value[0] === "string") return value[0].trim();
|
|
@@ -11984,6 +12089,7 @@ function makeAdminRouter(site, options) {
|
|
|
11984
12089
|
const prefix = (options.prefix ?? "/admin").replace(/\/$/, "");
|
|
11985
12090
|
const theme = resolveAdminTheme(site.theme);
|
|
11986
12091
|
const showMetrics = options.showMetrics ?? true;
|
|
12092
|
+
const exportMaxRows = options.exportMaxRows ?? 5e3;
|
|
11987
12093
|
const sessions = new AdminSessionStore({
|
|
11988
12094
|
secret: options.secretKey,
|
|
11989
12095
|
...options.cookieName === void 0 ? {} : { cookieName: options.cookieName },
|
|
@@ -12007,8 +12113,17 @@ function makeAdminRouter(site, options) {
|
|
|
12007
12113
|
messages: flashFor(req)
|
|
12008
12114
|
});
|
|
12009
12115
|
const flashFor = (req) => {
|
|
12010
|
-
const
|
|
12011
|
-
|
|
12116
|
+
const fixed = FLASH_MESSAGES[queryString(req.query.ok)];
|
|
12117
|
+
if (fixed !== void 0) return [fixed];
|
|
12118
|
+
const text = queryString(req.query.flash);
|
|
12119
|
+
if (text === "") return [];
|
|
12120
|
+
const level = queryString(req.query.level);
|
|
12121
|
+
return [
|
|
12122
|
+
{
|
|
12123
|
+
text: text.slice(0, FLASH_MAX_LENGTH),
|
|
12124
|
+
level: level === "error" || level === "warning" ? level : "success"
|
|
12125
|
+
}
|
|
12126
|
+
];
|
|
12012
12127
|
};
|
|
12013
12128
|
const html = (res, body, status = 200) => {
|
|
12014
12129
|
res.status(status).type("html").send(body);
|
|
@@ -12044,7 +12159,7 @@ function makeAdminRouter(site, options) {
|
|
|
12044
12159
|
res.redirect(`${prefix}/mfa`);
|
|
12045
12160
|
return null;
|
|
12046
12161
|
}
|
|
12047
|
-
return { session, dbSession };
|
|
12162
|
+
return { session, dbSession, principal };
|
|
12048
12163
|
};
|
|
12049
12164
|
const resolveAdmin = (req, res, state) => {
|
|
12050
12165
|
const admin = site.get(String(req.params.slug));
|
|
@@ -12200,7 +12315,9 @@ function makeAdminRouter(site, options) {
|
|
|
12200
12315
|
renderFormPage(context(req, state.session), {
|
|
12201
12316
|
mode: "create",
|
|
12202
12317
|
title: admin.verboseName(),
|
|
12203
|
-
fields: buildFormFields(admin
|
|
12318
|
+
fields: buildFormFields(admin, {
|
|
12319
|
+
foreignKeyOptions: await foreignKeyOptionsFor(admin, state.dbSession)
|
|
12320
|
+
}),
|
|
12204
12321
|
actionUrl: `${prefix}/m/${admin.slug()}/new`,
|
|
12205
12322
|
backUrl: `${prefix}/m/${admin.slug()}`,
|
|
12206
12323
|
error: null
|
|
@@ -12222,13 +12339,18 @@ function makeAdminRouter(site, options) {
|
|
|
12222
12339
|
if (!checkCsrf(req, res, state)) return;
|
|
12223
12340
|
const body = req.body;
|
|
12224
12341
|
const parsed = parseFormBody(admin, body);
|
|
12342
|
+
const foreignKeyOptions = await foreignKeyOptionsFor(admin, state.dbSession);
|
|
12225
12343
|
const rerender = (error, status) => {
|
|
12226
12344
|
html(
|
|
12227
12345
|
res,
|
|
12228
12346
|
renderFormPage(context(req, state.session), {
|
|
12229
12347
|
mode: "create",
|
|
12230
12348
|
title: admin.verboseName(),
|
|
12231
|
-
fields: buildFormFields(admin, {
|
|
12349
|
+
fields: buildFormFields(admin, {
|
|
12350
|
+
values: body,
|
|
12351
|
+
errors: parsed.errors,
|
|
12352
|
+
foreignKeyOptions
|
|
12353
|
+
}),
|
|
12232
12354
|
actionUrl: `${prefix}/m/${admin.slug()}/new`,
|
|
12233
12355
|
backUrl: `${prefix}/m/${admin.slug()}`,
|
|
12234
12356
|
error
|
|
@@ -12249,6 +12371,106 @@ function makeAdminRouter(site, options) {
|
|
|
12249
12371
|
res.redirect(`${prefix}/m/${admin.slug()}?ok=created`);
|
|
12250
12372
|
})
|
|
12251
12373
|
);
|
|
12374
|
+
router.get(
|
|
12375
|
+
`${prefix}/m/:slug/export.:format`,
|
|
12376
|
+
guarded(async (req, res) => {
|
|
12377
|
+
const state = await authenticate(req, res);
|
|
12378
|
+
if (state === null) return;
|
|
12379
|
+
const admin = resolveAdmin(req, res, state);
|
|
12380
|
+
if (admin === null) return;
|
|
12381
|
+
const format = String(req.params.format);
|
|
12382
|
+
if (format !== "csv" && format !== "json") {
|
|
12383
|
+
html(res, renderNotFound(context(req, state.session)), 404);
|
|
12384
|
+
return;
|
|
12385
|
+
}
|
|
12386
|
+
const query = await resolveListQuery(req, admin, state.dbSession);
|
|
12387
|
+
const result = await admin.repository(state.dbSession).paginate({
|
|
12388
|
+
page: 1,
|
|
12389
|
+
pageSize: exportMaxRows,
|
|
12390
|
+
...query.orderBy === void 0 ? {} : { orderBy: query.orderBy },
|
|
12391
|
+
ascending: query.ascending,
|
|
12392
|
+
...query.where === void 0 ? {} : { filters: query.where }
|
|
12393
|
+
});
|
|
12394
|
+
const columns = admin.listDisplayNames();
|
|
12395
|
+
const rows = result.items;
|
|
12396
|
+
const payload = format === "csv" ? toCsv(columns, rows) : toJson(columns, rows);
|
|
12397
|
+
res.status(200).type(format === "csv" ? "text/csv; charset=utf-8" : "application/json").set("content-disposition", `attachment; filename="${admin.slug()}.${format}"`).send(payload);
|
|
12398
|
+
})
|
|
12399
|
+
);
|
|
12400
|
+
router.post(
|
|
12401
|
+
`${prefix}/m/:slug/bulk`,
|
|
12402
|
+
guarded(async (req, res) => {
|
|
12403
|
+
const state = await authenticate(req, res);
|
|
12404
|
+
if (state === null) return;
|
|
12405
|
+
const admin = resolveAdmin(req, res, state);
|
|
12406
|
+
if (admin === null) return;
|
|
12407
|
+
if (!checkCsrf(req, res, state)) return;
|
|
12408
|
+
const body = req.body;
|
|
12409
|
+
const action = typeof body.action === "string" ? body.action : "";
|
|
12410
|
+
const raw = body.ids;
|
|
12411
|
+
const ids = (Array.isArray(raw) ? raw : raw === void 0 ? [] : [raw]).filter((value) => typeof value === "string").filter((value) => value !== "");
|
|
12412
|
+
const listUrl = `${prefix}/m/${admin.slug()}`;
|
|
12413
|
+
const back = (message, level) => {
|
|
12414
|
+
res.redirect(`${listUrl}?${buildQuery({ flash: message, level })}`);
|
|
12415
|
+
};
|
|
12416
|
+
if (ids.length === 0) {
|
|
12417
|
+
back("No rows were selected.", "warning");
|
|
12418
|
+
return;
|
|
12419
|
+
}
|
|
12420
|
+
if (!bulkActionsFor(admin).some((option) => option.value === action)) {
|
|
12421
|
+
html(res, renderNotFound(context(req, state.session)), 400);
|
|
12422
|
+
return;
|
|
12423
|
+
}
|
|
12424
|
+
const repository = admin.repository(state.dbSession);
|
|
12425
|
+
const scope = { [admin.identityField]: { in: ids } };
|
|
12426
|
+
if (action.startsWith("custom:")) {
|
|
12427
|
+
const custom = admin.getAction(action.slice("custom:".length));
|
|
12428
|
+
if (custom === null) {
|
|
12429
|
+
html(res, renderNotFound(context(req, state.session)), 400);
|
|
12430
|
+
return;
|
|
12431
|
+
}
|
|
12432
|
+
let result;
|
|
12433
|
+
try {
|
|
12434
|
+
result = await runCustomAction(custom, {
|
|
12435
|
+
ids,
|
|
12436
|
+
repository,
|
|
12437
|
+
dbSession: state.dbSession,
|
|
12438
|
+
request: req,
|
|
12439
|
+
session: state.session,
|
|
12440
|
+
principal: state.principal
|
|
12441
|
+
});
|
|
12442
|
+
} catch (error) {
|
|
12443
|
+
logger2.error("Admin action failed", {
|
|
12444
|
+
slug: admin.slug(),
|
|
12445
|
+
action: custom.name,
|
|
12446
|
+
error: error instanceof Error ? error.message : String(error)
|
|
12447
|
+
});
|
|
12448
|
+
back(
|
|
12449
|
+
`${custom.label} failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
12450
|
+
"error"
|
|
12451
|
+
);
|
|
12452
|
+
return;
|
|
12453
|
+
}
|
|
12454
|
+
if (result === null) {
|
|
12455
|
+
res.redirect(listUrl);
|
|
12456
|
+
return;
|
|
12457
|
+
}
|
|
12458
|
+
back(result.message, result.category ?? "success");
|
|
12459
|
+
return;
|
|
12460
|
+
}
|
|
12461
|
+
if (action === "delete") {
|
|
12462
|
+
const removed = await repository.delete(scope);
|
|
12463
|
+
back(`Deleted ${removed} record${removed === 1 ? "" : "s"}.`, "success");
|
|
12464
|
+
return;
|
|
12465
|
+
}
|
|
12466
|
+
const active = action === "activate";
|
|
12467
|
+
const changed = await repository.update(scope, { isActive: active });
|
|
12468
|
+
back(
|
|
12469
|
+
`${active ? "Activated" : "Deactivated"} ${changed} record${changed === 1 ? "" : "s"}.`,
|
|
12470
|
+
"success"
|
|
12471
|
+
);
|
|
12472
|
+
})
|
|
12473
|
+
);
|
|
12252
12474
|
router.get(
|
|
12253
12475
|
`${prefix}/m/:slug/:identity`,
|
|
12254
12476
|
guarded(async (req, res) => {
|
|
@@ -12293,7 +12515,10 @@ function makeAdminRouter(site, options) {
|
|
|
12293
12515
|
renderFormPage(context(req, state.session), {
|
|
12294
12516
|
mode: "edit",
|
|
12295
12517
|
title: admin.verboseName(),
|
|
12296
|
-
fields: buildFormFields(admin, {
|
|
12518
|
+
fields: buildFormFields(admin, {
|
|
12519
|
+
values: row,
|
|
12520
|
+
foreignKeyOptions: await foreignKeyOptionsFor(admin, state.dbSession)
|
|
12521
|
+
}),
|
|
12297
12522
|
actionUrl: `${prefix}/m/${admin.slug()}/${identity}/edit`,
|
|
12298
12523
|
backUrl: `${prefix}/m/${admin.slug()}/${identity}`,
|
|
12299
12524
|
error: null
|
|
@@ -12316,13 +12541,18 @@ function makeAdminRouter(site, options) {
|
|
|
12316
12541
|
if (!checkCsrf(req, res, state)) return;
|
|
12317
12542
|
const body = req.body;
|
|
12318
12543
|
const parsed = parseFormBody(admin, body);
|
|
12544
|
+
const foreignKeyOptions = await foreignKeyOptionsFor(admin, state.dbSession);
|
|
12319
12545
|
const rerender = (error, status) => {
|
|
12320
12546
|
html(
|
|
12321
12547
|
res,
|
|
12322
12548
|
renderFormPage(context(req, state.session), {
|
|
12323
12549
|
mode: "edit",
|
|
12324
12550
|
title: admin.verboseName(),
|
|
12325
|
-
fields: buildFormFields(admin, {
|
|
12551
|
+
fields: buildFormFields(admin, {
|
|
12552
|
+
values: body,
|
|
12553
|
+
errors: parsed.errors,
|
|
12554
|
+
foreignKeyOptions
|
|
12555
|
+
}),
|
|
12326
12556
|
actionUrl: `${prefix}/m/${admin.slug()}/${identity}/edit`,
|
|
12327
12557
|
backUrl: `${prefix}/m/${admin.slug()}/${identity}`,
|
|
12328
12558
|
error
|
|
@@ -12369,8 +12599,69 @@ function makeAdminRouter(site, options) {
|
|
|
12369
12599
|
}
|
|
12370
12600
|
async function renderList(req, admin, state) {
|
|
12371
12601
|
const columns = adminColumns(admin.model);
|
|
12372
|
-
const
|
|
12602
|
+
const query = await resolveListQuery(req, admin, state.dbSession);
|
|
12373
12603
|
const page2 = Math.max(1, Number.parseInt(queryString(req.query.page), 10) || 1);
|
|
12604
|
+
const result = await admin.repository(state.dbSession).paginate({
|
|
12605
|
+
page: page2,
|
|
12606
|
+
pageSize: admin.pageSize,
|
|
12607
|
+
...query.orderBy === void 0 ? {} : { orderBy: query.orderBy },
|
|
12608
|
+
ascending: query.ascending,
|
|
12609
|
+
...query.where === void 0 ? {} : { filters: query.where }
|
|
12610
|
+
});
|
|
12611
|
+
const displayed = admin.listDisplayNames();
|
|
12612
|
+
const sort = {};
|
|
12613
|
+
for (const column6 of displayed) {
|
|
12614
|
+
if (!(column6 in columns)) continue;
|
|
12615
|
+
const active = (query.sortColumn ?? admin.orderKey) === column6;
|
|
12616
|
+
const nextAscending = active ? !query.ascending : true;
|
|
12617
|
+
sort[column6] = {
|
|
12618
|
+
url: `?${buildQuery({
|
|
12619
|
+
...query.baseQuery,
|
|
12620
|
+
sort: column6,
|
|
12621
|
+
dir: nextAscending ? "asc" : "desc"
|
|
12622
|
+
})}`,
|
|
12623
|
+
active,
|
|
12624
|
+
ascending: query.ascending
|
|
12625
|
+
};
|
|
12626
|
+
}
|
|
12627
|
+
const sortParams = {
|
|
12628
|
+
sort: query.sortColumn ?? void 0,
|
|
12629
|
+
dir: query.sortColumn === null ? void 0 : query.ascending ? "asc" : "desc"
|
|
12630
|
+
};
|
|
12631
|
+
const pageUrl = (target) => `?${buildQuery({ ...query.baseQuery, ...sortParams, page: target })}`;
|
|
12632
|
+
const exportQuery = buildQuery({ ...query.baseQuery, ...sortParams });
|
|
12633
|
+
const exportUrl = (format) => `${prefix}/m/${admin.slug()}/export.${format}${exportQuery === "" ? "" : `?${exportQuery}`}`;
|
|
12634
|
+
const view = {
|
|
12635
|
+
title: admin.verboseNamePlural(),
|
|
12636
|
+
columns: displayed,
|
|
12637
|
+
rows: result.items.map((row) => {
|
|
12638
|
+
const identity = String(row[admin.identityField]);
|
|
12639
|
+
return {
|
|
12640
|
+
identity,
|
|
12641
|
+
cells: displayed.map((column6) => formatCellValue(row[column6])),
|
|
12642
|
+
url: `${prefix}/m/${admin.slug()}/${identity}`
|
|
12643
|
+
};
|
|
12644
|
+
}),
|
|
12645
|
+
total: result.total,
|
|
12646
|
+
page: result.page,
|
|
12647
|
+
pages: result.pages,
|
|
12648
|
+
prevUrl: result.page > 1 ? pageUrl(result.page - 1) : null,
|
|
12649
|
+
nextUrl: result.page < result.pages ? pageUrl(result.page + 1) : null,
|
|
12650
|
+
searchable: query.searchable.length > 0,
|
|
12651
|
+
searchValue: query.search,
|
|
12652
|
+
filters: query.filterViews,
|
|
12653
|
+
sort,
|
|
12654
|
+
newUrl: admin.canCreate ? `${prefix}/m/${admin.slug()}/new` : null,
|
|
12655
|
+
bulkActions: bulkActionsFor(admin),
|
|
12656
|
+
bulkUrl: `${prefix}/m/${admin.slug()}/bulk`,
|
|
12657
|
+
exportCsvUrl: exportUrl("csv"),
|
|
12658
|
+
exportJsonUrl: exportUrl("json")
|
|
12659
|
+
};
|
|
12660
|
+
return renderListPage(context(req, state.session), view);
|
|
12661
|
+
}
|
|
12662
|
+
async function resolveListQuery(req, admin, dbSession) {
|
|
12663
|
+
const columns = adminColumns(admin.model);
|
|
12664
|
+
const search = queryString(req.query.q);
|
|
12374
12665
|
const sortField = queryString(req.query.sort);
|
|
12375
12666
|
const sortColumn = sortField in columns ? sortField : null;
|
|
12376
12667
|
const ascending = sortColumn === null ? admin.orderAscending : queryString(req.query.dir) !== "desc";
|
|
@@ -12398,6 +12689,8 @@ function makeAdminRouter(site, options) {
|
|
|
12398
12689
|
});
|
|
12399
12690
|
continue;
|
|
12400
12691
|
}
|
|
12692
|
+
const related = await relatedOptions(column6, dbSession);
|
|
12693
|
+
const options2 = related ?? spec.options;
|
|
12401
12694
|
const value = queryString(req.query[`filter_${field}`]);
|
|
12402
12695
|
if (value !== "") {
|
|
12403
12696
|
conditions.push({
|
|
@@ -12407,11 +12700,11 @@ function makeAdminRouter(site, options) {
|
|
|
12407
12700
|
filterViews.push({
|
|
12408
12701
|
field,
|
|
12409
12702
|
label: humanizeField(field),
|
|
12410
|
-
kind: spec.kind,
|
|
12703
|
+
kind: related === null ? spec.kind : "select",
|
|
12411
12704
|
value,
|
|
12412
12705
|
valueFrom: "",
|
|
12413
12706
|
valueTo: "",
|
|
12414
|
-
options:
|
|
12707
|
+
options: options2.map((option) => ({
|
|
12415
12708
|
value: option.value,
|
|
12416
12709
|
label: option.label,
|
|
12417
12710
|
selected: option.value === value
|
|
@@ -12427,72 +12720,98 @@ function makeAdminRouter(site, options) {
|
|
|
12427
12720
|
or(...searchable.map((field) => ({ [field]: { ilike: `%${search}%` } })))
|
|
12428
12721
|
);
|
|
12429
12722
|
}
|
|
12430
|
-
const where = conditions.length === 0 ? void 0 : and(...conditions);
|
|
12431
|
-
const orderBy = sortColumn ?? admin.orderKey ?? void 0;
|
|
12432
|
-
const result = await admin.repository(state.dbSession).paginate({
|
|
12433
|
-
page: page2,
|
|
12434
|
-
pageSize: admin.pageSize,
|
|
12435
|
-
...orderBy === void 0 ? {} : { orderBy },
|
|
12436
|
-
ascending,
|
|
12437
|
-
...where === void 0 ? {} : { filters: where }
|
|
12438
|
-
});
|
|
12439
|
-
const displayed = admin.listDisplayNames();
|
|
12440
12723
|
const baseQuery = { q: search };
|
|
12441
|
-
for (const
|
|
12442
|
-
if (
|
|
12443
|
-
baseQuery[`filter_${
|
|
12444
|
-
baseQuery[`filter_${
|
|
12724
|
+
for (const view of filterViews) {
|
|
12725
|
+
if (view.kind === "daterange") {
|
|
12726
|
+
baseQuery[`filter_${view.field}_from`] = view.valueFrom;
|
|
12727
|
+
baseQuery[`filter_${view.field}_to`] = view.valueTo;
|
|
12445
12728
|
} else {
|
|
12446
|
-
baseQuery[`filter_${
|
|
12729
|
+
baseQuery[`filter_${view.field}`] = view.value;
|
|
12447
12730
|
}
|
|
12448
12731
|
}
|
|
12449
|
-
|
|
12450
|
-
|
|
12451
|
-
|
|
12452
|
-
|
|
12453
|
-
|
|
12454
|
-
|
|
12455
|
-
|
|
12456
|
-
|
|
12457
|
-
|
|
12458
|
-
dir: nextAscending ? "asc" : "desc"
|
|
12459
|
-
})}`,
|
|
12460
|
-
active,
|
|
12461
|
-
ascending
|
|
12462
|
-
};
|
|
12463
|
-
}
|
|
12464
|
-
const pageUrl = (target) => `?${buildQuery({
|
|
12465
|
-
...baseQuery,
|
|
12466
|
-
sort: sortColumn ?? void 0,
|
|
12467
|
-
dir: sortColumn === null ? void 0 : ascending ? "asc" : "desc",
|
|
12468
|
-
page: target
|
|
12469
|
-
})}`;
|
|
12470
|
-
const view = {
|
|
12471
|
-
title: admin.verboseNamePlural(),
|
|
12472
|
-
columns: displayed,
|
|
12473
|
-
rows: result.items.map((row) => {
|
|
12474
|
-
const identity = String(row[admin.identityField]);
|
|
12475
|
-
return {
|
|
12476
|
-
identity,
|
|
12477
|
-
cells: displayed.map((column6) => formatCellValue(row[column6])),
|
|
12478
|
-
url: `${prefix}/m/${admin.slug()}/${identity}`
|
|
12479
|
-
};
|
|
12480
|
-
}),
|
|
12481
|
-
total: result.total,
|
|
12482
|
-
page: result.page,
|
|
12483
|
-
pages: result.pages,
|
|
12484
|
-
prevUrl: result.page > 1 ? pageUrl(result.page - 1) : null,
|
|
12485
|
-
nextUrl: result.page < result.pages ? pageUrl(result.page + 1) : null,
|
|
12486
|
-
searchable: searchable.length > 0,
|
|
12487
|
-
searchValue: search,
|
|
12488
|
-
filters: filterViews,
|
|
12489
|
-
sort,
|
|
12490
|
-
newUrl: admin.canCreate ? `${prefix}/m/${admin.slug()}/new` : null
|
|
12732
|
+
return {
|
|
12733
|
+
search,
|
|
12734
|
+
searchable,
|
|
12735
|
+
where: conditions.length === 0 ? void 0 : and(...conditions),
|
|
12736
|
+
orderBy: sortColumn ?? admin.orderKey ?? void 0,
|
|
12737
|
+
ascending,
|
|
12738
|
+
sortColumn,
|
|
12739
|
+
filterViews,
|
|
12740
|
+
baseQuery
|
|
12491
12741
|
};
|
|
12492
|
-
|
|
12742
|
+
}
|
|
12743
|
+
async function relatedOptions(column6, dbSession) {
|
|
12744
|
+
const table = foreignKeyTable(column6);
|
|
12745
|
+
if (table === null) return null;
|
|
12746
|
+
const referenced = site.get(table);
|
|
12747
|
+
if (referenced === null) return null;
|
|
12748
|
+
const rows = await referenced.repository(dbSession).list();
|
|
12749
|
+
return rows.slice(0, FK_OPTION_CAP).map((row) => ({
|
|
12750
|
+
value: String(row[referenced.identityField]),
|
|
12751
|
+
label: foreignKeyLabel(referenced, row)
|
|
12752
|
+
}));
|
|
12753
|
+
}
|
|
12754
|
+
async function foreignKeyOptionsFor(admin, dbSession) {
|
|
12755
|
+
const columns = adminColumns(admin.model);
|
|
12756
|
+
const options2 = {};
|
|
12757
|
+
for (const field of Object.keys(foreignKeyFields(admin))) {
|
|
12758
|
+
const column6 = columns[field];
|
|
12759
|
+
if (column6 === void 0) continue;
|
|
12760
|
+
const related = await relatedOptions(column6, dbSession);
|
|
12761
|
+
if (related !== null) options2[field] = related;
|
|
12762
|
+
}
|
|
12763
|
+
return options2;
|
|
12493
12764
|
}
|
|
12494
12765
|
return router;
|
|
12495
12766
|
}
|
|
12767
|
+
function bulkActionsFor(admin) {
|
|
12768
|
+
const actions = [];
|
|
12769
|
+
const hasActiveFlag = "isActive" in adminColumns(admin.model);
|
|
12770
|
+
if (admin.canEdit && hasActiveFlag) {
|
|
12771
|
+
actions.push({ value: "activate", label: "Activate", dangerous: false });
|
|
12772
|
+
actions.push({ value: "deactivate", label: "Deactivate", dangerous: false });
|
|
12773
|
+
}
|
|
12774
|
+
if (admin.canDelete) {
|
|
12775
|
+
actions.push({ value: "delete", label: "Delete", dangerous: true });
|
|
12776
|
+
}
|
|
12777
|
+
for (const action of admin.customActions()) {
|
|
12778
|
+
actions.push({
|
|
12779
|
+
value: `custom:${action.name}`,
|
|
12780
|
+
label: action.label,
|
|
12781
|
+
dangerous: action.dangerous
|
|
12782
|
+
});
|
|
12783
|
+
}
|
|
12784
|
+
return actions;
|
|
12785
|
+
}
|
|
12786
|
+
function exportValue(value) {
|
|
12787
|
+
if (value instanceof Date) return value.toISOString();
|
|
12788
|
+
if (typeof value === "bigint") return value.toString();
|
|
12789
|
+
if (value instanceof Uint8Array) return Buffer.from(value).toString("base64");
|
|
12790
|
+
return value;
|
|
12791
|
+
}
|
|
12792
|
+
function csvField(value) {
|
|
12793
|
+
if (value === null || value === void 0) return "";
|
|
12794
|
+
const text = typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
12795
|
+
if (/[",\r\n]/.test(text)) return `"${text.replace(/"/g, '""')}"`;
|
|
12796
|
+
return text;
|
|
12797
|
+
}
|
|
12798
|
+
function toCsv(columns, rows) {
|
|
12799
|
+
const lines = [columns.map(csvField).join(",")];
|
|
12800
|
+
for (const row of rows) {
|
|
12801
|
+
lines.push(columns.map((column6) => csvField(exportValue(row[column6]))).join(","));
|
|
12802
|
+
}
|
|
12803
|
+
return `${lines.join("\r\n")}\r
|
|
12804
|
+
`;
|
|
12805
|
+
}
|
|
12806
|
+
function toJson(columns, rows) {
|
|
12807
|
+
return JSON.stringify(
|
|
12808
|
+
rows.map(
|
|
12809
|
+
(row) => Object.fromEntries(columns.map((column6) => [column6, exportValue(row[column6])]))
|
|
12810
|
+
),
|
|
12811
|
+
null,
|
|
12812
|
+
2
|
|
12813
|
+
);
|
|
12814
|
+
}
|
|
12496
12815
|
function describeWriteFailure(admin, error) {
|
|
12497
12816
|
const detail = error instanceof Error ? error.message : String(error);
|
|
12498
12817
|
return `The database refused this ${admin.verboseName().toLowerCase()}: ${detail}`;
|
|
@@ -14496,6 +14815,6 @@ async function withTestDatabase(models, fn) {
|
|
|
14496
14815
|
}
|
|
14497
14816
|
}
|
|
14498
14817
|
|
|
14499
|
-
export { ADMIN_CSS, ActivationService, AdminJsonSite, AdminModel, AdminSessionStore, AdminSite, AppException, AttemptThrottle, AuditAction, BaseAuditLogModel, BaseController, BaseModel, BaseOAuthClient, BaseOutboxModel, BaseService, BaseUserModel, BaseUserRefreshTokenModel, BaseUserTokenModel, CEP_PATTERN, CNPJ_PATTERN, CPF_PATTERN, CSRF_COOKIE_NAME, CSRF_HEADER_NAME, CircuitOpenError, CompositeFeatureFlagBackend, ConflictException, DEFAULT_DOCS_FAVICON, DEFAULT_LOCALE, EmailProvider, EmailUtils, EnvFeatureFlagBackend, EventStream, ExpiredTokenException, FeatureFlags, ForbiddenException, GitHubOAuthClient, GoogleOAuthClient, GracefulShutdown, HTTPClient, HTTP_500_LOG_FILE, HTTP_500_MARKER, HttpMetrics, IDEMPOTENCY_HEADER, InvalidTokenException, JSONLogger, JWTUtils, LEVEL_LOG_FILES, LocalUploadStorage, MemoryBroker, MemoryCacheManager, MemoryFeatureFlagBackend, MemoryIdempotencyStore, MemoryRateLimitStore, MemorySessionStore, MemoryThrottleBackend, MessageCatalog, MessagingHub, MetricsUtils, MfaService, NotFoundException, OAuthError, OIDCProvider, OutboxRelay, OutboxStatus, PHONE_BR_PATTERN, PasswordResetService, REDOC_CDN_URL, REQUEST_ID_HEADER, RabbitBroker, RedisCacheManager, RedisIdempotencyStore, RedisRateLimitStore, RedisSSEBroker, RedisSessionStore, Region, RetryPolicy, S3UploadStorage, SSEBroker, ServerSentEvent, SessionService, TOTPHelper, TaskManager, TelegramProvider, TenantScopedRepository, TooManyRequestsException, TwilioSmsProvider, UF, UnauthorizedException, UserAuthService, UserModelAuthBackend, UserTokenPurpose, ValidationException, WebPushDispatcher, WebPushError, WebPushGoneError, WebSocketHub, WebhookSignatureVerifier, WhatsAppProvider, activationSchema, addLogSink, adminColumns, adminThemeCss, attachWebSocketHub, authResponseSchema, authSettingsShape, backupDatabase, bearerToken, bodySizeLimitMiddleware, broadcastText, buildContentDisposition, buildFormFields, buildPaginationLinkHeader, cached2 as cached, cepField, citiesByUf, cnpjField, coerceFlag, configureFileLogging, configureLogging, cpfField, cpfOrCnpjField, createApp, createOpenApiRegistry, createTestDatabase, createdByColumn, csrfMiddleware, csrfTokenMatches, cursorPaginationFilterSchema, cursorPaginationSchema, decodeCursor, defaultMessageCatalog, defineEnum, deletedAtColumn, diffSnapshots, emailSettingsShape, encodeCursor, envList, escapeHtml, filterForColumn, formatCellValue, formatFieldValue, generateCsrfToken, generateOAuthState, generateOpaqueToken, generateOpenApiDocument, getAuth, getClientIp, getConditions, getPaginationConditions, getRequestId, getState, hashOpaqueToken, humanizeField, idempotencyMiddleware, inboundMessageSchema, isColumnOptional, isSearchableColumn, isValidCep, isValidCity, isValidCnpj, isValidCpf, isValidCpfCnpj, isValidPhoneBr, isValidUf, jwtSettingsShape, keyByHeader, keyByIp, keyByJwtClaim, keyByJwtSubject, listStates, logEntrySchema, logSettingsShape, loginSchema, makeAdminJsonRouter, makeAdminRouter, makeAppExceptionHandler, makeAuthRouter, makeFlagGuard, makeHealthRouter, makeJwtAuthMiddleware, makeLogsRouter, makeMetricsRouter, makeSessionMiddleware, makeToolSpecRouter, makeTwilioWebhookRouter, makeUnhandledExceptionHandler, makeWhatsAppWebhookRouter, mfaChallengeSchema, mfaCodeSchema, mfaEnrollResponseSchema, minioSettingsShape, modifyDict, mountOpenApiJson, mountRedoc, mountSwaggerUi, normalizeCep, normalizeCnpj, normalizeCpf, normalizeCpfCnpj, normalizePhoneBr, normalizeUf, notFoundHandler, onlyDigits, paginationFilterSchema, paginationSchema, parseAcceptLanguage, parseCookies, parseFormBody, passwordResetConfirmSchema, passwordResetRequestSchema, phoneBrField, prometheusMiddleware, rabbitmqSettingsShape, rateLimitMiddleware, redisSettingsShape, refreshSchema, registerExceptionHandlers, renderAuthResultPage, renderDashboardPage, renderDetailPage, renderFormPage, renderLayout, renderListPage, renderLoginPage, renderMfaPage, renderPasswordResetFormPage, requestIdMiddleware, requestTracingMiddleware, requireRoles, resolveAdminTheme, resolveDownloadPath, resolveRedocBundle, runServer, runWithRequestContext, sendBytesDownload, sendFileDownload, sessionCookie, sessionSettingsShape, setRequestId, signupSchema, snapshot, sseResponse, statesByRegion, syncFilterSchema, syncPaginationSchema, tableNameFor, toUtc, tokenFromUrl, tokenPairSchema, tokenSettingsShape, ufField, updatedByColumn, uploadSettingsShape, userPublicSchema, utcnow, validateTwilioSignature, verifyOpaqueToken, webPushKeysSchema, webPushPayloadSchema, webPushSettingsShape, webPushSubscriptionSchema, webSocketSettingsShape, widgetForColumn, withTestDatabase, wrapWithSlowQueryLog, wsEnvelopeSchema };
|
|
14818
|
+
export { ADMIN_CSS, ActivationService, AdminJsonSite, AdminModel, AdminSessionStore, AdminSite, AppException, AttemptThrottle, AuditAction, BaseAuditLogModel, BaseController, BaseModel, BaseOAuthClient, BaseOutboxModel, BaseService, BaseUserModel, BaseUserRefreshTokenModel, BaseUserTokenModel, CEP_PATTERN, CNPJ_PATTERN, CPF_PATTERN, CSRF_COOKIE_NAME, CSRF_HEADER_NAME, CircuitOpenError, CompositeFeatureFlagBackend, ConflictException, DEFAULT_DOCS_FAVICON, DEFAULT_LOCALE, EmailProvider, EmailUtils, EnvFeatureFlagBackend, EventStream, ExpiredTokenException, FeatureFlags, ForbiddenException, GitHubOAuthClient, GoogleOAuthClient, GracefulShutdown, HTTPClient, HTTP_500_LOG_FILE, HTTP_500_MARKER, HttpMetrics, IDEMPOTENCY_HEADER, InvalidTokenException, JSONLogger, JWTUtils, LEVEL_LOG_FILES, LocalUploadStorage, MemoryBroker, MemoryCacheManager, MemoryFeatureFlagBackend, MemoryIdempotencyStore, MemoryRateLimitStore, MemorySessionStore, MemoryThrottleBackend, MessageCatalog, MessagingHub, MetricsUtils, MfaService, NotFoundException, OAuthError, OIDCProvider, OutboxRelay, OutboxStatus, PHONE_BR_PATTERN, PasswordResetService, REDOC_CDN_URL, REQUEST_ID_HEADER, RabbitBroker, RedisCacheManager, RedisIdempotencyStore, RedisRateLimitStore, RedisSSEBroker, RedisSessionStore, Region, RetryPolicy, S3UploadStorage, SSEBroker, ServerSentEvent, SessionService, TOTPHelper, TaskManager, TelegramProvider, TenantScopedRepository, TooManyRequestsException, TwilioSmsProvider, UF, UnauthorizedException, UserAuthService, UserModelAuthBackend, UserTokenPurpose, ValidationException, WebPushDispatcher, WebPushError, WebPushGoneError, WebSocketHub, WebhookSignatureVerifier, WhatsAppProvider, activationSchema, addLogSink, adminAction, adminColumns, adminThemeCss, attachWebSocketHub, authResponseSchema, authSettingsShape, backupDatabase, bearerToken, bodySizeLimitMiddleware, broadcastText, buildContentDisposition, buildFormFields, buildPaginationLinkHeader, cached2 as cached, cepField, citiesByUf, cnpjField, coerceFlag, configureFileLogging, configureLogging, cpfField, cpfOrCnpjField, createApp, createOpenApiRegistry, createTestDatabase, createdByColumn, csrfMiddleware, csrfTokenMatches, cursorPaginationFilterSchema, cursorPaginationSchema, decodeCursor, defaultMessageCatalog, defineEnum, deletedAtColumn, diffSnapshots, emailSettingsShape, encodeCursor, envList, escapeHtml, filterForColumn, foreignKeyFields, foreignKeyLabel, foreignKeyTable, formatCellValue, formatFieldValue, generateCsrfToken, generateOAuthState, generateOpaqueToken, generateOpenApiDocument, getAuth, getClientIp, getConditions, getPaginationConditions, getRequestId, getState, hashOpaqueToken, humanizeField, idempotencyMiddleware, inboundMessageSchema, isColumnOptional, isSearchableColumn, isValidCep, isValidCity, isValidCnpj, isValidCpf, isValidCpfCnpj, isValidPhoneBr, isValidUf, jwtSettingsShape, keyByHeader, keyByIp, keyByJwtClaim, keyByJwtSubject, listStates, logEntrySchema, logSettingsShape, loginSchema, makeAdminJsonRouter, makeAdminRouter, makeAppExceptionHandler, makeAuthRouter, makeFlagGuard, makeHealthRouter, makeJwtAuthMiddleware, makeLogsRouter, makeMetricsRouter, makeSessionMiddleware, makeToolSpecRouter, makeTwilioWebhookRouter, makeUnhandledExceptionHandler, makeWhatsAppWebhookRouter, mfaChallengeSchema, mfaCodeSchema, mfaEnrollResponseSchema, minioSettingsShape, modifyDict, mountOpenApiJson, mountRedoc, mountSwaggerUi, normalizeCep, normalizeCnpj, normalizeCpf, normalizeCpfCnpj, normalizePhoneBr, normalizeUf, notFoundHandler, onlyDigits, paginationFilterSchema, paginationSchema, parseAcceptLanguage, parseCookies, parseFormBody, passwordResetConfirmSchema, passwordResetRequestSchema, phoneBrField, prometheusMiddleware, rabbitmqSettingsShape, rateLimitMiddleware, redisSettingsShape, refreshSchema, registerExceptionHandlers, renderAuthResultPage, renderDashboardPage, renderDetailPage, renderFormPage, renderLayout, renderListPage, renderLoginPage, renderMfaPage, renderPasswordResetFormPage, requestIdMiddleware, requestTracingMiddleware, requireRoles, resolveAdminTheme, resolveDownloadPath, resolveRedocBundle, runServer, runWithRequestContext, sendBytesDownload, sendFileDownload, sessionCookie, sessionSettingsShape, setRequestId, signupSchema, snapshot, sseResponse, statesByRegion, syncFilterSchema, syncPaginationSchema, tableNameFor, toUtc, tokenFromUrl, tokenPairSchema, tokenSettingsShape, ufField, updatedByColumn, uploadSettingsShape, userPublicSchema, utcnow, validateTwilioSignature, verifyOpaqueToken, webPushKeysSchema, webPushPayloadSchema, webPushSettingsShape, webPushSubscriptionSchema, webSocketSettingsShape, widgetForColumn, withTestDatabase, wrapWithSlowQueryLog, wsEnvelopeSchema };
|
|
14500
14819
|
//# sourceMappingURL=index.js.map
|
|
14501
14820
|
//# sourceMappingURL=index.js.map
|