@camstack/addon-waste-collections 0.1.34 → 0.1.35

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 CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.1.35] - 2026-11-06
11
+
12
+ ### Changed
13
+
14
+ - A boot after the credentials moved to the keychain no longer crash-loops the integrations runner
15
+
10
16
  ## [0.1.34] - 2026-11-06
11
17
 
12
18
  ### Changed
@@ -6706,6 +6706,33 @@ function integrationRowsApiOver(api) {
6706
6706
  clearLegacyIntegrationRows: (input) => api.legacyRows.clear(input)
6707
6707
  };
6708
6708
  }
6709
+ /**
6710
+ * The named failures of `ctx.records` (D881).
6711
+ *
6712
+ * A records call crosses a worker thread, a UDS channel and a tRPC router, and
6713
+ * an error class does not survive any of them - only its message does. So
6714
+ * every message STARTS with a stable code, `records/<code>: <detail>`, and
6715
+ * {@link recordsErrorFromMessage} rebuilds the typed class on the caller's side.
6716
+ * A failed read is never `[]` or `undefined`: it throws one of these.
6717
+ */
6718
+ /** Every code a records failure carries. */
6719
+ var RECORDS_ERROR_CODES = [
6720
+ "rev-conflict",
6721
+ "too-large",
6722
+ "unindexed-filter",
6723
+ "filter-required",
6724
+ "unknown-kind",
6725
+ "not-found",
6726
+ "unique-violation",
6727
+ "plaintext-secret",
6728
+ "foreign-marker",
6729
+ "secret-unavailable",
6730
+ "invalid-record",
6731
+ "declaration-refused",
6732
+ "no-caller",
6733
+ "batch-too-large",
6734
+ "transact-refused"
6735
+ ];
6709
6736
  var PREFIX = "records/";
6710
6737
  /** The base of every records failure. `detail` is the human part of the message. */
6711
6738
  var RecordsError = class extends Error {
@@ -6718,6 +6745,68 @@ var RecordsError = class extends Error {
6718
6745
  this.detail = detail;
6719
6746
  }
6720
6747
  };
6748
+ /** A write guarded by `ifRev` found another revision (or an existing row for `ifRev: 0`). */
6749
+ var RevConflictError = class extends RecordsError {
6750
+ constructor(detail) {
6751
+ super("rev-conflict", detail);
6752
+ this.name = "RevConflictError";
6753
+ }
6754
+ };
6755
+ /** `data` exceeds the kind's `maxDataBytes`. Bytes are never record fields (D613). */
6756
+ var RecordTooLargeError = class extends RecordsError {
6757
+ constructor(detail) {
6758
+ super("too-large", detail);
6759
+ this.name = "RecordTooLargeError";
6760
+ }
6761
+ };
6762
+ /** A filter, order or aggregate names a field no declared index serves. */
6763
+ var UnindexedFilterError = class extends RecordsError {
6764
+ constructor(detail) {
6765
+ super("unindexed-filter", detail);
6766
+ this.name = "UnindexedFilterError";
6767
+ }
6768
+ };
6769
+ /** A bulk delete with no predicate at all. */
6770
+ var FilterRequiredError = class extends RecordsError {
6771
+ constructor(detail) {
6772
+ super("filter-required", detail);
6773
+ this.name = "FilterRequiredError";
6774
+ }
6775
+ };
6776
+ /** The caller declared no such kind (another addon's kind is indistinguishable from none). */
6777
+ var UnknownRecordKindError = class extends RecordsError {
6778
+ constructor(detail) {
6779
+ super("unknown-kind", detail);
6780
+ this.name = "UnknownRecordKindError";
6781
+ }
6782
+ };
6783
+ var RecordNotFoundError = class extends RecordsError {
6784
+ constructor(detail) {
6785
+ super("not-found", detail);
6786
+ this.name = "RecordNotFoundError";
6787
+ }
6788
+ };
6789
+ /** A unique index refused the write. */
6790
+ var RecordUniqueViolationError = class extends RecordsError {
6791
+ constructor(detail) {
6792
+ super("unique-violation", detail);
6793
+ this.name = "RecordUniqueViolationError";
6794
+ }
6795
+ };
6796
+ /** A secret field held a plain string where only a keychain marker may be stored. */
6797
+ var PlaintextSecretError = class extends RecordsError {
6798
+ constructor(detail) {
6799
+ super("plaintext-secret", detail);
6800
+ this.name = "PlaintextSecretError";
6801
+ }
6802
+ };
6803
+ /** A marker whose ref is not the row's own (the D878 rule). */
6804
+ var ForeignSecretMarkerError = class extends RecordsError {
6805
+ constructor(detail) {
6806
+ super("foreign-marker", detail);
6807
+ this.name = "ForeignSecretMarkerError";
6808
+ }
6809
+ };
6721
6810
  /** The keychain could not store or serve a value: explicit, never an empty string. */
6722
6811
  var RecordSecretUnavailableError = class extends RecordsError {
6723
6812
  constructor(detail) {
@@ -6738,6 +6827,70 @@ var DeclarationRefusedError = class extends RecordsError {
6738
6827
  this.name = "DeclarationRefusedError";
6739
6828
  }
6740
6829
  };
6830
+ var NoCallerError = class extends RecordsError {
6831
+ constructor(detail) {
6832
+ super("no-caller", detail);
6833
+ this.name = "NoCallerError";
6834
+ }
6835
+ };
6836
+ var BatchTooLargeError = class extends RecordsError {
6837
+ constructor(detail) {
6838
+ super("batch-too-large", detail);
6839
+ this.name = "BatchTooLargeError";
6840
+ }
6841
+ };
6842
+ /**
6843
+ * A `transact` the engine refuses before touching a row: an op on a kind the
6844
+ * caller did not declare in ONE file and ONE `transactFamily`. The detail names
6845
+ * which rule (`cross-file`, `cross-family`, `no-family`); it is never a silent split.
6846
+ */
6847
+ var TransactRefusedError = class extends RecordsError {
6848
+ constructor(detail) {
6849
+ super("transact-refused", detail);
6850
+ this.name = "TransactRefusedError";
6851
+ }
6852
+ };
6853
+ var FACTORIES = {
6854
+ "rev-conflict": (d) => new RevConflictError(d),
6855
+ "too-large": (d) => new RecordTooLargeError(d),
6856
+ "unindexed-filter": (d) => new UnindexedFilterError(d),
6857
+ "filter-required": (d) => new FilterRequiredError(d),
6858
+ "unknown-kind": (d) => new UnknownRecordKindError(d),
6859
+ "not-found": (d) => new RecordNotFoundError(d),
6860
+ "unique-violation": (d) => new RecordUniqueViolationError(d),
6861
+ "plaintext-secret": (d) => new PlaintextSecretError(d),
6862
+ "foreign-marker": (d) => new ForeignSecretMarkerError(d),
6863
+ "secret-unavailable": (d) => new RecordSecretUnavailableError(d),
6864
+ "invalid-record": (d) => new InvalidRecordError(d),
6865
+ "declaration-refused": (d) => new DeclarationRefusedError(d),
6866
+ "no-caller": (d) => new NoCallerError(d),
6867
+ "batch-too-large": (d) => new BatchTooLargeError(d),
6868
+ "transact-refused": (d) => new TransactRefusedError(d)
6869
+ };
6870
+ function isCode(value) {
6871
+ return RECORDS_ERROR_CODES.some((code) => code === value);
6872
+ }
6873
+ /**
6874
+ * Rebuild the typed error from a message that crossed a wire; `null` when the
6875
+ * message is not a records failure.
6876
+ */
6877
+ function recordsErrorFromMessage(message) {
6878
+ if (!message.startsWith(PREFIX)) return null;
6879
+ const colon = message.indexOf(": ");
6880
+ if (colon < 0) return null;
6881
+ const code = message.slice(8, colon);
6882
+ if (!isCode(code)) return null;
6883
+ return FACTORIES[code](message.slice(colon + 2));
6884
+ }
6885
+ /** The records failure inside any thrown value (a wrapped tRPC error included), or the value. */
6886
+ function asRecordsError(err) {
6887
+ if (err instanceof RecordsError) return err;
6888
+ if (err instanceof Error) {
6889
+ const typed = recordsErrorFromMessage(err.message);
6890
+ if (typed !== null) return typed;
6891
+ }
6892
+ return err;
6893
+ }
6741
6894
  function linkTargetOf(meta) {
6742
6895
  if (typeof meta !== "object" || meta === null) return void 0;
6743
6896
  const link = Reflect.get(meta, "link");
@@ -91694,7 +91847,7 @@ async function sealPlaintextCredentials(records, secrets, log) {
91694
91847
  try {
91695
91848
  await records.declare({ "waste-source": plainWasteSourceKind });
91696
91849
  } catch (err) {
91697
- if (err instanceof RecordsError && err.code === "declaration-refused") {
91850
+ if (asRecordsError(err) instanceof DeclarationRefusedError) {
91698
91851
  log.info("waste-collections: the secret kind is already declared; no plain-text credential can remain");
91699
91852
  return { state: "already-secret" };
91700
91853
  }
@@ -6702,6 +6702,33 @@ function integrationRowsApiOver(api) {
6702
6702
  clearLegacyIntegrationRows: (input) => api.legacyRows.clear(input)
6703
6703
  };
6704
6704
  }
6705
+ /**
6706
+ * The named failures of `ctx.records` (D881).
6707
+ *
6708
+ * A records call crosses a worker thread, a UDS channel and a tRPC router, and
6709
+ * an error class does not survive any of them - only its message does. So
6710
+ * every message STARTS with a stable code, `records/<code>: <detail>`, and
6711
+ * {@link recordsErrorFromMessage} rebuilds the typed class on the caller's side.
6712
+ * A failed read is never `[]` or `undefined`: it throws one of these.
6713
+ */
6714
+ /** Every code a records failure carries. */
6715
+ var RECORDS_ERROR_CODES = [
6716
+ "rev-conflict",
6717
+ "too-large",
6718
+ "unindexed-filter",
6719
+ "filter-required",
6720
+ "unknown-kind",
6721
+ "not-found",
6722
+ "unique-violation",
6723
+ "plaintext-secret",
6724
+ "foreign-marker",
6725
+ "secret-unavailable",
6726
+ "invalid-record",
6727
+ "declaration-refused",
6728
+ "no-caller",
6729
+ "batch-too-large",
6730
+ "transact-refused"
6731
+ ];
6705
6732
  var PREFIX = "records/";
6706
6733
  /** The base of every records failure. `detail` is the human part of the message. */
6707
6734
  var RecordsError = class extends Error {
@@ -6714,6 +6741,68 @@ var RecordsError = class extends Error {
6714
6741
  this.detail = detail;
6715
6742
  }
6716
6743
  };
6744
+ /** A write guarded by `ifRev` found another revision (or an existing row for `ifRev: 0`). */
6745
+ var RevConflictError = class extends RecordsError {
6746
+ constructor(detail) {
6747
+ super("rev-conflict", detail);
6748
+ this.name = "RevConflictError";
6749
+ }
6750
+ };
6751
+ /** `data` exceeds the kind's `maxDataBytes`. Bytes are never record fields (D613). */
6752
+ var RecordTooLargeError = class extends RecordsError {
6753
+ constructor(detail) {
6754
+ super("too-large", detail);
6755
+ this.name = "RecordTooLargeError";
6756
+ }
6757
+ };
6758
+ /** A filter, order or aggregate names a field no declared index serves. */
6759
+ var UnindexedFilterError = class extends RecordsError {
6760
+ constructor(detail) {
6761
+ super("unindexed-filter", detail);
6762
+ this.name = "UnindexedFilterError";
6763
+ }
6764
+ };
6765
+ /** A bulk delete with no predicate at all. */
6766
+ var FilterRequiredError = class extends RecordsError {
6767
+ constructor(detail) {
6768
+ super("filter-required", detail);
6769
+ this.name = "FilterRequiredError";
6770
+ }
6771
+ };
6772
+ /** The caller declared no such kind (another addon's kind is indistinguishable from none). */
6773
+ var UnknownRecordKindError = class extends RecordsError {
6774
+ constructor(detail) {
6775
+ super("unknown-kind", detail);
6776
+ this.name = "UnknownRecordKindError";
6777
+ }
6778
+ };
6779
+ var RecordNotFoundError = class extends RecordsError {
6780
+ constructor(detail) {
6781
+ super("not-found", detail);
6782
+ this.name = "RecordNotFoundError";
6783
+ }
6784
+ };
6785
+ /** A unique index refused the write. */
6786
+ var RecordUniqueViolationError = class extends RecordsError {
6787
+ constructor(detail) {
6788
+ super("unique-violation", detail);
6789
+ this.name = "RecordUniqueViolationError";
6790
+ }
6791
+ };
6792
+ /** A secret field held a plain string where only a keychain marker may be stored. */
6793
+ var PlaintextSecretError = class extends RecordsError {
6794
+ constructor(detail) {
6795
+ super("plaintext-secret", detail);
6796
+ this.name = "PlaintextSecretError";
6797
+ }
6798
+ };
6799
+ /** A marker whose ref is not the row's own (the D878 rule). */
6800
+ var ForeignSecretMarkerError = class extends RecordsError {
6801
+ constructor(detail) {
6802
+ super("foreign-marker", detail);
6803
+ this.name = "ForeignSecretMarkerError";
6804
+ }
6805
+ };
6717
6806
  /** The keychain could not store or serve a value: explicit, never an empty string. */
6718
6807
  var RecordSecretUnavailableError = class extends RecordsError {
6719
6808
  constructor(detail) {
@@ -6734,6 +6823,70 @@ var DeclarationRefusedError = class extends RecordsError {
6734
6823
  this.name = "DeclarationRefusedError";
6735
6824
  }
6736
6825
  };
6826
+ var NoCallerError = class extends RecordsError {
6827
+ constructor(detail) {
6828
+ super("no-caller", detail);
6829
+ this.name = "NoCallerError";
6830
+ }
6831
+ };
6832
+ var BatchTooLargeError = class extends RecordsError {
6833
+ constructor(detail) {
6834
+ super("batch-too-large", detail);
6835
+ this.name = "BatchTooLargeError";
6836
+ }
6837
+ };
6838
+ /**
6839
+ * A `transact` the engine refuses before touching a row: an op on a kind the
6840
+ * caller did not declare in ONE file and ONE `transactFamily`. The detail names
6841
+ * which rule (`cross-file`, `cross-family`, `no-family`); it is never a silent split.
6842
+ */
6843
+ var TransactRefusedError = class extends RecordsError {
6844
+ constructor(detail) {
6845
+ super("transact-refused", detail);
6846
+ this.name = "TransactRefusedError";
6847
+ }
6848
+ };
6849
+ var FACTORIES = {
6850
+ "rev-conflict": (d) => new RevConflictError(d),
6851
+ "too-large": (d) => new RecordTooLargeError(d),
6852
+ "unindexed-filter": (d) => new UnindexedFilterError(d),
6853
+ "filter-required": (d) => new FilterRequiredError(d),
6854
+ "unknown-kind": (d) => new UnknownRecordKindError(d),
6855
+ "not-found": (d) => new RecordNotFoundError(d),
6856
+ "unique-violation": (d) => new RecordUniqueViolationError(d),
6857
+ "plaintext-secret": (d) => new PlaintextSecretError(d),
6858
+ "foreign-marker": (d) => new ForeignSecretMarkerError(d),
6859
+ "secret-unavailable": (d) => new RecordSecretUnavailableError(d),
6860
+ "invalid-record": (d) => new InvalidRecordError(d),
6861
+ "declaration-refused": (d) => new DeclarationRefusedError(d),
6862
+ "no-caller": (d) => new NoCallerError(d),
6863
+ "batch-too-large": (d) => new BatchTooLargeError(d),
6864
+ "transact-refused": (d) => new TransactRefusedError(d)
6865
+ };
6866
+ function isCode(value) {
6867
+ return RECORDS_ERROR_CODES.some((code) => code === value);
6868
+ }
6869
+ /**
6870
+ * Rebuild the typed error from a message that crossed a wire; `null` when the
6871
+ * message is not a records failure.
6872
+ */
6873
+ function recordsErrorFromMessage(message) {
6874
+ if (!message.startsWith(PREFIX)) return null;
6875
+ const colon = message.indexOf(": ");
6876
+ if (colon < 0) return null;
6877
+ const code = message.slice(8, colon);
6878
+ if (!isCode(code)) return null;
6879
+ return FACTORIES[code](message.slice(colon + 2));
6880
+ }
6881
+ /** The records failure inside any thrown value (a wrapped tRPC error included), or the value. */
6882
+ function asRecordsError(err) {
6883
+ if (err instanceof RecordsError) return err;
6884
+ if (err instanceof Error) {
6885
+ const typed = recordsErrorFromMessage(err.message);
6886
+ if (typed !== null) return typed;
6887
+ }
6888
+ return err;
6889
+ }
6737
6890
  function linkTargetOf(meta) {
6738
6891
  if (typeof meta !== "object" || meta === null) return void 0;
6739
6892
  const link = Reflect.get(meta, "link");
@@ -91690,7 +91843,7 @@ async function sealPlaintextCredentials(records, secrets, log) {
91690
91843
  try {
91691
91844
  await records.declare({ "waste-source": plainWasteSourceKind });
91692
91845
  } catch (err) {
91693
- if (err instanceof RecordsError && err.code === "declaration-refused") {
91846
+ if (asRecordsError(err) instanceof DeclarationRefusedError) {
91694
91847
  log.info("waste-collections: the secret kind is already declared; no plain-text credential can remain");
91695
91848
  return { state: "already-secret" };
91696
91849
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-waste-collections",
3
- "version": "0.1.34",
3
+ "version": "0.1.35",
4
4
  "description": "Waste collection schedules via the vendored HACS waste_collection_schedule Python core — full source catalog as calendar-source.",
5
5
  "keywords": [
6
6
  "camstack",