c8y-nitro 0.10.4 → 0.11.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.
Files changed (41) hide show
  1. package/README.md +2 -0
  2. package/dist/{apiClient-kxv5KHYJ.mjs → apiClient-GMQqcgQe.mjs} +2 -3
  3. package/dist/{autoBootstrap-CElU3xv-.mjs → autoBootstrap-D4vEytWW.mjs} +6 -8
  4. package/dist/{bootstrap-hV_pJO5R.mjs → bootstrap-DpYAhM7C.mjs} +6 -7
  5. package/dist/cli/index.mjs +6 -7
  6. package/dist/{config-4Ju9safS.mjs → config-Dozrdw3A.mjs} +2 -3
  7. package/dist/{credentials-eKnJ7m9Y.d.mts → credentials-C_3m4LVX.d.mts} +0 -2
  8. package/dist/defaults-CrrCinRJ.mjs +20 -0
  9. package/dist/{env-CM-t7BwA.mjs → env-fUAhIWsI.mjs} +3 -5
  10. package/dist/{env-file-BrOTmVjA.mjs → env-file-DWbaFlIp.mjs} +1 -2
  11. package/dist/{index-BOaWGoaf.d.mts → index-CmIQfBpj.d.mts} +38 -22
  12. package/dist/index.d.mts +4 -6
  13. package/dist/index.mjs +16 -22
  14. package/dist/{logging-BUYT8Z2V.mjs → logging-B1PuWdiF.mjs} +1 -2
  15. package/dist/{manifest-DV3UW9Dl.mjs → manifest-BhrHDm8Y.mjs} +4 -6
  16. package/dist/{options-Bif4gAIp.mjs → options-CgTptIpI.mjs} +5 -6
  17. package/dist/{package-WtwC9ClY.mjs → package-y3p_br3i.mjs} +2 -3
  18. package/dist/{roles-D08LKKLI.mjs → roles-DEIHe2Xt.mjs} +4 -5
  19. package/dist/runtime/handlers/invalidateTenantOptions.mjs +2 -408
  20. package/dist/runtime/handlers/liveness-readiness.mjs +1 -2
  21. package/dist/runtime/handlers/openapi.mjs +4 -5
  22. package/dist/runtime/handlers/rewriteRequestUrl.mjs +3 -4
  23. package/dist/runtime/middlewares/c8y-client.mjs +3 -4
  24. package/dist/runtime/middlewares/dev-user.dev.mjs +2 -3
  25. package/dist/runtime/plugins/c8y-variables.dev.mjs +2 -3
  26. package/dist/runtime/plugins/enrich-logs.mjs +2 -3
  27. package/dist/scope-CxEPZ74p.mjs +2763 -0
  28. package/dist/{client-D8DbCxT6.mjs → tenant-0MBgBY_o.mjs} +114 -138
  29. package/dist/testing/setup.d.mts +1 -0
  30. package/dist/testing/setup.mjs +62 -0
  31. package/dist/testing/vite.d.mts +26 -0
  32. package/dist/testing/vite.mjs +58 -0
  33. package/dist/testing-D5VjeD-F.mjs +14 -0
  34. package/dist/testing.d.mts +521 -0
  35. package/dist/testing.mjs +494 -0
  36. package/dist/{typegen-BO_AkyNc.mjs → typegen-Bw4VxFmA.mjs} +4 -5
  37. package/dist/types-D663gk80.d.mts +140 -0
  38. package/dist/types.d.mts +3 -3
  39. package/dist/utils.d.mts +48 -66
  40. package/dist/utils.mjs +15 -26
  41. package/package.json +36 -19
package/README.md CHANGED
@@ -13,6 +13,7 @@ Nitro-powered tooling for building Cumulocity IoT microservices without manually
13
13
  - 🔥 **File-based Routing** - Auto-discovered routes from your file structure
14
14
  - 🛠️ **TypeScript First** - Full type safety with excellent DX
15
15
  - 🔄 **Auto-Bootstrap** - Automatically registers and configures your microservice in development
16
+ - 🧪 **Testing** - Test your service in Vitest against a fake Cumulocity tenant you seed with devices, measurements, alarms, and more
16
17
 
17
18
  ## Quickstart
18
19
 
@@ -28,6 +29,7 @@ Useful entry points:
28
29
  - [Configuration](https://schplitt.github.io/c8y-nitro/guide/configuration)
29
30
  - [Module Options](https://schplitt.github.io/c8y-nitro/reference/module-options)
30
31
  - [Utilities](https://schplitt.github.io/c8y-nitro/reference/utilities)
32
+ - [Testing](https://schplitt.github.io/c8y-nitro/guide/testing)
31
33
 
32
34
  ## Development
33
35
 
@@ -1,7 +1,7 @@
1
- import { n as createC8yManifestFromNitro } from "./manifest-DV3UW9Dl.mjs";
1
+ import { n as createC8yManifestFromNitro } from "./manifest-BhrHDm8Y.mjs";
2
2
  import { dirname, join, relative } from "node:path";
3
3
  import { mkdir, writeFile } from "node:fs/promises";
4
- //#region src/module/apiClient.ts
4
+ // src/module/apiClient.ts
5
5
  /**
6
6
  * Converts route path to PascalCase function name.
7
7
  * Examples:
@@ -202,5 +202,4 @@ async function writeAPIClient(nitro, options) {
202
202
  await writeFile(outputFile, code, "utf-8");
203
203
  nitro.logger.success(`Generated API client with ${routes.length} routes at: ${relative(rootDir, outputFile)}`);
204
204
  }
205
- //#endregion
206
205
  export { writeAPIClient as t };
@@ -1,11 +1,11 @@
1
- import { t as createC8yManifest } from "./manifest-DV3UW9Dl.mjs";
2
- import { h as updateMicroservice, l as findMicroserviceByName, o as createBasicAuthHeader, p as subscribeToApplication, s as createMicroservice, u as getBootstrapCredentials } from "./env-CM-t7BwA.mjs";
3
- import { t as writeBootstrapCredentials } from "./env-file-BrOTmVjA.mjs";
1
+ import { t as createC8yManifest } from "./manifest-BhrHDm8Y.mjs";
2
+ import { h as updateMicroservice, l as findMicroserviceByName, o as createBasicAuthHeader, p as subscribeToApplication, s as createMicroservice, u as getBootstrapCredentials } from "./env-fUAhIWsI.mjs";
3
+ import { t as writeBootstrapCredentials } from "./env-file-DWbaFlIp.mjs";
4
+ import process from "node:process";
4
5
  import { join } from "node:path";
5
6
  import { mkdir, readFile, writeFile } from "node:fs/promises";
6
7
  import { createHash } from "node:crypto";
7
- import process from "node:process";
8
- //#region src/module/manifestCache.ts
8
+ // src/module/manifestCache.ts
9
9
  /**
10
10
  * Directory (inside the project's `node_modules`) where c8y-nitro persists
11
11
  * local dev state such as the last-synced manifest hash. Lives in
@@ -64,8 +64,7 @@ async function writeManifestCache(rootDir, state) {
64
64
  };
65
65
  await writeFile(getCacheFile(rootDir), JSON.stringify(payload, null, 2), "utf-8");
66
66
  }
67
- //#endregion
68
- //#region src/module/autoBootstrap.ts
67
+ // src/module/autoBootstrap.ts
69
68
  const BOOTSTRAP_ENV_VARS = [
70
69
  "C8Y_BOOTSTRAP_TENANT",
71
70
  "C8Y_BOOTSTRAP_USER",
@@ -212,5 +211,4 @@ async function finalizeBootstrap(opts) {
212
211
  });
213
212
  return credentials;
214
213
  }
215
- //#endregion
216
214
  export { readBootstrapCredentialsFromEnv as n, syncBootstrappedMicroservice as r, autoBootstrap as t };
@@ -1,10 +1,10 @@
1
- import { t as createC8yManifest } from "./manifest-DV3UW9Dl.mjs";
2
- import { h as updateMicroservice, l as findMicroserviceByName, o as createBasicAuthHeader, p as subscribeToApplication, s as createMicroservice, u as getBootstrapCredentials } from "./env-CM-t7BwA.mjs";
3
- import { t as writeBootstrapCredentials } from "./env-file-BrOTmVjA.mjs";
4
- import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-4Ju9safS.mjs";
1
+ import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-Dozrdw3A.mjs";
2
+ import { h as updateMicroservice, l as findMicroserviceByName, o as createBasicAuthHeader, p as subscribeToApplication, s as createMicroservice, u as getBootstrapCredentials } from "./env-fUAhIWsI.mjs";
3
+ import { t as writeBootstrapCredentials } from "./env-file-DWbaFlIp.mjs";
4
+ import { t as createC8yManifest } from "./manifest-BhrHDm8Y.mjs";
5
5
  import { defineCommand, runCommand } from "citty";
6
6
  import { consola } from "consola";
7
- //#region src/cli/commands/bootstrap.ts
7
+ // src/cli/commands/bootstrap.ts
8
8
  var bootstrap_default = defineCommand({
9
9
  meta: {
10
10
  name: "bootstrap",
@@ -54,12 +54,11 @@ var bootstrap_default = defineCommand({
54
54
  consola.success(`Bootstrap credentials written to ${envFileName}`);
55
55
  if (manifest.roles && manifest.roles.length > 0) {
56
56
  if (await consola.prompt("Do you want to manage microservice roles for your development user?", { type: "confirm" })) {
57
- const rolesCommand = await import("./roles-D08LKKLI.mjs").then((r) => r.default);
57
+ const rolesCommand = await import("./roles-DEIHe2Xt.mjs").then((r) => r.default);
58
58
  await runCommand(rolesCommand, { rawArgs: [] });
59
59
  }
60
60
  }
61
61
  consola.success("Bootstrap complete!");
62
62
  }
63
63
  });
64
- //#endregion
65
64
  export { bootstrap_default as default };
@@ -1,6 +1,6 @@
1
- import { n as name, r as version, t as description } from "../package-WtwC9ClY.mjs";
1
+ import { n as name, r as version, t as description } from "../package-y3p_br3i.mjs";
2
2
  import { defineCommand, runMain } from "citty";
3
- //#region src/cli/index.ts
3
+ // src/cli/index.ts
4
4
  const main = defineCommand({
5
5
  meta: {
6
6
  name,
@@ -8,12 +8,11 @@ const main = defineCommand({
8
8
  description
9
9
  },
10
10
  subCommands: {
11
- bootstrap: () => import("../bootstrap-hV_pJO5R.mjs").then((r) => r.default),
12
- roles: () => import("../roles-D08LKKLI.mjs").then((r) => r.default),
13
- options: () => import("../options-Bif4gAIp.mjs").then((r) => r.default),
14
- typegen: () => import("../typegen-BO_AkyNc.mjs").then((r) => r.default)
11
+ bootstrap: () => import("../bootstrap-DpYAhM7C.mjs").then((r) => r.default),
12
+ roles: () => import("../roles-DEIHe2Xt.mjs").then((r) => r.default),
13
+ options: () => import("../options-CgTptIpI.mjs").then((r) => r.default),
14
+ typegen: () => import("../typegen-Bw4VxFmA.mjs").then((r) => r.default)
15
15
  }
16
16
  });
17
17
  runMain(main);
18
- //#endregion
19
18
  export {};
@@ -1,8 +1,8 @@
1
- import { i as toPrefixedEnvVar, n as resolveEnvFileNames, t as applyC8yNitroEnvVars } from "./env-CM-t7BwA.mjs";
1
+ import { i as toPrefixedEnvVar, n as resolveEnvFileNames, t as applyC8yNitroEnvVars } from "./env-fUAhIWsI.mjs";
2
2
  import { dirname } from "pathe";
3
3
  import { loadConfig, loadDotenv } from "c12";
4
4
  import process from "process";
5
- //#region src/cli/utils/config.ts
5
+ // src/cli/utils/config.ts
6
6
  function normalizeBaseUrl(baseUrl) {
7
7
  return baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
8
8
  }
@@ -58,5 +58,4 @@ function validateBootstrapEnv(env) {
58
58
  C8Y_DEVELOPMENT_PASSWORD: env.C8Y_DEVELOPMENT_PASSWORD
59
59
  };
60
60
  }
61
- //#endregion
62
61
  export { validateBootstrapEnv as n, loadC8yConfig as t };
@@ -1,5 +1,3 @@
1
1
  import { ICredentials } from "@c8y/client";
2
- //#region src/types/credentials.d.ts
3
2
  type TenantCredentials = Record<string, ICredentials>;
4
- //#endregion
5
3
  export { TenantCredentials as t };
@@ -0,0 +1,20 @@
1
+ // src/testing/defaults.ts
2
+ /**
3
+ * Values the fake tenant uses when the plugin config leaves them out.
4
+ */
5
+ const DEFAULTS = {
6
+ tenant: "t12345",
7
+ baseUrl: "https://t12345.cumulocity.test",
8
+ user: {
9
+ userName: "test-user",
10
+ roles: []
11
+ },
12
+ bootstrapUser: "servicebootstrap_test",
13
+ bootstrapPassword: "bootstrap-password",
14
+ developmentPassword: "test-password"
15
+ };
16
+ /**
17
+ * Key under which the plugin provides its options to the test workers.
18
+ */
19
+ const PROVIDE_KEY = "c8yNitroTest";
20
+ export { PROVIDE_KEY as n, DEFAULTS as t };
@@ -1,9 +1,9 @@
1
+ import process from "node:process";
1
2
  import { resolve } from "pathe";
2
3
  import { Buffer } from "node:buffer";
3
4
  import { statSync } from "node:fs";
4
- import process from "node:process";
5
5
  import { setupDotenv } from "c12";
6
- //#region src/cli/utils/c8y-api.ts
6
+ // src/cli/utils/c8y-api.ts
7
7
  /**
8
8
  * Creates a Basic Auth header for Cumulocity API requests.
9
9
  * Format: base64(tenant/user:password)
@@ -311,8 +311,7 @@ async function deleteTenantOption(baseUrl, category, key, authHeader) {
311
311
  throw new Error(`Failed to delete tenant option ${category}/${key}: ${response.status} ${response.statusText}\n${errorText}`, { cause: response });
312
312
  }
313
313
  }
314
- //#endregion
315
- //#region src/cli/utils/env.ts
314
+ // src/cli/utils/env.ts
316
315
  /**
317
316
  * The project's own env files. Always loaded last so they override any
318
317
  * additional (e.g. monorepo-root) env files configured via `c8y.envFile`.
@@ -382,5 +381,4 @@ async function setupC8yDevEnv(rootDir, envFile) {
382
381
  });
383
382
  applyC8yNitroEnvVars(process.env);
384
383
  }
385
- //#endregion
386
384
  export { assignUserRole as a, deleteTenantOption as c, getCurrentApplicationSettings as d, getTenantOptionsByCategory as f, upsertTenantOption as g, updateMicroservice as h, toPrefixedEnvVar as i, findMicroserviceByName as l, unassignUserRole as m, resolveEnvFileNames as n, createBasicAuthHeader as o, subscribeToApplication as p, setupC8yDevEnv as r, createMicroservice as s, applyC8yNitroEnvVars as t, getBootstrapCredentials as u };
@@ -1,7 +1,7 @@
1
1
  import { join } from "node:path";
2
2
  import { readFile, writeFile } from "node:fs/promises";
3
3
  import { existsSync } from "node:fs";
4
- //#region src/cli/utils/env-file.ts
4
+ // src/cli/utils/env-file.ts
5
5
  /**
6
6
  * Writes or updates environment variables in a file.
7
7
  * Existing variables are overwritten, new ones are appended.
@@ -55,5 +55,4 @@ async function writeBootstrapCredentials(configDir, variables) {
55
55
  await writeEnvVariables(targetPath, variables);
56
56
  return targetName;
57
57
  }
58
- //#endregion
59
58
  export { writeBootstrapCredentials as t };
@@ -1,7 +1,6 @@
1
- import "./credentials-eKnJ7m9Y.mjs";
1
+ import "./credentials-C_3m4LVX.mjs";
2
2
  import { ConsumerResilienceOptions, SubscriptionApi } from "c8y-realtime";
3
3
  import { C8YTenantOptionKeysCacheConfig } from "c8y-nitro/types";
4
- //#region src/types/apiClient.d.ts
5
4
  interface C8YAPIClientOptions {
6
5
  /**
7
6
  * Relative directory from nitro configuration file to generate the API client into.
@@ -15,8 +14,6 @@ interface C8YAPIClientOptions {
15
14
  */
16
15
  contextPath?: string;
17
16
  }
18
- //#endregion
19
- //#region src/types/roles.generated.d.ts
20
17
  /**
21
18
  * AUTO-GENERATED by scripts/generate-roles.ts — do not edit by hand.
22
19
  *
@@ -30,8 +27,6 @@ interface C8YAPIClientOptions {
30
27
  * Cumulocity platform roles ("required roles") known from the core OpenAPI spec.
31
28
  */
32
29
  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
30
  /**
36
31
  * Roles your microservice provides. Populated at runtime from the manifest's
37
32
  * `roles` field (see the module's generated `c8y-nitro.d.ts`).
@@ -43,8 +38,6 @@ interface C8YRoles$1 {}
43
38
  * other string (custom roles, or roles not yet in the generated list).
44
39
  */
45
40
  type C8YRole$1 = C8YKnownRole | (string & {});
46
- //#endregion
47
- //#region src/types/manifest.d.ts
48
41
  type C8YManifestOptions = Omit<C8YManifest, 'name' | 'version' | 'apiVersion' | 'key' | 'type' | 'provider' | 'openApiSpec'>;
49
42
  interface C8YManifest {
50
43
  /**
@@ -165,6 +158,42 @@ interface C8YManifest {
165
158
  * @example "/_openapi.json"
166
159
  */
167
160
  openApiSpec?: string;
161
+ /**
162
+ * MCP (Model Context Protocol) servers exposed by this microservice.
163
+ * Once the application is subscribed, Cumulocity AI Agent Manager
164
+ * auto-registers these entries, and MCP-aware clients (e.g., mc8yp)
165
+ * discover them from the manifest.
166
+ * @example [{ name: "my-service", url: "/service/my-service/mcp", type: "http", sendAuthentication: true }]
167
+ */
168
+ exposeMcpServers?: ExposedMcpServer[];
169
+ }
170
+ /**
171
+ * MCP server entry declared via `exposeMcpServers`.
172
+ */
173
+ interface ExposedMcpServer {
174
+ /**
175
+ * Name of the MCP server as shown in AI Agent Manager.
176
+ * @example "my-service"
177
+ */
178
+ name: string;
179
+ /**
180
+ * Human-readable description of what the MCP server offers.
181
+ */
182
+ description?: string;
183
+ /**
184
+ * URL of the MCP endpoint, usually the full service path including the context path.
185
+ * @example "/service/my-service/mcp"
186
+ */
187
+ url: string;
188
+ /**
189
+ * MCP transport type. Streamable HTTP (`"http"`) is the supported transport.
190
+ * @example "http"
191
+ */
192
+ type: 'http' | (string & {});
193
+ /**
194
+ * Forward the calling user's authentication to the MCP server.
195
+ */
196
+ sendAuthentication?: boolean;
168
197
  }
169
198
  /**
170
199
  * Company/organization information.
@@ -367,8 +396,6 @@ interface Extension {
367
396
  */
368
397
  [key: string]: unknown;
369
398
  }
370
- //#endregion
371
- //#region src/types/zip.d.ts
372
399
  interface C8YZipOptions {
373
400
  /**
374
401
  * Name of the generated zip file
@@ -392,8 +419,6 @@ interface C8YZipOptions {
392
419
  */
393
420
  manifest?: C8YManifestOptions;
394
421
  }
395
- //#endregion
396
- //#region src/types/cache.d.ts
397
422
  interface C8yCacheOptions {
398
423
  /**
399
424
  * Cache TTL for subscribed tenant credentials in seconds.
@@ -417,8 +442,6 @@ interface C8yCacheOptions {
417
442
  */
418
443
  tenantOptions?: C8YTenantOptionKeysCacheConfig;
419
444
  }
420
- //#endregion
421
- //#region src/types/docker.d.ts
422
445
  interface C8yDockerOptions {
423
446
  /**
424
447
  * Path to a custom Dockerfile, relative to the Nitro config file location
@@ -453,8 +476,6 @@ interface C8yDockerOptions {
453
476
  */
454
477
  extraInstructions?: string[];
455
478
  }
456
- //#endregion
457
- //#region src/types/realtime.d.ts
458
479
  /**
459
480
  * Options for the Notification 2.0 realtime clients (backed by `c8y-realtime`).
460
481
  *
@@ -526,8 +547,6 @@ interface C8yRealtimeOptions {
526
547
  */
527
548
  resilience?: ConsumerResilienceOptions;
528
549
  }
529
- //#endregion
530
- //#region src/types/tenantOptions.d.ts
531
550
  /**
532
551
  * Per-key cache TTL configuration for tenant options.
533
552
  * Overwritten by generated types from manifest settings (manifest.settings[].key).
@@ -544,8 +563,6 @@ type C8YTenantOptionKey$1 = string;
544
563
  * Overwritten by generated types from the manifest.
545
564
  */
546
565
  type C8YSettingsCategory$1 = string;
547
- //#endregion
548
- //#region src/types/index.d.ts
549
566
  interface C8yDevOptions {
550
567
  /**
551
568
  * Automatically inject the configured development user into incoming requests
@@ -633,5 +650,4 @@ interface C8yNitroModuleOptions {
633
650
  */
634
651
  skipBootstrap?: boolean;
635
652
  }
636
- //#endregion
637
- 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 };
653
+ export { C8YAPIClientOptions as _, C8YTenantOptionKey$1 as a, C8yDockerOptions as c, C8YManifest as d, C8YManifestOptions as f, C8YKnownRole as g, C8YRoles$1 as h, C8YSettingsCategory$1 as i, C8yCacheOptions as l, C8YRole$1 as m, C8yNitroModuleOptions as n, C8YTenantOptionKeysCacheConfig$1 as o, ExposedMcpServer as p, C8yOpenAPIOptions as r, C8yRealtimeOptions as s, C8yDevOptions as t, C8YZipOptions as u };
package/dist/index.d.mts CHANGED
@@ -1,7 +1,6 @@
1
- import { n as C8yNitroModuleOptions } from "./index-BOaWGoaf.mjs";
2
- import { t as TenantCredentials } from "./credentials-eKnJ7m9Y.mjs";
1
+ import { n as C8yNitroModuleOptions } from "./index-CmIQfBpj.mjs";
2
+ import { t as TenantCredentials } from "./credentials-C_3m4LVX.mjs";
3
3
  import { NitroModule } from "nitro/types";
4
- //#region src/index.d.ts
5
4
  declare module 'nitro/types' {
6
5
  interface NitroOptions {
7
6
  c8y?: C8yNitroModuleOptions;
@@ -12,6 +11,5 @@ declare module 'nitro/types' {
12
11
  'c8y:tenantCredentialsUpdated': (prev: TenantCredentials | null, next: TenantCredentials) => void;
13
12
  }
14
13
  }
15
- declare function c8y(): NitroModule;
16
- //#endregion
17
- export { c8y, c8y as default };
14
+ export declare function c8y(): NitroModule;
15
+ export { c8y as default };
package/dist/index.mjs CHANGED
@@ -1,8 +1,9 @@
1
- import { a as GENERATED_INVALIDATE_TENANT_OPTIONS_ROUTE, i as C8Y_NITRO_TYPES_FILE, n as createC8yManifestFromNitro, o as GENERATED_LIVENESS_ROUTE, r as C8Y_NITRO_TYPES_DIR, s as GENERATED_READINESS_ROUTE, t as createC8yManifest } from "./manifest-DV3UW9Dl.mjs";
2
- import { t as writeAPIClient } from "./apiClient-kxv5KHYJ.mjs";
3
- import { r as setupC8yDevEnv } from "./env-CM-t7BwA.mjs";
4
- import { t as autoBootstrap } from "./autoBootstrap-CElU3xv-.mjs";
5
- import { n as name } from "./package-WtwC9ClY.mjs";
1
+ import { t as writeAPIClient } from "./apiClient-GMQqcgQe.mjs";
2
+ import { a as GENERATED_INVALIDATE_TENANT_OPTIONS_ROUTE, i as C8Y_NITRO_TYPES_FILE, n as createC8yManifestFromNitro, o as GENERATED_LIVENESS_ROUTE, r as C8Y_NITRO_TYPES_DIR, s as GENERATED_READINESS_ROUTE, t as createC8yManifest } from "./manifest-BhrHDm8Y.mjs";
3
+ import { t as autoBootstrap } from "./autoBootstrap-D4vEytWW.mjs";
4
+ import { r as setupC8yDevEnv } from "./env-fUAhIWsI.mjs";
5
+ import { n as name } from "./package-y3p_br3i.mjs";
6
+ import process from "node:process";
6
7
  import { basename, join, resolve } from "node:path";
7
8
  import { copyFile, mkdir, writeFile } from "node:fs/promises";
8
9
  import { x } from "tinyexec";
@@ -16,7 +17,7 @@ import { isValidRealtimeName, toRealtimeName } from "c8y-realtime";
16
17
  import { createHash } from "node:crypto";
17
18
  import { fileURLToPath } from "node:url";
18
19
  import evlog from "evlog/nitro/v3";
19
- //#region src/module/docker.ts
20
+ // src/module/docker.ts
20
21
  /**
21
22
  * Generate the Dockerfile content for a Nitro build
22
23
  * @param outputDirName - Name of the output directory (e.g., '.output')
@@ -119,8 +120,7 @@ async function createDockerImage(nitro, options = {}) {
119
120
  nitro.logger.debug("Docker image creation complete.");
120
121
  return imageTarPath;
121
122
  }
122
- //#endregion
123
- //#region src/module/c8yzip.ts
123
+ // src/module/c8yzip.ts
124
124
  const spinnies = new Spinnies();
125
125
  function formatBytes(bytes) {
126
126
  if (bytes === 0) return "0 B";
@@ -179,8 +179,7 @@ async function createC8yZip(nitro, options = {}, dockerOptions = {}) {
179
179
  nitro.logger.log(colors.gray(` └─ ${outputFile} (${zipSize})`));
180
180
  nitro.logger.info("Zip file can be uploaded to Cumulocity IoT platform");
181
181
  }
182
- //#endregion
183
- //#region src/module/runtime.ts
182
+ // src/module/runtime.ts
184
183
  function setupRuntime(nitro, manifest) {
185
184
  nitro.logger.debug("Setting up C8Y nitro runtime");
186
185
  const roles = manifest.roles ?? [];
@@ -217,8 +216,7 @@ export const c8yTenantOptionKeys = [${settingKeys.map((key) => `'${key}'`).join(
217
216
  writeFileSync(typesFile, typesContent, { encoding: "utf-8" });
218
217
  nitro.logger.debug(`Written C8Y types to ${typesFile}`);
219
218
  }
220
- //#endregion
221
- //#region src/module/runtimeConfig.ts
219
+ // src/module/runtimeConfig.ts
222
220
  /**
223
221
  * Derive a stable, unique realtime client name from the microservice identity
224
222
  * (its `contextPath`, falling back to `name`).
@@ -267,8 +265,7 @@ async function setupRuntimeConfig(nitro, options) {
267
265
  const probePaths = [options.manifest?.livenessProbe?.httpGet?.path, options.manifest?.readinessProbe?.httpGet?.path].filter((path) => Boolean(path));
268
266
  nitro.options.runtimeConfig.c8yOpenApiExcludeRoutes = [...excludeInternalRoutes ? ["/_", ...probePaths] : [], ...options.openapi?.excludeRoutes ?? []];
269
267
  }
270
- //#endregion
271
- //#region src/module/registerRuntime.ts
268
+ // src/module/registerRuntime.ts
272
269
  /**
273
270
  * Links runtime middleware, handlers, and plugins to the nitro instance.
274
271
  * Works by having the handlers in a relative path to this file.
@@ -364,8 +361,7 @@ function registerRuntime(nitro, options = {}) {
364
361
  }
365
362
  nitro.options.handlers.push(...handlers);
366
363
  }
367
- //#endregion
368
- //#region src/module/probeCheck.ts
364
+ // src/module/probeCheck.ts
369
365
  function checkProbes(nitro, manifestOptions = {}) {
370
366
  if (manifestOptions.livenessProbe?.httpGet) {
371
367
  const probe = manifestOptions.livenessProbe.httpGet;
@@ -392,8 +388,7 @@ function checkProbeEndpoint(nitro, probe, probeType) {
392
388
  nitro.logger.warn(`${probeType} route "${path}" exists but does not accept ${method} requests. Available methods: ${availableMethods || "none specified"}. The probe will fail at runtime.`);
393
389
  }
394
390
  }
395
- //#endregion
396
- //#region src/index.ts
391
+ // src/index.ts
397
392
  function c8y() {
398
393
  return {
399
394
  name: "c8y-nitro",
@@ -427,22 +422,22 @@ function c8y() {
427
422
  await setupEvlog(nitro);
428
423
  if (nitro.options.preset === "nitro-dev") {
429
424
  await setupC8yDevEnv(nitro.options.rootDir, options.envFile);
430
- if (!options.skipBootstrap) await autoBootstrap(nitro);
425
+ if (!options.skipBootstrap && !process.env.VITEST) await autoBootstrap(nitro);
431
426
  }
432
427
  await setupRuntimeConfig(nitro, options);
433
428
  setupRuntime(nitro, manifest);
429
+ registerRuntime(nitro, options);
434
430
  nitro.hooks.hook("dev:reload", async () => {
435
431
  await setupC8yDevEnv(nitro.options.rootDir, options.envFile);
436
432
  manifest = await createC8yManifestFromNitro(nitro);
437
433
  setupRuntime(nitro, manifest);
438
- if (!options.skipBootstrap) await autoBootstrap(nitro);
434
+ if (!options.skipBootstrap && !process.env.VITEST) await autoBootstrap(nitro);
439
435
  if (options.apiClient) {
440
436
  nitro.logger.debug("Generating C8Y API client");
441
437
  await writeAPIClient(nitro, options);
442
438
  }
443
439
  });
444
440
  nitro.hooks.hook("build:before", async () => {
445
- registerRuntime(nitro, options);
446
441
  if (options.manifest) checkProbes(nitro, options.manifest);
447
442
  });
448
443
  nitro.hooks.hook("close", async () => {
@@ -451,5 +446,4 @@ function c8y() {
451
446
  }
452
447
  };
453
448
  }
454
- //#endregion
455
449
  export { c8y, c8y as default };
@@ -1,6 +1,6 @@
1
1
  import { createError } from "evlog";
2
2
  import "evlog/nitro/v3";
3
- //#region src/utils/logging.ts
3
+ // src/utils/logging.ts
4
4
  /**
5
5
  * Create a structured error for a Cumulocity microservice. Always prefer this
6
6
  * over Nitro/h3's built-in `createError`: the returned error is captured in the
@@ -53,5 +53,4 @@ import "evlog/nitro/v3";
53
53
  * @see https://www.evlog.dev
54
54
  */
55
55
  const createError$1 = createError;
56
- //#endregion
57
56
  export { createError$1 as t };
@@ -1,5 +1,5 @@
1
1
  import { readPackage } from "pkg-types";
2
- //#region src/module/constants.ts
2
+ // src/module/constants.ts
3
3
  const GENERATED_LIVENESS_ROUTE = "/_c8y_nitro/liveness";
4
4
  const GENERATED_READINESS_ROUTE = "/_c8y_nitro/readiness";
5
5
  const GENERATED_INVALIDATE_TENANT_OPTIONS_ROUTE = "/_c8y_nitro/invalidate-tenant-options";
@@ -13,8 +13,7 @@ const C8Y_NITRO_TYPES_DIR = "node_modules/.c8y-nitro";
13
13
  * File name of the generated declarations inside {@link C8Y_NITRO_TYPES_DIR}.
14
14
  */
15
15
  const C8Y_NITRO_TYPES_FILE = "types.d.ts";
16
- //#endregion
17
- //#region src/module/manifest.ts
16
+ // src/module/manifest.ts
18
17
  const DEFAULT_OPENAPI_ROUTE = "/_openapi.json";
19
18
  const ROLE_OPTION_MANAGEMENT_READ = "ROLE_OPTION_MANAGEMENT_READ";
20
19
  /**
@@ -85,7 +84,7 @@ async function readPackageJsonFieldsForManifest(rootDir, logger) {
85
84
  * Used by both the Nitro module and the CLI commands.
86
85
  * @param rootDir - Directory containing the project's `package.json`
87
86
  * @param nitroConfig - Nitro config (or options) for this project
88
- * @param logger - Optional logger for debug output
87
+ * @param logger - Optional Nitro logger (`nitro.logger`) for debug output
89
88
  */
90
89
  async function createC8yManifest(rootDir, nitroConfig = {}, logger) {
91
90
  const { options, openApiSpec } = extractManifestInputs(nitroConfig);
@@ -108,8 +107,8 @@ async function createC8yManifest(rootDir, nitroConfig = {}, logger) {
108
107
  }
109
108
  const manifest = {
110
109
  ...restManifestFields,
111
- ...probeFields,
112
110
  ...options,
111
+ ...probeFields,
113
112
  ...requiredRoles !== void 0 ? { requiredRoles } : {},
114
113
  ...openApiSpec ? { openApiSpec } : {},
115
114
  provider,
@@ -131,5 +130,4 @@ async function createC8yManifest(rootDir, nitroConfig = {}, logger) {
131
130
  async function createC8yManifestFromNitro(nitro) {
132
131
  return createC8yManifest(nitro.options.rootDir, nitro.options, nitro.logger);
133
132
  }
134
- //#endregion
135
133
  export { GENERATED_INVALIDATE_TENANT_OPTIONS_ROUTE as a, C8Y_NITRO_TYPES_FILE as i, createC8yManifestFromNitro as n, GENERATED_LIVENESS_ROUTE as o, C8Y_NITRO_TYPES_DIR as r, GENERATED_READINESS_ROUTE as s, createC8yManifest as t };
@@ -1,12 +1,12 @@
1
- import { t as createC8yManifest } from "./manifest-DV3UW9Dl.mjs";
2
- import { c as deleteTenantOption, d as getCurrentApplicationSettings, f as getTenantOptionsByCategory, g as upsertTenantOption, o as createBasicAuthHeader } from "./env-CM-t7BwA.mjs";
3
- import { n as readBootstrapCredentialsFromEnv, r as syncBootstrappedMicroservice } from "./autoBootstrap-CElU3xv-.mjs";
4
- import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-4Ju9safS.mjs";
1
+ import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-Dozrdw3A.mjs";
2
+ import { c as deleteTenantOption, d as getCurrentApplicationSettings, f as getTenantOptionsByCategory, g as upsertTenantOption, o as createBasicAuthHeader } from "./env-fUAhIWsI.mjs";
3
+ import { n as readBootstrapCredentialsFromEnv, r as syncBootstrappedMicroservice } from "./autoBootstrap-D4vEytWW.mjs";
4
+ import { t as createC8yManifest } from "./manifest-BhrHDm8Y.mjs";
5
5
  import process from "node:process";
6
6
  import { defineCommand } from "citty";
7
7
  import { consola } from "consola";
8
8
  import { createInterface } from "node:readline/promises";
9
- //#region src/cli/commands/options.ts
9
+ // src/cli/commands/options.ts
10
10
  var options_default = defineCommand({
11
11
  meta: {
12
12
  name: "options",
@@ -176,5 +176,4 @@ async function handleDelete(ctx) {
176
176
  }
177
177
  consola.success("Delete operation completed");
178
178
  }
179
- //#endregion
180
179
  export { options_default as default };
@@ -1,6 +1,5 @@
1
- //#region package.json
1
+ // package.json
2
2
  var name = "c8y-nitro";
3
- var version = "0.10.4";
3
+ var version = "0.11.0";
4
4
  var description = "Lightning fast Cumulocity IoT microservice development powered by Nitro";
5
- //#endregion
6
5
  export { name as n, version as r, description as t };
@@ -1,9 +1,9 @@
1
- import { t as createC8yManifest } from "./manifest-DV3UW9Dl.mjs";
2
- import { a as assignUserRole, m as unassignUserRole, o as createBasicAuthHeader } from "./env-CM-t7BwA.mjs";
3
- import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-4Ju9safS.mjs";
1
+ import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-Dozrdw3A.mjs";
2
+ import { a as assignUserRole, m as unassignUserRole, o as createBasicAuthHeader } from "./env-fUAhIWsI.mjs";
3
+ import { t as createC8yManifest } from "./manifest-BhrHDm8Y.mjs";
4
4
  import { defineCommand } from "citty";
5
5
  import { consola } from "consola";
6
- //#region src/cli/commands/roles.ts
6
+ // src/cli/commands/roles.ts
7
7
  var roles_default = defineCommand({
8
8
  meta: {
9
9
  name: "roles",
@@ -35,5 +35,4 @@ var roles_default = defineCommand({
35
35
  } else consola.warn("No roles defined in manifest. Nothing to manage.");
36
36
  }
37
37
  });
38
- //#endregion
39
38
  export { roles_default as default };