@7365admin1/core 3.42.3 → 3.43.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/CHANGELOG.md +296 -0
- package/dist/index.d.ts +996 -1
- package/dist/index.js +8725 -6422
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8469 -6228
- package/dist/index.mjs.map +1 -1
- package/docs/camera-integration-config.md +191 -0
- package/package.json +3 -2
- package/test/camera-capability.util.test.mjs +545 -0
- package/test/camera-device-http.test.mjs +792 -0
- package/test/camera-entitlement-wiring.test.mjs +134 -0
- package/test/camera-view.util.test.mjs +892 -0
- package/test/camera-write-gate.test.mjs +121 -0
package/dist/index.d.ts
CHANGED
|
@@ -2561,6 +2561,1001 @@ declare function useSiteCameraController(): {
|
|
|
2561
2561
|
deleteById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
2562
2562
|
};
|
|
2563
2563
|
|
|
2564
|
+
/**
|
|
2565
|
+
* Camera-view rules, as pure functions.
|
|
2566
|
+
*
|
|
2567
|
+
* Everything in this file is decidable without a network, a database or an
|
|
2568
|
+
* Express request, which is the point: the access rules and the Dahua protocol
|
|
2569
|
+
* details below are the parts that must not silently rot, and they are the parts
|
|
2570
|
+
* that are otherwise impossible to test without a camera on a desk.
|
|
2571
|
+
*
|
|
2572
|
+
* Endpoint and page references are to Dahua HTTP API V3.37.
|
|
2573
|
+
*/
|
|
2574
|
+
/** Dahua `site.cameras.type` values. Only `ip` units serve pictures — see below. */
|
|
2575
|
+
declare const CAMERA_TYPE_IP = "ip";
|
|
2576
|
+
declare const CAMERA_TYPE_ANPR = "anpr";
|
|
2577
|
+
/**
|
|
2578
|
+
* The domain rule, and it is a product decision, not a technical workaround
|
|
2579
|
+
* (owner, 2026-08-07): **ANPR is a different estate from Virtual Patrol and
|
|
2580
|
+
* CCTV.** ANPR units belong to visitor management and vehicle management, where
|
|
2581
|
+
* they already work; they are not patrol checkpoints and they are not monitoring
|
|
2582
|
+
* cameras. So Patrol and CCTV see `type: "ip"` cameras and nothing else.
|
|
2583
|
+
*
|
|
2584
|
+
* That is why an ANPR record is REFUSED here rather than carried through as a
|
|
2585
|
+
* special case with a "cannot serve a picture" label: it is not a camera this
|
|
2586
|
+
* feature is allowed to touch at all. Nothing in the visitor or vehicle path
|
|
2587
|
+
* reads this file, so the working ANPR flows are untouched.
|
|
2588
|
+
*
|
|
2589
|
+
* The vendor spec agrees, incidentally — V3.37 §10.4.4 (p.538), verbatim: *"For
|
|
2590
|
+
* intelligent traffic device, it should use this method to take a snapshot. But,
|
|
2591
|
+
* the response is not image data."* — but the reason we refuse is the domain
|
|
2592
|
+
* rule, and it would still hold if a future firmware returned a JPEG.
|
|
2593
|
+
*/
|
|
2594
|
+
declare const CAMERA_NOT_PATROL_OR_CCTV = "This is an ANPR unit. ANPR belongs to visitor and vehicle management; Virtual Patrol and CCTV use IP cameras only.";
|
|
2595
|
+
/**
|
|
2596
|
+
* Is this a camera Virtual Patrol or CCTV may use at all?
|
|
2597
|
+
*
|
|
2598
|
+
* The single gate for every per-camera request, so a new endpoint cannot forget
|
|
2599
|
+
* it — and the reason it is a predicate rather than an inline `!==` is that the
|
|
2600
|
+
* rule now has a name a reviewer can look up.
|
|
2601
|
+
*/
|
|
2602
|
+
declare function isPatrolCctvCamera(camera: {
|
|
2603
|
+
type?: string;
|
|
2604
|
+
} | null): boolean;
|
|
2605
|
+
/**
|
|
2606
|
+
* The same rule as a database filter, for the listing paths.
|
|
2607
|
+
*
|
|
2608
|
+
* A wall that renders ANPR tiles as "unsupported" is still showing a supervisor
|
|
2609
|
+
* cameras from a module they are not looking at. They are excluded by the query,
|
|
2610
|
+
* so they cost neither a tile nor a probe.
|
|
2611
|
+
*/
|
|
2612
|
+
declare const PATROL_CCTV_CAMERA_FILTER: {
|
|
2613
|
+
type: string;
|
|
2614
|
+
};
|
|
2615
|
+
/**
|
|
2616
|
+
* Permission strings that may VIEW a camera.
|
|
2617
|
+
*
|
|
2618
|
+
* Measured, not chosen: these are the catalogued Virtual Patrol read strings, and
|
|
2619
|
+
* their union reaches 25 of 36 security members on staging once wildcards are
|
|
2620
|
+
* counted (the same union the client-side read gate uses). Spelling is verbatim
|
|
2621
|
+
* production spelling — never "corrected".
|
|
2622
|
+
*/
|
|
2623
|
+
declare const CAMERA_VIEW_PERMISSIONS: string[];
|
|
2624
|
+
/**
|
|
2625
|
+
* Permission strings that may MOVE a camera.
|
|
2626
|
+
*
|
|
2627
|
+
* Stricter on purpose: viewing a picture is a read, PTZ turns a motor. Only a
|
|
2628
|
+
* role that may actually start a patrol may steer a camera during one.
|
|
2629
|
+
*/
|
|
2630
|
+
declare const CAMERA_PTZ_PERMISSIONS: string[];
|
|
2631
|
+
/** `*` is the estate's wildcard permission and is honoured everywhere else too. */
|
|
2632
|
+
declare function hasAnyPermission(permissions: unknown, allowed: Array<string>): boolean;
|
|
2633
|
+
/** One row of `members`, as much of it as an entitlement decision needs. */
|
|
2634
|
+
type CameraMembership = {
|
|
2635
|
+
siteId?: unknown;
|
|
2636
|
+
org?: unknown;
|
|
2637
|
+
/**
|
|
2638
|
+
* The role this membership carries. Returned with the grant so permissions
|
|
2639
|
+
* are read off the role that actually granted access — see
|
|
2640
|
+
* `permissionsForGrant` in the service.
|
|
2641
|
+
*/
|
|
2642
|
+
role?: unknown;
|
|
2643
|
+
};
|
|
2644
|
+
/**
|
|
2645
|
+
* WHICH membership lets this caller reach this site, or `null` for none.
|
|
2646
|
+
*
|
|
2647
|
+
* Three sources, in order of how directly they say "this person works here":
|
|
2648
|
+
*
|
|
2649
|
+
* 1. **A membership at the site itself** (`members.siteId`). 277 of the 367 live
|
|
2650
|
+
* membership rows are recorded this way.
|
|
2651
|
+
* 2. **A membership at the site's OWNING organisation, with no site on it** —
|
|
2652
|
+
* an org-wide role. 90 rows, 56 people, are recorded this way.
|
|
2653
|
+
* 3. **An engagement** — an ACTIVE `customer.sites` row saying one of the
|
|
2654
|
+
* caller's organisations is contracted to serve this site, AND a membership
|
|
2655
|
+
* that is not pinned to some other site. This is how the product routes a
|
|
2656
|
+
* security agency to a property manager's site, and it is the list the web
|
|
2657
|
+
* apps' own site switcher is built from (`useCustomerSite().getAll()` in the
|
|
2658
|
+
* Security app's layout). Nothing in the camera path read it before, so a
|
|
2659
|
+
* guard whose agency is engaged at a site was refused a camera the switcher
|
|
2660
|
+
* had just offered them.
|
|
2661
|
+
*
|
|
2662
|
+
* ## Why the engagement branch requires an ORG-LEVEL membership
|
|
2663
|
+
*
|
|
2664
|
+
* **Product decision, owner, 2026-08-10, settled:** an agency engaged at several
|
|
2665
|
+
* sites gives its staff access to **the site each person is assigned to, and no
|
|
2666
|
+
* other**. It matches how the rest of the product is described — modules are set
|
|
2667
|
+
* up per site.
|
|
2668
|
+
*
|
|
2669
|
+
* So `!idOf(membership.siteId)` is required here exactly as branch 2 requires
|
|
2670
|
+
* it. Before, this branch matched on organisation alone, which made a person
|
|
2671
|
+
* pinned to site X reach every site their agency serves — while somebody pinned
|
|
2672
|
+
* to site X of the site's OWNING organisation could not reach its other sites.
|
|
2673
|
+
* The two branches now say the same thing: **a membership pinned to a site never
|
|
2674
|
+
* grants a different site**, and a membership with no site is an org-wide role
|
|
2675
|
+
* within whichever organisation holds it.
|
|
2676
|
+
*
|
|
2677
|
+
* Measured on staging before the change: this removes 68 (user, camera-site)
|
|
2678
|
+
* grants, all of them cross-organisation engagements held by a membership pinned
|
|
2679
|
+
* elsewhere; every one of those 68 belongs to somebody whose organisation is
|
|
2680
|
+
* engaged at the site they ARE pinned to, so nobody is left without their own
|
|
2681
|
+
* site. 0 grants through branch 2 are affected — **estate-side org-level access
|
|
2682
|
+
* is a different path and is untouched.**
|
|
2683
|
+
*
|
|
2684
|
+
* The membership is RETURNED, not just a yes/no, because the caller's
|
|
2685
|
+
* permissions must then be resolved against the organisation that actually
|
|
2686
|
+
* granted access — see `getUserPermissions` in the service. Resolving them
|
|
2687
|
+
* against an arbitrary row (`memberships[0]`) is wrong for the 22 people who
|
|
2688
|
+
* belong to more than one organisation.
|
|
2689
|
+
*
|
|
2690
|
+
* Ids are compared as strings so an ObjectId and its hex form match.
|
|
2691
|
+
*/
|
|
2692
|
+
declare function cameraGrant(params: {
|
|
2693
|
+
cameraSite?: unknown;
|
|
2694
|
+
cameraOrg?: unknown;
|
|
2695
|
+
memberships: Array<CameraMembership>;
|
|
2696
|
+
/**
|
|
2697
|
+
* The caller's organisations that hold an ACTIVE engagement to THIS site.
|
|
2698
|
+
* The query that fills it is already scoped to the site, so membership of one
|
|
2699
|
+
* of these organisations is the whole test here.
|
|
2700
|
+
*/
|
|
2701
|
+
engagedOrgs?: Set<string>;
|
|
2702
|
+
}): CameraMembership | null;
|
|
2703
|
+
/** `cameraGrant` as a yes/no, for the places that do not need to know which. */
|
|
2704
|
+
declare function isCameraEntitled(params: {
|
|
2705
|
+
cameraSite?: unknown;
|
|
2706
|
+
cameraOrg?: unknown;
|
|
2707
|
+
memberships: Array<CameraMembership>;
|
|
2708
|
+
engagedOrgs?: Set<string>;
|
|
2709
|
+
}): boolean;
|
|
2710
|
+
/**
|
|
2711
|
+
* Why this camera cannot serve a picture, or `null` when it can.
|
|
2712
|
+
*
|
|
2713
|
+
* Returned rather than thrown so the caller decides the HTTP status, and so the
|
|
2714
|
+
* whole rule set is one assertion in a test.
|
|
2715
|
+
*/
|
|
2716
|
+
declare function snapshotRefusalReason(camera: {
|
|
2717
|
+
type?: string;
|
|
2718
|
+
status?: string;
|
|
2719
|
+
host?: string;
|
|
2720
|
+
} | null, devices?: Record<string, CameraDevice>): string | null;
|
|
2721
|
+
/**
|
|
2722
|
+
* `site.cameras.host` is stored with or without a scheme depending on who added
|
|
2723
|
+
* the record. Default to `http://` rather than `https://`: 9 of the 17 hosts in
|
|
2724
|
+
* the estate are cleartext today (integration audit R8), and silently upgrading
|
|
2725
|
+
* them would turn a working camera into a TLS error.
|
|
2726
|
+
*
|
|
2727
|
+
* ponytail: no URL library. Trailing-slash trim + scheme default is the whole
|
|
2728
|
+
* job; swap in `new URL()` if hosts ever carry paths or ports we must rewrite.
|
|
2729
|
+
*/
|
|
2730
|
+
declare function cameraBaseUrl(host: string): string;
|
|
2731
|
+
/**
|
|
2732
|
+
* **`site.cameras.host` is not a device address for an `ip` camera.** Measured
|
|
2733
|
+
* across the whole estate, 2026-08-09: every active `ip` record stores the CCTV
|
|
2734
|
+
* relay's *page* URL — `https://<relay-authority>/<channel>` — and the numeric
|
|
2735
|
+
* last path segment is the **stream channel** on the recorder the relay reads.
|
|
2736
|
+
*
|
|
2737
|
+
* So a camera resolves in two parts:
|
|
2738
|
+
*
|
|
2739
|
+
* | Part | Comes from |
|
|
2740
|
+
* |---|---|
|
|
2741
|
+
* | which device | server configuration, keyed by the relay authority |
|
|
2742
|
+
* | which stream on it | the stored host's last path segment |
|
|
2743
|
+
*
|
|
2744
|
+
* The device address and its credential live in deployment configuration and
|
|
2745
|
+
* **never in the database and never in the client** — the same rule as every
|
|
2746
|
+
* other secret in this estate, and the reason this file only ever returns a
|
|
2747
|
+
* resolved device to server-side callers.
|
|
2748
|
+
*/
|
|
2749
|
+
type CameraDevice = {
|
|
2750
|
+
host: string;
|
|
2751
|
+
port: number;
|
|
2752
|
+
username: string;
|
|
2753
|
+
password: string;
|
|
2754
|
+
};
|
|
2755
|
+
/**
|
|
2756
|
+
* `CAMERA_RTSP_DEVICES` — a JSON object keyed by relay authority:
|
|
2757
|
+
*
|
|
2758
|
+
* ```
|
|
2759
|
+
* {"<relay-authority>":{"host":"…","port":554,"username":"…","password":"…"}}
|
|
2760
|
+
* ```
|
|
2761
|
+
*
|
|
2762
|
+
* One variable rather than a per-authority naming scheme, because the estate has
|
|
2763
|
+
* exactly one relay today and an unknown number tomorrow; adding the second one
|
|
2764
|
+
* is a config edit, not a code change. Malformed JSON yields no devices — every
|
|
2765
|
+
* camera then refuses with a reason, which is the correct failure for a
|
|
2766
|
+
* misconfigured server and is far better than a half-parsed device map.
|
|
2767
|
+
*/
|
|
2768
|
+
declare function cameraDevices(env?: Record<string, string | undefined>): Record<string, CameraDevice>;
|
|
2769
|
+
/**
|
|
2770
|
+
* The relay authority and the channel a stored host stands for.
|
|
2771
|
+
*
|
|
2772
|
+
* `null` channel means the host carries no numeric last segment — one record in
|
|
2773
|
+
* the estate is like that, and it is genuinely unresolvable rather than a
|
|
2774
|
+
* defaulted channel 1, which would silently show the wrong camera.
|
|
2775
|
+
*/
|
|
2776
|
+
declare function parseCameraHost(host: string): {
|
|
2777
|
+
authority: string;
|
|
2778
|
+
channel: number | null;
|
|
2779
|
+
} | null;
|
|
2780
|
+
/** The device + channel a camera record stands for, or `null` if it does not. */
|
|
2781
|
+
declare function resolveCamera(host: string | undefined, devices?: Record<string, CameraDevice>): {
|
|
2782
|
+
device: CameraDevice;
|
|
2783
|
+
channel: number;
|
|
2784
|
+
} | null;
|
|
2785
|
+
/**
|
|
2786
|
+
* Why a stored host cannot be resolved to a device, or `null` when it can.
|
|
2787
|
+
*
|
|
2788
|
+
* Three distinct reasons on purpose — a lead reading a tile must be able to tell
|
|
2789
|
+
* "nobody configured this relay" (a deployment fix) from "this record is a
|
|
2790
|
+
* placeholder" (a data fix). The estate has all three today: 12 cameras resolve,
|
|
2791
|
+
* two are `example.com` placeholders and one host carries no channel.
|
|
2792
|
+
*/
|
|
2793
|
+
declare function resolutionRefusalReason(host: string | undefined, devices?: Record<string, CameraDevice>): string | null;
|
|
2794
|
+
/**
|
|
2795
|
+
* The highest channel number worth accepting from a form.
|
|
2796
|
+
*
|
|
2797
|
+
* A bound, not a claim about any unit: a recorder answers for the channels it
|
|
2798
|
+
* has, and asking for 900 is a typo rather than a camera. 256 is comfortably
|
|
2799
|
+
* above the largest Dahua NVR channel count.
|
|
2800
|
+
*/
|
|
2801
|
+
declare const MAX_CAMERA_CHANNEL = 256;
|
|
2802
|
+
/** A channel number a person typed, or `null` if it is not one. */
|
|
2803
|
+
declare function parseCameraChannel(value: unknown): number | null;
|
|
2804
|
+
/**
|
|
2805
|
+
* Which relay serves a given recorder — the configured map, read backwards.
|
|
2806
|
+
*
|
|
2807
|
+
* `cameraDevices()` answers "given a relay, which recorder?", because that is
|
|
2808
|
+
* the question a stored record asks. Setting a camera UP asks the opposite: the
|
|
2809
|
+
* person has the recorder in front of them and no idea what a relay is. Same
|
|
2810
|
+
* single source of truth either way; there is deliberately no second map to
|
|
2811
|
+
* keep in step.
|
|
2812
|
+
*
|
|
2813
|
+
* ponytail: linear scan over the configured recorders. The estate has one; if
|
|
2814
|
+
* it ever has hundreds, build the reverse index once at module load.
|
|
2815
|
+
*/
|
|
2816
|
+
declare function relayForRecorder(recorderHost: string | undefined, recorderPort: number | undefined, devices?: Record<string, CameraDevice>): string | null;
|
|
2817
|
+
/**
|
|
2818
|
+
* Permission strings that may SET UP a camera.
|
|
2819
|
+
*
|
|
2820
|
+
* Verbatim production spelling, and the same string the web form already gates
|
|
2821
|
+
* the CCTV panel on (`useSettingsPermission.ts`), so the server enforces what
|
|
2822
|
+
* the client has always drawn rather than a second opinion invented here.
|
|
2823
|
+
*/
|
|
2824
|
+
declare const CAMERA_SETUP_PERMISSIONS: string[];
|
|
2825
|
+
/**
|
|
2826
|
+
* The ANPR half of the same panel.
|
|
2827
|
+
*
|
|
2828
|
+
* `POST`/`PATCH`/`DELETE /site-cameras` is ONE endpoint serving two panels, and
|
|
2829
|
+
* the Settings page draws them on two different strings: the CCTV panel on
|
|
2830
|
+
* `manage-cctv-camera`, the ANPR panel on `manage-anpr-camera`
|
|
2831
|
+
* (`SiteSettings.vue:79` and `:121`). Enforcing only the CCTV string would
|
|
2832
|
+
* refuse a role provisioned to manage ANPR and nothing else — so the server
|
|
2833
|
+
* asks the same question the client asked before it drew the button.
|
|
2834
|
+
*/
|
|
2835
|
+
declare const CAMERA_ANPR_PERMISSIONS: string[];
|
|
2836
|
+
/**
|
|
2837
|
+
* Which of the two a write needs, from the camera's own `type`.
|
|
2838
|
+
*
|
|
2839
|
+
* Anything that is not ANPR is treated as CCTV: `type` is validated to
|
|
2840
|
+
* `ip | anpr` by the model, and defaulting an unrecognised value to the CCTV
|
|
2841
|
+
* string fails towards asking for a permission rather than towards asking for
|
|
2842
|
+
* none.
|
|
2843
|
+
*/
|
|
2844
|
+
declare function cameraManagePermissions(type: unknown): Array<string>;
|
|
2845
|
+
/**
|
|
2846
|
+
* A "Test this camera" button is exactly the thing that locks a recorder: press
|
|
2847
|
+
* it four times with a wrong credential and V3.37 §4.7.x takes the account away
|
|
2848
|
+
* for half an hour — on a unit that in this estate also runs ANPR and a barrier.
|
|
2849
|
+
*
|
|
2850
|
+
* So a test is rationed twice over, before it can be attempted at all: not the
|
|
2851
|
+
* same camera twice inside `MIN_INTERVAL`, and not more than `ROUND_LIMIT`
|
|
2852
|
+
* against one recorder inside `ROUND_SECONDS`. Both sit far below the device's
|
|
2853
|
+
* own 3-in-30-seconds trigger, and they are checked BEFORE the shared
|
|
2854
|
+
* authentication budget is touched — so an impatient user runs out of tests
|
|
2855
|
+
* long before the recorder runs out of patience.
|
|
2856
|
+
*/
|
|
2857
|
+
declare const CAMERA_TEST_MIN_INTERVAL_SECONDS = 15;
|
|
2858
|
+
declare const CAMERA_TEST_ROUND_LIMIT = 4;
|
|
2859
|
+
declare const CAMERA_TEST_ROUND_SECONDS = 300;
|
|
2860
|
+
/** What a test can conclude. One of these, always, and never a stack trace. */
|
|
2861
|
+
type CameraTestStatus = "working" | "no-video" | "credential-refused" | "unreachable" | "cannot-test";
|
|
2862
|
+
/** What the setup form was asked for, before anything is derived from it. */
|
|
2863
|
+
type CameraAddressInput = {
|
|
2864
|
+
recorderHost?: string;
|
|
2865
|
+
recorderPort?: number | string;
|
|
2866
|
+
channel?: number | string;
|
|
2867
|
+
};
|
|
2868
|
+
/**
|
|
2869
|
+
* Turn what a person can read off a recorder into the address the product
|
|
2870
|
+
* stores — or say, in their words, why it cannot be done.
|
|
2871
|
+
*
|
|
2872
|
+
* This is the whole point of the guided form. The stored address is a relay
|
|
2873
|
+
* player page (`https://<relay-authority>/<channel>`), which nothing printed on
|
|
2874
|
+
* a camera will ever tell you; the server knows which relay carries which
|
|
2875
|
+
* recorder, so the server builds it. The person supplies the recorder and the
|
|
2876
|
+
* channel, which are on a label and in the recorder's own channel list.
|
|
2877
|
+
*
|
|
2878
|
+
* A refusal is a sentence for the person at the form, never a code and never an
|
|
2879
|
+
* address: an unrecognised recorder means somebody has to connect it to the
|
|
2880
|
+
* video service, and that is a request to their technical team, not a retry.
|
|
2881
|
+
*/
|
|
2882
|
+
declare function deriveCameraHost(input: CameraAddressInput, devices?: Record<string, CameraDevice>): {
|
|
2883
|
+
host: string;
|
|
2884
|
+
} | {
|
|
2885
|
+
refusal: string;
|
|
2886
|
+
};
|
|
2887
|
+
/**
|
|
2888
|
+
* The RTSP URL for one channel. **Carries the credential — never log it, never
|
|
2889
|
+
* return it, never put it in an error message.**
|
|
2890
|
+
*
|
|
2891
|
+
* The path is the recorder's own (`/cam/realmonitor`), which is what the CCTV
|
|
2892
|
+
* relay has always used; `subtype=1` is the low-bitrate substream and is what a
|
|
2893
|
+
* wall tile wants, `subtype=0` is the full-resolution main stream and is what an
|
|
2894
|
+
* evidence capture wants.
|
|
2895
|
+
*/
|
|
2896
|
+
declare function rtspUrl(device: CameraDevice, channel: number, subtype?: 0 | 1): string;
|
|
2897
|
+
/**
|
|
2898
|
+
* ffmpeg arguments for "one frame, as JPEG, on stdout".
|
|
2899
|
+
*
|
|
2900
|
+
* Separated from the spawn so the arguments are testable without a camera, and
|
|
2901
|
+
* kept deliberately small: TCP transport (the relay uses it and UDP loses frames
|
|
2902
|
+
* across the internet), a single frame, no audio, and nothing that could write
|
|
2903
|
+
* to the device — RTSP `PLAY` is a read.
|
|
2904
|
+
*/
|
|
2905
|
+
declare function ffmpegFrameArgs(url: string): Array<string>;
|
|
2906
|
+
/**
|
|
2907
|
+
* Measured against the live recorder on 2026-08-10: a substream frame arrives in
|
|
2908
|
+
* 7–9 s (RTSP setup plus the wait for a keyframe), three concurrent pulls showed
|
|
2909
|
+
* no degradation. The old 8 s HTTP budget would have timed out most frames, so
|
|
2910
|
+
* this is a separate, larger budget rather than a reuse of it.
|
|
2911
|
+
*/
|
|
2912
|
+
declare const CAMERA_RTSP_TIMEOUT_MS = 15000;
|
|
2913
|
+
/** `ffmpeg` on PATH by default; overridable where the host keeps it elsewhere. */
|
|
2914
|
+
declare function ffmpegPath(env?: Record<string, string | undefined>): string;
|
|
2915
|
+
/** §4.4.2, p.63 — `type=0` is "from the front end", i.e. the live picture. */
|
|
2916
|
+
declare function snapshotEndpoint(channel?: number): string;
|
|
2917
|
+
/** §4.6.14, p.114 — the cheapest call that completes a full digest handshake. */
|
|
2918
|
+
declare const SOFTWARE_VERSION_ENDPOINT = "/cgi-bin/magicBox.cgi?action=getSoftwareVersion";
|
|
2919
|
+
/** §4.6.2, p.106 — read-only. `setCurrentTime` (§4.6.3) is a write and is not ours. */
|
|
2920
|
+
declare const CURRENT_TIME_ENDPOINT = "/cgi-bin/global.cgi?action=getCurrentTime";
|
|
2921
|
+
/**
|
|
2922
|
+
* PTZ movement codes we are willing to send (§8.1.5, p.297).
|
|
2923
|
+
*
|
|
2924
|
+
* An allow-list, not a pass-through. The full `code` set in §8.1 also covers
|
|
2925
|
+
* presets, tours and patterns — those WRITE device configuration, and this
|
|
2926
|
+
* integration issues no configuration writes to any device.
|
|
2927
|
+
*/
|
|
2928
|
+
declare const PTZ_ALLOWED_CODES: string[];
|
|
2929
|
+
declare const PTZ_ALLOWED_ACTIONS: string[];
|
|
2930
|
+
/**
|
|
2931
|
+
* §8.1.5, p.297. Every value is percent-encoded — the same class of defect
|
|
2932
|
+
* `iservice365-core` #1803 fixed on the plate endpoints, where an unencoded
|
|
2933
|
+
* value silently changed the request the device saw.
|
|
2934
|
+
*/
|
|
2935
|
+
declare function ptzEndpoint(params: {
|
|
2936
|
+
action: string;
|
|
2937
|
+
channel?: number;
|
|
2938
|
+
code: string;
|
|
2939
|
+
speed?: number;
|
|
2940
|
+
}): string;
|
|
2941
|
+
/** §8.1.5 speeds run 1..8. Anything else is coerced, never passed through. */
|
|
2942
|
+
declare function clampPtzSpeed(speed: unknown): number;
|
|
2943
|
+
/** `version=3.140.0000000.0\nBuildDate=...` → `3.140.0000000.0`. */
|
|
2944
|
+
declare function parseSoftwareVersion(body: string): string | null;
|
|
2945
|
+
/** `result=2026-08-09 21:30:00` → the same string. */
|
|
2946
|
+
declare function parseDeviceTime(body: string): string | null;
|
|
2947
|
+
/**
|
|
2948
|
+
* How far the camera's clock is from ours, in seconds.
|
|
2949
|
+
*
|
|
2950
|
+
* The device reports LOCAL time with no offset, and the estate runs on Singapore
|
|
2951
|
+
* time (the product-wide rule), so it is compared against a fixed +8h — never
|
|
2952
|
+
* against the API host's own timezone, which is how the patrol-log day windows
|
|
2953
|
+
* went wrong in the first place.
|
|
2954
|
+
*
|
|
2955
|
+
* `null` when the device did not give a parseable time; a drifted clock and an
|
|
2956
|
+
* unreadable one are different facts and must not collapse into "0".
|
|
2957
|
+
*/
|
|
2958
|
+
declare function clockDriftSeconds(deviceTime: string | null, now: Date): number | null;
|
|
2959
|
+
/**
|
|
2960
|
+
* A camera is "healthy" when it answered at all. Firmware and clock are extra
|
|
2961
|
+
* detail; reachability is the signal the guardhouse actually needs, because
|
|
2962
|
+
* today `site.cameras.status` is OUR field and never the device's.
|
|
2963
|
+
*
|
|
2964
|
+
* A drift beyond a minute is called out separately: ANPR transactions are
|
|
2965
|
+
* timestamped from the device, so a drifted clock puts events in the wrong place
|
|
2966
|
+
* in the timeline and nothing currently notices.
|
|
2967
|
+
*/
|
|
2968
|
+
declare const CLOCK_DRIFT_WARN_SECONDS = 60;
|
|
2969
|
+
declare function cameraHealthSummary(params: {
|
|
2970
|
+
reachable: boolean;
|
|
2971
|
+
driftSeconds: number | null;
|
|
2972
|
+
}): "ok" | "drifted" | "unreachable";
|
|
2973
|
+
/**
|
|
2974
|
+
* Hard ceiling on a proxied picture.
|
|
2975
|
+
*
|
|
2976
|
+
* The device sits on the public internet, so an unbounded read is a way to hang
|
|
2977
|
+
* an API worker. 8 MB clears a 4K JPEG with room to spare and stops well short of
|
|
2978
|
+
* anything that could only be a fault or a hostile response.
|
|
2979
|
+
*
|
|
2980
|
+
* ponytail: checked after the response is buffered, not streamed with a running
|
|
2981
|
+
* counter — the request timeout already bounds how long a body can arrive for.
|
|
2982
|
+
* Move to a streaming counter if a device is ever found that trickles.
|
|
2983
|
+
*/
|
|
2984
|
+
declare const CAMERA_SNAPSHOT_MAX_BYTES: number;
|
|
2985
|
+
/** Short, because this call sits on a guard's screen and a camera may be down. */
|
|
2986
|
+
declare const CAMERA_REQUEST_TIMEOUT_MS = 8000;
|
|
2987
|
+
/**
|
|
2988
|
+
* Server-side snapshot cache, in seconds.
|
|
2989
|
+
*
|
|
2990
|
+
* The single most important number here. V3.37 does not document how many
|
|
2991
|
+
* concurrent pulls a unit tolerates (searched — it is simply absent), so N guards
|
|
2992
|
+
* watching one camera must cost ONE device request, not N.
|
|
2993
|
+
*/
|
|
2994
|
+
declare const CAMERA_SNAPSHOT_CACHE_SECONDS = 2;
|
|
2995
|
+
/**
|
|
2996
|
+
* Fields of a camera record that may cross the wire.
|
|
2997
|
+
*
|
|
2998
|
+
* Still an allow-list, not a delete-list: `username` and `password` must never
|
|
2999
|
+
* reach a client or a log, and a future field added to the model must be opted
|
|
3000
|
+
* IN rather than remembered about.
|
|
3001
|
+
*
|
|
3002
|
+
* ## Why `host` is now in it, for `ip` cameras only
|
|
3003
|
+
*
|
|
3004
|
+
* For a `type: "ip"` camera the stored `host` is **not** a device address and
|
|
3005
|
+
* **not** a credential — it is the video relay's own player-page URL, and
|
|
3006
|
+
* putting it in a WebView is how the live security app has shown motion video
|
|
3007
|
+
* for months (traced end to end, 2026-08-10). Stripping it here is what stops a
|
|
3008
|
+
* client from rendering the one path that demonstrably works.
|
|
3009
|
+
*
|
|
3010
|
+
* **It is not a new disclosure.** `GET /site-cameras` already returns `host` to
|
|
3011
|
+
* every authenticated caller — `site-camera.repo.ts` projects `{ password: 0 }`
|
|
3012
|
+
* and nothing else — which is exactly where the legacy app reads it from. This
|
|
3013
|
+
* makes the wall consistent with the endpoint next to it rather than widening
|
|
3014
|
+
* anything.
|
|
3015
|
+
*
|
|
3016
|
+
* **`anpr` is excluded and that is the whole reason this is conditional.** An
|
|
3017
|
+
* ANPR record's `host` IS a real device endpoint, on a unit that also has a real
|
|
3018
|
+
* `username` beside it, so handing one to a client would be a genuine leak. No
|
|
3019
|
+
* patrol or CCTV path ever loads an ANPR record — but the allow-list must hold
|
|
3020
|
+
* on its own, not because of a filter somewhere else.
|
|
3021
|
+
*/
|
|
3022
|
+
declare function publicCameraFields(camera: Record<string, any>): Record<string, any>;
|
|
3023
|
+
/**
|
|
3024
|
+
* Tuning for a multi-camera wall, read from the environment.
|
|
3025
|
+
*
|
|
3026
|
+
* **Every number here is a guess that must be measured against a real device**,
|
|
3027
|
+
* which is exactly why the client is not allowed to hold its own copy: the wall
|
|
3028
|
+
* endpoint hands these to the app, so an environment that finds its cameras
|
|
3029
|
+
* cannot take nine simultaneous pulls is retuned by a deployment variable and not
|
|
3030
|
+
* by an app-store release.
|
|
3031
|
+
*
|
|
3032
|
+
* V3.37 documents no concurrent-connection limit for any unit — it is absent, not
|
|
3033
|
+
* generous — so the defaults are deliberately slow and small.
|
|
3034
|
+
*/
|
|
3035
|
+
declare function wallConfig(env?: Record<string, string | undefined>): {
|
|
3036
|
+
/** A wall is situational awareness, not evidence. 5 s per tile is watchable. */
|
|
3037
|
+
snapshotPollMs: number;
|
|
3038
|
+
/**
|
|
3039
|
+
* Single-camera view. Matches `CAMERA_SNAPSHOT_CACHE_SECONDS` exactly —
|
|
3040
|
+
* polling faster than the cache costs round trips and never device requests,
|
|
3041
|
+
* so there is no point going below it and real harm in going far below it.
|
|
3042
|
+
*/
|
|
3043
|
+
singlePollMs: number;
|
|
3044
|
+
/** The 3x3 ceiling, enforced here as well as in the client's layout list. */
|
|
3045
|
+
maxTiles: number;
|
|
3046
|
+
/** How many cameras a health sweep probes at once. */
|
|
3047
|
+
maxConcurrentProbes: number;
|
|
3048
|
+
/** Health changes slowly; N supervisors on one wall should be one probe. */
|
|
3049
|
+
healthCacheSeconds: number;
|
|
3050
|
+
};
|
|
3051
|
+
/**
|
|
3052
|
+
* Runs `worker` over `items`, at most `limit` at a time.
|
|
3053
|
+
*
|
|
3054
|
+
* The whole reason the wall has a backend change at all. Nine tiles asking for
|
|
3055
|
+
* health separately is eighteen device requests fired at once; this makes it four
|
|
3056
|
+
* in flight regardless of how many tiles the supervisor opens.
|
|
3057
|
+
*
|
|
3058
|
+
* ponytail: index-cursor over N workers rather than a queue library — the input is
|
|
3059
|
+
* bounded by `maxTiles` and this is the entire semantics needed.
|
|
3060
|
+
*/
|
|
3061
|
+
declare function mapWithLimit<T, R>(items: Array<T>, limit: number, worker: (item: T) => Promise<R>): Promise<Array<R>>;
|
|
3062
|
+
|
|
3063
|
+
/**
|
|
3064
|
+
* What a camera can actually do RIGHT NOW, and which transport would do it.
|
|
3065
|
+
*
|
|
3066
|
+
* ## Why this file exists
|
|
3067
|
+
*
|
|
3068
|
+
* The estate has three different ways to reach a camera and they do not overlap:
|
|
3069
|
+
*
|
|
3070
|
+
* | Transport | What it carries | Proven today? |
|
|
3071
|
+
* |---|---|---|
|
|
3072
|
+
* | `RELAY_PLAYER` | the stored player-page URL, rendered in a WebView — one-way MPEG1 over a WebSocket | **YES** — this is how the live product has shown CCTV for months |
|
|
3073
|
+
* | `RTSP_FRAME` | one `ffmpeg` still off the recorder's RTSP stream | **YES** — measured against the live recorder, 2026-08-10 |
|
|
3074
|
+
* | `DEVICE_HTTP` | the camera's own CGI API — PTZ, presets, recordings, events, device info | **NO** — written, disabled, and unreachable from our hosts today (80/443/37777 time out; only 554 answers) |
|
|
3075
|
+
*
|
|
3076
|
+
* A client cannot be expected to know any of that. So the server computes it,
|
|
3077
|
+
* per camera, per capability, and hands back a descriptor the UI renders itself
|
|
3078
|
+
* from — with a machine-readable reason whenever the answer is no. **That
|
|
3079
|
+
* descriptor is the contract that lets a capability light up later by
|
|
3080
|
+
* configuration instead of by a code change.**
|
|
3081
|
+
*
|
|
3082
|
+
* ## Three states, never two
|
|
3083
|
+
*
|
|
3084
|
+
* `supported` / `unsupported` / `unknown`. `unknown` is load-bearing: a camera
|
|
3085
|
+
* whose control interface we have never been allowed to ask is NOT the same as a
|
|
3086
|
+
* camera that has told us it cannot pan. Collapsing the two is how a UI ends up
|
|
3087
|
+
* hiding a feature that works, or offering one that does not.
|
|
3088
|
+
*
|
|
3089
|
+
* Nothing in this file performs I/O, so the whole rule set is assertable in a
|
|
3090
|
+
* test without a camera, a recorder, a network or a database.
|
|
3091
|
+
*
|
|
3092
|
+
* Section references are to Dahua HTTP API V3.37.
|
|
3093
|
+
*/
|
|
3094
|
+
|
|
3095
|
+
/**
|
|
3096
|
+
* Every capability the UI may ask about.
|
|
3097
|
+
*
|
|
3098
|
+
* A fixed list rather than an open string, because a client that renders itself
|
|
3099
|
+
* from this descriptor has to be able to exhaust it. Adding one is a deliberate
|
|
3100
|
+
* change here plus a transport that declares it.
|
|
3101
|
+
*/
|
|
3102
|
+
declare const CAMERA_CAPABILITIES: readonly ["liveVideo", "stillFrame", "digitalZoom", "ptz", "presets", "playback", "events", "audio", "deviceInfo"];
|
|
3103
|
+
type CameraCapability = (typeof CAMERA_CAPABILITIES)[number];
|
|
3104
|
+
type CameraCapabilityState = "supported" | "unsupported" | "unknown";
|
|
3105
|
+
/** Transport ids. Strings, not an enum, so a new one can be registered. */
|
|
3106
|
+
declare const TRANSPORT_RELAY_PLAYER = "RELAY_PLAYER";
|
|
3107
|
+
declare const TRANSPORT_RTSP_FRAME = "RTSP_FRAME";
|
|
3108
|
+
declare const TRANSPORT_DEVICE_HTTP = "DEVICE_HTTP";
|
|
3109
|
+
/**
|
|
3110
|
+
* Machine-readable reasons, each with the one sentence a UI may show.
|
|
3111
|
+
*
|
|
3112
|
+
* The CODE is the contract — a client switches on it and never parses prose.
|
|
3113
|
+
* The sentence is here so that a client which has nothing better to show has
|
|
3114
|
+
* something honest to show, and so the same wording cannot drift between two
|
|
3115
|
+
* screens.
|
|
3116
|
+
*
|
|
3117
|
+
* Four of these are worded identically to `camera-view.util`'s refusal
|
|
3118
|
+
* sentences, on purpose: the mobile app already displays those strings, and a
|
|
3119
|
+
* camera must not explain itself two different ways depending on which field
|
|
3120
|
+
* was read. A test pins them equal.
|
|
3121
|
+
*/
|
|
3122
|
+
declare const CAMERA_CAPABILITY_REASONS: {
|
|
3123
|
+
readonly "not-patrol-cctv-camera": "This is an ANPR unit. ANPR belongs to visitor and vehicle management; Virtual Patrol and CCTV use IP cameras only.";
|
|
3124
|
+
readonly "camera-inactive": "This camera is not active.";
|
|
3125
|
+
readonly "no-address": "This camera has no address configured.";
|
|
3126
|
+
readonly "invalid-address": "This camera's address is not a valid address.";
|
|
3127
|
+
readonly "not-a-relay-player-url": "This camera's address is not a live-video page address.";
|
|
3128
|
+
readonly "no-recorder-configured": "No recorder is configured for this camera's relay.";
|
|
3129
|
+
readonly "no-channel-in-address": "This camera's address has no channel, so we cannot tell which stream it is.";
|
|
3130
|
+
readonly "device-http-not-configured": "No direct connection to this camera's recorder is configured on this server.";
|
|
3131
|
+
readonly "device-http-disabled": "Direct camera access is switched off on this server.";
|
|
3132
|
+
readonly "device-http-unreachable": "The camera's own control interface did not answer.";
|
|
3133
|
+
readonly "device-http-locked-out": "Too many rejected sign-ins: further attempts are being held back so the recorder's account is not locked.";
|
|
3134
|
+
readonly "device-not-probed": "This camera has not been asked what it can do yet.";
|
|
3135
|
+
readonly "device-no-ptz": "This camera does not move.";
|
|
3136
|
+
readonly "control-not-enabled": "Camera control is switched off on this server.";
|
|
3137
|
+
readonly "no-transport": "Nothing on this server can do that yet.";
|
|
3138
|
+
};
|
|
3139
|
+
type CameraCapabilityReason = keyof typeof CAMERA_CAPABILITY_REASONS;
|
|
3140
|
+
/** One capability's answer. `transport` is `null` whenever nothing can serve it. */
|
|
3141
|
+
type CameraCapabilityEntry = {
|
|
3142
|
+
state: CameraCapabilityState;
|
|
3143
|
+
transport: string | null;
|
|
3144
|
+
reason: CameraCapabilityReason | null;
|
|
3145
|
+
/** The sentence for `reason`, so a client never has to hold the table. */
|
|
3146
|
+
detail: string | null;
|
|
3147
|
+
};
|
|
3148
|
+
type CameraCapabilityDescriptor = Record<CameraCapability, CameraCapabilityEntry>;
|
|
3149
|
+
/**
|
|
3150
|
+
* A recorder's own HTTP interface, resolved from configuration.
|
|
3151
|
+
*
|
|
3152
|
+
* **Keyed by the same relay authority as `CAMERA_RTSP_DEVICES`**, because that
|
|
3153
|
+
* is the only stable identifier a camera record carries (`site.cameras.host` is
|
|
3154
|
+
* the relay's player page; its authority names the deployment and its last path
|
|
3155
|
+
* segment is the channel — see `camera-view.util`).
|
|
3156
|
+
*
|
|
3157
|
+
* The credential is **referenced, never embedded**: `credentialRef` names an
|
|
3158
|
+
* environment variable holding `username:password`. So the configuration that
|
|
3159
|
+
* enables device access can be reviewed, diffed and pasted into a PR
|
|
3160
|
+
* description without carrying a secret, and the secret itself lives where
|
|
3161
|
+
* every other secret on the host lives.
|
|
3162
|
+
*/
|
|
3163
|
+
type DeviceHttpTarget = {
|
|
3164
|
+
authority: string;
|
|
3165
|
+
/** Origin only — scheme, host, optional port. No path, no query. */
|
|
3166
|
+
baseUrl: string;
|
|
3167
|
+
username: string;
|
|
3168
|
+
password: string;
|
|
3169
|
+
/** `CAMERA_DEVICE_HTTP_ENABLED`. Nothing contacts a device while this is off. */
|
|
3170
|
+
enabled: boolean;
|
|
3171
|
+
/** `CAMERA_DEVICE_CONTROL_ENABLED`. Mutating operations only. */
|
|
3172
|
+
controlEnabled: boolean;
|
|
3173
|
+
timeoutMs: number;
|
|
3174
|
+
probeTtlSeconds: number;
|
|
3175
|
+
};
|
|
3176
|
+
type Env = Record<string, string | undefined>;
|
|
3177
|
+
/** Both flags are opt-IN. An unset or misspelt value is OFF, never on. */
|
|
3178
|
+
declare function deviceHttpEnabled(source?: Env): boolean;
|
|
3179
|
+
/**
|
|
3180
|
+
* The mutating switch, and it is deliberately separate from the one above.
|
|
3181
|
+
*
|
|
3182
|
+
* Reading a device (version, snapshot, recording list, events) and moving a
|
|
3183
|
+
* device (PTZ, preset recall) are different decisions with different blast
|
|
3184
|
+
* radii, so they are different variables. Turning reads on must not arm motors.
|
|
3185
|
+
*
|
|
3186
|
+
* It also cannot be on by itself: control requires device access as well.
|
|
3187
|
+
*/
|
|
3188
|
+
declare function deviceControlEnabled(source?: Env): boolean;
|
|
3189
|
+
declare function deviceHttpTimeoutMs(source?: Env): number;
|
|
3190
|
+
/**
|
|
3191
|
+
* How long a capability probe is trusted for.
|
|
3192
|
+
*
|
|
3193
|
+
* Long by the standards of this file — 15 minutes — because what it answers
|
|
3194
|
+
* ("is this a PTZ unit, what firmware, does it answer at all") changes when an
|
|
3195
|
+
* installer visits, not when a guard looks at a screen. A short TTL here buys
|
|
3196
|
+
* nothing and spends requests against a device with a 3-failures lockout.
|
|
3197
|
+
*/
|
|
3198
|
+
declare function deviceProbeTtlSeconds(source?: Env): number;
|
|
3199
|
+
/**
|
|
3200
|
+
* `CAMERA_DEVICE_HTTP` — a JSON object keyed by relay authority:
|
|
3201
|
+
*
|
|
3202
|
+
* ```
|
|
3203
|
+
* {"<relay-authority>":{"baseUrl":"https://<recorder-host>:443",
|
|
3204
|
+
* "credentialRef":"CAMERA_DEVICE_CRED_MAIN"}}
|
|
3205
|
+
* ```
|
|
3206
|
+
*
|
|
3207
|
+
* …plus `CAMERA_DEVICE_CRED_MAIN=<user>:<password>` set separately.
|
|
3208
|
+
*
|
|
3209
|
+
* Returns the valid entries AND the reasons any entry was rejected, because a
|
|
3210
|
+
* silently-dropped recorder is the failure mode that costs an afternoon: the
|
|
3211
|
+
* caller logs the errors once at startup, and every camera on a rejected entry
|
|
3212
|
+
* then reports `device-http-not-configured` truthfully rather than hanging.
|
|
3213
|
+
*
|
|
3214
|
+
* A malformed variable yields no targets at all — the same posture as
|
|
3215
|
+
* `cameraDevices()`, and far better than a half-parsed device map.
|
|
3216
|
+
*/
|
|
3217
|
+
declare function deviceHttpTargets(source?: Env): {
|
|
3218
|
+
targets: Record<string, DeviceHttpTarget>;
|
|
3219
|
+
errors: Array<string>;
|
|
3220
|
+
};
|
|
3221
|
+
/** The device-HTTP target for one camera record, or `null` when there is none. */
|
|
3222
|
+
declare function resolveDeviceHttp(host: string | undefined, targets?: Record<string, DeviceHttpTarget>): DeviceHttpTarget | null;
|
|
3223
|
+
/**
|
|
3224
|
+
* The cached answer to "we asked the device what it is".
|
|
3225
|
+
*
|
|
3226
|
+
* `ptz: null` and `reachable` are separate facts on purpose — a device can
|
|
3227
|
+
* answer while refusing to say whether it pans (older firmware, or a protocol
|
|
3228
|
+
* with no capability query), and that is an `unknown`, not a `no`.
|
|
3229
|
+
*/
|
|
3230
|
+
type DeviceProbeResult = {
|
|
3231
|
+
reachable: boolean;
|
|
3232
|
+
/** True when the failure budget is spent; nothing was sent. */
|
|
3233
|
+
lockedOut?: boolean;
|
|
3234
|
+
ptz?: boolean | null;
|
|
3235
|
+
presets?: boolean | null;
|
|
3236
|
+
softwareVersion?: string | null;
|
|
3237
|
+
deviceType?: string | null;
|
|
3238
|
+
probedAt?: string;
|
|
3239
|
+
};
|
|
3240
|
+
type CameraCapabilityContext = {
|
|
3241
|
+
camera: {
|
|
3242
|
+
type?: string;
|
|
3243
|
+
status?: string;
|
|
3244
|
+
host?: string;
|
|
3245
|
+
} | null;
|
|
3246
|
+
/** RTSP recorders, from `CAMERA_RTSP_DEVICES`. */
|
|
3247
|
+
rtspDevices?: Record<string, CameraDevice>;
|
|
3248
|
+
/** Resolved device-HTTP target for this camera, or `null`. */
|
|
3249
|
+
deviceHttp?: DeviceHttpTarget | null;
|
|
3250
|
+
/** A CACHED probe. `null`/absent means "never asked" → `unknown`, not `no`. */
|
|
3251
|
+
probe?: DeviceProbeResult | null;
|
|
3252
|
+
};
|
|
3253
|
+
type Decision = {
|
|
3254
|
+
state: CameraCapabilityState;
|
|
3255
|
+
reason: CameraCapabilityReason | null;
|
|
3256
|
+
};
|
|
3257
|
+
/**
|
|
3258
|
+
* A way of reaching a camera, and what it can do through that way.
|
|
3259
|
+
*
|
|
3260
|
+
* `evaluate` is asked once per capability it declares. Registration order is
|
|
3261
|
+
* preference order, so the first transport that says `supported` wins — which
|
|
3262
|
+
* is how one camera ends up serving live video over `RELAY_PLAYER` and evidence
|
|
3263
|
+
* stills over `RTSP_FRAME` at the same time, with nothing choosing between them
|
|
3264
|
+
* by hand.
|
|
3265
|
+
*/
|
|
3266
|
+
type CameraTransport = {
|
|
3267
|
+
id: string;
|
|
3268
|
+
provides: ReadonlyArray<CameraCapability>;
|
|
3269
|
+
evaluate: (capability: CameraCapability, ctx: CameraCapabilityContext) => Decision;
|
|
3270
|
+
};
|
|
3271
|
+
/**
|
|
3272
|
+
* Is this stored address a video-relay player page?
|
|
3273
|
+
*
|
|
3274
|
+
* The admin form ENFORCES `https://<domain>/<one segment>` for a CCTV camera
|
|
3275
|
+
* (`layer-common` `CameraForm.vue`), and all twelve real records match it. The
|
|
3276
|
+
* three that do not are two `example.com` placeholders and one bare authority
|
|
3277
|
+
* with no channel — so this predicate separates "a URL a WebView can render"
|
|
3278
|
+
* from "a record somebody has not finished", without contacting anything.
|
|
3279
|
+
*/
|
|
3280
|
+
declare function isRelayPlayerUrl(host: string | undefined): boolean;
|
|
3281
|
+
/** The registry, read-only to callers. */
|
|
3282
|
+
declare function cameraTransports(): ReadonlyArray<CameraTransport>;
|
|
3283
|
+
/**
|
|
3284
|
+
* Add or replace a transport.
|
|
3285
|
+
*
|
|
3286
|
+
* The point of the registry: an HLS relay, a MediaMTX playback URL or an audio
|
|
3287
|
+
* path is a new entry here and a new `provides` list. **No service, controller
|
|
3288
|
+
* or client changes to add one** — a capability that no transport declares
|
|
3289
|
+
* already answers `no-transport`, and starts answering `supported` the moment
|
|
3290
|
+
* something claims it.
|
|
3291
|
+
*/
|
|
3292
|
+
declare function registerCameraTransport(transport: CameraTransport): void;
|
|
3293
|
+
/** Test seam: restore the built-in registry. */
|
|
3294
|
+
declare function resetCameraTransports(): void;
|
|
3295
|
+
type CameraCapabilityTrace = Array<{
|
|
3296
|
+
capability: CameraCapability;
|
|
3297
|
+
transport: string | null;
|
|
3298
|
+
state: CameraCapabilityState;
|
|
3299
|
+
reason: CameraCapabilityReason | null;
|
|
3300
|
+
}>;
|
|
3301
|
+
/**
|
|
3302
|
+
* The descriptor for one camera, plus the trace of how each answer was reached.
|
|
3303
|
+
*
|
|
3304
|
+
* Selection per capability: ask every transport that declares it, in
|
|
3305
|
+
* registration order, and take the first `supported`. Failing that the first
|
|
3306
|
+
* `unknown` — because "we have not asked" outranks "this way cannot" when
|
|
3307
|
+
* telling someone what to do next. Failing that the first `unsupported`, whose
|
|
3308
|
+
* reason belongs to the most-preferred transport and is therefore the most
|
|
3309
|
+
* actionable one. A capability no transport declares is `no-transport`.
|
|
3310
|
+
*
|
|
3311
|
+
* The trace is for the server's log. It names capabilities, transport ids and
|
|
3312
|
+
* reason codes only — **no host, no credential, no address** — so it is safe to
|
|
3313
|
+
* write down, which is the point of having it at all: "why is PTZ off on this
|
|
3314
|
+
* camera" becomes one grep instead of an afternoon.
|
|
3315
|
+
*/
|
|
3316
|
+
declare function describeCameraCapabilities(ctx: CameraCapabilityContext, registry?: ReadonlyArray<CameraTransport>): {
|
|
3317
|
+
capabilities: CameraCapabilityDescriptor;
|
|
3318
|
+
trace: CameraCapabilityTrace;
|
|
3319
|
+
};
|
|
3320
|
+
/**
|
|
3321
|
+
* The descriptor for a camera record, reading configuration from the
|
|
3322
|
+
* environment. The convenience the service actually calls.
|
|
3323
|
+
*
|
|
3324
|
+
* **`probe` is passed IN, never fetched here.** Nothing in this file may cause
|
|
3325
|
+
* a device request, so a list endpoint cannot start probing by accident — the
|
|
3326
|
+
* single rule that keeps a wall of nine tiles from becoming a burst of
|
|
3327
|
+
* authenticated requests against a device with a lockout policy.
|
|
3328
|
+
*/
|
|
3329
|
+
declare function cameraCapabilitiesFor(params: {
|
|
3330
|
+
camera: {
|
|
3331
|
+
type?: string;
|
|
3332
|
+
status?: string;
|
|
3333
|
+
host?: string;
|
|
3334
|
+
} | null;
|
|
3335
|
+
probe?: DeviceProbeResult | null;
|
|
3336
|
+
rtspDevices?: Record<string, CameraDevice>;
|
|
3337
|
+
deviceHttpTargets?: Record<string, DeviceHttpTarget>;
|
|
3338
|
+
}): {
|
|
3339
|
+
capabilities: CameraCapabilityDescriptor;
|
|
3340
|
+
trace: CameraCapabilityTrace;
|
|
3341
|
+
};
|
|
3342
|
+
/** `true` when a camera has at least one capability that works right now. */
|
|
3343
|
+
declare function hasAnyCapability(descriptor: CameraCapabilityDescriptor): boolean;
|
|
3344
|
+
/** Kept for the wall's log line: `liveVideo=RELAY_PLAYER stillFrame=RTSP_FRAME …`. */
|
|
3345
|
+
declare function formatCapabilityTrace(trace: CameraCapabilityTrace): string;
|
|
3346
|
+
|
|
3347
|
+
/**
|
|
3348
|
+
* Camera functions for Virtual Patrol, proxied.
|
|
3349
|
+
*
|
|
3350
|
+
* ## Why this exists at all
|
|
3351
|
+
*
|
|
3352
|
+
* Dahua devices authenticate with digest and the cleartext password on EVERY
|
|
3353
|
+
* request (V3.37 §3.4). The specification offers no session, no API key and no
|
|
3354
|
+
* usable token — §4.1.5 mints one and never documents how to redeem it. So there
|
|
3355
|
+
* is no version of this feature in which the phone talks to the camera: the
|
|
3356
|
+
* credential would have to ship with the app.
|
|
3357
|
+
*
|
|
3358
|
+
* Everything here therefore runs server-side. The guard's ordinary session
|
|
3359
|
+
* authenticates them to US; we hold the camera credential and speak digest to the
|
|
3360
|
+
* device. The credential is never returned, never logged, and never appears in an
|
|
3361
|
+
* error message — `publicCameraFields` is an allow-list for exactly that reason.
|
|
3362
|
+
*
|
|
3363
|
+
* ## What is deliberately absent
|
|
3364
|
+
*
|
|
3365
|
+
* **No retry.** A failed camera call fails. The device locks an account for
|
|
3366
|
+
* 1800 s after 3 failures in 30 s (§4.7.x), and a retry loop on a user-facing
|
|
3367
|
+
* screen is precisely the defect `iservice365-core` #1803 fixed on the ANPR
|
|
3368
|
+
* listener. A snapshot that fails costs a guard one blank panel; a lockout costs
|
|
3369
|
+
* a site its ANPR and its barrier for half an hour.
|
|
3370
|
+
*
|
|
3371
|
+
* **No configuration write, no reboot, no barrier command.** The only
|
|
3372
|
+
* device-mutating call in this file is PTZ, and it is off unless explicitly
|
|
3373
|
+
* enabled.
|
|
3374
|
+
*
|
|
3375
|
+
* ## How a picture is actually fetched — measured, 2026-08-10
|
|
3376
|
+
*
|
|
3377
|
+
* The recorder these cameras live on is reachable on **RTSP (554) only**: its
|
|
3378
|
+
* HTTP interface (80/443) and the Dahua native port (37777) are not exposed,
|
|
3379
|
+
* verified by TCP connect from this workstation AND from the staging API host.
|
|
3380
|
+
* So `snapshot.cgi`, `magicBox.cgi`, `global.cgi` and PTZ — all HTTP CGI — cannot
|
|
3381
|
+
* be reached at all, and a snapshot has to come off the video stream.
|
|
3382
|
+
*
|
|
3383
|
+
* It therefore runs one `ffmpeg` per picture: connect, take a single frame,
|
|
3384
|
+
* encode JPEG, exit. Measured against the live recorder: a substream frame is
|
|
3385
|
+
* ~17–19 KB and arrives in 7–9 s; three concurrent pulls showed no degradation.
|
|
3386
|
+
* That latency is why the snapshot cache matters and why the RTSP budget is its
|
|
3387
|
+
* own, larger number.
|
|
3388
|
+
*
|
|
3389
|
+
* **ffmpeg's stderr is discarded, not piped** — the RTSP URL it echoes on failure
|
|
3390
|
+
* contains the recorder's credential, so the safest handling is for those bytes
|
|
3391
|
+
* never to exist in this process.
|
|
3392
|
+
*/
|
|
3393
|
+
declare function useCameraViewService(): {
|
|
3394
|
+
authorizeCamera: (params: {
|
|
3395
|
+
cameraId: string;
|
|
3396
|
+
userId?: string;
|
|
3397
|
+
permissions: Array<string>;
|
|
3398
|
+
}) => Promise<bson.Document>;
|
|
3399
|
+
entitleSite: (params: {
|
|
3400
|
+
siteId: string;
|
|
3401
|
+
userId?: string;
|
|
3402
|
+
}) => Promise<{
|
|
3403
|
+
site: mongodb.WithId<bson.Document> | null;
|
|
3404
|
+
siteObjectId: ObjectId;
|
|
3405
|
+
db: Db;
|
|
3406
|
+
memberships: (CameraMembership & {
|
|
3407
|
+
org?: ObjectId | undefined;
|
|
3408
|
+
})[];
|
|
3409
|
+
grant: CameraMembership;
|
|
3410
|
+
}>;
|
|
3411
|
+
authorizeSite: (params: {
|
|
3412
|
+
siteId: string;
|
|
3413
|
+
userId?: string;
|
|
3414
|
+
/**
|
|
3415
|
+
* Which permission this particular use of a site needs. Viewing is the
|
|
3416
|
+
* default because every existing caller views; setting a camera up is a
|
|
3417
|
+
* different, narrower right and passes its own list.
|
|
3418
|
+
*/
|
|
3419
|
+
permissions?: Array<string>;
|
|
3420
|
+
}) => Promise<{
|
|
3421
|
+
site: mongodb.WithId<bson.Document> | null;
|
|
3422
|
+
siteObjectId: ObjectId;
|
|
3423
|
+
db: Db;
|
|
3424
|
+
}>;
|
|
3425
|
+
testCameraAddress: (params: {
|
|
3426
|
+
siteId: string;
|
|
3427
|
+
userId?: string;
|
|
3428
|
+
host?: string;
|
|
3429
|
+
recorderHost?: string;
|
|
3430
|
+
recorderPort?: number | string;
|
|
3431
|
+
channel?: number | string;
|
|
3432
|
+
}) => Promise<{
|
|
3433
|
+
ok: boolean;
|
|
3434
|
+
status: CameraTestStatus;
|
|
3435
|
+
message: string;
|
|
3436
|
+
}>;
|
|
3437
|
+
getSnapshot: (params: {
|
|
3438
|
+
cameraId: string;
|
|
3439
|
+
userId?: string;
|
|
3440
|
+
/** Full-resolution main stream. For an evidence capture, not for a tile. */
|
|
3441
|
+
hd?: boolean;
|
|
3442
|
+
}) => Promise<{
|
|
3443
|
+
buffer: Buffer;
|
|
3444
|
+
cached: boolean;
|
|
3445
|
+
}>;
|
|
3446
|
+
captureSnapshot: (params: {
|
|
3447
|
+
cameraId: string;
|
|
3448
|
+
userId?: string;
|
|
3449
|
+
}) => Promise<{
|
|
3450
|
+
id: string;
|
|
3451
|
+
size: number;
|
|
3452
|
+
}>;
|
|
3453
|
+
getStatus: (params: {
|
|
3454
|
+
cameraId: string;
|
|
3455
|
+
userId?: string;
|
|
3456
|
+
}) => Promise<{
|
|
3457
|
+
reachable: boolean;
|
|
3458
|
+
health: "unsupported";
|
|
3459
|
+
reason: string;
|
|
3460
|
+
camera: Record<string, any>;
|
|
3461
|
+
snapshotSupported: boolean;
|
|
3462
|
+
capabilities: CameraCapabilityDescriptor;
|
|
3463
|
+
firmwareVersion: string | null;
|
|
3464
|
+
deviceTime: null;
|
|
3465
|
+
driftSeconds: null;
|
|
3466
|
+
detailUnavailableReason: string | null;
|
|
3467
|
+
} | {
|
|
3468
|
+
reachable: boolean;
|
|
3469
|
+
health: "unreachable" | "ok" | "drifted";
|
|
3470
|
+
reason: string | null;
|
|
3471
|
+
camera: Record<string, any>;
|
|
3472
|
+
snapshotSupported: boolean;
|
|
3473
|
+
capabilities: CameraCapabilityDescriptor;
|
|
3474
|
+
firmwareVersion: string | null;
|
|
3475
|
+
deviceTime: null;
|
|
3476
|
+
driftSeconds: null;
|
|
3477
|
+
detailUnavailableReason: string | null;
|
|
3478
|
+
}>;
|
|
3479
|
+
getSiteWall: (params: {
|
|
3480
|
+
siteId: string;
|
|
3481
|
+
userId?: string;
|
|
3482
|
+
}) => Promise<{
|
|
3483
|
+
site: {
|
|
3484
|
+
_id: ObjectId;
|
|
3485
|
+
name: any;
|
|
3486
|
+
};
|
|
3487
|
+
config: {
|
|
3488
|
+
snapshotPollMs: number;
|
|
3489
|
+
singlePollMs: number;
|
|
3490
|
+
maxTiles: number;
|
|
3491
|
+
maxConcurrentProbes: number;
|
|
3492
|
+
healthCacheSeconds: number;
|
|
3493
|
+
};
|
|
3494
|
+
cameras: {
|
|
3495
|
+
unavailableReason: string | null;
|
|
3496
|
+
capabilities: CameraCapabilityDescriptor;
|
|
3497
|
+
}[];
|
|
3498
|
+
}>;
|
|
3499
|
+
getSiteHealth: (params: {
|
|
3500
|
+
siteId: string;
|
|
3501
|
+
userId?: string;
|
|
3502
|
+
cameraIds: Array<string>;
|
|
3503
|
+
}) => Promise<{
|
|
3504
|
+
cameras: ({
|
|
3505
|
+
reachable: boolean;
|
|
3506
|
+
health: "unsupported";
|
|
3507
|
+
reason: string;
|
|
3508
|
+
capabilities: CameraCapabilityDescriptor;
|
|
3509
|
+
firmwareVersion: null;
|
|
3510
|
+
deviceTime: null;
|
|
3511
|
+
driftSeconds: null;
|
|
3512
|
+
detailUnavailableReason: string;
|
|
3513
|
+
lastFrameAt: string | null;
|
|
3514
|
+
unavailableReason: string | null;
|
|
3515
|
+
} | {
|
|
3516
|
+
reachable: boolean;
|
|
3517
|
+
health: "unreachable" | "ok" | "drifted";
|
|
3518
|
+
reason: string | null;
|
|
3519
|
+
capabilities: CameraCapabilityDescriptor;
|
|
3520
|
+
firmwareVersion: null;
|
|
3521
|
+
deviceTime: null;
|
|
3522
|
+
driftSeconds: null;
|
|
3523
|
+
detailUnavailableReason: string;
|
|
3524
|
+
lastFrameAt: string | null;
|
|
3525
|
+
unavailableReason: string | null;
|
|
3526
|
+
})[];
|
|
3527
|
+
}>;
|
|
3528
|
+
movePtz: (params: {
|
|
3529
|
+
cameraId: string;
|
|
3530
|
+
userId?: string;
|
|
3531
|
+
action: string;
|
|
3532
|
+
code: string;
|
|
3533
|
+
speed?: number;
|
|
3534
|
+
}) => Promise<{
|
|
3535
|
+
ok: boolean;
|
|
3536
|
+
}>;
|
|
3537
|
+
ptzEnabled: boolean;
|
|
3538
|
+
};
|
|
3539
|
+
|
|
3540
|
+
/**
|
|
3541
|
+
* Camera functions for Virtual Patrol.
|
|
3542
|
+
*
|
|
3543
|
+
* Every handler is mounted behind `requireAuth` and every one re-derives the
|
|
3544
|
+
* caller from the session — `req.user`, never a body or query field. The camera
|
|
3545
|
+
* id in the path selects a record; the service decides whether the caller may
|
|
3546
|
+
* have it.
|
|
3547
|
+
*/
|
|
3548
|
+
declare function useCameraViewController(): {
|
|
3549
|
+
snapshot: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
3550
|
+
capture: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
3551
|
+
status: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
3552
|
+
ptz: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
3553
|
+
capabilities: (_req: Request, res: Response) => Promise<void>;
|
|
3554
|
+
wall: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
3555
|
+
health: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
3556
|
+
test: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
3557
|
+
};
|
|
3558
|
+
|
|
2564
3559
|
type TCustomerSite = {
|
|
2565
3560
|
_id?: ObjectId;
|
|
2566
3561
|
name: string;
|
|
@@ -8187,4 +9182,4 @@ declare function useHidAmicoController(): {
|
|
|
8187
9182
|
finalizeIntercomCall: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
8188
9183
|
};
|
|
8189
9184
|
|
|
8190
|
-
export { ANPRMode, AccessTypeProps, AppServiceType, AssignCardConfig, BidStatus, BidType, BuildingLevelStatus, BuildingStatus, BulkCardUpdate, BulletinOrder, BulletinRecipient, BulletinSort, BulletinStatus, BulletinVideoOrder, BulletinVideoSort, Camera, CameraType, DEVICE_STATUS, DOBStatus, DayOfWeek, DynamicFormFields, EAccessCardTypes, EAccessCardUserTypes, EmailSender, EntryOrder, EntrySort, EventOrder, EventSort, EventStatus, EventType, FacilitySort, FacilityStatus, FormEntryStatus, GuestSort, GuestStatus, IAccessCard, IAccessCardTransaction, MAccessCard, MAccessCardTransaction, MAddress, MAttendance, MAttendanceSettings, MBidPreloved, MBillingConfiguration, MBillingItem, MBuilding, MBuildingLevel, MBuildingUnit, MBulletinBoard, MBulletinVideo, MCategoryPreloved, MChannelPreloved, MChat, MChatPreloved, MCustomer, MCustomerSite, MDocumentManagement, MEntryPassSettings, MEventManagement, MFeedback, MFile, MFormEntry, MGuestManagement, MHidAmicoEvent, MHidAmicoIdentity, MHidAmicoReader, MIncidentReport, MManpowerDesignations, MManpowerMonitoring, MManpowerRemarks, MManpowerSites, MMember, MNfcPatrolLog, MNfcPatrolRoute, MNfcPatrolSettings, MNfcPatrolSettingsUpdate, MNfcPatrolTag, MOccurrenceBook, MOccurrenceEntry, MOccurrenceSubject, MOnlineForm, MOrg, MOvernightParkingApprovalHours, MOvernightParkingRequest, MPatrolLog, MPatrolQuestion, MPatrolRoute, MPerson, MPost, MPostFavorite, MPromoCode, MRobot, MRole, MRoleV2, MServiceProvider, MServiceProviderBilling, MSession, MSite, MSiteCamera, MSiteFacility, MSiteFacilityBooking, MStatementOfAccount, MSubcategoryPreloved, MSubscription, MUnitBilling, MUser, MVehicle, MVehicleTransaction, MVerification, MVerificationV2, MVisitorTransaction, MWorkOrder, OrgNature, OvernightParkingRequestSort, OvernightParkingRequestStatus, PERSON_TYPES, PStatus, Period, PersonStatus, PersonType, PersonTypes, PostOrder, PostSort, PostStatus, QrTagProps, ResidentAppModuleKey, SiteAddress, SiteCategories, SiteStatus, SortFields, SortOrder, Status, SubjectOrder, SubjectSort, SubscriptionType, TAccessMngmntSettings, TActionStatus, TAddress, TAffectedEntities, TAffectedInjured, TAppServiceType, TApprovedBy, TApprover, TAttendance, TAttendanceCheckIn, TAttendanceCheckOut, TAttendanceCheckTime, TAttendanceLocation, TAttendanceSettings, TAttendanceSettingsGetBySite, TAuthorities, TAuthoritiesCalled, TBidPreloved, TBilling, TBillingConfiguration, TBillingItem, TBuilding, TBuildingLevel, TBuildingUnit, TBulletinBoard, TBulletinVideo, TCamera, TCategoryPreloved, TChannelPreloved, TChat, TChatPreloved, TCheckPoint$1 as TCheckPoint, TComplaintInfo, TComplaintReceivedTo, TCounter, TCreateNfcPatrolLog, TCustomer, TCustomerSite, TDayNumber, TDaySchedule, TDefaultAccessCard, TDesignations, TDocs, TDocumentCreate, TDocumentManagement, TEntryPassSettings, TEventManagement, TFeedback, TFeedbackMetadata, TFeedbackUpdate, TFeedbackUpdateCategory, TFeedbackUpdateServiceProvider, TFeedbackUpdateStatus, TFeedbackUpdateToCompleted, TFile, TFiles, TFolderUpdate, TFormEntry, TGetAttendancesByUserQuery, TGetAttendancesQuery, TGuestManagement, THidAmicoEvent, THidAmicoIdentity, THidAmicoReader, TIncidentInformation, TIncidentReport, TIncidentTypeAndTime, TInvoice, TKeyRef, TManpowerDesignations, TManpowerDesignationsUpdate, TManpowerMonitoring, TManpowerMonitoringUpdate, TManpowerRemarks, TManpowerRemarksStatusUpdate, TManpowerRemarksUpdate, TManpowerSearchFilter, TManpowerSites, TMember, TMemberUpdateStatus, TMessagePreloved, TMiniRole, TNfcPatrolLog, TNfcPatrolRoute, TNfcPatrolRouteEdit, TNfcPatrolSettings, TNfcPatrolSettingsGetBySite, TNfcPatrolSettingsUpdate, TNfcPatrolTag, TNfcPatrolTagConfigureReset, TNfcPatrolTagEdit, TNfcPatrolTagUpdateData, TOccurrenceBook, TOccurrenceEntry, TOccurrenceSubject, TOnlineForm, TOrg, TOvernightParkingApprovalHours, TOvernightParkingRequest, TPatrolLog, TPatrolQuestion, TPatrolRoute, TPerson, TPlaceOfIncident, TPlates, TPost, TPostFavorite, TPrice, TPriceType, TPromoCode, TPromoTier, TRecipientOfComplaint, TRemarks, TResident, TResidentAppModules, TRobot, TRobotMetadata, TRole, TRoleV2, TRoute, TSOABillingItem, TSOAStatus, TServiceProvider, TServiceProviderBilling, TSession, TSessionCreate, TShifts, TSignNfcPatrolLog, TSite, TSiteCamera, TSiteFacility, TSiteFacilityBooking, TSiteInfo, TSiteInformation, TSiteMetadata, TSiteUpdateBlock, TStatementOfAccount, TSubcategoryPreloved, TSubmissionForm, TSubscription, TUnitBilling, TUnits, TUpdateFormEntry, TUpdateName, TUser, TUserCreate, TVehicle, TVehicleTransaction, TVehicleUpdate, TVerification, TVerificationMetadata, TVerificationMetadataV2, TVerificationV2, TVisitorTransaction, TWorkOrder, TWorkOrderMetadata, TWorkOrderUpdate, TWorkOrderUpdateStatus, TWorkOrderUpdateToCompleted, TanyoneDamageToProperty, UseAccessManagementRepo, UserStatus, VehicleCategory, VehicleOrder, VehicleSort, VehicleStatus, VehicleType, VerificationLinkType, VerificationStatus, VerificationSubjectType, VerificationType, VisitorSort, VisitorStatus, addressSchema, allowedFieldsSite, allowedNatures, attendanceSchema, attendanceSettingsSchema, building_level_namespace_collection, building_units_namespace_collection, buildings_namespace_collection, bulletin_boards_namespace_collection, chatPrelovedEvents, chatSchema, createManpowerRemarksDaily, customerSchema, designationsSchema, events_namespace_collection, facility_bookings_namespace_collection, feedbackSchema, feedbacks2_namespace_collection, feedbacks_namespace_collection, formatDahuaDate, guests_namespace_collection, incidentReport, incidentReportLog, incidents_namespace_collection, logCamera, manpowerDesignationsSchema, manpowerEvents, manpowerMonitoringSchema, manpowerRemarksSchema, manpowerSitesSchema, nfcPatrolSettingsSchema, nfcPatrolSettingsSchemaUpdate, occurrence_book_namespace_collection, online_forms_namespace_collection, orgSchema, overnight_parking_requests_namespace_collection, parseDahuaFind, promoCodeSchema, remarksSchema, residentAppModuleKeys, residentFormEntry, robotSchema, schema, schemaApprovedBy, schemaApprover, schemaBidPreloved, schemaBilling, schemaBillingConfiguration, schemaBillingItem, schemaBuilding, schemaBuildingLevel, schemaBuildingUnit, schemaBuildingUpdateOptions, schemaBulletinBoard, schemaBulletinVideo, schemaCategoryPreloved, schemaChannelPreloved, schemaChatPreloved, schemaCreateHidAmicoIdentity, schemaCreateNfcPatrolLog, schemaCustomerSite, schemaDocumentManagement, schemaEntryPassSettings, schemaEventManagement, schemaFiles, schemaFormEntry, schemaGuestManagement, schemaHidAmicoConfiguration, schemaHidAmicoEvent, schemaHidAmicoExecuteActions, schemaHidAmicoIdentity, schemaHidAmicoIdentityIdParams, schemaHidAmicoIdentityQuery, schemaHidAmicoIntercomCall, schemaHidAmicoLogQuery, schemaHidAmicoNotificationParams, schemaHidAmicoObjectOperation, schemaHidAmicoReader, schemaHidAmicoReaderIdParams, schemaHidAmicoReaderListQuery, schemaHidAmicoSetConfiguration, schemaHidAmicoSync, schemaHidAmicoUserImageParams, schemaIncidentReport, schemaMultipleDocumentManagement, schemaNfcPatrolLog, schemaNfcPatrolRoute, schemaNfcPatrolTag, schemaNfcPatrolTagUpdateData, schemaOccurrenceBook, schemaOccurrenceEntry, schemaOccurrenceSubject, schemaOnlineForm, schemaOvernightParkingApprovalHours, schemaOvernightParkingRequest, schemaPatrolLog, schemaPatrolQuestion, schemaPatrolRoute, schemaPerson, schemaPlate, schemaPost, schemaPostFavorite, schemaServiceProvider, schemaServiceProviderBilling, schemaSignNfcPatrolLog, schemaSiteCamera, schemaSiteFacility, schemaSiteFacilityBooking, schemaStatementOfAccount, schemaSubcategoryPreloved, schemaUnitBilling, schemaUpdateBidPreloved, schemaUpdateBuildingLevel, schemaUpdateBulletinBoard, schemaUpdateBulletinVideo, schemaUpdateCategoryPreloved, schemaUpdateChatPreloved, schemaUpdateDocumentManagement, schemaUpdateEntryPassSettings, schemaUpdateEventManagement, schemaUpdateFolderManagement, schemaUpdateFormEntry, schemaUpdateGuestManagement, schemaUpdateHidAmicoIdentity, schemaUpdateHidAmicoReader, schemaUpdateIncidentReport, schemaUpdateOccurrenceBook, schemaUpdateOccurrenceEntry, schemaUpdateOccurrenceSubject, schemaUpdateOnlineForm, schemaUpdateOptions, schemaUpdateOvernightParkingRequest, schemaUpdatePatrolLog, schemaUpdatePatrolQuestion, schemaUpdatePatrolRoute, schemaUpdatePerson, schemaUpdatePost, schemaUpdatePostFavorite, schemaUpdateServiceProviderBilling, schemaUpdateSiteBillingConfiguration, schemaUpdateSiteBillingItem, schemaUpdateSiteCamera, schemaUpdateSiteFacility, schemaUpdateSiteFacilityBooking, schemaUpdateSiteUnitBilling, schemaUpdateStatementOfAccount, schemaUpdateSubcategoryPreloved, schemaUpdateVisTrans, schemaVehicleTransaction, schemaVisitorTransaction, schemeCamera, schemeLogCamera, sessionSchema, shiftSchema, siteSchema, site_people_namespace_collection, updateRemarksStatusEod, updateRemarksisAcknowledged, updateSiteSchema, useAccessManagementController, useAddressRepo, useAttendanceController, useAttendanceRepository, useAttendanceSettingsController, useAttendanceSettingsRepository, useAttendanceSettingsService, useAuthController, useAuthControllerV2, useAuthService, useAuthServiceV2, useBidPrelovedController, useBidPrelovedRepo, useBidPrelovedService, useBuildingController, useBuildingLevelController, useBuildingLevelRepo, useBuildingLevelService, useBuildingRepo, useBuildingService, useBuildingUnitController, useBuildingUnitRepo, useBuildingUnitService, useBulletinBoardController, useBulletinBoardRepo, useBulletinBoardService, useBulletinVideoController, useBulletinVideoRepo, useBulletinVideoService, useCategoryPrelovedController, useCategoryPrelovedRepo, useChannelPrelovedController, useChannelPrelovedRepo, useChatController, useChatPrelovedController, useChatPrelovedRepo, useChatPrelovedService, useChatRepo, useCounterModel, useCounterRepo, useCustomerController, useCustomerRepo, useCustomerSiteController, useCustomerSiteRepo, useCustomerSiteService, useDahuaService, useDashboardController, useDashboardRepo, useDocumentManagementController, useDocumentManagementRepo, useDocumentManagementService, useEntryPassSettingsController, useEntryPassSettingsRepo, useEventManagementController, useEventManagementRepo, useEventManagementService, useFeedbackController, useFeedbackRepo, useFeedbackService, useFileController, useFileRepo, useFileService, useFormEntryController, useFormEntryRepo, useGuestManagementController, useGuestManagementRepo, useGuestManagementService, useHidAmicoController, useHidAmicoRepo, useHidAmicoService, useHrmLabsAttendanceCtrl, useHrmLabsAttendanceSrvc, useIncidentReportController, useIncidentReportRepo, useIncidentReportService, useInvoiceController, useInvoiceModel, useInvoiceRepo, useManpowerDesignationCtrl, useManpowerDesignationRepo, useManpowerMonitoringCtrl, useManpowerMonitoringRepo, useManpowerMonitoringSrvc, useManpowerRemarkCtrl, useManpowerRemarksRepo, useManpowerSitesCtrl, useManpowerSitesRepo, useManpowerSitesSrvc, useMemberController, useMemberRepo, useMemberService, useNewDashboardController, useNewDashboardRepo, useNfcPatrolLogController, useNfcPatrolLogRepo, useNfcPatrolLogService, useNfcPatrolRouteController, useNfcPatrolRouteRepo, useNfcPatrolRouteService, useNfcPatrolSettingsController, useNfcPatrolSettingsRepository, useNfcPatrolSettingsService, useNfcPatrolTagController, useNfcPatrolTagRepo, useNfcPatrolTagService, useOccurrenceBookController, useOccurrenceBookRepo, useOccurrenceBookService, useOccurrenceEntryController, useOccurrenceEntryRepo, useOccurrenceEntryService, useOccurrenceSubjectController, useOccurrenceSubjectRepo, useOccurrenceSubjectService, useOnlineFormController, useOnlineFormRepo, useOrgController, useOrgControllerV2, useOrgRepo, useOvernightParkingController, useOvernightParkingRepo, useOvernightParkingRequestController, useOvernightParkingRequestRepo, useOvernightParkingRequestService, usePatrolLogController, usePatrolLogRepo, usePatrolQuestionController, usePatrolQuestionRepo, usePatrolRouteController, usePatrolRouteRepo, usePersonController, usePersonRepo, usePostFavoriteController, usePostFavoriteRepo, usePostFavoriteService, usePostPrelovedController, usePostPrelovedRepo, usePriceController, usePriceModel, usePriceRepo, usePromoCodeController, usePromoCodeRepo, useRedDotPaymentController, useRedDotPaymentRepo, useRedDotPaymentSvc, useRobotController, useRobotRepo, useRobotService, useRoleController, useRoleControllerV2, useRoleRepo, useRoleRepoV2, useRoleServiceV2, useServiceProviderBillingController, useServiceProviderBillingRepo, useServiceProviderBillingService, useServiceProviderController, useServiceProviderRepo, useSessionRepo, useSiteBillingConfigurationController, useSiteBillingConfigurationRepo, useSiteBillingItemController, useSiteBillingItemRepo, useSiteCameraController, useSiteCameraRepo, useSiteCameraService, useSiteController, useSiteFacilityBookingController, useSiteFacilityBookingRepo, useSiteFacilityBookingService, useSiteFacilityController, useSiteFacilityRepo, useSiteFacilityService, useSiteRepo, useSiteService, useSiteUnitBillingController, useSiteUnitBillingRepo, useSiteUnitBillingService, useStatementOfAccountController, useStatementOfAccountRepo, useSubcategoryPrelovedController, useSubcategoryPrelovedRepo, useSubscriptionController, useSubscriptionRepo, useSubscriptionService, useUserController, useUserControllerV2, useUserRepo, useUserRepoV2, useUserService, useUserServiceV2, useVehicleController, useVehicleRepo, useVehicleService, useVerificationController, useVerificationControllerV2, useVerificationRepo, useVerificationRepoV2, useVerificationService, useVerificationServiceV2, useVisitorTransactionController, useVisitorTransactionRepo, useVisitorTransactionService, useWorkOrderController, useWorkOrderRepo, useWorkOrderService, userSchema, vehicleSchema, vehicles_namespace_collection, visitorPersonRepo, visitorPersonService, visitorType, visitors_namespace_collection, workOrderSchema, work_orders2_namespace_collection, work_orders_namespace_collection };
|
|
9185
|
+
export { ANPRMode, AccessTypeProps, AppServiceType, AssignCardConfig, BidStatus, BidType, BuildingLevelStatus, BuildingStatus, BulkCardUpdate, BulletinOrder, BulletinRecipient, BulletinSort, BulletinStatus, BulletinVideoOrder, BulletinVideoSort, CAMERA_ANPR_PERMISSIONS, CAMERA_CAPABILITIES, CAMERA_CAPABILITY_REASONS, CAMERA_NOT_PATROL_OR_CCTV, CAMERA_PTZ_PERMISSIONS, CAMERA_REQUEST_TIMEOUT_MS, CAMERA_RTSP_TIMEOUT_MS, CAMERA_SETUP_PERMISSIONS, CAMERA_SNAPSHOT_CACHE_SECONDS, CAMERA_SNAPSHOT_MAX_BYTES, CAMERA_TEST_MIN_INTERVAL_SECONDS, CAMERA_TEST_ROUND_LIMIT, CAMERA_TEST_ROUND_SECONDS, CAMERA_TYPE_ANPR, CAMERA_TYPE_IP, CAMERA_VIEW_PERMISSIONS, CLOCK_DRIFT_WARN_SECONDS, CURRENT_TIME_ENDPOINT, Camera, CameraAddressInput, CameraCapability, CameraCapabilityContext, CameraCapabilityDescriptor, CameraCapabilityEntry, CameraCapabilityReason, CameraCapabilityState, CameraCapabilityTrace, CameraDevice, CameraMembership, CameraTestStatus, CameraTransport, CameraType, DEVICE_STATUS, DOBStatus, DayOfWeek, DeviceHttpTarget, DeviceProbeResult, DynamicFormFields, EAccessCardTypes, EAccessCardUserTypes, EmailSender, EntryOrder, EntrySort, EventOrder, EventSort, EventStatus, EventType, FacilitySort, FacilityStatus, FormEntryStatus, GuestSort, GuestStatus, IAccessCard, IAccessCardTransaction, MAX_CAMERA_CHANNEL, MAccessCard, MAccessCardTransaction, MAddress, MAttendance, MAttendanceSettings, MBidPreloved, MBillingConfiguration, MBillingItem, MBuilding, MBuildingLevel, MBuildingUnit, MBulletinBoard, MBulletinVideo, MCategoryPreloved, MChannelPreloved, MChat, MChatPreloved, MCustomer, MCustomerSite, MDocumentManagement, MEntryPassSettings, MEventManagement, MFeedback, MFile, MFormEntry, MGuestManagement, MHidAmicoEvent, MHidAmicoIdentity, MHidAmicoReader, MIncidentReport, MManpowerDesignations, MManpowerMonitoring, MManpowerRemarks, MManpowerSites, MMember, MNfcPatrolLog, MNfcPatrolRoute, MNfcPatrolSettings, MNfcPatrolSettingsUpdate, MNfcPatrolTag, MOccurrenceBook, MOccurrenceEntry, MOccurrenceSubject, MOnlineForm, MOrg, MOvernightParkingApprovalHours, MOvernightParkingRequest, MPatrolLog, MPatrolQuestion, MPatrolRoute, MPerson, MPost, MPostFavorite, MPromoCode, MRobot, MRole, MRoleV2, MServiceProvider, MServiceProviderBilling, MSession, MSite, MSiteCamera, MSiteFacility, MSiteFacilityBooking, MStatementOfAccount, MSubcategoryPreloved, MSubscription, MUnitBilling, MUser, MVehicle, MVehicleTransaction, MVerification, MVerificationV2, MVisitorTransaction, MWorkOrder, OrgNature, OvernightParkingRequestSort, OvernightParkingRequestStatus, PATROL_CCTV_CAMERA_FILTER, PERSON_TYPES, PStatus, PTZ_ALLOWED_ACTIONS, PTZ_ALLOWED_CODES, Period, PersonStatus, PersonType, PersonTypes, PostOrder, PostSort, PostStatus, QrTagProps, ResidentAppModuleKey, SOFTWARE_VERSION_ENDPOINT, SiteAddress, SiteCategories, SiteStatus, SortFields, SortOrder, Status, SubjectOrder, SubjectSort, SubscriptionType, TAccessMngmntSettings, TActionStatus, TAddress, TAffectedEntities, TAffectedInjured, TAppServiceType, TApprovedBy, TApprover, TAttendance, TAttendanceCheckIn, TAttendanceCheckOut, TAttendanceCheckTime, TAttendanceLocation, TAttendanceSettings, TAttendanceSettingsGetBySite, TAuthorities, TAuthoritiesCalled, TBidPreloved, TBilling, TBillingConfiguration, TBillingItem, TBuilding, TBuildingLevel, TBuildingUnit, TBulletinBoard, TBulletinVideo, TCamera, TCategoryPreloved, TChannelPreloved, TChat, TChatPreloved, TCheckPoint$1 as TCheckPoint, TComplaintInfo, TComplaintReceivedTo, TCounter, TCreateNfcPatrolLog, TCustomer, TCustomerSite, TDayNumber, TDaySchedule, TDefaultAccessCard, TDesignations, TDocs, TDocumentCreate, TDocumentManagement, TEntryPassSettings, TEventManagement, TFeedback, TFeedbackMetadata, TFeedbackUpdate, TFeedbackUpdateCategory, TFeedbackUpdateServiceProvider, TFeedbackUpdateStatus, TFeedbackUpdateToCompleted, TFile, TFiles, TFolderUpdate, TFormEntry, TGetAttendancesByUserQuery, TGetAttendancesQuery, TGuestManagement, THidAmicoEvent, THidAmicoIdentity, THidAmicoReader, TIncidentInformation, TIncidentReport, TIncidentTypeAndTime, TInvoice, TKeyRef, TManpowerDesignations, TManpowerDesignationsUpdate, TManpowerMonitoring, TManpowerMonitoringUpdate, TManpowerRemarks, TManpowerRemarksStatusUpdate, TManpowerRemarksUpdate, TManpowerSearchFilter, TManpowerSites, TMember, TMemberUpdateStatus, TMessagePreloved, TMiniRole, TNfcPatrolLog, TNfcPatrolRoute, TNfcPatrolRouteEdit, TNfcPatrolSettings, TNfcPatrolSettingsGetBySite, TNfcPatrolSettingsUpdate, TNfcPatrolTag, TNfcPatrolTagConfigureReset, TNfcPatrolTagEdit, TNfcPatrolTagUpdateData, TOccurrenceBook, TOccurrenceEntry, TOccurrenceSubject, TOnlineForm, TOrg, TOvernightParkingApprovalHours, TOvernightParkingRequest, TPatrolLog, TPatrolQuestion, TPatrolRoute, TPerson, TPlaceOfIncident, TPlates, TPost, TPostFavorite, TPrice, TPriceType, TPromoCode, TPromoTier, TRANSPORT_DEVICE_HTTP, TRANSPORT_RELAY_PLAYER, TRANSPORT_RTSP_FRAME, TRecipientOfComplaint, TRemarks, TResident, TResidentAppModules, TRobot, TRobotMetadata, TRole, TRoleV2, TRoute, TSOABillingItem, TSOAStatus, TServiceProvider, TServiceProviderBilling, TSession, TSessionCreate, TShifts, TSignNfcPatrolLog, TSite, TSiteCamera, TSiteFacility, TSiteFacilityBooking, TSiteInfo, TSiteInformation, TSiteMetadata, TSiteUpdateBlock, TStatementOfAccount, TSubcategoryPreloved, TSubmissionForm, TSubscription, TUnitBilling, TUnits, TUpdateFormEntry, TUpdateName, TUser, TUserCreate, TVehicle, TVehicleTransaction, TVehicleUpdate, TVerification, TVerificationMetadata, TVerificationMetadataV2, TVerificationV2, TVisitorTransaction, TWorkOrder, TWorkOrderMetadata, TWorkOrderUpdate, TWorkOrderUpdateStatus, TWorkOrderUpdateToCompleted, TanyoneDamageToProperty, UseAccessManagementRepo, UserStatus, VehicleCategory, VehicleOrder, VehicleSort, VehicleStatus, VehicleType, VerificationLinkType, VerificationStatus, VerificationSubjectType, VerificationType, VisitorSort, VisitorStatus, addressSchema, allowedFieldsSite, allowedNatures, attendanceSchema, attendanceSettingsSchema, building_level_namespace_collection, building_units_namespace_collection, buildings_namespace_collection, bulletin_boards_namespace_collection, cameraBaseUrl, cameraCapabilitiesFor, cameraDevices, cameraGrant, cameraHealthSummary, cameraManagePermissions, cameraTransports, chatPrelovedEvents, chatSchema, clampPtzSpeed, clockDriftSeconds, createManpowerRemarksDaily, customerSchema, deriveCameraHost, describeCameraCapabilities, designationsSchema, deviceControlEnabled, deviceHttpEnabled, deviceHttpTargets, deviceHttpTimeoutMs, deviceProbeTtlSeconds, events_namespace_collection, facility_bookings_namespace_collection, feedbackSchema, feedbacks2_namespace_collection, feedbacks_namespace_collection, ffmpegFrameArgs, ffmpegPath, formatCapabilityTrace, formatDahuaDate, guests_namespace_collection, hasAnyCapability, hasAnyPermission, incidentReport, incidentReportLog, incidents_namespace_collection, isCameraEntitled, isPatrolCctvCamera, isRelayPlayerUrl, logCamera, manpowerDesignationsSchema, manpowerEvents, manpowerMonitoringSchema, manpowerRemarksSchema, manpowerSitesSchema, mapWithLimit, nfcPatrolSettingsSchema, nfcPatrolSettingsSchemaUpdate, occurrence_book_namespace_collection, online_forms_namespace_collection, orgSchema, overnight_parking_requests_namespace_collection, parseCameraChannel, parseCameraHost, parseDahuaFind, parseDeviceTime, parseSoftwareVersion, promoCodeSchema, ptzEndpoint, publicCameraFields, registerCameraTransport, relayForRecorder, remarksSchema, resetCameraTransports, residentAppModuleKeys, residentFormEntry, resolutionRefusalReason, resolveCamera, resolveDeviceHttp, robotSchema, rtspUrl, schema, schemaApprovedBy, schemaApprover, schemaBidPreloved, schemaBilling, schemaBillingConfiguration, schemaBillingItem, schemaBuilding, schemaBuildingLevel, schemaBuildingUnit, schemaBuildingUpdateOptions, schemaBulletinBoard, schemaBulletinVideo, schemaCategoryPreloved, schemaChannelPreloved, schemaChatPreloved, schemaCreateHidAmicoIdentity, schemaCreateNfcPatrolLog, schemaCustomerSite, schemaDocumentManagement, schemaEntryPassSettings, schemaEventManagement, schemaFiles, schemaFormEntry, schemaGuestManagement, schemaHidAmicoConfiguration, schemaHidAmicoEvent, schemaHidAmicoExecuteActions, schemaHidAmicoIdentity, schemaHidAmicoIdentityIdParams, schemaHidAmicoIdentityQuery, schemaHidAmicoIntercomCall, schemaHidAmicoLogQuery, schemaHidAmicoNotificationParams, schemaHidAmicoObjectOperation, schemaHidAmicoReader, schemaHidAmicoReaderIdParams, schemaHidAmicoReaderListQuery, schemaHidAmicoSetConfiguration, schemaHidAmicoSync, schemaHidAmicoUserImageParams, schemaIncidentReport, schemaMultipleDocumentManagement, schemaNfcPatrolLog, schemaNfcPatrolRoute, schemaNfcPatrolTag, schemaNfcPatrolTagUpdateData, schemaOccurrenceBook, schemaOccurrenceEntry, schemaOccurrenceSubject, schemaOnlineForm, schemaOvernightParkingApprovalHours, schemaOvernightParkingRequest, schemaPatrolLog, schemaPatrolQuestion, schemaPatrolRoute, schemaPerson, schemaPlate, schemaPost, schemaPostFavorite, schemaServiceProvider, schemaServiceProviderBilling, schemaSignNfcPatrolLog, schemaSiteCamera, schemaSiteFacility, schemaSiteFacilityBooking, schemaStatementOfAccount, schemaSubcategoryPreloved, schemaUnitBilling, schemaUpdateBidPreloved, schemaUpdateBuildingLevel, schemaUpdateBulletinBoard, schemaUpdateBulletinVideo, schemaUpdateCategoryPreloved, schemaUpdateChatPreloved, schemaUpdateDocumentManagement, schemaUpdateEntryPassSettings, schemaUpdateEventManagement, schemaUpdateFolderManagement, schemaUpdateFormEntry, schemaUpdateGuestManagement, schemaUpdateHidAmicoIdentity, schemaUpdateHidAmicoReader, schemaUpdateIncidentReport, schemaUpdateOccurrenceBook, schemaUpdateOccurrenceEntry, schemaUpdateOccurrenceSubject, schemaUpdateOnlineForm, schemaUpdateOptions, schemaUpdateOvernightParkingRequest, schemaUpdatePatrolLog, schemaUpdatePatrolQuestion, schemaUpdatePatrolRoute, schemaUpdatePerson, schemaUpdatePost, schemaUpdatePostFavorite, schemaUpdateServiceProviderBilling, schemaUpdateSiteBillingConfiguration, schemaUpdateSiteBillingItem, schemaUpdateSiteCamera, schemaUpdateSiteFacility, schemaUpdateSiteFacilityBooking, schemaUpdateSiteUnitBilling, schemaUpdateStatementOfAccount, schemaUpdateSubcategoryPreloved, schemaUpdateVisTrans, schemaVehicleTransaction, schemaVisitorTransaction, schemeCamera, schemeLogCamera, sessionSchema, shiftSchema, siteSchema, site_people_namespace_collection, snapshotEndpoint, snapshotRefusalReason, updateRemarksStatusEod, updateRemarksisAcknowledged, updateSiteSchema, useAccessManagementController, useAddressRepo, useAttendanceController, useAttendanceRepository, useAttendanceSettingsController, useAttendanceSettingsRepository, useAttendanceSettingsService, useAuthController, useAuthControllerV2, useAuthService, useAuthServiceV2, useBidPrelovedController, useBidPrelovedRepo, useBidPrelovedService, useBuildingController, useBuildingLevelController, useBuildingLevelRepo, useBuildingLevelService, useBuildingRepo, useBuildingService, useBuildingUnitController, useBuildingUnitRepo, useBuildingUnitService, useBulletinBoardController, useBulletinBoardRepo, useBulletinBoardService, useBulletinVideoController, useBulletinVideoRepo, useBulletinVideoService, useCameraViewController, useCameraViewService, useCategoryPrelovedController, useCategoryPrelovedRepo, useChannelPrelovedController, useChannelPrelovedRepo, useChatController, useChatPrelovedController, useChatPrelovedRepo, useChatPrelovedService, useChatRepo, useCounterModel, useCounterRepo, useCustomerController, useCustomerRepo, useCustomerSiteController, useCustomerSiteRepo, useCustomerSiteService, useDahuaService, useDashboardController, useDashboardRepo, useDocumentManagementController, useDocumentManagementRepo, useDocumentManagementService, useEntryPassSettingsController, useEntryPassSettingsRepo, useEventManagementController, useEventManagementRepo, useEventManagementService, useFeedbackController, useFeedbackRepo, useFeedbackService, useFileController, useFileRepo, useFileService, useFormEntryController, useFormEntryRepo, useGuestManagementController, useGuestManagementRepo, useGuestManagementService, useHidAmicoController, useHidAmicoRepo, useHidAmicoService, useHrmLabsAttendanceCtrl, useHrmLabsAttendanceSrvc, useIncidentReportController, useIncidentReportRepo, useIncidentReportService, useInvoiceController, useInvoiceModel, useInvoiceRepo, useManpowerDesignationCtrl, useManpowerDesignationRepo, useManpowerMonitoringCtrl, useManpowerMonitoringRepo, useManpowerMonitoringSrvc, useManpowerRemarkCtrl, useManpowerRemarksRepo, useManpowerSitesCtrl, useManpowerSitesRepo, useManpowerSitesSrvc, useMemberController, useMemberRepo, useMemberService, useNewDashboardController, useNewDashboardRepo, useNfcPatrolLogController, useNfcPatrolLogRepo, useNfcPatrolLogService, useNfcPatrolRouteController, useNfcPatrolRouteRepo, useNfcPatrolRouteService, useNfcPatrolSettingsController, useNfcPatrolSettingsRepository, useNfcPatrolSettingsService, useNfcPatrolTagController, useNfcPatrolTagRepo, useNfcPatrolTagService, useOccurrenceBookController, useOccurrenceBookRepo, useOccurrenceBookService, useOccurrenceEntryController, useOccurrenceEntryRepo, useOccurrenceEntryService, useOccurrenceSubjectController, useOccurrenceSubjectRepo, useOccurrenceSubjectService, useOnlineFormController, useOnlineFormRepo, useOrgController, useOrgControllerV2, useOrgRepo, useOvernightParkingController, useOvernightParkingRepo, useOvernightParkingRequestController, useOvernightParkingRequestRepo, useOvernightParkingRequestService, usePatrolLogController, usePatrolLogRepo, usePatrolQuestionController, usePatrolQuestionRepo, usePatrolRouteController, usePatrolRouteRepo, usePersonController, usePersonRepo, usePostFavoriteController, usePostFavoriteRepo, usePostFavoriteService, usePostPrelovedController, usePostPrelovedRepo, usePriceController, usePriceModel, usePriceRepo, usePromoCodeController, usePromoCodeRepo, useRedDotPaymentController, useRedDotPaymentRepo, useRedDotPaymentSvc, useRobotController, useRobotRepo, useRobotService, useRoleController, useRoleControllerV2, useRoleRepo, useRoleRepoV2, useRoleServiceV2, useServiceProviderBillingController, useServiceProviderBillingRepo, useServiceProviderBillingService, useServiceProviderController, useServiceProviderRepo, useSessionRepo, useSiteBillingConfigurationController, useSiteBillingConfigurationRepo, useSiteBillingItemController, useSiteBillingItemRepo, useSiteCameraController, useSiteCameraRepo, useSiteCameraService, useSiteController, useSiteFacilityBookingController, useSiteFacilityBookingRepo, useSiteFacilityBookingService, useSiteFacilityController, useSiteFacilityRepo, useSiteFacilityService, useSiteRepo, useSiteService, useSiteUnitBillingController, useSiteUnitBillingRepo, useSiteUnitBillingService, useStatementOfAccountController, useStatementOfAccountRepo, useSubcategoryPrelovedController, useSubcategoryPrelovedRepo, useSubscriptionController, useSubscriptionRepo, useSubscriptionService, useUserController, useUserControllerV2, useUserRepo, useUserRepoV2, useUserService, useUserServiceV2, useVehicleController, useVehicleRepo, useVehicleService, useVerificationController, useVerificationControllerV2, useVerificationRepo, useVerificationRepoV2, useVerificationService, useVerificationServiceV2, useVisitorTransactionController, useVisitorTransactionRepo, useVisitorTransactionService, useWorkOrderController, useWorkOrderRepo, useWorkOrderService, userSchema, vehicleSchema, vehicles_namespace_collection, visitorPersonRepo, visitorPersonService, visitorType, visitors_namespace_collection, wallConfig, workOrderSchema, work_orders2_namespace_collection, work_orders_namespace_collection };
|