c8y-nitro 0.6.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.
- package/dist/{bootstrap-DUDpmXcU.mjs → bootstrap-ObaEF7rN.mjs} +6 -6
- package/dist/{c8y-api-BbRS1-Ls.mjs → c8y-api-BFjK6AYb.mjs} +36 -8
- package/dist/cli/index.mjs +4 -4
- package/dist/{credentials-9FO7rTIR.d.mts → credentials-eKnJ7m9Y.d.mts} +0 -1
- package/dist/{index-uOwpI6rD.d.mts → index-ByDSMEvU.d.mts} +20 -4
- package/dist/index.d.mts +2 -3
- package/dist/index.mjs +163 -35
- package/dist/{options-Web5UyIU.mjs → options-B7_yb_wr.mjs} +4 -4
- package/dist/{package-DsLC9Mo3.mjs → package-BhFLRPOb.mjs} +1 -1
- package/dist/{roles-D7rpbxPp.mjs → roles-B58Fguop.mjs} +4 -4
- package/dist/runtime/handlers/invalidateTenantOptions.mjs +616 -5
- package/dist/runtime/middlewares/c8y-client.mjs +2 -2
- package/dist/runtime/middlewares/dev-user.dev.mjs +2 -2
- package/dist/runtime/plugins/c8y-variables.dev.mjs +1 -1
- package/dist/types.d.mts +3 -3
- package/dist/utils.d.mts +201 -40
- package/dist/utils.mjs +380 -109
- package/package.json +11 -9
- /package/dist/{config-BRnvtthI.mjs → config-BVQHqlgV.mjs} +0 -0
- /package/dist/{env-file-B0BK-uZW.mjs → env-file-BrOTmVjA.mjs} +0 -0
- /package/dist/{logging-CVlaRS4O.mjs → logging-DYnYICoX.mjs} +0 -0
package/dist/utils.d.mts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { t as TenantCredentials } from "./credentials-
|
|
1
|
+
import { t as TenantCredentials } from "./credentials-eKnJ7m9Y.mjs";
|
|
2
2
|
import { useLogger } from "evlog/nitro/v3";
|
|
3
3
|
import { Client, ICredentials, ICurrentUser } from "@c8y/client";
|
|
4
|
-
import { EventHandler, H3Event } from "nitro/h3";
|
|
5
4
|
import { createError, createLogger } from "evlog";
|
|
5
|
+
import { EventHandler, H3Event } from "nitro/h3";
|
|
6
6
|
import { ServerRequest, TaskContext, TaskPayload } from "nitro/types";
|
|
7
|
-
import { C8YRoles, C8YTenantOptionKey } from "c8y-nitro/types";
|
|
8
|
-
|
|
7
|
+
import { C8YRoles, C8YSettingsCategory, C8YTenantOptionKey } from "c8y-nitro/types";
|
|
9
8
|
//#region src/utils/client.d.ts
|
|
10
9
|
/**
|
|
11
10
|
* Creates a Cumulocity client authenticated with the current user's credentials.\
|
|
@@ -173,7 +172,7 @@ declare const useSubscribedTenantCredentials: (() => Promise<TenantCredentials>)
|
|
|
173
172
|
* Uses the C8Y_BOOTSTRAP_TENANT environment variable to identify the deployed tenant.\
|
|
174
173
|
* Returns credentials from the subscribed tenant credentials cache (cached based on configured TTL, default: 10 minutes).
|
|
175
174
|
* @returns Credentials for the deployed tenant
|
|
176
|
-
* @throws {
|
|
175
|
+
* @throws {EvlogError} If no credentials found for the deployed tenant
|
|
177
176
|
* @example
|
|
178
177
|
* // Get deployed tenant credentials:
|
|
179
178
|
* const creds = await useDeployedTenantCredentials()
|
|
@@ -196,7 +195,7 @@ declare const useDeployedTenantCredentials: (() => Promise<ICredentials>) & {
|
|
|
196
195
|
* Results are cached in the request context for subsequent calls within the same request.
|
|
197
196
|
* @param requestOrEvent - The H3Event or ServerRequest from the current request
|
|
198
197
|
* @returns Credentials for the user's tenant
|
|
199
|
-
* @throws {
|
|
198
|
+
* @throws {EvlogError} If no subscribed tenant credentials found for the user's tenant
|
|
200
199
|
* @example
|
|
201
200
|
* // In a request handler:
|
|
202
201
|
* const userCreds = await useUserTenantCredentials(event)
|
|
@@ -209,12 +208,148 @@ declare function useUserTenantCredentials(requestOrEvent: ServerRequest | H3Even
|
|
|
209
208
|
//#endregion
|
|
210
209
|
//#region src/utils/tenantOptions.d.ts
|
|
211
210
|
/**
|
|
212
|
-
*
|
|
213
|
-
* Uses the deployed tenant's service user credentials to access the Options API.\
|
|
214
|
-
* Results are cached based on the configured TTL (default: 10 minutes).
|
|
211
|
+
* A tenant option key for the microservice's own settings category.
|
|
215
212
|
*
|
|
216
|
-
*
|
|
217
|
-
* @
|
|
213
|
+
* Manifest-declared keys are offered via autocomplete (from the generated
|
|
214
|
+
* {@link C8YTenantOptionKey} union) while any other string is still accepted, so
|
|
215
|
+
* runtime-computed keys such as `encrypted.password.${hash}` work too.
|
|
216
|
+
*/
|
|
217
|
+
type TenantOptionKeyInput = C8YTenantOptionKey | (string & {});
|
|
218
|
+
/**
|
|
219
|
+
* Guards a key used against a *foreign* settings category.
|
|
220
|
+
*
|
|
221
|
+
* `credentials.*` options are stored encrypted and can only be decrypted within
|
|
222
|
+
* the owning microservice's category, so they can never be read from a different
|
|
223
|
+
* category. Such keys collapse to `never`, turning the misuse into a compile error.
|
|
224
|
+
*/
|
|
225
|
+
type ForeignTenantOptionKeyInput<K extends string> = K & (K extends `credentials.${string}` ? never : unknown);
|
|
226
|
+
/**
|
|
227
|
+
* Options for {@link TenantOption.setEditable}.
|
|
228
|
+
*/
|
|
229
|
+
interface SetEditableOptions {
|
|
230
|
+
/**
|
|
231
|
+
* The tenant whose option `editable` flag is updated.
|
|
232
|
+
*
|
|
233
|
+
* Required by Cumulocity: the editable-flag endpoint is only permitted from
|
|
234
|
+
* the management tenant, and the target tenant must be given explicitly.
|
|
235
|
+
*/
|
|
236
|
+
targetTenant: string;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Handle for a single tenant option (a `category` + `key` pair).
|
|
240
|
+
*
|
|
241
|
+
* Obtained via {@link useTenantOption} (own category) or
|
|
242
|
+
* `useTenantOptions(category).option(key)`.
|
|
243
|
+
*/
|
|
244
|
+
interface TenantOption {
|
|
245
|
+
/**
|
|
246
|
+
* Read the current value. Returns `undefined` when the option is not set
|
|
247
|
+
* (Cumulocity responds `404`). The value is cached per the configured TTL.
|
|
248
|
+
*/
|
|
249
|
+
read: () => Promise<string | undefined>;
|
|
250
|
+
/**
|
|
251
|
+
* Create or update the option value (upsert), then invalidate the cached read.
|
|
252
|
+
*/
|
|
253
|
+
set: (value: string) => Promise<void>;
|
|
254
|
+
/**
|
|
255
|
+
* Read the value; if it is not set, write `fallback` and return it.
|
|
256
|
+
*/
|
|
257
|
+
getOrInsert: (fallback: string) => Promise<string>;
|
|
258
|
+
/**
|
|
259
|
+
* Delete the option. Idempotent — a missing option resolves without error.
|
|
260
|
+
* Invalidates the cached read afterwards.
|
|
261
|
+
*/
|
|
262
|
+
delete: () => Promise<void>;
|
|
263
|
+
/**
|
|
264
|
+
* Update the option's `editable` flag.
|
|
265
|
+
*
|
|
266
|
+
* @remarks Cumulocity only allows this from the **management tenant** (role
|
|
267
|
+
* `ROLE_OPTION_MANAGEMENT_ADMIN`). It will fail with `403` when called from a
|
|
268
|
+
* regular subscribed-tenant microservice.
|
|
269
|
+
*/
|
|
270
|
+
setEditable: (editable: boolean, options: SetEditableOptions) => Promise<void>;
|
|
271
|
+
/**
|
|
272
|
+
* Invalidate the cached value, then re-read it.
|
|
273
|
+
*/
|
|
274
|
+
refresh: () => Promise<string | undefined>;
|
|
275
|
+
/**
|
|
276
|
+
* Invalidate the cached value (no-op if it was never read).
|
|
277
|
+
*/
|
|
278
|
+
invalidate: () => Promise<void>;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Handle for all options within the microservice's own settings category.
|
|
282
|
+
*/
|
|
283
|
+
interface TenantOptionCategory {
|
|
284
|
+
/**
|
|
285
|
+
* Get a handle for a single option in this category.
|
|
286
|
+
*/
|
|
287
|
+
option: (key: TenantOptionKeyInput) => TenantOption;
|
|
288
|
+
/**
|
|
289
|
+
* List all options set in this category as a key/value map.
|
|
290
|
+
*/
|
|
291
|
+
list: () => Promise<Record<string, string>>;
|
|
292
|
+
/**
|
|
293
|
+
* Create or update multiple options in this category, then invalidate their caches.
|
|
294
|
+
*/
|
|
295
|
+
setAll: (values: Record<string, string>) => Promise<void>;
|
|
296
|
+
/**
|
|
297
|
+
* Invalidate every already-read option cache in this category.
|
|
298
|
+
*/
|
|
299
|
+
invalidateAll: () => Promise<void>;
|
|
300
|
+
/**
|
|
301
|
+
* Refresh every already-read option cache in this category.
|
|
302
|
+
* @returns A map of the refreshed keys to their new values.
|
|
303
|
+
*/
|
|
304
|
+
refreshAll: () => Promise<Record<string, string | undefined>>;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Handle for a *foreign* settings category (one other than the microservice's own).
|
|
308
|
+
*
|
|
309
|
+
* Identical to {@link TenantOptionCategory} except that:
|
|
310
|
+
* - `credentials.*` keys are rejected — see {@link ForeignTenantOptionKeyInput};
|
|
311
|
+
* - the optional type parameter `K` sets the known key set for autocomplete
|
|
312
|
+
* (`useTenantOptions<'a' | 'b'>(client, 'other')`). It defaults to `string`,
|
|
313
|
+
* which accepts any key (still minus `credentials.*`).
|
|
314
|
+
*/
|
|
315
|
+
interface ForeignTenantOptionCategory<K extends string = string> {
|
|
316
|
+
/**
|
|
317
|
+
* Get a handle for a single non-`credentials.*` option in this category.
|
|
318
|
+
* Completes to `K` when a key set was provided.
|
|
319
|
+
*/
|
|
320
|
+
option: <Key extends K>(key: ForeignTenantOptionKeyInput<Key>) => TenantOption;
|
|
321
|
+
/**
|
|
322
|
+
* List all options set in this category as a key/value map.
|
|
323
|
+
*/
|
|
324
|
+
list: () => Promise<Record<string, string>>;
|
|
325
|
+
/**
|
|
326
|
+
* Create or update multiple options in this category, then invalidate their caches.
|
|
327
|
+
*/
|
|
328
|
+
setAll: (values: Record<string, string>) => Promise<void>;
|
|
329
|
+
/**
|
|
330
|
+
* Invalidate every already-read option cache in this category.
|
|
331
|
+
*/
|
|
332
|
+
invalidateAll: () => Promise<void>;
|
|
333
|
+
/**
|
|
334
|
+
* Refresh every already-read option cache in this category.
|
|
335
|
+
* @returns A map of the refreshed keys to their new values.
|
|
336
|
+
*/
|
|
337
|
+
refreshAll: () => Promise<Record<string, string | undefined>>;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Gets a handle for a single tenant option in the microservice's **own** settings
|
|
341
|
+
* category, targeting the tenant of the given `client`.\
|
|
342
|
+
* Reads are cached per tenant, using the client's service user credentials.
|
|
343
|
+
*
|
|
344
|
+
* This is a shortcut for `useTenantOptions(client).option(key)` — it only drops
|
|
345
|
+
* the category argument. For a single option in a **foreign** category, use
|
|
346
|
+
* `useTenantOptions(client, category).option(key)`.
|
|
347
|
+
*
|
|
348
|
+
* Manifest-declared keys are offered via autocomplete, but any dynamic string
|
|
349
|
+
* is accepted too (e.g. `encrypted.password.${hash}`).
|
|
350
|
+
*
|
|
351
|
+
* @param client - The Cumulocity client that determines the target tenant
|
|
352
|
+
* @param key - The tenant option key
|
|
218
353
|
*
|
|
219
354
|
* @config Cache TTL can be configured via:
|
|
220
355
|
* - `c8y.cache.defaultTenantOptionsTTL` — Default TTL for all keys (in seconds)
|
|
@@ -222,47 +357,73 @@ declare function useUserTenantCredentials(requestOrEvent: ServerRequest | H3Even
|
|
|
222
357
|
* - `NITRO_C8Y_DEFAULT_TENANT_OPTIONS_TTL` — Environment variable for default TTL
|
|
223
358
|
*
|
|
224
359
|
* @example
|
|
225
|
-
* //
|
|
226
|
-
* const value = await useTenantOption('
|
|
227
|
-
*
|
|
228
|
-
* // Fetch an encrypted secret:
|
|
229
|
-
* const secret = await useTenantOption('credentials.apiKey')
|
|
230
|
-
*
|
|
231
|
-
* // Invalidate cache for a specific key:
|
|
232
|
-
* await useTenantOption.invalidate('myOption')
|
|
233
|
-
*
|
|
234
|
-
* // Force refresh a specific key:
|
|
235
|
-
* const fresh = await useTenantOption.refresh('myOption')
|
|
360
|
+
* // Read the owner tenant's config:
|
|
361
|
+
* const value = await useTenantOption(await useDeployedTenantClient(), 'featureMode').read()
|
|
236
362
|
*
|
|
237
|
-
* //
|
|
238
|
-
* await useTenantOption.
|
|
363
|
+
* // Read the current request tenant's config (multi-tenant):
|
|
364
|
+
* const value = await useTenantOption(await useUserTenantClient(event), 'featureMode').read()
|
|
239
365
|
*
|
|
240
|
-
* //
|
|
241
|
-
*
|
|
366
|
+
* // Create or update, or seed a dynamic key:
|
|
367
|
+
* await useTenantOption(client, 'featureMode').set('advanced')
|
|
368
|
+
* const token = await useTenantOption(client, `encrypted.password.${hash}`).getOrInsert('')
|
|
242
369
|
*/
|
|
243
|
-
declare
|
|
370
|
+
declare function useTenantOption(client: Client, key: TenantOptionKeyInput): TenantOption;
|
|
371
|
+
/**
|
|
372
|
+
* @internal
|
|
373
|
+
*/
|
|
374
|
+
interface UseTenantOptions {
|
|
244
375
|
/**
|
|
245
|
-
*
|
|
246
|
-
* @param key - The tenant option key to invalidate
|
|
376
|
+
* Handle for the client tenant's own settings category.
|
|
247
377
|
*/
|
|
248
|
-
|
|
378
|
+
(client: Client): TenantOptionCategory;
|
|
249
379
|
/**
|
|
250
|
-
*
|
|
251
|
-
* @param key - The tenant option key to refresh
|
|
380
|
+
* Handle for the client tenant's own settings category (given explicitly).
|
|
252
381
|
*/
|
|
253
|
-
|
|
382
|
+
(client: Client, category: C8YSettingsCategory): TenantOptionCategory;
|
|
254
383
|
/**
|
|
255
|
-
*
|
|
256
|
-
*
|
|
384
|
+
* Handle for a foreign settings category (`credentials.*` keys are rejected).
|
|
385
|
+
*
|
|
386
|
+
* Provide the key set as a type argument for autocomplete, e.g.
|
|
387
|
+
* `useTenantOptions<'featureA' | 'featureB'>(client, 'other-service')`.
|
|
388
|
+
* Supplying a type argument also explicitly selects this overload.
|
|
389
|
+
*/
|
|
390
|
+
<K extends string = string>(client: Client, category: string): ForeignTenantOptionCategory<K>;
|
|
391
|
+
/**
|
|
392
|
+
* Invalidate every already-read option cache, across all tenants and categories.
|
|
257
393
|
*/
|
|
258
394
|
invalidateAll: () => Promise<void>;
|
|
259
395
|
/**
|
|
260
|
-
* Refresh
|
|
261
|
-
*
|
|
262
|
-
* @returns Object mapping keys to their refreshed values
|
|
396
|
+
* Refresh every already-read option cache, across all tenants and categories.
|
|
397
|
+
* @returns Map of `${tenant}::${category}::${key}` store keys to their refreshed values.
|
|
263
398
|
*/
|
|
264
399
|
refreshAll: () => Promise<Record<string, string | undefined>>;
|
|
265
|
-
}
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Gets a handle for a whole settings category, targeting the tenant of the given
|
|
403
|
+
* `client`.\
|
|
404
|
+
* Omit the category (or pass the own {@link C8YSettingsCategory}) for the
|
|
405
|
+
* microservice's own category; pass any other category to read/write options in
|
|
406
|
+
* a foreign category (where `credentials.*` keys are rejected).
|
|
407
|
+
*
|
|
408
|
+
* @param client - The Cumulocity client that determines the target tenant
|
|
409
|
+
*
|
|
410
|
+
* @example
|
|
411
|
+
* const client = await useUserTenantClient(event)
|
|
412
|
+
*
|
|
413
|
+
* // Own category:
|
|
414
|
+
* const values = await useTenantOptions(client).list()
|
|
415
|
+
* await useTenantOptions(client).option('featureMode').set('advanced')
|
|
416
|
+
*
|
|
417
|
+
* // Foreign category:
|
|
418
|
+
* const value = await useTenantOptions(client, 'other-service').option('someKey').read()
|
|
419
|
+
*
|
|
420
|
+
* // Invalidate all cached options of one tenant + category:
|
|
421
|
+
* await useTenantOptions(client, 'other-service').invalidateAll()
|
|
422
|
+
*
|
|
423
|
+
* // Invalidate everything, across all tenants and categories:
|
|
424
|
+
* await useTenantOptions.invalidateAll()
|
|
425
|
+
*/
|
|
426
|
+
declare const useTenantOptions: UseTenantOptions;
|
|
266
427
|
//#endregion
|
|
267
428
|
//#region src/utils/schedule.d.ts
|
|
268
429
|
type ScheduledTaskPayload = TaskPayload;
|
|
@@ -370,4 +531,4 @@ declare function listScheduledTasks(): Promise<Record<string, ScheduledTaskInfo>
|
|
|
370
531
|
*/
|
|
371
532
|
declare function cancelScheduledTask(id: string): Promise<boolean>;
|
|
372
533
|
//#endregion
|
|
373
|
-
export { ScheduleTaskOptions, ScheduledTaskContext, ScheduledTaskInfo, ScheduledTaskInput, ScheduledTaskPayload, cancelScheduledTask, createError, createLogger, hasUserRequiredRole, isUserFromAllowedTenant, isUserFromDeployedTenant, listScheduledTasks, scheduleTask, useDeployedTenantClient, useDeployedTenantCredentials, useLogger, useSubscribedTenantClients, useSubscribedTenantCredentials, useTenantOption, useUser, useUserClient, useUserRoles, useUserTenantClient, useUserTenantCredentials };
|
|
534
|
+
export { ForeignTenantOptionCategory, ForeignTenantOptionKeyInput, ScheduleTaskOptions, ScheduledTaskContext, ScheduledTaskInfo, ScheduledTaskInput, ScheduledTaskPayload, SetEditableOptions, TenantOption, TenantOptionCategory, TenantOptionKeyInput, cancelScheduledTask, createError, createLogger, hasUserRequiredRole, isUserFromAllowedTenant, isUserFromDeployedTenant, listScheduledTasks, scheduleTask, useDeployedTenantClient, useDeployedTenantCredentials, useLogger, useSubscribedTenantClients, useSubscribedTenantCredentials, useTenantOption, useTenantOptions, useUser, useUserClient, useUserRoles, useUserTenantClient, useUserTenantCredentials };
|