@objectstack/rest 5.2.0 → 6.1.1
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/index.cjs +274 -274
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -19
- package/dist/index.d.ts +19 -19
- package/dist/index.js +274 -274
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -286,7 +286,7 @@ function mapDataError(error, object) {
|
|
|
286
286
|
}
|
|
287
287
|
const raw = String(error?.message ?? error ?? "");
|
|
288
288
|
const lower = raw.toLowerCase();
|
|
289
|
-
if (raw.includes("[
|
|
289
|
+
if (raw.includes("[EnvironmentKernelFactory]") && (lower.includes("missing database_url") || lower.includes("not found"))) {
|
|
290
290
|
const isProvisioning = lower.includes("status='provisioning'") || lower.includes("status='pending'");
|
|
291
291
|
const isFailed = lower.includes("status='failed'");
|
|
292
292
|
return {
|
|
@@ -443,7 +443,7 @@ function rowsToCsv(fields, rows, includeHeader) {
|
|
|
443
443
|
return lines.join("\r\n") + (lines.length > 0 ? "\r\n" : "");
|
|
444
444
|
}
|
|
445
445
|
var RestServer = class {
|
|
446
|
-
constructor(server, protocol, config = {}, kernelManager, envRegistry,
|
|
446
|
+
constructor(server, protocol, config = {}, kernelManager, envRegistry, defaultEnvironmentIdProvider, authServiceProvider, objectQLProvider, emailServiceProvider, sharingServiceProvider, reportsServiceProvider, approvalsServiceProvider, sharingRulesServiceProvider, i18nServiceProvider) {
|
|
447
447
|
/**
|
|
448
448
|
* Lazily load the OpenAPI spec JSON shipped by @objectstack/spec.
|
|
449
449
|
* Cached after first read. Resilient to missing files / parse errors
|
|
@@ -455,7 +455,7 @@ var RestServer = class {
|
|
|
455
455
|
this.routeManager = new RouteManager(server);
|
|
456
456
|
this.kernelManager = kernelManager;
|
|
457
457
|
this.envRegistry = envRegistry;
|
|
458
|
-
this.
|
|
458
|
+
this.defaultEnvironmentIdProvider = defaultEnvironmentIdProvider;
|
|
459
459
|
this.authServiceProvider = authServiceProvider;
|
|
460
460
|
this.objectQLProvider = objectQLProvider;
|
|
461
461
|
this.emailServiceProvider = emailServiceProvider;
|
|
@@ -466,20 +466,20 @@ var RestServer = class {
|
|
|
466
466
|
this.i18nServiceProvider = i18nServiceProvider;
|
|
467
467
|
}
|
|
468
468
|
/**
|
|
469
|
-
* Resolve the protocol for a given request. When `
|
|
469
|
+
* Resolve the protocol for a given request. When `environmentId` is present
|
|
470
470
|
* and a KernelManager is wired, fetch the per-project kernel's
|
|
471
471
|
* `protocol` service so metadata / data / UI reads hit the project's
|
|
472
472
|
* own registry and datastore.
|
|
473
473
|
*
|
|
474
|
-
* When `
|
|
474
|
+
* When `environmentId` is absent on an unscoped route and an `envRegistry`
|
|
475
475
|
* is wired (runtime mode), the resolution chain is:
|
|
476
|
-
* 1. Hostname →
|
|
477
|
-
* 2. `X-
|
|
478
|
-
* 3. Default-project fallback (`
|
|
479
|
-
* `
|
|
476
|
+
* 1. Hostname → environmentId (`envRegistry.resolveByHostname`)
|
|
477
|
+
* 2. `X-Environment-Id` header → environmentId (`envRegistry.resolveById`)
|
|
478
|
+
* 3. Default-project fallback (`defaultEnvironmentIdProvider`, set by
|
|
479
|
+
* `createSingleEnvironmentPlugin`)
|
|
480
480
|
* 4. Control-plane protocol captured at boot.
|
|
481
481
|
*
|
|
482
|
-
* Special case: `
|
|
482
|
+
* Special case: `environmentId === 'platform'` is a reserved virtual id used
|
|
483
483
|
* by Studio to address the control plane through the regular project
|
|
484
484
|
* URL shape (`/projects/platform/...`). It is NOT a row in the projects
|
|
485
485
|
* table, so we must never call `KernelManager.getOrCreate('platform')`.
|
|
@@ -487,37 +487,37 @@ var RestServer = class {
|
|
|
487
487
|
* (and any other client) speak a single, uniform URL family without
|
|
488
488
|
* duplicating route logic for the platform surface.
|
|
489
489
|
*/
|
|
490
|
-
async resolveProtocol(
|
|
491
|
-
if (
|
|
492
|
-
if (!
|
|
490
|
+
async resolveProtocol(environmentId, req) {
|
|
491
|
+
if (environmentId === "platform") return this.protocol;
|
|
492
|
+
if (!environmentId && req && this.envRegistry && this.kernelManager) {
|
|
493
493
|
const host = this.extractHostname(req);
|
|
494
494
|
if (host) {
|
|
495
495
|
try {
|
|
496
496
|
const result = await this.envRegistry.resolveByHostname(host);
|
|
497
|
-
if (result?.
|
|
497
|
+
if (result?.environmentId) environmentId = result.environmentId;
|
|
498
498
|
} catch {
|
|
499
499
|
}
|
|
500
500
|
}
|
|
501
|
-
if (!
|
|
501
|
+
if (!environmentId && typeof this.envRegistry.resolveById === "function") {
|
|
502
502
|
const headerVal = this.extractProjectIdHeader(req);
|
|
503
503
|
if (headerVal) {
|
|
504
504
|
try {
|
|
505
505
|
const driver = await this.envRegistry.resolveById(headerVal);
|
|
506
|
-
if (driver)
|
|
506
|
+
if (driver) environmentId = headerVal;
|
|
507
507
|
} catch {
|
|
508
508
|
}
|
|
509
509
|
}
|
|
510
510
|
}
|
|
511
511
|
}
|
|
512
|
-
if (!
|
|
512
|
+
if (!environmentId && this.defaultEnvironmentIdProvider) {
|
|
513
513
|
try {
|
|
514
|
-
const def = this.
|
|
515
|
-
if (def)
|
|
514
|
+
const def = this.defaultEnvironmentIdProvider();
|
|
515
|
+
if (def) environmentId = def;
|
|
516
516
|
} catch {
|
|
517
517
|
}
|
|
518
518
|
}
|
|
519
|
-
if (!
|
|
520
|
-
const kernel = await this.kernelManager.getOrCreate(
|
|
519
|
+
if (!environmentId || !this.kernelManager) return this.protocol;
|
|
520
|
+
const kernel = await this.kernelManager.getOrCreate(environmentId);
|
|
521
521
|
return kernel.getServiceAsync("protocol");
|
|
522
522
|
}
|
|
523
523
|
/**
|
|
@@ -526,43 +526,43 @@ var RestServer = class {
|
|
|
526
526
|
* registered, so callers can short-circuit and skip translation rather
|
|
527
527
|
* than failing.
|
|
528
528
|
*
|
|
529
|
-
* Mirrors `resolveProtocol`'s lookup chain: explicit `
|
|
529
|
+
* Mirrors `resolveProtocol`'s lookup chain: explicit `environmentId` from the
|
|
530
530
|
* route → kernel-managed `i18n` service. Control-plane / unscoped
|
|
531
531
|
* requests intentionally return `undefined` because the platform kernel
|
|
532
532
|
* does not own per-app translation bundles.
|
|
533
533
|
*/
|
|
534
|
-
async resolveI18nService(
|
|
535
|
-
if (
|
|
536
|
-
if (!
|
|
534
|
+
async resolveI18nService(environmentId, req) {
|
|
535
|
+
if (environmentId === "platform") return void 0;
|
|
536
|
+
if (!environmentId && req && this.envRegistry && this.kernelManager) {
|
|
537
537
|
const host = this.extractHostname(req);
|
|
538
538
|
if (host) {
|
|
539
539
|
try {
|
|
540
540
|
const result = await this.envRegistry.resolveByHostname(host);
|
|
541
|
-
if (result?.
|
|
541
|
+
if (result?.environmentId) environmentId = result.environmentId;
|
|
542
542
|
} catch {
|
|
543
543
|
}
|
|
544
544
|
}
|
|
545
|
-
if (!
|
|
545
|
+
if (!environmentId && typeof this.envRegistry.resolveById === "function") {
|
|
546
546
|
const headerVal = this.extractProjectIdHeader(req);
|
|
547
547
|
if (headerVal) {
|
|
548
548
|
try {
|
|
549
549
|
const driver = await this.envRegistry.resolveById(headerVal);
|
|
550
|
-
if (driver)
|
|
550
|
+
if (driver) environmentId = headerVal;
|
|
551
551
|
} catch {
|
|
552
552
|
}
|
|
553
553
|
}
|
|
554
554
|
}
|
|
555
555
|
}
|
|
556
|
-
if (!
|
|
556
|
+
if (!environmentId && this.defaultEnvironmentIdProvider) {
|
|
557
557
|
try {
|
|
558
|
-
const def = this.
|
|
559
|
-
if (def)
|
|
558
|
+
const def = this.defaultEnvironmentIdProvider();
|
|
559
|
+
if (def) environmentId = def;
|
|
560
560
|
} catch {
|
|
561
561
|
}
|
|
562
562
|
}
|
|
563
|
-
if (
|
|
563
|
+
if (environmentId && this.kernelManager) {
|
|
564
564
|
try {
|
|
565
|
-
const kernel = await this.kernelManager.getOrCreate(
|
|
565
|
+
const kernel = await this.kernelManager.getOrCreate(environmentId);
|
|
566
566
|
const svc = await kernel.getServiceAsync("i18n");
|
|
567
567
|
if (svc) return svc;
|
|
568
568
|
} catch {
|
|
@@ -570,7 +570,7 @@ var RestServer = class {
|
|
|
570
570
|
}
|
|
571
571
|
if (this.i18nServiceProvider) {
|
|
572
572
|
try {
|
|
573
|
-
return await this.i18nServiceProvider(
|
|
573
|
+
return await this.i18nServiceProvider(environmentId);
|
|
574
574
|
} catch {
|
|
575
575
|
return void 0;
|
|
576
576
|
}
|
|
@@ -602,23 +602,23 @@ var RestServer = class {
|
|
|
602
602
|
* `undefined` for anonymous requests so callers can pass `context` as-is
|
|
603
603
|
* to the protocol layer (the SecurityPlugin treats undefined as anon).
|
|
604
604
|
*/
|
|
605
|
-
async resolveExecCtx(
|
|
605
|
+
async resolveExecCtx(environmentId, req) {
|
|
606
606
|
try {
|
|
607
|
-
if (!
|
|
607
|
+
if (!environmentId && req && this.envRegistry && this.kernelManager) {
|
|
608
608
|
const host = this.extractHostname(req);
|
|
609
609
|
if (host) {
|
|
610
610
|
try {
|
|
611
611
|
const result = await this.envRegistry.resolveByHostname(host);
|
|
612
|
-
if (result?.
|
|
612
|
+
if (result?.environmentId) environmentId = result.environmentId;
|
|
613
613
|
} catch {
|
|
614
614
|
}
|
|
615
615
|
}
|
|
616
|
-
if (!
|
|
616
|
+
if (!environmentId && typeof this.envRegistry.resolveById === "function") {
|
|
617
617
|
const headerVal = this.extractProjectIdHeader(req);
|
|
618
618
|
if (headerVal) {
|
|
619
619
|
try {
|
|
620
620
|
const driver = await this.envRegistry.resolveById(headerVal);
|
|
621
|
-
if (driver)
|
|
621
|
+
if (driver) environmentId = headerVal;
|
|
622
622
|
} catch {
|
|
623
623
|
}
|
|
624
624
|
}
|
|
@@ -626,13 +626,13 @@ var RestServer = class {
|
|
|
626
626
|
}
|
|
627
627
|
let authService;
|
|
628
628
|
let kernel;
|
|
629
|
-
if (
|
|
630
|
-
kernel = await this.kernelManager.getOrCreate(
|
|
629
|
+
if (environmentId && environmentId !== "platform" && this.kernelManager) {
|
|
630
|
+
kernel = await this.kernelManager.getOrCreate(environmentId);
|
|
631
631
|
authService = await kernel.getServiceAsync("auth").catch(() => void 0);
|
|
632
632
|
}
|
|
633
|
-
if (!authService && this.
|
|
633
|
+
if (!authService && this.defaultEnvironmentIdProvider && this.kernelManager) {
|
|
634
634
|
try {
|
|
635
|
-
const def = this.
|
|
635
|
+
const def = this.defaultEnvironmentIdProvider();
|
|
636
636
|
if (def) {
|
|
637
637
|
kernel = await this.kernelManager.getOrCreate(def);
|
|
638
638
|
authService = await kernel.getServiceAsync("auth").catch(() => void 0);
|
|
@@ -641,7 +641,7 @@ var RestServer = class {
|
|
|
641
641
|
}
|
|
642
642
|
}
|
|
643
643
|
if (!authService && this.authServiceProvider) {
|
|
644
|
-
authService = await this.authServiceProvider(
|
|
644
|
+
authService = await this.authServiceProvider(environmentId).catch(() => void 0);
|
|
645
645
|
}
|
|
646
646
|
if (!authService) return void 0;
|
|
647
647
|
let api = authService.api;
|
|
@@ -674,7 +674,7 @@ var RestServer = class {
|
|
|
674
674
|
ql = await kernel.getServiceAsync("objectql").catch(() => void 0);
|
|
675
675
|
}
|
|
676
676
|
if (!ql && this.objectQLProvider) {
|
|
677
|
-
ql = await this.objectQLProvider(
|
|
677
|
+
ql = await this.objectQLProvider(environmentId).catch(() => void 0);
|
|
678
678
|
}
|
|
679
679
|
if (ql && typeof ql.find === "function") {
|
|
680
680
|
const sysOpts = { context: { isSystem: true } };
|
|
@@ -724,7 +724,7 @@ var RestServer = class {
|
|
|
724
724
|
ql = await kernel.getServiceAsync("objectql").catch(() => void 0);
|
|
725
725
|
}
|
|
726
726
|
if (!ql && this.objectQLProvider) {
|
|
727
|
-
ql = await this.objectQLProvider(
|
|
727
|
+
ql = await this.objectQLProvider(environmentId).catch(() => void 0);
|
|
728
728
|
}
|
|
729
729
|
if (ql && typeof ql.find === "function") {
|
|
730
730
|
const sysOpts = { context: { isSystem: true } };
|
|
@@ -803,10 +803,10 @@ var RestServer = class {
|
|
|
803
803
|
* locale yields a match. Falls through unchanged for unsupported types
|
|
804
804
|
* or missing translations.
|
|
805
805
|
*/
|
|
806
|
-
async translateMetaItem(req, type,
|
|
806
|
+
async translateMetaItem(req, type, environmentId, item) {
|
|
807
807
|
if (!item || typeof item !== "object") return item;
|
|
808
808
|
if (type !== "view" && type !== "action" && type !== "object") return item;
|
|
809
|
-
const i18n = await this.resolveI18nService(
|
|
809
|
+
const i18n = await this.resolveI18nService(environmentId, req);
|
|
810
810
|
const bundle = this.buildTranslationBundle(i18n);
|
|
811
811
|
if (!bundle) return item;
|
|
812
812
|
const locale = this.extractLocale(req, i18n);
|
|
@@ -817,10 +817,10 @@ var RestServer = class {
|
|
|
817
817
|
/**
|
|
818
818
|
* Translate a list of metadata documents using `translateMetaItem`.
|
|
819
819
|
*/
|
|
820
|
-
async translateMetaItems(req, type,
|
|
820
|
+
async translateMetaItems(req, type, environmentId, items) {
|
|
821
821
|
if (!Array.isArray(items)) return items;
|
|
822
822
|
if (type !== "view" && type !== "action" && type !== "object") return items;
|
|
823
|
-
const i18n = await this.resolveI18nService(
|
|
823
|
+
const i18n = await this.resolveI18nService(environmentId, req);
|
|
824
824
|
const bundle = this.buildTranslationBundle(i18n);
|
|
825
825
|
if (!bundle) return items;
|
|
826
826
|
const locale = this.extractLocale(req, i18n);
|
|
@@ -854,7 +854,7 @@ var RestServer = class {
|
|
|
854
854
|
return String(host).split(":")[0].toLowerCase();
|
|
855
855
|
}
|
|
856
856
|
/**
|
|
857
|
-
* Pull the `X-
|
|
857
|
+
* Pull the `X-Environment-Id` header from a Node- or Fetch-style request.
|
|
858
858
|
* Header names are case-insensitive; we probe both casings to cover
|
|
859
859
|
* adapters that don't normalize headers (e.g. raw Node http).
|
|
860
860
|
*/
|
|
@@ -863,9 +863,9 @@ var RestServer = class {
|
|
|
863
863
|
if (!headers) return void 0;
|
|
864
864
|
let val;
|
|
865
865
|
if (typeof headers.get === "function") {
|
|
866
|
-
val = headers.get("x-
|
|
866
|
+
val = headers.get("x-environment-id") ?? headers.get("X-Environment-Id");
|
|
867
867
|
} else {
|
|
868
|
-
val = headers["x-
|
|
868
|
+
val = headers["x-environment-id"] ?? headers["X-Environment-Id"];
|
|
869
869
|
}
|
|
870
870
|
if (Array.isArray(val)) val = val[0];
|
|
871
871
|
if (typeof val !== "string") return void 0;
|
|
@@ -950,16 +950,16 @@ var RestServer = class {
|
|
|
950
950
|
}
|
|
951
951
|
/**
|
|
952
952
|
* Get the project-scoped base path for a given unscoped base.
|
|
953
|
-
* Example: `/api/v1` → `/api/v1/
|
|
953
|
+
* Example: `/api/v1` → `/api/v1/environments/:environmentId`.
|
|
954
954
|
*/
|
|
955
955
|
getScopedBasePath(basePath) {
|
|
956
|
-
return `${basePath}/
|
|
956
|
+
return `${basePath}/environments/:environmentId`;
|
|
957
957
|
}
|
|
958
958
|
/**
|
|
959
959
|
* Register all REST API routes
|
|
960
960
|
*
|
|
961
961
|
* When `enableProjectScoping` is true, routes are registered under
|
|
962
|
-
* `/api/v1/
|
|
962
|
+
* `/api/v1/environments/:environmentId/...`. The `projectResolution` strategy
|
|
963
963
|
* controls whether unscoped legacy routes remain available:
|
|
964
964
|
* - `required` → only scoped routes registered.
|
|
965
965
|
* - `optional` / `auto` → both scoped and unscoped routes registered.
|
|
@@ -1013,12 +1013,12 @@ var RestServer = class {
|
|
|
1013
1013
|
* Register discovery endpoints
|
|
1014
1014
|
*/
|
|
1015
1015
|
registerDiscoveryEndpoints(basePath) {
|
|
1016
|
-
const isScoped = basePath.includes("/
|
|
1016
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
1017
1017
|
const discoveryHandler = async (req, res) => {
|
|
1018
1018
|
try {
|
|
1019
1019
|
const discovery = await this.protocol.getDiscovery();
|
|
1020
1020
|
discovery.version = this.config.api.version;
|
|
1021
|
-
const realBase = isScoped ? basePath.replace(":
|
|
1021
|
+
const realBase = isScoped ? basePath.replace(":environmentId", req.params?.environmentId ?? ":environmentId") : basePath;
|
|
1022
1022
|
if (discovery.routes) {
|
|
1023
1023
|
if (this.config.api.enableCrud) {
|
|
1024
1024
|
discovery.routes.data = `${realBase}${this.config.crud.dataPrefix}`;
|
|
@@ -1030,7 +1030,7 @@ var RestServer = class {
|
|
|
1030
1030
|
discovery.routes.ui = `${realBase}/ui`;
|
|
1031
1031
|
}
|
|
1032
1032
|
if (discovery.routes.auth) {
|
|
1033
|
-
const unscopedBase = isScoped ? basePath.replace(/\/projects\/:
|
|
1033
|
+
const unscopedBase = isScoped ? basePath.replace(/\/projects\/:environmentId$/, "") : basePath;
|
|
1034
1034
|
discovery.routes.auth = `${unscopedBase}/auth`;
|
|
1035
1035
|
}
|
|
1036
1036
|
}
|
|
@@ -1038,7 +1038,7 @@ var RestServer = class {
|
|
|
1038
1038
|
enabled: this.config.api.enableProjectScoping,
|
|
1039
1039
|
resolution: this.config.api.projectResolution,
|
|
1040
1040
|
scoped: isScoped,
|
|
1041
|
-
|
|
1041
|
+
environmentId: isScoped ? req.params?.environmentId : void 0
|
|
1042
1042
|
};
|
|
1043
1043
|
res.json(discovery);
|
|
1044
1044
|
} catch (error) {
|
|
@@ -1083,7 +1083,7 @@ var RestServer = class {
|
|
|
1083
1083
|
* malformed file degrades to a stub instead of crashing.
|
|
1084
1084
|
*/
|
|
1085
1085
|
registerOpenApiEndpoints(basePath) {
|
|
1086
|
-
const isScoped = basePath.includes("/
|
|
1086
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
1087
1087
|
const openApiHandler = async (req, res) => {
|
|
1088
1088
|
try {
|
|
1089
1089
|
const spec = await this.loadOpenApiSpec();
|
|
@@ -1105,8 +1105,8 @@ var RestServer = class {
|
|
|
1105
1105
|
];
|
|
1106
1106
|
}
|
|
1107
1107
|
try {
|
|
1108
|
-
const
|
|
1109
|
-
const protocol = await this.resolveProtocol(
|
|
1108
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1109
|
+
const protocol = await this.resolveProtocol(environmentId, req);
|
|
1110
1110
|
const items = await protocol?.getMetaItems?.({ type: "object" }).catch(() => null);
|
|
1111
1111
|
const objects = Array.isArray(items?.items) ? items.items.map((i) => i?.name).filter(Boolean) : Array.isArray(items) ? items.map((i) => i?.name).filter(Boolean) : [];
|
|
1112
1112
|
if (objects.length > 0 && enriched.paths) {
|
|
@@ -1200,15 +1200,15 @@ var RestServer = class {
|
|
|
1200
1200
|
registerMetadataEndpoints(basePath) {
|
|
1201
1201
|
const { metadata } = this.config;
|
|
1202
1202
|
const metaPath = `${basePath}${metadata.prefix}`;
|
|
1203
|
-
const isScoped = basePath.includes("/
|
|
1203
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
1204
1204
|
if (metadata.endpoints.types !== false) {
|
|
1205
1205
|
this.routeManager.register({
|
|
1206
1206
|
method: "GET",
|
|
1207
1207
|
path: metaPath,
|
|
1208
1208
|
handler: async (req, res) => {
|
|
1209
1209
|
try {
|
|
1210
|
-
const
|
|
1211
|
-
const p = await this.resolveProtocol(
|
|
1210
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1211
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1212
1212
|
const types = await p.getMetaTypes();
|
|
1213
1213
|
res.json(types);
|
|
1214
1214
|
} catch (error) {
|
|
@@ -1229,14 +1229,14 @@ var RestServer = class {
|
|
|
1229
1229
|
handler: async (req, res) => {
|
|
1230
1230
|
try {
|
|
1231
1231
|
const packageId = req.query?.package || void 0;
|
|
1232
|
-
const
|
|
1233
|
-
const p = await this.resolveProtocol(
|
|
1232
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1233
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1234
1234
|
const items = await p.getMetaItems({
|
|
1235
1235
|
type: req.params.type,
|
|
1236
1236
|
packageId,
|
|
1237
|
-
...
|
|
1237
|
+
...environmentId ? { environmentId } : {}
|
|
1238
1238
|
});
|
|
1239
|
-
const translated = await this.translateMetaItems(req, req.params.type,
|
|
1239
|
+
const translated = await this.translateMetaItems(req, req.params.type, environmentId, items);
|
|
1240
1240
|
res.header("Vary", "Accept-Language");
|
|
1241
1241
|
res.json(translated);
|
|
1242
1242
|
} catch (error) {
|
|
@@ -1256,8 +1256,8 @@ var RestServer = class {
|
|
|
1256
1256
|
path: `${metaPath}/:type/:name`,
|
|
1257
1257
|
handler: async (req, res) => {
|
|
1258
1258
|
try {
|
|
1259
|
-
const
|
|
1260
|
-
const p = await this.resolveProtocol(
|
|
1259
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1260
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1261
1261
|
if (metadata.enableCache && p.getMetaItemCached) {
|
|
1262
1262
|
const cacheRequest = {
|
|
1263
1263
|
ifNoneMatch: req.headers["if-none-match"],
|
|
@@ -1267,7 +1267,7 @@ var RestServer = class {
|
|
|
1267
1267
|
type: req.params.type,
|
|
1268
1268
|
name: req.params.name,
|
|
1269
1269
|
cacheRequest,
|
|
1270
|
-
...
|
|
1270
|
+
...environmentId ? { environmentId } : {}
|
|
1271
1271
|
});
|
|
1272
1272
|
if (result.notModified) {
|
|
1273
1273
|
res.status(304).send();
|
|
@@ -1286,7 +1286,7 @@ var RestServer = class {
|
|
|
1286
1286
|
res.header("Cache-Control", directives + maxAge);
|
|
1287
1287
|
}
|
|
1288
1288
|
res.header("Vary", "Accept-Language");
|
|
1289
|
-
res.json(await this.translateMetaItem(req, req.params.type,
|
|
1289
|
+
res.json(await this.translateMetaItem(req, req.params.type, environmentId, result.data));
|
|
1290
1290
|
} else {
|
|
1291
1291
|
const packageId = req.query?.package || void 0;
|
|
1292
1292
|
const item = await p.getMetaItem({
|
|
@@ -1295,7 +1295,7 @@ var RestServer = class {
|
|
|
1295
1295
|
packageId
|
|
1296
1296
|
});
|
|
1297
1297
|
res.header("Vary", "Accept-Language");
|
|
1298
|
-
res.json(await this.translateMetaItem(req, req.params.type,
|
|
1298
|
+
res.json(await this.translateMetaItem(req, req.params.type, environmentId, item));
|
|
1299
1299
|
}
|
|
1300
1300
|
} catch (error) {
|
|
1301
1301
|
logError("[REST] Unhandled error:", error);
|
|
@@ -1313,8 +1313,8 @@ var RestServer = class {
|
|
|
1313
1313
|
path: `${metaPath}/:type/:name`,
|
|
1314
1314
|
handler: async (req, res) => {
|
|
1315
1315
|
try {
|
|
1316
|
-
const
|
|
1317
|
-
const p = await this.resolveProtocol(
|
|
1316
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1317
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1318
1318
|
if (!p.saveMetaItem) {
|
|
1319
1319
|
res.status(501).json({ error: "Save operation not supported by protocol implementation" });
|
|
1320
1320
|
return;
|
|
@@ -1329,7 +1329,7 @@ var RestServer = class {
|
|
|
1329
1329
|
type: req.params.type,
|
|
1330
1330
|
name: req.params.name,
|
|
1331
1331
|
item,
|
|
1332
|
-
...
|
|
1332
|
+
...environmentId ? { environmentId } : {},
|
|
1333
1333
|
...parentVersion !== void 0 ? { parentVersion } : {},
|
|
1334
1334
|
...actor ? { actor } : {}
|
|
1335
1335
|
});
|
|
@@ -1349,8 +1349,8 @@ var RestServer = class {
|
|
|
1349
1349
|
path: `${metaPath}/:type/:name`,
|
|
1350
1350
|
handler: async (req, res) => {
|
|
1351
1351
|
try {
|
|
1352
|
-
const
|
|
1353
|
-
const p = await this.resolveProtocol(
|
|
1352
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1353
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1354
1354
|
if (!p.deleteMetaItem) {
|
|
1355
1355
|
res.status(501).json({
|
|
1356
1356
|
error: "Reset operation not supported by protocol implementation"
|
|
@@ -1364,7 +1364,7 @@ var RestServer = class {
|
|
|
1364
1364
|
const result = await p.deleteMetaItem({
|
|
1365
1365
|
type: req.params.type,
|
|
1366
1366
|
name: req.params.name,
|
|
1367
|
-
...
|
|
1367
|
+
...environmentId ? { environmentId } : {},
|
|
1368
1368
|
...parentVersion !== void 0 ? { parentVersion } : {},
|
|
1369
1369
|
...actor ? { actor } : {}
|
|
1370
1370
|
});
|
|
@@ -1384,8 +1384,8 @@ var RestServer = class {
|
|
|
1384
1384
|
path: `${metaPath}/:type/:name/history`,
|
|
1385
1385
|
handler: async (req, res) => {
|
|
1386
1386
|
try {
|
|
1387
|
-
const
|
|
1388
|
-
const p = await this.resolveProtocol(
|
|
1387
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1388
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1389
1389
|
if (!p.historyMetaItem) {
|
|
1390
1390
|
res.status(501).json({
|
|
1391
1391
|
error: "History query not supported by protocol implementation"
|
|
@@ -1397,7 +1397,7 @@ var RestServer = class {
|
|
|
1397
1397
|
const result = await p.historyMetaItem({
|
|
1398
1398
|
type: req.params.type,
|
|
1399
1399
|
name: req.params.name,
|
|
1400
|
-
...
|
|
1400
|
+
...environmentId ? { environmentId } : {},
|
|
1401
1401
|
...sinceSeq !== void 0 && Number.isFinite(sinceSeq) ? { sinceSeq } : {},
|
|
1402
1402
|
...limit !== void 0 && Number.isFinite(limit) ? { limit } : {}
|
|
1403
1403
|
});
|
|
@@ -1418,8 +1418,8 @@ var RestServer = class {
|
|
|
1418
1418
|
path: `${metaPath}/:type/:section/:name`,
|
|
1419
1419
|
handler: async (req, res) => {
|
|
1420
1420
|
try {
|
|
1421
|
-
const
|
|
1422
|
-
const p = await this.resolveProtocol(
|
|
1421
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1422
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1423
1423
|
const compoundName = `${req.params.section}/${req.params.name}`;
|
|
1424
1424
|
const packageId = req.query?.package || void 0;
|
|
1425
1425
|
const item = await p.getMetaItem({
|
|
@@ -1428,7 +1428,7 @@ var RestServer = class {
|
|
|
1428
1428
|
packageId
|
|
1429
1429
|
});
|
|
1430
1430
|
res.header("Vary", "Accept-Language");
|
|
1431
|
-
res.json(await this.translateMetaItem(req, req.params.type,
|
|
1431
|
+
res.json(await this.translateMetaItem(req, req.params.type, environmentId, item));
|
|
1432
1432
|
} catch (error) {
|
|
1433
1433
|
logError("[REST] Unhandled error:", error);
|
|
1434
1434
|
sendError(res, error);
|
|
@@ -1445,8 +1445,8 @@ var RestServer = class {
|
|
|
1445
1445
|
path: `${metaPath}/:type/:section/:name`,
|
|
1446
1446
|
handler: async (req, res) => {
|
|
1447
1447
|
try {
|
|
1448
|
-
const
|
|
1449
|
-
const p = await this.resolveProtocol(
|
|
1448
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1449
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1450
1450
|
if (!p.saveMetaItem) {
|
|
1451
1451
|
res.status(501).json({ error: "Save operation not supported by protocol implementation" });
|
|
1452
1452
|
return;
|
|
@@ -1460,7 +1460,7 @@ var RestServer = class {
|
|
|
1460
1460
|
type: req.params.type,
|
|
1461
1461
|
name: compoundName,
|
|
1462
1462
|
item: req.body,
|
|
1463
|
-
...
|
|
1463
|
+
...environmentId ? { environmentId } : {},
|
|
1464
1464
|
...parentVersion !== void 0 ? { parentVersion } : {},
|
|
1465
1465
|
...actor ? { actor } : {}
|
|
1466
1466
|
});
|
|
@@ -1481,19 +1481,19 @@ var RestServer = class {
|
|
|
1481
1481
|
*/
|
|
1482
1482
|
registerUiEndpoints(basePath) {
|
|
1483
1483
|
const uiPath = `${basePath}/ui`;
|
|
1484
|
-
const isScoped = basePath.includes("/
|
|
1484
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
1485
1485
|
this.routeManager.register({
|
|
1486
1486
|
method: "GET",
|
|
1487
1487
|
path: `${uiPath}/view/:object/:type`,
|
|
1488
1488
|
handler: async (req, res) => {
|
|
1489
1489
|
try {
|
|
1490
|
-
const
|
|
1491
|
-
const p = await this.resolveProtocol(
|
|
1490
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1491
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1492
1492
|
if (p.getUiView) {
|
|
1493
1493
|
const view = await p.getUiView({
|
|
1494
1494
|
object: req.params.object,
|
|
1495
1495
|
type: req.params.type,
|
|
1496
|
-
...
|
|
1496
|
+
...environmentId ? { environmentId } : {}
|
|
1497
1497
|
});
|
|
1498
1498
|
res.json(view);
|
|
1499
1499
|
} else {
|
|
@@ -1516,7 +1516,7 @@ var RestServer = class {
|
|
|
1516
1516
|
registerCrudEndpoints(basePath) {
|
|
1517
1517
|
const { crud } = this.config;
|
|
1518
1518
|
const dataPath = `${basePath}${crud.dataPrefix}`;
|
|
1519
|
-
const isScoped = basePath.includes("/
|
|
1519
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
1520
1520
|
const operations = crud.operations;
|
|
1521
1521
|
if (operations.list) {
|
|
1522
1522
|
this.routeManager.register({
|
|
@@ -1524,14 +1524,14 @@ var RestServer = class {
|
|
|
1524
1524
|
path: `${dataPath}/:object`,
|
|
1525
1525
|
handler: async (req, res) => {
|
|
1526
1526
|
try {
|
|
1527
|
-
const
|
|
1528
|
-
const p = await this.resolveProtocol(
|
|
1529
|
-
const context = await this.resolveExecCtx(
|
|
1527
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1528
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1529
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1530
1530
|
if (this.enforceAuth(req, res, context)) return;
|
|
1531
1531
|
const result = await p.findData({
|
|
1532
1532
|
object: req.params.object,
|
|
1533
1533
|
query: req.query,
|
|
1534
|
-
...
|
|
1534
|
+
...environmentId ? { environmentId } : {},
|
|
1535
1535
|
...context ? { context } : {}
|
|
1536
1536
|
});
|
|
1537
1537
|
res.json(result);
|
|
@@ -1557,17 +1557,17 @@ var RestServer = class {
|
|
|
1557
1557
|
path: `${dataPath}/:object/:id`,
|
|
1558
1558
|
handler: async (req, res) => {
|
|
1559
1559
|
try {
|
|
1560
|
-
const
|
|
1561
|
-
const p = await this.resolveProtocol(
|
|
1560
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1561
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1562
1562
|
const { select, expand } = req.query || {};
|
|
1563
|
-
const context = await this.resolveExecCtx(
|
|
1563
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1564
1564
|
if (this.enforceAuth(req, res, context)) return;
|
|
1565
1565
|
const result = await p.getData({
|
|
1566
1566
|
object: req.params.object,
|
|
1567
1567
|
id: req.params.id,
|
|
1568
1568
|
...select != null ? { select } : {},
|
|
1569
1569
|
...expand != null ? { expand } : {},
|
|
1570
|
-
...
|
|
1570
|
+
...environmentId ? { environmentId } : {},
|
|
1571
1571
|
...context ? { context } : {}
|
|
1572
1572
|
});
|
|
1573
1573
|
res.json(result);
|
|
@@ -1589,14 +1589,14 @@ var RestServer = class {
|
|
|
1589
1589
|
path: `${dataPath}/:object`,
|
|
1590
1590
|
handler: async (req, res) => {
|
|
1591
1591
|
try {
|
|
1592
|
-
const
|
|
1593
|
-
const p = await this.resolveProtocol(
|
|
1594
|
-
const context = await this.resolveExecCtx(
|
|
1592
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1593
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1594
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1595
1595
|
if (this.enforceAuth(req, res, context)) return;
|
|
1596
1596
|
const result = await p.createData({
|
|
1597
1597
|
object: req.params.object,
|
|
1598
1598
|
data: req.body,
|
|
1599
|
-
...
|
|
1599
|
+
...environmentId ? { environmentId } : {},
|
|
1600
1600
|
...context ? { context } : {}
|
|
1601
1601
|
});
|
|
1602
1602
|
res.status(201).json(result);
|
|
@@ -1618,14 +1618,14 @@ var RestServer = class {
|
|
|
1618
1618
|
path: `${dataPath}/:object/query`,
|
|
1619
1619
|
handler: async (req, res) => {
|
|
1620
1620
|
try {
|
|
1621
|
-
const
|
|
1622
|
-
const p = await this.resolveProtocol(
|
|
1623
|
-
const context = await this.resolveExecCtx(
|
|
1621
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1622
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1623
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1624
1624
|
if (this.enforceAuth(req, res, context)) return;
|
|
1625
1625
|
const result = await p.findData({
|
|
1626
1626
|
object: req.params.object,
|
|
1627
1627
|
query: req.body || {},
|
|
1628
|
-
...
|
|
1628
|
+
...environmentId ? { environmentId } : {},
|
|
1629
1629
|
...context ? { context } : {}
|
|
1630
1630
|
});
|
|
1631
1631
|
res.json(result);
|
|
@@ -1647,9 +1647,9 @@ var RestServer = class {
|
|
|
1647
1647
|
path: `${dataPath}/:object/:id`,
|
|
1648
1648
|
handler: async (req, res) => {
|
|
1649
1649
|
try {
|
|
1650
|
-
const
|
|
1651
|
-
const p = await this.resolveProtocol(
|
|
1652
|
-
const context = await this.resolveExecCtx(
|
|
1650
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1651
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1652
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1653
1653
|
if (this.enforceAuth(req, res, context)) return;
|
|
1654
1654
|
const ifMatchHeader = req.headers?.["if-match"] ?? req.headers?.["If-Match"];
|
|
1655
1655
|
const bodyVersion = req.body && typeof req.body === "object" ? req.body.expectedVersion : void 0;
|
|
@@ -1664,7 +1664,7 @@ var RestServer = class {
|
|
|
1664
1664
|
id: req.params.id,
|
|
1665
1665
|
data,
|
|
1666
1666
|
...expectedVersion ? { expectedVersion: String(expectedVersion) } : {},
|
|
1667
|
-
...
|
|
1667
|
+
...environmentId ? { environmentId } : {},
|
|
1668
1668
|
...context ? { context } : {}
|
|
1669
1669
|
});
|
|
1670
1670
|
res.json(result);
|
|
@@ -1686,9 +1686,9 @@ var RestServer = class {
|
|
|
1686
1686
|
path: `${dataPath}/:object/:id`,
|
|
1687
1687
|
handler: async (req, res) => {
|
|
1688
1688
|
try {
|
|
1689
|
-
const
|
|
1690
|
-
const p = await this.resolveProtocol(
|
|
1691
|
-
const context = await this.resolveExecCtx(
|
|
1689
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1690
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1691
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1692
1692
|
if (this.enforceAuth(req, res, context)) return;
|
|
1693
1693
|
const ifMatchHeader = req.headers?.["if-match"] ?? req.headers?.["If-Match"];
|
|
1694
1694
|
const queryVersion = req.query && typeof req.query === "object" ? req.query.expectedVersion : void 0;
|
|
@@ -1697,7 +1697,7 @@ var RestServer = class {
|
|
|
1697
1697
|
object: req.params.object,
|
|
1698
1698
|
id: req.params.id,
|
|
1699
1699
|
...expectedVersion ? { expectedVersion: String(expectedVersion) } : {},
|
|
1700
|
-
...
|
|
1700
|
+
...environmentId ? { environmentId } : {},
|
|
1701
1701
|
...context ? { context } : {}
|
|
1702
1702
|
});
|
|
1703
1703
|
res.json(result);
|
|
@@ -1723,7 +1723,7 @@ var RestServer = class {
|
|
|
1723
1723
|
* POST {basePath}/data/lead/:id/convert — M10.6 lead conversion.
|
|
1724
1724
|
*/
|
|
1725
1725
|
registerDataActionEndpoints(basePath) {
|
|
1726
|
-
const isScoped = basePath.includes("/
|
|
1726
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
1727
1727
|
const { crud } = this.config;
|
|
1728
1728
|
const dataPath = `${basePath}${crud.dataPrefix}`;
|
|
1729
1729
|
this.routeManager.register({
|
|
@@ -1731,9 +1731,9 @@ var RestServer = class {
|
|
|
1731
1731
|
path: `${dataPath}/lead/:id/convert`,
|
|
1732
1732
|
handler: async (req, res) => {
|
|
1733
1733
|
try {
|
|
1734
|
-
const
|
|
1735
|
-
const p = await this.resolveProtocol(
|
|
1736
|
-
const context = await this.resolveExecCtx(
|
|
1734
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1735
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1736
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1737
1737
|
if (this.enforceAuth(req, res, context)) return;
|
|
1738
1738
|
const convertLead = p.convertLead;
|
|
1739
1739
|
if (typeof convertLead !== "function") {
|
|
@@ -1766,9 +1766,9 @@ var RestServer = class {
|
|
|
1766
1766
|
path: `${dataPath}/:object/import`,
|
|
1767
1767
|
handler: async (req, res) => {
|
|
1768
1768
|
try {
|
|
1769
|
-
const
|
|
1770
|
-
const p = await this.resolveProtocol(
|
|
1771
|
-
const context = await this.resolveExecCtx(
|
|
1769
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1770
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1771
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1772
1772
|
if (this.enforceAuth(req, res, context)) return;
|
|
1773
1773
|
const objectName = String(req.params.object || "");
|
|
1774
1774
|
if (!objectName) {
|
|
@@ -1849,9 +1849,9 @@ var RestServer = class {
|
|
|
1849
1849
|
path: `${dataPath}/:object/export`,
|
|
1850
1850
|
handler: async (req, res) => {
|
|
1851
1851
|
try {
|
|
1852
|
-
const
|
|
1853
|
-
const p = await this.resolveProtocol(
|
|
1854
|
-
const context = await this.resolveExecCtx(
|
|
1852
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1853
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1854
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1855
1855
|
if (this.enforceAuth(req, res, context)) return;
|
|
1856
1856
|
const objectName = String(req.params.object || "");
|
|
1857
1857
|
if (!objectName) {
|
|
@@ -1900,7 +1900,7 @@ var RestServer = class {
|
|
|
1900
1900
|
}
|
|
1901
1901
|
if (!fields || fields.length === 0) {
|
|
1902
1902
|
try {
|
|
1903
|
-
const schema = await p.getObjectSchema?.(objectName,
|
|
1903
|
+
const schema = await p.getObjectSchema?.(objectName, environmentId);
|
|
1904
1904
|
const schemaFields = schema?.fields;
|
|
1905
1905
|
if (Array.isArray(schemaFields)) {
|
|
1906
1906
|
fields = schemaFields.map((f) => f.name).filter((n) => typeof n === "string");
|
|
@@ -1934,7 +1934,7 @@ var RestServer = class {
|
|
|
1934
1934
|
$top: take,
|
|
1935
1935
|
$skip: skip
|
|
1936
1936
|
},
|
|
1937
|
-
...
|
|
1937
|
+
...environmentId ? { environmentId } : {},
|
|
1938
1938
|
...context ? { context } : {}
|
|
1939
1939
|
};
|
|
1940
1940
|
const result = await p.findData(findArgs);
|
|
@@ -1982,15 +1982,15 @@ var RestServer = class {
|
|
|
1982
1982
|
* GET {basePath}/search?q=acme&objects=lead,account&limit=20&perObject=5
|
|
1983
1983
|
*/
|
|
1984
1984
|
registerSearchEndpoints(basePath) {
|
|
1985
|
-
const isScoped = basePath.includes("/
|
|
1985
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
1986
1986
|
this.routeManager.register({
|
|
1987
1987
|
method: "GET",
|
|
1988
1988
|
path: `${basePath}/search`,
|
|
1989
1989
|
handler: async (req, res) => {
|
|
1990
1990
|
try {
|
|
1991
|
-
const
|
|
1992
|
-
const p = await this.resolveProtocol(
|
|
1993
|
-
const context = await this.resolveExecCtx(
|
|
1991
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1992
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1993
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1994
1994
|
if (this.enforceAuth(req, res, context)) return;
|
|
1995
1995
|
const searchAll = p.searchAll;
|
|
1996
1996
|
if (typeof searchAll !== "function") {
|
|
@@ -2042,14 +2042,14 @@ var RestServer = class {
|
|
|
2042
2042
|
* }
|
|
2043
2043
|
*/
|
|
2044
2044
|
registerEmailEndpoints(basePath) {
|
|
2045
|
-
const isScoped = basePath.includes("/
|
|
2045
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
2046
2046
|
this.routeManager.register({
|
|
2047
2047
|
method: "POST",
|
|
2048
2048
|
path: `${basePath}/email/send`,
|
|
2049
2049
|
handler: async (req, res) => {
|
|
2050
2050
|
try {
|
|
2051
|
-
const
|
|
2052
|
-
const context = await this.resolveExecCtx(
|
|
2051
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2052
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2053
2053
|
if (this.enforceAuth(req, res, context)) return;
|
|
2054
2054
|
if (!this.emailServiceProvider) {
|
|
2055
2055
|
res.status(501).json({
|
|
@@ -2058,7 +2058,7 @@ var RestServer = class {
|
|
|
2058
2058
|
});
|
|
2059
2059
|
return;
|
|
2060
2060
|
}
|
|
2061
|
-
const emailService = await this.emailServiceProvider(
|
|
2061
|
+
const emailService = await this.emailServiceProvider(environmentId).catch(() => void 0);
|
|
2062
2062
|
if (!emailService || typeof emailService.send !== "function") {
|
|
2063
2063
|
res.status(501).json({
|
|
2064
2064
|
code: "NOT_IMPLEMENTED",
|
|
@@ -2137,7 +2137,7 @@ var RestServer = class {
|
|
|
2137
2137
|
* `mapViewSpecToEmbeddableConfig` expects.
|
|
2138
2138
|
*/
|
|
2139
2139
|
registerFormEndpoints(basePath) {
|
|
2140
|
-
const isScoped = basePath.includes("/
|
|
2140
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
2141
2141
|
const slugMatchesPublicLink = (publicLink, slug) => {
|
|
2142
2142
|
if (!publicLink || typeof publicLink !== "string") return false;
|
|
2143
2143
|
const normalized = publicLink.replace(/^\/+/, "").replace(/^forms\//, "");
|
|
@@ -2167,12 +2167,12 @@ var RestServer = class {
|
|
|
2167
2167
|
}
|
|
2168
2168
|
return null;
|
|
2169
2169
|
};
|
|
2170
|
-
const resolveFormBySlug = async (
|
|
2171
|
-
const p = await this.resolveProtocol(
|
|
2170
|
+
const resolveFormBySlug = async (environmentId, req, slug) => {
|
|
2171
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
2172
2172
|
if (typeof p.getMetaItems !== "function") return null;
|
|
2173
2173
|
const result = await p.getMetaItems({
|
|
2174
2174
|
type: "view",
|
|
2175
|
-
...
|
|
2175
|
+
...environmentId ? { environmentId } : {}
|
|
2176
2176
|
});
|
|
2177
2177
|
const items = Array.isArray(result?.items) ? result.items : Array.isArray(result) ? result : [];
|
|
2178
2178
|
return findPublicFormView(items, slug);
|
|
@@ -2182,13 +2182,13 @@ var RestServer = class {
|
|
|
2182
2182
|
path: `${basePath}/forms/:slug`,
|
|
2183
2183
|
handler: async (req, res) => {
|
|
2184
2184
|
try {
|
|
2185
|
-
const
|
|
2185
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2186
2186
|
const slug = String(req.params?.slug ?? "").trim();
|
|
2187
2187
|
if (!slug) {
|
|
2188
2188
|
res.status(400).json({ code: "INVALID_REQUEST", error: "slug is required" });
|
|
2189
2189
|
return;
|
|
2190
2190
|
}
|
|
2191
|
-
const match = await resolveFormBySlug(
|
|
2191
|
+
const match = await resolveFormBySlug(environmentId, req, slug);
|
|
2192
2192
|
if (!match) {
|
|
2193
2193
|
res.status(404).json({
|
|
2194
2194
|
code: "FORM_NOT_FOUND",
|
|
@@ -2198,11 +2198,11 @@ var RestServer = class {
|
|
|
2198
2198
|
}
|
|
2199
2199
|
let objectSchema = null;
|
|
2200
2200
|
try {
|
|
2201
|
-
const p = await this.resolveProtocol(
|
|
2201
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
2202
2202
|
if (typeof p.getMetaItems === "function") {
|
|
2203
2203
|
const r = await p.getMetaItems({
|
|
2204
2204
|
type: "object",
|
|
2205
|
-
...
|
|
2205
|
+
...environmentId ? { environmentId } : {}
|
|
2206
2206
|
});
|
|
2207
2207
|
const items = Array.isArray(r?.items) ? r.items : Array.isArray(r) ? r : [];
|
|
2208
2208
|
const obj = items.find((o) => o?.name === match.object);
|
|
@@ -2222,7 +2222,7 @@ var RestServer = class {
|
|
|
2222
2222
|
}
|
|
2223
2223
|
objectSchema = { name: obj.name, label: obj.label, fields };
|
|
2224
2224
|
try {
|
|
2225
|
-
const i18n = await this.resolveI18nService(
|
|
2225
|
+
const i18n = await this.resolveI18nService(environmentId, req);
|
|
2226
2226
|
const bundle = this.buildTranslationBundle(i18n);
|
|
2227
2227
|
const locale = this.extractLocale(req, i18n);
|
|
2228
2228
|
if (bundle && locale) {
|
|
@@ -2282,13 +2282,13 @@ var RestServer = class {
|
|
|
2282
2282
|
path: `${basePath}/forms/:slug/submit`,
|
|
2283
2283
|
handler: async (req, res) => {
|
|
2284
2284
|
try {
|
|
2285
|
-
const
|
|
2285
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2286
2286
|
const slug = String(req.params?.slug ?? "").trim();
|
|
2287
2287
|
if (!slug) {
|
|
2288
2288
|
res.status(400).json({ code: "INVALID_REQUEST", error: "slug is required" });
|
|
2289
2289
|
return;
|
|
2290
2290
|
}
|
|
2291
|
-
const match = await resolveFormBySlug(
|
|
2291
|
+
const match = await resolveFormBySlug(environmentId, req, slug);
|
|
2292
2292
|
if (!match) {
|
|
2293
2293
|
res.status(404).json({
|
|
2294
2294
|
code: "FORM_NOT_FOUND",
|
|
@@ -2316,11 +2316,11 @@ var RestServer = class {
|
|
|
2316
2316
|
permissions: ["guest_portal"],
|
|
2317
2317
|
anonymous: true
|
|
2318
2318
|
};
|
|
2319
|
-
const p = await this.resolveProtocol(
|
|
2319
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
2320
2320
|
const result = await p.createData({
|
|
2321
2321
|
object: match.object,
|
|
2322
2322
|
data: filteredData,
|
|
2323
|
-
...
|
|
2323
|
+
...environmentId ? { environmentId } : {},
|
|
2324
2324
|
context
|
|
2325
2325
|
});
|
|
2326
2326
|
res.status(201).json(result);
|
|
@@ -2342,14 +2342,14 @@ var RestServer = class {
|
|
|
2342
2342
|
path: `${basePath}/forms/:slug/lookup/:field`,
|
|
2343
2343
|
handler: async (req, res) => {
|
|
2344
2344
|
try {
|
|
2345
|
-
const
|
|
2345
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2346
2346
|
const slug = String(req.params?.slug ?? "").trim();
|
|
2347
2347
|
const fieldName = String(req.params?.field ?? "").trim();
|
|
2348
2348
|
if (!slug || !fieldName) {
|
|
2349
2349
|
res.status(400).json({ code: "INVALID_REQUEST", error: "slug and field are required" });
|
|
2350
2350
|
return;
|
|
2351
2351
|
}
|
|
2352
|
-
const match = await resolveFormBySlug(
|
|
2352
|
+
const match = await resolveFormBySlug(environmentId, req, slug);
|
|
2353
2353
|
if (!match) {
|
|
2354
2354
|
res.status(404).json({
|
|
2355
2355
|
code: "FORM_NOT_FOUND",
|
|
@@ -2376,13 +2376,13 @@ var RestServer = class {
|
|
|
2376
2376
|
});
|
|
2377
2377
|
return;
|
|
2378
2378
|
}
|
|
2379
|
-
const p = await this.resolveProtocol(
|
|
2379
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
2380
2380
|
let referenceTo = picker.object;
|
|
2381
2381
|
if (!referenceTo && typeof p.getMetaItems === "function") {
|
|
2382
2382
|
try {
|
|
2383
2383
|
const r = await p.getMetaItems({
|
|
2384
2384
|
type: "object",
|
|
2385
|
-
...
|
|
2385
|
+
...environmentId ? { environmentId } : {}
|
|
2386
2386
|
});
|
|
2387
2387
|
const items = Array.isArray(r?.items) ? r.items : Array.isArray(r) ? r : [];
|
|
2388
2388
|
const obj = items.find((o) => o?.name === match.object);
|
|
@@ -2418,7 +2418,7 @@ var RestServer = class {
|
|
|
2418
2418
|
select: ["id", ...displayFields],
|
|
2419
2419
|
sort: picker.sort ?? [{ field: displayFields[0], order: "asc" }]
|
|
2420
2420
|
},
|
|
2421
|
-
...
|
|
2421
|
+
...environmentId ? { environmentId } : {},
|
|
2422
2422
|
context
|
|
2423
2423
|
});
|
|
2424
2424
|
const rows = Array.isArray(result?.data) ? result.data : Array.isArray(result?.items) ? result.items : [];
|
|
@@ -2468,11 +2468,11 @@ var RestServer = class {
|
|
|
2468
2468
|
registerSharingEndpoints(basePath) {
|
|
2469
2469
|
const { crud } = this.config;
|
|
2470
2470
|
const dataPath = `${basePath}${crud.dataPrefix}`;
|
|
2471
|
-
const isScoped = basePath.includes("/
|
|
2472
|
-
const resolveService = async (
|
|
2471
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
2472
|
+
const resolveService = async (environmentId) => {
|
|
2473
2473
|
if (!this.sharingServiceProvider) return void 0;
|
|
2474
2474
|
try {
|
|
2475
|
-
return await this.sharingServiceProvider(
|
|
2475
|
+
return await this.sharingServiceProvider(environmentId);
|
|
2476
2476
|
} catch {
|
|
2477
2477
|
return void 0;
|
|
2478
2478
|
}
|
|
@@ -2486,10 +2486,10 @@ var RestServer = class {
|
|
|
2486
2486
|
path: `${dataPath}/:object/:id/shares`,
|
|
2487
2487
|
handler: async (req, res) => {
|
|
2488
2488
|
try {
|
|
2489
|
-
const
|
|
2490
|
-
const context = await this.resolveExecCtx(
|
|
2489
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2490
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2491
2491
|
if (this.enforceAuth(req, res, context)) return;
|
|
2492
|
-
const svc = await resolveService(
|
|
2492
|
+
const svc = await resolveService(environmentId);
|
|
2493
2493
|
if (!svc) return respond501(res);
|
|
2494
2494
|
const rows = await svc.listShares(req.params.object, req.params.id, context ?? {});
|
|
2495
2495
|
res.json({ data: rows });
|
|
@@ -2505,10 +2505,10 @@ var RestServer = class {
|
|
|
2505
2505
|
path: `${dataPath}/:object/:id/shares`,
|
|
2506
2506
|
handler: async (req, res) => {
|
|
2507
2507
|
try {
|
|
2508
|
-
const
|
|
2509
|
-
const context = await this.resolveExecCtx(
|
|
2508
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2509
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2510
2510
|
if (this.enforceAuth(req, res, context)) return;
|
|
2511
|
-
const svc = await resolveService(
|
|
2511
|
+
const svc = await resolveService(environmentId);
|
|
2512
2512
|
if (!svc) return respond501(res);
|
|
2513
2513
|
const body = req.body ?? {};
|
|
2514
2514
|
const input = {
|
|
@@ -2547,10 +2547,10 @@ var RestServer = class {
|
|
|
2547
2547
|
path: `${dataPath}/:object/:id/shares/:shareId`,
|
|
2548
2548
|
handler: async (req, res) => {
|
|
2549
2549
|
try {
|
|
2550
|
-
const
|
|
2551
|
-
const context = await this.resolveExecCtx(
|
|
2550
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2551
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2552
2552
|
if (this.enforceAuth(req, res, context)) return;
|
|
2553
|
-
const svc = await resolveService(
|
|
2553
|
+
const svc = await resolveService(environmentId);
|
|
2554
2554
|
if (!svc) return respond501(res);
|
|
2555
2555
|
await svc.revoke(req.params.shareId, context ?? {});
|
|
2556
2556
|
res.status(204).end();
|
|
@@ -2576,11 +2576,11 @@ var RestServer = class {
|
|
|
2576
2576
|
*/
|
|
2577
2577
|
registerSharingRuleEndpoints(basePath) {
|
|
2578
2578
|
const dataPath = basePath;
|
|
2579
|
-
const isScoped = basePath.includes("/
|
|
2580
|
-
const resolveService = async (
|
|
2579
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
2580
|
+
const resolveService = async (environmentId) => {
|
|
2581
2581
|
if (!this.sharingRulesServiceProvider) return void 0;
|
|
2582
2582
|
try {
|
|
2583
|
-
return await this.sharingRulesServiceProvider(
|
|
2583
|
+
return await this.sharingRulesServiceProvider(environmentId);
|
|
2584
2584
|
} catch {
|
|
2585
2585
|
return void 0;
|
|
2586
2586
|
}
|
|
@@ -2605,10 +2605,10 @@ var RestServer = class {
|
|
|
2605
2605
|
path: `${dataPath}/sharing/rules`,
|
|
2606
2606
|
handler: async (req, res) => {
|
|
2607
2607
|
try {
|
|
2608
|
-
const
|
|
2609
|
-
const context = await this.resolveExecCtx(
|
|
2608
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2609
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2610
2610
|
if (this.enforceAuth(req, res, context)) return;
|
|
2611
|
-
const svc = await resolveService(
|
|
2611
|
+
const svc = await resolveService(environmentId);
|
|
2612
2612
|
if (!svc) return respond501(res);
|
|
2613
2613
|
const rows = await svc.listRules({
|
|
2614
2614
|
object: req.query?.object,
|
|
@@ -2626,10 +2626,10 @@ var RestServer = class {
|
|
|
2626
2626
|
path: `${dataPath}/sharing/rules`,
|
|
2627
2627
|
handler: async (req, res) => {
|
|
2628
2628
|
try {
|
|
2629
|
-
const
|
|
2630
|
-
const context = await this.resolveExecCtx(
|
|
2629
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2630
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2631
2631
|
if (this.enforceAuth(req, res, context)) return;
|
|
2632
|
-
const svc = await resolveService(
|
|
2632
|
+
const svc = await resolveService(environmentId);
|
|
2633
2633
|
if (!svc) return respond501(res);
|
|
2634
2634
|
const body = req.body ?? {};
|
|
2635
2635
|
const input = {
|
|
@@ -2656,10 +2656,10 @@ var RestServer = class {
|
|
|
2656
2656
|
path: `${dataPath}/sharing/rules/:idOrName`,
|
|
2657
2657
|
handler: async (req, res) => {
|
|
2658
2658
|
try {
|
|
2659
|
-
const
|
|
2660
|
-
const context = await this.resolveExecCtx(
|
|
2659
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2660
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2661
2661
|
if (this.enforceAuth(req, res, context)) return;
|
|
2662
|
-
const svc = await resolveService(
|
|
2662
|
+
const svc = await resolveService(environmentId);
|
|
2663
2663
|
if (!svc) return respond501(res);
|
|
2664
2664
|
const row = await svc.getRule(req.params.idOrName, context ?? {});
|
|
2665
2665
|
if (!row) return res.status(404).json({ code: "RULE_NOT_FOUND" });
|
|
@@ -2675,10 +2675,10 @@ var RestServer = class {
|
|
|
2675
2675
|
path: `${dataPath}/sharing/rules/:idOrName`,
|
|
2676
2676
|
handler: async (req, res) => {
|
|
2677
2677
|
try {
|
|
2678
|
-
const
|
|
2679
|
-
const context = await this.resolveExecCtx(
|
|
2678
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2679
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2680
2680
|
if (this.enforceAuth(req, res, context)) return;
|
|
2681
|
-
const svc = await resolveService(
|
|
2681
|
+
const svc = await resolveService(environmentId);
|
|
2682
2682
|
if (!svc) return respond501(res);
|
|
2683
2683
|
await svc.deleteRule(req.params.idOrName, context ?? {});
|
|
2684
2684
|
res.status(204).end();
|
|
@@ -2693,10 +2693,10 @@ var RestServer = class {
|
|
|
2693
2693
|
path: `${dataPath}/sharing/rules/:idOrName/evaluate`,
|
|
2694
2694
|
handler: async (req, res) => {
|
|
2695
2695
|
try {
|
|
2696
|
-
const
|
|
2697
|
-
const context = await this.resolveExecCtx(
|
|
2696
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2697
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2698
2698
|
if (this.enforceAuth(req, res, context)) return;
|
|
2699
|
-
const svc = await resolveService(
|
|
2699
|
+
const svc = await resolveService(environmentId);
|
|
2700
2700
|
if (!svc) return respond501(res);
|
|
2701
2701
|
const result = await svc.evaluateRule(req.params.idOrName, context ?? {});
|
|
2702
2702
|
res.json(result);
|
|
@@ -2730,11 +2730,11 @@ var RestServer = class {
|
|
|
2730
2730
|
*/
|
|
2731
2731
|
registerReportsEndpoints(basePath) {
|
|
2732
2732
|
const dataPath = basePath;
|
|
2733
|
-
const isScoped = basePath.includes("/
|
|
2734
|
-
const resolveService = async (
|
|
2733
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
2734
|
+
const resolveService = async (environmentId) => {
|
|
2735
2735
|
if (!this.reportsServiceProvider) return void 0;
|
|
2736
2736
|
try {
|
|
2737
|
-
return await this.reportsServiceProvider(
|
|
2737
|
+
return await this.reportsServiceProvider(environmentId);
|
|
2738
2738
|
} catch {
|
|
2739
2739
|
return void 0;
|
|
2740
2740
|
}
|
|
@@ -2763,10 +2763,10 @@ var RestServer = class {
|
|
|
2763
2763
|
path: `${dataPath}/reports`,
|
|
2764
2764
|
handler: async (req, res) => {
|
|
2765
2765
|
try {
|
|
2766
|
-
const
|
|
2767
|
-
const context = await this.resolveExecCtx(
|
|
2766
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2767
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2768
2768
|
if (this.enforceAuth(req, res, context)) return;
|
|
2769
|
-
const svc = await resolveService(
|
|
2769
|
+
const svc = await resolveService(environmentId);
|
|
2770
2770
|
if (!svc) return respond501(res);
|
|
2771
2771
|
const q = req.query ?? {};
|
|
2772
2772
|
const rows = await svc.listReports({ object: q.object, ownerId: q.ownerId }, context ?? {});
|
|
@@ -2783,10 +2783,10 @@ var RestServer = class {
|
|
|
2783
2783
|
path: `${dataPath}/reports`,
|
|
2784
2784
|
handler: async (req, res) => {
|
|
2785
2785
|
try {
|
|
2786
|
-
const
|
|
2787
|
-
const context = await this.resolveExecCtx(
|
|
2786
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2787
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2788
2788
|
if (this.enforceAuth(req, res, context)) return;
|
|
2789
|
-
const svc = await resolveService(
|
|
2789
|
+
const svc = await resolveService(environmentId);
|
|
2790
2790
|
if (!svc) return respond501(res);
|
|
2791
2791
|
try {
|
|
2792
2792
|
const row = await svc.saveReport(req.body ?? {}, context ?? {});
|
|
@@ -2807,10 +2807,10 @@ var RestServer = class {
|
|
|
2807
2807
|
path: `${dataPath}/reports/:id`,
|
|
2808
2808
|
handler: async (req, res) => {
|
|
2809
2809
|
try {
|
|
2810
|
-
const
|
|
2811
|
-
const context = await this.resolveExecCtx(
|
|
2810
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2811
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2812
2812
|
if (this.enforceAuth(req, res, context)) return;
|
|
2813
|
-
const svc = await resolveService(
|
|
2813
|
+
const svc = await resolveService(environmentId);
|
|
2814
2814
|
if (!svc) return respond501(res);
|
|
2815
2815
|
const row = await svc.getReport(req.params.id, context ?? {});
|
|
2816
2816
|
if (!row) {
|
|
@@ -2830,10 +2830,10 @@ var RestServer = class {
|
|
|
2830
2830
|
path: `${dataPath}/reports/:id`,
|
|
2831
2831
|
handler: async (req, res) => {
|
|
2832
2832
|
try {
|
|
2833
|
-
const
|
|
2834
|
-
const context = await this.resolveExecCtx(
|
|
2833
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2834
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2835
2835
|
if (this.enforceAuth(req, res, context)) return;
|
|
2836
|
-
const svc = await resolveService(
|
|
2836
|
+
const svc = await resolveService(environmentId);
|
|
2837
2837
|
if (!svc) return respond501(res);
|
|
2838
2838
|
await svc.deleteReport(req.params.id, context ?? {});
|
|
2839
2839
|
res.status(204).end();
|
|
@@ -2849,10 +2849,10 @@ var RestServer = class {
|
|
|
2849
2849
|
path: `${dataPath}/reports/:id/run`,
|
|
2850
2850
|
handler: async (req, res) => {
|
|
2851
2851
|
try {
|
|
2852
|
-
const
|
|
2853
|
-
const context = await this.resolveExecCtx(
|
|
2852
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2853
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2854
2854
|
if (this.enforceAuth(req, res, context)) return;
|
|
2855
|
-
const svc = await resolveService(
|
|
2855
|
+
const svc = await resolveService(environmentId);
|
|
2856
2856
|
if (!svc) return respond501(res);
|
|
2857
2857
|
try {
|
|
2858
2858
|
const result = await svc.run(req.params.id, context ?? {});
|
|
@@ -2873,10 +2873,10 @@ var RestServer = class {
|
|
|
2873
2873
|
path: `${dataPath}/reports/:id/schedule`,
|
|
2874
2874
|
handler: async (req, res) => {
|
|
2875
2875
|
try {
|
|
2876
|
-
const
|
|
2877
|
-
const context = await this.resolveExecCtx(
|
|
2876
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2877
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2878
2878
|
if (this.enforceAuth(req, res, context)) return;
|
|
2879
|
-
const svc = await resolveService(
|
|
2879
|
+
const svc = await resolveService(environmentId);
|
|
2880
2880
|
if (!svc) return respond501(res);
|
|
2881
2881
|
const body = req.body ?? {};
|
|
2882
2882
|
try {
|
|
@@ -2909,10 +2909,10 @@ var RestServer = class {
|
|
|
2909
2909
|
path: `${dataPath}/reports/:id/schedules`,
|
|
2910
2910
|
handler: async (req, res) => {
|
|
2911
2911
|
try {
|
|
2912
|
-
const
|
|
2913
|
-
const context = await this.resolveExecCtx(
|
|
2912
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2913
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2914
2914
|
if (this.enforceAuth(req, res, context)) return;
|
|
2915
|
-
const svc = await resolveService(
|
|
2915
|
+
const svc = await resolveService(environmentId);
|
|
2916
2916
|
if (!svc) return respond501(res);
|
|
2917
2917
|
const rows = await svc.listSchedules({ reportId: req.params.id }, context ?? {});
|
|
2918
2918
|
res.json({ data: rows });
|
|
@@ -2928,10 +2928,10 @@ var RestServer = class {
|
|
|
2928
2928
|
path: `${dataPath}/reports/schedules/:scheduleId`,
|
|
2929
2929
|
handler: async (req, res) => {
|
|
2930
2930
|
try {
|
|
2931
|
-
const
|
|
2932
|
-
const context = await this.resolveExecCtx(
|
|
2931
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2932
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2933
2933
|
if (this.enforceAuth(req, res, context)) return;
|
|
2934
|
-
const svc = await resolveService(
|
|
2934
|
+
const svc = await resolveService(environmentId);
|
|
2935
2935
|
if (!svc) return respond501(res);
|
|
2936
2936
|
await svc.unscheduleReport(req.params.scheduleId, context ?? {});
|
|
2937
2937
|
res.status(204).end();
|
|
@@ -2964,11 +2964,11 @@ var RestServer = class {
|
|
|
2964
2964
|
*/
|
|
2965
2965
|
registerApprovalsEndpoints(basePath) {
|
|
2966
2966
|
const dataPath = basePath;
|
|
2967
|
-
const isScoped = basePath.includes("/
|
|
2968
|
-
const resolveService = async (
|
|
2967
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
2968
|
+
const resolveService = async (environmentId) => {
|
|
2969
2969
|
if (!this.approvalsServiceProvider) return void 0;
|
|
2970
2970
|
try {
|
|
2971
|
-
return await this.approvalsServiceProvider(
|
|
2971
|
+
return await this.approvalsServiceProvider(environmentId);
|
|
2972
2972
|
} catch {
|
|
2973
2973
|
return void 0;
|
|
2974
2974
|
}
|
|
@@ -3001,10 +3001,10 @@ var RestServer = class {
|
|
|
3001
3001
|
path: `${dataPath}/approvals/processes`,
|
|
3002
3002
|
handler: async (req, res) => {
|
|
3003
3003
|
try {
|
|
3004
|
-
const
|
|
3005
|
-
const context = await this.resolveExecCtx(
|
|
3004
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3005
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3006
3006
|
if (this.enforceAuth(req, res, context)) return;
|
|
3007
|
-
const svc = await resolveService(
|
|
3007
|
+
const svc = await resolveService(environmentId);
|
|
3008
3008
|
if (!svc) return respond501(res);
|
|
3009
3009
|
const q = req.query ?? {};
|
|
3010
3010
|
const rows = await svc.listProcesses({
|
|
@@ -3024,10 +3024,10 @@ var RestServer = class {
|
|
|
3024
3024
|
path: `${dataPath}/approvals/processes`,
|
|
3025
3025
|
handler: async (req, res) => {
|
|
3026
3026
|
try {
|
|
3027
|
-
const
|
|
3028
|
-
const context = await this.resolveExecCtx(
|
|
3027
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3028
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3029
3029
|
if (this.enforceAuth(req, res, context)) return;
|
|
3030
|
-
const svc = await resolveService(
|
|
3030
|
+
const svc = await resolveService(environmentId);
|
|
3031
3031
|
if (!svc) return respond501(res);
|
|
3032
3032
|
try {
|
|
3033
3033
|
const row = await svc.defineProcess(req.body ?? {}, context ?? {});
|
|
@@ -3048,10 +3048,10 @@ var RestServer = class {
|
|
|
3048
3048
|
path: `${dataPath}/approvals/processes/:id`,
|
|
3049
3049
|
handler: async (req, res) => {
|
|
3050
3050
|
try {
|
|
3051
|
-
const
|
|
3052
|
-
const context = await this.resolveExecCtx(
|
|
3051
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3052
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3053
3053
|
if (this.enforceAuth(req, res, context)) return;
|
|
3054
|
-
const svc = await resolveService(
|
|
3054
|
+
const svc = await resolveService(environmentId);
|
|
3055
3055
|
if (!svc) return respond501(res);
|
|
3056
3056
|
const row = await svc.getProcess(req.params.id, context ?? {});
|
|
3057
3057
|
if (!row) {
|
|
@@ -3071,10 +3071,10 @@ var RestServer = class {
|
|
|
3071
3071
|
path: `${dataPath}/approvals/processes/:id`,
|
|
3072
3072
|
handler: async (req, res) => {
|
|
3073
3073
|
try {
|
|
3074
|
-
const
|
|
3075
|
-
const context = await this.resolveExecCtx(
|
|
3074
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3075
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3076
3076
|
if (this.enforceAuth(req, res, context)) return;
|
|
3077
|
-
const svc = await resolveService(
|
|
3077
|
+
const svc = await resolveService(environmentId);
|
|
3078
3078
|
if (!svc) return respond501(res);
|
|
3079
3079
|
await svc.deleteProcess(req.params.id, context ?? {});
|
|
3080
3080
|
res.status(204).end();
|
|
@@ -3090,10 +3090,10 @@ var RestServer = class {
|
|
|
3090
3090
|
path: `${dataPath}/approvals/requests`,
|
|
3091
3091
|
handler: async (req, res) => {
|
|
3092
3092
|
try {
|
|
3093
|
-
const
|
|
3094
|
-
const context = await this.resolveExecCtx(
|
|
3093
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3094
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3095
3095
|
if (this.enforceAuth(req, res, context)) return;
|
|
3096
|
-
const svc = await resolveService(
|
|
3096
|
+
const svc = await resolveService(environmentId);
|
|
3097
3097
|
if (!svc) return respond501(res);
|
|
3098
3098
|
const body = req.body ?? {};
|
|
3099
3099
|
try {
|
|
@@ -3122,10 +3122,10 @@ var RestServer = class {
|
|
|
3122
3122
|
path: `${dataPath}/approvals/requests`,
|
|
3123
3123
|
handler: async (req, res) => {
|
|
3124
3124
|
try {
|
|
3125
|
-
const
|
|
3126
|
-
const context = await this.resolveExecCtx(
|
|
3125
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3126
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3127
3127
|
if (this.enforceAuth(req, res, context)) return;
|
|
3128
|
-
const svc = await resolveService(
|
|
3128
|
+
const svc = await resolveService(environmentId);
|
|
3129
3129
|
if (!svc) {
|
|
3130
3130
|
res.json({ data: [] });
|
|
3131
3131
|
return;
|
|
@@ -3151,10 +3151,10 @@ var RestServer = class {
|
|
|
3151
3151
|
path: `${dataPath}/approvals/requests/:id`,
|
|
3152
3152
|
handler: async (req, res) => {
|
|
3153
3153
|
try {
|
|
3154
|
-
const
|
|
3155
|
-
const context = await this.resolveExecCtx(
|
|
3154
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3155
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3156
3156
|
if (this.enforceAuth(req, res, context)) return;
|
|
3157
|
-
const svc = await resolveService(
|
|
3157
|
+
const svc = await resolveService(environmentId);
|
|
3158
3158
|
if (!svc) return respond501(res);
|
|
3159
3159
|
const row = await svc.getRequest(req.params.id, context ?? {});
|
|
3160
3160
|
if (!row) {
|
|
@@ -3175,10 +3175,10 @@ var RestServer = class {
|
|
|
3175
3175
|
path: `${dataPath}/approvals/requests/:id/${suffix}`,
|
|
3176
3176
|
handler: async (req, res) => {
|
|
3177
3177
|
try {
|
|
3178
|
-
const
|
|
3179
|
-
const context = await this.resolveExecCtx(
|
|
3178
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3179
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3180
3180
|
if (this.enforceAuth(req, res, context)) return;
|
|
3181
|
-
const svc = await resolveService(
|
|
3181
|
+
const svc = await resolveService(environmentId);
|
|
3182
3182
|
if (!svc) return respond501(res);
|
|
3183
3183
|
const body = req.body ?? {};
|
|
3184
3184
|
try {
|
|
@@ -3207,10 +3207,10 @@ var RestServer = class {
|
|
|
3207
3207
|
path: `${dataPath}/approvals/requests/:id/actions`,
|
|
3208
3208
|
handler: async (req, res) => {
|
|
3209
3209
|
try {
|
|
3210
|
-
const
|
|
3211
|
-
const context = await this.resolveExecCtx(
|
|
3210
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3211
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3212
3212
|
if (this.enforceAuth(req, res, context)) return;
|
|
3213
|
-
const svc = await resolveService(
|
|
3213
|
+
const svc = await resolveService(environmentId);
|
|
3214
3214
|
if (!svc) return respond501(res);
|
|
3215
3215
|
const rows = await svc.listActions(req.params.id, context ?? {});
|
|
3216
3216
|
res.json({ data: rows });
|
|
@@ -3228,7 +3228,7 @@ var RestServer = class {
|
|
|
3228
3228
|
registerBatchEndpoints(basePath) {
|
|
3229
3229
|
const { crud, batch } = this.config;
|
|
3230
3230
|
const dataPath = `${basePath}${crud.dataPrefix}`;
|
|
3231
|
-
const isScoped = basePath.includes("/
|
|
3231
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
3232
3232
|
const operations = batch.operations;
|
|
3233
3233
|
if (batch.enableBatchEndpoint && this.protocol.batchData) {
|
|
3234
3234
|
this.routeManager.register({
|
|
@@ -3236,14 +3236,14 @@ var RestServer = class {
|
|
|
3236
3236
|
path: `${dataPath}/:object/batch`,
|
|
3237
3237
|
handler: async (req, res) => {
|
|
3238
3238
|
try {
|
|
3239
|
-
const
|
|
3240
|
-
const p = await this.resolveProtocol(
|
|
3241
|
-
const context = await this.resolveExecCtx(
|
|
3239
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3240
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
3241
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3242
3242
|
if (this.enforceAuth(req, res, context)) return;
|
|
3243
3243
|
const result = await p.batchData({
|
|
3244
3244
|
object: req.params.object,
|
|
3245
3245
|
request: req.body,
|
|
3246
|
-
...
|
|
3246
|
+
...environmentId ? { environmentId } : {},
|
|
3247
3247
|
...context ? { context } : {}
|
|
3248
3248
|
});
|
|
3249
3249
|
res.json(result);
|
|
@@ -3264,14 +3264,14 @@ var RestServer = class {
|
|
|
3264
3264
|
path: `${dataPath}/:object/createMany`,
|
|
3265
3265
|
handler: async (req, res) => {
|
|
3266
3266
|
try {
|
|
3267
|
-
const
|
|
3268
|
-
const p = await this.resolveProtocol(
|
|
3269
|
-
const context = await this.resolveExecCtx(
|
|
3267
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3268
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
3269
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3270
3270
|
if (this.enforceAuth(req, res, context)) return;
|
|
3271
3271
|
const result = await p.createManyData({
|
|
3272
3272
|
object: req.params.object,
|
|
3273
3273
|
records: req.body || [],
|
|
3274
|
-
...
|
|
3274
|
+
...environmentId ? { environmentId } : {},
|
|
3275
3275
|
...context ? { context } : {}
|
|
3276
3276
|
});
|
|
3277
3277
|
res.status(201).json(result);
|
|
@@ -3292,14 +3292,14 @@ var RestServer = class {
|
|
|
3292
3292
|
path: `${dataPath}/:object/updateMany`,
|
|
3293
3293
|
handler: async (req, res) => {
|
|
3294
3294
|
try {
|
|
3295
|
-
const
|
|
3296
|
-
const p = await this.resolveProtocol(
|
|
3297
|
-
const context = await this.resolveExecCtx(
|
|
3295
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3296
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
3297
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3298
3298
|
if (this.enforceAuth(req, res, context)) return;
|
|
3299
3299
|
const result = await p.updateManyData({
|
|
3300
3300
|
object: req.params.object,
|
|
3301
3301
|
...req.body,
|
|
3302
|
-
...
|
|
3302
|
+
...environmentId ? { environmentId } : {},
|
|
3303
3303
|
...context ? { context } : {}
|
|
3304
3304
|
});
|
|
3305
3305
|
res.json(result);
|
|
@@ -3320,14 +3320,14 @@ var RestServer = class {
|
|
|
3320
3320
|
path: `${dataPath}/:object/deleteMany`,
|
|
3321
3321
|
handler: async (req, res) => {
|
|
3322
3322
|
try {
|
|
3323
|
-
const
|
|
3324
|
-
const p = await this.resolveProtocol(
|
|
3325
|
-
const context = await this.resolveExecCtx(
|
|
3323
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3324
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
3325
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3326
3326
|
if (this.enforceAuth(req, res, context)) return;
|
|
3327
3327
|
const result = await p.deleteManyData({
|
|
3328
3328
|
object: req.params.object,
|
|
3329
3329
|
...req.body,
|
|
3330
|
-
...
|
|
3330
|
+
...environmentId ? { environmentId } : {},
|
|
3331
3331
|
...context ? { context } : {}
|
|
3332
3332
|
});
|
|
3333
3333
|
res.json(result);
|
|
@@ -3505,64 +3505,64 @@ function createRestApiPlugin(config = {}) {
|
|
|
3505
3505
|
envRegistry = ctx.getService("env-registry");
|
|
3506
3506
|
} catch (e) {
|
|
3507
3507
|
}
|
|
3508
|
-
const
|
|
3508
|
+
const defaultEnvironmentIdProvider = () => {
|
|
3509
3509
|
try {
|
|
3510
3510
|
const dp = ctx.getService("default-project");
|
|
3511
|
-
return dp?.
|
|
3511
|
+
return dp?.environmentId;
|
|
3512
3512
|
} catch {
|
|
3513
3513
|
return void 0;
|
|
3514
3514
|
}
|
|
3515
3515
|
};
|
|
3516
|
-
const authServiceProvider = async (
|
|
3516
|
+
const authServiceProvider = async (_environmentId) => {
|
|
3517
3517
|
try {
|
|
3518
3518
|
return ctx.getService("auth");
|
|
3519
3519
|
} catch {
|
|
3520
3520
|
return void 0;
|
|
3521
3521
|
}
|
|
3522
3522
|
};
|
|
3523
|
-
const objectQLProvider = async (
|
|
3523
|
+
const objectQLProvider = async (_environmentId) => {
|
|
3524
3524
|
try {
|
|
3525
3525
|
return ctx.getService("objectql");
|
|
3526
3526
|
} catch {
|
|
3527
3527
|
return void 0;
|
|
3528
3528
|
}
|
|
3529
3529
|
};
|
|
3530
|
-
const emailServiceProvider = async (
|
|
3530
|
+
const emailServiceProvider = async (_environmentId) => {
|
|
3531
3531
|
try {
|
|
3532
3532
|
return ctx.getService("email");
|
|
3533
3533
|
} catch {
|
|
3534
3534
|
return void 0;
|
|
3535
3535
|
}
|
|
3536
3536
|
};
|
|
3537
|
-
const sharingServiceProvider = async (
|
|
3537
|
+
const sharingServiceProvider = async (_environmentId) => {
|
|
3538
3538
|
try {
|
|
3539
3539
|
return ctx.getService("sharing");
|
|
3540
3540
|
} catch {
|
|
3541
3541
|
return void 0;
|
|
3542
3542
|
}
|
|
3543
3543
|
};
|
|
3544
|
-
const reportsServiceProvider = async (
|
|
3544
|
+
const reportsServiceProvider = async (_environmentId) => {
|
|
3545
3545
|
try {
|
|
3546
3546
|
return ctx.getService("reports");
|
|
3547
3547
|
} catch {
|
|
3548
3548
|
return void 0;
|
|
3549
3549
|
}
|
|
3550
3550
|
};
|
|
3551
|
-
const approvalsServiceProvider = async (
|
|
3551
|
+
const approvalsServiceProvider = async (_environmentId) => {
|
|
3552
3552
|
try {
|
|
3553
3553
|
return ctx.getService("approvals");
|
|
3554
3554
|
} catch {
|
|
3555
3555
|
return void 0;
|
|
3556
3556
|
}
|
|
3557
3557
|
};
|
|
3558
|
-
const sharingRulesServiceProvider = async (
|
|
3558
|
+
const sharingRulesServiceProvider = async (_environmentId) => {
|
|
3559
3559
|
try {
|
|
3560
3560
|
return ctx.getService("sharingRules");
|
|
3561
3561
|
} catch {
|
|
3562
3562
|
return void 0;
|
|
3563
3563
|
}
|
|
3564
3564
|
};
|
|
3565
|
-
const i18nServiceProvider = async (
|
|
3565
|
+
const i18nServiceProvider = async (_environmentId) => {
|
|
3566
3566
|
try {
|
|
3567
3567
|
return ctx.getService("i18n");
|
|
3568
3568
|
} catch {
|
|
@@ -3579,7 +3579,7 @@ function createRestApiPlugin(config = {}) {
|
|
|
3579
3579
|
}
|
|
3580
3580
|
ctx.logger.info("Hydrating REST API from Protocol...");
|
|
3581
3581
|
try {
|
|
3582
|
-
const restServer = new RestServer(server, protocol, config.api, kernelManager, envRegistry,
|
|
3582
|
+
const restServer = new RestServer(server, protocol, config.api, kernelManager, envRegistry, defaultEnvironmentIdProvider, authServiceProvider, objectQLProvider, emailServiceProvider, sharingServiceProvider, reportsServiceProvider, approvalsServiceProvider, sharingRulesServiceProvider, i18nServiceProvider);
|
|
3583
3583
|
restServer.registerRoutes();
|
|
3584
3584
|
ctx.logger.info("REST API successfully registered");
|
|
3585
3585
|
} catch (err) {
|
|
@@ -3595,13 +3595,13 @@ function createRestApiPlugin(config = {}) {
|
|
|
3595
3595
|
const enableProjectScoping = config.api?.api?.enableProjectScoping ?? false;
|
|
3596
3596
|
const projectResolution = config.api?.api?.projectResolution ?? "auto";
|
|
3597
3597
|
if (enableProjectScoping && projectResolution === "required") {
|
|
3598
|
-
registerPackageRoutes(server, packageService, `${versionedBase}/
|
|
3598
|
+
registerPackageRoutes(server, packageService, `${versionedBase}/environments/:environmentId`, {
|
|
3599
3599
|
protocol
|
|
3600
3600
|
});
|
|
3601
3601
|
} else {
|
|
3602
3602
|
registerPackageRoutes(server, packageService, versionedBase, { protocol });
|
|
3603
3603
|
if (enableProjectScoping) {
|
|
3604
|
-
registerPackageRoutes(server, packageService, `${versionedBase}/
|
|
3604
|
+
registerPackageRoutes(server, packageService, `${versionedBase}/environments/:environmentId`, {
|
|
3605
3605
|
protocol
|
|
3606
3606
|
});
|
|
3607
3607
|
}
|