@homeflare/alchemy 0.27.4 → 0.29.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 (217) hide show
  1. package/README.md +2 -0
  2. package/dist/caddy/admin-address.d.ts +27 -0
  3. package/dist/caddy/admin-address.d.ts.map +1 -0
  4. package/dist/caddy/admin-calls.d.ts +25 -28
  5. package/dist/caddy/admin-calls.d.ts.map +1 -1
  6. package/dist/caddy/admin.d.ts +28 -38
  7. package/dist/caddy/admin.d.ts.map +1 -1
  8. package/dist/caddy/caddy-http-client.d.ts +25 -0
  9. package/dist/caddy/caddy-http-client.d.ts.map +1 -0
  10. package/dist/caddy/config-errors.d.ts +24 -0
  11. package/dist/caddy/config-errors.d.ts.map +1 -0
  12. package/dist/caddy/config-lifecycle.d.ts +20 -49
  13. package/dist/caddy/config-lifecycle.d.ts.map +1 -1
  14. package/dist/caddy/config-reconcile.d.ts +45 -0
  15. package/dist/caddy/config-reconcile.d.ts.map +1 -0
  16. package/dist/caddy/config.d.ts +4 -3
  17. package/dist/caddy/config.d.ts.map +1 -1
  18. package/dist/caddy/fake-caddy.d.ts +10 -2
  19. package/dist/caddy/fake-caddy.d.ts.map +1 -1
  20. package/dist/caddy/index.d.ts +3 -3
  21. package/dist/caddy/index.d.ts.map +1 -1
  22. package/dist/caddy/index.js +487 -444
  23. package/dist/caddy/index.js.map +16 -12
  24. package/dist/caddy/local-admin.d.ts +20 -34
  25. package/dist/caddy/local-admin.d.ts.map +1 -1
  26. package/dist/caddy/providers.d.ts +19 -3
  27. package/dist/caddy/providers.d.ts.map +1 -1
  28. package/dist/cloudflare/mesh-node-token.d.ts +1 -1
  29. package/dist/cloudflare/mesh-node-token.d.ts.map +1 -1
  30. package/dist/forgejo/branch-protection.d.ts +4 -4
  31. package/dist/forgejo/org-actions-secrets.d.ts +4 -4
  32. package/dist/forgejo/org-label.d.ts +4 -4
  33. package/dist/forgejo/org-team.d.ts +4 -4
  34. package/dist/forgejo/repo-webhook.d.ts +4 -4
  35. package/dist/forgejo/repository.d.ts +4 -4
  36. package/dist/forgejo/team-member.d.ts +4 -4
  37. package/dist/github/declare-repo-baseline.d.ts +1 -1
  38. package/dist/github/declare-repo-baseline.d.ts.map +1 -1
  39. package/dist/github/index.d.ts +9 -5
  40. package/dist/github/index.d.ts.map +1 -1
  41. package/dist/github/index.js +161 -25
  42. package/dist/github/index.js.map +15 -13
  43. package/dist/github/repo-baseline-data.d.ts +10 -1
  44. package/dist/github/repo-baseline-data.d.ts.map +1 -1
  45. package/dist/github/repo-policy.d.ts +1 -1
  46. package/dist/github/repo-policy.d.ts.map +1 -1
  47. package/dist/github/repository-ruleset-errors.d.ts +37 -3
  48. package/dist/github/repository-ruleset-errors.d.ts.map +1 -1
  49. package/dist/github/repository-ruleset-form.d.ts.map +1 -1
  50. package/dist/github/repository-ruleset-guards.d.ts +15 -2
  51. package/dist/github/repository-ruleset-guards.d.ts.map +1 -1
  52. package/dist/github/repository-ruleset-narrowing-guards.d.ts +39 -0
  53. package/dist/github/repository-ruleset-narrowing-guards.d.ts.map +1 -0
  54. package/dist/github/repository-ruleset-octokit.d.ts +49 -0
  55. package/dist/github/repository-ruleset-octokit.d.ts.map +1 -1
  56. package/dist/github/repository-ruleset-probe.d.ts +2 -1
  57. package/dist/github/repository-ruleset-probe.d.ts.map +1 -1
  58. package/dist/github/repository-ruleset-props.d.ts +91 -0
  59. package/dist/github/repository-ruleset-props.d.ts.map +1 -0
  60. package/dist/github/repository-ruleset-providers.d.ts +42 -0
  61. package/dist/github/repository-ruleset-providers.d.ts.map +1 -0
  62. package/dist/github/repository-ruleset-reconcile.d.ts.map +1 -1
  63. package/dist/github/repository-ruleset.d.ts +28 -34
  64. package/dist/github/repository-ruleset.d.ts.map +1 -1
  65. package/dist/litellm/fake-litellm.d.ts +27 -16
  66. package/dist/litellm/fake-litellm.d.ts.map +1 -1
  67. package/dist/litellm/fake-stack.d.ts +9 -4
  68. package/dist/litellm/fake-stack.d.ts.map +1 -1
  69. package/dist/litellm/index.d.ts +7 -5
  70. package/dist/litellm/index.d.ts.map +1 -1
  71. package/dist/litellm/index.js +53 -123
  72. package/dist/litellm/index.js.map +8 -8
  73. package/dist/litellm/operations.d.ts +60 -0
  74. package/dist/litellm/operations.d.ts.map +1 -0
  75. package/dist/litellm/pass-through-endpoint.d.ts +10 -28
  76. package/dist/litellm/pass-through-endpoint.d.ts.map +1 -1
  77. package/dist/litellm/pass-through-errors.d.ts +37 -0
  78. package/dist/litellm/pass-through-errors.d.ts.map +1 -0
  79. package/dist/litellm/pass-through-form.d.ts +11 -4
  80. package/dist/litellm/pass-through-form.d.ts.map +1 -1
  81. package/dist/litellm/providers.d.ts +7 -5
  82. package/dist/litellm/providers.d.ts.map +1 -1
  83. package/dist/netbox/prefix.d.ts +4 -4
  84. package/dist/paperless/custom-field.d.ts +21 -21
  85. package/dist/paperless/custom-field.d.ts.map +1 -1
  86. package/dist/paperless/document-type.d.ts +34 -4
  87. package/dist/paperless/document-type.d.ts.map +1 -1
  88. package/dist/paperless/fake-paperless.d.ts +36 -19
  89. package/dist/paperless/fake-paperless.d.ts.map +1 -1
  90. package/dist/paperless/index.d.ts +7 -2
  91. package/dist/paperless/index.d.ts.map +1 -1
  92. package/dist/paperless/index.js +164 -228
  93. package/dist/paperless/index.js.map +10 -13
  94. package/dist/paperless/matching-locate.d.ts +42 -20
  95. package/dist/paperless/matching-locate.d.ts.map +1 -1
  96. package/dist/paperless/matching-types.d.ts +47 -18
  97. package/dist/paperless/matching-types.d.ts.map +1 -1
  98. package/dist/paperless/matching.d.ts +30 -27
  99. package/dist/paperless/matching.d.ts.map +1 -1
  100. package/dist/paperless/providers.d.ts +13 -7
  101. package/dist/paperless/providers.d.ts.map +1 -1
  102. package/dist/paperless/storage-path.d.ts +34 -4
  103. package/dist/paperless/storage-path.d.ts.map +1 -1
  104. package/dist/paperless/tag.d.ts +43 -8
  105. package/dist/paperless/tag.d.ts.map +1 -1
  106. package/dist/proxmox/acl.d.ts +30 -23
  107. package/dist/proxmox/acl.d.ts.map +1 -1
  108. package/dist/proxmox/distilled-pve.d.ts +89 -0
  109. package/dist/proxmox/distilled-pve.d.ts.map +1 -0
  110. package/dist/proxmox/index.js +663 -609
  111. package/dist/proxmox/index.js.map +12 -11
  112. package/dist/proxmox/members.d.ts +29 -10
  113. package/dist/proxmox/members.d.ts.map +1 -1
  114. package/docs/caddy-admin.md +1 -1
  115. package/docs/caddy.md +3 -2
  116. package/docs/credentials.md +16 -0
  117. package/docs/litellm.md +21 -13
  118. package/docs/paperless.md +12 -0
  119. package/docs/peers.md +5 -0
  120. package/docs/repo-policy.md +16 -1
  121. package/docs/repository-ruleset.md +53 -13
  122. package/docs/upstream-conformance.md +126 -10
  123. package/package.json +9 -2
  124. package/src/caddy/admin-address.ts +71 -0
  125. package/src/caddy/admin-calls.ts +48 -100
  126. package/src/caddy/admin.ts +37 -41
  127. package/src/caddy/adopt-scope.test.ts +1 -1
  128. package/src/caddy/caddy-http-client.ts +229 -0
  129. package/src/caddy/config-adopt-provider.test.ts +139 -0
  130. package/src/caddy/config-adopt.test.ts +60 -126
  131. package/src/caddy/config-errors.ts +47 -0
  132. package/src/caddy/config-lifecycle.test.ts +55 -42
  133. package/src/caddy/config-lifecycle.ts +72 -162
  134. package/src/caddy/config-reconcile.ts +138 -0
  135. package/src/caddy/config.ts +36 -42
  136. package/src/caddy/fake-caddy.ts +20 -2
  137. package/src/caddy/index.ts +3 -8
  138. package/src/caddy/local-admin.test.ts +35 -21
  139. package/src/caddy/local-admin.ts +60 -167
  140. package/src/caddy/providers.test.ts +14 -6
  141. package/src/caddy/providers.ts +20 -4
  142. package/src/github/declare-repo-baseline.ts +6 -6
  143. package/src/github/index.ts +10 -4
  144. package/src/github/repo-baseline-data.test.ts +13 -0
  145. package/src/github/repo-baseline-data.ts +11 -2
  146. package/src/github/repo-policy-stack.test.ts +59 -0
  147. package/src/github/repo-policy.ts +3 -2
  148. package/src/github/repository-ruleset-errors.ts +51 -4
  149. package/src/github/repository-ruleset-exact-adopt-k1.test.ts +109 -0
  150. package/src/github/repository-ruleset-exact-adopt.test.ts +184 -0
  151. package/src/github/repository-ruleset-form.ts +7 -3
  152. package/src/github/repository-ruleset-guards.ts +11 -4
  153. package/src/github/repository-ruleset-narrowing-guards.ts +141 -0
  154. package/src/github/repository-ruleset-narrowing.test.ts +210 -0
  155. package/src/github/repository-ruleset-octokit.test.ts +141 -0
  156. package/src/github/repository-ruleset-octokit.ts +121 -30
  157. package/src/github/repository-ruleset-probe.ts +2 -1
  158. package/src/github/repository-ruleset-props.ts +95 -0
  159. package/src/github/repository-ruleset-providers.ts +46 -0
  160. package/src/github/repository-ruleset-reconcile.ts +35 -0
  161. package/src/github/repository-ruleset-wire.test.ts +38 -27
  162. package/src/github/repository-ruleset-write-refusals.test.ts +6 -26
  163. package/src/github/repository-ruleset.ts +53 -43
  164. package/src/litellm/fake-litellm.ts +83 -78
  165. package/src/litellm/fake-stack.ts +13 -5
  166. package/src/litellm/index.ts +7 -21
  167. package/src/litellm/operations.ts +149 -0
  168. package/src/litellm/pass-through-endpoint-delete-swallow.test.ts +17 -20
  169. package/src/litellm/pass-through-endpoint-replace.test.ts +3 -4
  170. package/src/litellm/pass-through-endpoint.test.ts +8 -8
  171. package/src/litellm/pass-through-endpoint.ts +21 -31
  172. package/src/litellm/pass-through-errors.ts +37 -0
  173. package/src/litellm/pass-through-form.ts +20 -10
  174. package/src/litellm/providers.ts +8 -7
  175. package/src/paperless/custom-field.test.ts +49 -40
  176. package/src/paperless/custom-field.ts +57 -33
  177. package/src/paperless/document-type.test.ts +48 -0
  178. package/src/paperless/document-type.ts +51 -22
  179. package/src/paperless/fake-paperless.ts +63 -72
  180. package/src/paperless/index.ts +7 -13
  181. package/src/paperless/matching-locate.test.ts +102 -0
  182. package/src/paperless/matching-locate.ts +80 -86
  183. package/src/paperless/matching-types.ts +49 -16
  184. package/src/paperless/matching.ts +77 -90
  185. package/src/paperless/providers.ts +14 -10
  186. package/src/paperless/storage-path.test.ts +56 -0
  187. package/src/paperless/storage-path.ts +53 -24
  188. package/src/paperless/tag-identity.test.ts +127 -0
  189. package/src/paperless/tag.test.ts +100 -0
  190. package/src/paperless/tag.ts +62 -32
  191. package/src/proxmox/acl.test.ts +145 -0
  192. package/src/proxmox/acl.ts +128 -150
  193. package/src/proxmox/distilled-pve.test.ts +231 -0
  194. package/src/proxmox/distilled-pve.ts +147 -0
  195. package/src/proxmox/members-timeout.test.ts +161 -0
  196. package/src/proxmox/members.test.ts +9 -0
  197. package/src/proxmox/members.ts +36 -2
  198. package/dist/litellm/client.d.ts +0 -76
  199. package/dist/litellm/client.d.ts.map +0 -1
  200. package/dist/litellm/credentials.d.ts +0 -48
  201. package/dist/litellm/credentials.d.ts.map +0 -1
  202. package/dist/litellm/generated/pass-through.d.ts +0 -71
  203. package/dist/litellm/generated/pass-through.d.ts.map +0 -1
  204. package/dist/paperless/client.d.ts +0 -37
  205. package/dist/paperless/client.d.ts.map +0 -1
  206. package/dist/paperless/credentials.d.ts +0 -40
  207. package/dist/paperless/credentials.d.ts.map +0 -1
  208. package/dist/paperless/errors.d.ts +0 -49
  209. package/dist/paperless/errors.d.ts.map +0 -1
  210. package/src/litellm/client.ts +0 -195
  211. package/src/litellm/credentials.ts +0 -73
  212. package/src/litellm/generated/pass-through.ts +0 -73
  213. package/src/paperless/client.ts +0 -88
  214. package/src/paperless/credentials.ts +0 -69
  215. package/src/paperless/errors.ts +0 -62
  216. package/src/paperless/matching-identity.test.ts +0 -194
  217. package/src/paperless/matching.test.ts +0 -128
@@ -1,55 +1,5 @@
1
- // src/paperless/credentials.ts
2
- import * as Context from "effect/Context";
3
- import * as Data from "effect/Data";
4
- import * as Effect from "effect/Effect";
5
- import * as Layer from "effect/Layer";
6
-
7
- class PaperlessCredentialsError extends Data.TaggedError("PaperlessCredentialsError") {
8
- }
9
- var readEnvironment = Effect.suspend(() => {
10
- const url = process.env["PAPERLESS_URL"];
11
- const token = process.env["PAPERLESS_TOKEN"];
12
- if (url === undefined || url.trim() === "") {
13
- return Effect.fail(new PaperlessCredentialsError({
14
- message: "PAPERLESS_URL is not set. Point it at your Paperless-ngx instance."
15
- }));
16
- }
17
- if (token === undefined || token.trim() === "") {
18
- return Effect.fail(new PaperlessCredentialsError({
19
- message: "PAPERLESS_TOKEN is not set. Mint a scoped token and export it — never store it in Alchemy props."
20
- }));
21
- }
22
- return Effect.succeed({ token: token.trim(), url: url.trim().replace(/\/$/, "") });
23
- });
24
-
25
- class PaperlessCredentials extends Context.Service()("PaperlessCredentials") {
26
- }
27
- var environmentLayer = Layer.succeed(PaperlessCredentials, readEnvironment);
28
- // src/paperless/errors.ts
29
- import * as Data2 from "effect/Data";
30
-
31
- class PaperlessNotFound extends Data2.TaggedError("PaperlessNotFound") {
32
- }
33
-
34
- class PaperlessUnauthorized extends Data2.TaggedError("PaperlessUnauthorized") {
35
- }
36
-
37
- class PaperlessValidation extends Data2.TaggedError("PaperlessValidation") {
38
- }
39
-
40
- class PaperlessUnavailable extends Data2.TaggedError("PaperlessUnavailable") {
41
- }
42
- var statusToError = (status, method, path, body) => {
43
- if (status === 404)
44
- return new PaperlessNotFound({ method, path });
45
- if (status === 401 || status === 403)
46
- return new PaperlessUnauthorized({ method, path, status });
47
- if (status >= 500)
48
- return new PaperlessUnavailable({ detail: body, method, path, status });
49
- return new PaperlessValidation({ body, method, path });
50
- };
51
1
  // src/paperless/constraint-guard.ts
52
- import * as Effect2 from "effect/Effect";
2
+ import * as Effect from "effect/Effect";
53
3
 
54
4
  // src/paperless/constraints.ts
55
5
  var lengthOf = (value) => [...value].length;
@@ -180,78 +130,52 @@ var constraintsFor = (key) => {
180
130
  return table;
181
131
  };
182
132
  var bodyViolations = (key, body, presence) => violations(constraintsFor(key), body, { presence });
183
- var guardBody = (key, body, presence) => Effect2.suspend(() => {
133
+ var guardBody = (key, body, presence) => Effect.suspend(() => {
184
134
  if (key === undefined)
185
- return Effect2.void;
135
+ return Effect.void;
186
136
  const found = bodyViolations(key, body, presence);
187
- return found.length === 0 ? Effect2.void : Effect2.die(new Error(refusal(key, found)));
137
+ return found.length === 0 ? Effect.void : Effect.die(new Error(refusal(key, found)));
188
138
  });
189
139
  // src/paperless/tag.ts
190
140
  import { Resource } from "alchemy";
191
141
  import * as Provider from "alchemy/Provider";
192
- import * as Effect6 from "effect/Effect";
142
+ import * as tags from "@distilled.cloud/paperless-ngx/tags";
143
+ import * as Effect4 from "effect/Effect";
193
144
 
194
145
  // src/paperless/matching.ts
195
146
  import { Unowned } from "alchemy/AdoptPolicy";
196
147
  import { isResolved } from "alchemy/Diff";
197
- import * as Effect5 from "effect/Effect";
198
-
199
- // src/paperless/client.ts
148
+ import { CredentialsFromEnv } from "@distilled.cloud/paperless-ngx/Credentials";
200
149
  import * as Effect3 from "effect/Effect";
201
- import * as HttpClient from "effect/unstable/http/HttpClient";
202
- import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
203
- var PATH_PREFIX = "/api";
204
- var API_VERSION = "10";
205
- var paperless = (method, path, body) => Effect3.gen(function* () {
206
- const credentials = yield* yield* PaperlessCredentials;
207
- const url = `${credentials.url}${PATH_PREFIX}/${path.replace(/^\//, "")}`;
208
- const client = yield* HttpClient.HttpClient;
209
- const request = HttpClientRequest.make(method)(url).pipe(HttpClientRequest.setHeaders({
210
- Accept: `application/json; version=${API_VERSION}`,
211
- Authorization: `Token ${credentials.token}`
212
- }), body === undefined ? (self) => self : HttpClientRequest.bodyText(JSON.stringify(body), "application/json"));
213
- const response = yield* client.execute(request).pipe(Effect3.mapError((cause) => new PaperlessUnavailable({ detail: String(cause), method, path, status: 0 })));
214
- if (response.status < 200 || response.status >= 300) {
215
- const detail = yield* response.text.pipe(Effect3.orElseSucceed(() => ""));
216
- return yield* Effect3.fail(statusToError(response.status, method, path, detail.slice(0, 500)));
217
- }
218
- const text = yield* response.text.pipe(Effect3.mapError(() => new PaperlessUnavailable({
219
- detail: "body read failed",
220
- method,
221
- path,
222
- status: response.status
223
- })));
224
- return text === "" ? undefined : JSON.parse(text);
225
- });
226
150
 
227
151
  // src/paperless/matching-locate.ts
228
- import * as Effect4 from "effect/Effect";
229
- var absentOn404 = (io) => io.pipe(Effect4.catchIf((cause) => cause instanceof PaperlessNotFound, () => Effect4.succeed(undefined)));
152
+ import * as Effect2 from "effect/Effect";
230
153
  var LOCATE_PAGE = 20;
231
- var ownerOf = (row) => typeof row["owner"] === "number" ? row["owner"] : undefined;
232
- var matchingLocate = (spec) => {
233
- const fetchByName = (props) => absentOn404(paperless("GET", `${spec.collection}/?name__iexact=${encodeURIComponent(props.name)}&page_size=${String(LOCATE_PAGE)}`)).pipe(Effect4.map((list) => {
234
- if (list !== undefined && list.count > LOCATE_PAGE) {
235
- throw new Error(`${spec.describe(props)}: name__iexact matched ${String(list.count)} rows, more than ` + `the ${String(LOCATE_PAGE)}-row page this reads. Narrow the name rather than paging.`);
236
- }
237
- const rows = (list?.results ?? []).filter((row) => row["name"] === props.name && ownerOf(row) === (props.owner ?? undefined));
238
- if (rows.length > 1) {
239
- throw new Error(`${spec.describe(props)}: matched ${String(rows.length)} Paperless objects with the same (name, owner).`);
240
- }
241
- return rows[0];
242
- }));
243
- const fetchById = (id) => absentOn404(paperless("GET", `${spec.collection}/${String(id)}/`));
244
- const fetchLive = (props, output) => output === undefined ? fetchByName(props) : fetchById(output.id).pipe(Effect4.flatMap((live) => live === undefined ? Effect4.die(new Error(`${spec.describe(props)}: id ${String(output.id)} is recorded in state but no ` + "longer exists live (deleted out of band). Refusing to create a replacement " + "— adopt the live object back under this declaration, or remove it from " + "state, before deploying again.")) : Effect4.succeed(live)));
245
- const objectPath = (live) => `${spec.collection}/${String(live["id"])}`;
246
- return { fetchByName, fetchById, fetchLive, objectPath };
154
+ var soleMatch = (rows, describe) => {
155
+ if (rows.length > 1) {
156
+ throw new Error(`${describe} matched ${String(rows.length)} Paperless objects with the same (name, owner).`);
157
+ }
158
+ return rows[0];
247
159
  };
160
+ var locateOne = (list, describe, identifies) => list.pipe(Effect2.map((page) => {
161
+ if (page.count > LOCATE_PAGE) {
162
+ throw new Error(`${describe}: name__iexact matched ${String(page.count)} rows, more than the ` + `${String(LOCATE_PAGE)}-row page this reads. Narrow the name rather than paging.`);
163
+ }
164
+ const rows = identifies === undefined ? page.results : page.results.filter(identifies);
165
+ return soleMatch(rows, describe);
166
+ }));
167
+ var fetchLive = (props, output, fetchByName, fetchById, describe) => output === undefined ? fetchByName(props) : fetchById(output.id).pipe(Effect2.flatMap((live) => live === undefined ? Effect2.die(new Error(`${describe(props)}: id ${String(output.id)} is recorded in state but no ` + "longer exists live (deleted out of band). Refusing to create a replacement " + "— adopt the live object back under this declaration, or remove it from " + "state, before deploying again.")) : Effect2.succeed(live)));
248
168
 
249
169
  // src/paperless/matching.ts
250
170
  var sameValue = (a, b) => typeof a === "object" && a !== null ? JSON.stringify(a) === JSON.stringify(b) : Object.is(a, b);
251
171
  var matchingOperations = (spec) => {
252
- const { fetchByName, fetchById, fetchLive, objectPath } = matchingLocate(spec);
253
- const read = (props) => fetchByName(props).pipe(Effect5.map((live) => live === undefined ? undefined : spec.attributes(live, props)));
254
- const readById = (props, id) => fetchById(id).pipe(Effect5.map((live) => live === undefined ? undefined : spec.attributes(live, props)));
172
+ const ownerOf = (live) => spec.owned === false || spec.ownerOf === undefined ? undefined : spec.ownerOf(live);
173
+ const ownerMatches = (live, props) => spec.owned === false || spec.ownerOf === undefined ? true : spec.ownerOf(live) === (props.owner ?? undefined);
174
+ const fetchByName = (props) => locateOne(spec.list(props), spec.describe(props), (row) => row.name === props.name && ownerMatches(row, props));
175
+ const fetchById = spec.getById;
176
+ const fetchLive2 = (props, output) => fetchLive(props, output, fetchByName, fetchById, spec.describe);
177
+ const read = (props) => fetchByName(props).pipe(Effect3.map((live) => live === undefined ? undefined : spec.attributes(live, props)));
178
+ const readById = (props, id) => fetchById(id).pipe(Effect3.map((live) => live === undefined ? undefined : spec.attributes(live, props)));
255
179
  const createBody = (props) => {
256
180
  const out = spec.owned === false ? { name: props.name } : { name: props.name, owner: props.owner ?? null };
257
181
  for (const field of [...spec.fields, ...spec.createOnly ?? []]) {
@@ -263,7 +187,7 @@ var matchingOperations = (spec) => {
263
187
  };
264
188
  const patchBody = (props, live) => {
265
189
  const out = {};
266
- if (props.name !== live["name"])
190
+ if (props.name !== live.name)
267
191
  out["name"] = props.name;
268
192
  if (spec.owned !== false && ownerOf(live) !== (props.owner ?? undefined)) {
269
193
  out["owner"] = props.owner ?? null;
@@ -276,7 +200,7 @@ var matchingOperations = (spec) => {
276
200
  return out;
277
201
  };
278
202
  const matches = (props, live) => {
279
- if (props.name !== live["name"])
203
+ if (props.name !== live.name)
280
204
  return false;
281
205
  if (spec.owned !== false && ownerOf(live) !== (props.owner ?? undefined))
282
206
  return false;
@@ -287,213 +211,232 @@ var matchingOperations = (spec) => {
287
211
  };
288
212
  return {
289
213
  read,
290
- diff: (news, output) => Effect5.gen(function* () {
214
+ diff: (news, output) => Effect3.gen(function* () {
291
215
  if (output === undefined || !isResolved(news))
292
216
  return;
293
- const live = yield* fetchLive(news, output);
217
+ const live = yield* fetchLive2(news, output);
294
218
  if (live === undefined)
295
219
  return { action: "update" };
296
220
  const refusal2 = spec.immutable?.(live, news);
297
221
  if (refusal2 !== undefined)
298
- return yield* Effect5.die(new Error(refusal2));
222
+ return yield* Effect3.die(new Error(refusal2));
299
223
  if (matches(news, live))
300
224
  return { action: "noop" };
301
- return spec.endpoint.update === undefined ? { action: "replace" } : { action: "update" };
225
+ return spec.update === undefined ? { action: "replace" } : { action: "update" };
302
226
  }),
303
- reconcile: (news, output) => Effect5.gen(function* () {
304
- const before = yield* fetchLive(news, output);
227
+ reconcile: (news, output) => Effect3.gen(function* () {
228
+ const before = yield* fetchLive2(news, output);
305
229
  let id;
306
230
  if (before === undefined) {
307
231
  const body = createBody(news);
308
232
  yield* guardBody(spec.endpoint.create, body, true);
309
- yield* paperless("POST", `${spec.collection}/`, body);
233
+ yield* spec.create(body);
310
234
  } else {
311
- id = typeof before["id"] === "number" ? before["id"] : undefined;
235
+ id = before.id;
312
236
  const refusal2 = spec.immutable?.(before, news);
313
237
  if (refusal2 !== undefined)
314
- return yield* Effect5.die(new Error(refusal2));
315
- if (spec.endpoint.update !== undefined) {
238
+ return yield* Effect3.die(new Error(refusal2));
239
+ if (spec.update !== undefined) {
316
240
  const body = patchBody(news, before);
317
241
  if (Object.keys(body).length > 0) {
318
242
  yield* guardBody(spec.endpoint.update, body, false);
319
- yield* paperless("PATCH", `${objectPath(before)}/`, body);
243
+ yield* spec.update(id, body);
320
244
  }
321
245
  }
322
246
  }
323
247
  const after = yield* id === undefined ? read(news) : readById(news, id);
324
248
  if (after === undefined) {
325
- return yield* Effect5.die(new Error(`${spec.describe(news)}: the write returned no error but the object is still absent.`));
249
+ return yield* Effect3.die(new Error(`${spec.describe(news)}: the write returned no error but the object is still absent.`));
326
250
  }
327
251
  return after;
328
252
  }),
329
- destroy: (olds, output) => Effect5.gen(function* () {
253
+ destroy: (olds, output) => Effect3.gen(function* () {
330
254
  const live = output === undefined ? yield* fetchByName(olds) : yield* fetchById(output.id);
331
255
  if (live === undefined)
332
256
  return;
333
- yield* absentOn404(paperless("DELETE", `${objectPath(live)}/`));
257
+ yield* spec.destroy(live.id);
334
258
  })
335
259
  };
336
260
  };
337
261
  var matchingHandlers = (spec) => {
338
262
  const ops = matchingOperations(spec);
263
+ const withCredentials = (effect) => Effect3.provide(effect, CredentialsFromEnv);
339
264
  return {
340
- list: () => Effect5.succeed([]),
341
- read: ({ olds }) => ops.read(olds).pipe(Effect5.map((attrs) => attrs === undefined ? undefined : Unowned(attrs))),
342
- diff: ({ news, output }) => ops.diff(news, output),
343
- reconcile: ({ news, output }) => ops.reconcile(news, output),
344
- delete: ({ olds, output }) => ops.destroy(olds, output)
265
+ list: () => Effect3.succeed([]),
266
+ read: ({ olds }) => withCredentials(ops.read(olds).pipe(Effect3.map((attrs) => attrs === undefined ? undefined : Unowned(attrs)))),
267
+ diff: ({ news, output }) => withCredentials(ops.diff(news, output)),
268
+ reconcile: ({ news, output }) => withCredentials(ops.reconcile(news, output)),
269
+ delete: ({ olds, output }) => withCredentials(ops.destroy(olds, output))
345
270
  };
346
271
  };
347
272
 
348
273
  // src/paperless/tag.ts
349
274
  var Tag = Resource("Paperless.Tag", { defaultRemovalPolicy: "retain" });
350
- var handlers = matchingHandlers({
351
- attributes: (live, props) => {
352
- const id = live["id"];
353
- if (typeof id !== "number")
354
- return;
355
- return {
356
- color: typeof live["color"] === "string" ? live["color"] : "",
357
- id,
358
- isInboxTag: live["is_inbox_tag"] === true,
359
- isInsensitive: live["is_insensitive"] === true,
360
- match: typeof live["match"] === "string" ? live["match"] : "",
361
- matchingAlgorithm: typeof live["matching_algorithm"] === "number" ? live["matching_algorithm"] : 0,
362
- name: typeof live["name"] === "string" ? live["name"] : props.name,
363
- owner: typeof live["owner"] === "number" ? live["owner"] : undefined,
364
- parent: typeof live["parent"] === "number" ? live["parent"] : undefined
365
- };
366
- },
367
- collection: "tags",
275
+ var spec = {
276
+ attributes: (live, props) => ({
277
+ color: live.color ?? "",
278
+ id: live.id,
279
+ isInboxTag: live.is_inbox_tag === true,
280
+ isInsensitive: live.is_insensitive === true,
281
+ match: live.match ?? "",
282
+ matchingAlgorithm: live.matching_algorithm ?? 0,
283
+ name: live.name,
284
+ owner: live.owner ?? undefined,
285
+ parent: live.parent ?? undefined
286
+ }),
287
+ create: (body) => tags.createTag(body),
368
288
  describe: (props) => `tags ${props.name}`,
289
+ destroy: (id) => tags.tagsDestroy({ id }),
369
290
  endpoint: { create: "paperless:POST /api/tags/", update: "paperless:PATCH /api/tags/{id}/" },
370
291
  fields: [
371
- { key: "color", live: (r) => r["color"], prop: (p) => p.color },
372
- { key: "match", live: (r) => r["match"], prop: (p) => p.match },
292
+ { key: "color", live: (r) => r.color, prop: (p) => p.color },
293
+ { key: "match", live: (r) => r.match, prop: (p) => p.match },
373
294
  {
374
295
  key: "matching_algorithm",
375
- live: (r) => r["matching_algorithm"],
296
+ live: (r) => r.matching_algorithm,
376
297
  prop: (p) => p.matchingAlgorithm
377
298
  },
378
- { key: "is_insensitive", live: (r) => r["is_insensitive"], prop: (p) => p.isInsensitive },
379
- { key: "is_inbox_tag", live: (r) => r["is_inbox_tag"], prop: (p) => p.isInboxTag },
380
- { key: "parent", live: (r) => r["parent"], prop: (p) => p.parent }
381
- ]
382
- });
383
- var TagProvider = () => Provider.effect(Tag, Effect6.succeed(Tag.Provider.of(handlers)));
299
+ { key: "is_insensitive", live: (r) => r.is_insensitive, prop: (p) => p.isInsensitive },
300
+ { key: "is_inbox_tag", live: (r) => r.is_inbox_tag, prop: (p) => p.isInboxTag },
301
+ { key: "parent", live: (r) => r.parent, prop: (p) => p.parent }
302
+ ],
303
+ getById: (id) => tags.getTag({ id }).pipe(Effect4.catchTag("NotFound", () => Effect4.succeed(undefined))),
304
+ list: (props) => tags.listTags({ name__iexact: props.name, page_size: LOCATE_PAGE }),
305
+ ownerOf: (live) => live.owner ?? undefined,
306
+ update: (id, body) => tags.updateTagsPartial({
307
+ ...body,
308
+ id
309
+ })
310
+ };
311
+ var handlers = matchingHandlers(spec);
312
+ var TagProvider = () => Provider.effect(Tag, Effect4.succeed(Tag.Provider.of(handlers)));
384
313
  // src/paperless/document-type.ts
385
314
  import { Resource as Resource2 } from "alchemy";
386
315
  import * as Provider2 from "alchemy/Provider";
387
- import * as Effect7 from "effect/Effect";
316
+ import * as documentTypes from "@distilled.cloud/paperless-ngx/document_types";
317
+ import * as Effect5 from "effect/Effect";
388
318
  var DocumentType = Resource2("Paperless.DocumentType", {
389
319
  defaultRemovalPolicy: "retain"
390
320
  });
391
- var handlers2 = matchingHandlers({
392
- attributes: (live, props) => {
393
- const id = live["id"];
394
- if (typeof id !== "number")
395
- return;
396
- return {
397
- id,
398
- isInsensitive: live["is_insensitive"] === true,
399
- match: typeof live["match"] === "string" ? live["match"] : "",
400
- matchingAlgorithm: typeof live["matching_algorithm"] === "number" ? live["matching_algorithm"] : 0,
401
- name: typeof live["name"] === "string" ? live["name"] : props.name,
402
- owner: typeof live["owner"] === "number" ? live["owner"] : undefined
403
- };
404
- },
405
- collection: "document_types",
321
+ var spec2 = {
322
+ attributes: (live, props) => ({
323
+ id: live.id,
324
+ isInsensitive: live.is_insensitive === true,
325
+ match: live.match ?? "",
326
+ matchingAlgorithm: live.matching_algorithm ?? 0,
327
+ name: live.name,
328
+ owner: live.owner ?? undefined
329
+ }),
330
+ create: (body) => documentTypes.createDocumentType(body),
406
331
  describe: (props) => `document_types ${props.name}`,
332
+ destroy: (id) => documentTypes.documentTypesDestroy({ id }),
407
333
  endpoint: {
408
334
  create: "paperless:POST /api/document_types/",
409
335
  update: "paperless:PATCH /api/document_types/{id}/"
410
336
  },
411
337
  fields: [
412
- { key: "match", live: (r) => r["match"], prop: (p) => p.match },
338
+ { key: "match", live: (r) => r.match, prop: (p) => p.match },
413
339
  {
414
340
  key: "matching_algorithm",
415
- live: (r) => r["matching_algorithm"],
341
+ live: (r) => r.matching_algorithm,
416
342
  prop: (p) => p.matchingAlgorithm
417
343
  },
418
- { key: "is_insensitive", live: (r) => r["is_insensitive"], prop: (p) => p.isInsensitive }
419
- ]
420
- });
421
- var DocumentTypeProvider = () => Provider2.effect(DocumentType, Effect7.succeed(DocumentType.Provider.of(handlers2)));
344
+ { key: "is_insensitive", live: (r) => r.is_insensitive, prop: (p) => p.isInsensitive }
345
+ ],
346
+ getById: (id) => documentTypes.getDocumentType({ id }).pipe(Effect5.catchTag("NotFound", () => Effect5.succeed(undefined))),
347
+ list: (props) => documentTypes.listDocumentTypes({ name__iexact: props.name, page_size: LOCATE_PAGE }),
348
+ ownerOf: (live) => live.owner ?? undefined,
349
+ update: (id, body) => documentTypes.updateDocumentTypesPartial({
350
+ ...body,
351
+ id
352
+ })
353
+ };
354
+ var handlers2 = matchingHandlers(spec2);
355
+ var DocumentTypeProvider = () => Provider2.effect(DocumentType, Effect5.succeed(DocumentType.Provider.of(handlers2)));
422
356
  // src/paperless/storage-path.ts
423
357
  import { Resource as Resource3 } from "alchemy";
424
358
  import * as Provider3 from "alchemy/Provider";
425
- import * as Effect8 from "effect/Effect";
359
+ import * as storagePaths from "@distilled.cloud/paperless-ngx/storage_paths";
360
+ import * as Effect6 from "effect/Effect";
426
361
  var StoragePath = Resource3("Paperless.StoragePath", {
427
362
  defaultRemovalPolicy: "retain"
428
363
  });
429
- var handlers3 = matchingHandlers({
430
- attributes: (live, props) => {
431
- const id = live["id"];
432
- if (typeof id !== "number")
433
- return;
434
- return {
435
- id,
436
- isInsensitive: live["is_insensitive"] === true,
437
- match: typeof live["match"] === "string" ? live["match"] : "",
438
- matchingAlgorithm: typeof live["matching_algorithm"] === "number" ? live["matching_algorithm"] : 0,
439
- name: typeof live["name"] === "string" ? live["name"] : props.name,
440
- owner: typeof live["owner"] === "number" ? live["owner"] : undefined,
441
- path: typeof live["path"] === "string" ? live["path"] : props.path
442
- };
443
- },
444
- collection: "storage_paths",
364
+ var spec3 = {
365
+ attributes: (live, props) => ({
366
+ id: live.id,
367
+ isInsensitive: live.is_insensitive === true,
368
+ match: live.match ?? "",
369
+ matchingAlgorithm: live.matching_algorithm ?? 0,
370
+ name: live.name,
371
+ owner: live.owner ?? undefined,
372
+ path: live.path
373
+ }),
374
+ create: (body) => storagePaths.createStoragePath(body),
445
375
  describe: (props) => `storage_paths ${props.name}`,
376
+ destroy: (id) => storagePaths.storagePathsDestroy({ id }),
446
377
  endpoint: {
447
378
  create: "paperless:POST /api/storage_paths/",
448
379
  update: "paperless:PATCH /api/storage_paths/{id}/"
449
380
  },
450
381
  fields: [
451
- { key: "path", live: (r) => r["path"], prop: (p) => p.path },
452
- { key: "match", live: (r) => r["match"], prop: (p) => p.match },
382
+ { key: "path", live: (r) => r.path, prop: (p) => p.path },
383
+ { key: "match", live: (r) => r.match, prop: (p) => p.match },
453
384
  {
454
385
  key: "matching_algorithm",
455
- live: (r) => r["matching_algorithm"],
386
+ live: (r) => r.matching_algorithm,
456
387
  prop: (p) => p.matchingAlgorithm
457
388
  },
458
- { key: "is_insensitive", live: (r) => r["is_insensitive"], prop: (p) => p.isInsensitive }
459
- ]
460
- });
461
- var StoragePathProvider = () => Provider3.effect(StoragePath, Effect8.succeed(StoragePath.Provider.of(handlers3)));
389
+ { key: "is_insensitive", live: (r) => r.is_insensitive, prop: (p) => p.isInsensitive }
390
+ ],
391
+ getById: (id) => storagePaths.getStoragePath({ id }).pipe(Effect6.catchTag("NotFound", () => Effect6.succeed(undefined))),
392
+ list: (props) => storagePaths.listStoragePaths({ name__iexact: props.name, page_size: LOCATE_PAGE }),
393
+ ownerOf: (live) => live.owner ?? undefined,
394
+ update: (id, body) => storagePaths.updateStoragePathsPartial({
395
+ ...body,
396
+ id
397
+ })
398
+ };
399
+ var handlers3 = matchingHandlers(spec3);
400
+ var StoragePathProvider = () => Provider3.effect(StoragePath, Effect6.succeed(StoragePath.Provider.of(handlers3)));
462
401
  // src/paperless/custom-field.ts
463
402
  import { Resource as Resource4 } from "alchemy";
464
403
  import * as Provider4 from "alchemy/Provider";
465
- import * as Effect9 from "effect/Effect";
404
+ import * as customFields from "@distilled.cloud/paperless-ngx/custom_fields";
405
+ import * as Effect7 from "effect/Effect";
466
406
  var CustomField = Resource4("Paperless.CustomField", {
467
407
  defaultRemovalPolicy: "retain"
468
408
  });
469
- var dataTypeImmutable = (live, props) => typeof live["data_type"] === "string" && live["data_type"] !== props.dataType ? `Paperless.CustomField "${props.name}": data_type is create-only (live: ${live["data_type"]}, ` + `declared: ${props.dataType}). Changing it would delete this field's value on every ` + "document. Create a new custom field instead, and retire this one by hand." : undefined;
470
- var customFieldHandlers = matchingHandlers({
471
- attributes: (live, props) => {
472
- const id = live["id"];
473
- if (typeof id !== "number")
474
- return;
475
- return {
476
- dataType: typeof live["data_type"] === "string" ? live["data_type"] : props.dataType,
477
- extraData: live["extra_data"],
478
- id,
479
- name: typeof live["name"] === "string" ? live["name"] : props.name
480
- };
481
- },
482
- collection: "custom_fields",
409
+ var dataTypeImmutable = (live, props) => live.data_type !== props.dataType ? `Paperless.CustomField "${props.name}": data_type is create-only (live: ${live.data_type}, ` + `declared: ${props.dataType}). Changing it would delete this field's value on every ` + "document. Create a new custom field instead, and retire this one by hand." : undefined;
410
+ var spec4 = {
411
+ attributes: (live, props) => ({
412
+ dataType: live.data_type ?? props.dataType,
413
+ extraData: live.extra_data,
414
+ id: live.id,
415
+ name: live.name
416
+ }),
417
+ create: (body) => customFields.createCustomField(body),
418
+ createOnly: [{ key: "data_type", live: (r) => r.data_type, prop: (p) => p.dataType }],
483
419
  describe: (props) => `custom_fields ${props.name}`,
420
+ destroy: (id) => customFields.customFieldsDestroy({ id }),
484
421
  endpoint: {
485
422
  create: "paperless:POST /api/custom_fields/",
486
423
  update: "paperless:PATCH /api/custom_fields/{id}/"
487
424
  },
488
- createOnly: [{ key: "data_type", live: (r) => r["data_type"], prop: (p) => p.dataType }],
489
- fields: [{ key: "extra_data", live: (r) => r["extra_data"], prop: (p) => p.extraData }],
425
+ fields: [{ key: "extra_data", live: (r) => r.extra_data, prop: (p) => p.extraData }],
426
+ getById: (id) => customFields.getCustomField({ id }).pipe(Effect7.catchTag("NotFound", () => Effect7.succeed(undefined))),
490
427
  immutable: dataTypeImmutable,
491
- owned: false
492
- });
493
- var CustomFieldProvider = () => Provider4.effect(CustomField, Effect9.succeed(CustomField.Provider.of(customFieldHandlers)));
428
+ list: (props) => customFields.listCustomFields({ name__iexact: props.name, page_size: LOCATE_PAGE }),
429
+ owned: false,
430
+ update: (id, body) => customFields.updateCustomFieldsPartial({
431
+ ...body,
432
+ id
433
+ })
434
+ };
435
+ var customFieldHandlers = matchingHandlers(spec4);
436
+ var CustomFieldProvider = () => Provider4.effect(CustomField, Effect7.succeed(CustomField.Provider.of(customFieldHandlers)));
494
437
  // src/paperless/providers.ts
495
- import * as Layer2 from "effect/Layer";
496
- var paperlessProviders = (credentials = environmentLayer) => Layer2.mergeAll(TagProvider(), DocumentTypeProvider(), StoragePathProvider(), CustomFieldProvider()).pipe(Layer2.provide(credentials));
438
+ import * as Layer from "effect/Layer";
439
+ var paperlessProviders = () => Layer.mergeAll(TagProvider(), DocumentTypeProvider(), StoragePathProvider(), CustomFieldProvider());
497
440
  export {
498
441
  CustomField,
499
442
  CustomFieldProvider,
@@ -501,12 +444,6 @@ export {
501
444
  DocumentTypeProvider,
502
445
  PAPERLESS_CONSTRAINTS,
503
446
  PAPERLESS_CONSTRAINTS_DIGEST,
504
- PaperlessCredentials,
505
- PaperlessCredentialsError,
506
- PaperlessNotFound,
507
- PaperlessUnauthorized,
508
- PaperlessUnavailable,
509
- PaperlessValidation,
510
447
  StoragePath,
511
448
  StoragePathProvider,
512
449
  Tag,
@@ -514,11 +451,10 @@ export {
514
451
  bodyViolations,
515
452
  constraintsFor,
516
453
  guardBody,
517
- environmentLayer as paperlessEnvironmentLayer,
518
454
  paperlessProviders,
519
455
  refusal,
520
456
  violations
521
457
  };
522
458
 
523
- //# debugId=EE28611444A13F1E64756E2164756E21
459
+ //# debugId=9FA700BA2BD9F67464756E2164756E21
524
460
  //# sourceMappingURL=index.js.map