@betterportal/config-manager 10.6.30 → 10.6.32
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/lib/.bsb/clients/service-betterportal-config-manager.d.ts +1 -1
- package/lib/.bsb/clients/service-betterportal-config-manager.js +1 -1
- package/lib/bp-contracts/org.betterportal.config-manager.json +1 -1
- package/lib/plugins/service-betterportal-config-manager/adminApi.d.ts +3 -2
- package/lib/plugins/service-betterportal-config-manager/adminApi.d.ts.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/adminApi.js +58 -36
- package/lib/plugins/service-betterportal-config-manager/adminApi.js.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/appQueries.d.ts +976 -0
- package/lib/plugins/service-betterportal-config-manager/appQueries.d.ts.map +1 -0
- package/lib/plugins/service-betterportal-config-manager/appQueries.js +330 -0
- package/lib/plugins/service-betterportal-config-manager/appQueries.js.map +1 -0
- package/lib/plugins/service-betterportal-config-manager/index.d.ts +6 -0
- package/lib/plugins/service-betterportal-config-manager/index.d.ts.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/index.js +83 -23
- package/lib/plugins/service-betterportal-config-manager/index.js.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/m2mConnections.d.ts +6 -3
- package/lib/plugins/service-betterportal-config-manager/m2mConnections.d.ts.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/m2mConnections.js.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/menuEditor.d.ts +2 -1
- package/lib/plugins/service-betterportal-config-manager/menuEditor.d.ts.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/menuEditor.js +131 -160
- package/lib/plugins/service-betterportal-config-manager/menuEditor.js.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/previewEnvironments.d.ts +1 -1
- package/lib/plugins/service-betterportal-config-manager/previewEnvironments.d.ts.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/previewEnvironments.js.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/routeContext.d.ts +2 -0
- package/lib/plugins/service-betterportal-config-manager/routeContext.d.ts.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/routeContext.js.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/storage/appData.d.ts +1 -1
- package/lib/plugins/service-betterportal-config-manager/storage/appData.d.ts.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/storage/appData.js +12 -5
- package/lib/plugins/service-betterportal-config-manager/storage/appData.js.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/storage/core.d.ts +5 -3
- package/lib/plugins/service-betterportal-config-manager/storage/core.d.ts.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/storage/core.js +1 -1
- package/lib/plugins/service-betterportal-config-manager/storage/core.js.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/storage/entities.d.ts.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/storage/entities.js +4 -2
- package/lib/plugins/service-betterportal-config-manager/storage/entities.js.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/storage/postgres.d.ts +19 -2
- package/lib/plugins/service-betterportal-config-manager/storage/postgres.d.ts.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/storage/postgres.js +74 -22
- package/lib/plugins/service-betterportal-config-manager/storage/postgres.js.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/syncApi.d.ts +4 -3
- package/lib/plugins/service-betterportal-config-manager/syncApi.d.ts.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/syncApi.js.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/tenantManagement.d.ts.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/tenantManagement.js +3 -1
- package/lib/plugins/service-betterportal-config-manager/tenantManagement.js.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/webhooks.d.ts.map +1 -1
- package/lib/plugins/service-betterportal-config-manager/webhooks.js +147 -54
- package/lib/plugins/service-betterportal-config-manager/webhooks.js.map +1 -1
- package/lib/schemas/service-betterportal-config-manager.json +1 -1
- package/lib/schemas/service-betterportal-config-manager.plugin.json +1 -1
- package/package.json +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated BSB virtual client for service-betterportal-config-manager
|
|
3
3
|
* DO NOT EDIT - Regenerated on every build
|
|
4
|
-
* @version 10.6.
|
|
4
|
+
* @version 10.6.32
|
|
5
5
|
*/
|
|
6
6
|
import { ServiceClient, BSBService } from "@bsb/base";
|
|
7
7
|
import type { Observable, BSBServiceClientDefinition, EventInputType } from "@bsb/base";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated BSB virtual client for service-betterportal-config-manager
|
|
3
3
|
* DO NOT EDIT - Regenerated on every build
|
|
4
|
-
* @version 10.6.
|
|
4
|
+
* @version 10.6.32
|
|
5
5
|
*/
|
|
6
6
|
import { ServiceClient, importPortableSchema, createFireAndForgetEvent, createBroadcastEvent, createEventSchemas } from "@bsb/base";
|
|
7
7
|
const _webhookDeliveryAvailableSchema = importPortableSchema(JSON.parse("{\"anyvaliVersion\":\"1.0\",\"schemaVersion\":\"1.1\",\"root\":{\"kind\":\"object\",\"properties\":{},\"required\":[],\"unknownKeys\":\"strip\"},\"definitions\":{},\"extensions\":{}}"));
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"pluginId": "org.betterportal.config-manager",
|
|
5
5
|
"title": "BetterPortal Config Manager",
|
|
6
6
|
"description": "Admin-facing BetterPortal service for discovering and managing service config surfaces.",
|
|
7
|
-
"version": "10.6.
|
|
7
|
+
"version": "10.6.32",
|
|
8
8
|
"category": "service",
|
|
9
9
|
"deploymentModes": [
|
|
10
10
|
"self-hosted"
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { type AppDatabase, type AppEditorData } from "./appQueries.js";
|
|
1
2
|
import type { BetterPortalH3App, PlatformConfigStore, JsonValue } from "@betterportal/framework";
|
|
2
3
|
import type { BetterPortalConfig, BetterPortalApp } from "@betterportal/framework";
|
|
3
4
|
import type { CpBootstrapState } from "./cpBootstrap.js";
|
|
4
5
|
export declare function validateFixedParamValue(name: string, value: string, paramsSchema?: Record<string, JsonValue>): string | undefined;
|
|
5
|
-
declare function automationServiceCatalog(config:
|
|
6
|
+
declare function automationServiceCatalog(config: AppEditorData, appDef: BetterPortalApp): {
|
|
6
7
|
protocol: string;
|
|
7
8
|
tenantId: string;
|
|
8
9
|
appId: string;
|
|
@@ -305,7 +306,7 @@ export declare function purgeServiceReferences(config: BetterPortalConfig, tenan
|
|
|
305
306
|
m2mGrantsRemoved: number;
|
|
306
307
|
webhooksRemoved: number;
|
|
307
308
|
};
|
|
308
|
-
export declare function registerAdminApiRoutes(app: BetterPortalH3App, store: PlatformConfigStore, cpState: CpBootstrapState): void;
|
|
309
|
+
export declare function registerAdminApiRoutes(app: BetterPortalH3App, store: PlatformConfigStore, cpState: CpBootstrapState, database?: AppDatabase): void;
|
|
309
310
|
export declare function renderConfigClientShell(d: {
|
|
310
311
|
hostname: string;
|
|
311
312
|
tenantId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adminApi.d.ts","sourceRoot":"","sources":["../../../src/plugins/service-betterportal-config-manager/adminApi.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iBAAiB,EAEjB,mBAAmB,EACnB,SAAS,EACV,MAAM,yBAAyB,CAAC;AAcjC,OAAO,KAAK,EAAuE,kBAAkB,EAAE,eAAe,EAAgE,MAAM,yBAAyB,CAAC;AACtN,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"adminApi.d.ts","sourceRoot":"","sources":["../../../src/plugins/service-betterportal-config-manager/adminApi.ts"],"names":[],"mappings":"AACA,OAAO,EAA2C,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhH,OAAO,KAAK,EACV,iBAAiB,EAEjB,mBAAmB,EACnB,SAAS,EACV,MAAM,yBAAyB,CAAC;AAcjC,OAAO,KAAK,EAAuE,kBAAkB,EAAE,eAAe,EAAgE,MAAM,yBAAyB,CAAC;AACtN,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAkLzD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GACvC,MAAM,GAAG,SAAS,CAepB;AAwGD,iBAAS,wBAAwB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkE/E;AAGD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,wBAAwB,CAAC,GAAG,MAAM,CA4CpG;AA8RD,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAiDtH;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG;IACvG,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACzB,CA2FA;AAkPD,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,iBAAiB,EACtB,KAAK,EAAE,mBAAmB,EAC1B,OAAO,EAAE,gBAAgB,EACzB,QAAQ,CAAC,EAAE,WAAW,GACrB,IAAI,CAyjDN;AAwPD,wBAAgB,uBAAuB,CAAC,CAAC,EAAE;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD,GAAG,MAAM,CAwaT"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { eventObservability } from "@betterportal/framework";
|
|
2
|
+
import { editAppRows, readApp, readRequestConfig } from "./appQueries.js";
|
|
1
3
|
import { isMenuRouteExcluded } from "./routeMounts.js";
|
|
2
4
|
import * as av from "anyvali";
|
|
3
5
|
import { AppAuthRoleSchema, eventHeaders, htmlResponse, jsonResponse, resolveEmbeddedRequestContext, signServiceConfigTicket, uuidv7, BetterPortalMenuItemSchema, BetterPortalThemeConfigSchema } from "@betterportal/framework";
|
|
@@ -72,7 +74,7 @@ function validationError(event, message) {
|
|
|
72
74
|
}
|
|
73
75
|
// PostgreSQL edits read current rows under an app-scoped transaction.
|
|
74
76
|
// File stores retain their existing single-process save semantics.
|
|
75
|
-
async function editApp(store, appId, action) {
|
|
77
|
+
async function editApp(store, appId, action, database, event) {
|
|
76
78
|
const apply = async (config) => {
|
|
77
79
|
const response = await action(config);
|
|
78
80
|
if (!response.ok)
|
|
@@ -80,6 +82,8 @@ async function editApp(store, appId, action) {
|
|
|
80
82
|
return response;
|
|
81
83
|
};
|
|
82
84
|
try {
|
|
85
|
+
if (database)
|
|
86
|
+
return await editAppRows(database, appId, event ? eventObservability(event) : undefined, action);
|
|
83
87
|
if (store.mutateApp)
|
|
84
88
|
return await store.mutateApp(appId, apply);
|
|
85
89
|
const config = await store.loadConfig();
|
|
@@ -984,12 +988,29 @@ function automationAppFromRequest(config, event) {
|
|
|
984
988
|
: config.apps.find((entry) => tenantUrl && appMatchesTenantUrl(entry, tenantUrl));
|
|
985
989
|
return resolved && !isPreviewApp(config, resolved.id) ? resolved : undefined;
|
|
986
990
|
}
|
|
987
|
-
export function registerAdminApiRoutes(app, store, cpState) {
|
|
991
|
+
export function registerAdminApiRoutes(app, store, cpState, database) {
|
|
992
|
+
const readCurrentApp = async (event) => {
|
|
993
|
+
if (!database) {
|
|
994
|
+
const config = await store.loadConfig();
|
|
995
|
+
return { config, appDef: currentAppFromRequest(config, event) };
|
|
996
|
+
}
|
|
997
|
+
const appId = new URL(event.req.url, RELATIVE_URL_PARSE_BASE).searchParams.get("appId") ?? event.req.headers.get("x-bp-app-id");
|
|
998
|
+
if (appId) {
|
|
999
|
+
const config = await readApp(database, appId);
|
|
1000
|
+
const appDef = config.apps[0];
|
|
1001
|
+
return { config, appDef: appDef && !isPreviewApp(config, appDef.id) ? appDef : undefined };
|
|
1002
|
+
}
|
|
1003
|
+
const config = await readRequestConfig(database, eventHeaders(event), eventObservability(event));
|
|
1004
|
+
return { config, appDef: currentAppFromRequest(config, event) };
|
|
1005
|
+
};
|
|
988
1006
|
app.use(`${API_BASE}/**`, async (event) => {
|
|
989
|
-
const
|
|
1007
|
+
const deployments = database
|
|
1008
|
+
? (await database.pool.query(`select value->>'tenantId' as "tenantId", value->>'appId' as "appId"
|
|
1009
|
+
from ${database.entities} where scope_id=$1 and kind='previewEnvironmentDeployments'`, [database.scope])).rows
|
|
1010
|
+
: (await store.loadConfig()).previewEnvironmentDeployments;
|
|
990
1011
|
const url = new URL(event.req.url, RELATIVE_URL_PARSE_BASE);
|
|
991
1012
|
const requestIds = `${url.pathname}\n${url.search}\n${event.req.headers.get("x-bp-tenant-id") ?? ""}\n${event.req.headers.get("x-bp-app-id") ?? ""}`;
|
|
992
|
-
const targetsPreview =
|
|
1013
|
+
const targetsPreview = deployments.some((deployment) => requestIds.includes(deployment.tenantId) || requestIds.includes(deployment.appId));
|
|
993
1014
|
if (targetsPreview)
|
|
994
1015
|
return jsonResponse({ error: "Preview resources are managed through Preview Environments" }, 404);
|
|
995
1016
|
});
|
|
@@ -1014,8 +1035,7 @@ export function registerAdminApiRoutes(app, store, cpState) {
|
|
|
1014
1035
|
});
|
|
1015
1036
|
});
|
|
1016
1037
|
app.get("/.well-known/bp/manage/current", async (event) => {
|
|
1017
|
-
const config = await
|
|
1018
|
-
const appDef = currentAppFromRequest(config, event);
|
|
1038
|
+
const { config, appDef } = await readCurrentApp(event);
|
|
1019
1039
|
if (!appDef)
|
|
1020
1040
|
return jsonResponse({ error: "Unable to resolve current BetterPortal app" }, 404);
|
|
1021
1041
|
const tenant = config.tenants.find((entry) => entry.id === appDef.tenantId);
|
|
@@ -1039,8 +1059,7 @@ export function registerAdminApiRoutes(app, store, cpState) {
|
|
|
1039
1059
|
});
|
|
1040
1060
|
});
|
|
1041
1061
|
app.get("/.well-known/bp/manage/services", async (event) => {
|
|
1042
|
-
const config = await
|
|
1043
|
-
const appDef = currentAppFromRequest(config, event);
|
|
1062
|
+
const { config, appDef } = await readCurrentApp(event);
|
|
1044
1063
|
if (!appDef)
|
|
1045
1064
|
return jsonResponse({ error: "Unable to resolve current BetterPortal app" }, 404);
|
|
1046
1065
|
return jsonResponse(automationServiceCatalog(config, appDef));
|
|
@@ -1073,40 +1092,43 @@ export function registerAdminApiRoutes(app, store, cpState) {
|
|
|
1073
1092
|
return jsonResponse({ ok: true, activation }, 201);
|
|
1074
1093
|
});
|
|
1075
1094
|
app.get("/.well-known/bp/manage/routes", async (event) => {
|
|
1076
|
-
const
|
|
1077
|
-
const appDef = currentAppFromRequest(config, event);
|
|
1095
|
+
const { appDef } = await readCurrentApp(event);
|
|
1078
1096
|
if (!appDef)
|
|
1079
1097
|
return jsonResponse({ error: "Unable to resolve current BetterPortal app" }, 404);
|
|
1080
1098
|
return jsonResponse({ appId: appDef.id, routes: appDef.routes });
|
|
1081
1099
|
});
|
|
1082
1100
|
app.post("/.well-known/bp/manage/routes", async (event) => {
|
|
1083
|
-
const
|
|
1084
|
-
const appDef = currentAppFromRequest(config, event);
|
|
1101
|
+
const { appDef } = await readCurrentApp(event);
|
|
1085
1102
|
if (!appDef)
|
|
1086
1103
|
return jsonResponse({ error: "Unable to resolve current BetterPortal app" }, 404);
|
|
1087
1104
|
const body = await readFormOrJsonBody(event);
|
|
1088
1105
|
const parsed = parseRouteCreateBody(body);
|
|
1089
1106
|
if (parsed.error || !parsed.route)
|
|
1090
1107
|
return validationError(event, parsed.error ?? "Invalid route");
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1108
|
+
return editApp(store, appDef.id, async (data) => {
|
|
1109
|
+
const current = data.apps.find(app => app.id === appDef.id);
|
|
1110
|
+
if (!current || isPreviewApp(data, current.id))
|
|
1111
|
+
return jsonResponse({ error: "App not found" }, 404);
|
|
1112
|
+
const serviceError = validateRegisteredRouteService(data, current, parsed.route.serviceId);
|
|
1113
|
+
if (serviceError)
|
|
1114
|
+
return validationError(event, serviceError);
|
|
1115
|
+
if (current.routes.some(candidate => appRoutePatternKey(candidate.path) === appRoutePatternKey(parsed.route.path))) {
|
|
1116
|
+
return validationError(event, `A route already exists at ${parsed.route.path}.`);
|
|
1117
|
+
}
|
|
1118
|
+
const route = { id: uuidv7(), ...parsed.route };
|
|
1119
|
+
current.routes.push(route);
|
|
1120
|
+
addRouteDependencies(current, route);
|
|
1121
|
+
return jsonResponse({ ok: true }, 201);
|
|
1122
|
+
}, database, event);
|
|
1099
1123
|
});
|
|
1100
1124
|
app.get("/.well-known/bp/manage/fragments", async (event) => {
|
|
1101
|
-
const
|
|
1102
|
-
const appDef = currentAppFromRequest(config, event);
|
|
1125
|
+
const { appDef } = await readCurrentApp(event);
|
|
1103
1126
|
if (!appDef)
|
|
1104
1127
|
return jsonResponse({ error: "Unable to resolve current BetterPortal app" }, 404);
|
|
1105
1128
|
return jsonResponse({ appId: appDef.id, fragments: appDef.fragments });
|
|
1106
1129
|
});
|
|
1107
1130
|
app.get("/.well-known/bp/manage/theme", async (event) => {
|
|
1108
|
-
const
|
|
1109
|
-
const appDef = currentAppFromRequest(config, event);
|
|
1131
|
+
const { appDef } = await readCurrentApp(event);
|
|
1110
1132
|
if (!appDef)
|
|
1111
1133
|
return jsonResponse({ error: "Unable to resolve current BetterPortal app" }, 404);
|
|
1112
1134
|
return jsonResponse({ appId: appDef.id, themeConfig: appDef.themeConfig });
|
|
@@ -1745,7 +1767,7 @@ export function registerAdminApiRoutes(app, store, cpState) {
|
|
|
1745
1767
|
const appId = getParam(event, "appId");
|
|
1746
1768
|
if (!appId)
|
|
1747
1769
|
return jsonResponse({ error: "appId required" }, 400);
|
|
1748
|
-
const
|
|
1770
|
+
const appDef = database ? (await readApp(database, appId)).apps[0] : (await getAppOr404(appId)).appDef;
|
|
1749
1771
|
if (!appDef)
|
|
1750
1772
|
return jsonResponse({ error: "App not found" }, 404);
|
|
1751
1773
|
const auth = appDef.auth;
|
|
@@ -1777,7 +1799,7 @@ export function registerAdminApiRoutes(app, store, cpState) {
|
|
|
1777
1799
|
return parsedRoles;
|
|
1778
1800
|
authResult.auth.roles = parsedRoles;
|
|
1779
1801
|
return jsonResponse({ ok: true, roles: parsedRoles.length });
|
|
1780
|
-
});
|
|
1802
|
+
}, database, event);
|
|
1781
1803
|
});
|
|
1782
1804
|
app.put(`${API_BASE}/services/self-mutation`, async (event) => {
|
|
1783
1805
|
const parsed = SelfMutationRequestSchema.safeParse(await readJsonBody(event));
|
|
@@ -1813,7 +1835,7 @@ export function registerAdminApiRoutes(app, store, cpState) {
|
|
|
1813
1835
|
return parsedRoles;
|
|
1814
1836
|
authResult.auth.roles = parsedRoles;
|
|
1815
1837
|
return jsonResponse({ ok: true, type, roles: parsedRoles.length });
|
|
1816
|
-
});
|
|
1838
|
+
}, database, event);
|
|
1817
1839
|
});
|
|
1818
1840
|
app.post(`${API_BASE}/apps/:appId/auth/roles`, async (event) => {
|
|
1819
1841
|
const appId = getParam(event, "appId");
|
|
@@ -1849,7 +1871,7 @@ export function registerAdminApiRoutes(app, store, cpState) {
|
|
|
1849
1871
|
if (wantsHtmx(event))
|
|
1850
1872
|
return htmxReload(`/auth?appId=${encodeURIComponent(appId)}`);
|
|
1851
1873
|
return jsonResponse(role, 201);
|
|
1852
|
-
});
|
|
1874
|
+
}, database, event);
|
|
1853
1875
|
});
|
|
1854
1876
|
app.put(`${API_BASE}/apps/:appId/auth/roles/:roleId`, async (event) => {
|
|
1855
1877
|
const appId = getParam(event, "appId");
|
|
@@ -1892,7 +1914,7 @@ export function registerAdminApiRoutes(app, store, cpState) {
|
|
|
1892
1914
|
if (wantsHtmx(event))
|
|
1893
1915
|
return htmxReload(`/auth?appId=${encodeURIComponent(appId)}`);
|
|
1894
1916
|
return jsonResponse(role);
|
|
1895
|
-
});
|
|
1917
|
+
}, database, event);
|
|
1896
1918
|
});
|
|
1897
1919
|
app.delete(`${API_BASE}/apps/:appId/auth/roles/:roleId`, async (event) => {
|
|
1898
1920
|
const appId = getParam(event, "appId");
|
|
@@ -1914,7 +1936,7 @@ export function registerAdminApiRoutes(app, store, cpState) {
|
|
|
1914
1936
|
if (wantsHtmx(event))
|
|
1915
1937
|
return htmxReload(`/auth?appId=${encodeURIComponent(appId)}`);
|
|
1916
1938
|
return jsonResponse({ ok: true });
|
|
1917
|
-
});
|
|
1939
|
+
}, database, event);
|
|
1918
1940
|
});
|
|
1919
1941
|
// Service connections (per app)
|
|
1920
1942
|
app.get(`${API_BASE}/apps/:appId/m2m/connections`, async (event) => {
|
|
@@ -1992,7 +2014,7 @@ export function registerAdminApiRoutes(app, store, cpState) {
|
|
|
1992
2014
|
const appId = getParam(event, "appId");
|
|
1993
2015
|
if (!appId)
|
|
1994
2016
|
return jsonResponse({ error: "appId required" }, 400);
|
|
1995
|
-
const config = await store.loadConfig();
|
|
2017
|
+
const config = database ? await readApp(database, appId) : await store.loadConfig();
|
|
1996
2018
|
const appDef = config.apps.find((a) => a.id === appId);
|
|
1997
2019
|
if (!appDef)
|
|
1998
2020
|
return jsonResponse({ error: "App not found" }, 404);
|
|
@@ -2026,7 +2048,7 @@ export function registerAdminApiRoutes(app, store, cpState) {
|
|
|
2026
2048
|
if (wantsHtmx(event))
|
|
2027
2049
|
return htmxReload(routesReloadPath(appId));
|
|
2028
2050
|
return jsonResponse({ ok: true, id: route.id }, 201);
|
|
2029
|
-
});
|
|
2051
|
+
}, database, event);
|
|
2030
2052
|
});
|
|
2031
2053
|
app.put(`${API_BASE}/apps/:appId/routes/:routeId`, async (event) => {
|
|
2032
2054
|
const appId = getParam(event, "appId");
|
|
@@ -2159,7 +2181,7 @@ export function registerAdminApiRoutes(app, store, cpState) {
|
|
|
2159
2181
|
if (wantsHtmx(event))
|
|
2160
2182
|
return htmxReload(routesReloadPath(appId, route.kind === "api" ? route.serviceId : undefined));
|
|
2161
2183
|
return jsonResponse({ ok: true });
|
|
2162
|
-
});
|
|
2184
|
+
}, database, event);
|
|
2163
2185
|
});
|
|
2164
2186
|
app.delete(`${API_BASE}/apps/:appId/routes/:routeId`, async (event) => {
|
|
2165
2187
|
const appId = getParam(event, "appId");
|
|
@@ -2193,14 +2215,14 @@ export function registerAdminApiRoutes(app, store, cpState) {
|
|
|
2193
2215
|
if (wantsHtmx(event))
|
|
2194
2216
|
return htmxReload(`/routes?appId=${encodeURIComponent(appId)}`);
|
|
2195
2217
|
return jsonResponse({ ok: true });
|
|
2196
|
-
});
|
|
2218
|
+
}, database, event);
|
|
2197
2219
|
});
|
|
2198
2220
|
// Menu (per app)
|
|
2199
2221
|
app.get(`${API_BASE}/apps/:appId/menu`, async (event) => {
|
|
2200
2222
|
const appId = getParam(event, "appId");
|
|
2201
2223
|
if (!appId)
|
|
2202
2224
|
return jsonResponse({ error: "appId required" }, 400);
|
|
2203
|
-
const config = await store.loadConfig();
|
|
2225
|
+
const config = database ? await readApp(database, appId) : await store.loadConfig();
|
|
2204
2226
|
const appDef = config.apps.find((a) => a.id === appId);
|
|
2205
2227
|
if (!appDef)
|
|
2206
2228
|
return jsonResponse({ error: "App not found" }, 404);
|
|
@@ -2225,7 +2247,7 @@ export function registerAdminApiRoutes(app, store, cpState) {
|
|
|
2225
2247
|
return jsonResponse({ error: "Menu contains a missing or excluded route" }, 400);
|
|
2226
2248
|
appDef.menu = menu;
|
|
2227
2249
|
return jsonResponse({ ok: true });
|
|
2228
|
-
});
|
|
2250
|
+
}, database, event);
|
|
2229
2251
|
});
|
|
2230
2252
|
// Full config (read-only)
|
|
2231
2253
|
app.get(`${API_BASE}/config`, async () => {
|