c8y-nitro 0.7.2 → 0.9.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/{autoBootstrap-Drk7ltXK.mjs → autoBootstrap-qCcCgset.mjs} +1 -1
- package/dist/{bootstrap-C1Qly0J_.mjs → bootstrap-BcTCUiqG.mjs} +2 -2
- package/dist/{c8y-api-DscUs-Kd.mjs → c8y-api-DpCWhaJU.mjs} +8 -0
- package/dist/cli/index.mjs +4 -4
- package/dist/{client-D0Tdq7H1.mjs → client-DCov9jV6.mjs} +15 -4
- package/dist/{index-vu4xaFkz.d.mts → index-Dil1PcDr.d.mts} +108 -4
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +36 -3
- package/dist/{options-CmLpZ3Qf.mjs → options-BBnR-y_W.mjs} +2 -2
- package/dist/{package-BHOzdhHp.mjs → package-gK1cGX1w.mjs} +1 -1
- package/dist/{roles-B-DNuScZ.mjs → roles-CkUvL64s.mjs} +1 -1
- package/dist/runtime/handlers/invalidateTenantOptions.mjs +1 -1
- package/dist/runtime/handlers/openapi.mjs +1 -1
- package/dist/runtime/handlers/rewriteRequestUrl.mjs +1 -1
- package/dist/types.d.mts +2 -2
- package/dist/utils.d.mts +344 -75
- package/dist/utils.mjs +417 -147
- package/package.json +4 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as findMicroserviceByName, d as updateMicroservice, l as subscribeToApplication, n as createBasicAuthHeader, o as getBootstrapCredentials, p as createC8yManifest, r as createMicroservice } from "./c8y-api-
|
|
1
|
+
import { a as findMicroserviceByName, d as updateMicroservice, l as subscribeToApplication, n as createBasicAuthHeader, o as getBootstrapCredentials, p as createC8yManifest, r as createMicroservice } from "./c8y-api-DpCWhaJU.mjs";
|
|
2
2
|
import { t as writeBootstrapCredentials } from "./env-file-BrOTmVjA.mjs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as findMicroserviceByName, d as updateMicroservice, l as subscribeToApplication, n as createBasicAuthHeader, o as getBootstrapCredentials, p as createC8yManifest, r as createMicroservice } from "./c8y-api-
|
|
1
|
+
import { a as findMicroserviceByName, d as updateMicroservice, l as subscribeToApplication, n as createBasicAuthHeader, o as getBootstrapCredentials, p as createC8yManifest, r as createMicroservice } from "./c8y-api-DpCWhaJU.mjs";
|
|
2
2
|
import { t as writeBootstrapCredentials } from "./env-file-BrOTmVjA.mjs";
|
|
3
3
|
import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-BVQHqlgV.mjs";
|
|
4
4
|
import { defineCommand, runCommand } from "citty";
|
|
@@ -52,7 +52,7 @@ var bootstrap_default = defineCommand({
|
|
|
52
52
|
});
|
|
53
53
|
consola.success(`Bootstrap credentials written to ${envFileName}`);
|
|
54
54
|
if (manifest.roles && manifest.roles.length > 0) {
|
|
55
|
-
if (await consola.prompt("Do you want to manage microservice roles for your development user?", { type: "confirm" })) await runCommand(await import("./roles-
|
|
55
|
+
if (await consola.prompt("Do you want to manage microservice roles for your development user?", { type: "confirm" })) await runCommand(await import("./roles-CkUvL64s.mjs").then((r) => r.default), { rawArgs: [] });
|
|
56
56
|
}
|
|
57
57
|
consola.success("Bootstrap complete!");
|
|
58
58
|
}
|
|
@@ -9,6 +9,13 @@ const GENERATED_INVALIDATE_TENANT_OPTIONS_ROUTE = "/_c8y_nitro/invalidate-tenant
|
|
|
9
9
|
const DEFAULT_OPENAPI_ROUTE = "/_openapi.json";
|
|
10
10
|
const ROLE_OPTION_MANAGEMENT_READ = "ROLE_OPTION_MANAGEMENT_READ";
|
|
11
11
|
/**
|
|
12
|
+
* Cumulocity microservice name constraints: lowercase letters, digits and
|
|
13
|
+
* hyphens only, 1-23 characters. Enforced by the platform on upload, so we
|
|
14
|
+
* fail early with a clear message instead of a cryptic API rejection.
|
|
15
|
+
* @see https://github.com/schplitt/c8y-nitro/issues/75
|
|
16
|
+
*/
|
|
17
|
+
const MICROSERVICE_NAME_REGEX = /^[a-z0-9-]{1,23}$/;
|
|
18
|
+
/**
|
|
12
19
|
* Decide whether Nitro will expose an OpenAPI spec in the deployed build,
|
|
13
20
|
* and if so return the configured route (with leading slash).
|
|
14
21
|
* Returns null when OpenAPI is not enabled for production.
|
|
@@ -45,6 +52,7 @@ async function readPackageJsonFieldsForManifest(rootDir, logger) {
|
|
|
45
52
|
const authorEmail = typeof author === "string" ? void 0 : author?.email;
|
|
46
53
|
const authorUrl = typeof author === "string" ? void 0 : author?.url;
|
|
47
54
|
if (!name || !version || !authorName) throw new Error("package.json must contain name, version, and author name fields");
|
|
55
|
+
if (!MICROSERVICE_NAME_REGEX.test(name)) throw new Error(`Invalid microservice name "${name}". Cumulocity requires the name to match ${MICROSERVICE_NAME_REGEX.source} (lowercase letters, digits and hyphens only, 1-23 characters). Adjust the "name" field in package.json accordingly (scope like "@org/" is stripped and does not count).`);
|
|
48
56
|
const support = typeof pkg.bugs === "string" ? pkg.bugs : pkg.bugs?.url ?? pkg.bugs?.email;
|
|
49
57
|
const provider = {
|
|
50
58
|
name: authorName ?? name,
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as name, r as version, t as description } from "../package-
|
|
1
|
+
import { n as name, r as version, t as description } from "../package-gK1cGX1w.mjs";
|
|
2
2
|
import { defineCommand, runMain } from "citty";
|
|
3
3
|
//#region src/cli/index.ts
|
|
4
4
|
runMain(defineCommand({
|
|
@@ -8,9 +8,9 @@ runMain(defineCommand({
|
|
|
8
8
|
description
|
|
9
9
|
},
|
|
10
10
|
subCommands: {
|
|
11
|
-
bootstrap: () => import("../bootstrap-
|
|
12
|
-
roles: () => import("../roles-
|
|
13
|
-
options: () => import("../options-
|
|
11
|
+
bootstrap: () => import("../bootstrap-BcTCUiqG.mjs").then((r) => r.default),
|
|
12
|
+
roles: () => import("../roles-CkUvL64s.mjs").then((r) => r.default),
|
|
13
|
+
options: () => import("../options-BBnR-y_W.mjs").then((r) => r.default)
|
|
14
14
|
}
|
|
15
15
|
}));
|
|
16
16
|
//#endregion
|
|
@@ -8,6 +8,18 @@ import { useRuntimeConfig } from "nitro/runtime-config";
|
|
|
8
8
|
import { useNitroHooks } from "nitro/app";
|
|
9
9
|
//#region src/utils/internal/common.ts
|
|
10
10
|
/**
|
|
11
|
+
* Whether two sets of tenant credentials are equivalent for the purposes of
|
|
12
|
+
* change detection: same tenant, user, and password. Used to detect a
|
|
13
|
+
* service-user password rotation (which keeps the tenant id but changes the
|
|
14
|
+
* secret), not just tenants entering/leaving the subscription set.
|
|
15
|
+
* @param a - First credentials, or `undefined` when the tenant is absent
|
|
16
|
+
* @param b - Second credentials, or `undefined` when the tenant is absent
|
|
17
|
+
*/
|
|
18
|
+
function credsEqual(a, b) {
|
|
19
|
+
if (!a || !b) return a === b;
|
|
20
|
+
return a.tenant === b.tenant && a.user === b.user && a.password === b.password;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
11
23
|
* Converts undici Request headers to the format expected by MicroserviceClientRequestAuth.\
|
|
12
24
|
* Extracts the following headers from the request:
|
|
13
25
|
* - `authorization`: Used for Basic Auth or Bearer token authentication
|
|
@@ -145,10 +157,9 @@ function buildPublicRequestUrl(tenantDomain, contextPath, url) {
|
|
|
145
157
|
let prevCredentials = null;
|
|
146
158
|
function shouldEmitTenantCredentialsUpdated(prev, next) {
|
|
147
159
|
if (!prev) return true;
|
|
148
|
-
const
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
return new Set(nextTenantIds).symmetricDifference(new Set(prevTenantIds)).size > 0;
|
|
160
|
+
const tenantIds = /* @__PURE__ */ new Set([...Object.keys(prev), ...Object.keys(next)]);
|
|
161
|
+
for (const tenantId of tenantIds) if (!credsEqual(prev[tenantId], next[tenantId])) return true;
|
|
162
|
+
return false;
|
|
152
163
|
}
|
|
153
164
|
/**
|
|
154
165
|
* Fetches credentials for all tenants subscribed to this microservice.\
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import "./credentials-eKnJ7m9Y.mjs";
|
|
2
|
+
import { ConsumerResilienceOptions, SubscriptionApi } from "c8y-realtime";
|
|
2
3
|
import { C8YTenantOptionKeysCacheConfig } from "c8y-nitro/types";
|
|
3
4
|
//#region src/types/apiClient.d.ts
|
|
4
5
|
interface C8YAPIClientOptions {
|
|
@@ -15,6 +16,34 @@ interface C8YAPIClientOptions {
|
|
|
15
16
|
contextPath?: string;
|
|
16
17
|
}
|
|
17
18
|
//#endregion
|
|
19
|
+
//#region src/types/roles.generated.d.ts
|
|
20
|
+
/**
|
|
21
|
+
* AUTO-GENERATED by scripts/generate-roles.ts — do not edit by hand.
|
|
22
|
+
*
|
|
23
|
+
* Source: https://cumulocity.com/api/core/dist/c8y-oas.json
|
|
24
|
+
* Spec version: Latest
|
|
25
|
+
* Known roles: 46
|
|
26
|
+
*
|
|
27
|
+
* Run `pnpm gen:roles` to regenerate.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Cumulocity platform roles ("required roles") known from the core OpenAPI spec.
|
|
31
|
+
*/
|
|
32
|
+
type C8YKnownRole = 'ROLE_ALARM_ADMIN' | 'ROLE_ALARM_READ' | 'ROLE_APPLICATION_MANAGEMENT_ADMIN' | 'ROLE_APPLICATION_MANAGEMENT_READ' | 'ROLE_AUDIT_ADMIN' | 'ROLE_AUDIT_READ' | 'ROLE_BINARY_ADMIN' | 'ROLE_BINARY_CREATE' | 'ROLE_BINARY_READ' | 'ROLE_BULK_OPERATION_ADMIN' | 'ROLE_BULK_OPERATION_READ' | 'ROLE_DEVICE' | 'ROLE_DEVICE_BOOTSTRAP' | 'ROLE_DEVICE_CONTROL_ADMIN' | 'ROLE_DEVICE_CONTROL_READ' | 'ROLE_EVENT_ADMIN' | 'ROLE_EVENT_READ' | 'ROLE_IDENTITY_ADMIN' | 'ROLE_IDENTITY_READ' | 'ROLE_INVENTORY_ADMIN' | 'ROLE_INVENTORY_CREATE' | 'ROLE_INVENTORY_READ' | 'ROLE_MANAGED_OBJECT_ADMIN' | 'ROLE_MANAGED_OBJECT_CREATE' | 'ROLE_MANAGED_OBJECT_READ' | 'ROLE_MEASUREMENT_ADMIN' | 'ROLE_MEASUREMENT_READ' | 'ROLE_NOTIFICATION_2_ADMIN' | 'ROLE_OPTION_MANAGEMENT_ADMIN' | 'ROLE_OPTION_MANAGEMENT_READ' | 'ROLE_RETENTION_RULE_ADMIN' | 'ROLE_RETENTION_RULE_READ' | 'ROLE_SMS_READ' | 'ROLE_SYSTEM' | 'ROLE_TENANT_ADMIN' | 'ROLE_TENANT_ALARM_ADMIN' | 'ROLE_TENANT_MANAGEMENT_ADMIN' | 'ROLE_TENANT_MANAGEMENT_CREATE' | 'ROLE_TENANT_MANAGEMENT_READ' | 'ROLE_TENANT_MANAGEMENT_UPDATE' | 'ROLE_TENANT_STATISTICS_READ' | 'ROLE_USER_MANAGEMENT_ADMIN' | 'ROLE_USER_MANAGEMENT_CREATE' | 'ROLE_USER_MANAGEMENT_OWN_ADMIN' | 'ROLE_USER_MANAGEMENT_OWN_READ' | 'ROLE_USER_MANAGEMENT_READ';
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/types/roles.d.ts
|
|
35
|
+
/**
|
|
36
|
+
* Roles your microservice provides. Populated at runtime from the manifest's
|
|
37
|
+
* `roles` field (see the module's generated `c8y-nitro.d.ts`).
|
|
38
|
+
*/
|
|
39
|
+
interface C8YRoles$1 {}
|
|
40
|
+
/**
|
|
41
|
+
* A Cumulocity role usable in the manifest. Autocompletes the platform roles
|
|
42
|
+
* known from the OpenAPI spec ({@link C8YKnownRole}) while still accepting any
|
|
43
|
+
* other string (custom roles, or roles not yet in the generated list).
|
|
44
|
+
*/
|
|
45
|
+
type C8YRole$1 = C8YKnownRole | (string & {});
|
|
46
|
+
//#endregion
|
|
18
47
|
//#region src/types/manifest.d.ts
|
|
19
48
|
type C8YManifestOptions = Omit<C8YManifest, 'name' | 'version' | 'apiVersion' | 'key' | 'type' | 'provider' | 'openApiSpec'>;
|
|
20
49
|
interface C8YManifest {
|
|
@@ -105,7 +134,7 @@ interface C8YManifest {
|
|
|
105
134
|
* Needed to access Cumulocity APIs (inventory, alarms, etc.).
|
|
106
135
|
* @example ["ROLE_ALARM_READ", "ROLE_INVENTORY_ADMIN"]
|
|
107
136
|
*/
|
|
108
|
-
requiredRoles?:
|
|
137
|
+
requiredRoles?: C8YRole$1[];
|
|
109
138
|
/**
|
|
110
139
|
* New permissions provided by this microservice.
|
|
111
140
|
* Users can be assigned these to access your endpoints.
|
|
@@ -407,8 +436,78 @@ interface C8yDockerOptions {
|
|
|
407
436
|
extraInstructions?: string[];
|
|
408
437
|
}
|
|
409
438
|
//#endregion
|
|
410
|
-
//#region src/types/
|
|
411
|
-
|
|
439
|
+
//#region src/types/realtime.d.ts
|
|
440
|
+
/**
|
|
441
|
+
* Options for the Notification 2.0 realtime clients (backed by `c8y-realtime`).
|
|
442
|
+
*
|
|
443
|
+
* Resolved once at build time into runtime config and spread **identically**
|
|
444
|
+
* into every per-tenant `RealtimeClient` the pool creates — so all subscribed
|
|
445
|
+
* tenants behave consistently in a multi-tenant deployment. Only the
|
|
446
|
+
* credentials differ per tenant.
|
|
447
|
+
*/
|
|
448
|
+
interface C8yRealtimeOptions {
|
|
449
|
+
/**
|
|
450
|
+
* Base name for this app's realtime topics/consumers (must be alphanumeric).
|
|
451
|
+
*
|
|
452
|
+
* Leave unset to derive it deterministically from the microservice
|
|
453
|
+
* `contextPath` (a short hash is appended so distinct services never collide
|
|
454
|
+
* on one platform topic). The derived name is **stable** across restarts and
|
|
455
|
+
* redeploys, so a reconnecting service resumes the same persistent
|
|
456
|
+
* subscription and its backlog. Set this only if you need to pin the name
|
|
457
|
+
* explicitly; it is a permanent identity — changing it later orphans the old
|
|
458
|
+
* subscriptions.
|
|
459
|
+
*/
|
|
460
|
+
name?: string;
|
|
461
|
+
/**
|
|
462
|
+
* Delete **every** remote subscription this service created when Nitro shuts
|
|
463
|
+
* down. Keep `false` so persistent backlogs survive a redeploy.
|
|
464
|
+
* @default false
|
|
465
|
+
*/
|
|
466
|
+
deleteSubscriptionsOnClose?: boolean;
|
|
467
|
+
/**
|
|
468
|
+
* Delete a `(type, device)` remote subscription once its last handler is
|
|
469
|
+
* removed. This is the only path that deletes a remote subscription — tenant
|
|
470
|
+
* churn never does.
|
|
471
|
+
* @default true
|
|
472
|
+
*/
|
|
473
|
+
deleteSubscriptionOnEmpty?: boolean;
|
|
474
|
+
/**
|
|
475
|
+
* Acknowledge each notification after its handlers resolve.
|
|
476
|
+
* @default true
|
|
477
|
+
*/
|
|
478
|
+
autoAck?: boolean;
|
|
479
|
+
/**
|
|
480
|
+
* Drop duplicate notifications redelivered on the same stream (e.g. on
|
|
481
|
+
* reconnect).
|
|
482
|
+
* @default true
|
|
483
|
+
*/
|
|
484
|
+
dedupe?: boolean;
|
|
485
|
+
/**
|
|
486
|
+
* Open the connection automatically as handlers are registered. Set `false`
|
|
487
|
+
* to connect manually via the client's `start()`.
|
|
488
|
+
* @default true
|
|
489
|
+
*/
|
|
490
|
+
autoStart?: boolean;
|
|
491
|
+
/**
|
|
492
|
+
* Subscription delivery mode applied to every tenant's client.
|
|
493
|
+
*/
|
|
494
|
+
subscription?: {
|
|
495
|
+
/**
|
|
496
|
+
* APIs for the `onAny` firehose topic. Typed topics always use their own
|
|
497
|
+
* type. Defaults to `['*']`.
|
|
498
|
+
*/
|
|
499
|
+
apis?: SubscriptionApi[];
|
|
500
|
+
/**
|
|
501
|
+
* Target a non-persistent topic (no server-side backlog; cheaper, but a
|
|
502
|
+
* disconnect loses messages). Defaults to `false`.
|
|
503
|
+
*/
|
|
504
|
+
nonPersistent?: boolean;
|
|
505
|
+
};
|
|
506
|
+
/**
|
|
507
|
+
* Reconnect/backoff behaviour, applied identically to every tenant's client.
|
|
508
|
+
*/
|
|
509
|
+
resilience?: ConsumerResilienceOptions;
|
|
510
|
+
}
|
|
412
511
|
//#endregion
|
|
413
512
|
//#region src/types/tenantOptions.d.ts
|
|
414
513
|
/**
|
|
@@ -466,6 +565,11 @@ interface C8yNitroModuleOptions {
|
|
|
466
565
|
*/
|
|
467
566
|
docker?: C8yDockerOptions;
|
|
468
567
|
cache?: C8yCacheOptions;
|
|
568
|
+
/**
|
|
569
|
+
* Options for the Notification 2.0 realtime clients (backed by `c8y-realtime`),
|
|
570
|
+
* shared by every subscribed tenant's pooled client.
|
|
571
|
+
*/
|
|
572
|
+
realtime?: C8yRealtimeOptions;
|
|
469
573
|
/**
|
|
470
574
|
* Controls how the OpenAPI document served by Nitro (`experimental.openAPI`)
|
|
471
575
|
* is transformed for Cumulocity microservices.
|
|
@@ -494,4 +598,4 @@ interface C8yNitroModuleOptions {
|
|
|
494
598
|
skipBootstrap?: boolean;
|
|
495
599
|
}
|
|
496
600
|
//#endregion
|
|
497
|
-
export { C8YTenantOptionKey$1 as a, C8yDockerOptions as c, C8YManifest as d, C8YManifestOptions as f, C8YSettingsCategory$1 as i, C8yCacheOptions as l, C8yNitroModuleOptions as n, C8YTenantOptionKeysCacheConfig$1 as o,
|
|
601
|
+
export { C8YTenantOptionKey$1 as a, C8yDockerOptions as c, C8YManifest as d, C8YManifestOptions as f, C8YAPIClientOptions as g, C8YKnownRole as h, C8YSettingsCategory$1 as i, C8yCacheOptions as l, C8YRoles$1 as m, C8yNitroModuleOptions as n, C8YTenantOptionKeysCacheConfig$1 as o, C8YRole$1 as p, C8yOpenAPIOptions as r, C8yRealtimeOptions as s, C8yDevOptions as t, C8YZipOptions as u };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as C8yNitroModuleOptions } from "./index-
|
|
1
|
+
import { n as C8yNitroModuleOptions } from "./index-Dil1PcDr.mjs";
|
|
2
2
|
import { t as TenantCredentials } from "./credentials-eKnJ7m9Y.mjs";
|
|
3
3
|
import { NitroModule } from "nitro/types";
|
|
4
4
|
//#region src/index.d.ts
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { _ as GENERATED_READINESS_ROUTE, g as GENERATED_LIVENESS_ROUTE, h as GENERATED_INVALIDATE_TENANT_OPTIONS_ROUTE, m as createC8yManifestFromNitro, p as createC8yManifest } from "./c8y-api-
|
|
2
|
-
import { t as autoBootstrap } from "./autoBootstrap-
|
|
3
|
-
import { n as name } from "./package-
|
|
1
|
+
import { _ as GENERATED_READINESS_ROUTE, g as GENERATED_LIVENESS_ROUTE, h as GENERATED_INVALIDATE_TENANT_OPTIONS_ROUTE, m as createC8yManifestFromNitro, p as createC8yManifest } from "./c8y-api-DpCWhaJU.mjs";
|
|
2
|
+
import { t as autoBootstrap } from "./autoBootstrap-qCcCgset.mjs";
|
|
3
|
+
import { n as name } from "./package-gK1cGX1w.mjs";
|
|
4
4
|
import { basename, dirname, join, relative } from "node:path";
|
|
5
5
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
6
6
|
import { x } from "tinyexec";
|
|
@@ -10,6 +10,8 @@ import JSZip from "jszip";
|
|
|
10
10
|
import Spinnies from "spinnies";
|
|
11
11
|
import { colors } from "consola/utils";
|
|
12
12
|
import { mkdirSync, writeFileSync } from "fs";
|
|
13
|
+
import { isValidRealtimeName, toRealtimeName } from "c8y-realtime";
|
|
14
|
+
import { createHash } from "node:crypto";
|
|
13
15
|
import { fileURLToPath } from "node:url";
|
|
14
16
|
import evlog from "evlog/nitro/v3";
|
|
15
17
|
//#region src/module/apiClient.ts
|
|
@@ -409,6 +411,24 @@ export const c8yTenantOptionKeys = [${settingKeys.map((key) => `'${key}'`).join(
|
|
|
409
411
|
//#endregion
|
|
410
412
|
//#region src/module/runtimeConfig.ts
|
|
411
413
|
/**
|
|
414
|
+
* Derive a stable, unique realtime client name from the microservice identity
|
|
415
|
+
* (its `contextPath`, falling back to `name`).
|
|
416
|
+
*
|
|
417
|
+
* The identity is sanitized to Cumulocity's alphanumeric name rule via
|
|
418
|
+
* `toRealtimeName`, then a short deterministic hash of the **raw** identity is
|
|
419
|
+
* appended. Sanitizing is lossy (`my-svc` and `my_svc` both become `mysvc`), so
|
|
420
|
+
* the hash restores the per-service uniqueness the `contextPath` guaranteed —
|
|
421
|
+
* without it, two different services could share one platform topic and clobber
|
|
422
|
+
* each other's subscriptions. Being deterministic, the name is identical across
|
|
423
|
+
* restarts and redeploys, so a reconnecting service resumes the same persistent
|
|
424
|
+
* subscription (and its backlog). This scheme is a permanent identity contract:
|
|
425
|
+
* changing it orphans existing subscriptions.
|
|
426
|
+
* @param identity - The microservice `contextPath` (or `name`)
|
|
427
|
+
*/
|
|
428
|
+
function deriveRealtimeName(identity) {
|
|
429
|
+
return `${toRealtimeName(identity)}${createHash("sha256").update(identity).digest("hex").slice(0, 8)}`;
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
412
432
|
* Sets up runtime configuration values from module options.
|
|
413
433
|
* These can be overridden by environment variables.
|
|
414
434
|
* @param nitro - The Nitro instance
|
|
@@ -421,6 +441,19 @@ async function setupRuntimeConfig(nitro, options) {
|
|
|
421
441
|
nitro.options.runtimeConfig.c8yTenantOptionsPerKeyTTL = options.cache?.tenantOptions ?? {};
|
|
422
442
|
const manifest = await createC8yManifest(nitro.options.rootDir, nitro.options, nitro.logger);
|
|
423
443
|
nitro.options.runtimeConfig.c8ySettingsCategory = options.manifest?.settingsCategory ?? manifest.contextPath ?? manifest.name;
|
|
444
|
+
const realtime = options.realtime ?? {};
|
|
445
|
+
const realtimeName = realtime.name ?? deriveRealtimeName(manifest.contextPath ?? manifest.name);
|
|
446
|
+
if (!isValidRealtimeName(realtimeName)) throw new Error(`c8y-nitro: invalid realtime name ${JSON.stringify(realtimeName)} — must be alphanumeric (^[a-zA-Z0-9]+\$). Set \`c8y.realtime.name\` to a valid value.`);
|
|
447
|
+
nitro.options.runtimeConfig.c8yRealtime = {
|
|
448
|
+
name: realtimeName,
|
|
449
|
+
autoAck: realtime.autoAck ?? true,
|
|
450
|
+
dedupe: realtime.dedupe ?? true,
|
|
451
|
+
autoStart: realtime.autoStart ?? true,
|
|
452
|
+
deleteSubscriptionOnEmpty: realtime.deleteSubscriptionOnEmpty ?? true,
|
|
453
|
+
deleteSubscriptionsOnClose: realtime.deleteSubscriptionsOnClose ?? false,
|
|
454
|
+
subscription: realtime.subscription,
|
|
455
|
+
resilience: realtime.resilience
|
|
456
|
+
};
|
|
424
457
|
const excludeInternalRoutes = options.openapi?.excludeInternalRoutes ?? true;
|
|
425
458
|
const probePaths = [options.manifest?.livenessProbe?.httpGet?.path, options.manifest?.readinessProbe?.httpGet?.path].filter((path) => Boolean(path));
|
|
426
459
|
nitro.options.runtimeConfig.c8yOpenApiExcludeRoutes = [...excludeInternalRoutes ? ["/_", ...probePaths] : [], ...options.openapi?.excludeRoutes ?? []];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as getTenantOptionsByCategory, f as upsertTenantOption, i as deleteTenantOption, n as createBasicAuthHeader, p as createC8yManifest, s as getCurrentApplicationSettings } from "./c8y-api-
|
|
2
|
-
import { n as readBootstrapCredentialsFromEnv, r as syncBootstrappedMicroservice } from "./autoBootstrap-
|
|
1
|
+
import { c as getTenantOptionsByCategory, f as upsertTenantOption, i as deleteTenantOption, n as createBasicAuthHeader, p as createC8yManifest, s as getCurrentApplicationSettings } from "./c8y-api-DpCWhaJU.mjs";
|
|
2
|
+
import { n as readBootstrapCredentialsFromEnv, r as syncBootstrappedMicroservice } from "./autoBootstrap-qCcCgset.mjs";
|
|
3
3
|
import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-BVQHqlgV.mjs";
|
|
4
4
|
import process from "node:process";
|
|
5
5
|
import { defineCommand } from "citty";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as createBasicAuthHeader, p as createC8yManifest, t as assignUserRole, u as unassignUserRole } from "./c8y-api-
|
|
1
|
+
import { n as createBasicAuthHeader, p as createC8yManifest, t as assignUserRole, u as unassignUserRole } from "./c8y-api-DpCWhaJU.mjs";
|
|
2
2
|
import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-BVQHqlgV.mjs";
|
|
3
3
|
import { defineCommand } from "citty";
|
|
4
4
|
import { consola } from "consola";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as createError } from "../../logging-BUYT8Z2V.mjs";
|
|
2
|
-
import { t as useDeployedTenantClient } from "../../client-
|
|
2
|
+
import { t as useDeployedTenantClient } from "../../client-DCov9jV6.mjs";
|
|
3
3
|
import { c8yTenantOptionKeys } from "c8y-nitro/runtime";
|
|
4
4
|
import { defineCachedFunction } from "nitro/cache";
|
|
5
5
|
import { useRuntimeConfig } from "nitro/runtime-config";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as tryGetUserTenantDomainFast } from "../../client-
|
|
1
|
+
import { r as tryGetUserTenantDomainFast } from "../../client-DCov9jV6.mjs";
|
|
2
2
|
import { c8yManifest } from "c8y-nitro/runtime";
|
|
3
3
|
import { useRuntimeConfig } from "nitro/runtime-config";
|
|
4
4
|
import { getRequestURL } from "nitro/h3";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as buildPublicRequestUrl, r as tryGetUserTenantDomainFast } from "../../client-
|
|
1
|
+
import { n as buildPublicRequestUrl, r as tryGetUserTenantDomainFast } from "../../client-DCov9jV6.mjs";
|
|
2
2
|
import { c8yManifest } from "c8y-nitro/runtime";
|
|
3
3
|
import { defineMiddleware } from "nitro";
|
|
4
4
|
//#region src/module/runtime/handlers/rewriteRequestUrl.ts
|
package/dist/types.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as C8YTenantOptionKey, c as C8yDockerOptions, d as C8YManifest, f as C8YManifestOptions, i as C8YSettingsCategory, l as C8yCacheOptions, n as C8yNitroModuleOptions, o as C8YTenantOptionKeysCacheConfig, p as
|
|
1
|
+
import { a as C8YTenantOptionKey, c as C8yDockerOptions, d as C8YManifest, f as C8YManifestOptions, g as C8YAPIClientOptions, h as C8YKnownRole, i as C8YSettingsCategory, l as C8yCacheOptions, m as C8YRoles, n as C8yNitroModuleOptions, o as C8YTenantOptionKeysCacheConfig, p as C8YRole, r as C8yOpenAPIOptions, s as C8yRealtimeOptions, t as C8yDevOptions, u as C8YZipOptions } from "./index-Dil1PcDr.mjs";
|
|
2
2
|
import { t as TenantCredentials } from "./credentials-eKnJ7m9Y.mjs";
|
|
3
|
-
export { C8YAPIClientOptions, type C8YManifest, type C8YManifestOptions, C8YRoles, C8YSettingsCategory, C8YTenantOptionKey, C8YTenantOptionKeysCacheConfig, type C8YZipOptions, type C8yCacheOptions, C8yDevOptions, type C8yDockerOptions, C8yNitroModuleOptions, C8yOpenAPIOptions, type TenantCredentials };
|
|
3
|
+
export { C8YAPIClientOptions, type C8YKnownRole, type C8YManifest, type C8YManifestOptions, C8YRole, C8YRoles, C8YSettingsCategory, C8YTenantOptionKey, C8YTenantOptionKeysCacheConfig, type C8YZipOptions, type C8yCacheOptions, C8yDevOptions, type C8yDockerOptions, C8yNitroModuleOptions, C8yOpenAPIOptions, type C8yRealtimeOptions, type TenantCredentials };
|