betterstart-cli 0.0.28 → 0.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/adapters/next/integrations/mailchimp/actions/mailchimp.ts +0 -1
- package/dist/assets/adapters/next/plugins/blog/schemas/menus.json +1 -1
- package/dist/assets/adapters/next/plugins/blog/schemas/posts.json +1 -1
- package/dist/assets/adapters/next/templates/init/admin-globals.css +1 -1
- package/dist/assets/adapters/next/templates/init/components/layouts/admin-nav-link.tsx +12 -2
- package/dist/assets/adapters/next/templates/init/components/layouts/admin-settings-sidebar.tsx +75 -0
- package/dist/assets/adapters/next/templates/init/components/layouts/admin-sidebar-nav-link.tsx +12 -2
- package/dist/assets/adapters/next/templates/init/components/layouts/admin-sidebar.tsx +2 -8
- package/dist/assets/adapters/next/templates/init/components/shared/data-table/data-grid.tsx +14 -5
- package/dist/assets/adapters/next/templates/init/components/shared/data-table/data-table.tsx +111 -112
- package/dist/assets/adapters/next/templates/init/components/shared/dev-mode/dev-mode-types.ts +4 -0
- package/dist/assets/adapters/next/templates/init/components/shared/dev-mode-integrate.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/components/shared/entity-versions/entity-versions-drawer.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/components/shared/media/media-url-importer.tsx +45 -47
- package/dist/assets/adapters/next/templates/init/components/shared/page-header.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/data/webhook-events.ts +5 -0
- package/dist/assets/adapters/next/templates/init/hooks/use-table-utils.ts +27 -7
- package/dist/assets/adapters/next/templates/init/hooks/use-webhooks.ts +211 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/audit/types.ts +2 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/forms/index.ts +0 -1
- package/dist/assets/adapters/next/templates/init/lib/actions/forms/types.ts +0 -4
- package/dist/assets/adapters/next/templates/init/lib/actions/forms/upsert-form-settings.ts +0 -2
- package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/create-webhook.ts +55 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/delete-webhook.ts +26 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/dispatch.ts +135 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/get-webhook-deliveries.ts +124 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/get-webhook-secret.ts +28 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/get-webhook-subscriptions.ts +32 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/get-webhooks.ts +154 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/index.ts +30 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/internal-get-active-endpoints.ts +20 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/regenerate-webhook-secret.ts +35 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/register.ts +70 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/send-test-webhook.ts +81 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/types.ts +104 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/update-webhook.ts +72 -0
- package/dist/assets/adapters/next/templates/init/lib/db/core/schema.ts +71 -2
- package/dist/assets/adapters/next/templates/init/lib/lifecycle-hooks/register.ts +2 -0
- package/dist/assets/adapters/next/templates/init/lib/lifecycle-hooks/runner.ts +3 -1
- package/dist/assets/adapters/next/templates/init/lib/lifecycle-hooks/types.ts +6 -1
- package/dist/assets/adapters/next/templates/init/pages/auth-gate-rsc.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/pages/media/media-page-content.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/pages/media/media-page-skeleton.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/pages/settings/audit-log/audit-log-columns.tsx +150 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/audit-log/audit-log-page-content.tsx +137 -0
- package/dist/assets/adapters/next/templates/init/pages/{audit-log → settings/audit-log}/audit-log-page-skeleton.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/pages/settings/audit-log/audit-log-table.tsx +295 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/forms/edit-form-notifications-dialog.tsx +128 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/forms/forms-settings-page-content.tsx +111 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/forms/forms-settings-page-skeleton.tsx +7 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/forms/forms-settings-page.tsx +14 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/settings-layout.tsx +10 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/delete-webhook-dialog.tsx +82 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhook-actions.tsx +53 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhook-enabled-switch.tsx +18 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhook-endpoint-dialog.tsx +370 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhooks-columns.tsx +258 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhooks-logs-columns.tsx +200 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhooks-logs-page-content.tsx +117 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhooks-logs-page.tsx +14 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhooks-logs-table.tsx +253 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhooks-page-content.tsx +161 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhooks-page-skeleton.tsx +7 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhooks-page.tsx +14 -0
- package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhooks-table.tsx +264 -0
- package/dist/assets/adapters/next/templates/init/pages/users/users-page-skeleton.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/pages/users/users-table.tsx +103 -109
- package/dist/assets/adapters/next/templates/init/types/webhooks.ts +7 -0
- package/dist/assets/adapters/next/templates/init/utils/webhook/signature.ts +13 -0
- package/dist/assets/shared-assets/react-admin/ui/card.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/drawer.tsx +2 -2
- package/dist/assets/shared-assets/react-admin/ui/input-group.tsx +3 -3
- package/dist/assets/shared-assets/react-admin/ui/sidebar.tsx +1 -1
- package/dist/cli.js +806 -554
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/dist/assets/adapters/next/templates/init/lib/actions/forms/test-form-webhook.ts +0 -40
- package/dist/assets/adapters/next/templates/init/pages/audit-log/audit-log-page-content.tsx +0 -550
- package/dist/assets/adapters/next/templates/init/utils/webhook/webhook.ts +0 -28
- /package/dist/assets/adapters/next/templates/init/pages/{audit-log → settings/audit-log}/audit-log-detail-drawer.tsx +0 -0
- /package/dist/assets/adapters/next/templates/init/pages/{audit-log → settings/audit-log}/audit-log-detail-row.tsx +0 -0
- /package/dist/assets/adapters/next/templates/init/pages/{audit-log → settings/audit-log}/audit-log-page.tsx +0 -0
package/dist/cli.js
CHANGED
|
@@ -1410,16 +1410,29 @@ import path9 from "path";
|
|
|
1410
1410
|
var PG_SSL_WARNING_START = "Warning: SECURITY WARNING: The SSL modes 'prefer', 'require', and 'verify-ca' are treated as aliases for 'verify-full'.";
|
|
1411
1411
|
var PG_SSL_WARNING_END = "See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode definitions.";
|
|
1412
1412
|
var NODE_TRACE_WARNING_HINT = "(Use `node --trace-warnings";
|
|
1413
|
-
var
|
|
1413
|
+
var DRIZZLE_NOISE_PATTERNS = [
|
|
1414
1414
|
/^No config path provided, using default 'drizzle\.config\.ts'$/,
|
|
1415
1415
|
/^Reading config file '.+drizzle\.config\.ts'$/,
|
|
1416
|
-
/^Using 'pg' driver for database querying
|
|
1416
|
+
/^Using 'pg' driver for database querying$/,
|
|
1417
|
+
/^\[.\] Pulling schema from database\.\.\.$/u,
|
|
1418
|
+
/^\[.\] Changes applied$/u
|
|
1417
1419
|
];
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
+
var SUPPRESSIBLE_LINE_STARTS = [
|
|
1421
|
+
"No config path provided",
|
|
1422
|
+
"Reading config file '",
|
|
1423
|
+
"Using 'pg' driver",
|
|
1424
|
+
"(node:",
|
|
1425
|
+
"["
|
|
1426
|
+
];
|
|
1427
|
+
var ANSI_ESCAPE_PATTERN = /\u001B\[[0-9;]*[A-Za-z]/g;
|
|
1428
|
+
function resolveDrizzlePushStdio(interactive) {
|
|
1429
|
+
return interactive ? ["inherit", "pipe", "pipe"] : "pipe";
|
|
1430
|
+
}
|
|
1431
|
+
function stripAnsi(text7) {
|
|
1432
|
+
return text7.replace(ANSI_ESCAPE_PATTERN, "").replaceAll("\r", "");
|
|
1420
1433
|
}
|
|
1421
|
-
function
|
|
1422
|
-
const text7 = line.
|
|
1434
|
+
function shouldSuppressOutputLine(line, state) {
|
|
1435
|
+
const text7 = stripAnsi(line).trim();
|
|
1423
1436
|
if (state.suppressNextTraceHint) {
|
|
1424
1437
|
state.suppressNextTraceHint = false;
|
|
1425
1438
|
if (text7.startsWith(NODE_TRACE_WARNING_HINT)) {
|
|
@@ -1437,20 +1450,20 @@ function shouldSuppressWarningLine(line, state) {
|
|
|
1437
1450
|
}
|
|
1438
1451
|
return true;
|
|
1439
1452
|
}
|
|
1440
|
-
return
|
|
1441
|
-
}
|
|
1442
|
-
function shouldSuppressDrizzleConfigBannerLine(line) {
|
|
1443
|
-
const text7 = line.trim();
|
|
1444
|
-
return DRIZZLE_CONFIG_BANNER_PATTERNS.some((pattern) => pattern.test(text7));
|
|
1453
|
+
return DRIZZLE_NOISE_PATTERNS.some((pattern) => pattern.test(text7));
|
|
1445
1454
|
}
|
|
1446
|
-
function
|
|
1447
|
-
return shouldSuppressWarningLine(line, state) || shouldSuppressDrizzleConfigBannerLine(line);
|
|
1448
|
-
}
|
|
1449
|
-
function filterWarningLines(output, state) {
|
|
1455
|
+
function filterNoiseLines(output, state) {
|
|
1450
1456
|
const lines = output.match(/[^\n]*\n|[^\n]+/g) ?? [];
|
|
1451
1457
|
return lines.filter((line) => !shouldSuppressOutputLine(line, state)).join("");
|
|
1452
1458
|
}
|
|
1453
|
-
function
|
|
1459
|
+
function couldBecomeSuppressible(partial, state) {
|
|
1460
|
+
if (state.suppressingPgSslWarning || state.suppressNextTraceHint) {
|
|
1461
|
+
return true;
|
|
1462
|
+
}
|
|
1463
|
+
const text7 = stripAnsi(partial);
|
|
1464
|
+
return SUPPRESSIBLE_LINE_STARTS.some((start) => text7.startsWith(start) || start.startsWith(text7));
|
|
1465
|
+
}
|
|
1466
|
+
function createDrizzleNoiseFilter(forward) {
|
|
1454
1467
|
const state = {
|
|
1455
1468
|
suppressingPgSslWarning: false,
|
|
1456
1469
|
suppressNextTraceHint: false
|
|
@@ -1460,24 +1473,27 @@ function createPgConnectionStringSslWarningFilter(write) {
|
|
|
1460
1473
|
write(chunk) {
|
|
1461
1474
|
buffer += chunk;
|
|
1462
1475
|
const lastNewlineIndex = buffer.lastIndexOf("\n");
|
|
1463
|
-
if (lastNewlineIndex
|
|
1464
|
-
|
|
1476
|
+
if (lastNewlineIndex !== -1) {
|
|
1477
|
+
const complete = buffer.slice(0, lastNewlineIndex + 1);
|
|
1478
|
+
buffer = buffer.slice(lastNewlineIndex + 1);
|
|
1479
|
+
const filtered = filterNoiseLines(complete, state);
|
|
1480
|
+
if (filtered) {
|
|
1481
|
+
forward(filtered);
|
|
1482
|
+
}
|
|
1465
1483
|
}
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
if (filtered) {
|
|
1470
|
-
write(filtered);
|
|
1484
|
+
if (buffer && !couldBecomeSuppressible(buffer, state)) {
|
|
1485
|
+
forward(buffer);
|
|
1486
|
+
buffer = "";
|
|
1471
1487
|
}
|
|
1472
1488
|
},
|
|
1473
1489
|
end() {
|
|
1474
1490
|
if (!buffer) {
|
|
1475
1491
|
return;
|
|
1476
1492
|
}
|
|
1477
|
-
const filtered =
|
|
1493
|
+
const filtered = filterNoiseLines(buffer, state);
|
|
1478
1494
|
buffer = "";
|
|
1479
1495
|
if (filtered) {
|
|
1480
|
-
|
|
1496
|
+
forward(filtered);
|
|
1481
1497
|
}
|
|
1482
1498
|
}
|
|
1483
1499
|
};
|
|
@@ -1487,20 +1503,20 @@ function runDrizzlePush(cwd, options = {}) {
|
|
|
1487
1503
|
const drizzleBin = path9.join(cwd, "node_modules", ".bin", "drizzle-kit");
|
|
1488
1504
|
const child = spawn2(drizzleBin, ["push", "--force"], {
|
|
1489
1505
|
cwd,
|
|
1490
|
-
stdio: resolveDrizzlePushStdio(options.
|
|
1506
|
+
stdio: resolveDrizzlePushStdio(options.interactive),
|
|
1491
1507
|
env: { ...process.env }
|
|
1492
1508
|
});
|
|
1493
1509
|
let stdout = "";
|
|
1494
1510
|
let stderr = "";
|
|
1495
|
-
const stderrFilter =
|
|
1496
|
-
if (options.
|
|
1511
|
+
const stderrFilter = createDrizzleNoiseFilter((chunk) => {
|
|
1512
|
+
if (options.interactive) {
|
|
1497
1513
|
process.stderr.write(chunk);
|
|
1498
1514
|
return;
|
|
1499
1515
|
}
|
|
1500
1516
|
stderr += chunk;
|
|
1501
1517
|
});
|
|
1502
|
-
const stdoutFilter =
|
|
1503
|
-
if (options.
|
|
1518
|
+
const stdoutFilter = createDrizzleNoiseFilter((chunk) => {
|
|
1519
|
+
if (options.interactive) {
|
|
1504
1520
|
process.stdout.write(chunk);
|
|
1505
1521
|
return;
|
|
1506
1522
|
}
|
|
@@ -1515,7 +1531,7 @@ function runDrizzlePush(cwd, options = {}) {
|
|
|
1515
1531
|
child.on("close", (code, signal) => {
|
|
1516
1532
|
stdoutFilter.end();
|
|
1517
1533
|
stderrFilter.end();
|
|
1518
|
-
if (options.
|
|
1534
|
+
if (options.interactive) {
|
|
1519
1535
|
if (code === 0) {
|
|
1520
1536
|
resolve({ success: true, error: null });
|
|
1521
1537
|
return;
|
|
@@ -1733,7 +1749,7 @@ async function runPostGenerate(cwd, schemaName, options = {}) {
|
|
|
1733
1749
|
} else {
|
|
1734
1750
|
console.log("\n Running drizzle-kit push...");
|
|
1735
1751
|
try {
|
|
1736
|
-
const pushResult = await runDrizzlePush(cwd, {
|
|
1752
|
+
const pushResult = await runDrizzlePush(cwd, { interactive: true });
|
|
1737
1753
|
if (!pushResult.success) {
|
|
1738
1754
|
throw new Error(pushResult.error ?? "drizzle-kit push failed");
|
|
1739
1755
|
}
|
|
@@ -2856,6 +2872,8 @@ function resolveProjectPaths(config) {
|
|
|
2856
2872
|
const adminTypesDir = path14.posix.join(adminDir, "types");
|
|
2857
2873
|
const adminNavigationFile = path14.posix.join(adminDir, "data", "navigation.ts");
|
|
2858
2874
|
const adminNavigationDir = path14.posix.join(adminDir, "data", "navigation");
|
|
2875
|
+
const adminWebhookEventsFile = path14.posix.join(adminDir, "data", "webhook-events.ts");
|
|
2876
|
+
const adminWebhookEventsDir = path14.posix.join(adminDir, "data", "webhook-events");
|
|
2859
2877
|
const adminActionsDir = path14.posix.join(adminDir, "lib", "actions");
|
|
2860
2878
|
return {
|
|
2861
2879
|
adminDir,
|
|
@@ -2872,6 +2890,8 @@ function resolveProjectPaths(config) {
|
|
|
2872
2890
|
adminTypesNavigationFile: path14.posix.join(adminTypesDir, "navigation.ts"),
|
|
2873
2891
|
adminNavigationFile,
|
|
2874
2892
|
adminNavigationDir,
|
|
2893
|
+
adminWebhookEventsFile,
|
|
2894
|
+
adminWebhookEventsDir,
|
|
2875
2895
|
adminActionsDir,
|
|
2876
2896
|
adminEmailTemplatesDir: path14.posix.join(adminDir, "components", "email-templates"),
|
|
2877
2897
|
adminHooksDir: path14.posix.join(adminDir, "hooks")
|
|
@@ -6322,6 +6342,22 @@ function lifecycleHookContextExample(event, schemaName, input, data, schemaType
|
|
|
6322
6342
|
if (schemaType === "form") {
|
|
6323
6343
|
context.schemaType = "form";
|
|
6324
6344
|
}
|
|
6345
|
+
if (event === "beforeRestore" || event === "afterRestore") {
|
|
6346
|
+
context.entityId = SAMPLE_UUID;
|
|
6347
|
+
context.changedFields = [];
|
|
6348
|
+
context.metadata = { restoredFromVersion: 2 };
|
|
6349
|
+
if (phase === "after") {
|
|
6350
|
+
context.data = data;
|
|
6351
|
+
}
|
|
6352
|
+
return createExample("Context", context);
|
|
6353
|
+
}
|
|
6354
|
+
if (event === "beforeReorder" || event === "afterReorder") {
|
|
6355
|
+
context.changedFields = ["sortOrder"];
|
|
6356
|
+
if (phase === "after") {
|
|
6357
|
+
context.data = { order: [{ id: SAMPLE_UUID, sortOrder: 0 }] };
|
|
6358
|
+
}
|
|
6359
|
+
return createExample("Context", context);
|
|
6360
|
+
}
|
|
6325
6361
|
if (event !== "beforeCreate" && event !== "afterCreate") {
|
|
6326
6362
|
context.entityId = SAMPLE_UUID;
|
|
6327
6363
|
}
|
|
@@ -6348,7 +6384,11 @@ function buildEntityDevModeLifecycleHooks(schema, adminImportAlias) {
|
|
|
6348
6384
|
"beforeUpdate",
|
|
6349
6385
|
"afterUpdate",
|
|
6350
6386
|
"beforeDelete",
|
|
6351
|
-
"afterDelete"
|
|
6387
|
+
"afterDelete",
|
|
6388
|
+
"beforeRestore",
|
|
6389
|
+
"afterRestore",
|
|
6390
|
+
"beforeReorder",
|
|
6391
|
+
"afterReorder"
|
|
6352
6392
|
];
|
|
6353
6393
|
if (schema.actions?.draft === true) {
|
|
6354
6394
|
events.push("beforePublish", "afterPublish", "beforeUnpublish", "afterUnpublish");
|
|
@@ -6896,7 +6936,7 @@ function generatePageSkeleton(pascal, label) {
|
|
|
6896
6936
|
return `export function ${pascal}SubmissionsPageSkeleton() {
|
|
6897
6937
|
return (
|
|
6898
6938
|
<div className="flex items-center justify-center h-48">
|
|
6899
|
-
<div className="text-muted-foreground">Loading ${label}
|
|
6939
|
+
<div className="text-muted-foreground">Loading ${label}\u2026</div>
|
|
6900
6940
|
</div>
|
|
6901
6941
|
)
|
|
6902
6942
|
}
|
|
@@ -7059,7 +7099,7 @@ ${deleteTransition}${bulkDeleteHandler}
|
|
|
7059
7099
|
<div className="flex items-center gap-1">
|
|
7060
7100
|
<${devModeIntegrateButtonExportName} initialSettings={initialSettings} />${exportButton}
|
|
7061
7101
|
<Button variant="outline" asChild>
|
|
7062
|
-
<Link href="${adminRoutePath}/forms
|
|
7102
|
+
<Link href="${adminRoutePath}/settings/forms">
|
|
7063
7103
|
<Settings className="size-3.5" />
|
|
7064
7104
|
Settings
|
|
7065
7105
|
</Link>
|
|
@@ -7105,199 +7145,6 @@ ${bulkDeleteActions}
|
|
|
7105
7145
|
`;
|
|
7106
7146
|
}
|
|
7107
7147
|
|
|
7108
|
-
// adapters/next/generators/form-admin/admin-settings-page.ts
|
|
7109
|
-
function generateSettingsPage(pascal, kebab) {
|
|
7110
|
-
return `import { getFormSettings } from '@admin/actions/forms'
|
|
7111
|
-
import { ${pascal}SettingsPageContent } from './settings-page-content'
|
|
7112
|
-
|
|
7113
|
-
export default async function ${pascal}SettingsPage() {
|
|
7114
|
-
const settings = await getFormSettings('${kebab}')
|
|
7115
|
-
|
|
7116
|
-
return <${pascal}SettingsPageContent initialSettings={settings} />
|
|
7117
|
-
}
|
|
7118
|
-
`;
|
|
7119
|
-
}
|
|
7120
|
-
function generateSettingsPageContent(pascal, kebab, label) {
|
|
7121
|
-
return `'use client'
|
|
7122
|
-
|
|
7123
|
-
import {
|
|
7124
|
-
testFormWebhook,
|
|
7125
|
-
type FormSettingsData,
|
|
7126
|
-
upsertFormSettings,
|
|
7127
|
-
} from '@admin/actions/forms'
|
|
7128
|
-
import { PageHeader } from '@admin/components/shared/page-header'
|
|
7129
|
-
import { Button } from '@admin/components/ui/button'
|
|
7130
|
-
import {
|
|
7131
|
-
Form,
|
|
7132
|
-
FormControl,
|
|
7133
|
-
FormDescription,
|
|
7134
|
-
FormField,
|
|
7135
|
-
FormItem,
|
|
7136
|
-
FormLabel,
|
|
7137
|
-
} from '@admin/components/ui/form'
|
|
7138
|
-
import { Input } from '@admin/components/ui/input'
|
|
7139
|
-
import { Switch } from '@admin/components/ui/switch'
|
|
7140
|
-
import { Textarea } from '@admin/components/ui/textarea'
|
|
7141
|
-
import { LoaderCircle } from 'lucide-react'
|
|
7142
|
-
import * as React from 'react'
|
|
7143
|
-
import { useForm } from 'react-hook-form'
|
|
7144
|
-
import { toast } from 'sonner'
|
|
7145
|
-
|
|
7146
|
-
interface ${pascal}SettingsPageContentProps {
|
|
7147
|
-
initialSettings: FormSettingsData | null
|
|
7148
|
-
}
|
|
7149
|
-
|
|
7150
|
-
interface ${pascal}SettingsFormValues {
|
|
7151
|
-
notificationEmails: string
|
|
7152
|
-
webhookUrl: string
|
|
7153
|
-
webhookEnabled: boolean
|
|
7154
|
-
}
|
|
7155
|
-
|
|
7156
|
-
export function ${pascal}SettingsPageContent({
|
|
7157
|
-
initialSettings,
|
|
7158
|
-
}: ${pascal}SettingsPageContentProps) {
|
|
7159
|
-
const form = useForm<${pascal}SettingsFormValues>({
|
|
7160
|
-
defaultValues: {
|
|
7161
|
-
notificationEmails: initialSettings?.notificationEmails ?? '',
|
|
7162
|
-
webhookUrl: initialSettings?.webhookUrl ?? '',
|
|
7163
|
-
webhookEnabled: initialSettings?.webhookEnabled ?? false,
|
|
7164
|
-
},
|
|
7165
|
-
})
|
|
7166
|
-
const [isSaving, startSaveTransition] = React.useTransition()
|
|
7167
|
-
const [isTesting, startTestTransition] = React.useTransition()
|
|
7168
|
-
const webhookUrl = form.watch('webhookUrl')
|
|
7169
|
-
const webhookEnabled = form.watch('webhookEnabled')
|
|
7170
|
-
|
|
7171
|
-
const handleSave = (values: ${pascal}SettingsFormValues) => {
|
|
7172
|
-
startSaveTransition(async () => {
|
|
7173
|
-
const result = await upsertFormSettings('${kebab}', {
|
|
7174
|
-
notificationEmails: values.notificationEmails || null,
|
|
7175
|
-
webhookUrl: values.webhookUrl || null,
|
|
7176
|
-
webhookEnabled: values.webhookEnabled,
|
|
7177
|
-
})
|
|
7178
|
-
if (result.success) {
|
|
7179
|
-
toast.success('Settings saved successfully')
|
|
7180
|
-
} else {
|
|
7181
|
-
toast.error(result.error || 'Failed to save settings')
|
|
7182
|
-
}
|
|
7183
|
-
})
|
|
7184
|
-
}
|
|
7185
|
-
|
|
7186
|
-
const handleTestWebhook = () => {
|
|
7187
|
-
startTestTransition(async () => {
|
|
7188
|
-
const result = await testFormWebhook('${kebab}')
|
|
7189
|
-
if (result.success) {
|
|
7190
|
-
toast.success('Test webhook sent successfully')
|
|
7191
|
-
} else {
|
|
7192
|
-
toast.error(result.error || 'Failed to send test webhook')
|
|
7193
|
-
}
|
|
7194
|
-
})
|
|
7195
|
-
}
|
|
7196
|
-
|
|
7197
|
-
return (
|
|
7198
|
-
<>
|
|
7199
|
-
<PageHeader title="${label} Settings" />
|
|
7200
|
-
<Form {...form}>
|
|
7201
|
-
<form
|
|
7202
|
-
onSubmit={form.handleSubmit(handleSave)}
|
|
7203
|
-
className="space-y-6 rounded-sm border p-6 mx-6 mt-6"
|
|
7204
|
-
>
|
|
7205
|
-
<FormField
|
|
7206
|
-
control={form.control}
|
|
7207
|
-
name="notificationEmails"
|
|
7208
|
-
render={({ field }) => (
|
|
7209
|
-
<FormItem>
|
|
7210
|
-
<FormLabel>Notification Emails</FormLabel>
|
|
7211
|
-
<FormControl>
|
|
7212
|
-
<Textarea
|
|
7213
|
-
placeholder="email@example.com, another@example.com"
|
|
7214
|
-
rows={3}
|
|
7215
|
-
{...field}
|
|
7216
|
-
/>
|
|
7217
|
-
</FormControl>
|
|
7218
|
-
<FormDescription>
|
|
7219
|
-
Comma-separated list of email addresses to notify on new submissions.
|
|
7220
|
-
</FormDescription>
|
|
7221
|
-
</FormItem>
|
|
7222
|
-
)}
|
|
7223
|
-
/>
|
|
7224
|
-
|
|
7225
|
-
<div className="space-y-4 border-t pt-6">
|
|
7226
|
-
<FormField
|
|
7227
|
-
control={form.control}
|
|
7228
|
-
name="webhookUrl"
|
|
7229
|
-
render={({ field }) => (
|
|
7230
|
-
<FormItem>
|
|
7231
|
-
<FormLabel>Webhook URL</FormLabel>
|
|
7232
|
-
<FormControl>
|
|
7233
|
-
<Input
|
|
7234
|
-
type="url"
|
|
7235
|
-
placeholder="https://hooks.example.com/endpoint"
|
|
7236
|
-
{...field}
|
|
7237
|
-
/>
|
|
7238
|
-
</FormControl>
|
|
7239
|
-
<FormDescription>
|
|
7240
|
-
Receive a POST request with form data on each submission.
|
|
7241
|
-
</FormDescription>
|
|
7242
|
-
</FormItem>
|
|
7243
|
-
)}
|
|
7244
|
-
/>
|
|
7245
|
-
|
|
7246
|
-
<FormField
|
|
7247
|
-
control={form.control}
|
|
7248
|
-
name="webhookEnabled"
|
|
7249
|
-
render={({ field }) => (
|
|
7250
|
-
<FormItem className="flex flex-row items-center space-x-2 space-y-0">
|
|
7251
|
-
<FormControl>
|
|
7252
|
-
<Switch
|
|
7253
|
-
checked={field.value}
|
|
7254
|
-
onCheckedChange={field.onChange}
|
|
7255
|
-
/>
|
|
7256
|
-
</FormControl>
|
|
7257
|
-
<FormLabel>Enable Webhook</FormLabel>
|
|
7258
|
-
</FormItem>
|
|
7259
|
-
)}
|
|
7260
|
-
/>
|
|
7261
|
-
|
|
7262
|
-
{webhookUrl && webhookEnabled && (
|
|
7263
|
-
<Button
|
|
7264
|
-
type="button"
|
|
7265
|
-
variant="outline"
|
|
7266
|
-
onClick={handleTestWebhook}
|
|
7267
|
-
disabled={isTesting}
|
|
7268
|
-
>
|
|
7269
|
-
{isTesting ? (
|
|
7270
|
-
<>
|
|
7271
|
-
<LoaderCircle className="animate-spin" />
|
|
7272
|
-
Sending...
|
|
7273
|
-
</>
|
|
7274
|
-
) : (
|
|
7275
|
-
'Test Webhook'
|
|
7276
|
-
)}
|
|
7277
|
-
</Button>
|
|
7278
|
-
)}
|
|
7279
|
-
</div>
|
|
7280
|
-
|
|
7281
|
-
<div className="border-t pt-6">
|
|
7282
|
-
<Button type="submit" disabled={isSaving}>
|
|
7283
|
-
{isSaving ? (
|
|
7284
|
-
<>
|
|
7285
|
-
<LoaderCircle className="animate-spin" />
|
|
7286
|
-
Saving...
|
|
7287
|
-
</>
|
|
7288
|
-
) : (
|
|
7289
|
-
'Save Settings'
|
|
7290
|
-
)}
|
|
7291
|
-
</Button>
|
|
7292
|
-
</div>
|
|
7293
|
-
</form>
|
|
7294
|
-
</Form>
|
|
7295
|
-
</>
|
|
7296
|
-
)
|
|
7297
|
-
}
|
|
7298
|
-
`;
|
|
7299
|
-
}
|
|
7300
|
-
|
|
7301
7148
|
// adapters/next/generators/form-admin/admin-submission-drawer.ts
|
|
7302
7149
|
function generateSubmissionDrawer(pascal, kebab, fields, label, includeDynamic, _actionImportPath) {
|
|
7303
7150
|
const fieldItems = fields.filter((f) => f.name).map((f) => {
|
|
@@ -7428,7 +7275,7 @@ export function ${pascal}SubmissionDrawer({
|
|
|
7428
7275
|
</DrawerHeader>
|
|
7429
7276
|
<ScrollArea className="min-h-0 flex-1">
|
|
7430
7277
|
{isPending ? (
|
|
7431
|
-
<div className="p-4 text-sm text-muted-foreground">Loading submission
|
|
7278
|
+
<div className="p-4 text-sm text-muted-foreground">Loading submission\u2026</div>
|
|
7432
7279
|
) : error ? (
|
|
7433
7280
|
<div className="p-4 text-sm text-destructive">
|
|
7434
7281
|
Error loading submission: {error.message}
|
|
@@ -7468,7 +7315,6 @@ import {
|
|
|
7468
7315
|
DataGridRow
|
|
7469
7316
|
} from '@admin/components/shared/data-table/data-grid'
|
|
7470
7317
|
import { DataTablePagination } from '@admin/components/shared/data-table/data-table-pagination'
|
|
7471
|
-
import { Card, CardContent } from '@admin/components/ui/card'
|
|
7472
7318
|
import { use${pascal}Submissions } from '@admin/hooks/use-${kebab}-form'
|
|
7473
7319
|
import { useTableUtils } from '@admin/hooks/use-table-utils'
|
|
7474
7320
|
import {
|
|
@@ -7602,108 +7448,104 @@ export function ${pascal}SubmissionsTable<TValue>({
|
|
|
7602
7448
|
|
|
7603
7449
|
return (
|
|
7604
7450
|
<div className={cn("flex flex-col gap-6 pt-px pb-2 h-full", className)}>
|
|
7605
|
-
<
|
|
7606
|
-
|
|
7607
|
-
|
|
7608
|
-
<
|
|
7609
|
-
{
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
'text-center': meta?.align === 'center',
|
|
7621
|
-
'text-right': meta?.align === 'right'
|
|
7622
|
-
})}
|
|
7623
|
-
data-column-id={header.column.id}
|
|
7624
|
-
onMouseEnter={() => setHoveredColumnId(header.column.id)}
|
|
7625
|
-
onMouseLeave={() => setHoveredColumnId((current) => (current === header.column.id ? null : current))}
|
|
7626
|
-
>
|
|
7627
|
-
{header.isPlaceholder
|
|
7628
|
-
? null
|
|
7629
|
-
: flexRender(header.column.columnDef.header, header.getContext())}
|
|
7630
|
-
{canResizeColumn ? (
|
|
7631
|
-
<button
|
|
7632
|
-
type="button"
|
|
7633
|
-
aria-label={\`Resize \${resizeLabel} column\`}
|
|
7634
|
-
className="group/resize-handle absolute right-0 top-0 z-10 flex h-full w-5 cursor-col-resize touch-none select-none items-center justify-center text-muted-foreground opacity-0 transition-opacity hover:text-foreground focus-visible:text-foreground focus-visible:opacity-100 focus-visible:outline-none group-focus-within/resize-header:opacity-100 data-[column-hovered=true]:opacity-100 data-[resizing=true]:opacity-100"
|
|
7635
|
-
data-resize-handle
|
|
7636
|
-
data-column-hovered={hoveredColumnId === header.column.id ? 'true' : 'false'}
|
|
7637
|
-
data-resizing={header.column.getIsResizing() ? 'true' : 'false'}
|
|
7638
|
-
onDoubleClick={resetColumnSizingToContainer}
|
|
7639
|
-
onMouseDown={header.getResizeHandler()}
|
|
7640
|
-
onTouchStart={header.getResizeHandler()}
|
|
7641
|
-
>
|
|
7642
|
-
<GripVertical aria-hidden="true" className={cn('size-3.5', { 'text-ring': header.column.getIsResizing() })} />
|
|
7643
|
-
</button>
|
|
7644
|
-
) : null}
|
|
7645
|
-
</DataGridHead>
|
|
7646
|
-
)
|
|
7647
|
-
})}
|
|
7648
|
-
</DataGridRow>
|
|
7649
|
-
))}
|
|
7650
|
-
</DataGridHeader>
|
|
7651
|
-
<DataGridBody>
|
|
7652
|
-
{isPending ? (
|
|
7653
|
-
<DataGridRow>
|
|
7654
|
-
<DataGridCell className="flex h-24 items-center justify-center text-center" style={{ gridColumn: '1 / -1' }}>
|
|
7655
|
-
<div className="text-muted-foreground">Loading ${label} submissions...</div>
|
|
7656
|
-
</DataGridCell>
|
|
7657
|
-
</DataGridRow>
|
|
7658
|
-
) : error ? (
|
|
7659
|
-
<DataGridRow>
|
|
7660
|
-
<DataGridCell className="flex h-24 items-center justify-center text-center" style={{ gridColumn: '1 / -1' }}>
|
|
7661
|
-
<div className="text-destructive">Error loading ${label} submissions: {error.message}</div>
|
|
7662
|
-
</DataGridCell>
|
|
7663
|
-
</DataGridRow>
|
|
7664
|
-
) : table.getRowModel().rows?.length ? (
|
|
7665
|
-
table.getRowModel().rows.map((row) => (
|
|
7666
|
-
<DataGridRow
|
|
7667
|
-
key={row.id}
|
|
7668
|
-
data-state={row.getIsSelected() ? 'selected' : undefined}
|
|
7669
|
-
className="cursor-pointer hover:bg-muted/50"
|
|
7670
|
-
onClick={(e) => {
|
|
7671
|
-
const target = e.target as HTMLElement
|
|
7672
|
-
if (!e.currentTarget.contains(target)) return
|
|
7673
|
-
if (target.closest('button, a, input, [role="checkbox"]')) return
|
|
7674
|
-
onViewSubmission(row.original.id)
|
|
7675
|
-
}}
|
|
7676
|
-
>
|
|
7677
|
-
{row.getVisibleCells().map((cell) => {
|
|
7678
|
-
const meta = cell.column.columnDef.meta as Record<string, unknown> | undefined
|
|
7679
|
-
return (
|
|
7680
|
-
<DataGridCell
|
|
7681
|
-
key={cell.id}
|
|
7682
|
-
className={cn({
|
|
7683
|
-
'text-center': meta?.align === 'center',
|
|
7684
|
-
'text-right': meta?.align === 'right'
|
|
7685
|
-
})}
|
|
7686
|
-
data-column-id={cell.column.id}
|
|
7687
|
-
onMouseEnter={() => setHoveredColumnId(cell.column.id)}
|
|
7688
|
-
onMouseLeave={() => setHoveredColumnId((current) => (current === cell.column.id ? null : current))}
|
|
7689
|
-
>
|
|
7690
|
-
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
7691
|
-
</DataGridCell>
|
|
7692
|
-
)
|
|
7451
|
+
<DataGrid containerClassName="min-h-0 flex-1" containerRef={tableContainerRef} gridTemplateColumns={gridTemplateColumns} style={{ width: table.getTotalSize() }}>
|
|
7452
|
+
<DataGridHeader>
|
|
7453
|
+
{table.getHeaderGroups().map((headerGroup) => (
|
|
7454
|
+
<DataGridRow key={headerGroup.id}>
|
|
7455
|
+
{headerGroup.headers.map((header, headerIndex) => {
|
|
7456
|
+
const meta = header.column.columnDef.meta as Record<string, unknown> | undefined
|
|
7457
|
+
const resizeLabel = typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : header.column.id
|
|
7458
|
+
const nextHeader = headerGroup.headers[headerIndex + 1]
|
|
7459
|
+
const canResizeColumn = header.column.getCanResize() && nextHeader?.column.getCanResize() === true
|
|
7460
|
+
return (
|
|
7461
|
+
<DataGridHead
|
|
7462
|
+
key={header.id}
|
|
7463
|
+
className={cn('group/resize-header relative overflow-hidden', {
|
|
7464
|
+
'text-center': meta?.align === 'center',
|
|
7465
|
+
'text-right': meta?.align === 'right'
|
|
7693
7466
|
})}
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
|
|
7705
|
-
|
|
7706
|
-
|
|
7467
|
+
data-column-id={header.column.id}
|
|
7468
|
+
onMouseEnter={() => setHoveredColumnId(header.column.id)}
|
|
7469
|
+
onMouseLeave={() => setHoveredColumnId((current) => (current === header.column.id ? null : current))}
|
|
7470
|
+
>
|
|
7471
|
+
{header.isPlaceholder
|
|
7472
|
+
? null
|
|
7473
|
+
: flexRender(header.column.columnDef.header, header.getContext())}
|
|
7474
|
+
{canResizeColumn ? (
|
|
7475
|
+
<button
|
|
7476
|
+
type="button"
|
|
7477
|
+
aria-label={\`Resize \${resizeLabel} column\`}
|
|
7478
|
+
className="group/resize-handle absolute right-0 top-0 z-10 flex h-full w-5 cursor-col-resize touch-none select-none items-center justify-center text-muted-foreground opacity-0 transition-opacity hover:text-foreground focus-visible:text-foreground focus-visible:opacity-100 focus-visible:outline-none group-focus-within/resize-header:opacity-100 data-[column-hovered=true]:opacity-100 data-[resizing=true]:opacity-100"
|
|
7479
|
+
data-resize-handle
|
|
7480
|
+
data-column-hovered={hoveredColumnId === header.column.id ? 'true' : 'false'}
|
|
7481
|
+
data-resizing={header.column.getIsResizing() ? 'true' : 'false'}
|
|
7482
|
+
onDoubleClick={resetColumnSizingToContainer}
|
|
7483
|
+
onMouseDown={header.getResizeHandler()}
|
|
7484
|
+
onTouchStart={header.getResizeHandler()}
|
|
7485
|
+
>
|
|
7486
|
+
<GripVertical aria-hidden="true" className={cn('size-3.5', { 'text-ring': header.column.getIsResizing() })} />
|
|
7487
|
+
</button>
|
|
7488
|
+
) : null}
|
|
7489
|
+
</DataGridHead>
|
|
7490
|
+
)
|
|
7491
|
+
})}
|
|
7492
|
+
</DataGridRow>
|
|
7493
|
+
))}
|
|
7494
|
+
</DataGridHeader>
|
|
7495
|
+
<DataGridBody>
|
|
7496
|
+
{isPending ? (
|
|
7497
|
+
<DataGridRow>
|
|
7498
|
+
<DataGridCell className="flex h-24 items-center justify-center text-center" style={{ gridColumn: '1 / -1' }}>
|
|
7499
|
+
<div className="text-muted-foreground">Loading ${label} submissions\u2026</div>
|
|
7500
|
+
</DataGridCell>
|
|
7501
|
+
</DataGridRow>
|
|
7502
|
+
) : error ? (
|
|
7503
|
+
<DataGridRow>
|
|
7504
|
+
<DataGridCell className="flex h-24 items-center justify-center text-center" style={{ gridColumn: '1 / -1' }}>
|
|
7505
|
+
<div className="text-destructive">Error loading ${label} submissions: {error.message}</div>
|
|
7506
|
+
</DataGridCell>
|
|
7507
|
+
</DataGridRow>
|
|
7508
|
+
) : table.getRowModel().rows?.length ? (
|
|
7509
|
+
table.getRowModel().rows.map((row) => (
|
|
7510
|
+
<DataGridRow
|
|
7511
|
+
key={row.id}
|
|
7512
|
+
data-state={row.getIsSelected() ? 'selected' : undefined}
|
|
7513
|
+
className="cursor-pointer hover:bg-muted/50"
|
|
7514
|
+
onClick={(e) => {
|
|
7515
|
+
const target = e.target as HTMLElement
|
|
7516
|
+
if (!e.currentTarget.contains(target)) return
|
|
7517
|
+
if (target.closest('button, a, input, [role="checkbox"]')) return
|
|
7518
|
+
onViewSubmission(row.original.id)
|
|
7519
|
+
}}
|
|
7520
|
+
>
|
|
7521
|
+
{row.getVisibleCells().map((cell) => {
|
|
7522
|
+
const meta = cell.column.columnDef.meta as Record<string, unknown> | undefined
|
|
7523
|
+
return (
|
|
7524
|
+
<DataGridCell
|
|
7525
|
+
key={cell.id}
|
|
7526
|
+
className={cn({
|
|
7527
|
+
'text-center': meta?.align === 'center',
|
|
7528
|
+
'text-right': meta?.align === 'right'
|
|
7529
|
+
})}
|
|
7530
|
+
data-column-id={cell.column.id}
|
|
7531
|
+
onMouseEnter={() => setHoveredColumnId(cell.column.id)}
|
|
7532
|
+
onMouseLeave={() => setHoveredColumnId((current) => (current === cell.column.id ? null : current))}
|
|
7533
|
+
>
|
|
7534
|
+
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
7535
|
+
</DataGridCell>
|
|
7536
|
+
)
|
|
7537
|
+
})}
|
|
7538
|
+
</DataGridRow>
|
|
7539
|
+
))
|
|
7540
|
+
) : (
|
|
7541
|
+
<DataGridRow>
|
|
7542
|
+
<DataGridCell className="flex h-24 items-center justify-center text-center" style={{ gridColumn: '1 / -1' }}>
|
|
7543
|
+
No ${label} submissions found.
|
|
7544
|
+
</DataGridCell>
|
|
7545
|
+
</DataGridRow>
|
|
7546
|
+
)}
|
|
7547
|
+
</DataGridBody>
|
|
7548
|
+
</DataGrid>
|
|
7707
7549
|
|
|
7708
7550
|
{shouldShowPagination ? (
|
|
7709
7551
|
<DataTablePagination
|
|
@@ -7812,14 +7654,6 @@ function generateFormAdminPages(schema, pagesDir, options) {
|
|
|
7812
7654
|
hasDynamicFields(schema),
|
|
7813
7655
|
actionImportPath
|
|
7814
7656
|
)
|
|
7815
|
-
),
|
|
7816
|
-
createGeneratedFile(
|
|
7817
|
-
`${pagesDir}/forms/${kebab}/settings/page.tsx`,
|
|
7818
|
-
generateSettingsPage(pascal, kebab)
|
|
7819
|
-
),
|
|
7820
|
-
createGeneratedFile(
|
|
7821
|
-
`${pagesDir}/forms/${kebab}/settings/settings-page-content.tsx`,
|
|
7822
|
-
generateSettingsPageContent(pascal, kebab, schema.label)
|
|
7823
7657
|
)
|
|
7824
7658
|
]
|
|
7825
7659
|
};
|
|
@@ -8227,7 +8061,6 @@ import { ${tableName} } from '@admin/db/schema'
|
|
|
8227
8061
|
import { getFormSettings } from '@admin/actions/forms'
|
|
8228
8062
|
import { sendFormEmails } from '@admin/actions/email/form-delivery'
|
|
8229
8063
|
import { getTouchedFieldNames } from '@admin/utils/audit/audit'
|
|
8230
|
-
import { sendWebhook } from '@admin/utils/webhook/webhook'
|
|
8231
8064
|
import { ${cacheInvalidationFn} } from 'next/cache'
|
|
8232
8065
|
${mailchimpImport}
|
|
8233
8066
|
import { CACHE_TAG, CACHE_TAG_BY_ID } from './types'
|
|
@@ -8268,16 +8101,7 @@ export async function create${pascal}Submission(
|
|
|
8268
8101
|
submitterEmail: ${submitterEmailField ? `data.${submitterEmailField}` : "null"},
|
|
8269
8102
|
submissionData: { ...data },
|
|
8270
8103
|
submittedAt: created${pascal}Submission.submittedAt,
|
|
8271
|
-
})
|
|
8272
|
-
|
|
8273
|
-
if (settings?.webhookEnabled && settings?.webhookUrl) {
|
|
8274
|
-
sendWebhook(settings.webhookUrl, {
|
|
8275
|
-
form_name: '${formName}',
|
|
8276
|
-
submission_id: created${pascal}Submission.id,
|
|
8277
|
-
...data,
|
|
8278
|
-
submitted_at: created${pascal}Submission.submittedAt,
|
|
8279
|
-
})
|
|
8280
|
-
}${mailchimpCall}
|
|
8104
|
+
})${mailchimpCall}
|
|
8281
8105
|
|
|
8282
8106
|
${cacheInvalidationFn}(CACHE_TAG)
|
|
8283
8107
|
${cacheInvalidationFn}(CACHE_TAG_BY_ID(created${pascal}Submission.id))
|
|
@@ -8792,6 +8616,58 @@ function namespaceGeneratedFiles(files, namespace) {
|
|
|
8792
8616
|
}));
|
|
8793
8617
|
}
|
|
8794
8618
|
|
|
8619
|
+
// adapters/next/generators/webhook-events.ts
|
|
8620
|
+
var NO_WEBHOOK_SCHEMAS = /* @__PURE__ */ new Set(["settings"]);
|
|
8621
|
+
function renderExtract(schemaName, kind, label, events, settingsKey) {
|
|
8622
|
+
const lines = [
|
|
8623
|
+
` schema: '${schemaName}'`,
|
|
8624
|
+
` kind: '${kind}'`,
|
|
8625
|
+
` label: ${JSON.stringify(label)}`,
|
|
8626
|
+
` events: [${events.map((event) => `'${event}'`).join(", ")}]`
|
|
8627
|
+
];
|
|
8628
|
+
if (settingsKey) {
|
|
8629
|
+
lines.push(` settingsKey: '${settingsKey}'`);
|
|
8630
|
+
}
|
|
8631
|
+
return `import type { WebhookEventSource } from '@admin/types/webhooks'
|
|
8632
|
+
|
|
8633
|
+
export const ${toCamelCase(schemaName)}WebhookEvents: WebhookEventSource = {
|
|
8634
|
+
${lines.join(",\n")}
|
|
8635
|
+
}
|
|
8636
|
+
`;
|
|
8637
|
+
}
|
|
8638
|
+
function updateWebhookEvents(schema, webhookEventsDir, kind) {
|
|
8639
|
+
if (NO_WEBHOOK_SCHEMAS.has(schema.name)) {
|
|
8640
|
+
return { files: [] };
|
|
8641
|
+
}
|
|
8642
|
+
const events = kind === "single" ? [`${schema.name}.updated`] : [
|
|
8643
|
+
`${schema.name}.created`,
|
|
8644
|
+
`${schema.name}.updated`,
|
|
8645
|
+
`${schema.name}.deleted`,
|
|
8646
|
+
...schema.actions?.draft === true ? [`${schema.name}.published`, `${schema.name}.unpublished`] : [],
|
|
8647
|
+
`${schema.name}.restored`,
|
|
8648
|
+
`${schema.name}.reordered`
|
|
8649
|
+
];
|
|
8650
|
+
return {
|
|
8651
|
+
files: [
|
|
8652
|
+
createGeneratedFile(
|
|
8653
|
+
`${webhookEventsDir}/${schema.name}.ts`,
|
|
8654
|
+
renderExtract(schema.name, kind, schema.label, events)
|
|
8655
|
+
)
|
|
8656
|
+
]
|
|
8657
|
+
};
|
|
8658
|
+
}
|
|
8659
|
+
function updateFormWebhookEvents(schema, webhookEventsDir) {
|
|
8660
|
+
const kebabName = toKebabCase(schema.name);
|
|
8661
|
+
return {
|
|
8662
|
+
files: [
|
|
8663
|
+
createGeneratedFile(
|
|
8664
|
+
`${webhookEventsDir}/${schema.name}.ts`,
|
|
8665
|
+
renderExtract(schema.name, "form", schema.label, [`form.${kebabName}.submitted`], kebabName)
|
|
8666
|
+
)
|
|
8667
|
+
]
|
|
8668
|
+
};
|
|
8669
|
+
}
|
|
8670
|
+
|
|
8795
8671
|
// adapters/next/generators/form-pipeline/pipeline.ts
|
|
8796
8672
|
function runFormPipeline(schema, cwd, config, options = {}) {
|
|
8797
8673
|
const paths = resolveProjectPaths(config);
|
|
@@ -8831,6 +8707,10 @@ function runFormPipeline(schema, cwd, config, options = {}) {
|
|
|
8831
8707
|
{
|
|
8832
8708
|
name: "Navigation",
|
|
8833
8709
|
run: () => updateFormNavigation(schema, paths.adminNavigationDir, namespacedOptions).files
|
|
8710
|
+
},
|
|
8711
|
+
{
|
|
8712
|
+
name: "Webhook events",
|
|
8713
|
+
run: () => updateFormWebhookEvents(schema, paths.adminWebhookEventsDir).files
|
|
8834
8714
|
}
|
|
8835
8715
|
];
|
|
8836
8716
|
for (let i = 0; i < steps.length; i++) {
|
|
@@ -9839,6 +9719,13 @@ function buildRestoreManyToManyStatements(ctx) {
|
|
|
9839
9719
|
}
|
|
9840
9720
|
function genRestoreContent(ctx) {
|
|
9841
9721
|
const kebabSingular = toKebabCase(ctx.singular);
|
|
9722
|
+
const restoreContext = lifecycleContext(
|
|
9723
|
+
ctx.plural,
|
|
9724
|
+
`,
|
|
9725
|
+
entityId: versionRow.entityId,
|
|
9726
|
+
changedFields: [],
|
|
9727
|
+
metadata: { restoredFromVersion: versionRow.version }`
|
|
9728
|
+
);
|
|
9842
9729
|
const snapshotImport = ctx.hasM2M ? `build${ctx.Singular}VersionSnapshotWithRelationships` : `build${ctx.Singular}VersionSnapshot`;
|
|
9843
9730
|
const currentSnapshot = ctx.hasM2M ? `await build${ctx.Singular}VersionSnapshotWithRelationships(currentRow as unknown as ${ctx.Singular}, tx)` : `build${ctx.Singular}VersionSnapshot(currentRow as unknown as ${ctx.Singular})`;
|
|
9844
9731
|
const dbImports = [
|
|
@@ -9864,6 +9751,7 @@ import {
|
|
|
9864
9751
|
build${ctx.Singular}RestoreData,
|
|
9865
9752
|
${snapshotImport}
|
|
9866
9753
|
} from './helpers'
|
|
9754
|
+
${lifecycleHookImport()}
|
|
9867
9755
|
import type { ${ctx.Singular}UpdateResult, ${ctx.Singular} } from './types'
|
|
9868
9756
|
|
|
9869
9757
|
export async function restore${ctx.Singular}Version(
|
|
@@ -9885,6 +9773,9 @@ export async function restore${ctx.Singular}Version(
|
|
|
9885
9773
|
|
|
9886
9774
|
const versionData = versionRow.data as Record<string, unknown>
|
|
9887
9775
|
const restoreData = build${ctx.Singular}RestoreData(versionData)
|
|
9776
|
+
const auditRequestMetadata = await getAuditRequestMetadata()
|
|
9777
|
+
const lifecycleContext = ${restoreContext}
|
|
9778
|
+
${beforeHook("beforeRestore", "lifecycleContext")}
|
|
9888
9779
|
|
|
9889
9780
|
const result = await db.transaction(async (tx) => {
|
|
9890
9781
|
const [currentRow] = await tx
|
|
@@ -9916,6 +9807,13 @@ ${restoreM2M}
|
|
|
9916
9807
|
${ctx.cacheInvalidationFn}(${ctx.camelPlural}CacheTags.byId(versionRow.entityId))
|
|
9917
9808
|
${ctx.cacheInvalidationFn}(entityVersionsCacheTags.for('${ctx.plural}', versionRow.entityId))
|
|
9918
9809
|
const restored${ctx.Singular} = await get${ctx.Singular}ById(versionRow.entityId)
|
|
9810
|
+
${afterHook(
|
|
9811
|
+
"afterRestore",
|
|
9812
|
+
`{
|
|
9813
|
+
...lifecycleContext,
|
|
9814
|
+
data: (restored${ctx.Singular} ?? result[0]) as unknown as Record<string, unknown>
|
|
9815
|
+
}`
|
|
9816
|
+
)}
|
|
9919
9817
|
|
|
9920
9818
|
return {
|
|
9921
9819
|
success: true,
|
|
@@ -10128,14 +10026,20 @@ export async function delete${ctx.Singular}(id: string): Promise<${ctx.Singular}
|
|
|
10128
10026
|
${beforeHook("beforeDelete", "lifecycleContext")}
|
|
10129
10027
|
|
|
10130
10028
|
try {
|
|
10131
|
-
await db.transaction(async (tx) => {
|
|
10029
|
+
const [deletedRow] = await db.transaction(async (tx) => {
|
|
10132
10030
|
await deleteEntityVersions(tx, '${ctx.plural}', [id])
|
|
10133
|
-
|
|
10031
|
+
return tx.delete(${ctx.tableVar}).where(eq(${ctx.tableVar}.id, id)).returning()
|
|
10134
10032
|
})
|
|
10135
10033
|
${ctx.cacheInvalidationFn}(${ctx.camelPlural}CacheTags.all)
|
|
10136
10034
|
${ctx.cacheInvalidationFn}(${ctx.camelPlural}CacheTags.byId(id))
|
|
10137
10035
|
${ctx.cacheInvalidationFn}(entityVersionsCacheTags.for('${ctx.plural}', id))
|
|
10138
|
-
${afterHook(
|
|
10036
|
+
${afterHook(
|
|
10037
|
+
"afterDelete",
|
|
10038
|
+
`{
|
|
10039
|
+
...lifecycleContext,
|
|
10040
|
+
data: deletedRow as unknown as Record<string, unknown> | undefined
|
|
10041
|
+
}`
|
|
10042
|
+
)}
|
|
10139
10043
|
return { success: true }
|
|
10140
10044
|
} catch (error) {
|
|
10141
10045
|
console.error('Error deleting ${ctx.singular}:', error)
|
|
@@ -10179,17 +10083,26 @@ export async function deleteBulk${ctx.Plural}(ids: string[]): Promise<${ctx.Sing
|
|
|
10179
10083
|
}
|
|
10180
10084
|
|
|
10181
10085
|
try {
|
|
10182
|
-
await db.transaction(async (tx) => {
|
|
10086
|
+
const deletedRows = await db.transaction(async (tx) => {
|
|
10183
10087
|
await deleteEntityVersions(tx, '${ctx.plural}', ids)
|
|
10184
|
-
|
|
10088
|
+
return tx.delete(${ctx.tableVar}).where(inArray(${ctx.tableVar}.id, ids)).returning()
|
|
10185
10089
|
})
|
|
10090
|
+
const deletedRowsById = new Map(
|
|
10091
|
+
deletedRows.map((row) => [row.id, row as unknown as Record<string, unknown>])
|
|
10092
|
+
)
|
|
10186
10093
|
${ctx.cacheInvalidationFn}(${ctx.camelPlural}CacheTags.all)
|
|
10187
10094
|
for (const id of ids) {
|
|
10188
10095
|
${ctx.cacheInvalidationFn}(${ctx.camelPlural}CacheTags.byId(id))
|
|
10189
10096
|
${ctx.cacheInvalidationFn}(entityVersionsCacheTags.for('${ctx.plural}', id))
|
|
10190
10097
|
}
|
|
10191
10098
|
for (const lifecycleContext of lifecycleContexts) {
|
|
10192
|
-
${afterHook(
|
|
10099
|
+
${afterHook(
|
|
10100
|
+
"afterDelete",
|
|
10101
|
+
`{
|
|
10102
|
+
...lifecycleContext,
|
|
10103
|
+
data: deletedRowsById.get(lifecycleContext.entityId)
|
|
10104
|
+
}`
|
|
10105
|
+
)}
|
|
10193
10106
|
}
|
|
10194
10107
|
return { success: true }
|
|
10195
10108
|
} catch (error) {
|
|
@@ -10200,6 +10113,8 @@ export async function deleteBulk${ctx.Plural}(ids: string[]): Promise<${ctx.Sing
|
|
|
10200
10113
|
`;
|
|
10201
10114
|
}
|
|
10202
10115
|
function genBulkSortOrderContent(ctx) {
|
|
10116
|
+
const reorderContext = lifecycleContext(ctx.plural, `,
|
|
10117
|
+
changedFields: ['sortOrder']`);
|
|
10203
10118
|
return `'use server'
|
|
10204
10119
|
|
|
10205
10120
|
import db from '@admin/db'
|
|
@@ -10208,15 +10123,20 @@ import { ${ctx.tableVar} } from '@admin/db/schema'
|
|
|
10208
10123
|
import { asc, eq, notInArray } from 'drizzle-orm'
|
|
10209
10124
|
import { ${ctx.cacheInvalidationFn} } from 'next/cache'
|
|
10210
10125
|
import { ${ctx.camelPlural}CacheTags } from './types'
|
|
10126
|
+
${lifecycleHookImport()}
|
|
10211
10127
|
|
|
10212
10128
|
export async function bulkUpdate${ctx.Plural}SortOrder(
|
|
10213
10129
|
updates: Array<{ id: string; sortOrder: number }>
|
|
10214
10130
|
): Promise<{ success: boolean; error?: string }> {
|
|
10215
|
-
await requireRole([UserRole.ADMIN, UserRole.EDITOR])
|
|
10131
|
+
const actor = await requireRole([UserRole.ADMIN, UserRole.EDITOR])
|
|
10132
|
+
if (updates.length === 0) return { success: true }
|
|
10216
10133
|
|
|
10217
|
-
|
|
10218
|
-
|
|
10134
|
+
const now = new Date().toISOString()
|
|
10135
|
+
const auditRequestMetadata = await getAuditRequestMetadata()
|
|
10136
|
+
const lifecycleContext = ${reorderContext}
|
|
10137
|
+
${beforeHook("beforeReorder", "lifecycleContext")}
|
|
10219
10138
|
|
|
10139
|
+
try {
|
|
10220
10140
|
// Sort the provided items by their new position
|
|
10221
10141
|
const sorted = [...updates].sort((a, b) => a.sortOrder - b.sortOrder)
|
|
10222
10142
|
const updatedIds = sorted.map((u) => u.id)
|
|
@@ -10260,13 +10180,18 @@ export async function bulkUpdate${ctx.Plural}SortOrder(
|
|
|
10260
10180
|
}
|
|
10261
10181
|
|
|
10262
10182
|
// Renumber all items gap-free
|
|
10183
|
+
const appliedOrder = allIds
|
|
10184
|
+
.filter(Boolean)
|
|
10185
|
+
.map((id, index) => ({ id, sortOrder: index }))
|
|
10186
|
+
|
|
10263
10187
|
await Promise.all(
|
|
10264
|
-
|
|
10265
|
-
db.update(${ctx.tableVar}).set({ sortOrder
|
|
10188
|
+
appliedOrder.map(({ id, sortOrder }) =>
|
|
10189
|
+
db.update(${ctx.tableVar}).set({ sortOrder }).where(eq(${ctx.tableVar}.id, id))
|
|
10266
10190
|
)
|
|
10267
10191
|
)
|
|
10268
10192
|
|
|
10269
10193
|
${ctx.cacheInvalidationFn}(${ctx.camelPlural}CacheTags.all)
|
|
10194
|
+
${afterHook("afterReorder", "{ ...lifecycleContext, data: { order: appliedOrder } }")}
|
|
10270
10195
|
return { success: true }
|
|
10271
10196
|
} catch (error) {
|
|
10272
10197
|
console.error('Error bulk updating sort order:', error)
|
|
@@ -11628,7 +11553,7 @@ import { getAuditRequestMetadata } from '@admin/actions/audit/request-metadata'
|
|
|
11628
11553
|
import db from '@admin/db'
|
|
11629
11554
|
import { ${upsertDbImports.join(", ")} } from '@admin/db/schema'
|
|
11630
11555
|
import { eq } from 'drizzle-orm'
|
|
11631
|
-
import {
|
|
11556
|
+
import { runAfterHooks, runBeforeHooks } from '@admin/lib/lifecycle-hooks'
|
|
11632
11557
|
import { getChangedFieldNames, getTouchedFieldNames } from '@admin/utils/audit/audit'
|
|
11633
11558
|
import { ${cacheInvalidationFn} } from 'next/cache'
|
|
11634
11559
|
import { get${Singular} } from './get-${kebabSingular}'
|
|
@@ -11680,6 +11605,22 @@ ${htmlUpsertBlock}
|
|
|
11680
11605
|
? getChangedFieldNames(previousRow as unknown as Record<string, unknown>, processedData)
|
|
11681
11606
|
: getTouchedFieldNames(processedData)
|
|
11682
11607
|
|
|
11608
|
+
const lifecycleContext = {
|
|
11609
|
+
user: actor,
|
|
11610
|
+
entityType: '${schema.name}',
|
|
11611
|
+
schemaType: 'single' as const,
|
|
11612
|
+
auditCategory: '${auditCategory}' as const,
|
|
11613
|
+
timestamp: now,
|
|
11614
|
+
sourceType: 'admin_ui' as const,
|
|
11615
|
+
ipAddress: auditRequestMetadata.ipAddress,
|
|
11616
|
+
userAgent: auditRequestMetadata.userAgent,
|
|
11617
|
+
entityId: SINGLETON_ID,
|
|
11618
|
+
input: processedData,
|
|
11619
|
+
changedFields,
|
|
11620
|
+
targetLabel: ${JSON.stringify(schema.label)}
|
|
11621
|
+
}
|
|
11622
|
+
await runBeforeHooks(previousRow ? 'beforeUpdate' : 'beforeCreate', lifecycleContext)
|
|
11623
|
+
|
|
11683
11624
|
const result = await db.transaction(async (tx) => {
|
|
11684
11625
|
const rows = await tx
|
|
11685
11626
|
.insert(${tableVar})
|
|
@@ -11704,18 +11645,9 @@ ${m2mWriteStatements}
|
|
|
11704
11645
|
|
|
11705
11646
|
${cacheInvalidationFn}(${cacheTagsVar}.all)
|
|
11706
11647
|
const saved${Singular} = await get${Singular}()
|
|
11707
|
-
|
|
11708
|
-
|
|
11709
|
-
|
|
11710
|
-
targetType: '${schema.name}',
|
|
11711
|
-
targetId: SINGLETON_ID,
|
|
11712
|
-
targetLabel: ${JSON.stringify(schema.label)},
|
|
11713
|
-
user: actor,
|
|
11714
|
-
timestamp: now,
|
|
11715
|
-
sourceType: 'admin_ui' as const,
|
|
11716
|
-
changedFields,
|
|
11717
|
-
metadata: { schemaType: 'single' },
|
|
11718
|
-
...auditRequestMetadata
|
|
11648
|
+
runAfterHooks(previousRow ? 'afterUpdate' : 'afterCreate', {
|
|
11649
|
+
...lifecycleContext,
|
|
11650
|
+
data: (saved${Singular} ?? result[0]) as unknown as Record<string, unknown>
|
|
11719
11651
|
})
|
|
11720
11652
|
|
|
11721
11653
|
return {
|
|
@@ -16574,7 +16506,7 @@ export default async function ${Plural}Page() {
|
|
|
16574
16506
|
const skeletonContent = `export function ${Plural}PageSkeleton() {
|
|
16575
16507
|
return (
|
|
16576
16508
|
<div className="flex items-center justify-center h-48">
|
|
16577
|
-
<div className="text-muted-foreground">Loading ${schema.label}
|
|
16509
|
+
<div className="text-muted-foreground">Loading ${schema.label}\u2026</div>
|
|
16578
16510
|
</div>
|
|
16579
16511
|
)
|
|
16580
16512
|
}
|
|
@@ -16906,7 +16838,6 @@ function generateSinglePage(schema, pagesDir, options = {}) {
|
|
|
16906
16838
|
const Singular = toPascalCase(singular);
|
|
16907
16839
|
const PageName = toPascalCase(schema.name);
|
|
16908
16840
|
const actionImportPath = resolveSchemaActionImportPath(schema.name, options.outputNamespace);
|
|
16909
|
-
const adminRoutePath = options.adminRoutePath ?? "/admin";
|
|
16910
16841
|
const devModeIntegration = buildSingleDevModeIntegration(
|
|
16911
16842
|
schema,
|
|
16912
16843
|
options.adminDir ?? "admin",
|
|
@@ -16914,7 +16845,6 @@ function generateSinglePage(schema, pagesDir, options = {}) {
|
|
|
16914
16845
|
options.adminImportAlias
|
|
16915
16846
|
);
|
|
16916
16847
|
const settingsImport = schema.name === "settings" ? "" : "import { getSetting } from '@admin/actions/settings'\n";
|
|
16917
|
-
const settingsAuditImports = schema.name === "settings" ? "import { Button } from '@admin/components/ui/button'\nimport { ScrollText } from 'lucide-react'\nimport Link from 'next/link'\n" : "";
|
|
16918
16848
|
const dataLoad = schema.name === "settings" ? ` const data = await get${Singular}()
|
|
16919
16849
|
` : ` const [data, initialSettings] = await Promise.all([
|
|
16920
16850
|
get${Singular}(),
|
|
@@ -16922,16 +16852,7 @@ function generateSinglePage(schema, pagesDir, options = {}) {
|
|
|
16922
16852
|
])
|
|
16923
16853
|
`;
|
|
16924
16854
|
const initialSettingsProp = schema.name === "settings" ? "initialSettings={data}" : "initialSettings={initialSettings}";
|
|
16925
|
-
const
|
|
16926
|
-
<Button asChild variant="outline" size="sm">
|
|
16927
|
-
<Link href="${adminRoutePath}/system/audit-log">
|
|
16928
|
-
<ScrollText />
|
|
16929
|
-
Audit Log
|
|
16930
|
-
</Link>
|
|
16931
|
-
</Button>
|
|
16932
|
-
<${devModeIntegration.buttonExportName} ${initialSettingsProp} />
|
|
16933
|
-
</div>` : `<${devModeIntegration.buttonExportName} ${initialSettingsProp} />`;
|
|
16934
|
-
const content = `${settingsImport}${settingsAuditImports}import { get${Singular} } from '@admin/actions/${actionImportPath}'
|
|
16855
|
+
const content = `${settingsImport}import { get${Singular} } from '@admin/actions/${actionImportPath}'
|
|
16935
16856
|
import { PageHeader } from '@admin/components/shared/page-header'
|
|
16936
16857
|
import { ${devModeIntegration.buttonExportName} } from '${devModeIntegration.buttonImportPath}'
|
|
16937
16858
|
import { ${Singular}Form } from './${schema.name}-form'
|
|
@@ -16944,9 +16865,9 @@ ${dataLoad}
|
|
|
16944
16865
|
<React.Fragment>
|
|
16945
16866
|
<PageHeader
|
|
16946
16867
|
title="${schema.label}"
|
|
16947
|
-
actions={${
|
|
16868
|
+
actions={<${devModeIntegration.buttonExportName} ${initialSettingsProp} />}
|
|
16948
16869
|
/>
|
|
16949
|
-
<main className="
|
|
16870
|
+
<main className="mx-auto max-w-5xl w-full p-4">
|
|
16950
16871
|
<${Singular}Form initialData={data} />
|
|
16951
16872
|
</main>
|
|
16952
16873
|
</React.Fragment>
|
|
@@ -17007,7 +16928,6 @@ import { GripVertical } from 'lucide-react'
|
|
|
17007
16928
|
import { parseAsInteger, parseAsString, useQueryStates } from 'nuqs'
|
|
17008
16929
|
${hasEdit ? "import { useRouter } from 'next/navigation'\n" : ""}import { use${Plural} } from '@admin/hooks/use-${schema.name}'
|
|
17009
16930
|
import type { ${Singular} } from '@admin/actions/${actionImportPath}'
|
|
17010
|
-
import { Card, CardContent } from '@admin/components/ui/card'
|
|
17011
16931
|
import { useTableUtils } from '@admin/hooks/use-table-utils'
|
|
17012
16932
|
import { cn } from '@admin/utils/shared/cn'
|
|
17013
16933
|
|
|
@@ -17113,110 +17033,106 @@ ${hasEdit ? " const router = useRouter()\n" : ""} const [{
|
|
|
17113
17033
|
<div
|
|
17114
17034
|
className={cn("flex flex-col gap-6 pt-px pb-2 h-full", className)}
|
|
17115
17035
|
>
|
|
17116
|
-
<
|
|
17117
|
-
<
|
|
17118
|
-
|
|
17119
|
-
<
|
|
17120
|
-
{
|
|
17121
|
-
|
|
17122
|
-
|
|
17123
|
-
|
|
17124
|
-
|
|
17125
|
-
|
|
17126
|
-
|
|
17127
|
-
|
|
17128
|
-
|
|
17129
|
-
|
|
17130
|
-
|
|
17131
|
-
'text-center': meta?.align === 'center',
|
|
17132
|
-
'text-right': meta?.align === 'right'
|
|
17133
|
-
})}
|
|
17134
|
-
data-column-id={header.column.id}
|
|
17135
|
-
onMouseEnter={() => setHoveredColumnId(header.column.id)}
|
|
17136
|
-
onMouseLeave={() => setHoveredColumnId((current) => (current === header.column.id ? null : current))}
|
|
17137
|
-
>
|
|
17138
|
-
{header.isPlaceholder
|
|
17139
|
-
? null
|
|
17140
|
-
: flexRender(header.column.columnDef.header, header.getContext())}
|
|
17141
|
-
{canResizeColumn ? (
|
|
17142
|
-
<button
|
|
17143
|
-
type="button"
|
|
17144
|
-
aria-label={\`Resize \${resizeLabel} column\`}
|
|
17145
|
-
className="group/resize-handle absolute right-0 top-0 z-10 flex h-full w-5 cursor-col-resize touch-none select-none items-center justify-center text-muted-foreground opacity-0 transition-opacity hover:text-foreground focus-visible:text-foreground focus-visible:opacity-100 focus-visible:outline-none group-focus-within/resize-header:opacity-100 data-[column-hovered=true]:opacity-100 data-[resizing=true]:opacity-100"
|
|
17146
|
-
data-resize-handle
|
|
17147
|
-
data-column-hovered={hoveredColumnId === header.column.id ? 'true' : 'false'}
|
|
17148
|
-
data-resizing={header.column.getIsResizing() ? 'true' : 'false'}
|
|
17149
|
-
onDoubleClick={resetColumnSizingToContainer}
|
|
17150
|
-
onMouseDown={header.getResizeHandler()}
|
|
17151
|
-
onTouchStart={header.getResizeHandler()}
|
|
17152
|
-
>
|
|
17153
|
-
<GripVertical aria-hidden="true" className={cn('size-3.5', { 'text-ring': header.column.getIsResizing() })} />
|
|
17154
|
-
</button>
|
|
17155
|
-
) : null}
|
|
17156
|
-
</DataGridHead>
|
|
17157
|
-
)
|
|
17158
|
-
})}
|
|
17159
|
-
</DataGridRow>
|
|
17160
|
-
))}
|
|
17161
|
-
</DataGridHeader>
|
|
17162
|
-
<DataGridBody>
|
|
17163
|
-
{isPending ? (
|
|
17164
|
-
<DataGridRow>
|
|
17165
|
-
<DataGridCell className="flex h-24 items-center justify-center text-center" style={{ gridColumn: '1 / -1' }}>
|
|
17166
|
-
<div className="text-muted-foreground">Loading ${schema.label}...</div>
|
|
17167
|
-
</DataGridCell>
|
|
17168
|
-
</DataGridRow>
|
|
17169
|
-
) : error ? (
|
|
17170
|
-
<DataGridRow>
|
|
17171
|
-
<DataGridCell className="flex h-24 items-center justify-center text-center" style={{ gridColumn: '1 / -1' }}>
|
|
17172
|
-
<div className="text-destructive">Error loading ${schema.label}: {error.message}</div>
|
|
17173
|
-
</DataGridCell>
|
|
17174
|
-
</DataGridRow>
|
|
17175
|
-
) : table.getRowModel().rows?.length ? (
|
|
17176
|
-
table.getRowModel().rows.map((row) => (
|
|
17177
|
-
<DataGridRow
|
|
17178
|
-
key={row.id}
|
|
17179
|
-
className={cn('hover:bg-muted/50', {
|
|
17180
|
-
'cursor-pointer': ${hasEdit ? "true" : "false"}
|
|
17036
|
+
<DataGrid containerClassName="min-h-0 flex-1" containerRef={tableContainerRef} gridTemplateColumns={gridTemplateColumns} style={{ width: table.getTotalSize() }}>
|
|
17037
|
+
<DataGridHeader>
|
|
17038
|
+
{table.getHeaderGroups().map((headerGroup) => (
|
|
17039
|
+
<DataGridRow key={headerGroup.id}>
|
|
17040
|
+
{headerGroup.headers.map((header, headerIndex) => {
|
|
17041
|
+
const meta = header.column.columnDef.meta as Record<string, unknown> | undefined
|
|
17042
|
+
const resizeLabel = typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : header.column.id
|
|
17043
|
+
const nextHeader = headerGroup.headers[headerIndex + 1]
|
|
17044
|
+
const canResizeColumn = header.column.getCanResize() && nextHeader?.column.getCanResize() === true
|
|
17045
|
+
return (
|
|
17046
|
+
<DataGridHead
|
|
17047
|
+
key={header.id}
|
|
17048
|
+
className={cn('group/resize-header relative overflow-hidden', {
|
|
17049
|
+
'text-center': meta?.align === 'center',
|
|
17050
|
+
'text-right': meta?.align === 'right'
|
|
17181
17051
|
})}
|
|
17182
|
-
data-
|
|
17183
|
-
|
|
17184
|
-
|
|
17185
|
-
if (!e.currentTarget.contains(target)) return
|
|
17186
|
-
if (target.closest('button, a, input, [role="checkbox"]')) return
|
|
17187
|
-
router.push(\`${adminRoutePath}/${schema.name}/\${row.original.id}/edit\`)
|
|
17188
|
-
}}` : ""}
|
|
17052
|
+
data-column-id={header.column.id}
|
|
17053
|
+
onMouseEnter={() => setHoveredColumnId(header.column.id)}
|
|
17054
|
+
onMouseLeave={() => setHoveredColumnId((current) => (current === header.column.id ? null : current))}
|
|
17189
17055
|
>
|
|
17190
|
-
{
|
|
17191
|
-
|
|
17192
|
-
|
|
17193
|
-
|
|
17194
|
-
|
|
17195
|
-
|
|
17196
|
-
|
|
17197
|
-
|
|
17198
|
-
|
|
17199
|
-
|
|
17200
|
-
|
|
17201
|
-
|
|
17202
|
-
|
|
17203
|
-
|
|
17204
|
-
|
|
17205
|
-
|
|
17206
|
-
|
|
17207
|
-
|
|
17208
|
-
|
|
17209
|
-
|
|
17210
|
-
|
|
17211
|
-
|
|
17212
|
-
|
|
17213
|
-
|
|
17214
|
-
|
|
17215
|
-
|
|
17216
|
-
|
|
17217
|
-
|
|
17218
|
-
|
|
17219
|
-
|
|
17056
|
+
{header.isPlaceholder
|
|
17057
|
+
? null
|
|
17058
|
+
: flexRender(header.column.columnDef.header, header.getContext())}
|
|
17059
|
+
{canResizeColumn ? (
|
|
17060
|
+
<button
|
|
17061
|
+
type="button"
|
|
17062
|
+
aria-label={\`Resize \${resizeLabel} column\`}
|
|
17063
|
+
className="group/resize-handle absolute right-0 top-0 z-10 flex h-full w-5 cursor-col-resize touch-none select-none items-center justify-center text-muted-foreground opacity-0 transition-opacity hover:text-foreground focus-visible:text-foreground focus-visible:opacity-100 focus-visible:outline-none group-focus-within/resize-header:opacity-100 data-[column-hovered=true]:opacity-100 data-[resizing=true]:opacity-100"
|
|
17064
|
+
data-resize-handle
|
|
17065
|
+
data-column-hovered={hoveredColumnId === header.column.id ? 'true' : 'false'}
|
|
17066
|
+
data-resizing={header.column.getIsResizing() ? 'true' : 'false'}
|
|
17067
|
+
onDoubleClick={resetColumnSizingToContainer}
|
|
17068
|
+
onMouseDown={header.getResizeHandler()}
|
|
17069
|
+
onTouchStart={header.getResizeHandler()}
|
|
17070
|
+
>
|
|
17071
|
+
<GripVertical aria-hidden="true" className={cn('size-3.5', { 'text-ring': header.column.getIsResizing() })} />
|
|
17072
|
+
</button>
|
|
17073
|
+
) : null}
|
|
17074
|
+
</DataGridHead>
|
|
17075
|
+
)
|
|
17076
|
+
})}
|
|
17077
|
+
</DataGridRow>
|
|
17078
|
+
))}
|
|
17079
|
+
</DataGridHeader>
|
|
17080
|
+
<DataGridBody>
|
|
17081
|
+
{isPending ? (
|
|
17082
|
+
<DataGridRow>
|
|
17083
|
+
<DataGridCell className="flex h-24 items-center justify-center text-center" style={{ gridColumn: '1 / -1' }}>
|
|
17084
|
+
<div className="text-muted-foreground">Loading ${schema.label}\u2026</div>
|
|
17085
|
+
</DataGridCell>
|
|
17086
|
+
</DataGridRow>
|
|
17087
|
+
) : error ? (
|
|
17088
|
+
<DataGridRow>
|
|
17089
|
+
<DataGridCell className="flex h-24 items-center justify-center text-center" style={{ gridColumn: '1 / -1' }}>
|
|
17090
|
+
<div className="text-destructive">Error loading ${schema.label}: {error.message}</div>
|
|
17091
|
+
</DataGridCell>
|
|
17092
|
+
</DataGridRow>
|
|
17093
|
+
) : table.getRowModel().rows?.length ? (
|
|
17094
|
+
table.getRowModel().rows.map((row) => (
|
|
17095
|
+
<DataGridRow
|
|
17096
|
+
key={row.id}
|
|
17097
|
+
className={cn('hover:bg-muted/50', {
|
|
17098
|
+
'cursor-pointer': ${hasEdit ? "true" : "false"}
|
|
17099
|
+
})}
|
|
17100
|
+
data-state={row.getIsSelected() ? 'selected' : undefined}${hasEdit ? `
|
|
17101
|
+
onClick={(e) => {
|
|
17102
|
+
const target = e.target as HTMLElement
|
|
17103
|
+
if (!e.currentTarget.contains(target)) return
|
|
17104
|
+
if (target.closest('button, a, input, [role="checkbox"]')) return
|
|
17105
|
+
router.push(\`${adminRoutePath}/${schema.name}/\${row.original.id}/edit\`)
|
|
17106
|
+
}}` : ""}
|
|
17107
|
+
>
|
|
17108
|
+
{row.getVisibleCells().map((cell) => {
|
|
17109
|
+
const meta = cell.column.columnDef.meta as Record<string, unknown> | undefined
|
|
17110
|
+
return (
|
|
17111
|
+
<DataGridCell
|
|
17112
|
+
key={cell.id}
|
|
17113
|
+
className={cn({
|
|
17114
|
+
'text-center': meta?.align === 'center',
|
|
17115
|
+
'text-right': meta?.align === 'right'
|
|
17116
|
+
})}
|
|
17117
|
+
data-column-id={cell.column.id}
|
|
17118
|
+
onMouseEnter={() => setHoveredColumnId(cell.column.id)}
|
|
17119
|
+
onMouseLeave={() => setHoveredColumnId((current) => (current === cell.column.id ? null : current))}
|
|
17120
|
+
>
|
|
17121
|
+
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
17122
|
+
</DataGridCell>
|
|
17123
|
+
)
|
|
17124
|
+
})}
|
|
17125
|
+
</DataGridRow>
|
|
17126
|
+
))
|
|
17127
|
+
) : (
|
|
17128
|
+
<DataGridRow>
|
|
17129
|
+
<DataGridCell className="flex h-24 items-center justify-center text-center" style={{ gridColumn: '1 / -1' }}>
|
|
17130
|
+
No ${schema.label} found.
|
|
17131
|
+
</DataGridCell>
|
|
17132
|
+
</DataGridRow>
|
|
17133
|
+
)}
|
|
17134
|
+
</DataGridBody>
|
|
17135
|
+
</DataGrid>
|
|
17220
17136
|
|
|
17221
17137
|
{shouldShowPagination ? (
|
|
17222
17138
|
<DataTablePagination
|
|
@@ -17331,6 +17247,10 @@ function runEntityPipeline(schema, cwd, config, options = {}) {
|
|
|
17331
17247
|
name: "Navigation",
|
|
17332
17248
|
run: () => updateNavigation(normalizedSchema, paths.adminNavigationDir, namespacedOptions).files
|
|
17333
17249
|
});
|
|
17250
|
+
steps.push({
|
|
17251
|
+
name: "Webhook events",
|
|
17252
|
+
run: () => updateWebhookEvents(normalizedSchema, paths.adminWebhookEventsDir, "entity").files
|
|
17253
|
+
});
|
|
17334
17254
|
for (let i = 0; i < steps.length; i++) {
|
|
17335
17255
|
const step = steps[i];
|
|
17336
17256
|
const stepNum = i + 1;
|
|
@@ -17393,6 +17313,10 @@ function runSinglePipeline(schema, cwd, config, options = {}) {
|
|
|
17393
17313
|
{
|
|
17394
17314
|
name: "Navigation",
|
|
17395
17315
|
run: () => updateNavigation(normalizedSchema, paths.adminNavigationDir, namespacedOptions).files
|
|
17316
|
+
},
|
|
17317
|
+
{
|
|
17318
|
+
name: "Webhook events",
|
|
17319
|
+
run: () => updateWebhookEvents(normalizedSchema, paths.adminWebhookEventsDir, "single").files
|
|
17396
17320
|
}
|
|
17397
17321
|
];
|
|
17398
17322
|
for (let i = 0; i < steps.length; i++) {
|
|
@@ -17968,18 +17892,41 @@ others.sort((a, b) => {
|
|
|
17968
17892
|
export const ${namespace.camel}Navigation = [...(dashboard ? [dashboard] : []), ...others]
|
|
17969
17893
|
`;
|
|
17970
17894
|
}
|
|
17895
|
+
function renderWebhookEventsBarrel(extractNames, namespaceValue) {
|
|
17896
|
+
const namespace = resolveAdminNamespace(namespaceValue);
|
|
17897
|
+
const importLines = extractNames.map(
|
|
17898
|
+
(name) => `import { ${toCamelCase(name)}WebhookEvents } from './webhook-events/${name}'`
|
|
17899
|
+
);
|
|
17900
|
+
const entryLines = extractNames.map((name) => ` ${toCamelCase(name)}WebhookEvents`);
|
|
17901
|
+
const extractImports = importLines.length > 0 ? `
|
|
17902
|
+
${importLines.join("\n")}` : "";
|
|
17903
|
+
const entries = entryLines.length > 0 ? `[
|
|
17904
|
+
${entryLines.join(",\n")}
|
|
17905
|
+
]` : "[]";
|
|
17906
|
+
return `import type { WebhookEventSource } from '${namespace.alias}/types/webhooks'${extractImports}
|
|
17907
|
+
|
|
17908
|
+
export type { WebhookEventSource } from '${namespace.alias}/types/webhooks'
|
|
17909
|
+
|
|
17910
|
+
export const webhookEventSources: WebhookEventSource[] = ${entries}
|
|
17911
|
+
`;
|
|
17912
|
+
}
|
|
17971
17913
|
function renderBarrelFiles(cwd, config) {
|
|
17972
17914
|
const paths = resolveProjectPaths(config);
|
|
17973
17915
|
const dbExtracts = listNamespacedExtracts(cwd, paths.adminDbDir).filter(
|
|
17974
17916
|
(extract) => !(extract.namespace === "core" && extract.name === "schema")
|
|
17975
17917
|
);
|
|
17976
17918
|
const navExtractNames = listExtractNames(cwd, paths.adminNavigationDir, /* @__PURE__ */ new Set(["core"]));
|
|
17919
|
+
const webhookEventExtractNames = listExtractNames(cwd, paths.adminWebhookEventsDir);
|
|
17977
17920
|
return namespaceGeneratedFiles(
|
|
17978
17921
|
[
|
|
17979
17922
|
createGeneratedFile(paths.adminDbSchemaFile, renderDbBarrel(dbExtracts)),
|
|
17980
17923
|
createGeneratedFile(
|
|
17981
17924
|
paths.adminNavigationFile,
|
|
17982
17925
|
renderNavigationBarrel(navExtractNames, config.frameworkConfig.next.namespace)
|
|
17926
|
+
),
|
|
17927
|
+
createGeneratedFile(
|
|
17928
|
+
paths.adminWebhookEventsFile,
|
|
17929
|
+
renderWebhookEventsBarrel(webhookEventExtractNames, config.frameworkConfig.next.namespace)
|
|
17983
17930
|
)
|
|
17984
17931
|
],
|
|
17985
17932
|
config.frameworkConfig.next.namespace
|
|
@@ -22337,6 +22284,10 @@ function scaffoldComponents({ cwd, config }) {
|
|
|
22337
22284
|
"components/layouts/admin-sidebar-nav-link-skeleton.tsx",
|
|
22338
22285
|
readTemplate("components/layouts/admin-sidebar-nav-link-skeleton.tsx")
|
|
22339
22286
|
);
|
|
22287
|
+
write(
|
|
22288
|
+
"components/layouts/admin-settings-sidebar.tsx",
|
|
22289
|
+
readTemplate("components/layouts/admin-settings-sidebar.tsx")
|
|
22290
|
+
);
|
|
22340
22291
|
write(
|
|
22341
22292
|
"components/layouts/admin-sidebar-user-menu.tsx",
|
|
22342
22293
|
readTemplate("components/layouts/admin-sidebar-user-menu.tsx")
|
|
@@ -22501,6 +22452,7 @@ function scaffoldComponents({ cwd, config }) {
|
|
|
22501
22452
|
write("types/auth.ts", readTemplate("types/auth.ts"));
|
|
22502
22453
|
write("types/navigation.ts", readTemplate("types/navigation.ts"));
|
|
22503
22454
|
write("types/table-meta.ts", readTemplate("types/table-meta.ts"));
|
|
22455
|
+
write("types/webhooks.ts", readTemplate("types/webhooks.ts"));
|
|
22504
22456
|
for (const relPath of [
|
|
22505
22457
|
"utils/auth/roles.ts",
|
|
22506
22458
|
"utils/audit/audit.ts",
|
|
@@ -22536,7 +22488,7 @@ function scaffoldComponents({ cwd, config }) {
|
|
|
22536
22488
|
"utils/upload/upload.ts",
|
|
22537
22489
|
"utils/user/user.ts",
|
|
22538
22490
|
"utils/validation/validation.ts",
|
|
22539
|
-
"utils/webhook/
|
|
22491
|
+
"utils/webhook/signature.ts"
|
|
22540
22492
|
]) {
|
|
22541
22493
|
write(relPath, readTemplate(relPath));
|
|
22542
22494
|
}
|
|
@@ -22618,6 +22570,7 @@ function scaffoldComponents({ cwd, config }) {
|
|
|
22618
22570
|
write("hooks/use-admin-theme.tsx", readTemplate("hooks/use-admin-theme.tsx"));
|
|
22619
22571
|
write("hooks/use-audit-log.ts", readTemplate("hooks/use-audit-log.ts"));
|
|
22620
22572
|
write("hooks/use-users.ts", readTemplate("hooks/use-users.ts"));
|
|
22573
|
+
write("hooks/use-webhooks.ts", readTemplate("hooks/use-webhooks.ts"));
|
|
22621
22574
|
write("hooks/use-mobile.ts", readTemplate("hooks/use-mobile.ts"));
|
|
22622
22575
|
write("hooks/use-failed-image-url.ts", readTemplate("hooks/use-failed-image-url.ts"));
|
|
22623
22576
|
write("hooks/use-media.ts", readTemplate("hooks/use-media.ts"));
|
|
@@ -22632,14 +22585,28 @@ function scaffoldComponents({ cwd, config }) {
|
|
|
22632
22585
|
const adminNamespace = resolveAdminNamespace(namespace);
|
|
22633
22586
|
const projectName = detectProjectName(cwd);
|
|
22634
22587
|
write("data/navigation.ts", readTemplate("data/navigation.ts"));
|
|
22588
|
+
write("data/webhook-events.ts", readTemplate("data/webhook-events.ts"));
|
|
22635
22589
|
write(`utils/app/${adminNamespace.camel}.ts`, adminDataTemplate(projectName, namespace));
|
|
22636
22590
|
for (const relPath of [
|
|
22637
22591
|
"lib/actions/forms/types.ts",
|
|
22638
22592
|
"lib/actions/forms/get-form-settings.ts",
|
|
22639
22593
|
"lib/actions/forms/upsert-form-settings.ts",
|
|
22640
22594
|
"lib/actions/forms/get-all-form-settings.ts",
|
|
22641
|
-
"lib/actions/forms/test-form-webhook.ts",
|
|
22642
22595
|
"lib/actions/forms/index.ts",
|
|
22596
|
+
"lib/actions/webhooks/types.ts",
|
|
22597
|
+
"lib/actions/webhooks/internal-get-active-endpoints.ts",
|
|
22598
|
+
"lib/actions/webhooks/dispatch.ts",
|
|
22599
|
+
"lib/actions/webhooks/get-webhooks.ts",
|
|
22600
|
+
"lib/actions/webhooks/create-webhook.ts",
|
|
22601
|
+
"lib/actions/webhooks/update-webhook.ts",
|
|
22602
|
+
"lib/actions/webhooks/delete-webhook.ts",
|
|
22603
|
+
"lib/actions/webhooks/get-webhook-secret.ts",
|
|
22604
|
+
"lib/actions/webhooks/regenerate-webhook-secret.ts",
|
|
22605
|
+
"lib/actions/webhooks/get-webhook-subscriptions.ts",
|
|
22606
|
+
"lib/actions/webhooks/send-test-webhook.ts",
|
|
22607
|
+
"lib/actions/webhooks/get-webhook-deliveries.ts",
|
|
22608
|
+
"lib/actions/webhooks/register.ts",
|
|
22609
|
+
"lib/actions/webhooks/index.ts",
|
|
22643
22610
|
"lib/actions/entity-versions/types.ts",
|
|
22644
22611
|
"lib/actions/entity-versions/get-entity-versions.ts",
|
|
22645
22612
|
"lib/actions/entity-versions/internal-create-entity-version.ts",
|
|
@@ -22824,41 +22791,27 @@ function defaultSettingsSchema() {
|
|
|
22824
22791
|
type: "section",
|
|
22825
22792
|
name: "siteSettings",
|
|
22826
22793
|
label: "Dashboard Settings",
|
|
22827
|
-
description: "General settings for the dashboard",
|
|
22828
22794
|
fields: [
|
|
22829
22795
|
{
|
|
22830
22796
|
name: "title",
|
|
22831
22797
|
type: "string",
|
|
22832
|
-
label: "Name",
|
|
22798
|
+
label: "Application Name",
|
|
22833
22799
|
hint: "Displayed in the sidebar and throughout the dashboard",
|
|
22834
22800
|
default: "BetterStart"
|
|
22835
22801
|
},
|
|
22836
|
-
{
|
|
22837
|
-
name: "dashboardDescription",
|
|
22838
|
-
type: "text",
|
|
22839
|
-
label: "Description",
|
|
22840
|
-
hint: "A brief description of the application"
|
|
22841
|
-
}
|
|
22802
|
+
{ name: "dashboardLogo", type: "image", label: "Logo" }
|
|
22842
22803
|
]
|
|
22843
22804
|
},
|
|
22844
|
-
{
|
|
22845
|
-
type: "section",
|
|
22846
|
-
name: "branding",
|
|
22847
|
-
label: "Branding",
|
|
22848
|
-
description: "Logo and visual identity",
|
|
22849
|
-
fields: [{ name: "dashboardLogo", type: "image", label: "Logo" }]
|
|
22850
|
-
},
|
|
22851
22805
|
{
|
|
22852
22806
|
type: "section",
|
|
22853
22807
|
name: "developer",
|
|
22854
|
-
label: "
|
|
22855
|
-
description: "Developer tools for the dashboard",
|
|
22808
|
+
label: "Developers",
|
|
22856
22809
|
fields: [
|
|
22857
22810
|
{
|
|
22858
22811
|
name: "devMode",
|
|
22859
22812
|
type: "boolean",
|
|
22860
22813
|
label: "Dev Mode",
|
|
22861
|
-
hint: "Show generated integration snippets and schema details
|
|
22814
|
+
hint: "Show generated integration snippets and schema details for developers",
|
|
22862
22815
|
default: true
|
|
22863
22816
|
}
|
|
22864
22817
|
]
|
|
@@ -22867,7 +22820,6 @@ function defaultSettingsSchema() {
|
|
|
22867
22820
|
type: "section",
|
|
22868
22821
|
name: "auditLog",
|
|
22869
22822
|
label: "Audit Log",
|
|
22870
|
-
description: "Audit retention controls",
|
|
22871
22823
|
fields: [
|
|
22872
22824
|
{
|
|
22873
22825
|
name: "auditRetentionEnabled",
|
|
@@ -23188,6 +23140,78 @@ function scaffoldLayout({ cwd, config }) {
|
|
|
23188
23140
|
path41.join(usersDir, "change-password-dialog.tsx"),
|
|
23189
23141
|
readTemplate("pages/users/change-password-dialog.tsx")
|
|
23190
23142
|
);
|
|
23143
|
+
const settingsDir = path41.join(config.paths.pages, "settings");
|
|
23144
|
+
write(path41.join(settingsDir, "layout.tsx"), readTemplate("pages/settings/settings-layout.tsx"));
|
|
23145
|
+
const settingsFormsDir = path41.join(settingsDir, "forms");
|
|
23146
|
+
write(
|
|
23147
|
+
path41.join(settingsFormsDir, "page.tsx"),
|
|
23148
|
+
readTemplate("pages/settings/forms/forms-settings-page.tsx")
|
|
23149
|
+
);
|
|
23150
|
+
write(
|
|
23151
|
+
path41.join(settingsFormsDir, "forms-settings-page-skeleton.tsx"),
|
|
23152
|
+
readTemplate("pages/settings/forms/forms-settings-page-skeleton.tsx")
|
|
23153
|
+
);
|
|
23154
|
+
write(
|
|
23155
|
+
path41.join(settingsFormsDir, "forms-settings-page-content.tsx"),
|
|
23156
|
+
readTemplate("pages/settings/forms/forms-settings-page-content.tsx")
|
|
23157
|
+
);
|
|
23158
|
+
write(
|
|
23159
|
+
path41.join(settingsFormsDir, "edit-form-notifications-dialog.tsx"),
|
|
23160
|
+
readTemplate("pages/settings/forms/edit-form-notifications-dialog.tsx")
|
|
23161
|
+
);
|
|
23162
|
+
const settingsWebhooksDir = path41.join(settingsDir, "webhooks");
|
|
23163
|
+
write(
|
|
23164
|
+
path41.join(settingsWebhooksDir, "page.tsx"),
|
|
23165
|
+
readTemplate("pages/settings/webhooks/webhooks-page.tsx")
|
|
23166
|
+
);
|
|
23167
|
+
write(
|
|
23168
|
+
path41.join(settingsWebhooksDir, "webhooks-page-skeleton.tsx"),
|
|
23169
|
+
readTemplate("pages/settings/webhooks/webhooks-page-skeleton.tsx")
|
|
23170
|
+
);
|
|
23171
|
+
write(
|
|
23172
|
+
path41.join(settingsWebhooksDir, "webhooks-page-content.tsx"),
|
|
23173
|
+
readTemplate("pages/settings/webhooks/webhooks-page-content.tsx")
|
|
23174
|
+
);
|
|
23175
|
+
write(
|
|
23176
|
+
path41.join(settingsWebhooksDir, "webhooks-table.tsx"),
|
|
23177
|
+
readTemplate("pages/settings/webhooks/webhooks-table.tsx")
|
|
23178
|
+
);
|
|
23179
|
+
write(
|
|
23180
|
+
path41.join(settingsWebhooksDir, "webhooks-columns.tsx"),
|
|
23181
|
+
readTemplate("pages/settings/webhooks/webhooks-columns.tsx")
|
|
23182
|
+
);
|
|
23183
|
+
write(
|
|
23184
|
+
path41.join(settingsWebhooksDir, "webhook-actions.tsx"),
|
|
23185
|
+
readTemplate("pages/settings/webhooks/webhook-actions.tsx")
|
|
23186
|
+
);
|
|
23187
|
+
write(
|
|
23188
|
+
path41.join(settingsWebhooksDir, "webhook-enabled-switch.tsx"),
|
|
23189
|
+
readTemplate("pages/settings/webhooks/webhook-enabled-switch.tsx")
|
|
23190
|
+
);
|
|
23191
|
+
write(
|
|
23192
|
+
path41.join(settingsWebhooksDir, "webhook-endpoint-dialog.tsx"),
|
|
23193
|
+
readTemplate("pages/settings/webhooks/webhook-endpoint-dialog.tsx")
|
|
23194
|
+
);
|
|
23195
|
+
write(
|
|
23196
|
+
path41.join(settingsWebhooksDir, "delete-webhook-dialog.tsx"),
|
|
23197
|
+
readTemplate("pages/settings/webhooks/delete-webhook-dialog.tsx")
|
|
23198
|
+
);
|
|
23199
|
+
write(
|
|
23200
|
+
path41.join(settingsWebhooksDir, "webhooks-logs-page-content.tsx"),
|
|
23201
|
+
readTemplate("pages/settings/webhooks/webhooks-logs-page-content.tsx")
|
|
23202
|
+
);
|
|
23203
|
+
write(
|
|
23204
|
+
path41.join(settingsWebhooksDir, "webhooks-logs-table.tsx"),
|
|
23205
|
+
readTemplate("pages/settings/webhooks/webhooks-logs-table.tsx")
|
|
23206
|
+
);
|
|
23207
|
+
write(
|
|
23208
|
+
path41.join(settingsWebhooksDir, "webhooks-logs-columns.tsx"),
|
|
23209
|
+
readTemplate("pages/settings/webhooks/webhooks-logs-columns.tsx")
|
|
23210
|
+
);
|
|
23211
|
+
write(
|
|
23212
|
+
path41.join(settingsWebhooksDir, "logs", "page.tsx"),
|
|
23213
|
+
readTemplate("pages/settings/webhooks/webhooks-logs-page.tsx")
|
|
23214
|
+
);
|
|
23191
23215
|
const mediaDir = path41.join(config.paths.pages, "media");
|
|
23192
23216
|
write(path41.join(mediaDir, "page.tsx"), readTemplate("pages/media/media-page.tsx"));
|
|
23193
23217
|
write(
|
|
@@ -23198,23 +23222,34 @@ function scaffoldLayout({ cwd, config }) {
|
|
|
23198
23222
|
path41.join(mediaDir, "media-page-content.tsx"),
|
|
23199
23223
|
readTemplate("pages/media/media-page-content.tsx")
|
|
23200
23224
|
);
|
|
23201
|
-
const auditLogDir = path41.join(config.paths.pages, "
|
|
23202
|
-
write(
|
|
23225
|
+
const auditLogDir = path41.join(config.paths.pages, "settings", "audit-log");
|
|
23226
|
+
write(
|
|
23227
|
+
path41.join(auditLogDir, "page.tsx"),
|
|
23228
|
+
readTemplate("pages/settings/audit-log/audit-log-page.tsx")
|
|
23229
|
+
);
|
|
23203
23230
|
write(
|
|
23204
23231
|
path41.join(auditLogDir, "audit-log-page-skeleton.tsx"),
|
|
23205
|
-
readTemplate("pages/audit-log/audit-log-page-skeleton.tsx")
|
|
23232
|
+
readTemplate("pages/settings/audit-log/audit-log-page-skeleton.tsx")
|
|
23206
23233
|
);
|
|
23207
23234
|
write(
|
|
23208
23235
|
path41.join(auditLogDir, "audit-log-page-content.tsx"),
|
|
23209
|
-
readTemplate("pages/audit-log/audit-log-page-content.tsx")
|
|
23236
|
+
readTemplate("pages/settings/audit-log/audit-log-page-content.tsx")
|
|
23237
|
+
);
|
|
23238
|
+
write(
|
|
23239
|
+
path41.join(auditLogDir, "audit-log-table.tsx"),
|
|
23240
|
+
readTemplate("pages/settings/audit-log/audit-log-table.tsx")
|
|
23241
|
+
);
|
|
23242
|
+
write(
|
|
23243
|
+
path41.join(auditLogDir, "audit-log-columns.tsx"),
|
|
23244
|
+
readTemplate("pages/settings/audit-log/audit-log-columns.tsx")
|
|
23210
23245
|
);
|
|
23211
23246
|
write(
|
|
23212
23247
|
path41.join(auditLogDir, "audit-log-detail-drawer.tsx"),
|
|
23213
|
-
readTemplate("pages/audit-log/audit-log-detail-drawer.tsx")
|
|
23248
|
+
readTemplate("pages/settings/audit-log/audit-log-detail-drawer.tsx")
|
|
23214
23249
|
);
|
|
23215
23250
|
write(
|
|
23216
23251
|
path41.join(auditLogDir, "audit-log-detail-row.tsx"),
|
|
23217
|
-
readTemplate("pages/audit-log/audit-log-detail-row.tsx")
|
|
23252
|
+
readTemplate("pages/settings/audit-log/audit-log-detail-row.tsx")
|
|
23218
23253
|
);
|
|
23219
23254
|
const accountDir = path41.join(adminDir, "(account)");
|
|
23220
23255
|
write(path41.join(accountDir, "layout.tsx"), readTemplate("pages/account-layout.tsx"));
|
|
@@ -25038,10 +25073,15 @@ async function main() {
|
|
|
25038
25073
|
process.exit(0)
|
|
25039
25074
|
}
|
|
25040
25075
|
|
|
25041
|
-
const EMAIL = process.env.SEED_EMAIL
|
|
25042
|
-
const PASSWORD = process.env.SEED_PASSWORD
|
|
25076
|
+
const EMAIL = process.env.SEED_EMAIL
|
|
25077
|
+
const PASSWORD = process.env.SEED_PASSWORD
|
|
25043
25078
|
const NAME = process.env.SEED_NAME || 'Admin'
|
|
25044
25079
|
|
|
25080
|
+
if (!EMAIL || !PASSWORD) {
|
|
25081
|
+
console.error(' SEED_EMAIL and SEED_PASSWORD are required.')
|
|
25082
|
+
process.exit(1)
|
|
25083
|
+
}
|
|
25084
|
+
|
|
25045
25085
|
// Check if a user already exists with the requested email
|
|
25046
25086
|
const existingUser = await db
|
|
25047
25087
|
.select({ id: schema.user.id, name: schema.user.name })
|
|
@@ -25221,7 +25261,7 @@ async function runSeedCommand(options) {
|
|
|
25221
25261
|
}
|
|
25222
25262
|
|
|
25223
25263
|
// adapters/next/commands/init.ts
|
|
25224
|
-
var
|
|
25264
|
+
var ANSI_ESCAPE_PATTERN2 = /\u001B\[[0-?]*[ -/]*[@-~]/g;
|
|
25225
25265
|
var REMOVABLE_NAMESPACE_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
25226
25266
|
function normalizeNamespaceForRemoval(value) {
|
|
25227
25267
|
if (typeof value !== "string") {
|
|
@@ -25868,7 +25908,7 @@ async function runInitCommand(name, options) {
|
|
|
25868
25908
|
} else {
|
|
25869
25909
|
s.start("Pushing database schema (drizzle-kit push)");
|
|
25870
25910
|
}
|
|
25871
|
-
const pushResult = await runDrizzlePush(cwd, {
|
|
25911
|
+
const pushResult = await runDrizzlePush(cwd, { interactive: useTerminalForDbPush });
|
|
25872
25912
|
if (pushResult.success) {
|
|
25873
25913
|
if (useTerminalForDbPush) {
|
|
25874
25914
|
const verification = await verifyDatabaseReachable(cwd);
|
|
@@ -26463,8 +26503,8 @@ function runQuietCommand(bin, args, options) {
|
|
|
26463
26503
|
});
|
|
26464
26504
|
});
|
|
26465
26505
|
}
|
|
26466
|
-
function
|
|
26467
|
-
return value.replace(
|
|
26506
|
+
function stripAnsi2(value) {
|
|
26507
|
+
return value.replace(ANSI_ESCAPE_PATTERN2, "");
|
|
26468
26508
|
}
|
|
26469
26509
|
function printAdminReadyNote(state) {
|
|
26470
26510
|
const lines = [`Admin: ${pc7.cyan(state.adminLoginUrl)}`];
|
|
@@ -26475,7 +26515,7 @@ function printAdminReadyNote(state) {
|
|
|
26475
26515
|
p17.note(lines.join("\n"), "Admin ready");
|
|
26476
26516
|
}
|
|
26477
26517
|
function shouldSuppressDevServerStartupLine(line) {
|
|
26478
|
-
const plain =
|
|
26518
|
+
const plain = stripAnsi2(line).trim();
|
|
26479
26519
|
if (plain.length === 0) {
|
|
26480
26520
|
return { suppress: true, isReadyLine: false };
|
|
26481
26521
|
}
|
|
@@ -26718,6 +26758,7 @@ function cleanupEmptyDirs3(cwd, deletedPaths, configPaths) {
|
|
|
26718
26758
|
const stopRoots = /* @__PURE__ */ new Set([
|
|
26719
26759
|
path54.join(cwd, ...configPaths.adminDir.split("/")),
|
|
26720
26760
|
path54.join(cwd, ...configPaths.adminNavigationDir.split("/")),
|
|
26761
|
+
path54.join(cwd, ...configPaths.adminWebhookEventsDir.split("/")),
|
|
26721
26762
|
path54.join(cwd, ...configPaths.pagesDir.split("/"))
|
|
26722
26763
|
]);
|
|
26723
26764
|
for (const deletedPath of deletedPaths) {
|
|
@@ -27504,6 +27545,11 @@ var TEMPLATE_REGISTRY = {
|
|
|
27504
27545
|
relPath: "components/layouts/admin-sidebar-nav-link-skeleton.tsx",
|
|
27505
27546
|
content: () => readTemplate("components/layouts/admin-sidebar-nav-link-skeleton.tsx")
|
|
27506
27547
|
},
|
|
27548
|
+
"admin-settings-sidebar": {
|
|
27549
|
+
relPath: "components/layouts/admin-settings-sidebar.tsx",
|
|
27550
|
+
content: () => readTemplate("components/layouts/admin-settings-sidebar.tsx"),
|
|
27551
|
+
dependencies: ["admin-sidebar-nav-link"]
|
|
27552
|
+
},
|
|
27507
27553
|
"admin-sidebar-user-menu": {
|
|
27508
27554
|
relPath: "components/layouts/admin-sidebar-user-menu.tsx",
|
|
27509
27555
|
content: () => readTemplate("components/layouts/admin-sidebar-user-menu.tsx"),
|
|
@@ -27898,6 +27944,11 @@ var TEMPLATE_REGISTRY = {
|
|
|
27898
27944
|
dependencies: ["audit-action"]
|
|
27899
27945
|
},
|
|
27900
27946
|
"use-users": { relPath: "hooks/use-users.ts", content: () => readTemplate("hooks/use-users.ts") },
|
|
27947
|
+
"use-webhooks": {
|
|
27948
|
+
relPath: "hooks/use-webhooks.ts",
|
|
27949
|
+
content: () => readTemplate("hooks/use-webhooks.ts"),
|
|
27950
|
+
dependencies: ["webhooks-action", "form-settings-action"]
|
|
27951
|
+
},
|
|
27901
27952
|
"use-mobile": {
|
|
27902
27953
|
relPath: "hooks/use-mobile.ts",
|
|
27903
27954
|
content: () => readTemplate("hooks/use-mobile.ts")
|
|
@@ -27946,6 +27997,10 @@ var TEMPLATE_REGISTRY = {
|
|
|
27946
27997
|
relPath: "types/table-meta.ts",
|
|
27947
27998
|
content: () => readTemplate("types/table-meta.ts")
|
|
27948
27999
|
},
|
|
28000
|
+
"webhooks-types": {
|
|
28001
|
+
relPath: "types/webhooks.ts",
|
|
28002
|
+
content: () => readTemplate("types/webhooks.ts")
|
|
28003
|
+
},
|
|
27949
28004
|
// Utils
|
|
27950
28005
|
"app-admin": {
|
|
27951
28006
|
relPath: ({ config }) => `utils/app/${resolveAdminNamespace(config.frameworkConfig.next.namespace).camel}.ts`,
|
|
@@ -28078,9 +28133,9 @@ var TEMPLATE_REGISTRY = {
|
|
|
28078
28133
|
relPath: "utils/validation/validation.ts",
|
|
28079
28134
|
content: () => readTemplate("utils/validation/validation.ts")
|
|
28080
28135
|
},
|
|
28081
|
-
webhook: {
|
|
28082
|
-
relPath: "utils/webhook/
|
|
28083
|
-
content: () => readTemplate("utils/webhook/
|
|
28136
|
+
"webhook-signature": {
|
|
28137
|
+
relPath: "utils/webhook/signature.ts",
|
|
28138
|
+
content: () => readTemplate("utils/webhook/signature.ts")
|
|
28084
28139
|
},
|
|
28085
28140
|
"dev-mode-code-block-height-utils": {
|
|
28086
28141
|
relPath: "utils/dev-mode/code-block-height.ts",
|
|
@@ -28113,7 +28168,8 @@ var TEMPLATE_REGISTRY = {
|
|
|
28113
28168
|
},
|
|
28114
28169
|
"lifecycle-hooks-register": {
|
|
28115
28170
|
relPath: "lib/lifecycle-hooks/register.ts",
|
|
28116
|
-
content: () => readTemplate("lib/lifecycle-hooks/register.ts")
|
|
28171
|
+
content: () => readTemplate("lib/lifecycle-hooks/register.ts"),
|
|
28172
|
+
dependencies: ["webhooks-register-action"]
|
|
28117
28173
|
},
|
|
28118
28174
|
"lifecycle-hooks-register-local": {
|
|
28119
28175
|
relPath: "lib/lifecycle-hooks/register.local.ts",
|
|
@@ -28298,6 +28354,119 @@ var TEMPLATE_REGISTRY = {
|
|
|
28298
28354
|
base: "cwd",
|
|
28299
28355
|
dependencies: ["profile-action", "users-action"]
|
|
28300
28356
|
},
|
|
28357
|
+
"settings-layout": {
|
|
28358
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/layout.tsx",
|
|
28359
|
+
content: () => readTemplate("pages/settings/settings-layout.tsx"),
|
|
28360
|
+
base: "cwd",
|
|
28361
|
+
dependencies: ["admin-settings-sidebar"]
|
|
28362
|
+
},
|
|
28363
|
+
"forms-settings-page": {
|
|
28364
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/forms/page.tsx",
|
|
28365
|
+
content: () => readTemplate("pages/settings/forms/forms-settings-page.tsx"),
|
|
28366
|
+
base: "cwd",
|
|
28367
|
+
dependencies: ["forms-settings-page-skeleton", "forms-settings-page-content"]
|
|
28368
|
+
},
|
|
28369
|
+
"forms-settings-page-skeleton": {
|
|
28370
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/forms/forms-settings-page-skeleton.tsx",
|
|
28371
|
+
content: () => readTemplate("pages/settings/forms/forms-settings-page-skeleton.tsx"),
|
|
28372
|
+
base: "cwd"
|
|
28373
|
+
},
|
|
28374
|
+
"forms-settings-page-content": {
|
|
28375
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/forms/forms-settings-page-content.tsx",
|
|
28376
|
+
content: () => readTemplate("pages/settings/forms/forms-settings-page-content.tsx"),
|
|
28377
|
+
base: "cwd",
|
|
28378
|
+
dependencies: ["edit-form-notifications-dialog", "use-webhooks"]
|
|
28379
|
+
},
|
|
28380
|
+
"edit-form-notifications-dialog": {
|
|
28381
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/forms/edit-form-notifications-dialog.tsx",
|
|
28382
|
+
content: () => readTemplate("pages/settings/forms/edit-form-notifications-dialog.tsx"),
|
|
28383
|
+
base: "cwd",
|
|
28384
|
+
dependencies: ["form-settings-action"]
|
|
28385
|
+
},
|
|
28386
|
+
"webhooks-page": {
|
|
28387
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/webhooks/page.tsx",
|
|
28388
|
+
content: () => readTemplate("pages/settings/webhooks/webhooks-page.tsx"),
|
|
28389
|
+
base: "cwd",
|
|
28390
|
+
dependencies: ["webhooks-page-skeleton", "webhooks-page-content"]
|
|
28391
|
+
},
|
|
28392
|
+
"webhooks-page-skeleton": {
|
|
28393
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/webhooks/webhooks-page-skeleton.tsx",
|
|
28394
|
+
content: () => readTemplate("pages/settings/webhooks/webhooks-page-skeleton.tsx"),
|
|
28395
|
+
base: "cwd"
|
|
28396
|
+
},
|
|
28397
|
+
"webhooks-page-content": {
|
|
28398
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/webhooks/webhooks-page-content.tsx",
|
|
28399
|
+
content: () => readTemplate("pages/settings/webhooks/webhooks-page-content.tsx"),
|
|
28400
|
+
base: "cwd",
|
|
28401
|
+
dependencies: [
|
|
28402
|
+
"webhooks-table",
|
|
28403
|
+
"webhooks-columns",
|
|
28404
|
+
"webhook-endpoint-dialog",
|
|
28405
|
+
"delete-webhook-dialog",
|
|
28406
|
+
"use-webhooks",
|
|
28407
|
+
"webhooks-action"
|
|
28408
|
+
]
|
|
28409
|
+
},
|
|
28410
|
+
"webhooks-table": {
|
|
28411
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/webhooks/webhooks-table.tsx",
|
|
28412
|
+
content: () => readTemplate("pages/settings/webhooks/webhooks-table.tsx"),
|
|
28413
|
+
base: "cwd",
|
|
28414
|
+
dependencies: ["use-webhooks"]
|
|
28415
|
+
},
|
|
28416
|
+
"webhooks-columns": {
|
|
28417
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/webhooks/webhooks-columns.tsx",
|
|
28418
|
+
content: () => readTemplate("pages/settings/webhooks/webhooks-columns.tsx"),
|
|
28419
|
+
base: "cwd",
|
|
28420
|
+
dependencies: ["webhook-actions", "webhook-enabled-switch"]
|
|
28421
|
+
},
|
|
28422
|
+
"webhook-actions": {
|
|
28423
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/webhooks/webhook-actions.tsx",
|
|
28424
|
+
content: () => readTemplate("pages/settings/webhooks/webhook-actions.tsx"),
|
|
28425
|
+
base: "cwd",
|
|
28426
|
+
dependencies: ["use-webhooks"]
|
|
28427
|
+
},
|
|
28428
|
+
"webhook-enabled-switch": {
|
|
28429
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/webhooks/webhook-enabled-switch.tsx",
|
|
28430
|
+
content: () => readTemplate("pages/settings/webhooks/webhook-enabled-switch.tsx"),
|
|
28431
|
+
base: "cwd",
|
|
28432
|
+
dependencies: ["use-webhooks"]
|
|
28433
|
+
},
|
|
28434
|
+
"webhook-endpoint-dialog": {
|
|
28435
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/webhooks/webhook-endpoint-dialog.tsx",
|
|
28436
|
+
content: () => readTemplate("pages/settings/webhooks/webhook-endpoint-dialog.tsx"),
|
|
28437
|
+
base: "cwd",
|
|
28438
|
+
dependencies: ["use-webhooks", "webhooks-action"]
|
|
28439
|
+
},
|
|
28440
|
+
"delete-webhook-dialog": {
|
|
28441
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/webhooks/delete-webhook-dialog.tsx",
|
|
28442
|
+
content: () => readTemplate("pages/settings/webhooks/delete-webhook-dialog.tsx"),
|
|
28443
|
+
base: "cwd",
|
|
28444
|
+
dependencies: ["webhooks-action"]
|
|
28445
|
+
},
|
|
28446
|
+
"webhooks-logs-page": {
|
|
28447
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/webhooks/logs/page.tsx",
|
|
28448
|
+
content: () => readTemplate("pages/settings/webhooks/webhooks-logs-page.tsx"),
|
|
28449
|
+
base: "cwd",
|
|
28450
|
+
dependencies: ["webhooks-logs-page-content", "webhooks-page-skeleton"]
|
|
28451
|
+
},
|
|
28452
|
+
"webhooks-logs-page-content": {
|
|
28453
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/webhooks/webhooks-logs-page-content.tsx",
|
|
28454
|
+
content: () => readTemplate("pages/settings/webhooks/webhooks-logs-page-content.tsx"),
|
|
28455
|
+
base: "cwd",
|
|
28456
|
+
dependencies: ["webhooks-logs-table", "webhooks-logs-columns", "use-webhooks"]
|
|
28457
|
+
},
|
|
28458
|
+
"webhooks-logs-table": {
|
|
28459
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/webhooks/webhooks-logs-table.tsx",
|
|
28460
|
+
content: () => readTemplate("pages/settings/webhooks/webhooks-logs-table.tsx"),
|
|
28461
|
+
base: "cwd",
|
|
28462
|
+
dependencies: ["use-webhooks"]
|
|
28463
|
+
},
|
|
28464
|
+
"webhooks-logs-columns": {
|
|
28465
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/webhooks/webhooks-logs-columns.tsx",
|
|
28466
|
+
content: () => readTemplate("pages/settings/webhooks/webhooks-logs-columns.tsx"),
|
|
28467
|
+
base: "cwd",
|
|
28468
|
+
dependencies: ["webhooks-action"]
|
|
28469
|
+
},
|
|
28301
28470
|
// Lib
|
|
28302
28471
|
"email-index": {
|
|
28303
28472
|
relPath: "lib/actions/email/index.ts",
|
|
@@ -28375,8 +28544,7 @@ var TEMPLATE_REGISTRY = {
|
|
|
28375
28544
|
"form-settings-types",
|
|
28376
28545
|
"get-form-settings-action",
|
|
28377
28546
|
"upsert-form-settings-action",
|
|
28378
|
-
"get-all-form-settings-action"
|
|
28379
|
-
"test-form-webhook-action"
|
|
28547
|
+
"get-all-form-settings-action"
|
|
28380
28548
|
]
|
|
28381
28549
|
},
|
|
28382
28550
|
"form-settings-types": {
|
|
@@ -28398,9 +28566,87 @@ var TEMPLATE_REGISTRY = {
|
|
|
28398
28566
|
content: () => readTemplate("lib/actions/forms/get-all-form-settings.ts"),
|
|
28399
28567
|
dependencies: ["form-settings-types"]
|
|
28400
28568
|
},
|
|
28401
|
-
"
|
|
28402
|
-
relPath: "lib/actions/
|
|
28403
|
-
content: () => readTemplate("lib/actions/
|
|
28569
|
+
"webhooks-action": {
|
|
28570
|
+
relPath: "lib/actions/webhooks/index.ts",
|
|
28571
|
+
content: () => readTemplate("lib/actions/webhooks/index.ts"),
|
|
28572
|
+
dependencies: [
|
|
28573
|
+
"webhooks-action-types",
|
|
28574
|
+
"internal-get-active-endpoints-action",
|
|
28575
|
+
"webhooks-dispatch",
|
|
28576
|
+
"get-webhooks-action",
|
|
28577
|
+
"create-webhook-action",
|
|
28578
|
+
"update-webhook-action",
|
|
28579
|
+
"delete-webhook-action",
|
|
28580
|
+
"get-webhook-secret-action",
|
|
28581
|
+
"regenerate-webhook-secret-action",
|
|
28582
|
+
"get-webhook-subscriptions-action",
|
|
28583
|
+
"send-test-webhook-action",
|
|
28584
|
+
"get-webhook-deliveries-action",
|
|
28585
|
+
"webhooks-register-action"
|
|
28586
|
+
]
|
|
28587
|
+
},
|
|
28588
|
+
"webhooks-action-types": {
|
|
28589
|
+
relPath: "lib/actions/webhooks/types.ts",
|
|
28590
|
+
content: () => readTemplate("lib/actions/webhooks/types.ts")
|
|
28591
|
+
},
|
|
28592
|
+
"internal-get-active-endpoints-action": {
|
|
28593
|
+
relPath: "lib/actions/webhooks/internal-get-active-endpoints.ts",
|
|
28594
|
+
content: () => readTemplate("lib/actions/webhooks/internal-get-active-endpoints.ts")
|
|
28595
|
+
},
|
|
28596
|
+
"webhooks-dispatch": {
|
|
28597
|
+
relPath: "lib/actions/webhooks/dispatch.ts",
|
|
28598
|
+
content: () => readTemplate("lib/actions/webhooks/dispatch.ts"),
|
|
28599
|
+
dependencies: ["webhook-signature", "internal-get-active-endpoints-action"]
|
|
28600
|
+
},
|
|
28601
|
+
"get-webhooks-action": {
|
|
28602
|
+
relPath: "lib/actions/webhooks/get-webhooks.ts",
|
|
28603
|
+
content: () => readTemplate("lib/actions/webhooks/get-webhooks.ts"),
|
|
28604
|
+
dependencies: ["webhooks-action-types"]
|
|
28605
|
+
},
|
|
28606
|
+
"create-webhook-action": {
|
|
28607
|
+
relPath: "lib/actions/webhooks/create-webhook.ts",
|
|
28608
|
+
content: () => readTemplate("lib/actions/webhooks/create-webhook.ts"),
|
|
28609
|
+
dependencies: ["webhooks-action-types", "webhook-signature"]
|
|
28610
|
+
},
|
|
28611
|
+
"update-webhook-action": {
|
|
28612
|
+
relPath: "lib/actions/webhooks/update-webhook.ts",
|
|
28613
|
+
content: () => readTemplate("lib/actions/webhooks/update-webhook.ts"),
|
|
28614
|
+
dependencies: ["webhooks-action-types"]
|
|
28615
|
+
},
|
|
28616
|
+
"delete-webhook-action": {
|
|
28617
|
+
relPath: "lib/actions/webhooks/delete-webhook.ts",
|
|
28618
|
+
content: () => readTemplate("lib/actions/webhooks/delete-webhook.ts"),
|
|
28619
|
+
dependencies: ["webhooks-action-types"]
|
|
28620
|
+
},
|
|
28621
|
+
"get-webhook-secret-action": {
|
|
28622
|
+
relPath: "lib/actions/webhooks/get-webhook-secret.ts",
|
|
28623
|
+
content: () => readTemplate("lib/actions/webhooks/get-webhook-secret.ts"),
|
|
28624
|
+
dependencies: ["webhooks-action-types"]
|
|
28625
|
+
},
|
|
28626
|
+
"regenerate-webhook-secret-action": {
|
|
28627
|
+
relPath: "lib/actions/webhooks/regenerate-webhook-secret.ts",
|
|
28628
|
+
content: () => readTemplate("lib/actions/webhooks/regenerate-webhook-secret.ts"),
|
|
28629
|
+
dependencies: ["webhooks-action-types", "webhook-signature"]
|
|
28630
|
+
},
|
|
28631
|
+
"get-webhook-subscriptions-action": {
|
|
28632
|
+
relPath: "lib/actions/webhooks/get-webhook-subscriptions.ts",
|
|
28633
|
+
content: () => readTemplate("lib/actions/webhooks/get-webhook-subscriptions.ts"),
|
|
28634
|
+
dependencies: ["webhooks-action-types"]
|
|
28635
|
+
},
|
|
28636
|
+
"send-test-webhook-action": {
|
|
28637
|
+
relPath: "lib/actions/webhooks/send-test-webhook.ts",
|
|
28638
|
+
content: () => readTemplate("lib/actions/webhooks/send-test-webhook.ts"),
|
|
28639
|
+
dependencies: ["webhooks-action-types", "webhook-signature", "webhooks-dispatch"]
|
|
28640
|
+
},
|
|
28641
|
+
"get-webhook-deliveries-action": {
|
|
28642
|
+
relPath: "lib/actions/webhooks/get-webhook-deliveries.ts",
|
|
28643
|
+
content: () => readTemplate("lib/actions/webhooks/get-webhook-deliveries.ts"),
|
|
28644
|
+
dependencies: ["webhooks-action-types"]
|
|
28645
|
+
},
|
|
28646
|
+
"webhooks-register-action": {
|
|
28647
|
+
relPath: "lib/actions/webhooks/register.ts",
|
|
28648
|
+
content: () => readTemplate("lib/actions/webhooks/register.ts"),
|
|
28649
|
+
dependencies: ["webhooks-dispatch", "webhooks-types"]
|
|
28404
28650
|
},
|
|
28405
28651
|
"entity-versions-action": {
|
|
28406
28652
|
relPath: "lib/actions/entity-versions/index.ts",
|
|
@@ -28688,44 +28934,50 @@ var TEMPLATE_REGISTRY = {
|
|
|
28688
28934
|
dependencies: ["use-media", "media-grid-pagination"]
|
|
28689
28935
|
},
|
|
28690
28936
|
"audit-log-page": {
|
|
28691
|
-
relPath: "app/(admin)/admin/(authenticated)/
|
|
28692
|
-
content: () => readTemplate("pages/audit-log/audit-log-page.tsx"),
|
|
28937
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/audit-log/page.tsx",
|
|
28938
|
+
content: () => readTemplate("pages/settings/audit-log/audit-log-page.tsx"),
|
|
28693
28939
|
base: "cwd",
|
|
28694
28940
|
dependencies: ["audit-log-page-content", "audit-log-page-skeleton"]
|
|
28695
28941
|
},
|
|
28696
28942
|
"audit-log-page-skeleton": {
|
|
28697
|
-
relPath: "app/(admin)/admin/(authenticated)/
|
|
28698
|
-
content: () => readTemplate("pages/audit-log/audit-log-page-skeleton.tsx"),
|
|
28943
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/audit-log/audit-log-page-skeleton.tsx",
|
|
28944
|
+
content: () => readTemplate("pages/settings/audit-log/audit-log-page-skeleton.tsx"),
|
|
28699
28945
|
base: "cwd",
|
|
28700
28946
|
dependencies: ["page-header", "skeleton"]
|
|
28701
28947
|
},
|
|
28702
28948
|
"audit-log-page-content": {
|
|
28703
|
-
relPath: "app/(admin)/admin/(authenticated)/
|
|
28704
|
-
content: () => readTemplate("pages/audit-log/audit-log-page-content.tsx"),
|
|
28949
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/audit-log/audit-log-page-content.tsx",
|
|
28950
|
+
content: () => readTemplate("pages/settings/audit-log/audit-log-page-content.tsx"),
|
|
28705
28951
|
base: "cwd",
|
|
28706
28952
|
dependencies: [
|
|
28953
|
+
"audit-log-columns",
|
|
28707
28954
|
"audit-log-detail-drawer",
|
|
28708
|
-
"
|
|
28709
|
-
"button",
|
|
28710
|
-
"card",
|
|
28711
|
-
"data-grid",
|
|
28712
|
-
"data-table-pagination",
|
|
28955
|
+
"audit-log-table",
|
|
28713
28956
|
"entity-filters-bar",
|
|
28714
|
-
"page-header"
|
|
28715
|
-
"sort-indicator",
|
|
28716
|
-
"use-table-utils",
|
|
28717
|
-
"use-audit-log"
|
|
28957
|
+
"page-header"
|
|
28718
28958
|
]
|
|
28719
28959
|
},
|
|
28960
|
+
"audit-log-table": {
|
|
28961
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/audit-log/audit-log-table.tsx",
|
|
28962
|
+
content: () => readTemplate("pages/settings/audit-log/audit-log-table.tsx"),
|
|
28963
|
+
base: "cwd",
|
|
28964
|
+
dependencies: ["data-grid", "data-table-pagination", "use-audit-log", "use-table-utils"]
|
|
28965
|
+
},
|
|
28966
|
+
"audit-log-columns": {
|
|
28967
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/audit-log/audit-log-columns.tsx",
|
|
28968
|
+
content: () => readTemplate("pages/settings/audit-log/audit-log-columns.tsx"),
|
|
28969
|
+
base: "cwd",
|
|
28970
|
+
dependencies: ["badge", "button", "sort-indicator"]
|
|
28971
|
+
},
|
|
28720
28972
|
"audit-log-detail-drawer": {
|
|
28721
|
-
relPath: "app/(admin)/admin/(authenticated)/
|
|
28722
|
-
content: () => readTemplate("pages/audit-log/audit-log-detail-drawer.tsx"),
|
|
28973
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/audit-log/audit-log-detail-drawer.tsx",
|
|
28974
|
+
content: () => readTemplate("pages/settings/audit-log/audit-log-detail-drawer.tsx"),
|
|
28723
28975
|
base: "cwd",
|
|
28724
28976
|
dependencies: ["audit-log-detail-row", "badge", "drawer", "scroll-area"]
|
|
28725
28977
|
},
|
|
28726
28978
|
"audit-log-detail-row": {
|
|
28727
|
-
relPath: "app/(admin)/admin/(authenticated)/
|
|
28728
|
-
content: () => readTemplate("pages/audit-log/audit-log-detail-row.tsx"),
|
|
28979
|
+
relPath: "app/(admin)/admin/(authenticated)/settings/audit-log/audit-log-detail-row.tsx",
|
|
28980
|
+
content: () => readTemplate("pages/settings/audit-log/audit-log-detail-row.tsx"),
|
|
28729
28981
|
base: "cwd"
|
|
28730
28982
|
}
|
|
28731
28983
|
};
|