@homeflare/distilled-proxmox-backup 0.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.
Files changed (113) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +102 -0
  3. package/dist/credentials.d.ts +50 -0
  4. package/dist/credentials.d.ts.map +1 -0
  5. package/dist/credentials.js +105 -0
  6. package/dist/credentials.js.map +1 -0
  7. package/dist/errors.d.ts +100 -0
  8. package/dist/errors.d.ts.map +1 -0
  9. package/dist/errors.js +73 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/index.d.ts +33 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +33 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/protocol.d.ts +19 -0
  16. package/dist/protocol.d.ts.map +1 -0
  17. package/dist/protocol.js +158 -0
  18. package/dist/protocol.js.map +1 -0
  19. package/dist/protocol.test.d.ts +2 -0
  20. package/dist/protocol.test.d.ts.map +1 -0
  21. package/dist/protocol.test.js +75 -0
  22. package/dist/protocol.test.js.map +1 -0
  23. package/dist/retry.d.ts +53 -0
  24. package/dist/retry.d.ts.map +1 -0
  25. package/dist/retry.js +46 -0
  26. package/dist/retry.js.map +1 -0
  27. package/dist/services/access.d.ts +587 -0
  28. package/dist/services/access.d.ts.map +1 -0
  29. package/dist/services/access.js +787 -0
  30. package/dist/services/access.js.map +1 -0
  31. package/dist/services/admin.d.ts +1110 -0
  32. package/dist/services/admin.d.ts.map +1 -0
  33. package/dist/services/admin.js +1428 -0
  34. package/dist/services/admin.js.map +1 -0
  35. package/dist/services/backup.d.ts +224 -0
  36. package/dist/services/backup.d.ts.map +1 -0
  37. package/dist/services/backup.js +325 -0
  38. package/dist/services/backup.js.map +1 -0
  39. package/dist/services/config.d.ts +3662 -0
  40. package/dist/services/config.d.ts.map +1 -0
  41. package/dist/services/config.js +4445 -0
  42. package/dist/services/config.js.map +1 -0
  43. package/dist/services/index.d.ts +14 -0
  44. package/dist/services/index.d.ts.map +1 -0
  45. package/dist/services/index.js +15 -0
  46. package/dist/services/index.js.map +1 -0
  47. package/dist/services/nodes.d.ts +1441 -0
  48. package/dist/services/nodes.d.ts.map +1 -0
  49. package/dist/services/nodes.js +1829 -0
  50. package/dist/services/nodes.js.map +1 -0
  51. package/dist/services/ping.d.ts +15 -0
  52. package/dist/services/ping.d.ts.map +1 -0
  53. package/dist/services/ping.js +21 -0
  54. package/dist/services/ping.js.map +1 -0
  55. package/dist/services/pull.d.ts +54 -0
  56. package/dist/services/pull.d.ts.map +1 -0
  57. package/dist/services/pull.js +47 -0
  58. package/dist/services/pull.js.map +1 -0
  59. package/dist/services/push.d.ts +50 -0
  60. package/dist/services/push.d.ts.map +1 -0
  61. package/dist/services/push.js +45 -0
  62. package/dist/services/push.js.map +1 -0
  63. package/dist/services/reader.d.ts +68 -0
  64. package/dist/services/reader.d.ts.map +1 -0
  65. package/dist/services/reader.js +89 -0
  66. package/dist/services/reader.js.map +1 -0
  67. package/dist/services/root.d.ts +14 -0
  68. package/dist/services/root.d.ts.map +1 -0
  69. package/dist/services/root.js +19 -0
  70. package/dist/services/root.js.map +1 -0
  71. package/dist/services/status.d.ts +78 -0
  72. package/dist/services/status.d.ts.map +1 -0
  73. package/dist/services/status.js +97 -0
  74. package/dist/services/status.js.map +1 -0
  75. package/dist/services/tape.d.ts +711 -0
  76. package/dist/services/tape.d.ts.map +1 -0
  77. package/dist/services/tape.js +986 -0
  78. package/dist/services/tape.js.map +1 -0
  79. package/dist/services/version.d.ts +17 -0
  80. package/dist/services/version.d.ts.map +1 -0
  81. package/dist/services/version.js +25 -0
  82. package/dist/services/version.js.map +1 -0
  83. package/dist/task.d.ts +48 -0
  84. package/dist/task.d.ts.map +1 -0
  85. package/dist/task.js +57 -0
  86. package/dist/task.js.map +1 -0
  87. package/dist/traits.d.ts +13 -0
  88. package/dist/traits.d.ts.map +1 -0
  89. package/dist/traits.js +15 -0
  90. package/dist/traits.js.map +1 -0
  91. package/package.json +81 -0
  92. package/src/credentials.ts +139 -0
  93. package/src/errors.ts +126 -0
  94. package/src/index.ts +36 -0
  95. package/src/protocol.test.ts +128 -0
  96. package/src/protocol.ts +196 -0
  97. package/src/retry.ts +79 -0
  98. package/src/services/access.ts +1787 -0
  99. package/src/services/admin.ts +3258 -0
  100. package/src/services/backup.ts +698 -0
  101. package/src/services/config.ts +10561 -0
  102. package/src/services/index.ts +14 -0
  103. package/src/services/nodes.ts +4313 -0
  104. package/src/services/ping.ts +43 -0
  105. package/src/services/pull.ts +118 -0
  106. package/src/services/push.ts +108 -0
  107. package/src/services/reader.ts +196 -0
  108. package/src/services/root.ts +39 -0
  109. package/src/services/status.ts +233 -0
  110. package/src/services/tape.ts +2257 -0
  111. package/src/services/version.ts +49 -0
  112. package/src/task.ts +84 -0
  113. package/src/traits.ts +46 -0
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @distilled.cloud/proxmox-backup — Proxmox Backup Server API SDK for
3
+ * Effect.
4
+ *
5
+ * `./services` is generated by `scripts/generate.ts` from the Smithy
6
+ * models in `.generated-specs` (written by `scripts/convert.ts` from PBS's
7
+ * own `apidoc.js`, mirrored under `specs/`). Everything else in this
8
+ * folder is hand-written.
9
+ *
10
+ * One module per PBS top-level path segment — `access`, `admin`, `backup`,
11
+ * `config`, `nodes`, `ping`, `pull`, `push`, `reader`, `root`, `status`,
12
+ * `tape`, `version` — the same split the vendor's own api-viewer uses
13
+ * (measured on the pinned schema; see `scripts/convert.ts`'s header for
14
+ * per-bucket endpoint counts).
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import * as ProxmoxBackup from "@distilled.cloud/proxmox-backup";
19
+ *
20
+ * const status = yield* ProxmoxBackup.Services.nodes.getNodeTaskStatus({
21
+ * node: "pbs1",
22
+ * upid: "UPID:pbs1:00001234:...",
23
+ * });
24
+ * ```
25
+ */
26
+ export * from "./credentials.ts";
27
+ export * from "./errors.ts";
28
+ export * as T from "./traits.ts";
29
+ export { ProxmoxBackupProtocol, type ProxmoxBackupOpError, type ProxmoxBackupOpContext, } from "./protocol.ts";
30
+ export * as Retry from "./retry.ts";
31
+ export * as Services from "./services/index.ts";
32
+ export { awaitTask, type TaskRef, type AwaitTaskOptions } from "./task.ts";
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,OAAO,KAAK,CAAC,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,qBAAqB,EACrB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC5B,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,KAAK,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @distilled.cloud/proxmox-backup — Proxmox Backup Server API SDK for
3
+ * Effect.
4
+ *
5
+ * `./services` is generated by `scripts/generate.ts` from the Smithy
6
+ * models in `.generated-specs` (written by `scripts/convert.ts` from PBS's
7
+ * own `apidoc.js`, mirrored under `specs/`). Everything else in this
8
+ * folder is hand-written.
9
+ *
10
+ * One module per PBS top-level path segment — `access`, `admin`, `backup`,
11
+ * `config`, `nodes`, `ping`, `pull`, `push`, `reader`, `root`, `status`,
12
+ * `tape`, `version` — the same split the vendor's own api-viewer uses
13
+ * (measured on the pinned schema; see `scripts/convert.ts`'s header for
14
+ * per-bucket endpoint counts).
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import * as ProxmoxBackup from "@distilled.cloud/proxmox-backup";
19
+ *
20
+ * const status = yield* ProxmoxBackup.Services.nodes.getNodeTaskStatus({
21
+ * node: "pbs1",
22
+ * upid: "UPID:pbs1:00001234:...",
23
+ * });
24
+ * ```
25
+ */
26
+ export * from "./credentials.js";
27
+ export * from "./errors.js";
28
+ export * as T from "./traits.js";
29
+ export { ProxmoxBackupProtocol, } from "./protocol.js";
30
+ export * as Retry from "./retry.js";
31
+ export * as Services from "./services/index.js";
32
+ export { awaitTask } from "./task.js";
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,OAAO,KAAK,CAAC,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,qBAAqB,GAGtB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAuC,MAAM,WAAW,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type * as Layer from "effect/Layer";
2
+ import type * as HttpClient from "effect/unstable/http/HttpClient";
3
+ import type * as HttpClientError from "effect/unstable/http/HttpClientError";
4
+ import type * as API from "@distilled.cloud/core/api";
5
+ import { type ConfigError } from "@distilled.cloud/core/errors";
6
+ import { Credentials } from "./credentials.ts";
7
+ import { type DefaultErrors } from "./errors.ts";
8
+ /**
9
+ * Error channel shared by every generated Proxmox Backup Server operation.
10
+ * Generated service files annotate operations with
11
+ * `API.OperationMethod<I, O, ProxmoxBackupOpError, ProxmoxBackupOpContext>`
12
+ * explicitly so the compiler never infers these back out of the schema
13
+ * generics.
14
+ */
15
+ export type ProxmoxBackupOpError = DefaultErrors | ConfigError | HttpClientError.HttpClientError;
16
+ /** Context (requirements) shared by every generated Proxmox Backup Server operation. */
17
+ export type ProxmoxBackupOpContext = Credentials | HttpClient.HttpClient;
18
+ export declare const ProxmoxBackupProtocol: Layer.Layer<API.Protocol>;
19
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AA4EA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,KAAK,UAAU,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,KAAK,eAAe,MAAM,sCAAsC,CAAC;AAC7E,OAAO,KAAK,KAAK,GAAG,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,8BAA8B,CAAC;AAKtC,OAAO,EAAE,WAAW,EAAe,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAErB;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAC5B,aAAa,GACb,WAAW,GACX,eAAe,CAAC,eAAe,CAAC;AAEpC,wFAAwF;AACxF,MAAM,MAAM,sBAAsB,GAAG,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC;AAwBzE,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CA6DxD,CAAC"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * ProxmoxBackupProtocol — the shared bearer-REST protocol instantiated for
3
+ * Proxmox Backup Server. Hand-written; `@distilled.cloud/core` is never
4
+ * changed for a provider's own quirks — they all live here.
5
+ *
6
+ * Ported from `packages/proxmox/src/protocol.ts` in this same distilled
7
+ * clone. Three of PVE's "THREE 200-TRAPS" carry forward; the fourth
8
+ * (cluster-forwarding 595) does not exist for PBS — see `src/errors.ts`'s
9
+ * header. Each trap below cites what was actually checked against the
10
+ * pinned schema (`~/.cache/homeflare/schemas/proxmox/
11
+ * pbs_4.2.6-1_apidoc.js`), versus what is carried by same-vendor
12
+ * architecture and NOT independently measured (this build makes no live
13
+ * PBS calls).
14
+ *
15
+ * ## The envelope
16
+ *
17
+ * Every PBS response is wrapped `{"data": …}`, the same as PVE.
18
+ * ⚠️ NOT independently measured live (no PBS credential exists to call
19
+ * with). Asserted, not just assumed: `taslabs-net/homeflare-kit`'s
20
+ * `packages/alchemy/src/proxmox/credentials.ts` documents PVE and PBS
21
+ * sharing ONE http client specifically BECAUSE "Proxmox Backup Server
22
+ * speaks the same `/api2/json` paths, wraps every answer in the same
23
+ * `{"data": …}` envelope" — also written before that repo had a live PBS
24
+ * credential, so this is the same vendor-architecture inference stated
25
+ * independently in two places, not two confirmations of one live check.
26
+ * `transformResponse` below unwraps it before `core/protocol-rest`'s
27
+ * schema-driven decode ever sees a payload, exactly as PVE's does.
28
+ *
29
+ * ## Authentication
30
+ *
31
+ * The API-token scheme: `Authorization: PBSAPIToken=<user>@<realm>!
32
+ * <tokenid>:<secret>` — MEASURED DIFFERENT FROM PVE: a colon separator,
33
+ * not `=`, and a `PBSAPIToken` prefix, not `PVEAPIToken`. See
34
+ * `src/credentials.ts`'s header for the two independent citations (kit
35
+ * `credentials.ts` and `pbs-prune-job.ts`) and their shared caveat
36
+ * (reasoned from PBS's documented scheme, not a live call either).
37
+ *
38
+ * ## THE TRAPS CARRIED FROM PVE (measured against the pinned schema)
39
+ *
40
+ * (a) **Async POST/PUT/DELETE answer 200 with a UPID and can fail later.**
41
+ * CONFIRMED IN SCHEMA: the pinned file's `pattern` for UPID-shaped
42
+ * strings appears 44 times, and `GET /nodes/{node}/tasks/{upid}/status`
43
+ * exists (measured: `grep -n 'tasks/{upid}/status'` finds it at line
44
+ * 25814) — the identical path shape PVE's own `awaitTask` polls.
45
+ * Handled with real code: `src/task.ts`'s `awaitTask`, unchanged in
46
+ * its `"OK"` exact-equality logic from PVE's (see that file's header
47
+ * for why `"OK (warnings)"` must not match a prefix/substring check).
48
+ *
49
+ * (b) **Some PUTs answer 200 `{"data":null}` even when nothing changed.**
50
+ * CONFIRMED IN SCHEMA: e.g. `PUT /access/acl` and `PUT /access/
51
+ * password` both declare `"returns": {"type": "null"}` (measured,
52
+ * among 53 total PUT endpoints in the pinned schema) — the same
53
+ * declared-null-return signature PVE's update endpoints carry. THIS IS
54
+ * NOT SOMETHING A PROTOCOL LAYER CAN DETECT OR FIX; documented here so
55
+ * it travels with the protocol.
56
+ *
57
+ * (c) **Permission-filtered lists return 200 + `[]` instead of 403.**
58
+ * CONFIRMED IN SCHEMA: `GET /access/acl`'s own `permissions.description`
59
+ * reads "Returns all ACLs if user has Sys.Audit on '/access/acl', or
60
+ * just the ACLs containing the user's API tokens" (measured, line 32
61
+ * of the pinned file) — the identical conditional-visibility-by-token
62
+ * phrasing the PVE package's header cites for this trap, not a guess
63
+ * by analogy. Also undetectable here for the same reason as (b).
64
+ *
65
+ * ## NOT carried: cluster-forwarding 595
66
+ *
67
+ * See `src/errors.ts`'s header — the pinned schema has zero `proxyto`
68
+ * occurrences. PBS is not a cluster product.
69
+ *
70
+ * ## Self-signed TLS
71
+ *
72
+ * Same as PVE: explicitly not handled here or anywhere in this package —
73
+ * the `HttpClient.HttpClient` layer the caller provides owns that
74
+ * decision.
75
+ */
76
+ import * as Effect from "effect/Effect";
77
+ import * as Redacted from "effect/Redacted";
78
+ import { BadRequest, HTTP_STATUS_MAP, } from "@distilled.cloud/core/errors";
79
+ import { makeRestProtocol, } from "@distilled.cloud/core/protocol-rest";
80
+ import { Credentials } from "./credentials.js";
81
+ import { ParameterVerificationFailed, UnknownProxmoxBackupError, } from "./errors.js";
82
+ /**
83
+ * PBS's failure envelope is `{"data": null, "message": "...", "errors"?:
84
+ * {…}}` — see PVE's identical `errorEnvelope` for why `message` alone is
85
+ * read here (the `errors` sub-object is read straight from the body in
86
+ * `unknownError` below, never here).
87
+ */
88
+ const errorEnvelope = (body) => {
89
+ if (body === null || typeof body !== "object")
90
+ return undefined;
91
+ const b = body;
92
+ return { message: typeof b.message === "string" ? b.message : undefined };
93
+ };
94
+ /**
95
+ * `HTTP_STATUS_MAP` minus 400 — same reasoning as PVE's copy: PBS's 400 is
96
+ * specifically the parameter-verification failure, and the generic
97
+ * `BadRequest` would throw away the per-field `errors` object.
98
+ */
99
+ const PROXMOX_BACKUP_STATUS_MAP = {
100
+ ...HTTP_STATUS_MAP,
101
+ };
102
+ delete PROXMOX_BACKUP_STATUS_MAP[400];
103
+ export const ProxmoxBackupProtocol = makeRestProtocol({
104
+ credentials: Effect.gen(function* () {
105
+ const resolve = yield* Credentials;
106
+ return yield* resolve;
107
+ }),
108
+ baseUrl: (creds) => creds.apiBaseUrl,
109
+ headers: (creds) => ({
110
+ // ⛔ COLON, NOT `=` — see the module header's Authentication section.
111
+ Authorization: `PBSAPIToken=${creds.tokenId}:${Redacted.value(creds.secret)}`,
112
+ Accept: "application/json",
113
+ }),
114
+ errorEnvelope,
115
+ statusMap: PROXMOX_BACKUP_STATUS_MAP,
116
+ // Unwrap PBS's `{"data": …}` envelope BEFORE the schema-driven decode —
117
+ // see the module header. `data` is `null`/absent for a Unit-output
118
+ // operation; `?? {}` is core's own convention for "no body".
119
+ transformResponse: (body) => {
120
+ if (body !== null &&
121
+ typeof body === "object" &&
122
+ "data" in body) {
123
+ return body.data ?? {};
124
+ }
125
+ return body;
126
+ },
127
+ // Reached for a 400 (see PROXMOX_BACKUP_STATUS_MAP above) or a status
128
+ // with no core mapping at all. `body` is the FULL parsed failure
129
+ // envelope, so this is where PBS's per-field `errors` object is read.
130
+ //
131
+ // ⛔ A BARE 400 WITHOUT THE `errors` OBJECT MUST NOT FALL INTO
132
+ // `UnknownProxmoxBackupError` — same retry-amplification hazard
133
+ // PVE's identical comment explains (`ServerError` is retried
134
+ // automatically; a malformed request is permanent). `BadRequest`
135
+ // (`Category.withBadRequestError`, not retryable) is the honest
136
+ // answer for "PBS said 400 and gave no further structure".
137
+ unknownError: ({ status, message, body }) => {
138
+ const b = body !== null && typeof body === "object"
139
+ ? body
140
+ : undefined;
141
+ const fieldErrors = b?.errors;
142
+ if (status === 400) {
143
+ if (fieldErrors !== null &&
144
+ typeof fieldErrors === "object" &&
145
+ !Array.isArray(fieldErrors)) {
146
+ const errors = {};
147
+ for (const [k, v] of Object.entries(fieldErrors)) {
148
+ if (typeof v === "string")
149
+ errors[k] = v;
150
+ }
151
+ return new ParameterVerificationFailed({ message, errors });
152
+ }
153
+ return new BadRequest({ message });
154
+ }
155
+ return new UnknownProxmoxBackupError({ status, message, body });
156
+ },
157
+ });
158
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0EG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAI5C,OAAO,EACL,UAAU,EACV,eAAe,GAEhB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,gBAAgB,GAEjB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAe,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,GAE1B,MAAM,aAAa,CAAC;AAiBrB;;;;;GAKG;AACH,MAAM,aAAa,GAAG,CAAC,IAAa,EAAiC,EAAE;IACrE,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChE,MAAM,CAAC,GAAG,IAA+B,CAAC;IAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;AAC5E,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,yBAAyB,GAA+C;IAC5E,GAAG,eAAe;CACnB,CAAC;AACF,OAAQ,yBAAqD,CAAC,GAAG,CAAC,CAAC;AAEnE,MAAM,CAAC,MAAM,qBAAqB,GAChC,gBAAgB,CAAS;IACvB,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC/B,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC;QACnC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC;IACxB,CAAC,CAAC;IACF,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU;IACpC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACnB,qEAAqE;QACrE,aAAa,EAAE,eAAe,KAAK,CAAC,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;QAC7E,MAAM,EAAE,kBAAkB;KAC3B,CAAC;IACF,aAAa;IACb,SAAS,EAAE,yBAAyB;IACpC,wEAAwE;IACxE,mEAAmE;IACnE,6DAA6D;IAC7D,iBAAiB,EAAE,CAAC,IAAI,EAAE,EAAE;QAC1B,IACE,IAAI,KAAK,IAAI;YACb,OAAO,IAAI,KAAK,QAAQ;YACxB,MAAM,IAAK,IAAgC,EAC3C,CAAC;YACD,OAAQ,IAAgC,CAAC,IAAI,IAAI,EAAE,CAAC;QACtD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,sEAAsE;IACtE,iEAAiE;IACjE,sEAAsE;IACtE,EAAE;IACF,8DAA8D;IAC9D,kEAAkE;IAClE,+DAA+D;IAC/D,mEAAmE;IACnE,kEAAkE;IAClE,6DAA6D;IAC7D,YAAY,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;QAC1C,MAAM,CAAC,GACL,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YACvC,CAAC,CAAE,IAAgC;YACnC,CAAC,CAAC,SAAS,CAAC;QAChB,MAAM,WAAW,GAAG,CAAC,EAAE,MAAM,CAAC;QAC9B,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,IACE,WAAW,KAAK,IAAI;gBACpB,OAAO,WAAW,KAAK,QAAQ;gBAC/B,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAC3B,CAAC;gBACD,MAAM,MAAM,GAA2B,EAAE,CAAC;gBAC1C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CACjC,WAAsC,CACvC,EAAE,CAAC;oBACF,IAAI,OAAO,CAAC,KAAK,QAAQ;wBAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBAC3C,CAAC;gBACD,OAAO,IAAI,2BAA2B,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9D,CAAC;YACD,OAAO,IAAI,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,IAAI,yBAAyB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAClE,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=protocol.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.test.d.ts","sourceRoot":"","sources":["../src/protocol.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Ported from `packages/proxmox/src/protocol.test.ts` in this same
3
+ * distilled clone — same bug class, same shape: a bare 400 (no `errors`
4
+ * object) must decode to the non-retryable `BadRequest`, never the
5
+ * `Category.withServerError`-tagged `UnknownProxmoxBackupError`. See
6
+ * `protocol.ts`'s `unknownError` and `errors.ts`'s module header.
7
+ *
8
+ * Adds one test PVE's file does not need: the auth header itself, because
9
+ * that is the one thing measurably different between the two packages
10
+ * (`PBSAPIToken=<id>:<secret>`, colon separator — see `credentials.ts`'s
11
+ * header) and a wrong separator fails SILENTLY AS A 401 with no other
12
+ * symptom, per that same header's citation of the kit's own warning. All
13
+ * of this runs against a fake `HttpClient` — no live PBS host is
14
+ * contacted anywhere in this file.
15
+ */
16
+ import { describe, expect, test } from "bun:test";
17
+ import * as Effect from "effect/Effect";
18
+ import * as Layer from "effect/Layer";
19
+ import * as HttpClient from "effect/unstable/http/HttpClient";
20
+ import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse";
21
+ import { credentials } from "./credentials.js";
22
+ import { BadRequest, ParameterVerificationFailed, UnknownProxmoxBackupError, } from "./errors.js";
23
+ import * as Retry from "./retry.js";
24
+ import { getVersion } from "./services/version.js";
25
+ const testCredentials = credentials({
26
+ tokenId: "backup@pbs!test",
27
+ secret: "test-secret",
28
+ baseUrl: "https://pbs.test:8007",
29
+ });
30
+ const fakePbs = (status, body) => Layer.succeed(HttpClient.HttpClient, HttpClient.make((request) => Effect.sync(() => HttpClientResponse.fromWeb(request, new Response(JSON.stringify(body), { status })))));
31
+ const call = (status, body) => Effect.runPromise(getVersion({}).pipe(Retry.none, Effect.provide(Layer.mergeAll(fakePbs(status, body), testCredentials)), Effect.flip));
32
+ describe("protocol.ts error decoding", () => {
33
+ test("a bare 400 (no `errors` object) is BadRequest, never UnknownProxmoxBackupError", async () => {
34
+ const error = await call(400, { data: null, message: "invalid parameter" });
35
+ expect(error).toBeInstanceOf(BadRequest);
36
+ expect(error).not.toBeInstanceOf(UnknownProxmoxBackupError);
37
+ expect(error).toMatchObject({ message: "invalid parameter" });
38
+ });
39
+ test("a 400 with an `errors` object is ParameterVerificationFailed, carrying the per-field messages", async () => {
40
+ const error = await call(400, {
41
+ data: null,
42
+ message: "parameter verification failed",
43
+ errors: { comment: "value may only be 128 characters long" },
44
+ });
45
+ expect(error).toBeInstanceOf(ParameterVerificationFailed);
46
+ expect(error).toMatchObject({
47
+ message: "parameter verification failed",
48
+ errors: { comment: "value may only be 128 characters long" },
49
+ });
50
+ });
51
+ test("a genuinely unmapped, non-5xx status still falls back to UnknownProxmoxBackupError", async () => {
52
+ const error = await call(418, { data: null, message: "weird" });
53
+ expect(error).toBeInstanceOf(UnknownProxmoxBackupError);
54
+ });
55
+ test('the {"data": ...} envelope is unwrapped before decode', async () => {
56
+ const result = await Effect.runPromise(getVersion({}).pipe(Effect.provide(Layer.mergeAll(fakePbs(200, {
57
+ data: { version: "4.2.6", release: "4.2", repoid: "abc123" },
58
+ }), testCredentials))));
59
+ expect(result).toMatchObject({ version: "4.2.6", release: "4.2" });
60
+ });
61
+ });
62
+ describe("credentials.ts auth header", () => {
63
+ test("Authorization is PBSAPIToken=<id>:<secret> — colon, never `=` like PVE's PVEAPIToken", async () => {
64
+ let seenAuth;
65
+ const capturing = Layer.succeed(HttpClient.HttpClient, HttpClient.make((request) => Effect.sync(() => {
66
+ seenAuth = request.headers["authorization"];
67
+ return HttpClientResponse.fromWeb(request, new Response(JSON.stringify({
68
+ data: { version: "4.2.6", release: "4.2", repoid: "abc" },
69
+ }), { status: 200 }));
70
+ })));
71
+ await Effect.runPromise(getVersion({}).pipe(Effect.provide(Layer.mergeAll(capturing, testCredentials))));
72
+ expect(seenAuth).toBe("PBSAPIToken=backup@pbs!test:test-secret");
73
+ });
74
+ });
75
+ //# sourceMappingURL=protocol.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.test.js","sourceRoot":"","sources":["../src/protocol.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Proxmox Backup Server retry surface — a veneer over
3
+ * `@distilled.cloud/core/retry`. Copied unchanged from
4
+ * `packages/proxmox/src/retry.ts` (no vendor-specific logic; only the
5
+ * Context.Service tag name below is package-local).
6
+ *
7
+ * The `Retry` service tag is threaded into every generated operation via
8
+ * `API.make({ retry: Retry })`, so a caller-installed policy applies to all
9
+ * Proxmox Backup Server calls below it and core's `makeDefault` is the
10
+ * fallback when none is provided.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import * as ProxmoxBackup from "@distilled.cloud/proxmox-backup";
15
+ *
16
+ * myEffect.pipe(ProxmoxBackup.Retry.transient);
17
+ * ```
18
+ */
19
+ import * as Context from "effect/Context";
20
+ import * as Effect from "effect/Effect";
21
+ import * as Retries from "@distilled.cloud/core/retry";
22
+ export type Options = Retries.Options;
23
+ export type Factory = Retries.Factory;
24
+ export type Policy = Retries.Policy;
25
+ declare const Retry_base: Context.ServiceClass<Retry, "ProxmoxBackupRetry", Retries.Policy>;
26
+ /** Context tag for configuring retry behavior of Proxmox Backup Server API calls. */
27
+ export declare class Retry extends Retry_base {
28
+ }
29
+ /** Provides a custom retry policy to every Proxmox Backup Server API call below it. */
30
+ export declare const policy: {
31
+ (options: Options): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Retry>>;
32
+ (factory: Factory): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Retry>>;
33
+ };
34
+ /** Disables all automatic retries. */
35
+ export declare const none: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Retry>>;
36
+ /**
37
+ * The default retry policy (core's): transient/throttling/retryable errors,
38
+ * capped exponential backoff with jitter, server `retryAfter` hints honored
39
+ * with precedence.
40
+ */
41
+ export declare const makeDefault: Factory;
42
+ export declare const jittered: <Error, Env>(self: import("effect/Schedule").Schedule<unknown, unknown, Error, Env>) => import("effect/Schedule").Schedule<unknown, unknown, Error, Env>;
43
+ export declare const capped: (max: import("effect/Duration").Duration) => <Error, Env>(self: import("effect/Schedule").Schedule<unknown, unknown, Error, Env>) => import("effect/Schedule").Schedule<unknown, unknown, Error, Env>;
44
+ /** Retry options that retry all throttling errors indefinitely. */
45
+ export declare const throttlingOptions: Options;
46
+ /** Retries all throttling errors indefinitely (honoring server hints). */
47
+ export declare const throttling: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Retry>>;
48
+ /** Retry options that retry all transient errors indefinitely. */
49
+ export declare const transientOptions: Options;
50
+ /** Retries all transient errors indefinitely (honoring server hints). */
51
+ export declare const transient: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Retry>>;
52
+ export {};
53
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,OAAO,MAAM,6BAA6B,CAAC;AAEvD,MAAM,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;AACtC,MAAM,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;AACtC,MAAM,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;;AAEpC,qFAAqF;AACrF,qBAAa,KAAM,SAAQ,UAE1B;CAAG;AAEJ,uFAAuF;AACvF,eAAO,MAAM,MAAM,EAAE;IACnB,CACE,OAAO,EAAE,OAAO,GACf,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAC5C,CACE,OAAO,EAAE,OAAO,GACf,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;CAEU,CAAC;AAEzD,sCAAsC;AACtC,eAAO,MAAM,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACzB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAEzC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,OAA6B,CAAC;AAExD,eAAO,MAAM,QAAQ,0JAAmB,CAAC;AACzC,eAAO,MAAM,MAAM,uMAAiB,CAAC;AAErC,mEAAmE;AACnE,eAAO,MAAM,iBAAiB,EAAE,OAAmC,CAAC;AAEpE,0EAA0E;AAC1E,eAAO,MAAM,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAqC,CAAC;AAEhF,kEAAkE;AAClE,eAAO,MAAM,gBAAgB,EAAE,OAAkC,CAAC;AAElE,yEAAyE;AACzE,eAAO,MAAM,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAoC,CAAC"}
package/dist/retry.js ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Proxmox Backup Server retry surface — a veneer over
3
+ * `@distilled.cloud/core/retry`. Copied unchanged from
4
+ * `packages/proxmox/src/retry.ts` (no vendor-specific logic; only the
5
+ * Context.Service tag name below is package-local).
6
+ *
7
+ * The `Retry` service tag is threaded into every generated operation via
8
+ * `API.make({ retry: Retry })`, so a caller-installed policy applies to all
9
+ * Proxmox Backup Server calls below it and core's `makeDefault` is the
10
+ * fallback when none is provided.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import * as ProxmoxBackup from "@distilled.cloud/proxmox-backup";
15
+ *
16
+ * myEffect.pipe(ProxmoxBackup.Retry.transient);
17
+ * ```
18
+ */
19
+ import * as Context from "effect/Context";
20
+ import * as Effect from "effect/Effect";
21
+ import * as Layer from "effect/Layer";
22
+ import * as Retries from "@distilled.cloud/core/retry";
23
+ /** Context tag for configuring retry behavior of Proxmox Backup Server API calls. */
24
+ export class Retry extends Context.Service()("ProxmoxBackupRetry") {
25
+ }
26
+ /** Provides a custom retry policy to every Proxmox Backup Server API call below it. */
27
+ export const policy = (optionsOrFactory) => Effect.provide(Layer.succeed(Retry, optionsOrFactory));
28
+ /** Disables all automatic retries. */
29
+ export const none = Effect.provide(Layer.succeed(Retry, { while: () => false }));
30
+ /**
31
+ * The default retry policy (core's): transient/throttling/retryable errors,
32
+ * capped exponential backoff with jitter, server `retryAfter` hints honored
33
+ * with precedence.
34
+ */
35
+ export const makeDefault = Retries.makeDefault;
36
+ export const jittered = Retries.jittered;
37
+ export const capped = Retries.capped;
38
+ /** Retry options that retry all throttling errors indefinitely. */
39
+ export const throttlingOptions = Retries.throttlingOptions;
40
+ /** Retries all throttling errors indefinitely (honoring server hints). */
41
+ export const throttling = policy(Retries.throttlingFactory);
42
+ /** Retry options that retry all transient errors indefinitely. */
43
+ export const transientOptions = Retries.transientOptions;
44
+ /** Retries all transient errors indefinitely (honoring server hints). */
45
+ export const transient = policy(Retries.transientFactory);
46
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,OAAO,MAAM,6BAA6B,CAAC;AAMvD,qFAAqF;AACrF,MAAM,OAAO,KAAM,SAAQ,OAAO,CAAC,OAAO,EAAiB,CACzD,oBAAoB,CACrB;CAAG;AAEJ,uFAAuF;AACvF,MAAM,CAAC,MAAM,MAAM,GAWf,CAAC,gBAAmC,EAAE,EAAE,CAC1C,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAEzD,sCAAsC;AACtC,MAAM,CAAC,MAAM,IAAI,GAE6B,MAAM,CAAC,OAAO,CAC1D,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,CAC7C,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAY,OAAO,CAAC,WAAW,CAAC;AAExD,MAAM,CAAC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;AACzC,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;AAErC,mEAAmE;AACnE,MAAM,CAAC,MAAM,iBAAiB,GAAY,OAAO,CAAC,iBAAiB,CAAC;AAEpE,0EAA0E;AAC1E,MAAM,CAAC,MAAM,UAAU,GAEuB,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEhF,kEAAkE;AAClE,MAAM,CAAC,MAAM,gBAAgB,GAAY,OAAO,CAAC,gBAAgB,CAAC;AAElE,yEAAyE;AACzE,MAAM,CAAC,MAAM,SAAS,GAEwB,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC"}