@objectstack/rest 5.2.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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.js
CHANGED
|
@@ -246,7 +246,7 @@ function mapDataError(error, object) {
|
|
|
246
246
|
}
|
|
247
247
|
const raw = String(error?.message ?? error ?? "");
|
|
248
248
|
const lower = raw.toLowerCase();
|
|
249
|
-
if (raw.includes("[
|
|
249
|
+
if (raw.includes("[EnvironmentKernelFactory]") && (lower.includes("missing database_url") || lower.includes("not found"))) {
|
|
250
250
|
const isProvisioning = lower.includes("status='provisioning'") || lower.includes("status='pending'");
|
|
251
251
|
const isFailed = lower.includes("status='failed'");
|
|
252
252
|
return {
|
|
@@ -403,7 +403,7 @@ function rowsToCsv(fields, rows, includeHeader) {
|
|
|
403
403
|
return lines.join("\r\n") + (lines.length > 0 ? "\r\n" : "");
|
|
404
404
|
}
|
|
405
405
|
var RestServer = class {
|
|
406
|
-
constructor(server, protocol, config = {}, kernelManager, envRegistry,
|
|
406
|
+
constructor(server, protocol, config = {}, kernelManager, envRegistry, defaultEnvironmentIdProvider, authServiceProvider, objectQLProvider, emailServiceProvider, sharingServiceProvider, reportsServiceProvider, approvalsServiceProvider, sharingRulesServiceProvider, i18nServiceProvider) {
|
|
407
407
|
/**
|
|
408
408
|
* Lazily load the OpenAPI spec JSON shipped by @objectstack/spec.
|
|
409
409
|
* Cached after first read. Resilient to missing files / parse errors
|
|
@@ -415,7 +415,7 @@ var RestServer = class {
|
|
|
415
415
|
this.routeManager = new RouteManager(server);
|
|
416
416
|
this.kernelManager = kernelManager;
|
|
417
417
|
this.envRegistry = envRegistry;
|
|
418
|
-
this.
|
|
418
|
+
this.defaultEnvironmentIdProvider = defaultEnvironmentIdProvider;
|
|
419
419
|
this.authServiceProvider = authServiceProvider;
|
|
420
420
|
this.objectQLProvider = objectQLProvider;
|
|
421
421
|
this.emailServiceProvider = emailServiceProvider;
|
|
@@ -426,20 +426,20 @@ var RestServer = class {
|
|
|
426
426
|
this.i18nServiceProvider = i18nServiceProvider;
|
|
427
427
|
}
|
|
428
428
|
/**
|
|
429
|
-
* Resolve the protocol for a given request. When `
|
|
429
|
+
* Resolve the protocol for a given request. When `environmentId` is present
|
|
430
430
|
* and a KernelManager is wired, fetch the per-project kernel's
|
|
431
431
|
* `protocol` service so metadata / data / UI reads hit the project's
|
|
432
432
|
* own registry and datastore.
|
|
433
433
|
*
|
|
434
|
-
* When `
|
|
434
|
+
* When `environmentId` is absent on an unscoped route and an `envRegistry`
|
|
435
435
|
* is wired (runtime mode), the resolution chain is:
|
|
436
|
-
* 1. Hostname →
|
|
437
|
-
* 2. `X-
|
|
438
|
-
* 3. Default-project fallback (`
|
|
439
|
-
* `
|
|
436
|
+
* 1. Hostname → environmentId (`envRegistry.resolveByHostname`)
|
|
437
|
+
* 2. `X-Environment-Id` header → environmentId (`envRegistry.resolveById`)
|
|
438
|
+
* 3. Default-project fallback (`defaultEnvironmentIdProvider`, set by
|
|
439
|
+
* `createSingleEnvironmentPlugin`)
|
|
440
440
|
* 4. Control-plane protocol captured at boot.
|
|
441
441
|
*
|
|
442
|
-
* Special case: `
|
|
442
|
+
* Special case: `environmentId === 'platform'` is a reserved virtual id used
|
|
443
443
|
* by Studio to address the control plane through the regular project
|
|
444
444
|
* URL shape (`/projects/platform/...`). It is NOT a row in the projects
|
|
445
445
|
* table, so we must never call `KernelManager.getOrCreate('platform')`.
|
|
@@ -447,37 +447,37 @@ var RestServer = class {
|
|
|
447
447
|
* (and any other client) speak a single, uniform URL family without
|
|
448
448
|
* duplicating route logic for the platform surface.
|
|
449
449
|
*/
|
|
450
|
-
async resolveProtocol(
|
|
451
|
-
if (
|
|
452
|
-
if (!
|
|
450
|
+
async resolveProtocol(environmentId, req) {
|
|
451
|
+
if (environmentId === "platform") return this.protocol;
|
|
452
|
+
if (!environmentId && req && this.envRegistry && this.kernelManager) {
|
|
453
453
|
const host = this.extractHostname(req);
|
|
454
454
|
if (host) {
|
|
455
455
|
try {
|
|
456
456
|
const result = await this.envRegistry.resolveByHostname(host);
|
|
457
|
-
if (result?.
|
|
457
|
+
if (result?.environmentId) environmentId = result.environmentId;
|
|
458
458
|
} catch {
|
|
459
459
|
}
|
|
460
460
|
}
|
|
461
|
-
if (!
|
|
461
|
+
if (!environmentId && typeof this.envRegistry.resolveById === "function") {
|
|
462
462
|
const headerVal = this.extractProjectIdHeader(req);
|
|
463
463
|
if (headerVal) {
|
|
464
464
|
try {
|
|
465
465
|
const driver = await this.envRegistry.resolveById(headerVal);
|
|
466
|
-
if (driver)
|
|
466
|
+
if (driver) environmentId = headerVal;
|
|
467
467
|
} catch {
|
|
468
468
|
}
|
|
469
469
|
}
|
|
470
470
|
}
|
|
471
471
|
}
|
|
472
|
-
if (!
|
|
472
|
+
if (!environmentId && this.defaultEnvironmentIdProvider) {
|
|
473
473
|
try {
|
|
474
|
-
const def = this.
|
|
475
|
-
if (def)
|
|
474
|
+
const def = this.defaultEnvironmentIdProvider();
|
|
475
|
+
if (def) environmentId = def;
|
|
476
476
|
} catch {
|
|
477
477
|
}
|
|
478
478
|
}
|
|
479
|
-
if (!
|
|
480
|
-
const kernel = await this.kernelManager.getOrCreate(
|
|
479
|
+
if (!environmentId || !this.kernelManager) return this.protocol;
|
|
480
|
+
const kernel = await this.kernelManager.getOrCreate(environmentId);
|
|
481
481
|
return kernel.getServiceAsync("protocol");
|
|
482
482
|
}
|
|
483
483
|
/**
|
|
@@ -486,43 +486,43 @@ var RestServer = class {
|
|
|
486
486
|
* registered, so callers can short-circuit and skip translation rather
|
|
487
487
|
* than failing.
|
|
488
488
|
*
|
|
489
|
-
* Mirrors `resolveProtocol`'s lookup chain: explicit `
|
|
489
|
+
* Mirrors `resolveProtocol`'s lookup chain: explicit `environmentId` from the
|
|
490
490
|
* route → kernel-managed `i18n` service. Control-plane / unscoped
|
|
491
491
|
* requests intentionally return `undefined` because the platform kernel
|
|
492
492
|
* does not own per-app translation bundles.
|
|
493
493
|
*/
|
|
494
|
-
async resolveI18nService(
|
|
495
|
-
if (
|
|
496
|
-
if (!
|
|
494
|
+
async resolveI18nService(environmentId, req) {
|
|
495
|
+
if (environmentId === "platform") return void 0;
|
|
496
|
+
if (!environmentId && req && this.envRegistry && this.kernelManager) {
|
|
497
497
|
const host = this.extractHostname(req);
|
|
498
498
|
if (host) {
|
|
499
499
|
try {
|
|
500
500
|
const result = await this.envRegistry.resolveByHostname(host);
|
|
501
|
-
if (result?.
|
|
501
|
+
if (result?.environmentId) environmentId = result.environmentId;
|
|
502
502
|
} catch {
|
|
503
503
|
}
|
|
504
504
|
}
|
|
505
|
-
if (!
|
|
505
|
+
if (!environmentId && typeof this.envRegistry.resolveById === "function") {
|
|
506
506
|
const headerVal = this.extractProjectIdHeader(req);
|
|
507
507
|
if (headerVal) {
|
|
508
508
|
try {
|
|
509
509
|
const driver = await this.envRegistry.resolveById(headerVal);
|
|
510
|
-
if (driver)
|
|
510
|
+
if (driver) environmentId = headerVal;
|
|
511
511
|
} catch {
|
|
512
512
|
}
|
|
513
513
|
}
|
|
514
514
|
}
|
|
515
515
|
}
|
|
516
|
-
if (!
|
|
516
|
+
if (!environmentId && this.defaultEnvironmentIdProvider) {
|
|
517
517
|
try {
|
|
518
|
-
const def = this.
|
|
519
|
-
if (def)
|
|
518
|
+
const def = this.defaultEnvironmentIdProvider();
|
|
519
|
+
if (def) environmentId = def;
|
|
520
520
|
} catch {
|
|
521
521
|
}
|
|
522
522
|
}
|
|
523
|
-
if (
|
|
523
|
+
if (environmentId && this.kernelManager) {
|
|
524
524
|
try {
|
|
525
|
-
const kernel = await this.kernelManager.getOrCreate(
|
|
525
|
+
const kernel = await this.kernelManager.getOrCreate(environmentId);
|
|
526
526
|
const svc = await kernel.getServiceAsync("i18n");
|
|
527
527
|
if (svc) return svc;
|
|
528
528
|
} catch {
|
|
@@ -530,7 +530,7 @@ var RestServer = class {
|
|
|
530
530
|
}
|
|
531
531
|
if (this.i18nServiceProvider) {
|
|
532
532
|
try {
|
|
533
|
-
return await this.i18nServiceProvider(
|
|
533
|
+
return await this.i18nServiceProvider(environmentId);
|
|
534
534
|
} catch {
|
|
535
535
|
return void 0;
|
|
536
536
|
}
|
|
@@ -562,23 +562,23 @@ var RestServer = class {
|
|
|
562
562
|
* `undefined` for anonymous requests so callers can pass `context` as-is
|
|
563
563
|
* to the protocol layer (the SecurityPlugin treats undefined as anon).
|
|
564
564
|
*/
|
|
565
|
-
async resolveExecCtx(
|
|
565
|
+
async resolveExecCtx(environmentId, req) {
|
|
566
566
|
try {
|
|
567
|
-
if (!
|
|
567
|
+
if (!environmentId && req && this.envRegistry && this.kernelManager) {
|
|
568
568
|
const host = this.extractHostname(req);
|
|
569
569
|
if (host) {
|
|
570
570
|
try {
|
|
571
571
|
const result = await this.envRegistry.resolveByHostname(host);
|
|
572
|
-
if (result?.
|
|
572
|
+
if (result?.environmentId) environmentId = result.environmentId;
|
|
573
573
|
} catch {
|
|
574
574
|
}
|
|
575
575
|
}
|
|
576
|
-
if (!
|
|
576
|
+
if (!environmentId && typeof this.envRegistry.resolveById === "function") {
|
|
577
577
|
const headerVal = this.extractProjectIdHeader(req);
|
|
578
578
|
if (headerVal) {
|
|
579
579
|
try {
|
|
580
580
|
const driver = await this.envRegistry.resolveById(headerVal);
|
|
581
|
-
if (driver)
|
|
581
|
+
if (driver) environmentId = headerVal;
|
|
582
582
|
} catch {
|
|
583
583
|
}
|
|
584
584
|
}
|
|
@@ -586,13 +586,13 @@ var RestServer = class {
|
|
|
586
586
|
}
|
|
587
587
|
let authService;
|
|
588
588
|
let kernel;
|
|
589
|
-
if (
|
|
590
|
-
kernel = await this.kernelManager.getOrCreate(
|
|
589
|
+
if (environmentId && environmentId !== "platform" && this.kernelManager) {
|
|
590
|
+
kernel = await this.kernelManager.getOrCreate(environmentId);
|
|
591
591
|
authService = await kernel.getServiceAsync("auth").catch(() => void 0);
|
|
592
592
|
}
|
|
593
|
-
if (!authService && this.
|
|
593
|
+
if (!authService && this.defaultEnvironmentIdProvider && this.kernelManager) {
|
|
594
594
|
try {
|
|
595
|
-
const def = this.
|
|
595
|
+
const def = this.defaultEnvironmentIdProvider();
|
|
596
596
|
if (def) {
|
|
597
597
|
kernel = await this.kernelManager.getOrCreate(def);
|
|
598
598
|
authService = await kernel.getServiceAsync("auth").catch(() => void 0);
|
|
@@ -601,7 +601,7 @@ var RestServer = class {
|
|
|
601
601
|
}
|
|
602
602
|
}
|
|
603
603
|
if (!authService && this.authServiceProvider) {
|
|
604
|
-
authService = await this.authServiceProvider(
|
|
604
|
+
authService = await this.authServiceProvider(environmentId).catch(() => void 0);
|
|
605
605
|
}
|
|
606
606
|
if (!authService) return void 0;
|
|
607
607
|
let api = authService.api;
|
|
@@ -634,7 +634,7 @@ var RestServer = class {
|
|
|
634
634
|
ql = await kernel.getServiceAsync("objectql").catch(() => void 0);
|
|
635
635
|
}
|
|
636
636
|
if (!ql && this.objectQLProvider) {
|
|
637
|
-
ql = await this.objectQLProvider(
|
|
637
|
+
ql = await this.objectQLProvider(environmentId).catch(() => void 0);
|
|
638
638
|
}
|
|
639
639
|
if (ql && typeof ql.find === "function") {
|
|
640
640
|
const sysOpts = { context: { isSystem: true } };
|
|
@@ -684,7 +684,7 @@ var RestServer = class {
|
|
|
684
684
|
ql = await kernel.getServiceAsync("objectql").catch(() => void 0);
|
|
685
685
|
}
|
|
686
686
|
if (!ql && this.objectQLProvider) {
|
|
687
|
-
ql = await this.objectQLProvider(
|
|
687
|
+
ql = await this.objectQLProvider(environmentId).catch(() => void 0);
|
|
688
688
|
}
|
|
689
689
|
if (ql && typeof ql.find === "function") {
|
|
690
690
|
const sysOpts = { context: { isSystem: true } };
|
|
@@ -763,10 +763,10 @@ var RestServer = class {
|
|
|
763
763
|
* locale yields a match. Falls through unchanged for unsupported types
|
|
764
764
|
* or missing translations.
|
|
765
765
|
*/
|
|
766
|
-
async translateMetaItem(req, type,
|
|
766
|
+
async translateMetaItem(req, type, environmentId, item) {
|
|
767
767
|
if (!item || typeof item !== "object") return item;
|
|
768
768
|
if (type !== "view" && type !== "action" && type !== "object") return item;
|
|
769
|
-
const i18n = await this.resolveI18nService(
|
|
769
|
+
const i18n = await this.resolveI18nService(environmentId, req);
|
|
770
770
|
const bundle = this.buildTranslationBundle(i18n);
|
|
771
771
|
if (!bundle) return item;
|
|
772
772
|
const locale = this.extractLocale(req, i18n);
|
|
@@ -777,10 +777,10 @@ var RestServer = class {
|
|
|
777
777
|
/**
|
|
778
778
|
* Translate a list of metadata documents using `translateMetaItem`.
|
|
779
779
|
*/
|
|
780
|
-
async translateMetaItems(req, type,
|
|
780
|
+
async translateMetaItems(req, type, environmentId, items) {
|
|
781
781
|
if (!Array.isArray(items)) return items;
|
|
782
782
|
if (type !== "view" && type !== "action" && type !== "object") return items;
|
|
783
|
-
const i18n = await this.resolveI18nService(
|
|
783
|
+
const i18n = await this.resolveI18nService(environmentId, req);
|
|
784
784
|
const bundle = this.buildTranslationBundle(i18n);
|
|
785
785
|
if (!bundle) return items;
|
|
786
786
|
const locale = this.extractLocale(req, i18n);
|
|
@@ -814,7 +814,7 @@ var RestServer = class {
|
|
|
814
814
|
return String(host).split(":")[0].toLowerCase();
|
|
815
815
|
}
|
|
816
816
|
/**
|
|
817
|
-
* Pull the `X-
|
|
817
|
+
* Pull the `X-Environment-Id` header from a Node- or Fetch-style request.
|
|
818
818
|
* Header names are case-insensitive; we probe both casings to cover
|
|
819
819
|
* adapters that don't normalize headers (e.g. raw Node http).
|
|
820
820
|
*/
|
|
@@ -823,9 +823,9 @@ var RestServer = class {
|
|
|
823
823
|
if (!headers) return void 0;
|
|
824
824
|
let val;
|
|
825
825
|
if (typeof headers.get === "function") {
|
|
826
|
-
val = headers.get("x-
|
|
826
|
+
val = headers.get("x-environment-id") ?? headers.get("X-Environment-Id");
|
|
827
827
|
} else {
|
|
828
|
-
val = headers["x-
|
|
828
|
+
val = headers["x-environment-id"] ?? headers["X-Environment-Id"];
|
|
829
829
|
}
|
|
830
830
|
if (Array.isArray(val)) val = val[0];
|
|
831
831
|
if (typeof val !== "string") return void 0;
|
|
@@ -910,16 +910,16 @@ var RestServer = class {
|
|
|
910
910
|
}
|
|
911
911
|
/**
|
|
912
912
|
* Get the project-scoped base path for a given unscoped base.
|
|
913
|
-
* Example: `/api/v1` → `/api/v1/
|
|
913
|
+
* Example: `/api/v1` → `/api/v1/environments/:environmentId`.
|
|
914
914
|
*/
|
|
915
915
|
getScopedBasePath(basePath) {
|
|
916
|
-
return `${basePath}/
|
|
916
|
+
return `${basePath}/environments/:environmentId`;
|
|
917
917
|
}
|
|
918
918
|
/**
|
|
919
919
|
* Register all REST API routes
|
|
920
920
|
*
|
|
921
921
|
* When `enableProjectScoping` is true, routes are registered under
|
|
922
|
-
* `/api/v1/
|
|
922
|
+
* `/api/v1/environments/:environmentId/...`. The `projectResolution` strategy
|
|
923
923
|
* controls whether unscoped legacy routes remain available:
|
|
924
924
|
* - `required` → only scoped routes registered.
|
|
925
925
|
* - `optional` / `auto` → both scoped and unscoped routes registered.
|
|
@@ -973,12 +973,12 @@ var RestServer = class {
|
|
|
973
973
|
* Register discovery endpoints
|
|
974
974
|
*/
|
|
975
975
|
registerDiscoveryEndpoints(basePath) {
|
|
976
|
-
const isScoped = basePath.includes("/
|
|
976
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
977
977
|
const discoveryHandler = async (req, res) => {
|
|
978
978
|
try {
|
|
979
979
|
const discovery = await this.protocol.getDiscovery();
|
|
980
980
|
discovery.version = this.config.api.version;
|
|
981
|
-
const realBase = isScoped ? basePath.replace(":
|
|
981
|
+
const realBase = isScoped ? basePath.replace(":environmentId", req.params?.environmentId ?? ":environmentId") : basePath;
|
|
982
982
|
if (discovery.routes) {
|
|
983
983
|
if (this.config.api.enableCrud) {
|
|
984
984
|
discovery.routes.data = `${realBase}${this.config.crud.dataPrefix}`;
|
|
@@ -990,7 +990,7 @@ var RestServer = class {
|
|
|
990
990
|
discovery.routes.ui = `${realBase}/ui`;
|
|
991
991
|
}
|
|
992
992
|
if (discovery.routes.auth) {
|
|
993
|
-
const unscopedBase = isScoped ? basePath.replace(/\/projects\/:
|
|
993
|
+
const unscopedBase = isScoped ? basePath.replace(/\/projects\/:environmentId$/, "") : basePath;
|
|
994
994
|
discovery.routes.auth = `${unscopedBase}/auth`;
|
|
995
995
|
}
|
|
996
996
|
}
|
|
@@ -998,7 +998,7 @@ var RestServer = class {
|
|
|
998
998
|
enabled: this.config.api.enableProjectScoping,
|
|
999
999
|
resolution: this.config.api.projectResolution,
|
|
1000
1000
|
scoped: isScoped,
|
|
1001
|
-
|
|
1001
|
+
environmentId: isScoped ? req.params?.environmentId : void 0
|
|
1002
1002
|
};
|
|
1003
1003
|
res.json(discovery);
|
|
1004
1004
|
} catch (error) {
|
|
@@ -1043,7 +1043,7 @@ var RestServer = class {
|
|
|
1043
1043
|
* malformed file degrades to a stub instead of crashing.
|
|
1044
1044
|
*/
|
|
1045
1045
|
registerOpenApiEndpoints(basePath) {
|
|
1046
|
-
const isScoped = basePath.includes("/
|
|
1046
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
1047
1047
|
const openApiHandler = async (req, res) => {
|
|
1048
1048
|
try {
|
|
1049
1049
|
const spec = await this.loadOpenApiSpec();
|
|
@@ -1065,8 +1065,8 @@ var RestServer = class {
|
|
|
1065
1065
|
];
|
|
1066
1066
|
}
|
|
1067
1067
|
try {
|
|
1068
|
-
const
|
|
1069
|
-
const protocol = await this.resolveProtocol(
|
|
1068
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1069
|
+
const protocol = await this.resolveProtocol(environmentId, req);
|
|
1070
1070
|
const items = await protocol?.getMetaItems?.({ type: "object" }).catch(() => null);
|
|
1071
1071
|
const objects = Array.isArray(items?.items) ? items.items.map((i) => i?.name).filter(Boolean) : Array.isArray(items) ? items.map((i) => i?.name).filter(Boolean) : [];
|
|
1072
1072
|
if (objects.length > 0 && enriched.paths) {
|
|
@@ -1160,15 +1160,15 @@ var RestServer = class {
|
|
|
1160
1160
|
registerMetadataEndpoints(basePath) {
|
|
1161
1161
|
const { metadata } = this.config;
|
|
1162
1162
|
const metaPath = `${basePath}${metadata.prefix}`;
|
|
1163
|
-
const isScoped = basePath.includes("/
|
|
1163
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
1164
1164
|
if (metadata.endpoints.types !== false) {
|
|
1165
1165
|
this.routeManager.register({
|
|
1166
1166
|
method: "GET",
|
|
1167
1167
|
path: metaPath,
|
|
1168
1168
|
handler: async (req, res) => {
|
|
1169
1169
|
try {
|
|
1170
|
-
const
|
|
1171
|
-
const p = await this.resolveProtocol(
|
|
1170
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1171
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1172
1172
|
const types = await p.getMetaTypes();
|
|
1173
1173
|
res.json(types);
|
|
1174
1174
|
} catch (error) {
|
|
@@ -1189,14 +1189,14 @@ var RestServer = class {
|
|
|
1189
1189
|
handler: async (req, res) => {
|
|
1190
1190
|
try {
|
|
1191
1191
|
const packageId = req.query?.package || void 0;
|
|
1192
|
-
const
|
|
1193
|
-
const p = await this.resolveProtocol(
|
|
1192
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1193
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1194
1194
|
const items = await p.getMetaItems({
|
|
1195
1195
|
type: req.params.type,
|
|
1196
1196
|
packageId,
|
|
1197
|
-
...
|
|
1197
|
+
...environmentId ? { environmentId } : {}
|
|
1198
1198
|
});
|
|
1199
|
-
const translated = await this.translateMetaItems(req, req.params.type,
|
|
1199
|
+
const translated = await this.translateMetaItems(req, req.params.type, environmentId, items);
|
|
1200
1200
|
res.header("Vary", "Accept-Language");
|
|
1201
1201
|
res.json(translated);
|
|
1202
1202
|
} catch (error) {
|
|
@@ -1216,8 +1216,8 @@ var RestServer = class {
|
|
|
1216
1216
|
path: `${metaPath}/:type/:name`,
|
|
1217
1217
|
handler: async (req, res) => {
|
|
1218
1218
|
try {
|
|
1219
|
-
const
|
|
1220
|
-
const p = await this.resolveProtocol(
|
|
1219
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1220
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1221
1221
|
if (metadata.enableCache && p.getMetaItemCached) {
|
|
1222
1222
|
const cacheRequest = {
|
|
1223
1223
|
ifNoneMatch: req.headers["if-none-match"],
|
|
@@ -1227,7 +1227,7 @@ var RestServer = class {
|
|
|
1227
1227
|
type: req.params.type,
|
|
1228
1228
|
name: req.params.name,
|
|
1229
1229
|
cacheRequest,
|
|
1230
|
-
...
|
|
1230
|
+
...environmentId ? { environmentId } : {}
|
|
1231
1231
|
});
|
|
1232
1232
|
if (result.notModified) {
|
|
1233
1233
|
res.status(304).send();
|
|
@@ -1246,7 +1246,7 @@ var RestServer = class {
|
|
|
1246
1246
|
res.header("Cache-Control", directives + maxAge);
|
|
1247
1247
|
}
|
|
1248
1248
|
res.header("Vary", "Accept-Language");
|
|
1249
|
-
res.json(await this.translateMetaItem(req, req.params.type,
|
|
1249
|
+
res.json(await this.translateMetaItem(req, req.params.type, environmentId, result.data));
|
|
1250
1250
|
} else {
|
|
1251
1251
|
const packageId = req.query?.package || void 0;
|
|
1252
1252
|
const item = await p.getMetaItem({
|
|
@@ -1255,7 +1255,7 @@ var RestServer = class {
|
|
|
1255
1255
|
packageId
|
|
1256
1256
|
});
|
|
1257
1257
|
res.header("Vary", "Accept-Language");
|
|
1258
|
-
res.json(await this.translateMetaItem(req, req.params.type,
|
|
1258
|
+
res.json(await this.translateMetaItem(req, req.params.type, environmentId, item));
|
|
1259
1259
|
}
|
|
1260
1260
|
} catch (error) {
|
|
1261
1261
|
logError("[REST] Unhandled error:", error);
|
|
@@ -1273,8 +1273,8 @@ var RestServer = class {
|
|
|
1273
1273
|
path: `${metaPath}/:type/:name`,
|
|
1274
1274
|
handler: async (req, res) => {
|
|
1275
1275
|
try {
|
|
1276
|
-
const
|
|
1277
|
-
const p = await this.resolveProtocol(
|
|
1276
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1277
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1278
1278
|
if (!p.saveMetaItem) {
|
|
1279
1279
|
res.status(501).json({ error: "Save operation not supported by protocol implementation" });
|
|
1280
1280
|
return;
|
|
@@ -1289,7 +1289,7 @@ var RestServer = class {
|
|
|
1289
1289
|
type: req.params.type,
|
|
1290
1290
|
name: req.params.name,
|
|
1291
1291
|
item,
|
|
1292
|
-
...
|
|
1292
|
+
...environmentId ? { environmentId } : {},
|
|
1293
1293
|
...parentVersion !== void 0 ? { parentVersion } : {},
|
|
1294
1294
|
...actor ? { actor } : {}
|
|
1295
1295
|
});
|
|
@@ -1309,8 +1309,8 @@ var RestServer = class {
|
|
|
1309
1309
|
path: `${metaPath}/:type/:name`,
|
|
1310
1310
|
handler: async (req, res) => {
|
|
1311
1311
|
try {
|
|
1312
|
-
const
|
|
1313
|
-
const p = await this.resolveProtocol(
|
|
1312
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1313
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1314
1314
|
if (!p.deleteMetaItem) {
|
|
1315
1315
|
res.status(501).json({
|
|
1316
1316
|
error: "Reset operation not supported by protocol implementation"
|
|
@@ -1324,7 +1324,7 @@ var RestServer = class {
|
|
|
1324
1324
|
const result = await p.deleteMetaItem({
|
|
1325
1325
|
type: req.params.type,
|
|
1326
1326
|
name: req.params.name,
|
|
1327
|
-
...
|
|
1327
|
+
...environmentId ? { environmentId } : {},
|
|
1328
1328
|
...parentVersion !== void 0 ? { parentVersion } : {},
|
|
1329
1329
|
...actor ? { actor } : {}
|
|
1330
1330
|
});
|
|
@@ -1344,8 +1344,8 @@ var RestServer = class {
|
|
|
1344
1344
|
path: `${metaPath}/:type/:name/history`,
|
|
1345
1345
|
handler: async (req, res) => {
|
|
1346
1346
|
try {
|
|
1347
|
-
const
|
|
1348
|
-
const p = await this.resolveProtocol(
|
|
1347
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1348
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1349
1349
|
if (!p.historyMetaItem) {
|
|
1350
1350
|
res.status(501).json({
|
|
1351
1351
|
error: "History query not supported by protocol implementation"
|
|
@@ -1357,7 +1357,7 @@ var RestServer = class {
|
|
|
1357
1357
|
const result = await p.historyMetaItem({
|
|
1358
1358
|
type: req.params.type,
|
|
1359
1359
|
name: req.params.name,
|
|
1360
|
-
...
|
|
1360
|
+
...environmentId ? { environmentId } : {},
|
|
1361
1361
|
...sinceSeq !== void 0 && Number.isFinite(sinceSeq) ? { sinceSeq } : {},
|
|
1362
1362
|
...limit !== void 0 && Number.isFinite(limit) ? { limit } : {}
|
|
1363
1363
|
});
|
|
@@ -1378,8 +1378,8 @@ var RestServer = class {
|
|
|
1378
1378
|
path: `${metaPath}/:type/:section/:name`,
|
|
1379
1379
|
handler: async (req, res) => {
|
|
1380
1380
|
try {
|
|
1381
|
-
const
|
|
1382
|
-
const p = await this.resolveProtocol(
|
|
1381
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1382
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1383
1383
|
const compoundName = `${req.params.section}/${req.params.name}`;
|
|
1384
1384
|
const packageId = req.query?.package || void 0;
|
|
1385
1385
|
const item = await p.getMetaItem({
|
|
@@ -1388,7 +1388,7 @@ var RestServer = class {
|
|
|
1388
1388
|
packageId
|
|
1389
1389
|
});
|
|
1390
1390
|
res.header("Vary", "Accept-Language");
|
|
1391
|
-
res.json(await this.translateMetaItem(req, req.params.type,
|
|
1391
|
+
res.json(await this.translateMetaItem(req, req.params.type, environmentId, item));
|
|
1392
1392
|
} catch (error) {
|
|
1393
1393
|
logError("[REST] Unhandled error:", error);
|
|
1394
1394
|
sendError(res, error);
|
|
@@ -1405,8 +1405,8 @@ var RestServer = class {
|
|
|
1405
1405
|
path: `${metaPath}/:type/:section/:name`,
|
|
1406
1406
|
handler: async (req, res) => {
|
|
1407
1407
|
try {
|
|
1408
|
-
const
|
|
1409
|
-
const p = await this.resolveProtocol(
|
|
1408
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1409
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1410
1410
|
if (!p.saveMetaItem) {
|
|
1411
1411
|
res.status(501).json({ error: "Save operation not supported by protocol implementation" });
|
|
1412
1412
|
return;
|
|
@@ -1420,7 +1420,7 @@ var RestServer = class {
|
|
|
1420
1420
|
type: req.params.type,
|
|
1421
1421
|
name: compoundName,
|
|
1422
1422
|
item: req.body,
|
|
1423
|
-
...
|
|
1423
|
+
...environmentId ? { environmentId } : {},
|
|
1424
1424
|
...parentVersion !== void 0 ? { parentVersion } : {},
|
|
1425
1425
|
...actor ? { actor } : {}
|
|
1426
1426
|
});
|
|
@@ -1441,19 +1441,19 @@ var RestServer = class {
|
|
|
1441
1441
|
*/
|
|
1442
1442
|
registerUiEndpoints(basePath) {
|
|
1443
1443
|
const uiPath = `${basePath}/ui`;
|
|
1444
|
-
const isScoped = basePath.includes("/
|
|
1444
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
1445
1445
|
this.routeManager.register({
|
|
1446
1446
|
method: "GET",
|
|
1447
1447
|
path: `${uiPath}/view/:object/:type`,
|
|
1448
1448
|
handler: async (req, res) => {
|
|
1449
1449
|
try {
|
|
1450
|
-
const
|
|
1451
|
-
const p = await this.resolveProtocol(
|
|
1450
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1451
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1452
1452
|
if (p.getUiView) {
|
|
1453
1453
|
const view = await p.getUiView({
|
|
1454
1454
|
object: req.params.object,
|
|
1455
1455
|
type: req.params.type,
|
|
1456
|
-
...
|
|
1456
|
+
...environmentId ? { environmentId } : {}
|
|
1457
1457
|
});
|
|
1458
1458
|
res.json(view);
|
|
1459
1459
|
} else {
|
|
@@ -1476,7 +1476,7 @@ var RestServer = class {
|
|
|
1476
1476
|
registerCrudEndpoints(basePath) {
|
|
1477
1477
|
const { crud } = this.config;
|
|
1478
1478
|
const dataPath = `${basePath}${crud.dataPrefix}`;
|
|
1479
|
-
const isScoped = basePath.includes("/
|
|
1479
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
1480
1480
|
const operations = crud.operations;
|
|
1481
1481
|
if (operations.list) {
|
|
1482
1482
|
this.routeManager.register({
|
|
@@ -1484,14 +1484,14 @@ var RestServer = class {
|
|
|
1484
1484
|
path: `${dataPath}/:object`,
|
|
1485
1485
|
handler: async (req, res) => {
|
|
1486
1486
|
try {
|
|
1487
|
-
const
|
|
1488
|
-
const p = await this.resolveProtocol(
|
|
1489
|
-
const context = await this.resolveExecCtx(
|
|
1487
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1488
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1489
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1490
1490
|
if (this.enforceAuth(req, res, context)) return;
|
|
1491
1491
|
const result = await p.findData({
|
|
1492
1492
|
object: req.params.object,
|
|
1493
1493
|
query: req.query,
|
|
1494
|
-
...
|
|
1494
|
+
...environmentId ? { environmentId } : {},
|
|
1495
1495
|
...context ? { context } : {}
|
|
1496
1496
|
});
|
|
1497
1497
|
res.json(result);
|
|
@@ -1517,17 +1517,17 @@ var RestServer = class {
|
|
|
1517
1517
|
path: `${dataPath}/:object/:id`,
|
|
1518
1518
|
handler: async (req, res) => {
|
|
1519
1519
|
try {
|
|
1520
|
-
const
|
|
1521
|
-
const p = await this.resolveProtocol(
|
|
1520
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1521
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1522
1522
|
const { select, expand } = req.query || {};
|
|
1523
|
-
const context = await this.resolveExecCtx(
|
|
1523
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1524
1524
|
if (this.enforceAuth(req, res, context)) return;
|
|
1525
1525
|
const result = await p.getData({
|
|
1526
1526
|
object: req.params.object,
|
|
1527
1527
|
id: req.params.id,
|
|
1528
1528
|
...select != null ? { select } : {},
|
|
1529
1529
|
...expand != null ? { expand } : {},
|
|
1530
|
-
...
|
|
1530
|
+
...environmentId ? { environmentId } : {},
|
|
1531
1531
|
...context ? { context } : {}
|
|
1532
1532
|
});
|
|
1533
1533
|
res.json(result);
|
|
@@ -1549,14 +1549,14 @@ var RestServer = class {
|
|
|
1549
1549
|
path: `${dataPath}/:object`,
|
|
1550
1550
|
handler: async (req, res) => {
|
|
1551
1551
|
try {
|
|
1552
|
-
const
|
|
1553
|
-
const p = await this.resolveProtocol(
|
|
1554
|
-
const context = await this.resolveExecCtx(
|
|
1552
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1553
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1554
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1555
1555
|
if (this.enforceAuth(req, res, context)) return;
|
|
1556
1556
|
const result = await p.createData({
|
|
1557
1557
|
object: req.params.object,
|
|
1558
1558
|
data: req.body,
|
|
1559
|
-
...
|
|
1559
|
+
...environmentId ? { environmentId } : {},
|
|
1560
1560
|
...context ? { context } : {}
|
|
1561
1561
|
});
|
|
1562
1562
|
res.status(201).json(result);
|
|
@@ -1578,14 +1578,14 @@ var RestServer = class {
|
|
|
1578
1578
|
path: `${dataPath}/:object/query`,
|
|
1579
1579
|
handler: async (req, res) => {
|
|
1580
1580
|
try {
|
|
1581
|
-
const
|
|
1582
|
-
const p = await this.resolveProtocol(
|
|
1583
|
-
const context = await this.resolveExecCtx(
|
|
1581
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1582
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1583
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1584
1584
|
if (this.enforceAuth(req, res, context)) return;
|
|
1585
1585
|
const result = await p.findData({
|
|
1586
1586
|
object: req.params.object,
|
|
1587
1587
|
query: req.body || {},
|
|
1588
|
-
...
|
|
1588
|
+
...environmentId ? { environmentId } : {},
|
|
1589
1589
|
...context ? { context } : {}
|
|
1590
1590
|
});
|
|
1591
1591
|
res.json(result);
|
|
@@ -1607,9 +1607,9 @@ var RestServer = class {
|
|
|
1607
1607
|
path: `${dataPath}/:object/:id`,
|
|
1608
1608
|
handler: async (req, res) => {
|
|
1609
1609
|
try {
|
|
1610
|
-
const
|
|
1611
|
-
const p = await this.resolveProtocol(
|
|
1612
|
-
const context = await this.resolveExecCtx(
|
|
1610
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1611
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1612
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1613
1613
|
if (this.enforceAuth(req, res, context)) return;
|
|
1614
1614
|
const ifMatchHeader = req.headers?.["if-match"] ?? req.headers?.["If-Match"];
|
|
1615
1615
|
const bodyVersion = req.body && typeof req.body === "object" ? req.body.expectedVersion : void 0;
|
|
@@ -1624,7 +1624,7 @@ var RestServer = class {
|
|
|
1624
1624
|
id: req.params.id,
|
|
1625
1625
|
data,
|
|
1626
1626
|
...expectedVersion ? { expectedVersion: String(expectedVersion) } : {},
|
|
1627
|
-
...
|
|
1627
|
+
...environmentId ? { environmentId } : {},
|
|
1628
1628
|
...context ? { context } : {}
|
|
1629
1629
|
});
|
|
1630
1630
|
res.json(result);
|
|
@@ -1646,9 +1646,9 @@ var RestServer = class {
|
|
|
1646
1646
|
path: `${dataPath}/:object/:id`,
|
|
1647
1647
|
handler: async (req, res) => {
|
|
1648
1648
|
try {
|
|
1649
|
-
const
|
|
1650
|
-
const p = await this.resolveProtocol(
|
|
1651
|
-
const context = await this.resolveExecCtx(
|
|
1649
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1650
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1651
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1652
1652
|
if (this.enforceAuth(req, res, context)) return;
|
|
1653
1653
|
const ifMatchHeader = req.headers?.["if-match"] ?? req.headers?.["If-Match"];
|
|
1654
1654
|
const queryVersion = req.query && typeof req.query === "object" ? req.query.expectedVersion : void 0;
|
|
@@ -1657,7 +1657,7 @@ var RestServer = class {
|
|
|
1657
1657
|
object: req.params.object,
|
|
1658
1658
|
id: req.params.id,
|
|
1659
1659
|
...expectedVersion ? { expectedVersion: String(expectedVersion) } : {},
|
|
1660
|
-
...
|
|
1660
|
+
...environmentId ? { environmentId } : {},
|
|
1661
1661
|
...context ? { context } : {}
|
|
1662
1662
|
});
|
|
1663
1663
|
res.json(result);
|
|
@@ -1683,7 +1683,7 @@ var RestServer = class {
|
|
|
1683
1683
|
* POST {basePath}/data/lead/:id/convert — M10.6 lead conversion.
|
|
1684
1684
|
*/
|
|
1685
1685
|
registerDataActionEndpoints(basePath) {
|
|
1686
|
-
const isScoped = basePath.includes("/
|
|
1686
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
1687
1687
|
const { crud } = this.config;
|
|
1688
1688
|
const dataPath = `${basePath}${crud.dataPrefix}`;
|
|
1689
1689
|
this.routeManager.register({
|
|
@@ -1691,9 +1691,9 @@ var RestServer = class {
|
|
|
1691
1691
|
path: `${dataPath}/lead/:id/convert`,
|
|
1692
1692
|
handler: async (req, res) => {
|
|
1693
1693
|
try {
|
|
1694
|
-
const
|
|
1695
|
-
const p = await this.resolveProtocol(
|
|
1696
|
-
const context = await this.resolveExecCtx(
|
|
1694
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1695
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1696
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1697
1697
|
if (this.enforceAuth(req, res, context)) return;
|
|
1698
1698
|
const convertLead = p.convertLead;
|
|
1699
1699
|
if (typeof convertLead !== "function") {
|
|
@@ -1726,9 +1726,9 @@ var RestServer = class {
|
|
|
1726
1726
|
path: `${dataPath}/:object/import`,
|
|
1727
1727
|
handler: async (req, res) => {
|
|
1728
1728
|
try {
|
|
1729
|
-
const
|
|
1730
|
-
const p = await this.resolveProtocol(
|
|
1731
|
-
const context = await this.resolveExecCtx(
|
|
1729
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1730
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1731
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1732
1732
|
if (this.enforceAuth(req, res, context)) return;
|
|
1733
1733
|
const objectName = String(req.params.object || "");
|
|
1734
1734
|
if (!objectName) {
|
|
@@ -1809,9 +1809,9 @@ var RestServer = class {
|
|
|
1809
1809
|
path: `${dataPath}/:object/export`,
|
|
1810
1810
|
handler: async (req, res) => {
|
|
1811
1811
|
try {
|
|
1812
|
-
const
|
|
1813
|
-
const p = await this.resolveProtocol(
|
|
1814
|
-
const context = await this.resolveExecCtx(
|
|
1812
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1813
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1814
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1815
1815
|
if (this.enforceAuth(req, res, context)) return;
|
|
1816
1816
|
const objectName = String(req.params.object || "");
|
|
1817
1817
|
if (!objectName) {
|
|
@@ -1860,7 +1860,7 @@ var RestServer = class {
|
|
|
1860
1860
|
}
|
|
1861
1861
|
if (!fields || fields.length === 0) {
|
|
1862
1862
|
try {
|
|
1863
|
-
const schema = await p.getObjectSchema?.(objectName,
|
|
1863
|
+
const schema = await p.getObjectSchema?.(objectName, environmentId);
|
|
1864
1864
|
const schemaFields = schema?.fields;
|
|
1865
1865
|
if (Array.isArray(schemaFields)) {
|
|
1866
1866
|
fields = schemaFields.map((f) => f.name).filter((n) => typeof n === "string");
|
|
@@ -1894,7 +1894,7 @@ var RestServer = class {
|
|
|
1894
1894
|
$top: take,
|
|
1895
1895
|
$skip: skip
|
|
1896
1896
|
},
|
|
1897
|
-
...
|
|
1897
|
+
...environmentId ? { environmentId } : {},
|
|
1898
1898
|
...context ? { context } : {}
|
|
1899
1899
|
};
|
|
1900
1900
|
const result = await p.findData(findArgs);
|
|
@@ -1942,15 +1942,15 @@ var RestServer = class {
|
|
|
1942
1942
|
* GET {basePath}/search?q=acme&objects=lead,account&limit=20&perObject=5
|
|
1943
1943
|
*/
|
|
1944
1944
|
registerSearchEndpoints(basePath) {
|
|
1945
|
-
const isScoped = basePath.includes("/
|
|
1945
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
1946
1946
|
this.routeManager.register({
|
|
1947
1947
|
method: "GET",
|
|
1948
1948
|
path: `${basePath}/search`,
|
|
1949
1949
|
handler: async (req, res) => {
|
|
1950
1950
|
try {
|
|
1951
|
-
const
|
|
1952
|
-
const p = await this.resolveProtocol(
|
|
1953
|
-
const context = await this.resolveExecCtx(
|
|
1951
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1952
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
1953
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
1954
1954
|
if (this.enforceAuth(req, res, context)) return;
|
|
1955
1955
|
const searchAll = p.searchAll;
|
|
1956
1956
|
if (typeof searchAll !== "function") {
|
|
@@ -2002,14 +2002,14 @@ var RestServer = class {
|
|
|
2002
2002
|
* }
|
|
2003
2003
|
*/
|
|
2004
2004
|
registerEmailEndpoints(basePath) {
|
|
2005
|
-
const isScoped = basePath.includes("/
|
|
2005
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
2006
2006
|
this.routeManager.register({
|
|
2007
2007
|
method: "POST",
|
|
2008
2008
|
path: `${basePath}/email/send`,
|
|
2009
2009
|
handler: async (req, res) => {
|
|
2010
2010
|
try {
|
|
2011
|
-
const
|
|
2012
|
-
const context = await this.resolveExecCtx(
|
|
2011
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2012
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2013
2013
|
if (this.enforceAuth(req, res, context)) return;
|
|
2014
2014
|
if (!this.emailServiceProvider) {
|
|
2015
2015
|
res.status(501).json({
|
|
@@ -2018,7 +2018,7 @@ var RestServer = class {
|
|
|
2018
2018
|
});
|
|
2019
2019
|
return;
|
|
2020
2020
|
}
|
|
2021
|
-
const emailService = await this.emailServiceProvider(
|
|
2021
|
+
const emailService = await this.emailServiceProvider(environmentId).catch(() => void 0);
|
|
2022
2022
|
if (!emailService || typeof emailService.send !== "function") {
|
|
2023
2023
|
res.status(501).json({
|
|
2024
2024
|
code: "NOT_IMPLEMENTED",
|
|
@@ -2097,7 +2097,7 @@ var RestServer = class {
|
|
|
2097
2097
|
* `mapViewSpecToEmbeddableConfig` expects.
|
|
2098
2098
|
*/
|
|
2099
2099
|
registerFormEndpoints(basePath) {
|
|
2100
|
-
const isScoped = basePath.includes("/
|
|
2100
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
2101
2101
|
const slugMatchesPublicLink = (publicLink, slug) => {
|
|
2102
2102
|
if (!publicLink || typeof publicLink !== "string") return false;
|
|
2103
2103
|
const normalized = publicLink.replace(/^\/+/, "").replace(/^forms\//, "");
|
|
@@ -2127,12 +2127,12 @@ var RestServer = class {
|
|
|
2127
2127
|
}
|
|
2128
2128
|
return null;
|
|
2129
2129
|
};
|
|
2130
|
-
const resolveFormBySlug = async (
|
|
2131
|
-
const p = await this.resolveProtocol(
|
|
2130
|
+
const resolveFormBySlug = async (environmentId, req, slug) => {
|
|
2131
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
2132
2132
|
if (typeof p.getMetaItems !== "function") return null;
|
|
2133
2133
|
const result = await p.getMetaItems({
|
|
2134
2134
|
type: "view",
|
|
2135
|
-
...
|
|
2135
|
+
...environmentId ? { environmentId } : {}
|
|
2136
2136
|
});
|
|
2137
2137
|
const items = Array.isArray(result?.items) ? result.items : Array.isArray(result) ? result : [];
|
|
2138
2138
|
return findPublicFormView(items, slug);
|
|
@@ -2142,13 +2142,13 @@ var RestServer = class {
|
|
|
2142
2142
|
path: `${basePath}/forms/:slug`,
|
|
2143
2143
|
handler: async (req, res) => {
|
|
2144
2144
|
try {
|
|
2145
|
-
const
|
|
2145
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2146
2146
|
const slug = String(req.params?.slug ?? "").trim();
|
|
2147
2147
|
if (!slug) {
|
|
2148
2148
|
res.status(400).json({ code: "INVALID_REQUEST", error: "slug is required" });
|
|
2149
2149
|
return;
|
|
2150
2150
|
}
|
|
2151
|
-
const match = await resolveFormBySlug(
|
|
2151
|
+
const match = await resolveFormBySlug(environmentId, req, slug);
|
|
2152
2152
|
if (!match) {
|
|
2153
2153
|
res.status(404).json({
|
|
2154
2154
|
code: "FORM_NOT_FOUND",
|
|
@@ -2158,11 +2158,11 @@ var RestServer = class {
|
|
|
2158
2158
|
}
|
|
2159
2159
|
let objectSchema = null;
|
|
2160
2160
|
try {
|
|
2161
|
-
const p = await this.resolveProtocol(
|
|
2161
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
2162
2162
|
if (typeof p.getMetaItems === "function") {
|
|
2163
2163
|
const r = await p.getMetaItems({
|
|
2164
2164
|
type: "object",
|
|
2165
|
-
...
|
|
2165
|
+
...environmentId ? { environmentId } : {}
|
|
2166
2166
|
});
|
|
2167
2167
|
const items = Array.isArray(r?.items) ? r.items : Array.isArray(r) ? r : [];
|
|
2168
2168
|
const obj = items.find((o) => o?.name === match.object);
|
|
@@ -2182,7 +2182,7 @@ var RestServer = class {
|
|
|
2182
2182
|
}
|
|
2183
2183
|
objectSchema = { name: obj.name, label: obj.label, fields };
|
|
2184
2184
|
try {
|
|
2185
|
-
const i18n = await this.resolveI18nService(
|
|
2185
|
+
const i18n = await this.resolveI18nService(environmentId, req);
|
|
2186
2186
|
const bundle = this.buildTranslationBundle(i18n);
|
|
2187
2187
|
const locale = this.extractLocale(req, i18n);
|
|
2188
2188
|
if (bundle && locale) {
|
|
@@ -2242,13 +2242,13 @@ var RestServer = class {
|
|
|
2242
2242
|
path: `${basePath}/forms/:slug/submit`,
|
|
2243
2243
|
handler: async (req, res) => {
|
|
2244
2244
|
try {
|
|
2245
|
-
const
|
|
2245
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2246
2246
|
const slug = String(req.params?.slug ?? "").trim();
|
|
2247
2247
|
if (!slug) {
|
|
2248
2248
|
res.status(400).json({ code: "INVALID_REQUEST", error: "slug is required" });
|
|
2249
2249
|
return;
|
|
2250
2250
|
}
|
|
2251
|
-
const match = await resolveFormBySlug(
|
|
2251
|
+
const match = await resolveFormBySlug(environmentId, req, slug);
|
|
2252
2252
|
if (!match) {
|
|
2253
2253
|
res.status(404).json({
|
|
2254
2254
|
code: "FORM_NOT_FOUND",
|
|
@@ -2276,11 +2276,11 @@ var RestServer = class {
|
|
|
2276
2276
|
permissions: ["guest_portal"],
|
|
2277
2277
|
anonymous: true
|
|
2278
2278
|
};
|
|
2279
|
-
const p = await this.resolveProtocol(
|
|
2279
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
2280
2280
|
const result = await p.createData({
|
|
2281
2281
|
object: match.object,
|
|
2282
2282
|
data: filteredData,
|
|
2283
|
-
...
|
|
2283
|
+
...environmentId ? { environmentId } : {},
|
|
2284
2284
|
context
|
|
2285
2285
|
});
|
|
2286
2286
|
res.status(201).json(result);
|
|
@@ -2302,14 +2302,14 @@ var RestServer = class {
|
|
|
2302
2302
|
path: `${basePath}/forms/:slug/lookup/:field`,
|
|
2303
2303
|
handler: async (req, res) => {
|
|
2304
2304
|
try {
|
|
2305
|
-
const
|
|
2305
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2306
2306
|
const slug = String(req.params?.slug ?? "").trim();
|
|
2307
2307
|
const fieldName = String(req.params?.field ?? "").trim();
|
|
2308
2308
|
if (!slug || !fieldName) {
|
|
2309
2309
|
res.status(400).json({ code: "INVALID_REQUEST", error: "slug and field are required" });
|
|
2310
2310
|
return;
|
|
2311
2311
|
}
|
|
2312
|
-
const match = await resolveFormBySlug(
|
|
2312
|
+
const match = await resolveFormBySlug(environmentId, req, slug);
|
|
2313
2313
|
if (!match) {
|
|
2314
2314
|
res.status(404).json({
|
|
2315
2315
|
code: "FORM_NOT_FOUND",
|
|
@@ -2336,13 +2336,13 @@ var RestServer = class {
|
|
|
2336
2336
|
});
|
|
2337
2337
|
return;
|
|
2338
2338
|
}
|
|
2339
|
-
const p = await this.resolveProtocol(
|
|
2339
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
2340
2340
|
let referenceTo = picker.object;
|
|
2341
2341
|
if (!referenceTo && typeof p.getMetaItems === "function") {
|
|
2342
2342
|
try {
|
|
2343
2343
|
const r = await p.getMetaItems({
|
|
2344
2344
|
type: "object",
|
|
2345
|
-
...
|
|
2345
|
+
...environmentId ? { environmentId } : {}
|
|
2346
2346
|
});
|
|
2347
2347
|
const items = Array.isArray(r?.items) ? r.items : Array.isArray(r) ? r : [];
|
|
2348
2348
|
const obj = items.find((o) => o?.name === match.object);
|
|
@@ -2378,7 +2378,7 @@ var RestServer = class {
|
|
|
2378
2378
|
select: ["id", ...displayFields],
|
|
2379
2379
|
sort: picker.sort ?? [{ field: displayFields[0], order: "asc" }]
|
|
2380
2380
|
},
|
|
2381
|
-
...
|
|
2381
|
+
...environmentId ? { environmentId } : {},
|
|
2382
2382
|
context
|
|
2383
2383
|
});
|
|
2384
2384
|
const rows = Array.isArray(result?.data) ? result.data : Array.isArray(result?.items) ? result.items : [];
|
|
@@ -2428,11 +2428,11 @@ var RestServer = class {
|
|
|
2428
2428
|
registerSharingEndpoints(basePath) {
|
|
2429
2429
|
const { crud } = this.config;
|
|
2430
2430
|
const dataPath = `${basePath}${crud.dataPrefix}`;
|
|
2431
|
-
const isScoped = basePath.includes("/
|
|
2432
|
-
const resolveService = async (
|
|
2431
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
2432
|
+
const resolveService = async (environmentId) => {
|
|
2433
2433
|
if (!this.sharingServiceProvider) return void 0;
|
|
2434
2434
|
try {
|
|
2435
|
-
return await this.sharingServiceProvider(
|
|
2435
|
+
return await this.sharingServiceProvider(environmentId);
|
|
2436
2436
|
} catch {
|
|
2437
2437
|
return void 0;
|
|
2438
2438
|
}
|
|
@@ -2446,10 +2446,10 @@ var RestServer = class {
|
|
|
2446
2446
|
path: `${dataPath}/:object/:id/shares`,
|
|
2447
2447
|
handler: async (req, res) => {
|
|
2448
2448
|
try {
|
|
2449
|
-
const
|
|
2450
|
-
const context = await this.resolveExecCtx(
|
|
2449
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2450
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2451
2451
|
if (this.enforceAuth(req, res, context)) return;
|
|
2452
|
-
const svc = await resolveService(
|
|
2452
|
+
const svc = await resolveService(environmentId);
|
|
2453
2453
|
if (!svc) return respond501(res);
|
|
2454
2454
|
const rows = await svc.listShares(req.params.object, req.params.id, context ?? {});
|
|
2455
2455
|
res.json({ data: rows });
|
|
@@ -2465,10 +2465,10 @@ var RestServer = class {
|
|
|
2465
2465
|
path: `${dataPath}/:object/:id/shares`,
|
|
2466
2466
|
handler: async (req, res) => {
|
|
2467
2467
|
try {
|
|
2468
|
-
const
|
|
2469
|
-
const context = await this.resolveExecCtx(
|
|
2468
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2469
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2470
2470
|
if (this.enforceAuth(req, res, context)) return;
|
|
2471
|
-
const svc = await resolveService(
|
|
2471
|
+
const svc = await resolveService(environmentId);
|
|
2472
2472
|
if (!svc) return respond501(res);
|
|
2473
2473
|
const body = req.body ?? {};
|
|
2474
2474
|
const input = {
|
|
@@ -2507,10 +2507,10 @@ var RestServer = class {
|
|
|
2507
2507
|
path: `${dataPath}/:object/:id/shares/:shareId`,
|
|
2508
2508
|
handler: async (req, res) => {
|
|
2509
2509
|
try {
|
|
2510
|
-
const
|
|
2511
|
-
const context = await this.resolveExecCtx(
|
|
2510
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2511
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2512
2512
|
if (this.enforceAuth(req, res, context)) return;
|
|
2513
|
-
const svc = await resolveService(
|
|
2513
|
+
const svc = await resolveService(environmentId);
|
|
2514
2514
|
if (!svc) return respond501(res);
|
|
2515
2515
|
await svc.revoke(req.params.shareId, context ?? {});
|
|
2516
2516
|
res.status(204).end();
|
|
@@ -2536,11 +2536,11 @@ var RestServer = class {
|
|
|
2536
2536
|
*/
|
|
2537
2537
|
registerSharingRuleEndpoints(basePath) {
|
|
2538
2538
|
const dataPath = basePath;
|
|
2539
|
-
const isScoped = basePath.includes("/
|
|
2540
|
-
const resolveService = async (
|
|
2539
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
2540
|
+
const resolveService = async (environmentId) => {
|
|
2541
2541
|
if (!this.sharingRulesServiceProvider) return void 0;
|
|
2542
2542
|
try {
|
|
2543
|
-
return await this.sharingRulesServiceProvider(
|
|
2543
|
+
return await this.sharingRulesServiceProvider(environmentId);
|
|
2544
2544
|
} catch {
|
|
2545
2545
|
return void 0;
|
|
2546
2546
|
}
|
|
@@ -2565,10 +2565,10 @@ var RestServer = class {
|
|
|
2565
2565
|
path: `${dataPath}/sharing/rules`,
|
|
2566
2566
|
handler: async (req, res) => {
|
|
2567
2567
|
try {
|
|
2568
|
-
const
|
|
2569
|
-
const context = await this.resolveExecCtx(
|
|
2568
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2569
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2570
2570
|
if (this.enforceAuth(req, res, context)) return;
|
|
2571
|
-
const svc = await resolveService(
|
|
2571
|
+
const svc = await resolveService(environmentId);
|
|
2572
2572
|
if (!svc) return respond501(res);
|
|
2573
2573
|
const rows = await svc.listRules({
|
|
2574
2574
|
object: req.query?.object,
|
|
@@ -2586,10 +2586,10 @@ var RestServer = class {
|
|
|
2586
2586
|
path: `${dataPath}/sharing/rules`,
|
|
2587
2587
|
handler: async (req, res) => {
|
|
2588
2588
|
try {
|
|
2589
|
-
const
|
|
2590
|
-
const context = await this.resolveExecCtx(
|
|
2589
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2590
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2591
2591
|
if (this.enforceAuth(req, res, context)) return;
|
|
2592
|
-
const svc = await resolveService(
|
|
2592
|
+
const svc = await resolveService(environmentId);
|
|
2593
2593
|
if (!svc) return respond501(res);
|
|
2594
2594
|
const body = req.body ?? {};
|
|
2595
2595
|
const input = {
|
|
@@ -2616,10 +2616,10 @@ var RestServer = class {
|
|
|
2616
2616
|
path: `${dataPath}/sharing/rules/:idOrName`,
|
|
2617
2617
|
handler: async (req, res) => {
|
|
2618
2618
|
try {
|
|
2619
|
-
const
|
|
2620
|
-
const context = await this.resolveExecCtx(
|
|
2619
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2620
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2621
2621
|
if (this.enforceAuth(req, res, context)) return;
|
|
2622
|
-
const svc = await resolveService(
|
|
2622
|
+
const svc = await resolveService(environmentId);
|
|
2623
2623
|
if (!svc) return respond501(res);
|
|
2624
2624
|
const row = await svc.getRule(req.params.idOrName, context ?? {});
|
|
2625
2625
|
if (!row) return res.status(404).json({ code: "RULE_NOT_FOUND" });
|
|
@@ -2635,10 +2635,10 @@ var RestServer = class {
|
|
|
2635
2635
|
path: `${dataPath}/sharing/rules/:idOrName`,
|
|
2636
2636
|
handler: async (req, res) => {
|
|
2637
2637
|
try {
|
|
2638
|
-
const
|
|
2639
|
-
const context = await this.resolveExecCtx(
|
|
2638
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2639
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2640
2640
|
if (this.enforceAuth(req, res, context)) return;
|
|
2641
|
-
const svc = await resolveService(
|
|
2641
|
+
const svc = await resolveService(environmentId);
|
|
2642
2642
|
if (!svc) return respond501(res);
|
|
2643
2643
|
await svc.deleteRule(req.params.idOrName, context ?? {});
|
|
2644
2644
|
res.status(204).end();
|
|
@@ -2653,10 +2653,10 @@ var RestServer = class {
|
|
|
2653
2653
|
path: `${dataPath}/sharing/rules/:idOrName/evaluate`,
|
|
2654
2654
|
handler: async (req, res) => {
|
|
2655
2655
|
try {
|
|
2656
|
-
const
|
|
2657
|
-
const context = await this.resolveExecCtx(
|
|
2656
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2657
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2658
2658
|
if (this.enforceAuth(req, res, context)) return;
|
|
2659
|
-
const svc = await resolveService(
|
|
2659
|
+
const svc = await resolveService(environmentId);
|
|
2660
2660
|
if (!svc) return respond501(res);
|
|
2661
2661
|
const result = await svc.evaluateRule(req.params.idOrName, context ?? {});
|
|
2662
2662
|
res.json(result);
|
|
@@ -2690,11 +2690,11 @@ var RestServer = class {
|
|
|
2690
2690
|
*/
|
|
2691
2691
|
registerReportsEndpoints(basePath) {
|
|
2692
2692
|
const dataPath = basePath;
|
|
2693
|
-
const isScoped = basePath.includes("/
|
|
2694
|
-
const resolveService = async (
|
|
2693
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
2694
|
+
const resolveService = async (environmentId) => {
|
|
2695
2695
|
if (!this.reportsServiceProvider) return void 0;
|
|
2696
2696
|
try {
|
|
2697
|
-
return await this.reportsServiceProvider(
|
|
2697
|
+
return await this.reportsServiceProvider(environmentId);
|
|
2698
2698
|
} catch {
|
|
2699
2699
|
return void 0;
|
|
2700
2700
|
}
|
|
@@ -2723,10 +2723,10 @@ var RestServer = class {
|
|
|
2723
2723
|
path: `${dataPath}/reports`,
|
|
2724
2724
|
handler: async (req, res) => {
|
|
2725
2725
|
try {
|
|
2726
|
-
const
|
|
2727
|
-
const context = await this.resolveExecCtx(
|
|
2726
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2727
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2728
2728
|
if (this.enforceAuth(req, res, context)) return;
|
|
2729
|
-
const svc = await resolveService(
|
|
2729
|
+
const svc = await resolveService(environmentId);
|
|
2730
2730
|
if (!svc) return respond501(res);
|
|
2731
2731
|
const q = req.query ?? {};
|
|
2732
2732
|
const rows = await svc.listReports({ object: q.object, ownerId: q.ownerId }, context ?? {});
|
|
@@ -2743,10 +2743,10 @@ var RestServer = class {
|
|
|
2743
2743
|
path: `${dataPath}/reports`,
|
|
2744
2744
|
handler: async (req, res) => {
|
|
2745
2745
|
try {
|
|
2746
|
-
const
|
|
2747
|
-
const context = await this.resolveExecCtx(
|
|
2746
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2747
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2748
2748
|
if (this.enforceAuth(req, res, context)) return;
|
|
2749
|
-
const svc = await resolveService(
|
|
2749
|
+
const svc = await resolveService(environmentId);
|
|
2750
2750
|
if (!svc) return respond501(res);
|
|
2751
2751
|
try {
|
|
2752
2752
|
const row = await svc.saveReport(req.body ?? {}, context ?? {});
|
|
@@ -2767,10 +2767,10 @@ var RestServer = class {
|
|
|
2767
2767
|
path: `${dataPath}/reports/:id`,
|
|
2768
2768
|
handler: async (req, res) => {
|
|
2769
2769
|
try {
|
|
2770
|
-
const
|
|
2771
|
-
const context = await this.resolveExecCtx(
|
|
2770
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2771
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2772
2772
|
if (this.enforceAuth(req, res, context)) return;
|
|
2773
|
-
const svc = await resolveService(
|
|
2773
|
+
const svc = await resolveService(environmentId);
|
|
2774
2774
|
if (!svc) return respond501(res);
|
|
2775
2775
|
const row = await svc.getReport(req.params.id, context ?? {});
|
|
2776
2776
|
if (!row) {
|
|
@@ -2790,10 +2790,10 @@ var RestServer = class {
|
|
|
2790
2790
|
path: `${dataPath}/reports/:id`,
|
|
2791
2791
|
handler: async (req, res) => {
|
|
2792
2792
|
try {
|
|
2793
|
-
const
|
|
2794
|
-
const context = await this.resolveExecCtx(
|
|
2793
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2794
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2795
2795
|
if (this.enforceAuth(req, res, context)) return;
|
|
2796
|
-
const svc = await resolveService(
|
|
2796
|
+
const svc = await resolveService(environmentId);
|
|
2797
2797
|
if (!svc) return respond501(res);
|
|
2798
2798
|
await svc.deleteReport(req.params.id, context ?? {});
|
|
2799
2799
|
res.status(204).end();
|
|
@@ -2809,10 +2809,10 @@ var RestServer = class {
|
|
|
2809
2809
|
path: `${dataPath}/reports/:id/run`,
|
|
2810
2810
|
handler: async (req, res) => {
|
|
2811
2811
|
try {
|
|
2812
|
-
const
|
|
2813
|
-
const context = await this.resolveExecCtx(
|
|
2812
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2813
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2814
2814
|
if (this.enforceAuth(req, res, context)) return;
|
|
2815
|
-
const svc = await resolveService(
|
|
2815
|
+
const svc = await resolveService(environmentId);
|
|
2816
2816
|
if (!svc) return respond501(res);
|
|
2817
2817
|
try {
|
|
2818
2818
|
const result = await svc.run(req.params.id, context ?? {});
|
|
@@ -2833,10 +2833,10 @@ var RestServer = class {
|
|
|
2833
2833
|
path: `${dataPath}/reports/:id/schedule`,
|
|
2834
2834
|
handler: async (req, res) => {
|
|
2835
2835
|
try {
|
|
2836
|
-
const
|
|
2837
|
-
const context = await this.resolveExecCtx(
|
|
2836
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2837
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2838
2838
|
if (this.enforceAuth(req, res, context)) return;
|
|
2839
|
-
const svc = await resolveService(
|
|
2839
|
+
const svc = await resolveService(environmentId);
|
|
2840
2840
|
if (!svc) return respond501(res);
|
|
2841
2841
|
const body = req.body ?? {};
|
|
2842
2842
|
try {
|
|
@@ -2869,10 +2869,10 @@ var RestServer = class {
|
|
|
2869
2869
|
path: `${dataPath}/reports/:id/schedules`,
|
|
2870
2870
|
handler: async (req, res) => {
|
|
2871
2871
|
try {
|
|
2872
|
-
const
|
|
2873
|
-
const context = await this.resolveExecCtx(
|
|
2872
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2873
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2874
2874
|
if (this.enforceAuth(req, res, context)) return;
|
|
2875
|
-
const svc = await resolveService(
|
|
2875
|
+
const svc = await resolveService(environmentId);
|
|
2876
2876
|
if (!svc) return respond501(res);
|
|
2877
2877
|
const rows = await svc.listSchedules({ reportId: req.params.id }, context ?? {});
|
|
2878
2878
|
res.json({ data: rows });
|
|
@@ -2888,10 +2888,10 @@ var RestServer = class {
|
|
|
2888
2888
|
path: `${dataPath}/reports/schedules/:scheduleId`,
|
|
2889
2889
|
handler: async (req, res) => {
|
|
2890
2890
|
try {
|
|
2891
|
-
const
|
|
2892
|
-
const context = await this.resolveExecCtx(
|
|
2891
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2892
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2893
2893
|
if (this.enforceAuth(req, res, context)) return;
|
|
2894
|
-
const svc = await resolveService(
|
|
2894
|
+
const svc = await resolveService(environmentId);
|
|
2895
2895
|
if (!svc) return respond501(res);
|
|
2896
2896
|
await svc.unscheduleReport(req.params.scheduleId, context ?? {});
|
|
2897
2897
|
res.status(204).end();
|
|
@@ -2924,11 +2924,11 @@ var RestServer = class {
|
|
|
2924
2924
|
*/
|
|
2925
2925
|
registerApprovalsEndpoints(basePath) {
|
|
2926
2926
|
const dataPath = basePath;
|
|
2927
|
-
const isScoped = basePath.includes("/
|
|
2928
|
-
const resolveService = async (
|
|
2927
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
2928
|
+
const resolveService = async (environmentId) => {
|
|
2929
2929
|
if (!this.approvalsServiceProvider) return void 0;
|
|
2930
2930
|
try {
|
|
2931
|
-
return await this.approvalsServiceProvider(
|
|
2931
|
+
return await this.approvalsServiceProvider(environmentId);
|
|
2932
2932
|
} catch {
|
|
2933
2933
|
return void 0;
|
|
2934
2934
|
}
|
|
@@ -2961,10 +2961,10 @@ var RestServer = class {
|
|
|
2961
2961
|
path: `${dataPath}/approvals/processes`,
|
|
2962
2962
|
handler: async (req, res) => {
|
|
2963
2963
|
try {
|
|
2964
|
-
const
|
|
2965
|
-
const context = await this.resolveExecCtx(
|
|
2964
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2965
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2966
2966
|
if (this.enforceAuth(req, res, context)) return;
|
|
2967
|
-
const svc = await resolveService(
|
|
2967
|
+
const svc = await resolveService(environmentId);
|
|
2968
2968
|
if (!svc) return respond501(res);
|
|
2969
2969
|
const q = req.query ?? {};
|
|
2970
2970
|
const rows = await svc.listProcesses({
|
|
@@ -2984,10 +2984,10 @@ var RestServer = class {
|
|
|
2984
2984
|
path: `${dataPath}/approvals/processes`,
|
|
2985
2985
|
handler: async (req, res) => {
|
|
2986
2986
|
try {
|
|
2987
|
-
const
|
|
2988
|
-
const context = await this.resolveExecCtx(
|
|
2987
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
2988
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
2989
2989
|
if (this.enforceAuth(req, res, context)) return;
|
|
2990
|
-
const svc = await resolveService(
|
|
2990
|
+
const svc = await resolveService(environmentId);
|
|
2991
2991
|
if (!svc) return respond501(res);
|
|
2992
2992
|
try {
|
|
2993
2993
|
const row = await svc.defineProcess(req.body ?? {}, context ?? {});
|
|
@@ -3008,10 +3008,10 @@ var RestServer = class {
|
|
|
3008
3008
|
path: `${dataPath}/approvals/processes/:id`,
|
|
3009
3009
|
handler: async (req, res) => {
|
|
3010
3010
|
try {
|
|
3011
|
-
const
|
|
3012
|
-
const context = await this.resolveExecCtx(
|
|
3011
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3012
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3013
3013
|
if (this.enforceAuth(req, res, context)) return;
|
|
3014
|
-
const svc = await resolveService(
|
|
3014
|
+
const svc = await resolveService(environmentId);
|
|
3015
3015
|
if (!svc) return respond501(res);
|
|
3016
3016
|
const row = await svc.getProcess(req.params.id, context ?? {});
|
|
3017
3017
|
if (!row) {
|
|
@@ -3031,10 +3031,10 @@ var RestServer = class {
|
|
|
3031
3031
|
path: `${dataPath}/approvals/processes/:id`,
|
|
3032
3032
|
handler: async (req, res) => {
|
|
3033
3033
|
try {
|
|
3034
|
-
const
|
|
3035
|
-
const context = await this.resolveExecCtx(
|
|
3034
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3035
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3036
3036
|
if (this.enforceAuth(req, res, context)) return;
|
|
3037
|
-
const svc = await resolveService(
|
|
3037
|
+
const svc = await resolveService(environmentId);
|
|
3038
3038
|
if (!svc) return respond501(res);
|
|
3039
3039
|
await svc.deleteProcess(req.params.id, context ?? {});
|
|
3040
3040
|
res.status(204).end();
|
|
@@ -3050,10 +3050,10 @@ var RestServer = class {
|
|
|
3050
3050
|
path: `${dataPath}/approvals/requests`,
|
|
3051
3051
|
handler: async (req, res) => {
|
|
3052
3052
|
try {
|
|
3053
|
-
const
|
|
3054
|
-
const context = await this.resolveExecCtx(
|
|
3053
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3054
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3055
3055
|
if (this.enforceAuth(req, res, context)) return;
|
|
3056
|
-
const svc = await resolveService(
|
|
3056
|
+
const svc = await resolveService(environmentId);
|
|
3057
3057
|
if (!svc) return respond501(res);
|
|
3058
3058
|
const body = req.body ?? {};
|
|
3059
3059
|
try {
|
|
@@ -3082,10 +3082,10 @@ var RestServer = class {
|
|
|
3082
3082
|
path: `${dataPath}/approvals/requests`,
|
|
3083
3083
|
handler: async (req, res) => {
|
|
3084
3084
|
try {
|
|
3085
|
-
const
|
|
3086
|
-
const context = await this.resolveExecCtx(
|
|
3085
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3086
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3087
3087
|
if (this.enforceAuth(req, res, context)) return;
|
|
3088
|
-
const svc = await resolveService(
|
|
3088
|
+
const svc = await resolveService(environmentId);
|
|
3089
3089
|
if (!svc) {
|
|
3090
3090
|
res.json({ data: [] });
|
|
3091
3091
|
return;
|
|
@@ -3111,10 +3111,10 @@ var RestServer = class {
|
|
|
3111
3111
|
path: `${dataPath}/approvals/requests/:id`,
|
|
3112
3112
|
handler: async (req, res) => {
|
|
3113
3113
|
try {
|
|
3114
|
-
const
|
|
3115
|
-
const context = await this.resolveExecCtx(
|
|
3114
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3115
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3116
3116
|
if (this.enforceAuth(req, res, context)) return;
|
|
3117
|
-
const svc = await resolveService(
|
|
3117
|
+
const svc = await resolveService(environmentId);
|
|
3118
3118
|
if (!svc) return respond501(res);
|
|
3119
3119
|
const row = await svc.getRequest(req.params.id, context ?? {});
|
|
3120
3120
|
if (!row) {
|
|
@@ -3135,10 +3135,10 @@ var RestServer = class {
|
|
|
3135
3135
|
path: `${dataPath}/approvals/requests/:id/${suffix}`,
|
|
3136
3136
|
handler: async (req, res) => {
|
|
3137
3137
|
try {
|
|
3138
|
-
const
|
|
3139
|
-
const context = await this.resolveExecCtx(
|
|
3138
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3139
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3140
3140
|
if (this.enforceAuth(req, res, context)) return;
|
|
3141
|
-
const svc = await resolveService(
|
|
3141
|
+
const svc = await resolveService(environmentId);
|
|
3142
3142
|
if (!svc) return respond501(res);
|
|
3143
3143
|
const body = req.body ?? {};
|
|
3144
3144
|
try {
|
|
@@ -3167,10 +3167,10 @@ var RestServer = class {
|
|
|
3167
3167
|
path: `${dataPath}/approvals/requests/:id/actions`,
|
|
3168
3168
|
handler: async (req, res) => {
|
|
3169
3169
|
try {
|
|
3170
|
-
const
|
|
3171
|
-
const context = await this.resolveExecCtx(
|
|
3170
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3171
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3172
3172
|
if (this.enforceAuth(req, res, context)) return;
|
|
3173
|
-
const svc = await resolveService(
|
|
3173
|
+
const svc = await resolveService(environmentId);
|
|
3174
3174
|
if (!svc) return respond501(res);
|
|
3175
3175
|
const rows = await svc.listActions(req.params.id, context ?? {});
|
|
3176
3176
|
res.json({ data: rows });
|
|
@@ -3188,7 +3188,7 @@ var RestServer = class {
|
|
|
3188
3188
|
registerBatchEndpoints(basePath) {
|
|
3189
3189
|
const { crud, batch } = this.config;
|
|
3190
3190
|
const dataPath = `${basePath}${crud.dataPrefix}`;
|
|
3191
|
-
const isScoped = basePath.includes("/
|
|
3191
|
+
const isScoped = basePath.includes("/environments/:environmentId");
|
|
3192
3192
|
const operations = batch.operations;
|
|
3193
3193
|
if (batch.enableBatchEndpoint && this.protocol.batchData) {
|
|
3194
3194
|
this.routeManager.register({
|
|
@@ -3196,14 +3196,14 @@ var RestServer = class {
|
|
|
3196
3196
|
path: `${dataPath}/:object/batch`,
|
|
3197
3197
|
handler: async (req, res) => {
|
|
3198
3198
|
try {
|
|
3199
|
-
const
|
|
3200
|
-
const p = await this.resolveProtocol(
|
|
3201
|
-
const context = await this.resolveExecCtx(
|
|
3199
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3200
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
3201
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3202
3202
|
if (this.enforceAuth(req, res, context)) return;
|
|
3203
3203
|
const result = await p.batchData({
|
|
3204
3204
|
object: req.params.object,
|
|
3205
3205
|
request: req.body,
|
|
3206
|
-
...
|
|
3206
|
+
...environmentId ? { environmentId } : {},
|
|
3207
3207
|
...context ? { context } : {}
|
|
3208
3208
|
});
|
|
3209
3209
|
res.json(result);
|
|
@@ -3224,14 +3224,14 @@ var RestServer = class {
|
|
|
3224
3224
|
path: `${dataPath}/:object/createMany`,
|
|
3225
3225
|
handler: async (req, res) => {
|
|
3226
3226
|
try {
|
|
3227
|
-
const
|
|
3228
|
-
const p = await this.resolveProtocol(
|
|
3229
|
-
const context = await this.resolveExecCtx(
|
|
3227
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3228
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
3229
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3230
3230
|
if (this.enforceAuth(req, res, context)) return;
|
|
3231
3231
|
const result = await p.createManyData({
|
|
3232
3232
|
object: req.params.object,
|
|
3233
3233
|
records: req.body || [],
|
|
3234
|
-
...
|
|
3234
|
+
...environmentId ? { environmentId } : {},
|
|
3235
3235
|
...context ? { context } : {}
|
|
3236
3236
|
});
|
|
3237
3237
|
res.status(201).json(result);
|
|
@@ -3252,14 +3252,14 @@ var RestServer = class {
|
|
|
3252
3252
|
path: `${dataPath}/:object/updateMany`,
|
|
3253
3253
|
handler: async (req, res) => {
|
|
3254
3254
|
try {
|
|
3255
|
-
const
|
|
3256
|
-
const p = await this.resolveProtocol(
|
|
3257
|
-
const context = await this.resolveExecCtx(
|
|
3255
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3256
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
3257
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3258
3258
|
if (this.enforceAuth(req, res, context)) return;
|
|
3259
3259
|
const result = await p.updateManyData({
|
|
3260
3260
|
object: req.params.object,
|
|
3261
3261
|
...req.body,
|
|
3262
|
-
...
|
|
3262
|
+
...environmentId ? { environmentId } : {},
|
|
3263
3263
|
...context ? { context } : {}
|
|
3264
3264
|
});
|
|
3265
3265
|
res.json(result);
|
|
@@ -3280,14 +3280,14 @@ var RestServer = class {
|
|
|
3280
3280
|
path: `${dataPath}/:object/deleteMany`,
|
|
3281
3281
|
handler: async (req, res) => {
|
|
3282
3282
|
try {
|
|
3283
|
-
const
|
|
3284
|
-
const p = await this.resolveProtocol(
|
|
3285
|
-
const context = await this.resolveExecCtx(
|
|
3283
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3284
|
+
const p = await this.resolveProtocol(environmentId, req);
|
|
3285
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3286
3286
|
if (this.enforceAuth(req, res, context)) return;
|
|
3287
3287
|
const result = await p.deleteManyData({
|
|
3288
3288
|
object: req.params.object,
|
|
3289
3289
|
...req.body,
|
|
3290
|
-
...
|
|
3290
|
+
...environmentId ? { environmentId } : {},
|
|
3291
3291
|
...context ? { context } : {}
|
|
3292
3292
|
});
|
|
3293
3293
|
res.json(result);
|
|
@@ -3465,64 +3465,64 @@ function createRestApiPlugin(config = {}) {
|
|
|
3465
3465
|
envRegistry = ctx.getService("env-registry");
|
|
3466
3466
|
} catch (e) {
|
|
3467
3467
|
}
|
|
3468
|
-
const
|
|
3468
|
+
const defaultEnvironmentIdProvider = () => {
|
|
3469
3469
|
try {
|
|
3470
3470
|
const dp = ctx.getService("default-project");
|
|
3471
|
-
return dp?.
|
|
3471
|
+
return dp?.environmentId;
|
|
3472
3472
|
} catch {
|
|
3473
3473
|
return void 0;
|
|
3474
3474
|
}
|
|
3475
3475
|
};
|
|
3476
|
-
const authServiceProvider = async (
|
|
3476
|
+
const authServiceProvider = async (_environmentId) => {
|
|
3477
3477
|
try {
|
|
3478
3478
|
return ctx.getService("auth");
|
|
3479
3479
|
} catch {
|
|
3480
3480
|
return void 0;
|
|
3481
3481
|
}
|
|
3482
3482
|
};
|
|
3483
|
-
const objectQLProvider = async (
|
|
3483
|
+
const objectQLProvider = async (_environmentId) => {
|
|
3484
3484
|
try {
|
|
3485
3485
|
return ctx.getService("objectql");
|
|
3486
3486
|
} catch {
|
|
3487
3487
|
return void 0;
|
|
3488
3488
|
}
|
|
3489
3489
|
};
|
|
3490
|
-
const emailServiceProvider = async (
|
|
3490
|
+
const emailServiceProvider = async (_environmentId) => {
|
|
3491
3491
|
try {
|
|
3492
3492
|
return ctx.getService("email");
|
|
3493
3493
|
} catch {
|
|
3494
3494
|
return void 0;
|
|
3495
3495
|
}
|
|
3496
3496
|
};
|
|
3497
|
-
const sharingServiceProvider = async (
|
|
3497
|
+
const sharingServiceProvider = async (_environmentId) => {
|
|
3498
3498
|
try {
|
|
3499
3499
|
return ctx.getService("sharing");
|
|
3500
3500
|
} catch {
|
|
3501
3501
|
return void 0;
|
|
3502
3502
|
}
|
|
3503
3503
|
};
|
|
3504
|
-
const reportsServiceProvider = async (
|
|
3504
|
+
const reportsServiceProvider = async (_environmentId) => {
|
|
3505
3505
|
try {
|
|
3506
3506
|
return ctx.getService("reports");
|
|
3507
3507
|
} catch {
|
|
3508
3508
|
return void 0;
|
|
3509
3509
|
}
|
|
3510
3510
|
};
|
|
3511
|
-
const approvalsServiceProvider = async (
|
|
3511
|
+
const approvalsServiceProvider = async (_environmentId) => {
|
|
3512
3512
|
try {
|
|
3513
3513
|
return ctx.getService("approvals");
|
|
3514
3514
|
} catch {
|
|
3515
3515
|
return void 0;
|
|
3516
3516
|
}
|
|
3517
3517
|
};
|
|
3518
|
-
const sharingRulesServiceProvider = async (
|
|
3518
|
+
const sharingRulesServiceProvider = async (_environmentId) => {
|
|
3519
3519
|
try {
|
|
3520
3520
|
return ctx.getService("sharingRules");
|
|
3521
3521
|
} catch {
|
|
3522
3522
|
return void 0;
|
|
3523
3523
|
}
|
|
3524
3524
|
};
|
|
3525
|
-
const i18nServiceProvider = async (
|
|
3525
|
+
const i18nServiceProvider = async (_environmentId) => {
|
|
3526
3526
|
try {
|
|
3527
3527
|
return ctx.getService("i18n");
|
|
3528
3528
|
} catch {
|
|
@@ -3539,7 +3539,7 @@ function createRestApiPlugin(config = {}) {
|
|
|
3539
3539
|
}
|
|
3540
3540
|
ctx.logger.info("Hydrating REST API from Protocol...");
|
|
3541
3541
|
try {
|
|
3542
|
-
const restServer = new RestServer(server, protocol, config.api, kernelManager, envRegistry,
|
|
3542
|
+
const restServer = new RestServer(server, protocol, config.api, kernelManager, envRegistry, defaultEnvironmentIdProvider, authServiceProvider, objectQLProvider, emailServiceProvider, sharingServiceProvider, reportsServiceProvider, approvalsServiceProvider, sharingRulesServiceProvider, i18nServiceProvider);
|
|
3543
3543
|
restServer.registerRoutes();
|
|
3544
3544
|
ctx.logger.info("REST API successfully registered");
|
|
3545
3545
|
} catch (err) {
|
|
@@ -3555,13 +3555,13 @@ function createRestApiPlugin(config = {}) {
|
|
|
3555
3555
|
const enableProjectScoping = config.api?.api?.enableProjectScoping ?? false;
|
|
3556
3556
|
const projectResolution = config.api?.api?.projectResolution ?? "auto";
|
|
3557
3557
|
if (enableProjectScoping && projectResolution === "required") {
|
|
3558
|
-
registerPackageRoutes(server, packageService, `${versionedBase}/
|
|
3558
|
+
registerPackageRoutes(server, packageService, `${versionedBase}/environments/:environmentId`, {
|
|
3559
3559
|
protocol
|
|
3560
3560
|
});
|
|
3561
3561
|
} else {
|
|
3562
3562
|
registerPackageRoutes(server, packageService, versionedBase, { protocol });
|
|
3563
3563
|
if (enableProjectScoping) {
|
|
3564
|
-
registerPackageRoutes(server, packageService, `${versionedBase}/
|
|
3564
|
+
registerPackageRoutes(server, packageService, `${versionedBase}/environments/:environmentId`, {
|
|
3565
3565
|
protocol
|
|
3566
3566
|
});
|
|
3567
3567
|
}
|