c8y-nitro 0.10.3 → 0.10.4

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.
@@ -1,5 +1,5 @@
1
1
  import { t as createC8yManifest } from "./manifest-DV3UW9Dl.mjs";
2
- import { a as findMicroserviceByName, d as updateMicroservice, l as subscribeToApplication, n as createBasicAuthHeader, o as getBootstrapCredentials, r as createMicroservice } from "./c8y-api-DSs1xIIh.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
3
  import { t as writeBootstrapCredentials } from "./env-file-BrOTmVjA.mjs";
4
4
  import { join } from "node:path";
5
5
  import { mkdir, readFile, writeFile } from "node:fs/promises";
@@ -1,7 +1,7 @@
1
1
  import { t as createC8yManifest } from "./manifest-DV3UW9Dl.mjs";
2
- import { a as findMicroserviceByName, d as updateMicroservice, l as subscribeToApplication, n as createBasicAuthHeader, o as getBootstrapCredentials, r as createMicroservice } from "./c8y-api-DSs1xIIh.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
3
  import { t as writeBootstrapCredentials } from "./env-file-BrOTmVjA.mjs";
4
- import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-BVQHqlgV.mjs";
4
+ import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-4Ju9safS.mjs";
5
5
  import { defineCommand, runCommand } from "citty";
6
6
  import { consola } from "consola";
7
7
  //#region src/cli/commands/bootstrap.ts
@@ -54,7 +54,7 @@ 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-CNCObfa3.mjs").then((r) => r.default);
57
+ const rolesCommand = await import("./roles-D08LKKLI.mjs").then((r) => r.default);
58
58
  await runCommand(rolesCommand, { rawArgs: [] });
59
59
  }
60
60
  }
@@ -1,4 +1,4 @@
1
- import { n as name, r as version, t as description } from "../package-Dqlz6AoZ.mjs";
1
+ import { n as name, r as version, t as description } from "../package-WtwC9ClY.mjs";
2
2
  import { defineCommand, runMain } from "citty";
3
3
  //#region src/cli/index.ts
4
4
  const main = defineCommand({
@@ -8,9 +8,9 @@ const main = defineCommand({
8
8
  description
9
9
  },
10
10
  subCommands: {
11
- bootstrap: () => import("../bootstrap-DrMjty-k.mjs").then((r) => r.default),
12
- roles: () => import("../roles-CNCObfa3.mjs").then((r) => r.default),
13
- options: () => import("../options-54uJmuUV.mjs").then((r) => r.default),
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
14
  typegen: () => import("../typegen-BO_AkyNc.mjs").then((r) => r.default)
15
15
  }
16
16
  });
@@ -266,7 +266,7 @@ function useUserClient(requestOrEvent) {
266
266
  const auth = new MicroserviceClientRequestAuth(headers);
267
267
  const client = new Client(auth, process.env.C8Y_BASEURL);
268
268
  const forwardedHost = request.headers.get("x-forwarded-host")?.split(",")[0]?.trim();
269
- client.core.defaultHeaders["X-Forwarded-Host"] = forwardedHost || process.env.C8Y_BASEURL;
269
+ if (forwardedHost) client.core.defaultHeaders["X-Forwarded-Host"] = forwardedHost;
270
270
  request.context ??= {};
271
271
  request.context["c8y_user_client"] = client;
272
272
  return client;
@@ -1,3 +1,4 @@
1
+ import { i as toPrefixedEnvVar, n as resolveEnvFileNames, t as applyC8yNitroEnvVars } from "./env-CM-t7BwA.mjs";
1
2
  import { dirname } from "pathe";
2
3
  import { loadConfig, loadDotenv } from "c12";
3
4
  import process from "process";
@@ -11,20 +12,23 @@ function normalizeBaseUrl(baseUrl) {
11
12
  */
12
13
  async function loadC8yConfig() {
13
14
  const cwd = process.cwd();
14
- const env = await loadDotenv({
15
- cwd,
16
- fileName: [".env", ".env.local"]
17
- });
18
15
  const { config, _configFile } = await loadConfig({
19
16
  configFile: "nitro.config",
20
17
  cwd
21
18
  });
22
19
  if (!_configFile) throw new Error("No nitro.config file found. Please ensure you have a valid nitro.config file.");
23
20
  const configDir = dirname(_configFile);
21
+ const c8yOptions = config.c8y;
22
+ const env = await loadDotenv({
23
+ cwd: configDir,
24
+ fileName: resolveEnvFileNames(configDir, c8yOptions?.envFile),
25
+ interpolate: true
26
+ });
27
+ applyC8yNitroEnvVars(env);
24
28
  return {
25
29
  env,
26
30
  nitroConfig: config,
27
- c8yOptions: config.c8y,
31
+ c8yOptions,
28
32
  configDir,
29
33
  configFile: _configFile
30
34
  };
@@ -46,7 +50,7 @@ const REQUIRED_BOOTSTRAP_ENV_VARS = [
46
50
  */
47
51
  function validateBootstrapEnv(env) {
48
52
  const missing = REQUIRED_BOOTSTRAP_ENV_VARS.filter((key) => !env[key]);
49
- if (missing.length > 0) throw new Error(`Missing required environment variables:\n${missing.map((k) => ` - ${k}`).join("\n")}\n\nPlease set these in your .env or .env.local file.`);
53
+ if (missing.length > 0) throw new Error(`Missing required environment variables:\n${missing.map((k) => ` - ${k} (or ${toPrefixedEnvVar(k)})`).join("\n")}\n\nPlease set these in your .env or .env.local file (or a file configured via \`c8y.envFile\`).`);
50
54
  return {
51
55
  C8Y_BASEURL: normalizeBaseUrl(env.C8Y_BASEURL),
52
56
  C8Y_DEVELOPMENT_TENANT: env.C8Y_DEVELOPMENT_TENANT,
@@ -1,4 +1,8 @@
1
+ import { resolve } from "pathe";
1
2
  import { Buffer } from "node:buffer";
3
+ import { statSync } from "node:fs";
4
+ import process from "node:process";
5
+ import { setupDotenv } from "c12";
2
6
  //#region src/cli/utils/c8y-api.ts
3
7
  /**
4
8
  * Creates a Basic Auth header for Cumulocity API requests.
@@ -308,4 +312,75 @@ async function deleteTenantOption(baseUrl, category, key, authHeader) {
308
312
  }
309
313
  }
310
314
  //#endregion
311
- export { findMicroserviceByName as a, getTenantOptionsByCategory as c, updateMicroservice as d, upsertTenantOption as f, deleteTenantOption as i, subscribeToApplication as l, createBasicAuthHeader as n, getBootstrapCredentials as o, createMicroservice as r, getCurrentApplicationSettings as s, assignUserRole as t, unassignUserRole as u };
315
+ //#region src/cli/utils/env.ts
316
+ /**
317
+ * The project's own env files. Always loaded last so they override any
318
+ * additional (e.g. monorepo-root) env files configured via `c8y.envFile`.
319
+ */
320
+ const LOCAL_ENV_FILES = [".env", ".env.local"];
321
+ /**
322
+ * Env vars that also accept a `C8Y_NITRO_`-prefixed variant
323
+ * (e.g. `C8Y_NITRO_DEVELOPMENT_USER`). The prefixed variant takes precedence,
324
+ * so shared env files can carry c8y-nitro credentials without clashing with
325
+ * other tools that read the generic `C8Y_*` names.
326
+ */
327
+ const PREFIXABLE_ENV_VARS = [
328
+ "C8Y_BASEURL",
329
+ "C8Y_DEVELOPMENT_TENANT",
330
+ "C8Y_DEVELOPMENT_USER",
331
+ "C8Y_DEVELOPMENT_PASSWORD"
332
+ ];
333
+ /**
334
+ * Maps a `C8Y_*` variable name to its `C8Y_NITRO_*` variant.
335
+ * @param name - Unprefixed variable name (e.g. `C8Y_DEVELOPMENT_USER`)
336
+ */
337
+ function toPrefixedEnvVar(name) {
338
+ return name.replace(/^C8Y_/, "C8Y_NITRO_");
339
+ }
340
+ /**
341
+ * Builds the ordered list of env files to load. Later entries override earlier
342
+ * ones, so configured extra files (monorepo root) come first and the project's
343
+ * own `.env`/`.env.local` last.
344
+ *
345
+ * Extra entries may point at a file (`../../.env`) or a directory (`../..`,
346
+ * expanded to its `.env` and `.env.local`).
347
+ *
348
+ * @param cwd - Directory that relative entries are resolved against
349
+ * @param envFile - Extra env file(s) or directory(ies) from `c8y.envFile`
350
+ */
351
+ function resolveEnvFileNames(cwd, envFile) {
352
+ return [...(typeof envFile === "string" ? [envFile] : envFile ?? []).flatMap((entry) => {
353
+ const resolved = resolve(cwd, entry);
354
+ if (statSync(resolved, { throwIfNoEntry: false })?.isDirectory()) return LOCAL_ENV_FILES.map((fileName) => resolve(resolved, fileName));
355
+ return [resolved];
356
+ }), ...LOCAL_ENV_FILES];
357
+ }
358
+ /**
359
+ * Applies `C8Y_NITRO_*` variants onto their unprefixed `C8Y_*` counterparts
360
+ * (see {@link PREFIXABLE_ENV_VARS}). Mutates `env` in place; a set prefixed
361
+ * variant always wins over the unprefixed value.
362
+ * @param env - Environment variables object (e.g. `process.env` or a loaded `.env`)
363
+ */
364
+ function applyC8yNitroEnvVars(env) {
365
+ for (const name of PREFIXABLE_ENV_VARS) {
366
+ const prefixed = env[toPrefixedEnvVar(name)];
367
+ if (prefixed) env[name] = prefixed;
368
+ }
369
+ }
370
+ /**
371
+ * Loads the configured env files into `process.env` (existing real environment
372
+ * variables are never overridden) and resolves `C8Y_NITRO_*` variants.
373
+ * Used during Nitro dev mode, where only the project's own env files would be
374
+ * picked up otherwise.
375
+ * @param rootDir - Project root directory
376
+ * @param envFile - Extra env file(s)/directory(ies) from `c8y.envFile`
377
+ */
378
+ async function setupC8yDevEnv(rootDir, envFile) {
379
+ await setupDotenv({
380
+ cwd: rootDir,
381
+ fileName: resolveEnvFileNames(rootDir, envFile)
382
+ });
383
+ applyC8yNitroEnvVars(process.env);
384
+ }
385
+ //#endregion
386
+ 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 };
@@ -605,6 +605,24 @@ interface C8yNitroModuleOptions {
605
605
  * @default false
606
606
  */
607
607
  enableTenantOptionsInvalidationRoute?: boolean;
608
+ /**
609
+ * Additional `.env` file(s) to load during development and for CLI commands,
610
+ * for example a shared monorepo-root env file.
611
+ *
612
+ * Entries are resolved relative to the project root (absolute paths work too)
613
+ * and may point at a file (`'../../.env'`) or a directory (`'../..'`, which
614
+ * loads its `.env` and `.env.local`).
615
+ *
616
+ * Precedence (highest first): real environment variables, the project's own
617
+ * `.env.local` and `.env`, then the entries here (later entries override
618
+ * earlier ones). Bootstrap credentials are still written to the project's
619
+ * own env file, keeping them per-microservice in a monorepo.
620
+ *
621
+ * Only used in dev mode and by the CLI - deployed microservices get their
622
+ * environment from the platform.
623
+ * @default []
624
+ */
625
+ envFile?: string | string[];
608
626
  /**
609
627
  * Disable auto-bootstrap during development.
610
628
  * When true, the module will not automatically register the microservice
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as C8yNitroModuleOptions } from "./index-BEFoDy-y.mjs";
1
+ import { n as C8yNitroModuleOptions } from "./index-BOaWGoaf.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,7 +1,8 @@
1
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
2
  import { t as writeAPIClient } from "./apiClient-kxv5KHYJ.mjs";
3
- import { t as autoBootstrap } from "./autoBootstrap-DUjHuHe_.mjs";
4
- import { n as name } from "./package-Dqlz6AoZ.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";
5
6
  import { basename, join, resolve } from "node:path";
6
7
  import { copyFile, mkdir, writeFile } from "node:fs/promises";
7
8
  import { x } from "tinyexec";
@@ -424,10 +425,14 @@ function c8y() {
424
425
  exclude: [manifest.livenessProbe?.httpGet?.path, manifest.readinessProbe?.httpGet?.path].filter(Boolean)
425
426
  });
426
427
  await setupEvlog(nitro);
427
- if (nitro.options.preset === "nitro-dev" && !options.skipBootstrap) await autoBootstrap(nitro);
428
+ if (nitro.options.preset === "nitro-dev") {
429
+ await setupC8yDevEnv(nitro.options.rootDir, options.envFile);
430
+ if (!options.skipBootstrap) await autoBootstrap(nitro);
431
+ }
428
432
  await setupRuntimeConfig(nitro, options);
429
433
  setupRuntime(nitro, manifest);
430
434
  nitro.hooks.hook("dev:reload", async () => {
435
+ await setupC8yDevEnv(nitro.options.rootDir, options.envFile);
431
436
  manifest = await createC8yManifestFromNitro(nitro);
432
437
  setupRuntime(nitro, manifest);
433
438
  if (!options.skipBootstrap) await autoBootstrap(nitro);
@@ -1,7 +1,7 @@
1
1
  import { t as createC8yManifest } from "./manifest-DV3UW9Dl.mjs";
2
- import { c as getTenantOptionsByCategory, f as upsertTenantOption, i as deleteTenantOption, n as createBasicAuthHeader, s as getCurrentApplicationSettings } from "./c8y-api-DSs1xIIh.mjs";
3
- import { n as readBootstrapCredentialsFromEnv, r as syncBootstrappedMicroservice } from "./autoBootstrap-DUjHuHe_.mjs";
4
- import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-BVQHqlgV.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";
5
5
  import process from "node:process";
6
6
  import { defineCommand } from "citty";
7
7
  import { consola } from "consola";
@@ -1,6 +1,6 @@
1
1
  //#region package.json
2
2
  var name = "c8y-nitro";
3
- var version = "0.10.3";
3
+ var version = "0.10.4";
4
4
  var description = "Lightning fast Cumulocity IoT microservice development powered by Nitro";
5
5
  //#endregion
6
6
  export { name as n, version as r, description as t };
@@ -1,6 +1,6 @@
1
1
  import { t as createC8yManifest } from "./manifest-DV3UW9Dl.mjs";
2
- import { n as createBasicAuthHeader, t as assignUserRole, u as unassignUserRole } from "./c8y-api-DSs1xIIh.mjs";
3
- import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-BVQHqlgV.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";
4
4
  import { defineCommand } from "citty";
5
5
  import { consola } from "consola";
6
6
  //#region src/cli/commands/roles.ts
@@ -1,5 +1,5 @@
1
1
  import { t as createError } from "../../logging-BUYT8Z2V.mjs";
2
- import { t as useDeployedTenantClient } from "../../client-BmSKIcuq.mjs";
2
+ import { t as useDeployedTenantClient } from "../../client-D8DbCxT6.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-BmSKIcuq.mjs";
1
+ import { r as tryGetUserTenantDomainFast } from "../../client-D8DbCxT6.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-BmSKIcuq.mjs";
1
+ import { n as buildPublicRequestUrl, r as tryGetUserTenantDomainFast } from "../../client-D8DbCxT6.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, 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-BEFoDy-y.mjs";
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-BOaWGoaf.mjs";
2
2
  import { t as TenantCredentials } from "./credentials-eKnJ7m9Y.mjs";
3
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 };
package/dist/utils.mjs CHANGED
@@ -329,7 +329,7 @@ function useUserClient(requestOrEvent) {
329
329
  const auth = new MicroserviceClientRequestAuth(headers);
330
330
  const client = new Client(auth, process.env.C8Y_BASEURL);
331
331
  const forwardedHost = request.headers.get("x-forwarded-host")?.split(",")[0]?.trim();
332
- client.core.defaultHeaders["X-Forwarded-Host"] = forwardedHost || process.env.C8Y_BASEURL;
332
+ if (forwardedHost) client.core.defaultHeaders["X-Forwarded-Host"] = forwardedHost;
333
333
  request.context ??= {};
334
334
  request.context["c8y_user_client"] = client;
335
335
  return client;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c8y-nitro",
3
- "version": "0.10.3",
3
+ "version": "0.10.4",
4
4
  "type": "module",
5
5
  "description": "Lightning fast Cumulocity IoT microservice development powered by Nitro",
6
6
  "keywords": [