c8y-nitro 0.3.0 → 0.4.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/bootstrap-CGOe2HxK.mjs +61 -0
- package/dist/{cli/utils/c8y-api.mjs → c8y-api-BBSKRwKs.mjs} +73 -3
- package/dist/cli/index.mjs +5 -7
- package/dist/{cli/utils/config.mjs → config-Dqi-ttQi.mjs} +1 -3
- package/dist/{cli/utils/env-file.mjs → env-file-B0BK-uZW.mjs} +1 -3
- package/dist/{types/manifest.d.mts → index-B6HtYHU0.d.mts} +94 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +542 -11
- package/dist/{cli/commands/options.mjs → options-CuGdGP4l.mjs} +27 -30
- package/dist/{package.mjs → package-BAjMvZYS.mjs} +2 -3
- package/dist/{cli/commands/roles.mjs → roles-DrJsxUG-.mjs} +11 -14
- package/dist/runtime/handlers/liveness-readiness.d.mts +8 -0
- package/dist/runtime/handlers/liveness-readiness.mjs +7 -0
- package/dist/runtime/middlewares/dev-user.d.mts +6 -0
- package/dist/runtime/middlewares/dev-user.mjs +23 -0
- package/dist/runtime/plugins/c8y-variables.d.mts +6 -0
- package/dist/runtime/plugins/c8y-variables.mjs +17 -0
- package/dist/types.d.mts +2 -25
- package/dist/types.mjs +1 -1
- package/dist/utils.d.mts +292 -6
- package/dist/utils.mjs +444 -8
- package/package.json +10 -10
- package/dist/cli/commands/bootstrap.mjs +0 -64
- package/dist/module/apiClient.mjs +0 -207
- package/dist/module/autoBootstrap.mjs +0 -54
- package/dist/module/c8yzip.mjs +0 -66
- package/dist/module/constants.mjs +0 -6
- package/dist/module/docker.mjs +0 -101
- package/dist/module/manifest.mjs +0 -72
- package/dist/module/probeCheck.mjs +0 -30
- package/dist/module/register.mjs +0 -58
- package/dist/module/runtime/handlers/liveness-readiness.ts +0 -7
- package/dist/module/runtime/middlewares/dev-user.ts +0 -25
- package/dist/module/runtime/plugins/c8y-variables.ts +0 -24
- package/dist/module/runtime.mjs +0 -38
- package/dist/module/runtimeConfig.mjs +0 -20
- package/dist/types/apiClient.d.mts +0 -16
- package/dist/types/cache.d.mts +0 -28
- package/dist/types/roles.d.mts +0 -4
- package/dist/types/tenantOptions.d.mts +0 -13
- package/dist/types/zip.d.mts +0 -22
- package/dist/utils/client.d.mts +0 -52
- package/dist/utils/client.mjs +0 -90
- package/dist/utils/credentials.d.mts +0 -71
- package/dist/utils/credentials.mjs +0 -120
- package/dist/utils/internal/common.mjs +0 -26
- package/dist/utils/logging.d.mts +0 -3
- package/dist/utils/logging.mjs +0 -4
- package/dist/utils/middleware.d.mts +0 -89
- package/dist/utils/middleware.mjs +0 -62
- package/dist/utils/resources.d.mts +0 -30
- package/dist/utils/resources.mjs +0 -49
- package/dist/utils/tenantOptions.d.mts +0 -65
- package/dist/utils/tenantOptions.mjs +0 -127
|
@@ -0,0 +1,61 @@
|
|
|
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-BBSKRwKs.mjs";
|
|
2
|
+
import { t as writeBootstrapCredentials } from "./env-file-B0BK-uZW.mjs";
|
|
3
|
+
import { n as validateBootstrapEnv, t as loadC8yConfig } from "./config-Dqi-ttQi.mjs";
|
|
4
|
+
import { defineCommand, runCommand } from "citty";
|
|
5
|
+
import { consola as consola$1 } from "consola";
|
|
6
|
+
//#region src/cli/commands/bootstrap.ts
|
|
7
|
+
var bootstrap_default = defineCommand({
|
|
8
|
+
meta: {
|
|
9
|
+
name: "bootstrap",
|
|
10
|
+
description: "Bootstrap your microservice to the development tenant"
|
|
11
|
+
},
|
|
12
|
+
args: {},
|
|
13
|
+
async run() {
|
|
14
|
+
consola$1.info("Loading configuration...");
|
|
15
|
+
const { env, c8yOptions, configDir } = await loadC8yConfig();
|
|
16
|
+
consola$1.info("Validating environment variables...");
|
|
17
|
+
const envVars = validateBootstrapEnv(env);
|
|
18
|
+
consola$1.info("Building manifest...");
|
|
19
|
+
const manifest = await createC8yManifest(configDir, c8yOptions?.manifest);
|
|
20
|
+
consola$1.success(`Manifest created for: ${manifest.name} v${manifest.version}`);
|
|
21
|
+
const authHeader = createBasicAuthHeader(envVars.C8Y_DEVELOPMENT_TENANT, envVars.C8Y_DEVELOPMENT_USER, envVars.C8Y_DEVELOPMENT_PASSWORD);
|
|
22
|
+
consola$1.info(`Checking if microservice "${manifest.name}" exists...`);
|
|
23
|
+
const existingApp = await findMicroserviceByName(envVars.C8Y_BASEURL, manifest.name, authHeader);
|
|
24
|
+
let appId;
|
|
25
|
+
if (existingApp) {
|
|
26
|
+
consola$1.warn(`Microservice "${manifest.name}" already exists on development tenant (ID: ${existingApp.id})`);
|
|
27
|
+
if (!await consola$1.prompt("Do you want to update the existing microservice?", {
|
|
28
|
+
type: "confirm",
|
|
29
|
+
cancel: "reject"
|
|
30
|
+
})) {
|
|
31
|
+
consola$1.info("Bootstrap cancelled.");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
consola$1.info("Updating microservice...");
|
|
35
|
+
appId = (await updateMicroservice(envVars.C8Y_BASEURL, existingApp.id, manifest, authHeader)).id;
|
|
36
|
+
consola$1.success(`Microservice updated successfully (ID: ${appId})`);
|
|
37
|
+
} else {
|
|
38
|
+
consola$1.info("Creating microservice...");
|
|
39
|
+
appId = (await createMicroservice(envVars.C8Y_BASEURL, manifest, authHeader)).id;
|
|
40
|
+
consola$1.success(`Microservice created successfully (ID: ${appId})`);
|
|
41
|
+
}
|
|
42
|
+
consola$1.info("Subscribing tenant to application...");
|
|
43
|
+
await subscribeToApplication(envVars.C8Y_BASEURL, envVars.C8Y_DEVELOPMENT_TENANT, appId, authHeader);
|
|
44
|
+
consola$1.success("Tenant subscribed to application");
|
|
45
|
+
consola$1.info("Fetching bootstrap credentials...");
|
|
46
|
+
const credentials = await getBootstrapCredentials(envVars.C8Y_BASEURL, appId, authHeader);
|
|
47
|
+
consola$1.info("Writing bootstrap credentials...");
|
|
48
|
+
const envFileName = await writeBootstrapCredentials(configDir, {
|
|
49
|
+
C8Y_BOOTSTRAP_TENANT: credentials.tenant,
|
|
50
|
+
C8Y_BOOTSTRAP_USER: credentials.name,
|
|
51
|
+
C8Y_BOOTSTRAP_PASSWORD: credentials.password
|
|
52
|
+
});
|
|
53
|
+
consola$1.success(`Bootstrap credentials written to ${envFileName}`);
|
|
54
|
+
if (manifest.roles && manifest.roles.length > 0) {
|
|
55
|
+
if (await consola$1.prompt("Do you want to manage microservice roles for your development user?", { type: "confirm" })) await runCommand(await import("./roles-DrJsxUG-.mjs").then((r) => r.default), { rawArgs: [] });
|
|
56
|
+
}
|
|
57
|
+
consola$1.success("Bootstrap complete!");
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
//#endregion
|
|
61
|
+
export { bootstrap_default as default };
|
|
@@ -1,5 +1,76 @@
|
|
|
1
|
+
import { readPackage } from "pkg-types";
|
|
1
2
|
import { Buffer } from "node:buffer";
|
|
2
|
-
|
|
3
|
+
//#region src/module/constants.ts
|
|
4
|
+
const GENERATED_LIVENESS_ROUTE = "/_c8y_nitro/liveness";
|
|
5
|
+
const GENERATED_READINESS_ROUTE = "/_c8y_nitro/readiness";
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/module/manifest.ts
|
|
8
|
+
async function readPackageJsonFieldsForManifest(rootDir, logger) {
|
|
9
|
+
logger?.debug(`Reading package file from ${rootDir}`);
|
|
10
|
+
const pkg = await readPackage(rootDir);
|
|
11
|
+
const name = pkg.name?.replace(/^@[^/]+\//, "");
|
|
12
|
+
const version = pkg.version;
|
|
13
|
+
const author = pkg.author;
|
|
14
|
+
const authorName = typeof author === "string" ? author : author?.name;
|
|
15
|
+
const authorEmail = typeof author === "string" ? void 0 : author?.email;
|
|
16
|
+
const authorUrl = typeof author === "string" ? void 0 : author?.url;
|
|
17
|
+
if (!name || !version || !authorName) throw new Error("package.json must contain name, version, and author name fields");
|
|
18
|
+
const support = typeof pkg.bugs === "string" ? pkg.bugs : pkg.bugs?.url ?? pkg.bugs?.email;
|
|
19
|
+
const provider = {
|
|
20
|
+
name: authorName ?? name,
|
|
21
|
+
domain: authorUrl ?? pkg.homepage,
|
|
22
|
+
support: support ?? authorEmail
|
|
23
|
+
};
|
|
24
|
+
logger?.debug(`Found package.json fields for manifest: name=${name}, version=${version}, provider=${JSON.stringify(provider)}`);
|
|
25
|
+
return {
|
|
26
|
+
name,
|
|
27
|
+
version,
|
|
28
|
+
provider,
|
|
29
|
+
contextPath: name
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Creates a Cumulocity manifest from rootDir and options.
|
|
34
|
+
* Standalone function that can be used by CLI or module.
|
|
35
|
+
* @param rootDir - Directory containing package.json
|
|
36
|
+
* @param options - Manifest options
|
|
37
|
+
* @param logger - Optional logger for debug output
|
|
38
|
+
*/
|
|
39
|
+
async function createC8yManifest(rootDir, options = {}, logger) {
|
|
40
|
+
const { name, version, provider, ...restManifestFields } = await readPackageJsonFieldsForManifest(rootDir, logger);
|
|
41
|
+
const probeFields = {};
|
|
42
|
+
if (!options.livenessProbe?.httpGet) probeFields.livenessProbe = {
|
|
43
|
+
...options.livenessProbe,
|
|
44
|
+
httpGet: { path: GENERATED_LIVENESS_ROUTE }
|
|
45
|
+
};
|
|
46
|
+
if (!options.readinessProbe?.httpGet) probeFields.readinessProbe = {
|
|
47
|
+
...options.readinessProbe,
|
|
48
|
+
httpGet: { path: GENERATED_READINESS_ROUTE }
|
|
49
|
+
};
|
|
50
|
+
const key = `${name}-key`;
|
|
51
|
+
const manifest = {
|
|
52
|
+
...restManifestFields,
|
|
53
|
+
...probeFields,
|
|
54
|
+
...options,
|
|
55
|
+
provider,
|
|
56
|
+
name,
|
|
57
|
+
version,
|
|
58
|
+
apiVersion: "v2",
|
|
59
|
+
key,
|
|
60
|
+
type: "MICROSERVICE"
|
|
61
|
+
};
|
|
62
|
+
logger?.debug(`Created Cumulocity manifest: ${JSON.stringify(manifest, null, 2)}`);
|
|
63
|
+
return manifest;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Creates a Cumulocity manifest from a Nitro instance.
|
|
67
|
+
* Convenience wrapper for use in the Nitro module.
|
|
68
|
+
* @param nitro - The Nitro instance
|
|
69
|
+
*/
|
|
70
|
+
async function createC8yManifestFromNitro(nitro) {
|
|
71
|
+
return createC8yManifest(nitro.options.rootDir, nitro.options.c8y?.manifest, nitro.logger);
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
3
74
|
//#region src/cli/utils/c8y-api.ts
|
|
4
75
|
/**
|
|
5
76
|
* Creates a Basic Auth header for Cumulocity API requests.
|
|
@@ -257,6 +328,5 @@ async function deleteTenantOption(baseUrl, category, key, authHeader) {
|
|
|
257
328
|
throw new Error(`Failed to delete tenant option ${category}/${key}: ${response.status} ${response.statusText}\n${errorText}`, { cause: response });
|
|
258
329
|
}
|
|
259
330
|
}
|
|
260
|
-
|
|
261
331
|
//#endregion
|
|
262
|
-
export {
|
|
332
|
+
export { findMicroserviceByName as a, getTenantOptionsByCategory as c, updateMicroservice as d, updateTenantOption as f, GENERATED_READINESS_ROUTE as g, GENERATED_LIVENESS_ROUTE as h, deleteTenantOption as i, subscribeToApplication as l, createC8yManifestFromNitro as m, createBasicAuthHeader as n, getBootstrapCredentials as o, createC8yManifest as p, createMicroservice as r, getTenantOption as s, assignUserRole as t, unassignUserRole as u };
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as name, r as version, t as description } from "../package-BAjMvZYS.mjs";
|
|
2
2
|
import { defineCommand, runMain } from "citty";
|
|
3
|
-
|
|
4
3
|
//#region src/cli/index.ts
|
|
5
4
|
runMain(defineCommand({
|
|
6
5
|
meta: {
|
|
@@ -9,11 +8,10 @@ runMain(defineCommand({
|
|
|
9
8
|
description
|
|
10
9
|
},
|
|
11
10
|
subCommands: {
|
|
12
|
-
bootstrap: () => import("
|
|
13
|
-
roles: () => import("
|
|
14
|
-
options: () => import("
|
|
11
|
+
bootstrap: () => import("../bootstrap-CGOe2HxK.mjs").then((r) => r.default),
|
|
12
|
+
roles: () => import("../roles-DrJsxUG-.mjs").then((r) => r.default),
|
|
13
|
+
options: () => import("../options-CuGdGP4l.mjs").then((r) => r.default)
|
|
15
14
|
}
|
|
16
15
|
}));
|
|
17
|
-
|
|
18
16
|
//#endregion
|
|
19
|
-
export {
|
|
17
|
+
export {};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { dirname } from "pathe";
|
|
2
2
|
import { loadConfig, loadDotenv } from "c12";
|
|
3
3
|
import process from "process";
|
|
4
|
-
|
|
5
4
|
//#region src/cli/utils/config.ts
|
|
6
5
|
/**
|
|
7
6
|
* Loads c8y configuration from nitro.config and .env files.
|
|
@@ -52,6 +51,5 @@ function validateBootstrapEnv(env) {
|
|
|
52
51
|
C8Y_DEVELOPMENT_PASSWORD: env.C8Y_DEVELOPMENT_PASSWORD
|
|
53
52
|
};
|
|
54
53
|
}
|
|
55
|
-
|
|
56
54
|
//#endregion
|
|
57
|
-
export {
|
|
55
|
+
export { validateBootstrapEnv as n, loadC8yConfig as t };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { readFile, writeFile } from "node:fs/promises";
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
|
-
|
|
5
4
|
//#region src/cli/utils/env-file.ts
|
|
6
5
|
/**
|
|
7
6
|
* Writes or updates environment variables in a file.
|
|
@@ -56,6 +55,5 @@ async function writeBootstrapCredentials(configDir, variables) {
|
|
|
56
55
|
await writeEnvVariables(targetPath, variables);
|
|
57
56
|
return targetName;
|
|
58
57
|
}
|
|
59
|
-
|
|
60
58
|
//#endregion
|
|
61
|
-
export { writeBootstrapCredentials };
|
|
59
|
+
export { writeBootstrapCredentials as t };
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
import { C8YTenantOptionKeysCacheConfig } from "c8y-nitro/types";
|
|
2
|
+
|
|
3
|
+
//#region src/types/apiClient.d.ts
|
|
4
|
+
interface C8YAPIClientOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Relative directory from nitro configuration file to generate the API client into.
|
|
7
|
+
*/
|
|
8
|
+
dir: string;
|
|
9
|
+
/**
|
|
10
|
+
* Service context path for microservice endpoints.\
|
|
11
|
+
* Defaults to contextPath from manifest (package.json name, with scope stripped).\
|
|
12
|
+
* Override this if deploying with a different context path.
|
|
13
|
+
* @example "my-microservice" results in "https://<tenant>.com/service/my-microservice/..."
|
|
14
|
+
*/
|
|
15
|
+
contextPath?: string;
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
1
18
|
//#region src/types/manifest.d.ts
|
|
2
19
|
type C8YManifestOptions = Omit<C8YManifest, 'name' | 'version' | 'apiVersion' | 'key' | 'type' | 'provider'>;
|
|
3
20
|
interface C8YManifest {
|
|
@@ -312,4 +329,80 @@ interface Extension {
|
|
|
312
329
|
[key: string]: unknown;
|
|
313
330
|
}
|
|
314
331
|
//#endregion
|
|
315
|
-
|
|
332
|
+
//#region src/types/zip.d.ts
|
|
333
|
+
interface C8YZipOptions {
|
|
334
|
+
/**
|
|
335
|
+
* Name of the generated zip file
|
|
336
|
+
* @default '${packageName}-${version}.zip'
|
|
337
|
+
*/
|
|
338
|
+
name?: string | ((packageName: string, version: string) => string);
|
|
339
|
+
/**
|
|
340
|
+
* Output directory for the generated zip file.\
|
|
341
|
+
* Relative to the config file.
|
|
342
|
+
* @default './'
|
|
343
|
+
*/
|
|
344
|
+
outputDir?: string;
|
|
345
|
+
/**
|
|
346
|
+
* Configuration of the "cumulocity.json" manifest file used for the zip.
|
|
347
|
+
*/
|
|
348
|
+
manifest?: C8YManifestOptions;
|
|
349
|
+
}
|
|
350
|
+
//#endregion
|
|
351
|
+
//#region src/types/cache.d.ts
|
|
352
|
+
interface C8yCacheOptions {
|
|
353
|
+
/**
|
|
354
|
+
* Cache TTL for subscribed tenant credentials in seconds.
|
|
355
|
+
* @default 600 (10 minutes)
|
|
356
|
+
*/
|
|
357
|
+
credentialsTTL?: number;
|
|
358
|
+
/**
|
|
359
|
+
* Default cache TTL for tenant options in seconds.
|
|
360
|
+
* Applied to all keys unless overridden in `tenantOptions`.
|
|
361
|
+
* @default 600 (10 minutes)
|
|
362
|
+
*/
|
|
363
|
+
defaultTenantOptionsTTL?: number;
|
|
364
|
+
/**
|
|
365
|
+
* Per-key cache TTL overrides for tenant options in seconds.
|
|
366
|
+
* Keys should match those defined in `manifest.settings[].key`.
|
|
367
|
+
* @example
|
|
368
|
+
* {
|
|
369
|
+
* 'myOption': 300, // 5 minutes
|
|
370
|
+
* 'credentials.secret': 60, // 1 minute
|
|
371
|
+
* }
|
|
372
|
+
*/
|
|
373
|
+
tenantOptions?: C8YTenantOptionKeysCacheConfig;
|
|
374
|
+
}
|
|
375
|
+
//#endregion
|
|
376
|
+
//#region src/types/roles.d.ts
|
|
377
|
+
interface C8YRoles$1 {}
|
|
378
|
+
//#endregion
|
|
379
|
+
//#region src/types/tenantOptions.d.ts
|
|
380
|
+
/**
|
|
381
|
+
* Per-key cache TTL configuration for tenant options.
|
|
382
|
+
* Overwritten by generated types from manifest settings (manifest.settings[].key).
|
|
383
|
+
*/
|
|
384
|
+
type C8YTenantOptionKeysCacheConfig$1 = Partial<Record<C8YTenantOptionKey$1, number>>;
|
|
385
|
+
/**
|
|
386
|
+
* Type for tenant option keys.
|
|
387
|
+
* Overwritten by generated types from manifest settings (manifest.settings[].key).
|
|
388
|
+
*/
|
|
389
|
+
type C8YTenantOptionKey$1 = string;
|
|
390
|
+
//#endregion
|
|
391
|
+
//#region src/types/index.d.ts
|
|
392
|
+
interface C8yNitroModuleOptions {
|
|
393
|
+
manifest?: C8YManifestOptions;
|
|
394
|
+
apiClient?: C8YAPIClientOptions;
|
|
395
|
+
zip?: C8YZipOptions;
|
|
396
|
+
cache?: C8yCacheOptions;
|
|
397
|
+
/**
|
|
398
|
+
* Disable auto-bootstrap during development.
|
|
399
|
+
* When true, the module will not automatically register the microservice
|
|
400
|
+
* or retrieve bootstrap credentials on startup.
|
|
401
|
+
*
|
|
402
|
+
* Useful for CI/CD pipelines or manual bootstrap management.
|
|
403
|
+
* @default false
|
|
404
|
+
*/
|
|
405
|
+
skipBootstrap?: boolean;
|
|
406
|
+
}
|
|
407
|
+
//#endregion
|
|
408
|
+
export { C8yCacheOptions as a, C8YAPIClientOptions as c, C8YRoles$1 as i, C8YTenantOptionKey$1 as n, C8YZipOptions as o, C8YTenantOptionKeysCacheConfig$1 as r, C8YManifestOptions as s, C8yNitroModuleOptions as t };
|
package/dist/index.d.mts
CHANGED