c8y-nitro 0.7.2 → 0.9.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/{autoBootstrap-Drk7ltXK.mjs → autoBootstrap-qCcCgset.mjs} +1 -1
- package/dist/{bootstrap-C1Qly0J_.mjs → bootstrap-BcTCUiqG.mjs} +2 -2
- package/dist/{c8y-api-DscUs-Kd.mjs → c8y-api-DpCWhaJU.mjs} +8 -0
- package/dist/cli/index.mjs +4 -4
- package/dist/{client-D0Tdq7H1.mjs → client-DCov9jV6.mjs} +15 -4
- package/dist/{index-vu4xaFkz.d.mts → index-Dil1PcDr.d.mts} +108 -4
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +36 -3
- package/dist/{options-CmLpZ3Qf.mjs → options-BBnR-y_W.mjs} +2 -2
- package/dist/{package-BHOzdhHp.mjs → package-gK1cGX1w.mjs} +1 -1
- package/dist/{roles-B-DNuScZ.mjs → roles-CkUvL64s.mjs} +1 -1
- package/dist/runtime/handlers/invalidateTenantOptions.mjs +1 -1
- package/dist/runtime/handlers/openapi.mjs +1 -1
- package/dist/runtime/handlers/rewriteRequestUrl.mjs +1 -1
- package/dist/types.d.mts +2 -2
- package/dist/utils.d.mts +344 -75
- package/dist/utils.mjs +417 -147
- package/package.json +4 -1
package/dist/utils.d.mts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { t as TenantCredentials } from "./credentials-eKnJ7m9Y.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { RealtimeClient } from "c8y-realtime";
|
|
3
|
+
import { Client, ICredentials, ICurrentUser, IResultList } from "@c8y/client";
|
|
3
4
|
import { createError as createError$1, createLogger } from "evlog";
|
|
4
5
|
import { EventHandler, H3Event, HTTPEvent } from "nitro/h3";
|
|
5
6
|
import { ServerRequest, TaskContext, TaskPayload } from "nitro/types";
|
|
6
|
-
import { C8YRoles, C8YSettingsCategory, C8YTenantOptionKey } from "c8y-nitro/types";
|
|
7
|
+
import { C8YRole, C8YRoles, C8YSettingsCategory, C8YTenantOptionKey } from "c8y-nitro/types";
|
|
7
8
|
//#region src/utils/client.d.ts
|
|
8
9
|
/**
|
|
9
10
|
* Creates a Cumulocity client authenticated with the current user's credentials.\
|
|
@@ -51,8 +52,98 @@ declare function useSubscribedTenantClients(): Promise<Record<string, Client>>;
|
|
|
51
52
|
*/
|
|
52
53
|
declare function useDeployedTenantClient(): Promise<Client>;
|
|
53
54
|
//#endregion
|
|
55
|
+
//#region src/utils/paging.d.ts
|
|
56
|
+
/**
|
|
57
|
+
* The first page of a Cumulocity list result, in any of the shapes a caller
|
|
58
|
+
* naturally has on hand:
|
|
59
|
+
*
|
|
60
|
+
* - an already-awaited {@link IResultList} (`await client.inventory.list(...)`)
|
|
61
|
+
* - the pending `list()` promise itself (`client.inventory.list(...)`)
|
|
62
|
+
* - a thunk that produces it lazily (`() => client.inventory.list(...)`)
|
|
63
|
+
*
|
|
64
|
+
* Only the first page has to be supplied. Every subsequent page is fetched via
|
|
65
|
+
* the result's own `paging.next()`, which re-uses the exact client, auth, and
|
|
66
|
+
* filter that produced the first page — so there is no client to pass and no
|
|
67
|
+
* ambiguity between user, tenant, or microservice clients.
|
|
68
|
+
*/
|
|
69
|
+
type PageSource<T> = IResultList<T> | Promise<IResultList<T>> | (() => IResultList<T> | Promise<IResultList<T>>);
|
|
70
|
+
/**
|
|
71
|
+
* Optional safety guards for walking large or unbounded Cumulocity collections.
|
|
72
|
+
*/
|
|
73
|
+
interface PagingOptions {
|
|
74
|
+
/**
|
|
75
|
+
* Stop after fetching this many pages. Guards against runaway iteration over
|
|
76
|
+
* unexpectedly large collections. Unlimited when omitted.
|
|
77
|
+
*/
|
|
78
|
+
maxPages?: number;
|
|
79
|
+
/**
|
|
80
|
+
* Stop once this many items have been produced. The page that crosses the
|
|
81
|
+
* limit is truncated so exactly `maxItems` items are yielded. Unlimited when
|
|
82
|
+
* omitted.
|
|
83
|
+
*/
|
|
84
|
+
maxItems?: number;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Lazily walks a Cumulocity list result page by page, yielding each page's data
|
|
88
|
+
* array. This is the engine behind {@link paginate} and {@link fetchAllPages}.
|
|
89
|
+
*
|
|
90
|
+
* Pages are fetched on demand: the next request is only issued when the consumer
|
|
91
|
+
* asks for the next value. Iteration stops when a page comes back shorter than
|
|
92
|
+
* the requested page size (Cumulocity's signal that there is no more data),
|
|
93
|
+
* when the result carries no paging information, or when a {@link PagingOptions}
|
|
94
|
+
* guard is hit.
|
|
95
|
+
*
|
|
96
|
+
* @param source - The first page (result, promise, or thunk). See {@link PageSource}.
|
|
97
|
+
* @param options - Optional {@link PagingOptions} safety guards.
|
|
98
|
+
* @yields Each page as an array of items.
|
|
99
|
+
* @example
|
|
100
|
+
* // Process one page at a time (e.g. bulk insert per page):
|
|
101
|
+
* for await (const page of paginatePages(client.event.list({ pageSize: 2000 }))) {
|
|
102
|
+
* await bulkInsert(page)
|
|
103
|
+
* }
|
|
104
|
+
*/
|
|
105
|
+
declare function paginatePages<T>(source: PageSource<T>, options?: PagingOptions): AsyncGenerator<T[]>;
|
|
106
|
+
/**
|
|
107
|
+
* Lazily iterates every item across all pages of a Cumulocity list result,
|
|
108
|
+
* yielding one entry at a time — ideal for streaming large collections with a
|
|
109
|
+
* low memory footprint.
|
|
110
|
+
*
|
|
111
|
+
* Pages are fetched on demand as iteration advances, walking via the result's
|
|
112
|
+
* own `paging.next()` (same client and filter as the first page). Iteration
|
|
113
|
+
* stops when a page comes back shorter than the requested page size.
|
|
114
|
+
*
|
|
115
|
+
* @param source - The first page (result, promise, or thunk). See {@link PageSource}.
|
|
116
|
+
* @param options - Optional {@link PagingOptions} safety guards.
|
|
117
|
+
* @yields Each item, in order, across all pages.
|
|
118
|
+
* @example
|
|
119
|
+
* // Stream every active alarm, one at a time:
|
|
120
|
+
* for await (const alarm of paginate(() => client.alarm.list({ pageSize: 2000, status: 'ACTIVE' }))) {
|
|
121
|
+
* await handleAlarm(alarm)
|
|
122
|
+
* }
|
|
123
|
+
*/
|
|
124
|
+
declare function paginate<T>(source: PageSource<T>, options?: PagingOptions): AsyncGenerator<T>;
|
|
125
|
+
/**
|
|
126
|
+
* Collects every item across all pages of a Cumulocity list result into a single
|
|
127
|
+
* array, awaiting until all pages have been fetched.
|
|
128
|
+
*
|
|
129
|
+
* Walks via the result's own `paging.next()` (same client and filter as the
|
|
130
|
+
* first page), stopping when a page comes back shorter than the requested page
|
|
131
|
+
* size. For very large collections prefer {@link paginate} to avoid holding
|
|
132
|
+
* every item in memory at once, or cap the result with
|
|
133
|
+
* {@link PagingOptions.maxItems}.
|
|
134
|
+
*
|
|
135
|
+
* @param source - The first page (result, promise, or thunk). See {@link PageSource}.
|
|
136
|
+
* @param options - Optional {@link PagingOptions} safety guards.
|
|
137
|
+
* @returns All items across all pages, in order.
|
|
138
|
+
* @example
|
|
139
|
+
* // Fetch every managed object matching a fragment:
|
|
140
|
+
* const client = useUserClient(event)
|
|
141
|
+
* const all = await fetchAllPages(client.inventory.list({ pageSize: 2000, fragmentType: 'c8y_Sensor' }))
|
|
142
|
+
*/
|
|
143
|
+
declare function fetchAllPages<T>(source: PageSource<T>, options?: PagingOptions): Promise<T[]>;
|
|
144
|
+
//#endregion
|
|
54
145
|
//#region src/utils/middleware.d.ts
|
|
55
|
-
type UserRole = keyof C8YRoles |
|
|
146
|
+
type UserRole = keyof C8YRoles | C8YRole;
|
|
56
147
|
/**
|
|
57
148
|
* Middleware to check if the current user has the required role.\
|
|
58
149
|
* If the user doesn't have the required role, throws a 403 Forbidden error.\
|
|
@@ -502,110 +593,288 @@ declare function useLogger<T extends object = Record<string, unknown>>(eventOrRe
|
|
|
502
593
|
*/
|
|
503
594
|
declare const createError: typeof createError$1;
|
|
504
595
|
//#endregion
|
|
505
|
-
//#region src/utils/
|
|
506
|
-
|
|
507
|
-
|
|
596
|
+
//#region src/utils/tasks.d.ts
|
|
597
|
+
/**
|
|
598
|
+
* Concurrency policy for a single job.
|
|
599
|
+
* - `'single'`: at most one run of the job is in flight at a time. A tick that
|
|
600
|
+
* fires while the previous run is still going is skipped, and a manual
|
|
601
|
+
* {@link TaskRegistry.triggerJob} while a run is active joins the in-flight run.
|
|
602
|
+
* - `'parallel'`: every tick (or trigger) starts a fresh run, even if a previous
|
|
603
|
+
* run has not finished. Runs of the same job may overlap.
|
|
604
|
+
*/
|
|
605
|
+
type JobConcurrency = 'single' | 'parallel';
|
|
606
|
+
type TaskRegistryPayload = TaskPayload;
|
|
607
|
+
type TaskRegistryContext = TaskContext;
|
|
608
|
+
/**
|
|
609
|
+
* The event passed to a task handler on every execution.
|
|
610
|
+
*/
|
|
611
|
+
interface TaskEvent<TPayload = TaskRegistryPayload> {
|
|
612
|
+
/**
|
|
613
|
+
* Name of the task (function) being executed.
|
|
614
|
+
*/
|
|
615
|
+
task: string;
|
|
616
|
+
/**
|
|
617
|
+
* Name of the job that triggered this run, when the run originates from a scheduled or triggered job.
|
|
618
|
+
*/
|
|
619
|
+
job?: string;
|
|
620
|
+
/**
|
|
621
|
+
* Data bound when the job was scheduled (or passed to `run()`/`triggerJob()`).
|
|
622
|
+
*/
|
|
623
|
+
payload: TPayload;
|
|
624
|
+
/**
|
|
625
|
+
* Arbitrary context bound alongside the payload.
|
|
626
|
+
*/
|
|
627
|
+
context: TaskRegistryContext;
|
|
628
|
+
}
|
|
508
629
|
/**
|
|
509
|
-
* A
|
|
510
|
-
* Numbers are treated as seconds from now, strings are parsed as human-readable durations
|
|
511
|
-
* such as `"10 minutes"`, and dates are used as exact run times.
|
|
630
|
+
* A task handler function registered via {@link TaskRegistry.createTask}.
|
|
512
631
|
*/
|
|
513
|
-
type
|
|
632
|
+
type TaskHandler<TPayload = TaskRegistryPayload, TResult = unknown> = (event: TaskEvent<TPayload>) => TResult | Promise<TResult>;
|
|
514
633
|
/**
|
|
515
|
-
*
|
|
516
|
-
* `
|
|
634
|
+
* When a job should run.
|
|
635
|
+
* - `{ cron }`: recurring on a cron expression. 5- or 6-field (with seconds) is
|
|
636
|
+
* supported. Evaluated in UTC by default, or in the job's `timezone` if set.
|
|
637
|
+
* - `{ in }`: one-shot, from now — either a number of seconds (`{ in: 30 }`) or a
|
|
638
|
+
* human duration string (`{ in: '5 minutes' }`, `{ in: '1 hour' }`).
|
|
639
|
+
* - `{ at }`: one-shot, at an exact instant given as a `Date` or ISO 8601 string,
|
|
640
|
+
* taken literally (never re-projected to another timezone). Times in the past
|
|
641
|
+
* fire almost immediately.
|
|
517
642
|
*/
|
|
518
|
-
|
|
643
|
+
type JobSchedule = {
|
|
644
|
+
cron: string;
|
|
645
|
+
} | {
|
|
646
|
+
in: number | string;
|
|
647
|
+
} | {
|
|
648
|
+
at: Date | string;
|
|
649
|
+
};
|
|
650
|
+
/**
|
|
651
|
+
* Options for scheduling a job via {@link TaskRegistry.scheduleJob}.
|
|
652
|
+
*/
|
|
653
|
+
interface ScheduleJobOptions<TTask extends string = string, TPayload = TaskRegistryPayload, TSchedule extends JobSchedule = JobSchedule> {
|
|
654
|
+
/**
|
|
655
|
+
* Unique, caller-chosen job name. This is the handle used by `cancelJob()`, `getJob()` and `triggerJob()`.
|
|
656
|
+
*/
|
|
657
|
+
name: string;
|
|
519
658
|
/**
|
|
520
|
-
*
|
|
659
|
+
* Name of a task registered via `createTask()` that this job runs.
|
|
521
660
|
*/
|
|
522
|
-
|
|
661
|
+
task: TTask;
|
|
523
662
|
/**
|
|
524
|
-
*
|
|
663
|
+
* When the job should run.
|
|
525
664
|
*/
|
|
526
|
-
|
|
665
|
+
schedule: TSchedule;
|
|
527
666
|
/**
|
|
528
|
-
*
|
|
667
|
+
* Data forwarded to the handler's `event.payload`.\
|
|
668
|
+
* Prefer stable identifiers (e.g. a config id) over live object references so the
|
|
669
|
+
* handler can resolve current values at run time and the schedule stays serializable.
|
|
529
670
|
*/
|
|
530
|
-
|
|
671
|
+
payload?: TPayload;
|
|
672
|
+
/**
|
|
673
|
+
* Data forwarded to the handler's `event.context`.
|
|
674
|
+
*/
|
|
675
|
+
context?: TaskRegistryContext;
|
|
676
|
+
/**
|
|
677
|
+
* Concurrency policy for this job. Defaults to `'single'`.
|
|
678
|
+
*/
|
|
679
|
+
concurrency?: JobConcurrency;
|
|
680
|
+
/**
|
|
681
|
+
* Recurring only: the IANA timezone the cron expression is evaluated in
|
|
682
|
+
* (e.g. `'Europe/Berlin'`). Defaults to `'UTC'` so the schedule is deterministic
|
|
683
|
+
* regardless of the container's local time. croner performs the alignment — no
|
|
684
|
+
* conversion is done by `c8y-nitro`. Ignored for one-shot schedules.
|
|
685
|
+
*/
|
|
686
|
+
timezone?: string;
|
|
687
|
+
/**
|
|
688
|
+
* Recurring only: also run once immediately on registration, in addition to the cron. Defaults to `false`.
|
|
689
|
+
*/
|
|
690
|
+
immediate?: boolean;
|
|
691
|
+
/**
|
|
692
|
+
* Recurring only: stop after this many scheduled runs.
|
|
693
|
+
*/
|
|
694
|
+
maxRuns?: number;
|
|
695
|
+
/**
|
|
696
|
+
* Overwrite an existing job with the same name instead of throwing. Defaults to `false`.
|
|
697
|
+
*/
|
|
698
|
+
replace?: boolean;
|
|
531
699
|
}
|
|
532
700
|
/**
|
|
533
|
-
*
|
|
534
|
-
* Returned by `scheduleTask()` and by `listScheduledTasks()`.
|
|
701
|
+
* Fields common to every job, regardless of kind.
|
|
535
702
|
*/
|
|
536
|
-
interface
|
|
703
|
+
interface BaseJobInfo {
|
|
537
704
|
/**
|
|
538
|
-
*
|
|
705
|
+
* The job's unique name.
|
|
539
706
|
*/
|
|
540
|
-
|
|
707
|
+
name: string;
|
|
541
708
|
/**
|
|
542
|
-
*
|
|
709
|
+
* The task (function) the job runs.
|
|
543
710
|
*/
|
|
544
711
|
task: string;
|
|
545
712
|
/**
|
|
546
|
-
*
|
|
713
|
+
* The job's concurrency policy.
|
|
547
714
|
*/
|
|
548
|
-
|
|
715
|
+
concurrency: JobConcurrency;
|
|
716
|
+
/**
|
|
717
|
+
* Next scheduled execution as an ISO datetime string, or `null` if nothing is pending.
|
|
718
|
+
*/
|
|
719
|
+
nextRun: string | null;
|
|
720
|
+
/**
|
|
721
|
+
* Whether a run of this job is currently in flight.
|
|
722
|
+
*/
|
|
723
|
+
running: boolean;
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* Information about a one-shot job (scheduled with `{ in }` or `{ at }`).
|
|
727
|
+
*/
|
|
728
|
+
interface OnceJobInfo extends BaseJobInfo {
|
|
729
|
+
kind: 'once';
|
|
730
|
+
/**
|
|
731
|
+
* Always `null` for one-shot jobs.
|
|
732
|
+
*/
|
|
733
|
+
cron: null;
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* Information about a recurring job (scheduled with `{ cron }`).
|
|
737
|
+
*/
|
|
738
|
+
interface RecurringJobInfo extends BaseJobInfo {
|
|
739
|
+
kind: 'recurring';
|
|
740
|
+
/**
|
|
741
|
+
* The cron expression the job runs on.
|
|
742
|
+
*/
|
|
743
|
+
cron: string;
|
|
744
|
+
/**
|
|
745
|
+
* The IANA timezone the cron expression is evaluated in.
|
|
746
|
+
*/
|
|
747
|
+
timezone: string;
|
|
748
|
+
/**
|
|
749
|
+
* A few upcoming executions as ISO datetime strings.
|
|
750
|
+
*/
|
|
751
|
+
nextRuns: string[];
|
|
549
752
|
}
|
|
550
753
|
/**
|
|
551
|
-
*
|
|
552
|
-
*
|
|
553
|
-
|
|
754
|
+
* Public information about a registered job. A discriminated union on `kind` —
|
|
755
|
+
* returned by `scheduleJob()`, `getJob()` and `listJobs()`.
|
|
756
|
+
*/
|
|
757
|
+
type JobInfo = OnceJobInfo | RecurringJobInfo;
|
|
758
|
+
/**
|
|
759
|
+
* Maps a {@link JobSchedule} to the {@link JobInfo} variant it produces.
|
|
760
|
+
*/
|
|
761
|
+
type JobInfoFor<TSchedule extends JobSchedule> = TSchedule extends {
|
|
762
|
+
cron: string;
|
|
763
|
+
} ? RecurringJobInfo : OnceJobInfo;
|
|
764
|
+
/**
|
|
765
|
+
* Describes the payload and result type of a single registered task.
|
|
766
|
+
*/
|
|
767
|
+
interface TaskShape<TPayload = TaskRegistryPayload, TResult = unknown> {
|
|
768
|
+
payload: TPayload;
|
|
769
|
+
result: TResult;
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
772
|
+
* A map of task name to its {@link TaskShape}, accumulated by the builder.
|
|
773
|
+
*/
|
|
774
|
+
type TaskMap = Record<string, TaskShape>;
|
|
775
|
+
/**
|
|
776
|
+
* A type-charged registry of tasks (functions) and the jobs that schedule them.
|
|
554
777
|
*
|
|
555
|
-
*
|
|
556
|
-
*
|
|
557
|
-
*
|
|
778
|
+
* Each `createTask()` call widens the registry's type with the new task name, so
|
|
779
|
+
* `run()`, `scheduleJob()` and `triggerJob()` autocomplete known task names and
|
|
780
|
+
* reject typos at compile time.
|
|
781
|
+
*/
|
|
782
|
+
interface TaskRegistry<TTasks extends TaskMap = {}> {
|
|
783
|
+
/**
|
|
784
|
+
* Registers a task (function) under a compile-time-known name.\
|
|
785
|
+
* Passing a name that is already registered is a type error (and throws at runtime).
|
|
786
|
+
*
|
|
787
|
+
* @param name - Unique task name
|
|
788
|
+
* @param handler - The function to run. Annotate its event to type the payload,
|
|
789
|
+
* e.g. `(e: TaskEvent<{ configId: string }>) => ...`.
|
|
790
|
+
*/
|
|
791
|
+
createTask: <TName extends string, TPayload extends TaskRegistryPayload = TaskRegistryPayload, TResult = unknown>(name: TName extends keyof TTasks ? never : TName, handler: TaskHandler<TPayload, TResult>) => TaskRegistry<TTasks & Record<TName, TaskShape<TPayload, TResult>>>;
|
|
792
|
+
/**
|
|
793
|
+
* Runs a task immediately and ad-hoc, without registering a job. Always runs
|
|
794
|
+
* fresh (no deduplication). Use a job with `'single'` concurrency when you need
|
|
795
|
+
* overlap protection.
|
|
796
|
+
*/
|
|
797
|
+
run: <TName extends keyof TTasks & string>(task: TName, options?: {
|
|
798
|
+
payload?: TTasks[TName]['payload'];
|
|
799
|
+
context?: TaskRegistryContext;
|
|
800
|
+
}) => Promise<TTasks[TName]['result']>;
|
|
801
|
+
/**
|
|
802
|
+
* Schedules a named job that runs a task once or repeatedly. The return type is
|
|
803
|
+
* inferred from the schedule: `{ cron }` yields a {@link RecurringJobInfo},
|
|
804
|
+
* `{ in }`/`{ at }` yield a {@link OnceJobInfo}.
|
|
805
|
+
*/
|
|
806
|
+
scheduleJob: <TName extends keyof TTasks & string, TSchedule extends JobSchedule>(options: ScheduleJobOptions<TName, TTasks[TName]['payload'], TSchedule>) => JobInfoFor<TSchedule>;
|
|
807
|
+
/**
|
|
808
|
+
* Runs an already-registered job immediately, respecting its concurrency policy.
|
|
809
|
+
* For a `'single'` job with a run in flight this returns the in-flight promise.
|
|
810
|
+
*/
|
|
811
|
+
triggerJob: <TResult = unknown>(name: string, options?: {
|
|
812
|
+
payload?: TaskRegistryPayload;
|
|
813
|
+
context?: TaskRegistryContext;
|
|
814
|
+
}) => Promise<TResult>;
|
|
815
|
+
/**
|
|
816
|
+
* Cancels a scheduled job by name.
|
|
817
|
+
* @returns `true` when a job was found and cancelled, otherwise `false`.
|
|
818
|
+
*/
|
|
819
|
+
cancelJob: (name: string) => boolean;
|
|
820
|
+
/**
|
|
821
|
+
* Lists all currently registered jobs.
|
|
822
|
+
*/
|
|
823
|
+
listJobs: () => JobInfo[];
|
|
824
|
+
/**
|
|
825
|
+
* Returns information about a single job, or `undefined` if it does not exist.
|
|
826
|
+
*/
|
|
827
|
+
getJob: (name: string) => JobInfo | undefined;
|
|
828
|
+
/**
|
|
829
|
+
* Returns `true` when a task with the given name is registered.
|
|
830
|
+
*/
|
|
831
|
+
hasTask: (name: string) => boolean;
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Creates a new, empty task registry.
|
|
558
835
|
*
|
|
559
836
|
* @example
|
|
560
|
-
*
|
|
561
|
-
* const scheduled = await scheduleTask('emails:send', {
|
|
562
|
-
* payload: { messageId: 'abc123' },
|
|
563
|
-
* schedule: 30,
|
|
564
|
-
* })
|
|
837
|
+
* import { c8yTasks } from 'c8y-nitro/utils'
|
|
565
838
|
*
|
|
566
|
-
*
|
|
567
|
-
*
|
|
568
|
-
* await
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
* })
|
|
839
|
+
* export const tasks = c8yTasks()
|
|
840
|
+
* .createTask('sync', async ({ payload }) => {
|
|
841
|
+
* const config = await loadConfig(payload.configId) // resolve live state here
|
|
842
|
+
* await sync(config)
|
|
843
|
+
* })
|
|
572
844
|
*
|
|
573
|
-
*
|
|
574
|
-
*
|
|
575
|
-
*
|
|
576
|
-
*
|
|
577
|
-
*
|
|
578
|
-
*
|
|
845
|
+
* // one per config, each an independent job
|
|
846
|
+
* tasks.scheduleJob({ name: 'sync-abc', task: 'sync', payload: { configId: 'abc' }, schedule: { cron: '*\/5 * * * *' } })
|
|
847
|
+
* tasks.scheduleJob({ name: 'sync-def', task: 'sync', payload: { configId: 'def' }, schedule: { cron: '*\/5 * * * *' }, concurrency: 'parallel' })
|
|
848
|
+
*
|
|
849
|
+
* @remarks
|
|
850
|
+
* The registry is a plain runtime singleton — export it from one module and import
|
|
851
|
+
* it wherever you schedule or cancel jobs. Recurring jobs only arm when the module
|
|
852
|
+
* that schedules them executes, so register them from a Nitro plugin (or another
|
|
853
|
+
* startup path) if they must run from boot.
|
|
579
854
|
*/
|
|
580
|
-
declare function
|
|
855
|
+
declare function c8yTasks(): TaskRegistry;
|
|
856
|
+
//#endregion
|
|
857
|
+
//#region src/utils/realtime.d.ts
|
|
581
858
|
/**
|
|
582
|
-
*
|
|
583
|
-
*
|
|
584
|
-
*
|
|
585
|
-
*
|
|
586
|
-
*
|
|
587
|
-
* @example
|
|
588
|
-
* const tasks = await listScheduledTasks()
|
|
589
|
-
* for (const [id, task] of Object.entries(tasks)) {
|
|
590
|
-
* console.log(id, task.task, task.runAt)
|
|
591
|
-
* }
|
|
859
|
+
* Anything a caller might already have on hand that identifies a tenant, from
|
|
860
|
+
* which {@link useTenantRealtimeClient} resolves the tenant's service
|
|
861
|
+
* credentials: a tenant id, that tenant's credentials, a `@c8y/client` scoped to
|
|
862
|
+
* it, or the current request.
|
|
592
863
|
*/
|
|
593
|
-
|
|
864
|
+
type TenantRealtimeInput = string | ICredentials | Client | H3Event | ServerRequest;
|
|
594
865
|
/**
|
|
595
|
-
*
|
|
596
|
-
*
|
|
597
|
-
*
|
|
598
|
-
*
|
|
599
|
-
* @returns `true` when a pending task was cancelled, otherwise `false`
|
|
866
|
+
* Get the pooled Notification 2.0 realtime client for a tenant, creating it on
|
|
867
|
+
* first use and reusing it after. Accepts whatever identifies the tenant — a
|
|
868
|
+
* tenant id, that tenant's credentials, a `@c8y/client`, or the current request
|
|
869
|
+
* — and always connects with the tenant's **service** credentials.
|
|
600
870
|
*
|
|
871
|
+
* Register handlers directly on the returned client (see `c8y-realtime`):
|
|
601
872
|
* @example
|
|
602
|
-
* const
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
607
|
-
* const cancelled = await cancelScheduledTask(scheduled.id)
|
|
873
|
+
* const rt = await useTenantRealtimeClient(event)
|
|
874
|
+
* rt.alarms.onCreate('*', alarm => log.info(alarm.severity, alarm.text))
|
|
875
|
+
* rt.measurements.onCreate('device42', m => log.info(m.type, m.time))
|
|
876
|
+
* @param input - A tenant id, `ICredentials`, a `Client`, or an `H3Event`/`ServerRequest`.
|
|
608
877
|
*/
|
|
609
|
-
declare function
|
|
878
|
+
declare function useTenantRealtimeClient(input: TenantRealtimeInput): Promise<RealtimeClient>;
|
|
610
879
|
//#endregion
|
|
611
|
-
export { ForeignTenantOptionCategory, ForeignTenantOptionKeyInput,
|
|
880
|
+
export { BaseJobInfo, ForeignTenantOptionCategory, ForeignTenantOptionKeyInput, JobConcurrency, JobInfo, JobInfoFor, JobSchedule, OnceJobInfo, PageSource, PagingOptions, RecurringJobInfo, ScheduleJobOptions, SetEditableOptions, TaskEvent, TaskHandler, TaskMap, TaskRegistry, TaskRegistryContext, TaskRegistryPayload, TaskShape, TenantOption, TenantOptionCategory, TenantOptionKeyInput, type TenantRealtimeInput, c8yTasks, createError, createLogger, fetchAllPages, hasUserRequiredRole, isUserFromAllowedTenant, isUserFromDeployedTenant, paginate, paginatePages, useDeployedTenantClient, useDeployedTenantCredentials, useLogger, useSubscribedTenantClients, useSubscribedTenantCredentials, useTenantOption, useTenantOptions, useTenantRealtimeClient, useUser, useUserClient, useUserRoles, useUserTenantClient, useUserTenantCredentials };
|