@homeflare/alchemy 0.27.1 → 0.27.2
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 +3 -2
- package/dist/cloudflare/fake-r2-lock.d.ts +53 -0
- package/dist/cloudflare/fake-r2-lock.d.ts.map +1 -0
- package/dist/cloudflare/index.d.ts +4 -5
- package/dist/cloudflare/index.d.ts.map +1 -1
- package/dist/cloudflare/index.js +79 -103
- package/dist/cloudflare/index.js.map +6 -7
- package/dist/cloudflare/mesh-node-api.d.ts +3 -2
- package/dist/cloudflare/mesh-node-api.d.ts.map +1 -1
- package/dist/cloudflare/providers.d.ts +1 -1
- package/dist/cloudflare/providers.d.ts.map +1 -1
- package/dist/cloudflare/r2-bucket-lock.d.ts +28 -21
- package/dist/cloudflare/r2-bucket-lock.d.ts.map +1 -1
- package/dist/forgejo/branch-protection-form.d.ts +16 -5
- package/dist/forgejo/branch-protection-form.d.ts.map +1 -1
- package/dist/forgejo/branch-protection.d.ts +34 -3
- package/dist/forgejo/branch-protection.d.ts.map +1 -1
- package/dist/forgejo/fake-forgejo.d.ts +41 -0
- package/dist/forgejo/fake-forgejo.d.ts.map +1 -0
- package/dist/forgejo/index.js +220 -284
- package/dist/forgejo/index.js.map +14 -15
- package/dist/forgejo/org-actions-secrets.d.ts +42 -12
- package/dist/forgejo/org-actions-secrets.d.ts.map +1 -1
- package/dist/forgejo/org-label.d.ts +30 -3
- package/dist/forgejo/org-label.d.ts.map +1 -1
- package/dist/forgejo/org-team.d.ts +37 -4
- package/dist/forgejo/org-team.d.ts.map +1 -1
- package/dist/forgejo/repo-webhook-form.d.ts +9 -18
- package/dist/forgejo/repo-webhook-form.d.ts.map +1 -1
- package/dist/forgejo/repo-webhook.d.ts +35 -3
- package/dist/forgejo/repo-webhook.d.ts.map +1 -1
- package/dist/forgejo/repository.d.ts +47 -2
- package/dist/forgejo/repository.d.ts.map +1 -1
- package/dist/forgejo/resource.d.ts +37 -37
- package/dist/forgejo/resource.d.ts.map +1 -1
- package/dist/forgejo/team-member.d.ts +48 -4
- package/dist/forgejo/team-member.d.ts.map +1 -1
- package/dist/forgejo/values.d.ts +9 -5
- package/dist/forgejo/values.d.ts.map +1 -1
- package/docs/credentials.md +6 -0
- package/docs/distilled-interim.md +151 -0
- package/docs/peers.md +15 -6
- package/docs/upstream-conformance.md +46 -22
- package/package.json +2 -2
- package/src/cloudflare/fake-r2-lock.ts +120 -0
- package/src/cloudflare/index.ts +4 -5
- package/src/cloudflare/mesh-node-api.ts +3 -2
- package/src/cloudflare/providers.ts +13 -16
- package/src/cloudflare/r2-bucket-lock.test.ts +139 -0
- package/src/cloudflare/r2-bucket-lock.ts +59 -51
- package/src/forgejo/branch-protection-form.ts +12 -5
- package/src/forgejo/branch-protection.ts +58 -26
- package/src/forgejo/fake-forgejo.ts +54 -0
- package/src/forgejo/org-actions-secrets.ts +44 -36
- package/src/forgejo/org-label.test.ts +100 -0
- package/src/forgejo/org-label.ts +46 -36
- package/src/forgejo/org-team.ts +40 -27
- package/src/forgejo/repo-webhook-form.ts +10 -27
- package/src/forgejo/repo-webhook.ts +66 -35
- package/src/forgejo/repository.test.ts +125 -0
- package/src/forgejo/repository.ts +72 -52
- package/src/forgejo/resource.ts +80 -79
- package/src/forgejo/team-member.test.ts +97 -0
- package/src/forgejo/team-member.ts +56 -38
- package/src/forgejo/values.ts +9 -17
- package/dist/cloudflare/client.d.ts +0 -45
- package/dist/cloudflare/client.d.ts.map +0 -1
- package/dist/forgejo/client.d.ts +0 -37
- package/dist/forgejo/client.d.ts.map +0 -1
- package/src/cloudflare/client.ts +0 -76
- package/src/forgejo/client.ts +0 -136
package/dist/forgejo/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// src/forgejo/branch-protection.ts
|
|
2
2
|
import { Resource } from "alchemy";
|
|
3
3
|
import * as Provider from "alchemy/Provider";
|
|
4
|
-
import * as
|
|
4
|
+
import * as repository from "@distilled.cloud/forgejo/repository";
|
|
5
|
+
import * as Effect2 from "effect/Effect";
|
|
5
6
|
|
|
6
7
|
// src/forgejo/branch-protection-form.ts
|
|
7
|
-
var
|
|
8
|
+
var shared = (props) => ({
|
|
8
9
|
...props.applyToAdmins === undefined ? {} : { apply_to_admins: props.applyToAdmins },
|
|
9
10
|
...props.dismissStaleApprovals === undefined ? {} : { dismiss_stale_approvals: props.dismissStaleApprovals },
|
|
10
11
|
...props.enablePush === undefined ? {} : { enable_push: props.enablePush },
|
|
@@ -12,70 +13,23 @@ var branchProtectionForm = (props) => ({
|
|
|
12
13
|
...props.ignoreStaleApprovals === undefined ? {} : { ignore_stale_approvals: props.ignoreStaleApprovals },
|
|
13
14
|
...props.requireSignedCommits === undefined ? {} : { require_signed_commits: props.requireSignedCommits },
|
|
14
15
|
...props.requiredApprovals === undefined ? {} : { required_approvals: props.requiredApprovals },
|
|
15
|
-
...props.statusCheckContexts === undefined ? {} : { status_check_contexts: props.statusCheckContexts }
|
|
16
|
-
rule_name: props.branchName
|
|
16
|
+
...props.statusCheckContexts === undefined ? {} : { status_check_contexts: props.statusCheckContexts }
|
|
17
17
|
});
|
|
18
|
+
var createBranchProtectionForm = (props) => ({
|
|
19
|
+
...shared(props),
|
|
20
|
+
branch_name: props.branchName
|
|
21
|
+
});
|
|
22
|
+
var editBranchProtectionForm = (props) => shared(props);
|
|
18
23
|
|
|
19
24
|
// src/forgejo/resource.ts
|
|
20
25
|
import { isResolved } from "alchemy/Diff";
|
|
21
|
-
import
|
|
22
|
-
|
|
23
|
-
// src/forgejo/client.ts
|
|
26
|
+
import { CredentialsFromEnv } from "@distilled.cloud/forgejo/Credentials";
|
|
24
27
|
import * as Effect from "effect/Effect";
|
|
25
|
-
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
26
|
-
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
|
|
27
|
-
var PATH_PREFIX = "/api/v1";
|
|
28
|
-
var apiBase = () => {
|
|
29
|
-
const raw = process.env["FORGEJO_URL"];
|
|
30
|
-
if (raw === undefined || raw.trim() === "") {
|
|
31
|
-
throw new Error("FORGEJO_URL is not set. Point it at your Forgejo instance, e.g. https://git.example.com");
|
|
32
|
-
}
|
|
33
|
-
return raw.trim().replace(/\/$/, "");
|
|
34
|
-
};
|
|
35
|
-
var token = () => Effect.gen(function* () {
|
|
36
|
-
const raw = process.env["FORGEJO_TOKEN"];
|
|
37
|
-
if (raw === undefined || raw.trim() === "") {
|
|
38
|
-
return yield* Effect.fail(new ForgejoError(0, "GET", "", "FORGEJO_TOKEN is unset. Mint a scoped token and export it — never store it in Alchemy props."));
|
|
39
|
-
}
|
|
40
|
-
return raw.trim();
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
class ForgejoError extends Error {
|
|
44
|
-
status;
|
|
45
|
-
method;
|
|
46
|
-
path;
|
|
47
|
-
constructor(status, method, path, detail) {
|
|
48
|
-
super(`Forgejo ${method} ${path} -> ${String(status)}: ${detail}`);
|
|
49
|
-
this.status = status;
|
|
50
|
-
this.method = method;
|
|
51
|
-
this.path = path;
|
|
52
|
-
this.name = "ForgejoError";
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
var authorization = (value) => ({ Authorization: `token ${value}` });
|
|
56
|
-
var forgejo = (method, path, body) => Effect.gen(function* () {
|
|
57
|
-
const credential = yield* token();
|
|
58
|
-
const url = `${apiBase()}${PATH_PREFIX}/${path.replace(/^\//, "")}`;
|
|
59
|
-
const client = yield* HttpClient.HttpClient;
|
|
60
|
-
const request = HttpClientRequest.make(method)(url).pipe(HttpClientRequest.setHeaders({ ...authorization(credential), Accept: "application/json" }), body === undefined ? (self) => self : HttpClientRequest.bodyText(JSON.stringify(body), "application/json"));
|
|
61
|
-
const response = yield* client.execute(request).pipe(Effect.mapError((cause) => new ForgejoError(0, method, path, String(cause))));
|
|
62
|
-
if (response.status < 200 || response.status >= 300) {
|
|
63
|
-
const detail = yield* response.text.pipe(Effect.orElseSucceed(() => ""));
|
|
64
|
-
return yield* Effect.fail(new ForgejoError(response.status, method, path, detail.slice(0, 300)));
|
|
65
|
-
}
|
|
66
|
-
const text = yield* response.text.pipe(Effect.mapError((cause) => new ForgejoError(0, method, path, String(cause))));
|
|
67
|
-
return text === "" ? undefined : JSON.parse(text);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// src/forgejo/resource.ts
|
|
71
|
-
var absentOn404 = (io) => io.pipe(Effect2.catchIf((cause) => cause instanceof ForgejoError && cause.status === 404, () => Effect2.succeed(undefined)));
|
|
72
28
|
var forgejoOperations = (spec) => {
|
|
73
|
-
const
|
|
74
|
-
const objectPath = (props, live) => spec.wirePath === undefined ? spec.path(props) : spec.wirePath(props, live);
|
|
75
|
-
const read = (props) => fetchLive(props).pipe(Effect2.map((data) => data === undefined ? undefined : spec.attributes(data, props)));
|
|
29
|
+
const read = (props) => spec.fetchLive(props).pipe(Effect.map((live) => live === undefined ? undefined : spec.attributes(live, props)));
|
|
76
30
|
return {
|
|
77
31
|
read,
|
|
78
|
-
diff: (news, output) =>
|
|
32
|
+
diff: (news, output) => Effect.gen(function* () {
|
|
79
33
|
if (output === undefined || !isResolved(news))
|
|
80
34
|
return;
|
|
81
35
|
const live = yield* read(news);
|
|
@@ -83,62 +37,51 @@ var forgejoOperations = (spec) => {
|
|
|
83
37
|
return { action: "update" };
|
|
84
38
|
if (spec.matches(live, news))
|
|
85
39
|
return { action: "noop" };
|
|
86
|
-
return spec.
|
|
40
|
+
return spec.update === undefined ? { action: "replace" } : { action: "update" };
|
|
87
41
|
}),
|
|
88
|
-
reconcile: (news) =>
|
|
89
|
-
const before = yield* fetchLive(news);
|
|
42
|
+
reconcile: (news) => Effect.gen(function* () {
|
|
43
|
+
const before = yield* spec.fetchLive(news);
|
|
90
44
|
if (spec.upsert !== undefined) {
|
|
91
45
|
yield* spec.upsert(news, before);
|
|
92
46
|
} else if (before === undefined) {
|
|
93
|
-
|
|
94
|
-
|
|
47
|
+
if (spec.create === undefined) {
|
|
48
|
+
return yield* Effect.die(new Error("forgejoOperations: spec declares neither create nor upsert"));
|
|
49
|
+
}
|
|
50
|
+
yield* spec.create(news);
|
|
51
|
+
} else if (spec.update !== undefined) {
|
|
95
52
|
const mapped = spec.attributes(before, news);
|
|
96
53
|
if (mapped === undefined || spec.matches(mapped, news)) {} else {
|
|
97
|
-
|
|
98
|
-
if (Object.keys(form).length > 0) {
|
|
99
|
-
yield* forgejo("PATCH", objectPath(news, before), form);
|
|
100
|
-
}
|
|
54
|
+
yield* spec.update(news, before);
|
|
101
55
|
}
|
|
102
56
|
}
|
|
103
57
|
const after = yield* read(news);
|
|
104
58
|
if (after === undefined) {
|
|
105
|
-
return yield*
|
|
59
|
+
return yield* Effect.die(new Error("the write returned no error but the object is still absent. " + "Gitea returns the object directly — read back rather than trusting the status code."));
|
|
106
60
|
}
|
|
107
61
|
return after;
|
|
108
62
|
}),
|
|
109
|
-
destroy: (olds) =>
|
|
110
|
-
const live = yield* fetchLive(olds);
|
|
63
|
+
destroy: (olds) => Effect.gen(function* () {
|
|
64
|
+
const live = yield* spec.fetchLive(olds);
|
|
111
65
|
if (live === undefined)
|
|
112
66
|
return;
|
|
113
|
-
yield*
|
|
67
|
+
yield* spec.destroy(olds, live);
|
|
114
68
|
})
|
|
115
69
|
};
|
|
116
70
|
};
|
|
117
71
|
var forgejoHandlers = (spec) => {
|
|
118
72
|
const ops = forgejoOperations(spec);
|
|
73
|
+
const withCredentials = (effect) => Effect.provide(effect, CredentialsFromEnv);
|
|
119
74
|
return {
|
|
120
|
-
list: () =>
|
|
121
|
-
read: ({ olds }) => ops.read(olds),
|
|
122
|
-
diff: ({ news, output }) => ops.diff(news, output),
|
|
123
|
-
reconcile: ({ news }) => ops.reconcile(news),
|
|
124
|
-
delete: ({ olds }) => ops.destroy(olds)
|
|
75
|
+
list: () => Effect.succeed([]),
|
|
76
|
+
read: ({ olds }) => withCredentials(ops.read(olds)),
|
|
77
|
+
diff: ({ news, output }) => withCredentials(ops.diff(news, output)),
|
|
78
|
+
reconcile: ({ news }) => withCredentials(ops.reconcile(news)),
|
|
79
|
+
delete: ({ olds }) => withCredentials(ops.destroy(olds))
|
|
125
80
|
};
|
|
126
81
|
};
|
|
127
82
|
|
|
128
83
|
// src/forgejo/values.ts
|
|
129
|
-
var
|
|
130
|
-
var color = (value) => text(value).replace(/^#/, "").toLowerCase();
|
|
131
|
-
var bool = (value, fallback = false) => value === undefined || value === null ? fallback : value === true || value === 1 || value === "1";
|
|
132
|
-
var int = (value, fallback = 0) => {
|
|
133
|
-
if (typeof value === "number" && Number.isFinite(value))
|
|
134
|
-
return Math.trunc(value);
|
|
135
|
-
if (typeof value === "string" && value.trim() !== "") {
|
|
136
|
-
const parsed = Number.parseInt(value, 10);
|
|
137
|
-
if (Number.isFinite(parsed))
|
|
138
|
-
return parsed;
|
|
139
|
-
}
|
|
140
|
-
return fallback;
|
|
141
|
-
};
|
|
84
|
+
var color = (value) => value.replace(/^#/, "").toLowerCase();
|
|
142
85
|
var stringArray = (value) => Array.isArray(value) ? value.filter((entry) => typeof entry === "string").toSorted() : [];
|
|
143
86
|
var stringRecord = (value) => {
|
|
144
87
|
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
@@ -167,107 +110,116 @@ var hookSecretEnvKey = (owner, repo, name) => `FORGEJO_HOOK_SECRET_${owner}_${re
|
|
|
167
110
|
|
|
168
111
|
// src/forgejo/branch-protection.ts
|
|
169
112
|
var ForgejoBranchProtection = Resource("Forgejo.BranchProtection", { defaultRemovalPolicy: "retain" });
|
|
170
|
-
var
|
|
171
|
-
attributes: (live, props) => {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
},
|
|
189
|
-
|
|
190
|
-
|
|
113
|
+
var spec = {
|
|
114
|
+
attributes: (live, props) => ({
|
|
115
|
+
applyToAdmins: live.apply_to_admins ?? false,
|
|
116
|
+
branchName: props.branchName,
|
|
117
|
+
dismissStaleApprovals: live.dismiss_stale_approvals ?? false,
|
|
118
|
+
enablePush: live.enable_push ?? true,
|
|
119
|
+
enableStatusCheck: live.enable_status_check ?? false,
|
|
120
|
+
ignoreStaleApprovals: live.ignore_stale_approvals ?? false,
|
|
121
|
+
owner: props.owner,
|
|
122
|
+
repo: props.repo,
|
|
123
|
+
requireSignedCommits: live.require_signed_commits ?? false,
|
|
124
|
+
requiredApprovals: live.required_approvals ?? 0,
|
|
125
|
+
statusCheckContexts: stringArray(live.status_check_contexts ?? [])
|
|
126
|
+
}),
|
|
127
|
+
create: (props) => repository.repoCreateBranchProtection({
|
|
128
|
+
owner: props.owner,
|
|
129
|
+
repo: props.repo,
|
|
130
|
+
...createBranchProtectionForm(props)
|
|
131
|
+
}),
|
|
132
|
+
destroy: (props) => repository.repoDeleteBranchProtection({
|
|
133
|
+
owner: props.owner,
|
|
134
|
+
repo: props.repo,
|
|
135
|
+
name: props.branchName
|
|
136
|
+
}),
|
|
137
|
+
fetchLive: (props) => repository.repoGetBranchProtection({ owner: props.owner, repo: props.repo, name: props.branchName }).pipe(Effect2.catchTag("NotFound", () => Effect2.succeed(undefined))),
|
|
191
138
|
matches: (attributes, props) => attributes.requiredApprovals === (props.requiredApprovals ?? 0) && attributes.enablePush === (props.enablePush ?? true) && attributes.enableStatusCheck === (props.enableStatusCheck ?? false) && attributes.requireSignedCommits === (props.requireSignedCommits ?? false) && attributes.dismissStaleApprovals === (props.dismissStaleApprovals ?? false) && attributes.ignoreStaleApprovals === (props.ignoreStaleApprovals ?? false) && attributes.applyToAdmins === (props.applyToAdmins ?? false) && (props.statusCheckContexts === undefined || stringArray(props.statusCheckContexts).join("\x00") === attributes.statusCheckContexts.join("\x00")),
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
139
|
+
update: (props) => repository.repoEditBranchProtection({
|
|
140
|
+
owner: props.owner,
|
|
141
|
+
repo: props.repo,
|
|
142
|
+
name: props.branchName,
|
|
143
|
+
...editBranchProtectionForm(props)
|
|
144
|
+
})
|
|
145
|
+
};
|
|
146
|
+
var handlers = forgejoHandlers(spec);
|
|
147
|
+
var ForgejoBranchProtectionProvider = () => Provider.effect(ForgejoBranchProtection, Effect2.succeed(ForgejoBranchProtection.Provider.of(handlers)));
|
|
196
148
|
// src/forgejo/org-actions-secrets.ts
|
|
197
149
|
import { Resource as Resource2 } from "alchemy";
|
|
198
150
|
import * as Provider2 from "alchemy/Provider";
|
|
199
|
-
import * as
|
|
151
|
+
import * as organization from "@distilled.cloud/forgejo/organization";
|
|
152
|
+
import * as Data from "effect/Data";
|
|
153
|
+
import * as Effect3 from "effect/Effect";
|
|
200
154
|
var ForgejoOrgSecret = Resource2("Forgejo.OrgSecret");
|
|
201
|
-
|
|
155
|
+
|
|
156
|
+
class ForgejoSecretEnvUnsetError extends Data.TaggedError("ForgejoSecretEnvUnsetError") {
|
|
157
|
+
}
|
|
158
|
+
var secretData = (org, name) => Effect3.gen(function* () {
|
|
202
159
|
const key = orgSecretEnvKey(org, name);
|
|
203
160
|
const raw = process.env[key];
|
|
204
161
|
if (raw === undefined || raw.trim() === "") {
|
|
205
|
-
return yield*
|
|
162
|
+
return yield* Effect3.fail(new ForgejoSecretEnvUnsetError({
|
|
163
|
+
message: `${key} is unset. Export the secret value there — never as an Alchemy prop.`
|
|
164
|
+
}));
|
|
206
165
|
}
|
|
207
166
|
return raw.trim();
|
|
208
167
|
});
|
|
209
|
-
var
|
|
168
|
+
var spec2 = {
|
|
210
169
|
attributes: (live, props) => ({
|
|
211
|
-
createdAt:
|
|
170
|
+
createdAt: live.created_at,
|
|
212
171
|
name: props.name,
|
|
213
172
|
org: props.org
|
|
214
173
|
}),
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
locate: (props) => forgejo("GET", `orgs/${props.org}/actions/secrets?limit=200`).pipe(Effect4.map((rows) => Array.isArray(rows) ? rows.find((row) => row["name"] === props.name) : undefined)),
|
|
174
|
+
destroy: (props) => organization.deleteOrgSecret({ org: props.org, secretname: props.name }),
|
|
175
|
+
fetchLive: (props) => organization.orgListActionsSecrets({ org: props.org, limit: 200 }).pipe(Effect3.map((rows) => rows.find((row) => row.name === props.name)), Effect3.catchTag("NotFound", () => Effect3.succeed(undefined))),
|
|
218
176
|
matches: () => true,
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
const data = yield* secretData(props.org, props.name);
|
|
224
|
-
yield* forgejo("PUT", `orgs/${props.org}/actions/secrets/${props.name}`, { data });
|
|
225
|
-
})
|
|
226
|
-
});
|
|
227
|
-
var ForgejoOrgSecretProvider = () => Provider2.effect(ForgejoOrgSecret, Effect4.succeed(ForgejoOrgSecret.Provider.of(handlers2)));
|
|
177
|
+
upsert: (props, before) => before !== undefined ? Effect3.void : Effect3.flatMap(secretData(props.org, props.name), (data) => Effect3.asVoid(organization.updateOrgSecret({ data, org: props.org, secretname: props.name })))
|
|
178
|
+
};
|
|
179
|
+
var handlers2 = forgejoHandlers(spec2);
|
|
180
|
+
var ForgejoOrgSecretProvider = () => Provider2.effect(ForgejoOrgSecret, Effect3.succeed(ForgejoOrgSecret.Provider.of(handlers2)));
|
|
228
181
|
// src/forgejo/org-label.ts
|
|
229
182
|
import { Resource as Resource3 } from "alchemy";
|
|
230
183
|
import * as Provider3 from "alchemy/Provider";
|
|
231
|
-
import * as
|
|
184
|
+
import * as organization2 from "@distilled.cloud/forgejo/organization";
|
|
185
|
+
import * as Effect4 from "effect/Effect";
|
|
232
186
|
var ForgejoOrgLabel = Resource3("Forgejo.OrgLabel", {
|
|
233
187
|
defaultRemovalPolicy: "retain"
|
|
234
188
|
});
|
|
235
|
-
var
|
|
236
|
-
attributes: (live, props) => {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
name: props.name,
|
|
246
|
-
org: props.org
|
|
247
|
-
};
|
|
248
|
-
},
|
|
249
|
-
collection: (props) => `orgs/${props.org}/labels`,
|
|
250
|
-
createForm: (props) => ({
|
|
189
|
+
var spec3 = {
|
|
190
|
+
attributes: (live, props) => ({
|
|
191
|
+
color: color(live.color),
|
|
192
|
+
description: live.description ?? "",
|
|
193
|
+
exclusive: live.exclusive ?? false,
|
|
194
|
+
labelId: live.id,
|
|
195
|
+
name: props.name,
|
|
196
|
+
org: props.org
|
|
197
|
+
}),
|
|
198
|
+
create: (props) => organization2.orgCreateLabel({
|
|
251
199
|
color: color(props.color),
|
|
252
200
|
description: props.description ?? "",
|
|
253
201
|
exclusive: props.exclusive ?? false,
|
|
254
|
-
name: props.name
|
|
202
|
+
name: props.name,
|
|
203
|
+
org: props.org
|
|
255
204
|
}),
|
|
256
|
-
|
|
205
|
+
destroy: (props, live) => organization2.orgDeleteLabel({ org: props.org, id: live.id }),
|
|
206
|
+
fetchLive: (props) => organization2.orgListLabels({ org: props.org, limit: 200 }).pipe(Effect4.map((rows) => rows.find((row) => row.name === props.name)), Effect4.catchTag("NotFound", () => Effect4.succeed(undefined))),
|
|
257
207
|
matches: (attributes, props) => attributes.color === color(props.color) && attributes.description === (props.description ?? "") && attributes.exclusive === (props.exclusive ?? false),
|
|
258
|
-
|
|
259
|
-
updateForm: (props) => ({
|
|
208
|
+
update: (props, live) => organization2.orgEditLabel({
|
|
260
209
|
color: color(props.color),
|
|
261
210
|
description: props.description ?? "",
|
|
262
|
-
exclusive: props.exclusive ?? false
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
})
|
|
266
|
-
|
|
211
|
+
exclusive: props.exclusive ?? false,
|
|
212
|
+
id: live.id,
|
|
213
|
+
org: props.org
|
|
214
|
+
})
|
|
215
|
+
};
|
|
216
|
+
var handlers3 = forgejoHandlers(spec3);
|
|
217
|
+
var ForgejoOrgLabelProvider = () => Provider3.effect(ForgejoOrgLabel, Effect4.succeed(ForgejoOrgLabel.Provider.of(handlers3)));
|
|
267
218
|
// src/forgejo/org-team.ts
|
|
268
219
|
import { Resource as Resource4 } from "alchemy";
|
|
269
220
|
import * as Provider4 from "alchemy/Provider";
|
|
270
|
-
import * as
|
|
221
|
+
import * as organization3 from "@distilled.cloud/forgejo/organization";
|
|
222
|
+
import * as Effect5 from "effect/Effect";
|
|
271
223
|
var ForgejoOrgTeam = Resource4("Forgejo.OrgTeam");
|
|
272
224
|
var teamForm = (props) => ({
|
|
273
225
|
can_create_org_repo: props.canCreateOrgRepo ?? false,
|
|
@@ -278,42 +230,38 @@ var teamForm = (props) => ({
|
|
|
278
230
|
...props.units === undefined ? {} : { units: props.units },
|
|
279
231
|
...props.unitsMap === undefined ? {} : { units_map: props.unitsMap }
|
|
280
232
|
});
|
|
281
|
-
var
|
|
233
|
+
var spec4 = {
|
|
282
234
|
attributes: (live, props) => {
|
|
283
|
-
const
|
|
284
|
-
if (typeof id !== "number")
|
|
285
|
-
return;
|
|
286
|
-
const permission = text(live["permission"], "read");
|
|
235
|
+
const permission = live.permission ?? "read";
|
|
287
236
|
if (permission !== "read" && permission !== "write" && permission !== "admin")
|
|
288
237
|
return;
|
|
289
238
|
return {
|
|
290
|
-
canCreateOrgRepo:
|
|
291
|
-
description:
|
|
292
|
-
includesAllRepositories:
|
|
239
|
+
canCreateOrgRepo: live.can_create_org_repo ?? false,
|
|
240
|
+
description: live.description ?? "",
|
|
241
|
+
includesAllRepositories: live.includes_all_repositories ?? false,
|
|
293
242
|
name: props.name,
|
|
294
243
|
org: props.org,
|
|
295
244
|
permission,
|
|
296
|
-
teamId: id,
|
|
297
|
-
units: stringArray(live[
|
|
298
|
-
unitsMap: stringRecord(live
|
|
245
|
+
teamId: live.id,
|
|
246
|
+
units: stringArray(live.units ?? []),
|
|
247
|
+
unitsMap: stringRecord(live.units_map ?? {})
|
|
299
248
|
};
|
|
300
249
|
},
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
250
|
+
create: (props) => organization3.orgCreateTeam({ org: props.org, ...teamForm(props) }),
|
|
251
|
+
destroy: (_props, live) => organization3.orgDeleteTeam({ id: live.id }),
|
|
252
|
+
fetchLive: (props) => organization3.orgListTeams({ org: props.org, limit: 200 }).pipe(Effect5.map((rows) => rows.find((row) => row.name === props.name)), Effect5.catchTag("NotFound", () => Effect5.succeed(undefined))),
|
|
304
253
|
matches: (attributes, props) => attributes.description === (props.description ?? "") && attributes.permission === (props.permission ?? "read") && attributes.includesAllRepositories === (props.includesAllRepositories ?? false) && attributes.canCreateOrgRepo === (props.canCreateOrgRepo ?? false) && (props.units === undefined || stringArray(props.units).join("\x00") === attributes.units.join("\x00")) && (props.unitsMap === undefined || recordEqual(attributes.unitsMap, props.unitsMap)),
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
var ForgejoOrgTeamProvider = () => Provider4.effect(ForgejoOrgTeam, Effect6.succeed(ForgejoOrgTeam.Provider.of(handlers4)));
|
|
254
|
+
update: (props, live) => organization3.orgEditTeam({ id: live.id, ...teamForm(props) })
|
|
255
|
+
};
|
|
256
|
+
var handlers4 = forgejoHandlers(spec4);
|
|
257
|
+
var ForgejoOrgTeamProvider = () => Provider4.effect(ForgejoOrgTeam, Effect5.succeed(ForgejoOrgTeam.Provider.of(handlers4)));
|
|
310
258
|
// src/forgejo/repo-webhook.ts
|
|
311
259
|
import { Resource as Resource5 } from "alchemy";
|
|
312
260
|
import * as Provider5 from "alchemy/Provider";
|
|
313
|
-
import * as
|
|
261
|
+
import * as repository2 from "@distilled.cloud/forgejo/repository";
|
|
262
|
+
import * as Effect6 from "effect/Effect";
|
|
314
263
|
|
|
315
264
|
// src/forgejo/repo-webhook-form.ts
|
|
316
|
-
var hookUrl = (live) => text(live["url"]) || text(stringRecord(live["config"])["url"]);
|
|
317
265
|
var hookConfigForm = (props, includeSecret) => {
|
|
318
266
|
const config = {
|
|
319
267
|
content_type: props.contentType ?? "json",
|
|
@@ -327,141 +275,129 @@ var hookConfigForm = (props, includeSecret) => {
|
|
|
327
275
|
}
|
|
328
276
|
return config;
|
|
329
277
|
};
|
|
330
|
-
var createHookForm = (props) => ({
|
|
331
|
-
active: props.active ?? true,
|
|
332
|
-
...props.authorizationHeader === undefined ? {} : { authorization_header: props.authorizationHeader },
|
|
333
|
-
...props.branchFilter === undefined ? {} : { branch_filter: props.branchFilter },
|
|
334
|
-
config: hookConfigForm(props, true),
|
|
335
|
-
events: props.events,
|
|
336
|
-
name: props.name,
|
|
337
|
-
type: props.type
|
|
338
|
-
});
|
|
339
|
-
var updateHookForm = (props) => ({
|
|
340
|
-
active: props.active ?? true,
|
|
341
|
-
...props.authorizationHeader === undefined ? {} : { authorization_header: props.authorizationHeader },
|
|
342
|
-
...props.branchFilter === undefined ? {} : { branch_filter: props.branchFilter },
|
|
343
|
-
config: hookConfigForm(props, false),
|
|
344
|
-
events: props.events
|
|
345
|
-
});
|
|
346
278
|
|
|
347
279
|
// src/forgejo/repo-webhook.ts
|
|
348
280
|
var ForgejoRepoWebhook = Resource5("Forgejo.RepoWebhook");
|
|
349
|
-
var
|
|
281
|
+
var spec5 = {
|
|
350
282
|
attributes: (live, props) => {
|
|
351
|
-
const
|
|
352
|
-
if (typeof id !== "number")
|
|
353
|
-
return;
|
|
354
|
-
const config = hookConfigPublic(live["config"]);
|
|
355
|
-
const type = text(live["type"]);
|
|
283
|
+
const config = hookConfigPublic(live.config);
|
|
356
284
|
return {
|
|
357
|
-
active:
|
|
358
|
-
authorizationHeader:
|
|
359
|
-
branchFilter:
|
|
360
|
-
contentType:
|
|
361
|
-
events: stringArray(live[
|
|
362
|
-
hookId: id,
|
|
285
|
+
active: live.active ?? true,
|
|
286
|
+
authorizationHeader: live.authorization_header ?? "",
|
|
287
|
+
branchFilter: live.branch_filter ?? "",
|
|
288
|
+
contentType: config["content_type"] ?? live.content_type ?? "json",
|
|
289
|
+
events: stringArray(live.events ?? []),
|
|
290
|
+
hookId: live.id,
|
|
363
291
|
name: props.name,
|
|
364
292
|
owner: props.owner,
|
|
365
293
|
repo: props.repo,
|
|
366
|
-
type,
|
|
367
|
-
url:
|
|
294
|
+
type: live.type,
|
|
295
|
+
url: live.url
|
|
368
296
|
};
|
|
369
297
|
},
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
298
|
+
create: (props) => repository2.repoCreateHook({
|
|
299
|
+
active: props.active ?? true,
|
|
300
|
+
...props.authorizationHeader === undefined ? {} : { authorization_header: props.authorizationHeader },
|
|
301
|
+
...props.branchFilter === undefined ? {} : { branch_filter: props.branchFilter },
|
|
302
|
+
config: hookConfigForm(props, true),
|
|
303
|
+
events: props.events,
|
|
304
|
+
owner: props.owner,
|
|
305
|
+
repo: props.repo,
|
|
306
|
+
type: props.type
|
|
307
|
+
}),
|
|
308
|
+
destroy: (props, live) => repository2.repoDeleteHook({ owner: props.owner, repo: props.repo, id: live.id }),
|
|
309
|
+
fetchLive: (props) => repository2.repoListHooks({ owner: props.owner, repo: props.repo, limit: 200 }).pipe(Effect6.map((rows) => rows.find((row) => row.url === props.url)), Effect6.catchTag("NotFound", () => Effect6.succeed(undefined))),
|
|
373
310
|
matches: (attributes, props) => attributes.type === props.type && attributes.url === props.url && attributes.active === (props.active ?? true) && attributes.contentType === (props.contentType ?? "json") && attributes.branchFilter === (props.branchFilter ?? "") && attributes.authorizationHeader === (props.authorizationHeader ?? "") && stringArray(props.events).join("\x00") === attributes.events.join("\x00"),
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
}
|
|
378
|
-
|
|
311
|
+
update: (props, live) => repository2.repoEditHook({
|
|
312
|
+
active: props.active ?? true,
|
|
313
|
+
...props.authorizationHeader === undefined ? {} : { authorization_header: props.authorizationHeader },
|
|
314
|
+
...props.branchFilter === undefined ? {} : { branch_filter: props.branchFilter },
|
|
315
|
+
config: hookConfigForm(props, false),
|
|
316
|
+
events: props.events,
|
|
317
|
+
id: live.id,
|
|
318
|
+
owner: props.owner,
|
|
319
|
+
repo: props.repo
|
|
320
|
+
})
|
|
321
|
+
};
|
|
322
|
+
var handlers5 = forgejoHandlers(spec5);
|
|
323
|
+
var ForgejoRepoWebhookProvider = () => Provider5.effect(ForgejoRepoWebhook, Effect6.succeed(ForgejoRepoWebhook.Provider.of(handlers5)));
|
|
379
324
|
// src/forgejo/repository.ts
|
|
380
325
|
import { Resource as Resource6 } from "alchemy";
|
|
381
326
|
import * as Provider6 from "alchemy/Provider";
|
|
382
|
-
import * as
|
|
327
|
+
import * as organization4 from "@distilled.cloud/forgejo/organization";
|
|
328
|
+
import * as repository3 from "@distilled.cloud/forgejo/repository";
|
|
329
|
+
import * as Effect7 from "effect/Effect";
|
|
383
330
|
var ForgejoRepository = Resource6("Forgejo.Repository", {
|
|
384
331
|
defaultRemovalPolicy: "retain"
|
|
385
332
|
});
|
|
386
|
-
var
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
333
|
+
var editForm = (props) => ({
|
|
334
|
+
...props.defaultBranch === undefined ? {} : { default_branch: props.defaultBranch },
|
|
335
|
+
...props.description === undefined ? {} : { description: props.description },
|
|
336
|
+
...props.hasIssues === undefined ? {} : { has_issues: props.hasIssues },
|
|
337
|
+
...props.hasProjects === undefined ? {} : { has_projects: props.hasProjects },
|
|
338
|
+
...props.hasWiki === undefined ? {} : { has_wiki: props.hasWiki },
|
|
339
|
+
...props.private === undefined ? {} : { private: props.private }
|
|
340
|
+
});
|
|
341
|
+
var spec6 = {
|
|
342
|
+
attributes: (live, props) => ({
|
|
343
|
+
defaultBranch: live.default_branch,
|
|
344
|
+
description: live.description ?? "",
|
|
345
|
+
empty: live.empty ?? false,
|
|
346
|
+
hasIssues: live.has_issues ?? true,
|
|
347
|
+
hasProjects: live.has_projects ?? true,
|
|
348
|
+
hasWiki: live.has_wiki ?? true,
|
|
349
|
+
name: props.name,
|
|
350
|
+
org: props.org,
|
|
351
|
+
private: live.private ?? true,
|
|
352
|
+
repoId: live.id
|
|
353
|
+
}),
|
|
354
|
+
create: (props) => organization4.createOrgRepo({
|
|
406
355
|
auto_init: props.autoInit ?? false,
|
|
407
356
|
description: props.description ?? "",
|
|
408
|
-
has_issues: props.hasIssues ?? true,
|
|
409
|
-
has_projects: props.hasProjects ?? true,
|
|
410
|
-
has_wiki: props.hasWiki ?? true,
|
|
411
357
|
name: props.name,
|
|
358
|
+
org: props.org,
|
|
412
359
|
private: props.private ?? true
|
|
413
360
|
}),
|
|
361
|
+
destroy: (props) => repository3.deleteRepo({ owner: props.org, repo: props.name }),
|
|
362
|
+
fetchLive: (props) => repository3.getRepo({ owner: props.org, repo: props.name }).pipe(Effect7.catchTag("NotFound", () => Effect7.succeed(undefined))),
|
|
414
363
|
matches: (attributes, props) => (props.description === undefined || attributes.description === props.description) && (props.private === undefined || attributes.private === props.private) && (props.hasIssues === undefined || attributes.hasIssues === props.hasIssues) && (props.hasWiki === undefined || attributes.hasWiki === props.hasWiki) && (props.hasProjects === undefined || attributes.hasProjects === props.hasProjects) && (props.defaultBranch === undefined || attributes.defaultBranch === props.defaultBranch),
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
...props.hasIssues === undefined ? {} : { has_issues: props.hasIssues },
|
|
420
|
-
...props.hasProjects === undefined ? {} : { has_projects: props.hasProjects },
|
|
421
|
-
...props.hasWiki === undefined ? {} : { has_wiki: props.hasWiki },
|
|
422
|
-
...props.private === undefined ? {} : { private: props.private }
|
|
423
|
-
})
|
|
424
|
-
});
|
|
425
|
-
var ForgejoRepositoryProvider = () => Provider6.effect(ForgejoRepository, Effect8.succeed(ForgejoRepository.Provider.of(handlers6)));
|
|
364
|
+
update: (props) => repository3.editRepo({ owner: props.org, repo: props.name, ...editForm(props) })
|
|
365
|
+
};
|
|
366
|
+
var handlers6 = forgejoHandlers(spec6);
|
|
367
|
+
var ForgejoRepositoryProvider = () => Provider6.effect(ForgejoRepository, Effect7.succeed(ForgejoRepository.Provider.of(handlers6)));
|
|
426
368
|
// src/forgejo/team-member.ts
|
|
427
369
|
import { Resource as Resource7 } from "alchemy";
|
|
428
370
|
import * as Provider7 from "alchemy/Provider";
|
|
429
|
-
import * as
|
|
371
|
+
import * as organization5 from "@distilled.cloud/forgejo/organization";
|
|
372
|
+
import * as Data2 from "effect/Data";
|
|
373
|
+
import * as Effect8 from "effect/Effect";
|
|
430
374
|
var ForgejoTeamMember = Resource7("Forgejo.TeamMember");
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
const id =
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
var memberPath = (id, props) => `teams/${String(id)}/members/${props.username}`;
|
|
442
|
-
var handlers7 = forgejoHandlers({
|
|
375
|
+
|
|
376
|
+
class ForgejoTeamNotFoundError extends Data2.TaggedError("ForgejoTeamNotFoundError") {
|
|
377
|
+
}
|
|
378
|
+
var teamIdOf = (props) => organization5.orgListTeams({ org: props.org, limit: 200 }).pipe(Effect8.flatMap((rows) => {
|
|
379
|
+
const id = rows.find((row) => row.name === props.team)?.id;
|
|
380
|
+
return id === undefined ? Effect8.fail(new ForgejoTeamNotFoundError({
|
|
381
|
+
message: `no team named ${props.team} in org ${props.org}`
|
|
382
|
+
})) : Effect8.succeed(id);
|
|
383
|
+
}));
|
|
384
|
+
var spec7 = {
|
|
443
385
|
attributes: (live, props) => {
|
|
444
|
-
|
|
445
|
-
const login = live["login"];
|
|
446
|
-
if (typeof id !== "number" || typeof login !== "string")
|
|
447
|
-
return;
|
|
448
|
-
if (login.toLowerCase() !== props.username.toLowerCase())
|
|
386
|
+
if (live.login.toLowerCase() !== props.username.toLowerCase())
|
|
449
387
|
return;
|
|
450
|
-
return { org: props.org, team: props.team, teamId:
|
|
388
|
+
return { org: props.org, team: props.team, teamId: live.teamId, username: props.username };
|
|
451
389
|
},
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
const
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
}),
|
|
390
|
+
destroy: (props, live) => organization5.orgRemoveTeamMember({ id: live.teamId, username: props.username }),
|
|
391
|
+
fetchLive: (props) => Effect8.gen(function* () {
|
|
392
|
+
const teamId = yield* teamIdOf(props);
|
|
393
|
+
const user = yield* organization5.orgListTeamMember({ id: teamId, username: props.username });
|
|
394
|
+
return { login: user.login, teamId };
|
|
395
|
+
}).pipe(Effect8.catchTag("NotFound", () => Effect8.succeed(undefined))),
|
|
459
396
|
matches: () => true,
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
var ForgejoTeamMemberProvider = () => Provider7.effect(ForgejoTeamMember, Effect9.succeed(ForgejoTeamMember.Provider.of(handlers7)));
|
|
397
|
+
upsert: (props, before) => before !== undefined ? Effect8.void : Effect8.flatMap(teamIdOf(props), (id) => Effect8.asVoid(organization5.orgAddTeamMember({ id, username: props.username })))
|
|
398
|
+
};
|
|
399
|
+
var handlers7 = forgejoHandlers(spec7);
|
|
400
|
+
var ForgejoTeamMemberProvider = () => Provider7.effect(ForgejoTeamMember, Effect8.succeed(ForgejoTeamMember.Provider.of(handlers7)));
|
|
465
401
|
export {
|
|
466
402
|
ForgejoBranchProtectionProvider,
|
|
467
403
|
ForgejoOrgLabel,
|
|
@@ -475,5 +411,5 @@ export {
|
|
|
475
411
|
ForgejoTeamMemberProvider
|
|
476
412
|
};
|
|
477
413
|
|
|
478
|
-
//# debugId=
|
|
414
|
+
//# debugId=D0F244891AADE98C64756E2164756E21
|
|
479
415
|
//# sourceMappingURL=index.js.map
|