@ceralive/modem-control 1.0.0 → 1.2.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/README.md +341 -0
- package/dist/backend/at-lease.d.ts +59 -0
- package/dist/backend/at-lease.js +118 -0
- package/dist/backend/cell-info.d.ts +46 -0
- package/dist/backend/cell-info.js +124 -0
- package/dist/backend/constants.d.ts +24 -0
- package/{src/backend/constants.ts → dist/backend/constants.js} +4 -9
- package/dist/backend/device-classifier.d.ts +46 -0
- package/dist/backend/device-classifier.js +258 -0
- package/dist/backend/enrichment.d.ts +28 -0
- package/dist/backend/enrichment.js +59 -0
- package/dist/backend/features.d.ts +61 -0
- package/dist/backend/features.js +109 -0
- package/dist/backend/identity-ladder.d.ts +57 -0
- package/dist/backend/identity-ladder.js +158 -0
- package/dist/backend/identity-registry.d.ts +51 -0
- package/dist/backend/identity-registry.js +101 -0
- package/dist/backend/index.d.ts +30 -0
- package/dist/backend/index.js +35 -0
- package/dist/backend/lifecycle-interlock.d.ts +25 -0
- package/dist/backend/lifecycle-interlock.js +18 -0
- package/dist/backend/managed-objects.d.ts +39 -0
- package/dist/backend/managed-objects.js +82 -0
- package/dist/backend/mapping.d.ts +11 -0
- package/dist/backend/mapping.js +148 -0
- package/dist/backend/mm-backend.d.ts +44 -0
- package/dist/backend/mm-backend.js +154 -0
- package/dist/backend/mm-location.d.ts +21 -0
- package/dist/backend/mm-location.js +237 -0
- package/dist/backend/mm-mutations.d.ts +42 -0
- package/dist/backend/mm-mutations.js +259 -0
- package/dist/backend/modem-actor.d.ts +41 -0
- package/dist/backend/modem-actor.js +78 -0
- package/dist/backend/nm-auto-apn.d.ts +54 -0
- package/dist/backend/nm-auto-apn.js +124 -0
- package/dist/backend/nm-gsm-fields.d.ts +23 -0
- package/dist/backend/nm-gsm-fields.js +107 -0
- package/dist/backend/nmcli-nm-port.d.ts +28 -0
- package/dist/backend/nmcli-nm-port.js +173 -0
- package/dist/backend/nmcli-runner.d.ts +24 -0
- package/dist/backend/nmcli-runner.js +35 -0
- package/dist/backend/observer.d.ts +37 -0
- package/dist/backend/observer.js +219 -0
- package/dist/backend/power-contract.d.ts +49 -0
- package/dist/backend/power-contract.js +34 -0
- package/dist/backend/recovery-attribution.d.ts +32 -0
- package/dist/backend/recovery-attribution.js +57 -0
- package/dist/backend/recovery-budget.d.ts +45 -0
- package/dist/backend/recovery-budget.js +44 -0
- package/dist/backend/recovery-ladder.d.ts +94 -0
- package/dist/backend/recovery-ladder.js +116 -0
- package/dist/backend/router-ethernet.d.ts +19 -0
- package/dist/backend/router-ethernet.js +66 -0
- package/dist/backend/row-store.d.ts +13 -0
- package/dist/backend/row-store.js +82 -0
- package/dist/backend/signal-setup.d.ts +30 -0
- package/dist/backend/signal-setup.js +92 -0
- package/dist/backend/sim-unlock.d.ts +13 -0
- package/dist/backend/sim-unlock.js +153 -0
- package/dist/backend/transition-preconditions.d.ts +101 -0
- package/dist/backend/transition-preconditions.js +132 -0
- package/dist/backend/usage/accounting.d.ts +39 -0
- package/dist/backend/usage/accounting.js +73 -0
- package/dist/backend/usage/billing-cycle.d.ts +11 -0
- package/dist/backend/usage/billing-cycle.js +39 -0
- package/dist/backend/usage/boot-id.d.ts +6 -0
- package/{src/backend/usage/boot-id.ts → dist/backend/usage/boot-id.js} +7 -7
- package/dist/backend/usage/index.d.ts +8 -0
- package/dist/backend/usage/index.js +11 -0
- package/dist/backend/usage/policy-store.d.ts +50 -0
- package/dist/backend/usage/policy-store.js +161 -0
- package/dist/backend/usage/policy-write.d.ts +65 -0
- package/dist/backend/usage/policy-write.js +112 -0
- package/dist/backend/usage/proc-net-dev.d.ts +18 -0
- package/{src/backend/usage/proc-net-dev.ts → dist/backend/usage/proc-net-dev.js} +39 -47
- package/dist/backend/usage/sampler.d.ts +75 -0
- package/dist/backend/usage/sampler.js +211 -0
- package/dist/backend/usage/store.d.ts +38 -0
- package/dist/backend/usage/store.js +126 -0
- package/dist/backend/usb-device-snapshot.d.ts +31 -0
- package/dist/backend/usb-device-snapshot.js +1 -0
- package/dist/backend/usb-enumerator.d.ts +21 -0
- package/dist/backend/usb-enumerator.js +153 -0
- package/dist/backend/usb-mode-transition.d.ts +29 -0
- package/dist/backend/usb-mode-transition.js +216 -0
- package/dist/band/band-names.d.ts +42 -0
- package/dist/band/band-names.js +150 -0
- package/dist/band/certification.d.ts +84 -0
- package/dist/band/certification.js +127 -0
- package/dist/band/certified-bands.json +4 -0
- package/dist/band/index.d.ts +2 -0
- package/dist/band/index.js +8 -0
- package/dist/capability/detect.d.ts +52 -0
- package/dist/capability/detect.js +86 -0
- package/dist/capability/five-g-preference.d.ts +104 -0
- package/dist/capability/five-g-preference.js +171 -0
- package/dist/capability/index.d.ts +3 -0
- package/dist/capability/index.js +10 -0
- package/dist/capability/support-claim.d.ts +39 -0
- package/dist/capability/support-claim.js +81 -0
- package/dist/domain/brand.d.ts +10 -0
- package/dist/domain/brand.js +21 -0
- package/dist/domain/errors.d.ts +32 -0
- package/dist/domain/errors.js +48 -0
- package/dist/domain/generation.d.ts +8 -0
- package/dist/domain/generation.js +12 -0
- package/dist/domain/guards.d.ts +6 -0
- package/dist/domain/guards.js +127 -0
- package/dist/domain/identity.d.ts +109 -0
- package/dist/domain/identity.js +86 -0
- package/dist/domain/index.d.ts +14 -0
- package/dist/domain/index.js +18 -0
- package/dist/domain/mm-enums.d.ts +12 -0
- package/dist/domain/mm-enums.js +139 -0
- package/dist/domain/modem-presentation.d.ts +10 -0
- package/dist/domain/modem-presentation.js +39 -0
- package/dist/domain/observation.d.ts +39 -0
- package/dist/domain/observation.js +4 -0
- package/dist/domain/operation.d.ts +118 -0
- package/dist/domain/operation.js +85 -0
- package/dist/domain/physical-identity.d.ts +43 -0
- package/dist/domain/physical-identity.js +113 -0
- package/{src/domain/policy.ts → dist/domain/policy.d.ts} +34 -69
- package/dist/domain/policy.js +38 -0
- package/dist/domain/shadow-divergence.d.ts +27 -0
- package/dist/domain/shadow-divergence.js +70 -0
- package/dist/domain/snapshot.d.ts +53 -0
- package/dist/domain/snapshot.js +75 -0
- package/{src/domain/state.ts → dist/domain/state.d.ts} +23 -122
- package/dist/domain/state.js +38 -0
- package/dist/fcc/coverage.d.ts +63 -0
- package/dist/fcc/coverage.js +102 -0
- package/dist/fcc/index.d.ts +3 -0
- package/dist/fcc/index.js +12 -0
- package/dist/fcc/policy-store.d.ts +40 -0
- package/dist/fcc/policy-store.js +146 -0
- package/dist/fcc/policy-write.d.ts +32 -0
- package/dist/fcc/policy-write.js +37 -0
- package/dist/hardware/hilink-protocol.d.ts +39 -0
- package/dist/hardware/hilink-protocol.js +58 -0
- package/dist/hardware/index.d.ts +3 -0
- package/dist/hardware/index.js +15 -0
- package/dist/hardware/router-parsers.d.ts +89 -0
- package/dist/hardware/router-parsers.js +234 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +27 -0
- package/dist/journal/codec.d.ts +44 -0
- package/dist/journal/codec.js +198 -0
- package/dist/journal/engine.d.ts +28 -0
- package/dist/journal/engine.js +68 -0
- package/dist/journal/entry.d.ts +74 -0
- package/dist/journal/entry.js +56 -0
- package/dist/journal/index.d.ts +6 -0
- package/dist/journal/index.js +6 -0
- package/dist/journal/legacy-ceraui.d.ts +73 -0
- package/dist/journal/legacy-ceraui.js +227 -0
- package/dist/journal/recovery.d.ts +58 -0
- package/dist/journal/recovery.js +117 -0
- package/dist/journal/store.d.ts +55 -0
- package/dist/journal/store.js +150 -0
- package/dist/location/fix-state.d.ts +53 -0
- package/dist/location/fix-state.js +75 -0
- package/dist/location/index.d.ts +2 -0
- package/dist/location/index.js +8 -0
- package/dist/location/nmea.d.ts +10 -0
- package/dist/location/nmea.js +89 -0
- package/dist/observations/envelope.d.ts +63 -0
- package/dist/observations/envelope.js +77 -0
- package/dist/observations/freshness.d.ts +28 -0
- package/dist/observations/freshness.js +76 -0
- package/dist/observations/index.d.ts +13 -0
- package/dist/observations/index.js +24 -0
- package/dist/observations/metric.d.ts +61 -0
- package/dist/observations/metric.js +73 -0
- package/dist/observations/model.d.ts +80 -0
- package/dist/observations/model.js +11 -0
- package/dist/observations/provenance.d.ts +94 -0
- package/dist/observations/provenance.js +67 -0
- package/dist/observations/raw.d.ts +42 -0
- package/dist/observations/raw.js +146 -0
- package/dist/observations/reading.d.ts +51 -0
- package/dist/observations/reading.js +65 -0
- package/dist/observations/sources/hilink.d.ts +10 -0
- package/dist/observations/sources/hilink.js +84 -0
- package/dist/observations/sources/modemmanager.d.ts +18 -0
- package/dist/observations/sources/modemmanager.js +239 -0
- package/dist/observations/sources/router-shared.d.ts +29 -0
- package/dist/observations/sources/router-shared.js +68 -0
- package/dist/observations/sources/ufi.d.ts +10 -0
- package/dist/observations/sources/ufi.js +111 -0
- package/dist/observations/sources/zte.d.ts +7 -0
- package/dist/observations/sources/zte.js +71 -0
- package/dist/observations/state-separation.d.ts +64 -0
- package/dist/observations/state-separation.js +52 -0
- package/dist/operation-ids.d.ts +2 -0
- package/dist/operation-ids.js +26 -0
- package/dist/operations/contracts.d.ts +72 -0
- package/dist/operations/contracts.js +1 -0
- package/dist/operations/index.d.ts +1 -0
- package/dist/operations/index.js +1 -0
- package/dist/operations/operation-engine.d.ts +16 -0
- package/dist/operations/operation-engine.js +194 -0
- package/dist/ports/index.d.ts +12 -0
- package/{src/ports/index.ts → dist/ports/index.js} +12 -8
- package/dist/ports/location.d.ts +87 -0
- package/dist/ports/location.js +36 -0
- package/dist/ports/modem-manager.d.ts +89 -0
- package/dist/ports/modem-manager.js +9 -0
- package/dist/ports/mutation-admission.d.ts +27 -0
- package/dist/ports/mutation-admission.js +9 -0
- package/dist/ports/network-manager.d.ts +68 -0
- package/dist/ports/network-manager.js +13 -0
- package/{src/ports/observation.ts → dist/ports/observation.d.ts} +16 -27
- package/dist/ports/observation.js +7 -0
- package/dist/ports/ops.d.ts +44 -0
- package/dist/ports/ops.js +16 -0
- package/{src/ports/receipts.ts → dist/ports/receipts.d.ts} +5 -27
- package/dist/ports/receipts.js +9 -0
- package/dist/ports/reconcile.d.ts +33 -0
- package/dist/ports/reconcile.js +200 -0
- package/dist/ports/resource-ownership.d.ts +29 -0
- package/dist/ports/resource-ownership.js +1 -0
- package/dist/ports/router.d.ts +19 -0
- package/dist/ports/router.js +7 -0
- package/dist/ports/sms.d.ts +64 -0
- package/dist/ports/sms.js +24 -0
- package/dist/ports/uhubctl.d.ts +6 -0
- package/dist/ports/uhubctl.js +1 -0
- package/dist/providers/contracts.d.ts +124 -0
- package/dist/providers/contracts.js +10 -0
- package/dist/providers/huawei-hilink/index.d.ts +2 -0
- package/dist/providers/huawei-hilink/index.js +2 -0
- package/dist/providers/huawei-hilink/operations.d.ts +20 -0
- package/dist/providers/huawei-hilink/operations.js +56 -0
- package/dist/providers/huawei-hilink/provider.d.ts +52 -0
- package/dist/providers/huawei-hilink/provider.js +76 -0
- package/dist/providers/huawei-hilink/runtime.d.ts +22 -0
- package/dist/providers/huawei-hilink/runtime.js +171 -0
- package/dist/providers/huawei-hilink/session.d.ts +28 -0
- package/dist/providers/huawei-hilink/session.js +120 -0
- package/dist/providers/huawei-hilink/transport.d.ts +19 -0
- package/dist/providers/huawei-hilink/transport.js +1 -0
- package/dist/providers/index.d.ts +8 -0
- package/dist/providers/index.js +8 -0
- package/dist/providers/matcher.d.ts +3 -0
- package/dist/providers/matcher.js +205 -0
- package/dist/providers/modem-manager/errors.d.ts +7 -0
- package/dist/providers/modem-manager/errors.js +37 -0
- package/dist/providers/modem-manager/generic-operations.d.ts +10 -0
- package/dist/providers/modem-manager/generic-operations.js +209 -0
- package/dist/providers/modem-manager/index.d.ts +4 -0
- package/dist/providers/modem-manager/index.js +4 -0
- package/dist/providers/modem-manager/module-operations.d.ts +21 -0
- package/dist/providers/modem-manager/module-operations.js +118 -0
- package/dist/providers/modem-manager/provider.d.ts +41 -0
- package/dist/providers/modem-manager/provider.js +155 -0
- package/dist/providers/modem-manager/runtime-composition-operation.d.ts +32 -0
- package/dist/providers/modem-manager/runtime-composition-operation.js +151 -0
- package/dist/providers/modem-manager/snapshot.d.ts +5 -0
- package/dist/providers/modem-manager/snapshot.js +204 -0
- package/dist/providers/modem-manager/types.d.ts +137 -0
- package/dist/providers/modem-manager/types.js +1 -0
- package/dist/providers/network-manager/adapter.d.ts +71 -0
- package/dist/providers/network-manager/adapter.js +348 -0
- package/dist/providers/network-manager/index.d.ts +2 -0
- package/dist/providers/network-manager/index.js +2 -0
- package/dist/providers/network-manager/types.d.ts +171 -0
- package/dist/providers/network-manager/types.js +77 -0
- package/dist/providers/registry.d.ts +13 -0
- package/dist/providers/registry.js +33 -0
- package/dist/providers/ufi-himi/index.d.ts +6 -0
- package/dist/providers/ufi-himi/index.js +6 -0
- package/dist/providers/ufi-himi/operations.d.ts +41 -0
- package/dist/providers/ufi-himi/operations.js +66 -0
- package/dist/providers/ufi-himi/prohibitions.d.ts +62 -0
- package/dist/providers/ufi-himi/prohibitions.js +88 -0
- package/dist/providers/ufi-himi/provider.d.ts +41 -0
- package/dist/providers/ufi-himi/provider.js +204 -0
- package/dist/providers/ufi-himi/qualcomm-evidence.d.ts +32 -0
- package/dist/providers/ufi-himi/qualcomm-evidence.js +51 -0
- package/dist/providers/ufi-himi/session.d.ts +46 -0
- package/dist/providers/ufi-himi/session.js +92 -0
- package/dist/providers/ufi-himi/transport.d.ts +29 -0
- package/dist/providers/ufi-himi/transport.js +25 -0
- package/dist/providers/zte-goform/index.d.ts +2 -0
- package/dist/providers/zte-goform/index.js +2 -0
- package/dist/providers/zte-goform/provider.d.ts +56 -0
- package/dist/providers/zte-goform/provider.js +101 -0
- package/dist/providers/zte-goform/session.d.ts +23 -0
- package/dist/providers/zte-goform/session.js +197 -0
- package/dist/providers/zte-goform/transport.d.ts +16 -0
- package/dist/providers/zte-goform/transport.js +1 -0
- package/dist/radio/band-truth.d.ts +50 -0
- package/dist/radio/band-truth.js +92 -0
- package/dist/radio/index.d.ts +3 -0
- package/dist/radio/index.js +10 -0
- package/dist/radio/mode-combinations.d.ts +88 -0
- package/dist/radio/mode-combinations.js +198 -0
- package/dist/radio/mode-truth.d.ts +67 -0
- package/dist/radio/mode-truth.js +112 -0
- package/dist/redact.d.ts +15 -0
- package/dist/redact.js +189 -0
- package/dist/safety/composition-root.d.ts +28 -0
- package/dist/safety/composition-root.js +65 -0
- package/dist/safety/flock-resource-ownership.d.ts +11 -0
- package/dist/safety/flock-resource-ownership.js +138 -0
- package/dist/safety/index.d.ts +2 -0
- package/dist/safety/index.js +2 -0
- package/dist/sms/dbus-messaging.d.ts +17 -0
- package/dist/sms/dbus-messaging.js +185 -0
- package/dist/sms/inbox-store.d.ts +10 -0
- package/dist/sms/inbox-store.js +82 -0
- package/dist/sms/index.d.ts +4 -0
- package/dist/sms/index.js +10 -0
- package/dist/sms/mmcli-parse.d.ts +54 -0
- package/dist/sms/mmcli-parse.js +224 -0
- package/dist/sms/normalize.d.ts +42 -0
- package/dist/sms/normalize.js +95 -0
- package/dist/testing/domain-fakes.d.ts +58 -0
- package/dist/testing/domain-fakes.js +98 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.js +17 -0
- package/dist/testing/provider-fakes.d.ts +45 -0
- package/dist/testing/provider-fakes.js +64 -0
- package/dist/transport/calls.d.ts +9 -0
- package/dist/transport/calls.js +88 -0
- package/dist/transport/codec.d.ts +3 -0
- package/dist/transport/codec.js +207 -0
- package/dist/transport/dbus-native.d.ts +57 -0
- package/dist/transport/dbus-native.js +17 -0
- package/dist/transport/errors.d.ts +21 -0
- package/{src/transport/errors.ts → dist/transport/errors.js} +34 -46
- package/dist/transport/index.d.ts +4 -0
- package/dist/transport/index.js +9 -0
- package/dist/transport/signals.d.ts +15 -0
- package/dist/transport/signals.js +123 -0
- package/dist/transport/signature.d.ts +7 -0
- package/dist/transport/signature.js +94 -0
- package/dist/transport/transport.d.ts +2 -0
- package/dist/transport/transport.js +202 -0
- package/dist/transport/types.d.ts +61 -0
- package/dist/transport/types.js +19 -0
- package/dist/usb-mode/catalog-schema.d.ts +139 -0
- package/dist/usb-mode/catalog-schema.js +97 -0
- package/dist/usb-mode/catalog.d.ts +21 -0
- package/{src/usb-mode/catalog.ts → dist/usb-mode/catalog.js} +10 -32
- package/dist/usb-mode/certified-catalog.json +67 -0
- package/dist/usb-mode/index.d.ts +6 -0
- package/dist/usb-mode/index.js +16 -0
- package/dist/usb-mode/ingestion.d.ts +111 -0
- package/dist/usb-mode/ingestion.js +187 -0
- package/dist/usb-mode/promotion-review.d.ts +21 -0
- package/dist/usb-mode/promotion-review.js +87 -0
- package/dist/usb-mode/runtime-capability.d.ts +59 -0
- package/dist/usb-mode/runtime-capability.js +157 -0
- package/dist/usb-mode/usb-devices-parse.d.ts +36 -0
- package/dist/usb-mode/usb-devices-parse.js +157 -0
- package/dist/ussd/calls.d.ts +32 -0
- package/dist/ussd/calls.js +96 -0
- package/dist/ussd/index.d.ts +5 -0
- package/dist/ussd/index.js +12 -0
- package/dist/ussd/mm-ussd.d.ts +37 -0
- package/dist/ussd/mm-ussd.js +205 -0
- package/dist/ussd/refusal.d.ts +53 -0
- package/dist/ussd/refusal.js +154 -0
- package/dist/ussd/registration.d.ts +20 -0
- package/dist/ussd/registration.js +101 -0
- package/dist/ussd/session.d.ts +106 -0
- package/dist/ussd/session.js +163 -0
- package/package.json +38 -4
- package/src/backend/at-lease.test.ts +0 -106
- package/src/backend/at-lease.ts +0 -158
- package/src/backend/cell-info.test.ts +0 -154
- package/src/backend/cell-info.ts +0 -160
- package/src/backend/device-classifier.test.ts +0 -168
- package/src/backend/device-classifier.ts +0 -248
- package/src/backend/enrichment.ts +0 -96
- package/src/backend/features.test.ts +0 -162
- package/src/backend/features.ts +0 -179
- package/src/backend/identity-ladder.test.ts +0 -117
- package/src/backend/identity-ladder.ts +0 -221
- package/src/backend/identity-registry.test.ts +0 -89
- package/src/backend/identity-registry.ts +0 -151
- package/src/backend/index.ts +0 -236
- package/src/backend/lifecycle-interlock.ts +0 -38
- package/src/backend/managed-objects.ts +0 -108
- package/src/backend/mapping.ts +0 -160
- package/src/backend/mm-backend.ts +0 -191
- package/src/backend/mm-mutations.ts +0 -228
- package/src/backend/modem-actor.test.ts +0 -95
- package/src/backend/modem-actor.ts +0 -112
- package/src/backend/nm-auto-apn.ts +0 -161
- package/src/backend/nm-gsm-fields.ts +0 -122
- package/src/backend/nmcli-nm-port.ts +0 -228
- package/src/backend/nmcli-runner.ts +0 -52
- package/src/backend/observer.ts +0 -297
- package/src/backend/power-contract.test.ts +0 -40
- package/src/backend/power-contract.ts +0 -83
- package/src/backend/recovery-attribution.test.ts +0 -102
- package/src/backend/recovery-attribution.ts +0 -86
- package/src/backend/recovery-budget.test.ts +0 -64
- package/src/backend/recovery-budget.ts +0 -84
- package/src/backend/recovery-ladder.test.ts +0 -257
- package/src/backend/recovery-ladder.ts +0 -249
- package/src/backend/router-ethernet.test.ts +0 -71
- package/src/backend/router-ethernet.ts +0 -90
- package/src/backend/row-store.ts +0 -105
- package/src/backend/signal-setup.ts +0 -112
- package/src/backend/sim-unlock.ts +0 -193
- package/src/backend/transition-preconditions.ts +0 -149
- package/src/backend/uhubctl-power-hook.test.ts +0 -274
- package/src/backend/uhubctl-power-hook.ts +0 -377
- package/src/backend/usage/accounting.test.ts +0 -147
- package/src/backend/usage/accounting.ts +0 -123
- package/src/backend/usage/billing-cycle.test.ts +0 -62
- package/src/backend/usage/billing-cycle.ts +0 -45
- package/src/backend/usage/index.ts +0 -60
- package/src/backend/usage/policy-store.test.ts +0 -164
- package/src/backend/usage/policy-store.ts +0 -216
- package/src/backend/usage/policy-write.test.ts +0 -198
- package/src/backend/usage/policy-write.ts +0 -207
- package/src/backend/usage/proc-net-dev.test.ts +0 -56
- package/src/backend/usage/sampler.test.ts +0 -327
- package/src/backend/usage/sampler.ts +0 -282
- package/src/backend/usage/store.test.ts +0 -148
- package/src/backend/usage/store.ts +0 -177
- package/src/backend/usb-enumerator.test.ts +0 -87
- package/src/backend/usb-enumerator.ts +0 -181
- package/src/backend/usb-mode-transition.test.ts +0 -323
- package/src/backend/usb-mode-transition.ts +0 -253
- package/src/domain/brand.ts +0 -29
- package/src/domain/errors.ts +0 -77
- package/src/domain/guards.test.ts +0 -218
- package/src/domain/guards.ts +0 -144
- package/src/domain/identity.test.ts +0 -83
- package/src/domain/identity.ts +0 -165
- package/src/domain/index.ts +0 -12
- package/src/domain/snapshot.test.ts +0 -266
- package/src/domain/snapshot.ts +0 -120
- package/src/index.test.ts +0 -6
- package/src/index.ts +0 -15
- package/src/ports/README.md +0 -61
- package/src/ports/forbidden-surface.test.ts +0 -241
- package/src/ports/modem-manager.ts +0 -72
- package/src/ports/network-manager.ts +0 -87
- package/src/ports/ops.ts +0 -60
- package/src/ports/ops.type-test.ts +0 -39
- package/src/ports/receipts.test.ts +0 -153
- package/src/ports/reconcile.test.ts +0 -152
- package/src/ports/reconcile.ts +0 -338
- package/src/ports/router.ts +0 -29
- package/src/redact.test.ts +0 -82
- package/src/redact.ts +0 -73
- package/src/transport/README.md +0 -65
- package/src/transport/calls.ts +0 -113
- package/src/transport/characterization.test.ts +0 -260
- package/src/transport/codec.test.ts +0 -118
- package/src/transport/codec.ts +0 -240
- package/src/transport/conformance-python.test.ts +0 -152
- package/src/transport/conformance-same-lib.test.ts +0 -115
- package/src/transport/dbus-native-lib.d.ts +0 -19
- package/src/transport/dbus-native.ts +0 -85
- package/src/transport/index.ts +0 -30
- package/src/transport/no-library-leak.test.ts +0 -61
- package/src/transport/reliability.test.ts +0 -173
- package/src/transport/signals.ts +0 -150
- package/src/transport/signature.ts +0 -110
- package/src/transport/test-support/fake-service.ts +0 -168
- package/src/transport/test-support/independent-producer.py +0 -110
- package/src/transport/test-support/private-bus.ts +0 -66
- package/src/transport/transport.ts +0 -250
- package/src/transport/types.ts +0 -118
- package/src/usb-mode/catalog-schema.test.ts +0 -181
- package/src/usb-mode/catalog-schema.ts +0 -113
- package/src/usb-mode/certified-catalog.json +0 -67
- package/src/usb-mode/index.ts +0 -58
- package/src/usb-mode/ingestion.test.ts +0 -268
- package/src/usb-mode/ingestion.ts +0 -297
- package/src/usb-mode/promotion-review.ts +0 -117
- package/src/usb-mode/usb-devices-parse.ts +0 -196
package/src/transport/codec.ts
DELETED
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
// Signature-aware encode / decode between the transport's public value vocabulary
|
|
2
|
-
// (`DbusValue`, `bigint` for 64-bit, `DbusVariant`) and the shape the underlying
|
|
3
|
-
// `@httptoolkit/dbus-native` marshaller consumes and produces.
|
|
4
|
-
//
|
|
5
|
-
// Two invariants this layer enforces that the library does not:
|
|
6
|
-
// * 64-bit `x`/`t` are `bigint` end-to-end. On decode the library returns Long.js
|
|
7
|
-
// objects (only under `ReturnLongjs: true`); we convert them to `bigint` losslessly
|
|
8
|
-
// via their exact decimal `toString()`. On encode the library accepts a decimal
|
|
9
|
-
// string for the full 64-bit range but silently truncates a `number` above 2^53 —
|
|
10
|
-
// so we require a `bigint` and convert it to a decimal string ourselves.
|
|
11
|
-
// * `h` (UNIX_FD) is rejected up front with a typed error rather than reaching the
|
|
12
|
-
// library, which would throw a generic "Unknown/Unsupported type" instead.
|
|
13
|
-
|
|
14
|
-
import { BigIntRequiredError, SixtyFourBitRangeError, UnsupportedSignatureError } from './errors';
|
|
15
|
-
import { parseSignature, type SignatureNode, signatureFromNode } from './signature';
|
|
16
|
-
import type { DbusValue, DbusVariant } from './types';
|
|
17
|
-
|
|
18
|
-
const INT64_MIN = -(2n ** 63n);
|
|
19
|
-
const INT64_MAX = 2n ** 63n - 1n;
|
|
20
|
-
const UINT64_MAX = 2n ** 64n - 1n;
|
|
21
|
-
|
|
22
|
-
// A Long.js instance as the library hands it back with `ReturnLongjs: true`. We never
|
|
23
|
-
// import `long` (it is a transitive dependency, not ours) — we duck-type and use the
|
|
24
|
-
// exact decimal `toString()`, so no library type crosses this boundary.
|
|
25
|
-
interface LongLike {
|
|
26
|
-
readonly low: number;
|
|
27
|
-
readonly high: number;
|
|
28
|
-
readonly unsigned: boolean;
|
|
29
|
-
toString(): string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function isLongLike(value: unknown): value is LongLike {
|
|
33
|
-
return (
|
|
34
|
-
typeof value === 'object' &&
|
|
35
|
-
value !== null &&
|
|
36
|
-
typeof (value as LongLike).low === 'number' &&
|
|
37
|
-
typeof (value as LongLike).high === 'number' &&
|
|
38
|
-
typeof (value as LongLike).unsigned === 'boolean'
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function longToBigInt(value: LongLike): bigint {
|
|
43
|
-
return BigInt(value.toString());
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// ── Encode ─────────────────────────────────────────────────────────────────────────
|
|
47
|
-
// Public values → library-native body. `assertSupportedSignature` is applied to the
|
|
48
|
-
// whole signature first, so no `h` reaches the recursion.
|
|
49
|
-
export function encodeBody(signature: string, args: readonly DbusValue[]): unknown[] {
|
|
50
|
-
if (signature.includes('h')) {
|
|
51
|
-
throw new UnsupportedSignatureError(signature, 'h');
|
|
52
|
-
}
|
|
53
|
-
const nodes = parseSignature(signature);
|
|
54
|
-
if (nodes.length !== args.length) {
|
|
55
|
-
throw new Error(
|
|
56
|
-
`Body arity ${args.length} does not match signature "${signature}" (${nodes.length} types)`,
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
return nodes.map((node, i) => encodeNode(node, args[i] as DbusValue));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function encodeNode(node: SignatureNode, value: DbusValue): unknown {
|
|
63
|
-
switch (node.type) {
|
|
64
|
-
case 'x':
|
|
65
|
-
return encode64(node.type, value, INT64_MIN, INT64_MAX);
|
|
66
|
-
case 't':
|
|
67
|
-
return encode64(node.type, value, 0n, UINT64_MAX);
|
|
68
|
-
case 'a':
|
|
69
|
-
return encodeArray(node, value);
|
|
70
|
-
case '(':
|
|
71
|
-
return encodeStruct(node, value);
|
|
72
|
-
case '{':
|
|
73
|
-
return encodeDictEntry(node, value);
|
|
74
|
-
case 'v':
|
|
75
|
-
return encodeVariant(value);
|
|
76
|
-
default:
|
|
77
|
-
// y b n q i u d s o g — the library validates range/type on marshal.
|
|
78
|
-
return value;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function encode64(type: string, value: DbusValue, min: bigint, max: bigint): string {
|
|
83
|
-
if (typeof value !== 'bigint') {
|
|
84
|
-
throw new BigIntRequiredError(type, value);
|
|
85
|
-
}
|
|
86
|
-
if (value < min || value > max) {
|
|
87
|
-
throw new SixtyFourBitRangeError(type, value);
|
|
88
|
-
}
|
|
89
|
-
// Decimal string: the library parses this across the full 64-bit range losslessly.
|
|
90
|
-
return value.toString();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function encodeArray(node: SignatureNode, value: DbusValue): unknown {
|
|
94
|
-
const element = node.child[0] as SignatureNode;
|
|
95
|
-
// `ay` byte arrays pass straight through as a Uint8Array / Buffer (index-addressable).
|
|
96
|
-
if (element.type === 'y' && value instanceof Uint8Array) {
|
|
97
|
-
return value;
|
|
98
|
-
}
|
|
99
|
-
if (!Array.isArray(value)) {
|
|
100
|
-
throw new Error(`Expected array for signature "a${element.type}"`);
|
|
101
|
-
}
|
|
102
|
-
return value.map((item) => encodeNode(element, item));
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function encodeStruct(node: SignatureNode, value: DbusValue): unknown[] {
|
|
106
|
-
if (!Array.isArray(value)) {
|
|
107
|
-
throw new Error('Expected array for struct value');
|
|
108
|
-
}
|
|
109
|
-
if (value.length !== node.child.length) {
|
|
110
|
-
throw new Error(`Struct arity ${value.length} does not match ${node.child.length} field types`);
|
|
111
|
-
}
|
|
112
|
-
return node.child.map((child, i) => encodeNode(child, value[i] as DbusValue));
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function encodeDictEntry(node: SignatureNode, value: DbusValue): unknown[] {
|
|
116
|
-
if (!Array.isArray(value) || value.length !== 2) {
|
|
117
|
-
throw new Error('Expected [key, value] pair for dict entry');
|
|
118
|
-
}
|
|
119
|
-
const keyNode = node.child[0] as SignatureNode;
|
|
120
|
-
const valueNode = node.child[1] as SignatureNode;
|
|
121
|
-
return [encodeNode(keyNode, value[0] as DbusValue), encodeNode(valueNode, value[1] as DbusValue)];
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function encodeVariant(value: DbusValue): [string, unknown] {
|
|
125
|
-
const asVariant = value as DbusVariant;
|
|
126
|
-
if (typeof asVariant?.signature !== 'string' || !('value' in (asVariant as object))) {
|
|
127
|
-
throw new Error('Expected a DbusVariant ({ signature, value }) for variant field');
|
|
128
|
-
}
|
|
129
|
-
if (asVariant.signature.includes('h')) {
|
|
130
|
-
throw new UnsupportedSignatureError(asVariant.signature, 'h');
|
|
131
|
-
}
|
|
132
|
-
const inner = parseSignature(asVariant.signature);
|
|
133
|
-
if (inner.length !== 1) {
|
|
134
|
-
throw new Error(`Variant signature "${asVariant.signature}" must be exactly one complete type`);
|
|
135
|
-
}
|
|
136
|
-
return [asVariant.signature, encodeNode(inner[0] as SignatureNode, asVariant.value)];
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// ── Decode ─────────────────────────────────────────────────────────────────────────
|
|
140
|
-
// Library-native body → public values. The library must have been created with
|
|
141
|
-
// `ReturnLongjs: true` so `x`/`t` arrive as Long objects (this transport does exactly
|
|
142
|
-
// that); a raw `number` in a 64-bit slot means that flag was lost and is treated as a
|
|
143
|
-
// bug, not silently accepted.
|
|
144
|
-
export function decodeBody(signature: string, body: readonly unknown[]): DbusValue[] {
|
|
145
|
-
if (signature.includes('h')) {
|
|
146
|
-
throw new UnsupportedSignatureError(signature, 'h');
|
|
147
|
-
}
|
|
148
|
-
const nodes = parseSignature(signature);
|
|
149
|
-
return nodes.map((node, i) => decodeNode(node, body[i]));
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function decodeNode(node: SignatureNode, value: unknown): DbusValue {
|
|
153
|
-
switch (node.type) {
|
|
154
|
-
case 'x':
|
|
155
|
-
case 't':
|
|
156
|
-
return decode64(node.type, value);
|
|
157
|
-
case 'a':
|
|
158
|
-
return decodeArray(node, value);
|
|
159
|
-
case '(':
|
|
160
|
-
return decodeStruct(node, value);
|
|
161
|
-
case '{':
|
|
162
|
-
return decodeDictEntry(node, value);
|
|
163
|
-
case 'v':
|
|
164
|
-
return decodeVariant(value);
|
|
165
|
-
case 'y':
|
|
166
|
-
case 'b':
|
|
167
|
-
case 'n':
|
|
168
|
-
case 'q':
|
|
169
|
-
case 'i':
|
|
170
|
-
case 'u':
|
|
171
|
-
case 'd':
|
|
172
|
-
case 's':
|
|
173
|
-
case 'o':
|
|
174
|
-
case 'g':
|
|
175
|
-
return value as DbusValue;
|
|
176
|
-
default:
|
|
177
|
-
throw new UnsupportedSignatureError(node.type, node.type);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function decode64(type: string, value: unknown): bigint {
|
|
182
|
-
if (isLongLike(value)) {
|
|
183
|
-
return longToBigInt(value);
|
|
184
|
-
}
|
|
185
|
-
if (typeof value === 'bigint') {
|
|
186
|
-
return value;
|
|
187
|
-
}
|
|
188
|
-
// A plain number reaching here means ReturnLongjs was not applied — refuse it rather
|
|
189
|
-
// than risk having already lost precision above 2^53.
|
|
190
|
-
throw new BigIntRequiredError(type, value);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function decodeArray(node: SignatureNode, value: unknown): DbusValue {
|
|
194
|
-
const element = node.child[0] as SignatureNode;
|
|
195
|
-
if (element.type === 'y') {
|
|
196
|
-
// `ay`: the library returns a Buffer; normalise to a plain Uint8Array.
|
|
197
|
-
if (value instanceof Uint8Array) {
|
|
198
|
-
return new Uint8Array(value);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
if (!Array.isArray(value)) {
|
|
202
|
-
throw new Error(`Expected array while decoding "a${element.type}"`);
|
|
203
|
-
}
|
|
204
|
-
return value.map((item) => decodeNode(element, item));
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
function decodeStruct(node: SignatureNode, value: unknown): DbusValue {
|
|
208
|
-
if (!Array.isArray(value)) {
|
|
209
|
-
throw new Error('Expected array while decoding struct');
|
|
210
|
-
}
|
|
211
|
-
return node.child.map((child, i) => decodeNode(child, value[i]));
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function decodeDictEntry(node: SignatureNode, value: unknown): DbusValue {
|
|
215
|
-
if (!Array.isArray(value) || value.length !== 2) {
|
|
216
|
-
throw new Error('Expected [key, value] pair while decoding dict entry');
|
|
217
|
-
}
|
|
218
|
-
const keyNode = node.child[0] as SignatureNode;
|
|
219
|
-
const valueNode = node.child[1] as SignatureNode;
|
|
220
|
-
return [decodeNode(keyNode, value[0]), decodeNode(valueNode, value[1])];
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// The library decodes a variant to `[parseTree, [innerValue]]`. We recover the inner
|
|
224
|
-
// signature from the tree and decode the contained value recursively, preserving both.
|
|
225
|
-
function decodeVariant(value: unknown): DbusVariant {
|
|
226
|
-
if (!Array.isArray(value) || value.length !== 2) {
|
|
227
|
-
throw new Error('Malformed variant from library (expected [tree, [value]])');
|
|
228
|
-
}
|
|
229
|
-
const tree = value[0] as SignatureNode[];
|
|
230
|
-
const inner = value[1] as unknown[];
|
|
231
|
-
if (!Array.isArray(tree) || tree.length !== 1 || !Array.isArray(inner)) {
|
|
232
|
-
throw new Error('Malformed variant tree from library');
|
|
233
|
-
}
|
|
234
|
-
const innerNode = tree[0] as SignatureNode;
|
|
235
|
-
const innerSignature = signatureFromNode(innerNode);
|
|
236
|
-
return {
|
|
237
|
-
signature: innerSignature,
|
|
238
|
-
value: decodeNode(innerNode, inner[0]),
|
|
239
|
-
};
|
|
240
|
-
}
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
// Conformance half (b): round-trip against an INDEPENDENT `python3-dbus` producer running
|
|
2
|
-
// as a subprocess — a different implementation on the wire than the JavaScript library
|
|
3
|
-
// under test. Agreement with a foreign producer, not just the same-library fake, is the
|
|
4
|
-
// real proof the codec is correct. Exercises the MM `a{oa{sa{sv}}}` shape, `x`/`t` above
|
|
5
|
-
// 2^53, variants, and a `PropertiesChanged` signal carrying invalidated properties.
|
|
6
|
-
//
|
|
7
|
-
// Skips loudly (never fails) when the session bus or `dbus-python` bindings are absent.
|
|
8
|
-
|
|
9
|
-
import { afterAll, beforeAll, describe, expect, test } from 'bun:test';
|
|
10
|
-
import { join } from 'node:path';
|
|
11
|
-
import type { DbusTransport, SignalEvent } from './index';
|
|
12
|
-
import { createDbusTransport } from './index';
|
|
13
|
-
|
|
14
|
-
const SESSION_BUS = process.env.DBUS_SESSION_BUS_ADDRESS;
|
|
15
|
-
|
|
16
|
-
const PY_BUS_NAME = 'tv.ceralive.ModemStackPy';
|
|
17
|
-
const PY_PATH = '/tv/ceralive/pyfake';
|
|
18
|
-
const PY_IFACE = 'tv.ceralive.ModemStackPy.Conformance';
|
|
19
|
-
const PROPERTIES_IFACE = 'org.freedesktop.DBus.Properties';
|
|
20
|
-
|
|
21
|
-
const INT64_MAX = 2n ** 63n - 1n;
|
|
22
|
-
const UINT64_MAX = 2n ** 64n - 1n;
|
|
23
|
-
|
|
24
|
-
function hasDbusPython(): boolean {
|
|
25
|
-
const probe = Bun.spawnSync(['python3', '-c', 'import dbus, dbus.service, gi.repository.GLib']);
|
|
26
|
-
return probe.exitCode === 0;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async function waitForReady(proc: ReturnType<typeof Bun.spawn>, timeoutMs: number): Promise<void> {
|
|
30
|
-
const reader = (proc.stdout as ReadableStream<Uint8Array>).getReader();
|
|
31
|
-
const decoder = new TextDecoder();
|
|
32
|
-
let seen = '';
|
|
33
|
-
const deadline = Date.now() + timeoutMs;
|
|
34
|
-
try {
|
|
35
|
-
while (Date.now() < deadline) {
|
|
36
|
-
const { value, done } = await reader.read();
|
|
37
|
-
if (done) {
|
|
38
|
-
throw new Error('python producer exited before signalling READY');
|
|
39
|
-
}
|
|
40
|
-
seen += decoder.decode(value, { stream: true });
|
|
41
|
-
if (seen.includes('READY')) {
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
throw new Error('timed out waiting for python producer READY');
|
|
46
|
-
} finally {
|
|
47
|
-
reader.releaseLock();
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const runnable = Boolean(SESSION_BUS) && hasDbusPython();
|
|
52
|
-
|
|
53
|
-
describe.skipIf(!runnable)('conformance vs independent python3-dbus producer', () => {
|
|
54
|
-
let producer: ReturnType<typeof Bun.spawn>;
|
|
55
|
-
let transport: DbusTransport;
|
|
56
|
-
|
|
57
|
-
beforeAll(async () => {
|
|
58
|
-
const script = join(import.meta.dir, 'test-support', 'independent-producer.py');
|
|
59
|
-
producer = Bun.spawn(['python3', script], {
|
|
60
|
-
stdout: 'pipe',
|
|
61
|
-
stderr: 'inherit',
|
|
62
|
-
env: process.env,
|
|
63
|
-
});
|
|
64
|
-
await waitForReady(producer, 10_000);
|
|
65
|
-
transport = createDbusTransport({ busAddress: SESSION_BUS as string });
|
|
66
|
-
await transport.connect();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
afterAll(async () => {
|
|
70
|
-
await transport.disconnect();
|
|
71
|
-
producer.kill();
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
const call = (member: string, signature?: string, args?: unknown[]) =>
|
|
75
|
-
transport.callMethod({
|
|
76
|
-
destination: PY_BUS_NAME,
|
|
77
|
-
path: PY_PATH,
|
|
78
|
-
interface: PY_IFACE,
|
|
79
|
-
member,
|
|
80
|
-
...(signature !== undefined ? { signature } : {}),
|
|
81
|
-
...(args !== undefined ? { args: args as never } : {}),
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
test('the independent producer returns the a{oa{sa{sv}}} shape with 64-bit variants', async () => {
|
|
85
|
-
const reply = await call('GetManagedObjects');
|
|
86
|
-
expect(reply.signature).toBe('a{oa{sa{sv}}}');
|
|
87
|
-
expect(reply.body[0]).toEqual([
|
|
88
|
-
[
|
|
89
|
-
'/org/freedesktop/ModemManager1/Modem/0',
|
|
90
|
-
[
|
|
91
|
-
[
|
|
92
|
-
'org.freedesktop.ModemManager1.Modem',
|
|
93
|
-
[
|
|
94
|
-
['SupportedCapabilities', { signature: 't', value: UINT64_MAX }],
|
|
95
|
-
['MaxBearers', { signature: 'x', value: -INT64_MAX }],
|
|
96
|
-
['SignalQuality', { signature: 'u', value: 87 }],
|
|
97
|
-
['DeviceIdentifier', { signature: 's', value: 'py-device-0' }],
|
|
98
|
-
],
|
|
99
|
-
],
|
|
100
|
-
],
|
|
101
|
-
],
|
|
102
|
-
]);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
test('an INT64 above 2^53 from the independent producer decodes to an exact bigint', async () => {
|
|
106
|
-
const reply = await call('GetInt64');
|
|
107
|
-
expect(reply.body[0]).toBe(INT64_MAX);
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
test('a UINT64 at the 64-bit maximum from the independent producer decodes exactly', async () => {
|
|
111
|
-
const reply = await call('GetUint64');
|
|
112
|
-
expect(reply.body[0]).toBe(UINT64_MAX);
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
test('a bare variant from the independent producer preserves signature and value', async () => {
|
|
116
|
-
const reply = await call('GetVariant');
|
|
117
|
-
expect(reply.body[0]).toEqual({ signature: 't', value: UINT64_MAX });
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
test('2^63-1 round-trips through the independent producer exactly', async () => {
|
|
121
|
-
const reply = await call('EchoUint64', 't', [INT64_MAX]);
|
|
122
|
-
expect(reply.body[0]).toBe(INT64_MAX);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
test('the independent producer confirms the exact 64-bit value we encoded', async () => {
|
|
126
|
-
const reply = await call('DescribeUint64', 't', [UINT64_MAX]);
|
|
127
|
-
expect(reply.body[0]).toBe(UINT64_MAX.toString());
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
test('a PropertiesChanged signal decodes changed 64-bit values and invalidated names', async () => {
|
|
131
|
-
let resolveEvent: (event: SignalEvent) => void = () => undefined;
|
|
132
|
-
const received = new Promise<SignalEvent>((resolve) => {
|
|
133
|
-
resolveEvent = resolve;
|
|
134
|
-
});
|
|
135
|
-
const subscription = await transport.subscribeSignal(
|
|
136
|
-
{ interface: PROPERTIES_IFACE, member: 'PropertiesChanged', path: PY_PATH },
|
|
137
|
-
(event) => resolveEvent(event),
|
|
138
|
-
);
|
|
139
|
-
await call('TriggerPropertiesChanged');
|
|
140
|
-
|
|
141
|
-
const event = await received;
|
|
142
|
-
expect(event.signature).toBe('sa{sv}as');
|
|
143
|
-
const [interfaceName, changed, invalidated] = event.body;
|
|
144
|
-
expect(interfaceName).toBe(PY_IFACE);
|
|
145
|
-
expect(changed).toEqual([
|
|
146
|
-
['AccessTechnologies', { signature: 't', value: UINT64_MAX }],
|
|
147
|
-
['SignalQuality', { signature: 'u', value: 42 }],
|
|
148
|
-
]);
|
|
149
|
-
expect(invalidated).toEqual(['OperatorName', 'OperatorCode']);
|
|
150
|
-
await subscription.unsubscribe();
|
|
151
|
-
});
|
|
152
|
-
});
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
// Conformance half (a): round-trip representative signatures against a fake service built
|
|
2
|
-
// on the SAME `@httptoolkit/dbus-native` library, over a real session bus. This proves the
|
|
3
|
-
// transport works end-to-end against the daemon; half (b) proves it against an independent
|
|
4
|
-
// producer. Run under `dbus-run-session -- bun test control/src/transport`.
|
|
5
|
-
|
|
6
|
-
import { afterAll, beforeAll, describe, expect, test } from 'bun:test';
|
|
7
|
-
import type { DbusTransport } from './index';
|
|
8
|
-
import { createDbusTransport } from './index';
|
|
9
|
-
import {
|
|
10
|
-
FAKE_IFACE,
|
|
11
|
-
FAKE_PATH,
|
|
12
|
-
type FakeService,
|
|
13
|
-
INT64_MAX,
|
|
14
|
-
startFakeService,
|
|
15
|
-
UINT64_MAX,
|
|
16
|
-
} from './test-support/fake-service';
|
|
17
|
-
|
|
18
|
-
const SESSION_BUS = process.env.DBUS_SESSION_BUS_ADDRESS;
|
|
19
|
-
|
|
20
|
-
describe.skipIf(!SESSION_BUS)('conformance vs same-library fake service', () => {
|
|
21
|
-
let fake: FakeService;
|
|
22
|
-
let transport: DbusTransport;
|
|
23
|
-
|
|
24
|
-
beforeAll(async () => {
|
|
25
|
-
const busAddress = SESSION_BUS as string;
|
|
26
|
-
fake = await startFakeService({ busAddress });
|
|
27
|
-
transport = createDbusTransport({ busAddress });
|
|
28
|
-
await transport.connect();
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
afterAll(async () => {
|
|
32
|
-
await transport.disconnect();
|
|
33
|
-
await fake.stop();
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const call = (member: string, signature?: string, args?: unknown[]) =>
|
|
37
|
-
transport.callMethod({
|
|
38
|
-
destination: fake.busName,
|
|
39
|
-
path: FAKE_PATH,
|
|
40
|
-
interface: FAKE_IFACE,
|
|
41
|
-
member,
|
|
42
|
-
...(signature !== undefined ? { signature } : {}),
|
|
43
|
-
...(args !== undefined ? { args: args as never } : {}),
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
test('a basic string method replies', async () => {
|
|
47
|
-
const reply = await call('Ping');
|
|
48
|
-
expect(reply.signature).toBe('s');
|
|
49
|
-
expect(reply.body[0]).toBe('pong');
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
test('GetManagedObjects decodes the a{oa{sa{sv}}} shape with a 64-bit variant', async () => {
|
|
53
|
-
const reply = await call('GetManagedObjects');
|
|
54
|
-
expect(reply.signature).toBe('a{oa{sa{sv}}}');
|
|
55
|
-
expect(reply.body[0]).toEqual([
|
|
56
|
-
[
|
|
57
|
-
'/org/freedesktop/ModemManager1/Modem/0',
|
|
58
|
-
[
|
|
59
|
-
[
|
|
60
|
-
'org.freedesktop.ModemManager1.Modem',
|
|
61
|
-
[
|
|
62
|
-
['SupportedCapabilities', { signature: 't', value: UINT64_MAX }],
|
|
63
|
-
['SignalQuality', { signature: 'u', value: 87 }],
|
|
64
|
-
['DeviceIdentifier', { signature: 's', value: 'fake-device-0' }],
|
|
65
|
-
],
|
|
66
|
-
],
|
|
67
|
-
],
|
|
68
|
-
],
|
|
69
|
-
]);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test('an INT64 reply above 2^53 decodes to an exact bigint', async () => {
|
|
73
|
-
const reply = await call('GetInt64');
|
|
74
|
-
expect(reply.body[0]).toBe(INT64_MAX);
|
|
75
|
-
expect(typeof reply.body[0]).toBe('bigint');
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
test('a UINT64 reply at the full 64-bit maximum decodes exactly', async () => {
|
|
79
|
-
const reply = await call('GetUint64');
|
|
80
|
-
expect(reply.body[0]).toBe(UINT64_MAX);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
test('2^63-1 round-trips through the daemon exactly (encode + decode)', async () => {
|
|
84
|
-
const reply = await call('EchoUint64', 't', [INT64_MAX]);
|
|
85
|
-
expect(reply.body[0]).toBe(INT64_MAX);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
test('the full UINT64 maximum round-trips through the daemon exactly', async () => {
|
|
89
|
-
const reply = await call('EchoUint64', 't', [UINT64_MAX]);
|
|
90
|
-
expect(reply.body[0]).toBe(UINT64_MAX);
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
test('a negative INT64 round-trips through the daemon exactly', async () => {
|
|
94
|
-
const reply = await call('EchoInt64', 'x', [-INT64_MAX]);
|
|
95
|
-
expect(reply.body[0]).toBe(-INT64_MAX);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
test('the service reports back the exact 64-bit value we encoded', async () => {
|
|
99
|
-
const reply = await call('DescribeUint64', 't', [INT64_MAX]);
|
|
100
|
-
expect(reply.body[0]).toBe(INT64_MAX.toString());
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
test('passing a JS number for a 64-bit argument is refused before the wire', async () => {
|
|
104
|
-
await expect(
|
|
105
|
-
transport.callMethod({
|
|
106
|
-
destination: fake.busName,
|
|
107
|
-
path: FAKE_PATH,
|
|
108
|
-
interface: FAKE_IFACE,
|
|
109
|
-
member: 'EchoUint64',
|
|
110
|
-
signature: 't',
|
|
111
|
-
args: [123 as never],
|
|
112
|
-
}),
|
|
113
|
-
).rejects.toThrow('requires a bigint');
|
|
114
|
-
});
|
|
115
|
-
});
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// Ambient declarations for the deep library entry points the transport tests use to run
|
|
2
|
-
// an in-process, bus-free marshal/unmarshal round-trip. These are test-only reaches into
|
|
3
|
-
// `@httptoolkit/dbus-native` internals; the production transport never imports them.
|
|
4
|
-
|
|
5
|
-
declare module '@httptoolkit/dbus-native/lib/marshall' {
|
|
6
|
-
const marshall: (signature: string, data: unknown[], offset?: number) => Buffer;
|
|
7
|
-
export default marshall;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
declare module '@httptoolkit/dbus-native/lib/dbus-buffer' {
|
|
11
|
-
export default class DBusBuffer {
|
|
12
|
-
constructor(
|
|
13
|
-
buffer: Buffer,
|
|
14
|
-
startPos?: number,
|
|
15
|
-
options?: { ayBuffer?: boolean; ReturnLongjs?: boolean },
|
|
16
|
-
);
|
|
17
|
-
read(signature: string): unknown;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
// Internal typed facade over the `@httptoolkit/dbus-native` CommonJS module.
|
|
2
|
-
//
|
|
3
|
-
// The library ships a `types.d.ts` that covers only a fraction of the surface we use
|
|
4
|
-
// (no `invoke`, `addMatch`, `connection`, or `messageType`), so we describe the exact
|
|
5
|
-
// parts we depend on here and cast once, at this single boundary. NOTHING in this file
|
|
6
|
-
// is re-exported from the package's public entry (`../index.ts`): the raw library types
|
|
7
|
-
// stay quarantined behind the transport seam. See `./README.md` for why this library
|
|
8
|
-
// was chosen and the documented fallback (`@particle/dbus-next`).
|
|
9
|
-
|
|
10
|
-
import * as dbusNativeModule from '@httptoolkit/dbus-native';
|
|
11
|
-
|
|
12
|
-
// A D-Bus message as the library marshals/unmarshals it.
|
|
13
|
-
export interface RawMessage {
|
|
14
|
-
type?: number;
|
|
15
|
-
path?: string;
|
|
16
|
-
interface?: string;
|
|
17
|
-
member?: string;
|
|
18
|
-
destination?: string;
|
|
19
|
-
sender?: string;
|
|
20
|
-
signature?: string;
|
|
21
|
-
body?: unknown[];
|
|
22
|
-
errorName?: string;
|
|
23
|
-
serial?: number;
|
|
24
|
-
replySerial?: number;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// The context (`this`) the library binds when it invokes a reply callback. `signature`
|
|
28
|
-
// is the reply's own D-Bus signature — the promisified `invoke` drops this and collapses
|
|
29
|
-
// multi-value bodies, which is why we always call `invoke` with an explicit callback.
|
|
30
|
-
export interface ReplyContext {
|
|
31
|
-
signature?: string;
|
|
32
|
-
message?: RawMessage;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export type ReplyCallback = (this: ReplyContext, error: unknown, ...body: unknown[]) => void;
|
|
36
|
-
|
|
37
|
-
// The underlying stream/EventEmitter. We drive reconnect off its lifecycle events and
|
|
38
|
-
// assert on `listenerCount` in the leak test, so both are part of the facade.
|
|
39
|
-
export interface RawConnection {
|
|
40
|
-
on(event: string, handler: (...args: unknown[]) => void): void;
|
|
41
|
-
once(event: string, handler: (...args: unknown[]) => void): void;
|
|
42
|
-
removeListener(event: string, handler: (...args: unknown[]) => void): void;
|
|
43
|
-
removeAllListeners(event?: string): void;
|
|
44
|
-
listenerCount(event: string): number;
|
|
45
|
-
end(): void;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export interface RawBus {
|
|
49
|
-
connection: RawConnection;
|
|
50
|
-
invoke(message: RawMessage, callback: ReplyCallback): void;
|
|
51
|
-
addMatch(rule: string): Promise<unknown>;
|
|
52
|
-
removeMatch(rule: string): Promise<unknown>;
|
|
53
|
-
disconnect(): Promise<void>;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface CreateClientOptions {
|
|
57
|
-
busAddress?: string;
|
|
58
|
-
socket?: string;
|
|
59
|
-
// Return 64-bit `x`/`t` fields as Long.js objects instead of lossy numbers. The
|
|
60
|
-
// transport always sets this so `codec.decodeBody` can convert them to `bigint`.
|
|
61
|
-
ReturnLongjs?: boolean;
|
|
62
|
-
direct?: boolean;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export interface DbusNativeModule {
|
|
66
|
-
createClient(options: CreateClientOptions): RawBus;
|
|
67
|
-
messageType: {
|
|
68
|
-
invalid: number;
|
|
69
|
-
methodCall: number;
|
|
70
|
-
methodReturn: number;
|
|
71
|
-
error: number;
|
|
72
|
-
signal: number;
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Bun/Node CJS interop: `import *` yields the module namespace whose `default` (when
|
|
77
|
-
// present) is `module.exports`. One cast confines the untyped surface to this line.
|
|
78
|
-
const resolved = ((dbusNativeModule as { default?: unknown }).default ??
|
|
79
|
-
dbusNativeModule) as unknown as DbusNativeModule;
|
|
80
|
-
|
|
81
|
-
export const messageType = resolved.messageType;
|
|
82
|
-
|
|
83
|
-
export function createClient(options: CreateClientOptions): RawBus {
|
|
84
|
-
return resolved.createClient(options);
|
|
85
|
-
}
|
package/src/transport/index.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// Public surface of the D-Bus transport seam.
|
|
2
|
-
//
|
|
3
|
-
// This is the ONLY module the rest of `@ceralive/modem-control` (and the A3.x D-Bus
|
|
4
|
-
// backend) imports from `./transport`. Every type here is the transport's own — no
|
|
5
|
-
// `@httptoolkit/dbus-native` type is re-exported, so swapping the underlying library
|
|
6
|
-
// (documented fallback: `@particle/dbus-next`) is invisible to callers. See README.md.
|
|
7
|
-
|
|
8
|
-
export {
|
|
9
|
-
BigIntRequiredError,
|
|
10
|
-
DisconnectedError,
|
|
11
|
-
SixtyFourBitRangeError,
|
|
12
|
-
TransportError,
|
|
13
|
-
UnsupportedSignatureError,
|
|
14
|
-
} from './errors';
|
|
15
|
-
export { createDbusTransport } from './transport';
|
|
16
|
-
export type {
|
|
17
|
-
DbusTransport,
|
|
18
|
-
DbusTransportOptions,
|
|
19
|
-
DbusValue,
|
|
20
|
-
DbusVariant,
|
|
21
|
-
MethodCall,
|
|
22
|
-
MethodReply,
|
|
23
|
-
ReconnectOptions,
|
|
24
|
-
SignalEvent,
|
|
25
|
-
SignalListener,
|
|
26
|
-
SignalSpec,
|
|
27
|
-
Subscription,
|
|
28
|
-
TransportEvent,
|
|
29
|
-
} from './types';
|
|
30
|
-
export { isVariant, variant } from './types';
|