c8y-nitro 0.5.0 → 0.7.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.
@@ -1,4 +1,4 @@
1
- import { n as name, r as version, t as description } from "../package-bfMasPPg.mjs";
1
+ import { n as name, r as version, t as description } from "../package-BhFLRPOb.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-BSdVwFWO.mjs").then((r) => r.default),
12
- roles: () => import("../roles-CoBPqvDv.mjs").then((r) => r.default),
13
- options: () => import("../options-BkWL1FOa.mjs").then((r) => r.default)
11
+ bootstrap: () => import("../bootstrap-ObaEF7rN.mjs").then((r) => r.default),
12
+ roles: () => import("../roles-B58Fguop.mjs").then((r) => r.default),
13
+ options: () => import("../options-B7_yb_wr.mjs").then((r) => r.default)
14
14
  }
15
15
  }));
16
16
  //#endregion
@@ -0,0 +1,5 @@
1
+ import { ICredentials } from "@c8y/client";
2
+ //#region src/types/credentials.d.ts
3
+ type TenantCredentials = Record<string, ICredentials>;
4
+ //#endregion
5
+ export { TenantCredentials as t };
@@ -1,5 +1,5 @@
1
+ import "./credentials-eKnJ7m9Y.mjs";
1
2
  import { C8YTenantOptionKeysCacheConfig } from "c8y-nitro/types";
2
-
3
3
  //#region src/types/apiClient.d.ts
4
4
  interface C8YAPIClientOptions {
5
5
  /**
@@ -16,7 +16,7 @@ interface C8YAPIClientOptions {
16
16
  }
17
17
  //#endregion
18
18
  //#region src/types/manifest.d.ts
19
- type C8YManifestOptions = Omit<C8YManifest, 'name' | 'version' | 'apiVersion' | 'key' | 'type' | 'provider'>;
19
+ type C8YManifestOptions = Omit<C8YManifest, 'name' | 'version' | 'apiVersion' | 'key' | 'type' | 'provider' | 'openApiSpec'>;
20
20
  interface C8YManifest {
21
21
  /**
22
22
  * API version (e.g., "v2", "2"). Version 2 required for enhanced container security.
@@ -126,6 +126,16 @@ interface C8YManifest {
126
126
  * Platform extensions (e.g., UI plugins).
127
127
  */
128
128
  extensions?: Extension[];
129
+ /**
130
+ * OpenAPI specification path exposed by this microservice. Auto-populated
131
+ * by c8y-nitro when Nitro's `experimental.openAPI` is enabled and
132
+ * `openAPI.production` is configured. Used by clients (e.g., mc8yp) to
133
+ * auto-discover the API.
134
+ *
135
+ * Path is relative to the microservice context path.
136
+ * @example "/_openapi.json"
137
+ */
138
+ openApiSpec?: string;
129
139
  }
130
140
  /**
131
141
  * Company/organization information.
@@ -383,10 +393,16 @@ interface C8YRoles$1 {}
383
393
  */
384
394
  type C8YTenantOptionKeysCacheConfig$1 = Partial<Record<C8YTenantOptionKey$1, number>>;
385
395
  /**
386
- * Type for tenant option keys.
396
+ * Union of tenant option keys declared in `manifest.settings`.
387
397
  * Overwritten by generated types from manifest settings (manifest.settings[].key).
388
398
  */
389
399
  type C8YTenantOptionKey$1 = string;
400
+ /**
401
+ * The microservice's own tenant option settings category, resolved from
402
+ * `manifest.settingsCategory` (falling back to `contextPath`, then `name`).
403
+ * Overwritten by generated types from the manifest.
404
+ */
405
+ type C8YSettingsCategory$1 = string;
390
406
  //#endregion
391
407
  //#region src/types/index.d.ts
392
408
  interface C8yDevOptions {
@@ -411,7 +427,7 @@ interface C8yNitroModuleOptions {
411
427
  *
412
428
  * Query params:
413
429
  * - `all`: invalidate all created tenant option fetchers
414
- * - `key`: invalidate a single manifest-defined tenant option key if its fetcher exists
430
+ * - `key`: invalidate a single manifest-defined tenant option key if it exists
415
431
  *
416
432
  * `all` takes priority over `key`.
417
433
  * @default false
@@ -428,4 +444,4 @@ interface C8yNitroModuleOptions {
428
444
  skipBootstrap?: boolean;
429
445
  }
430
446
  //#endregion
431
- export { C8YRoles$1 as a, C8YManifest as c, C8YTenantOptionKeysCacheConfig$1 as i, C8YManifestOptions as l, C8yNitroModuleOptions as n, C8yCacheOptions as o, C8YTenantOptionKey$1 as r, C8YZipOptions as s, C8yDevOptions as t, C8YAPIClientOptions as u };
447
+ export { C8YTenantOptionKeysCacheConfig$1 as a, C8YZipOptions as c, C8YAPIClientOptions as d, C8YTenantOptionKey$1 as i, C8YManifest as l, C8yNitroModuleOptions as n, C8YRoles$1 as o, C8YSettingsCategory$1 as r, C8yCacheOptions as s, C8yDevOptions as t, C8YManifestOptions as u };
package/dist/index.d.mts CHANGED
@@ -1,12 +1,17 @@
1
- import { n as C8yNitroModuleOptions } from "./index-Bvu7DqDt.mjs";
1
+ import { n as C8yNitroModuleOptions } from "./index-ByDSMEvU.mjs";
2
+ import { t as TenantCredentials } from "./credentials-eKnJ7m9Y.mjs";
2
3
  import { NitroModule } from "nitro/types";
3
-
4
4
  //#region src/index.d.ts
5
5
  declare module 'nitro/types' {
6
6
  interface NitroOptions {
7
7
  c8y?: C8yNitroModuleOptions;
8
8
  }
9
9
  }
10
+ declare module 'nitro/types' {
11
+ interface NitroRuntimeHooks {
12
+ 'c8y:tenantCredentialsUpdated': (prev: TenantCredentials | null, next: TenantCredentials) => void;
13
+ }
14
+ }
10
15
  declare function c8y(): NitroModule;
11
16
  //#endregion
12
17
  export { c8y, c8y as default };
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import { _ as GENERATED_READINESS_ROUTE, a as findMicroserviceByName, g as GENERATED_LIVENESS_ROUTE, h as GENERATED_INVALIDATE_TENANT_OPTIONS_ROUTE, l as subscribeToApplication, m as createC8yManifestFromNitro, n as createBasicAuthHeader, o as getBootstrapCredentials, p as createC8yManifest, r as createMicroservice } from "./c8y-api-BgTNTqHd.mjs";
2
- import { t as writeBootstrapCredentials } from "./env-file-B0BK-uZW.mjs";
3
- import { n as name } from "./package-bfMasPPg.mjs";
1
+ import { _ as GENERATED_READINESS_ROUTE, a as findMicroserviceByName, d as updateMicroservice, g as GENERATED_LIVENESS_ROUTE, h as GENERATED_INVALIDATE_TENANT_OPTIONS_ROUTE, l as subscribeToApplication, m as createC8yManifestFromNitro, n as createBasicAuthHeader, o as getBootstrapCredentials, p as createC8yManifest, r as createMicroservice } from "./c8y-api-BFjK6AYb.mjs";
2
+ import { t as writeBootstrapCredentials } from "./env-file-BrOTmVjA.mjs";
3
+ import { n as name } from "./package-BhFLRPOb.mjs";
4
4
  import { basename, dirname, join, relative } from "node:path";
5
- import { mkdir, writeFile } from "node:fs/promises";
5
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
6
6
  import { x } from "tinyexec";
7
7
  import { join as join$1 } from "pathe";
8
8
  import { mkdir as mkdir$1, readFile as readFile$1, stat, writeFile as writeFile$1 } from "fs/promises";
@@ -11,6 +11,7 @@ import Spinnies from "spinnies";
11
11
  import { colors } from "consola/utils";
12
12
  import { mkdirSync, writeFileSync } from "fs";
13
13
  import { fileURLToPath } from "node:url";
14
+ import { createHash } from "node:crypto";
14
15
  import process from "node:process";
15
16
  import evlog from "evlog/nitro/v3";
16
17
  //#region src/module/apiClient.ts
@@ -113,6 +114,7 @@ type C8ySerialize<T> = T extends void | undefined | null ? undefined : T extends
113
114
  * @param className - The class name for the generated service (e.g., "PlaygroundAPIClient")
114
115
  */
115
116
  function generateAPIClient(routes, contextPath, className) {
117
+ const methods = routes.map((route) => generateMethod(route)).join("\n\n");
116
118
  return `/* eslint-disable eslint-comments/no-unlimited-disable */
117
119
  /* eslint-disable */
118
120
  /**
@@ -157,7 +159,7 @@ export class ${className} {
157
159
  return JSON.parse(text);
158
160
  }
159
161
 
160
- ${routes.map((route) => generateMethod(route)).join("\n\n")}
162
+ ${methods}
161
163
  }`;
162
164
  }
163
165
  /**
@@ -262,6 +264,8 @@ async function buildDockerImage(nitro, c8yDir) {
262
264
  try {
263
265
  const result = await x("docker", [
264
266
  "build",
267
+ "--platform",
268
+ "linux/amd64",
265
269
  "-t",
266
270
  imageName,
267
271
  "-f",
@@ -370,6 +374,7 @@ function setupRuntime(nitro, manifest) {
370
374
  nitro.logger.debug("Setting up C8Y nitro runtime");
371
375
  const roles = manifest.roles ?? [];
372
376
  const settingKeys = (manifest.settings ?? []).map((s) => s.key);
377
+ const settingsCategory = manifest.settingsCategory ?? manifest.contextPath ?? manifest.name;
373
378
  const completeTypesDir = join$1(nitro.options.rootDir, nitro.options.typescript.generatedTypesDir ?? "node_modules/.nitro/types");
374
379
  const typesFile = join$1(completeTypesDir, "c8y-nitro.d.ts");
375
380
  const typesContent = `// generated by c8y-nitro
@@ -379,6 +384,7 @@ ${roles.map((role) => ` '${role}': '${role}';`).join("\n")}
379
384
  }
380
385
  type C8YTenantOptionKey = ${settingKeys.length > 0 ? `${settingKeys.map((k) => `'${k}'`).join(" | ")}` : "never"}
381
386
  type C8YTenantOptionKeysCacheConfig = Partial<Record<C8YTenantOptionKey, number>>;
387
+ type C8YSettingsCategory = ${settingsCategory ? `'${settingsCategory}'` : "string"};
382
388
  }
383
389
 
384
390
  declare module 'c8y-nitro/runtime' {
@@ -413,7 +419,7 @@ async function setupRuntimeConfig(nitro, options) {
413
419
  nitro.options.runtimeConfig.c8yCredentialsCacheTTL = options.cache?.credentialsTTL ?? 600;
414
420
  nitro.options.runtimeConfig.c8yDefaultTenantOptionsTTL = options.cache?.defaultTenantOptionsTTL ?? 600;
415
421
  nitro.options.runtimeConfig.c8yTenantOptionsPerKeyTTL = options.cache?.tenantOptions ?? {};
416
- const manifest = await createC8yManifest(nitro.options.rootDir, options.manifest, nitro.logger);
422
+ const manifest = await createC8yManifest(nitro.options.rootDir, nitro.options, nitro.logger);
417
423
  nitro.options.runtimeConfig.c8ySettingsCategory = options.manifest?.settingsCategory ?? manifest.contextPath ?? manifest.name;
418
424
  }
419
425
  //#endregion
@@ -515,39 +521,156 @@ function checkProbeEndpoint(nitro, probe, probeType) {
515
521
  }
516
522
  }
517
523
  //#endregion
524
+ //#region src/module/manifestCache.ts
525
+ /**
526
+ * Directory (inside the project's `node_modules`) where c8y-nitro persists
527
+ * local dev state such as the last-synced manifest hash. Lives in
528
+ * `node_modules` so it is naturally gitignored and scoped per-checkout.
529
+ */
530
+ const CACHE_DIR_SEGMENTS = ["node_modules", ".c8y-nitro"];
531
+ const CACHE_FILE_NAME = "bootstrap-state.json";
532
+ const CACHE_SCHEMA_VERSION = 1;
533
+ function getCacheDir(rootDir) {
534
+ return join(rootDir, ...CACHE_DIR_SEGMENTS);
535
+ }
536
+ function getCacheFile(rootDir) {
537
+ return join(getCacheDir(rootDir), CACHE_FILE_NAME);
538
+ }
539
+ /**
540
+ * Compute a hash over the manifest and the deployment target it will be synced
541
+ * to. Folding the target in means switching tenant/baseURL invalidates the
542
+ * cached hash even if the manifest itself is unchanged.
543
+ *
544
+ * @param manifest - The generated Cumulocity manifest
545
+ * @param target - The deployment target identity
546
+ */
547
+ function hashManifest(manifest, target) {
548
+ const payload = JSON.stringify({
549
+ manifest,
550
+ target
551
+ });
552
+ return createHash("sha256").update(payload).digest("hex");
553
+ }
554
+ /**
555
+ * Read the persisted bootstrap state, or `null` when absent, unreadable, or
556
+ * from an incompatible schema version.
557
+ * @param rootDir - Project root directory (containing `node_modules`)
558
+ */
559
+ async function readManifestCache(rootDir) {
560
+ try {
561
+ const content = await readFile(getCacheFile(rootDir), "utf-8");
562
+ const state = JSON.parse(content);
563
+ if (state.schemaVersion !== CACHE_SCHEMA_VERSION) return null;
564
+ return state;
565
+ } catch {
566
+ return null;
567
+ }
568
+ }
569
+ /**
570
+ * Persist the bootstrap state for future dev restarts.
571
+ * @param rootDir - Project root directory (containing `node_modules`)
572
+ * @param state - The state to persist (schema version is filled in automatically)
573
+ */
574
+ async function writeManifestCache(rootDir, state) {
575
+ await mkdir(getCacheDir(rootDir), { recursive: true });
576
+ const payload = {
577
+ schemaVersion: CACHE_SCHEMA_VERSION,
578
+ ...state
579
+ };
580
+ await writeFile(getCacheFile(rootDir), JSON.stringify(payload, null, 2), "utf-8");
581
+ }
582
+ //#endregion
518
583
  //#region src/module/autoBootstrap.ts
584
+ const BOOTSTRAP_ENV_VARS = [
585
+ "C8Y_BOOTSTRAP_TENANT",
586
+ "C8Y_BOOTSTRAP_USER",
587
+ "C8Y_BOOTSTRAP_PASSWORD"
588
+ ];
589
+ const DEV_ENV_VARS = [
590
+ "C8Y_BASEURL",
591
+ "C8Y_DEVELOPMENT_TENANT",
592
+ "C8Y_DEVELOPMENT_USER",
593
+ "C8Y_DEVELOPMENT_PASSWORD"
594
+ ];
519
595
  /**
520
- * Automatically bootstraps the microservice to the development tenant if needed.
521
- * Runs silently - only logs if bootstrap was performed or if errors occur.
596
+ * Verifies the microservice on the development tenant and keeps it in sync with
597
+ * the local manifest, bootstrapping (or re-bootstrapping) when needed.
598
+ *
599
+ * Unlike a purely env-var-based check, this always verifies against the tenant
600
+ * when development credentials are available, so it also handles:
601
+ * - the manifest changing between dev restarts (auto-updates a placeholder), and
602
+ * - the application being deleted on the tenant while stale bootstrap env vars
603
+ * still linger locally (re-creates it).
604
+ *
605
+ * A previously *deployed* microservice (one with an active version) is never
606
+ * overwritten automatically - we only warn about the drift.
607
+ *
608
+ * Runs silently unless a bootstrap/sync was performed or an error occurs.
522
609
  * @param nitro - Nitro instance
523
610
  */
524
611
  async function autoBootstrap(nitro) {
525
612
  try {
526
- if ([
527
- "C8Y_BOOTSTRAP_TENANT",
528
- "C8Y_BOOTSTRAP_USER",
529
- "C8Y_BOOTSTRAP_PASSWORD"
530
- ].every((v) => process.env[v])) return;
531
- if ([
532
- "C8Y_BASEURL",
533
- "C8Y_DEVELOPMENT_TENANT",
534
- "C8Y_DEVELOPMENT_USER",
535
- "C8Y_DEVELOPMENT_PASSWORD"
536
- ].filter((v) => !process.env[v]).length > 0) return;
613
+ const rootDir = nitro.options.rootDir;
614
+ if (DEV_ENV_VARS.filter((v) => !process.env[v]).length > 0) return;
537
615
  const baseUrl = process.env.C8Y_BASEURL.endsWith("/") ? process.env.C8Y_BASEURL.slice(0, -1) : process.env.C8Y_BASEURL;
538
- const authHeader = createBasicAuthHeader(process.env.C8Y_DEVELOPMENT_TENANT, process.env.C8Y_DEVELOPMENT_USER, process.env.C8Y_DEVELOPMENT_PASSWORD);
539
- const manifest = await createC8yManifest(nitro.options.rootDir, nitro.options.c8y?.manifest, nitro.logger);
616
+ const developmentTenant = process.env.C8Y_DEVELOPMENT_TENANT;
617
+ const authHeader = createBasicAuthHeader(developmentTenant, process.env.C8Y_DEVELOPMENT_USER, process.env.C8Y_DEVELOPMENT_PASSWORD);
618
+ const manifest = await createC8yManifest(rootDir, nitro.options, nitro.logger);
619
+ const target = {
620
+ baseUrl,
621
+ developmentTenant,
622
+ name: manifest.name
623
+ };
624
+ const currentHash = hashManifest(manifest, target);
540
625
  const existingApp = await findMicroserviceByName(baseUrl, manifest.name, authHeader);
541
- let appId;
542
- if (existingApp) {
543
- appId = existingApp.id;
544
- nitro.logger.debug(`Microservice "${manifest.name}" already exists (ID: ${appId}), retrieving bootstrap credentials...`);
545
- } else {
546
- appId = (await createMicroservice(baseUrl, manifest, authHeader)).id;
547
- nitro.logger.debug(`Microservice "${manifest.name}" created (ID: ${appId})`);
626
+ if (!existingApp) {
627
+ const createdApp = await createMicroservice(baseUrl, manifest, authHeader);
628
+ nitro.logger.debug(`Microservice "${manifest.name}" created (ID: ${createdApp.id})`);
629
+ await finalizeBootstrap(nitro, {
630
+ baseUrl,
631
+ developmentTenant,
632
+ appId: createdApp.id,
633
+ authHeader,
634
+ target,
635
+ manifestHash: currentHash,
636
+ forceCredentials: true
637
+ });
638
+ nitro.logger.success(`Auto-bootstrap complete! Microservice "${manifest.name}" created on tenant.`);
639
+ return;
640
+ }
641
+ const appId = existingApp.id;
642
+ const isRealService = Boolean(existingApp.activeVersionId);
643
+ const cache = await readManifestCache(rootDir);
644
+ if (!cache || cache.manifestHash !== currentHash || cache.appId !== appId) if (isRealService) nitro.logger.warn(`Local manifest for "${manifest.name}" differs from the deployed microservice on the development tenant. The running service was left untouched. Redeploy or run \`npx c8y-nitro bootstrap\` to update it explicitly.`);
645
+ else {
646
+ await updateMicroservice(baseUrl, appId, manifest, authHeader);
647
+ nitro.logger.success(`Auto-bootstrap: updated microservice "${manifest.name}" with changed manifest.`);
548
648
  }
549
- await subscribeToApplication(baseUrl, process.env.C8Y_DEVELOPMENT_TENANT, appId, authHeader);
550
- const credentials = await getBootstrapCredentials(baseUrl, appId, authHeader);
649
+ const hasBootstrapCreds = BOOTSTRAP_ENV_VARS.every((v) => process.env[v]);
650
+ const appChanged = cache?.appId !== appId;
651
+ await finalizeBootstrap(nitro, {
652
+ baseUrl,
653
+ developmentTenant,
654
+ appId,
655
+ authHeader,
656
+ target,
657
+ manifestHash: currentHash,
658
+ forceCredentials: !hasBootstrapCreds || appChanged
659
+ });
660
+ } catch (error) {
661
+ nitro.logger.warn("Auto-bootstrap failed:", error instanceof Error ? error.message : String(error));
662
+ }
663
+ }
664
+ /**
665
+ * Subscribe the tenant, optionally (re)write bootstrap credentials, and persist
666
+ * the synced state to the local cache.
667
+ * @param nitro
668
+ * @param opts
669
+ */
670
+ async function finalizeBootstrap(nitro, opts) {
671
+ await subscribeToApplication(opts.baseUrl, opts.developmentTenant, opts.appId, opts.authHeader);
672
+ if (opts.forceCredentials) {
673
+ const credentials = await getBootstrapCredentials(opts.baseUrl, opts.appId, opts.authHeader);
551
674
  const envFileName = await writeBootstrapCredentials(nitro.options.rootDir, {
552
675
  C8Y_BOOTSTRAP_TENANT: credentials.tenant,
553
676
  C8Y_BOOTSTRAP_USER: credentials.name,
@@ -556,10 +679,13 @@ async function autoBootstrap(nitro) {
556
679
  process.env.C8Y_BOOTSTRAP_TENANT = credentials.tenant;
557
680
  process.env.C8Y_BOOTSTRAP_USER = credentials.name;
558
681
  process.env.C8Y_BOOTSTRAP_PASSWORD = credentials.password;
559
- nitro.logger.success(`Auto-bootstrap complete! Bootstrap credentials written to ${envFileName}`);
560
- } catch (error) {
561
- nitro.logger.warn("Auto-bootstrap failed:", error instanceof Error ? error.message : String(error));
682
+ nitro.logger.debug(`Bootstrap credentials written to ${envFileName}`);
562
683
  }
684
+ await writeManifestCache(nitro.options.rootDir, {
685
+ manifestHash: opts.manifestHash,
686
+ target: opts.target,
687
+ appId: opts.appId
688
+ });
563
689
  }
564
690
  //#endregion
565
691
  //#region src/index.ts
@@ -575,7 +701,8 @@ function c8y() {
575
701
  nitro.options.noExternals = nitro.options.noExternals === true ? true : [
576
702
  ...Array.isArray(nitro.options.noExternals) ? nitro.options.noExternals : [],
577
703
  name,
578
- "@c8y/client"
704
+ "@c8y/client",
705
+ "tslib"
579
706
  ];
580
707
  nitro.options.rolldownConfig = {
581
708
  ...nitro.options.rolldownConfig,
@@ -597,12 +724,13 @@ function c8y() {
597
724
  exclude: [manifest.livenessProbe?.httpGet?.path, manifest.readinessProbe?.httpGet?.path].filter(Boolean)
598
725
  });
599
726
  await setupEvlog(nitro);
600
- if (!options.skipBootstrap) await autoBootstrap(nitro);
727
+ if (nitro.options.preset === "nitro-dev" && !options.skipBootstrap) await autoBootstrap(nitro);
601
728
  await setupRuntimeConfig(nitro, options);
602
729
  setupRuntime(nitro, manifest);
603
730
  nitro.hooks.hook("dev:reload", async () => {
604
731
  manifest = await createC8yManifestFromNitro(nitro);
605
732
  setupRuntime(nitro, manifest);
733
+ if (!options.skipBootstrap) await autoBootstrap(nitro);
606
734
  if (options.apiClient) {
607
735
  nitro.logger.debug("Generating C8Y API client");
608
736
  await writeAPIClient(nitro, options);
@@ -1,5 +1,5 @@
1
- import { c as getTenantOptionsByCategory, f as upsertTenantOption, i as deleteTenantOption, n as createBasicAuthHeader, p as createC8yManifest, s as getTenantOption } from "./c8y-api-BgTNTqHd.mjs";
2
- import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-BRnvtthI.mjs";
1
+ import { c as getTenantOptionsByCategory, f as upsertTenantOption, i as deleteTenantOption, n as createBasicAuthHeader, p as createC8yManifest, s as getTenantOption } from "./c8y-api-BFjK6AYb.mjs";
2
+ import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-BVQHqlgV.mjs";
3
3
  import { defineCommand } from "citty";
4
4
  import { consola } from "consola";
5
5
  //#region src/cli/commands/options.ts
@@ -11,11 +11,11 @@ var options_default = defineCommand({
11
11
  args: {},
12
12
  async run() {
13
13
  consola.info("Loading configuration...");
14
- const { env, c8yOptions, configDir } = await loadC8yConfig();
14
+ const { env, nitroConfig, configDir } = await loadC8yConfig();
15
15
  consola.info("Validating environment variables...");
16
16
  const envVars = validateBootstrapEnv(env);
17
17
  consola.info("Loading manifest...");
18
- const manifest = await createC8yManifest(configDir, c8yOptions?.manifest);
18
+ const manifest = await createC8yManifest(configDir, nitroConfig);
19
19
  const category = manifest.settingsCategory || manifest.contextPath || manifest.name;
20
20
  if (!manifest.settings || manifest.settings.length === 0) throw new Error("No settings defined in manifest. Add settings to your c8y.manifest configuration.");
21
21
  consola.success(`Using category: ${category}`);
@@ -1,6 +1,6 @@
1
1
  //#region package.json
2
2
  var name = "c8y-nitro";
3
- var version = "0.5.0";
3
+ var version = "0.7.0";
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,5 +1,5 @@
1
- import { n as createBasicAuthHeader, p as createC8yManifest, t as assignUserRole, u as unassignUserRole } from "./c8y-api-BgTNTqHd.mjs";
2
- import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-BRnvtthI.mjs";
1
+ import { n as createBasicAuthHeader, p as createC8yManifest, t as assignUserRole, u as unassignUserRole } from "./c8y-api-BFjK6AYb.mjs";
2
+ import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-BVQHqlgV.mjs";
3
3
  import { defineCommand } from "citty";
4
4
  import { consola } from "consola";
5
5
  //#region src/cli/commands/roles.ts
@@ -11,11 +11,11 @@ var roles_default = defineCommand({
11
11
  args: {},
12
12
  async run() {
13
13
  consola.info("Loading configuration...");
14
- const { env, c8yOptions, configDir } = await loadC8yConfig();
14
+ const { env, nitroConfig, configDir } = await loadC8yConfig();
15
15
  consola.info("Validating environment variables...");
16
16
  const envVars = validateBootstrapEnv(env);
17
17
  consola.info("Building manifest...");
18
- const manifest = await createC8yManifest(configDir, c8yOptions?.manifest);
18
+ const manifest = await createC8yManifest(configDir, nitroConfig);
19
19
  const authHeader = createBasicAuthHeader(envVars.C8Y_DEVELOPMENT_TENANT, envVars.C8Y_DEVELOPMENT_USER, envVars.C8Y_DEVELOPMENT_PASSWORD);
20
20
  if (manifest.roles && manifest.roles.length > 0) {
21
21
  const rolesToAssign = await consola.prompt("Select roles to assign to your user (unselected roles will be removed):", {