forges 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENCE +21 -0
- package/README.md +72 -0
- package/dist/azure-devops/index.d.mts +2 -0
- package/dist/azure-devops/index.mjs +1 -0
- package/dist/azure-devops-DwQvL4TV.mjs +1355 -0
- package/dist/bitbucket/index.d.mts +2 -0
- package/dist/bitbucket/index.mjs +1 -0
- package/dist/bitbucket-CpcfJlYi.mjs +1171 -0
- package/dist/crypto-CQNEyYHD.mjs +156 -0
- package/dist/cursor-origin/index.d.mts +2 -0
- package/dist/cursor-origin/index.mjs +1 -0
- package/dist/cursor-origin-BhqYx2oW.mjs +980 -0
- package/dist/define-B2_4ob2i.d.mts +307 -0
- package/dist/define-D3yEXtKK.mjs +2276 -0
- package/dist/env.d.mts +46 -0
- package/dist/env.mjs +283 -0
- package/dist/fake/index.d.mts +227 -0
- package/dist/fake/index.mjs +1001 -0
- package/dist/fetch-D4pSRvvA.d.mts +1723 -0
- package/dist/forgejo/index.d.mts +2 -0
- package/dist/forgejo/index.mjs +1 -0
- package/dist/forgejo-BCefbHUN.mjs +2005 -0
- package/dist/gitea/index.d.mts +2 -0
- package/dist/gitea/index.mjs +22 -0
- package/dist/gitee/index.d.mts +2 -0
- package/dist/gitee/index.mjs +1 -0
- package/dist/gitee-CA-f7Rs8.mjs +1272 -0
- package/dist/github/index.d.mts +2 -0
- package/dist/github/index.mjs +1 -0
- package/dist/github-B0umL8_f.mjs +3259 -0
- package/dist/gitlab/index.d.mts +2 -0
- package/dist/gitlab/index.mjs +1 -0
- package/dist/gitlab-Bsr__Z0C.mjs +2378 -0
- package/dist/graphql-D7uGzZTf.mjs +366 -0
- package/dist/index-BQ6VS31s.d.mts +32 -0
- package/dist/index-C-jz9Mo3.d.mts +16 -0
- package/dist/index-C4fYzmK3.d.mts +102 -0
- package/dist/index-CQiIX4SH.d.mts +27 -0
- package/dist/index-CTj5gQzl.d.mts +35 -0
- package/dist/index-CliBWzOF.d.mts +23 -0
- package/dist/index-Cz_y-t3d.d.mts +36 -0
- package/dist/index-DEt25E1w.d.mts +77 -0
- package/dist/index-DIuS0EOy.d.mts +43 -0
- package/dist/index-uSpsMCrC.d.mts +26 -0
- package/dist/index.d.mts +41 -0
- package/dist/index.mjs +13 -0
- package/dist/kit.d.mts +183 -0
- package/dist/kit.mjs +4 -0
- package/dist/provider-CoZ7cCxp.d.mts +1439 -0
- package/dist/provider-Ed1YhkQN.mjs +169 -0
- package/dist/pushin/index.d.mts +2 -0
- package/dist/pushin/index.mjs +1 -0
- package/dist/pushin-CkxgJ2cU.mjs +343 -0
- package/dist/schema/Actor.json +96 -0
- package/dist/schema/AlertSupport.json +49 -0
- package/dist/schema/AuthKind.json +15 -0
- package/dist/schema/Branch.json +31 -0
- package/dist/schema/ChangedFile.json +58 -0
- package/dist/schema/Check.json +169 -0
- package/dist/schema/CheckRef.json +114 -0
- package/dist/schema/CheckState.json +14 -0
- package/dist/schema/ChecksSummary.json +34 -0
- package/dist/schema/CiJob.json +186 -0
- package/dist/schema/CiJobRef.json +132 -0
- package/dist/schema/CiRun.json +234 -0
- package/dist/schema/CiRunRef.json +103 -0
- package/dist/schema/CodeFragment.json +19 -0
- package/dist/schema/CodeMatch.json +128 -0
- package/dist/schema/Collaborator.json +169 -0
- package/dist/schema/Comment.json +336 -0
- package/dist/schema/CommentRef.json +158 -0
- package/dist/schema/Commit.json +307 -0
- package/dist/schema/CommitRef.json +104 -0
- package/dist/schema/CommitSignature.json +118 -0
- package/dist/schema/Comparison.json +355 -0
- package/dist/schema/Cursor.json +21 -0
- package/dist/schema/EventAction.json +33 -0
- package/dist/schema/EventDetail.json +649 -0
- package/dist/schema/EventKind.json +26 -0
- package/dist/schema/FileContent.json +73 -0
- package/dist/schema/FileStatus.json +15 -0
- package/dist/schema/ForgeCapabilities.json +737 -0
- package/dist/schema/ForgeEvent.json +789 -0
- package/dist/schema/ForgeInstance.json +7 -0
- package/dist/schema/ForgeKind.json +32 -0
- package/dist/schema/ForgeWarning.json +49 -0
- package/dist/schema/ForgeWarningCode.json +7 -0
- package/dist/schema/GetManyResult.json +699 -0
- package/dist/schema/Installation.json +131 -0
- package/dist/schema/InstallationToken.json +31 -0
- package/dist/schema/KnownForgeKind.json +19 -0
- package/dist/schema/Label.json +22 -0
- package/dist/schema/MergeMethod.json +14 -0
- package/dist/schema/Milestone.json +40 -0
- package/dist/schema/Notification.json +498 -0
- package/dist/schema/NotificationReason.json +28 -0
- package/dist/schema/NotificationRef.json +60 -0
- package/dist/schema/NotificationSubject.json +376 -0
- package/dist/schema/PerKind.json +49 -0
- package/dist/schema/PullBranches.json +125 -0
- package/dist/schema/PushCommit.json +24 -0
- package/dist/schema/Reaction.json +148 -0
- package/dist/schema/ReactionContent.json +17 -0
- package/dist/schema/ReactionSummary.json +70 -0
- package/dist/schema/Release.json +286 -0
- package/dist/schema/ReleaseAsset.json +169 -0
- package/dist/schema/ReleaseAssetRef.json +138 -0
- package/dist/schema/ReleaseRef.json +107 -0
- package/dist/schema/Repo.json +354 -0
- package/dist/schema/RepoFeatures.json +35 -0
- package/dist/schema/RepoPermissions.json +35 -0
- package/dist/schema/RepoRef.json +77 -0
- package/dist/schema/RepoRole.json +15 -0
- package/dist/schema/RepoVisibility.json +12 -0
- package/dist/schema/Review.json +371 -0
- package/dist/schema/ReviewComment.json +280 -0
- package/dist/schema/ReviewCommentInput.json +34 -0
- package/dist/schema/ReviewRef.json +158 -0
- package/dist/schema/ReviewState.json +15 -0
- package/dist/schema/Reviewer.json +133 -0
- package/dist/schema/SecurityAlert.json +219 -0
- package/dist/schema/SecurityAlertKind.json +14 -0
- package/dist/schema/SecurityAlertRef.json +122 -0
- package/dist/schema/SecuritySeverity.json +14 -0
- package/dist/schema/SourceKind.json +12 -0
- package/dist/schema/SubscriptionState.json +12 -0
- package/dist/schema/Support.json +23 -0
- package/dist/schema/Tag.json +25 -0
- package/dist/schema/TextLimits.json +18 -0
- package/dist/schema/Thread.json +653 -0
- package/dist/schema/ThreadKind.json +14 -0
- package/dist/schema/ThreadRef.json +131 -0
- package/dist/schema/ThreadStack.json +146 -0
- package/dist/schema/ThreadState.json +13 -0
- package/dist/schema/TreeEntry.json +46 -0
- package/dist/schema/TreeEntryType.json +13 -0
- package/dist/schema/UpsertCommentResult.json +355 -0
- package/dist/schema/User.json +123 -0
- package/dist/schema/Webhook.json +188 -0
- package/dist/schema/WebhookDeliveryRecord.json +173 -0
- package/dist/schema/WebhookDeliveryRef.json +135 -0
- package/dist/schema/WebhookRef.json +105 -0
- package/dist/schema/index.d.mts +4 -0
- package/dist/schema/index.mjs +3219 -0
- package/dist/tangled/index.d.mts +2 -0
- package/dist/tangled/index.mjs +1 -0
- package/dist/tangled-ChdPmiv-.mjs +1570 -0
- package/dist/testing/index.d.mts +123 -0
- package/dist/testing/index.mjs +242 -0
- package/dist/webhooks-rn9-8lxT.mjs +70 -0
- package/package.json +115 -3
- package/dist/.gitkeep +0 -0
package/dist/env.d.mts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { n as FetchLike } from "./fetch-D4pSRvvA.mjs";
|
|
2
|
+
import { _ as Forges, g as ForgeProviderFactory } from "./provider-CoZ7cCxp.mjs";
|
|
3
|
+
//#region src/env.d.ts
|
|
4
|
+
/** One set of variables that `providersFromEnv()` reads, and the provider factory it made from them. */
|
|
5
|
+
export interface EnvProvider {
|
|
6
|
+
forge: string;
|
|
7
|
+
/** The part after the field, for example `WORK` in `FORGES_GITHUB_TOKEN_WORK`. Empty for the unsuffixed set. */
|
|
8
|
+
suffix: string;
|
|
9
|
+
/** The factory to pass to `createForges()`. Missing when the set was skipped. */
|
|
10
|
+
factory?: ForgeProviderFactory;
|
|
11
|
+
/** Instance host the factory's providers report, when the set was not skipped. */
|
|
12
|
+
instance?: string;
|
|
13
|
+
/** Why the set was skipped, when it was. Never contains a credential. */
|
|
14
|
+
skipped?: string;
|
|
15
|
+
/** `DEMO_REPO`: a repository to show, as `owner/name`. GitLab owners may contain slashes. */
|
|
16
|
+
demoRepo?: {
|
|
17
|
+
owner: string;
|
|
18
|
+
name: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Options for `providersFromEnv()` and `forgesFromEnv()`. */
|
|
22
|
+
export interface FromEnvOptions {
|
|
23
|
+
/** Passed to every provider, for tests and runtimes without a global `fetch`. */
|
|
24
|
+
fetch?: FetchLike;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Reads provider sets from `FORGES_<KIND>_<FIELD>[_<SUFFIX>]` variables. A
|
|
28
|
+
* suffix starts another instance of the same forge.
|
|
29
|
+
* @param env The variables to read, such as `process.env`.
|
|
30
|
+
* @param options Options that every provider is created with.
|
|
31
|
+
*/
|
|
32
|
+
export declare function providersFromEnv(env: Record<string, string | undefined>, options?: FromEnvOptions): EnvProvider[];
|
|
33
|
+
/**
|
|
34
|
+
* Builds `Forges` from environment variables; see {@link providersFromEnv}.
|
|
35
|
+
* @param env The variables to read, such as `process.env`.
|
|
36
|
+
* @param options Options that every provider is created with.
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* import { forgesFromEnv } from 'forges/env'
|
|
40
|
+
*
|
|
41
|
+
* // FORGES_GITHUB_TOKEN=... FORGES_GITLAB_TOKEN=...
|
|
42
|
+
* const forges = forgesFromEnv(process.env)
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare function forgesFromEnv(env: Record<string, string | undefined>, options?: FromEnvOptions): Forges;
|
|
46
|
+
//#endregion
|
package/dist/env.mjs
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { n as azureDevOps } from "./azure-devops-DwQvL4TV.mjs";
|
|
2
|
+
import { t as bitbucket } from "./bitbucket-CpcfJlYi.mjs";
|
|
3
|
+
import { n as cursorOrigin } from "./cursor-origin-BhqYx2oW.mjs";
|
|
4
|
+
import { n as forgejo } from "./forgejo-BCefbHUN.mjs";
|
|
5
|
+
import { gitea } from "./gitea/index.mjs";
|
|
6
|
+
import { t as gitee } from "./gitee-CA-f7Rs8.mjs";
|
|
7
|
+
import { t as github } from "./github-B0umL8_f.mjs";
|
|
8
|
+
import { t as gitlab } from "./gitlab-Bsr__Z0C.mjs";
|
|
9
|
+
import { t as createForges } from "./provider-Ed1YhkQN.mjs";
|
|
10
|
+
import { t as pushin } from "./pushin-CkxgJ2cU.mjs";
|
|
11
|
+
import { t as tangled } from "./tangled-ChdPmiv-.mjs";
|
|
12
|
+
//#region src/env.ts
|
|
13
|
+
const KINDS = [
|
|
14
|
+
"GITHUB",
|
|
15
|
+
"GITLAB",
|
|
16
|
+
"BITBUCKET",
|
|
17
|
+
"FORGEJO",
|
|
18
|
+
"GITEA",
|
|
19
|
+
"TANGLED",
|
|
20
|
+
"CURSOR_ORIGIN",
|
|
21
|
+
"GITEE",
|
|
22
|
+
"AZURE_DEVOPS",
|
|
23
|
+
"PUSHIN"
|
|
24
|
+
];
|
|
25
|
+
/** Field names, longest first so `INSTANCE_VERSION` is not read as `INSTANCE` with suffix `VERSION`. */
|
|
26
|
+
const FIELDS = [
|
|
27
|
+
"NOTIFICATIONS_URL",
|
|
28
|
+
"INSTANCE_VERSION",
|
|
29
|
+
"INSTALLATION_ID",
|
|
30
|
+
"WEBHOOK_SECRET",
|
|
31
|
+
"PRIVATE_KEY",
|
|
32
|
+
"ORGANIZATION",
|
|
33
|
+
"IDENTIFIER",
|
|
34
|
+
"READ_ONLY",
|
|
35
|
+
"BASE_URL",
|
|
36
|
+
"PASSWORD",
|
|
37
|
+
"USERNAME",
|
|
38
|
+
"DEMO_REPO",
|
|
39
|
+
"INSTANCE",
|
|
40
|
+
"API_URL",
|
|
41
|
+
"ENABLED",
|
|
42
|
+
"APP_ID",
|
|
43
|
+
"TOKEN",
|
|
44
|
+
"PDS"
|
|
45
|
+
];
|
|
46
|
+
function parseRepo(value) {
|
|
47
|
+
const path = value?.replace(/^@/, "");
|
|
48
|
+
const slash = path?.lastIndexOf("/") ?? -1;
|
|
49
|
+
return path && slash > 0 ? {
|
|
50
|
+
owner: path.slice(0, slash),
|
|
51
|
+
name: path.slice(slash + 1)
|
|
52
|
+
} : void 0;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Reads provider sets from `FORGES_<KIND>_<FIELD>[_<SUFFIX>]` variables. A
|
|
56
|
+
* suffix starts another instance of the same forge.
|
|
57
|
+
* @param env The variables to read, such as `process.env`.
|
|
58
|
+
* @param options Options that every provider is created with.
|
|
59
|
+
*/
|
|
60
|
+
function providersFromEnv(env, options = {}) {
|
|
61
|
+
const sets = /* @__PURE__ */ new Map();
|
|
62
|
+
for (const [key, value] of Object.entries(env)) {
|
|
63
|
+
if (!key.startsWith("FORGES_") || value === void 0 || value === "") continue;
|
|
64
|
+
const rest = key.slice(7);
|
|
65
|
+
const kind = KINDS.find((candidate) => rest === candidate || rest.startsWith(`${candidate}_`));
|
|
66
|
+
if (!kind) continue;
|
|
67
|
+
const tail = rest.slice(kind.length + 1);
|
|
68
|
+
const fieldName = FIELDS.find((candidate) => tail === candidate || tail.startsWith(`${candidate}_`));
|
|
69
|
+
if (!fieldName) continue;
|
|
70
|
+
const suffix = tail.slice(fieldName.length + 1);
|
|
71
|
+
const id = `${kind}:${suffix}`;
|
|
72
|
+
const set = sets.get(id) ?? {
|
|
73
|
+
kind,
|
|
74
|
+
suffix,
|
|
75
|
+
fields: {}
|
|
76
|
+
};
|
|
77
|
+
set.fields[fieldName] = value;
|
|
78
|
+
sets.set(id, set);
|
|
79
|
+
}
|
|
80
|
+
return [...sets.values()].map((set) => withInstance(fromFields(set.kind, set.suffix, set.fields, options)));
|
|
81
|
+
}
|
|
82
|
+
/** Adds `instance`, creating a provider only when it is first read. */
|
|
83
|
+
function withInstance(entry) {
|
|
84
|
+
const { factory } = entry;
|
|
85
|
+
if (!factory) return entry;
|
|
86
|
+
let instance;
|
|
87
|
+
return Object.defineProperty({ ...entry }, "instance", {
|
|
88
|
+
enumerable: true,
|
|
89
|
+
configurable: true,
|
|
90
|
+
get: () => instance ??= factory.create().instance,
|
|
91
|
+
set: (value) => {
|
|
92
|
+
instance = value;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function fromFields(kind, suffix, fields, options) {
|
|
97
|
+
const base = {
|
|
98
|
+
...options.fetch ? { fetch: options.fetch } : {},
|
|
99
|
+
...fields.BASE_URL ? { baseUrl: fields.BASE_URL } : {},
|
|
100
|
+
...fields.WEBHOOK_SECRET ? { webhookSecret: fields.WEBHOOK_SECRET } : {},
|
|
101
|
+
...fields.INSTANCE ? { instance: fields.INSTANCE } : {},
|
|
102
|
+
...fields.INSTANCE_VERSION ? { instanceVersion: fields.INSTANCE_VERSION } : {},
|
|
103
|
+
...isOn(fields.READ_ONLY) ? { readOnly: true } : {}
|
|
104
|
+
};
|
|
105
|
+
const demoRepo = parseRepo(fields.DEMO_REPO);
|
|
106
|
+
const anonymous = isOn(fields.ENABLED) || Boolean(demoRepo);
|
|
107
|
+
const entry = {
|
|
108
|
+
forge: kind.toLowerCase().replaceAll("_", "-"),
|
|
109
|
+
suffix,
|
|
110
|
+
...demoRepo ? { demoRepo } : {}
|
|
111
|
+
};
|
|
112
|
+
if (fields.ENABLED === "0" || fields.ENABLED === "false") return {
|
|
113
|
+
...entry,
|
|
114
|
+
skipped: "ENABLED is off"
|
|
115
|
+
};
|
|
116
|
+
switch (kind) {
|
|
117
|
+
case "GITHUB":
|
|
118
|
+
if (fields.APP_ID && fields.PRIVATE_KEY) return {
|
|
119
|
+
...entry,
|
|
120
|
+
factory: github({
|
|
121
|
+
...base,
|
|
122
|
+
auth: {
|
|
123
|
+
type: "app",
|
|
124
|
+
appId: fields.APP_ID,
|
|
125
|
+
privateKey: fields.PRIVATE_KEY.replaceAll("\\n", "\n"),
|
|
126
|
+
installationId: fields.INSTALLATION_ID
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
};
|
|
130
|
+
if (fields.TOKEN || anonymous) return {
|
|
131
|
+
...entry,
|
|
132
|
+
factory: github({
|
|
133
|
+
...base,
|
|
134
|
+
...fields.TOKEN ? { auth: {
|
|
135
|
+
type: "token",
|
|
136
|
+
token: fields.TOKEN
|
|
137
|
+
} } : {}
|
|
138
|
+
})
|
|
139
|
+
};
|
|
140
|
+
return {
|
|
141
|
+
...entry,
|
|
142
|
+
skipped: "needs TOKEN, or APP_ID and PRIVATE_KEY, or ENABLED for anonymous reads"
|
|
143
|
+
};
|
|
144
|
+
case "BITBUCKET":
|
|
145
|
+
if (fields.USERNAME && fields.PASSWORD) return {
|
|
146
|
+
...entry,
|
|
147
|
+
factory: bitbucket({
|
|
148
|
+
...base,
|
|
149
|
+
auth: {
|
|
150
|
+
type: "basic",
|
|
151
|
+
username: fields.USERNAME,
|
|
152
|
+
password: fields.PASSWORD
|
|
153
|
+
}
|
|
154
|
+
})
|
|
155
|
+
};
|
|
156
|
+
if (fields.TOKEN || anonymous) return {
|
|
157
|
+
...entry,
|
|
158
|
+
factory: bitbucket({
|
|
159
|
+
...base,
|
|
160
|
+
...fields.TOKEN ? { auth: {
|
|
161
|
+
type: "token",
|
|
162
|
+
token: fields.TOKEN
|
|
163
|
+
} } : {}
|
|
164
|
+
})
|
|
165
|
+
};
|
|
166
|
+
return {
|
|
167
|
+
...entry,
|
|
168
|
+
skipped: "needs TOKEN, or USERNAME and PASSWORD, or ENABLED for anonymous reads"
|
|
169
|
+
};
|
|
170
|
+
case "AZURE_DEVOPS": {
|
|
171
|
+
if (!fields.ORGANIZATION) return {
|
|
172
|
+
...entry,
|
|
173
|
+
skipped: "needs ORGANIZATION"
|
|
174
|
+
};
|
|
175
|
+
const auth = fields.USERNAME && fields.PASSWORD ? {
|
|
176
|
+
type: "basic",
|
|
177
|
+
username: fields.USERNAME,
|
|
178
|
+
password: fields.PASSWORD
|
|
179
|
+
} : fields.TOKEN ? {
|
|
180
|
+
type: "token",
|
|
181
|
+
token: fields.TOKEN
|
|
182
|
+
} : void 0;
|
|
183
|
+
return auth || anonymous ? {
|
|
184
|
+
...entry,
|
|
185
|
+
factory: azureDevOps({
|
|
186
|
+
...base,
|
|
187
|
+
organization: fields.ORGANIZATION,
|
|
188
|
+
...auth ? { auth } : {}
|
|
189
|
+
})
|
|
190
|
+
} : {
|
|
191
|
+
...entry,
|
|
192
|
+
skipped: "needs TOKEN, or USERNAME and PASSWORD, or ENABLED for anonymous reads"
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
case "CURSOR_ORIGIN":
|
|
196
|
+
if (fields.APP_ID && fields.PRIVATE_KEY) return {
|
|
197
|
+
...entry,
|
|
198
|
+
factory: cursorOrigin({
|
|
199
|
+
...base,
|
|
200
|
+
auth: {
|
|
201
|
+
type: "app",
|
|
202
|
+
appId: fields.APP_ID,
|
|
203
|
+
privateKey: fields.PRIVATE_KEY.replaceAll("\\n", "\n"),
|
|
204
|
+
installationId: fields.INSTALLATION_ID
|
|
205
|
+
}
|
|
206
|
+
})
|
|
207
|
+
};
|
|
208
|
+
if (fields.TOKEN) return {
|
|
209
|
+
...entry,
|
|
210
|
+
factory: cursorOrigin({
|
|
211
|
+
...base,
|
|
212
|
+
auth: {
|
|
213
|
+
type: "token",
|
|
214
|
+
token: fields.TOKEN
|
|
215
|
+
}
|
|
216
|
+
})
|
|
217
|
+
};
|
|
218
|
+
return isOn(fields.ENABLED) ? {
|
|
219
|
+
...entry,
|
|
220
|
+
factory: cursorOrigin(base)
|
|
221
|
+
} : {
|
|
222
|
+
...entry,
|
|
223
|
+
skipped: "needs TOKEN, or APP_ID and PRIVATE_KEY, or ENABLED for webhooks only"
|
|
224
|
+
};
|
|
225
|
+
case "TANGLED": return {
|
|
226
|
+
...entry,
|
|
227
|
+
factory: tangled({
|
|
228
|
+
...base,
|
|
229
|
+
...fields.API_URL ? { apiUrl: fields.API_URL } : {},
|
|
230
|
+
...fields.NOTIFICATIONS_URL ? { notificationsUrl: fields.NOTIFICATIONS_URL } : {},
|
|
231
|
+
...fields.IDENTIFIER && fields.PASSWORD ? { auth: {
|
|
232
|
+
type: "app_password",
|
|
233
|
+
identifier: fields.IDENTIFIER,
|
|
234
|
+
password: fields.PASSWORD,
|
|
235
|
+
...fields.PDS ? { pds: fields.PDS } : {}
|
|
236
|
+
} } : {}
|
|
237
|
+
})
|
|
238
|
+
};
|
|
239
|
+
default: {
|
|
240
|
+
if (!fields.TOKEN && !anonymous) return {
|
|
241
|
+
...entry,
|
|
242
|
+
skipped: "needs TOKEN, or ENABLED for anonymous reads"
|
|
243
|
+
};
|
|
244
|
+
const create = {
|
|
245
|
+
GITLAB: gitlab,
|
|
246
|
+
FORGEJO: forgejo,
|
|
247
|
+
GITEA: gitea,
|
|
248
|
+
GITEE: gitee,
|
|
249
|
+
PUSHIN: pushin
|
|
250
|
+
}[kind];
|
|
251
|
+
return {
|
|
252
|
+
...entry,
|
|
253
|
+
factory: create({
|
|
254
|
+
...base,
|
|
255
|
+
...fields.TOKEN ? { auth: {
|
|
256
|
+
type: "token",
|
|
257
|
+
token: fields.TOKEN
|
|
258
|
+
} } : {}
|
|
259
|
+
})
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
function isOn(value) {
|
|
265
|
+
return value === "1" || value === "true";
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Builds `Forges` from environment variables; see {@link providersFromEnv}.
|
|
269
|
+
* @param env The variables to read, such as `process.env`.
|
|
270
|
+
* @param options Options that every provider is created with.
|
|
271
|
+
* @example
|
|
272
|
+
* ```ts
|
|
273
|
+
* import { forgesFromEnv } from 'forges/env'
|
|
274
|
+
*
|
|
275
|
+
* // FORGES_GITHUB_TOKEN=... FORGES_GITLAB_TOKEN=...
|
|
276
|
+
* const forges = forgesFromEnv(process.env)
|
|
277
|
+
* ```
|
|
278
|
+
*/
|
|
279
|
+
function forgesFromEnv(env, options = {}) {
|
|
280
|
+
return createForges(providersFromEnv(env, options).flatMap((entry) => entry.factory ? [entry.factory] : []));
|
|
281
|
+
}
|
|
282
|
+
//#endregion
|
|
283
|
+
export { forgesFromEnv, providersFromEnv };
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { Bt as Notification, Ct as ForgeEvent, Et as ForgeKind, Fn as Thread, G as Check, Ht as NotificationReason, J as CheckState, Ln as ThreadKind, Q as CiRun, St as FileStatus, Vn as ThreadState, W as ChangedFile, X as CiJob, Yn as Webhook, Zt as Reaction, at as Comment, en as Release, gn as Review, jn as SubscriptionState, on as Repo, st as Commit } from "../fetch-D4pSRvvA.mjs";
|
|
2
|
+
import { f as ForgeCapabilities, g as ForgeProviderFactory, h as ForgeProvider, m as ForgeOptionsBase, q as ForgeVerb } from "../provider-CoZ7cCxp.mjs";
|
|
3
|
+
import { f as VerbKind, u as SupportInput } from "../define-B2_4ob2i.mjs";
|
|
4
|
+
//#region src/fake/index.d.ts
|
|
5
|
+
/** A repository to seed, as `owner/name` plus whatever the test cares about. */
|
|
6
|
+
export interface FakeRepoSeed {
|
|
7
|
+
/** The repository as `owner/name`. */
|
|
8
|
+
repo: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
/**
|
|
11
|
+
* The default branch.
|
|
12
|
+
* @default main
|
|
13
|
+
*/
|
|
14
|
+
defaultBranch?: string;
|
|
15
|
+
/**
|
|
16
|
+
* @default public
|
|
17
|
+
*/
|
|
18
|
+
visibility?: Repo["visibility"];
|
|
19
|
+
/** Names of the labels that the repository defines. */
|
|
20
|
+
labels?: string[];
|
|
21
|
+
}
|
|
22
|
+
/** An issue, pull request or discussion to seed. */
|
|
23
|
+
export interface FakeThreadSeed {
|
|
24
|
+
/** The repository as `owner/name`. */
|
|
25
|
+
repo: string;
|
|
26
|
+
kind: Exclude<ThreadKind, "other" | "commit">;
|
|
27
|
+
/** Defaults to the next free number in the repository. */
|
|
28
|
+
number?: number;
|
|
29
|
+
title: string;
|
|
30
|
+
body?: string;
|
|
31
|
+
/**
|
|
32
|
+
* @default open
|
|
33
|
+
*/
|
|
34
|
+
state?: ThreadState;
|
|
35
|
+
isDraft?: boolean;
|
|
36
|
+
/** The login of the author. Defaults to the viewer. */
|
|
37
|
+
author?: string;
|
|
38
|
+
labels?: string[];
|
|
39
|
+
assignees?: string[];
|
|
40
|
+
comments?: Array<{
|
|
41
|
+
body: string;
|
|
42
|
+
author?: string;
|
|
43
|
+
}>;
|
|
44
|
+
checks?: Array<{
|
|
45
|
+
name: string;
|
|
46
|
+
state: CheckState;
|
|
47
|
+
}>;
|
|
48
|
+
/** Files the pull request changes. */
|
|
49
|
+
files?: Array<{
|
|
50
|
+
path: string;
|
|
51
|
+
status?: FileStatus;
|
|
52
|
+
additions?: number;
|
|
53
|
+
deletions?: number;
|
|
54
|
+
patch?: string;
|
|
55
|
+
}>;
|
|
56
|
+
/** Shas of seeded commits on the pull request. */
|
|
57
|
+
commits?: string[];
|
|
58
|
+
}
|
|
59
|
+
/** A CI run to seed, with its jobs and their logs. */
|
|
60
|
+
export interface FakeRunSeed {
|
|
61
|
+
/** The repository as `owner/name`. */
|
|
62
|
+
repo: string;
|
|
63
|
+
name: string;
|
|
64
|
+
state?: CheckState;
|
|
65
|
+
branch?: string;
|
|
66
|
+
sha?: string;
|
|
67
|
+
jobs?: Array<{
|
|
68
|
+
name: string;
|
|
69
|
+
state?: CheckState;
|
|
70
|
+
log?: string;
|
|
71
|
+
}>;
|
|
72
|
+
}
|
|
73
|
+
/** A file to seed into a repository, at `ref` or on every ref. */
|
|
74
|
+
export interface FakeFileSeed {
|
|
75
|
+
/** The repository as `owner/name`. */
|
|
76
|
+
repo: string;
|
|
77
|
+
path: string;
|
|
78
|
+
/** Text, or bytes for a binary file. */
|
|
79
|
+
content: string | Uint8Array;
|
|
80
|
+
/** Branch, tag or sha the file exists at. Defaults to every ref. */
|
|
81
|
+
ref?: string;
|
|
82
|
+
}
|
|
83
|
+
/** A commit to seed, with the files it changed. */
|
|
84
|
+
export interface FakeCommitSeed {
|
|
85
|
+
/** The repository as `owner/name`. */
|
|
86
|
+
repo: string;
|
|
87
|
+
sha: string;
|
|
88
|
+
message: string;
|
|
89
|
+
author?: string;
|
|
90
|
+
parents?: string[];
|
|
91
|
+
committedAt?: Date;
|
|
92
|
+
files?: Array<{
|
|
93
|
+
path: string;
|
|
94
|
+
status?: FileStatus;
|
|
95
|
+
additions?: number;
|
|
96
|
+
deletions?: number;
|
|
97
|
+
patch?: string;
|
|
98
|
+
}>;
|
|
99
|
+
}
|
|
100
|
+
/** A notification to seed, for an issue or pull request that is seeded as well. */
|
|
101
|
+
export interface FakeNotificationSeed {
|
|
102
|
+
/** The repository as `owner/name`. */
|
|
103
|
+
repo: string;
|
|
104
|
+
/** The number of the thread the notification is about. */
|
|
105
|
+
number: number;
|
|
106
|
+
/** Why the viewer got the notification. */
|
|
107
|
+
reason?: NotificationReason;
|
|
108
|
+
/**
|
|
109
|
+
* @default true
|
|
110
|
+
*/
|
|
111
|
+
unread?: boolean;
|
|
112
|
+
}
|
|
113
|
+
/** A release to seed. */
|
|
114
|
+
export interface FakeReleaseSeed {
|
|
115
|
+
/** The repository as `owner/name`. */
|
|
116
|
+
repo: string;
|
|
117
|
+
tag: string;
|
|
118
|
+
name?: string;
|
|
119
|
+
body?: string;
|
|
120
|
+
isDraft?: boolean;
|
|
121
|
+
isPrerelease?: boolean;
|
|
122
|
+
/** The release is immutable, so its tag and target cannot change. */
|
|
123
|
+
immutable?: boolean;
|
|
124
|
+
publishedAt?: Date;
|
|
125
|
+
assets?: Array<{
|
|
126
|
+
name: string;
|
|
127
|
+
content: string | Uint8Array;
|
|
128
|
+
contentType?: string;
|
|
129
|
+
}>;
|
|
130
|
+
}
|
|
131
|
+
/** The data a fake forge starts with. */
|
|
132
|
+
export interface FakeSeed {
|
|
133
|
+
repos?: FakeRepoSeed[];
|
|
134
|
+
files?: FakeFileSeed[];
|
|
135
|
+
commits?: FakeCommitSeed[];
|
|
136
|
+
runs?: FakeRunSeed[];
|
|
137
|
+
threads?: FakeThreadSeed[];
|
|
138
|
+
notifications?: FakeNotificationSeed[];
|
|
139
|
+
releases?: FakeReleaseSeed[];
|
|
140
|
+
}
|
|
141
|
+
/** Support for one verb: a level, or a level per thread kind for per-kind verbs. */
|
|
142
|
+
export type FakeSupport = SupportInput | Partial<Record<VerbKind, SupportInput>>;
|
|
143
|
+
/** Options for `fake()`. */
|
|
144
|
+
export interface FakeOptions extends Omit<ForgeOptionsBase, "fetch"> {
|
|
145
|
+
/**
|
|
146
|
+
* @default fake
|
|
147
|
+
*/
|
|
148
|
+
forge?: ForgeKind;
|
|
149
|
+
/**
|
|
150
|
+
* Login of the authenticated account; authors every write.
|
|
151
|
+
* @default fake-user
|
|
152
|
+
*/
|
|
153
|
+
viewer?: string;
|
|
154
|
+
seed?: FakeSeed;
|
|
155
|
+
/** Overrides the default support of individual verbs. */
|
|
156
|
+
support?: Partial<Record<ForgeVerb, FakeSupport>>;
|
|
157
|
+
/** Support to copy from a real provider, such as `github().create().capabilities`. `support` wins where both set a verb. */
|
|
158
|
+
capabilities?: ForgeCapabilities;
|
|
159
|
+
}
|
|
160
|
+
interface FakeRunState {
|
|
161
|
+
run: CiRun;
|
|
162
|
+
jobs: Array<{
|
|
163
|
+
job: CiJob;
|
|
164
|
+
log: string;
|
|
165
|
+
}>;
|
|
166
|
+
}
|
|
167
|
+
interface FakeThreadState {
|
|
168
|
+
thread: Thread;
|
|
169
|
+
files: ChangedFile[];
|
|
170
|
+
commits: string[];
|
|
171
|
+
comments: Comment[];
|
|
172
|
+
/** Reactions on the thread, keyed by comment id, with `''` for the thread itself. */
|
|
173
|
+
reactions: Map<string, Reaction[]>;
|
|
174
|
+
checks: Check[];
|
|
175
|
+
reviews: Review[];
|
|
176
|
+
subscription: SubscriptionState;
|
|
177
|
+
}
|
|
178
|
+
/** The in-memory state behind a fake forge. Mutate it to set up a test, read it to assert. */
|
|
179
|
+
export interface FakeStore {
|
|
180
|
+
/** Every repository with its threads, releases, runs, files and commits, keyed by `owner/name`. */
|
|
181
|
+
repos: Map<string, {
|
|
182
|
+
repo: Repo;
|
|
183
|
+
labels: string[];
|
|
184
|
+
threads: Map<string, FakeThreadState>;
|
|
185
|
+
releases: Release[];
|
|
186
|
+
statuses: Map<string, Check[]>;
|
|
187
|
+
runs: FakeRunState[];
|
|
188
|
+
/** Seeded file bytes, keyed by `<ref>:<path>`, with `*` for a file on every ref. */
|
|
189
|
+
files: Map<string, Uint8Array>;
|
|
190
|
+
commits: Commit[];
|
|
191
|
+
/** Seeded release asset bytes, keyed by `<releaseId>:<assetName>`. */
|
|
192
|
+
assets: Map<string, Uint8Array>;
|
|
193
|
+
}>;
|
|
194
|
+
notifications: Notification[];
|
|
195
|
+
/** Every event a write produced, in order. */
|
|
196
|
+
events: ForgeEvent[];
|
|
197
|
+
/** Registered webhooks. Secrets are held separately and never readable. */
|
|
198
|
+
webhooks: Webhook[];
|
|
199
|
+
}
|
|
200
|
+
/** What `fake()` returns: a provider factory that also exposes the store. */
|
|
201
|
+
export interface FakeForgeFactory extends ForgeProviderFactory<ForgeProvider> {
|
|
202
|
+
/** The in-memory state of the forge. */
|
|
203
|
+
readonly store: FakeStore;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* An in-memory forge implementing the whole provider surface, for testing
|
|
207
|
+
* code that writes. Every write changes `store` and appends a `ForgeEvent`
|
|
208
|
+
* that `threads.events()` and `sources.subscribe()` return. Webhook
|
|
209
|
+
* deliveries carry normalised events as JSON, signed as `signDelivery('fake', ...)`
|
|
210
|
+
* from `forges/testing` signs them.
|
|
211
|
+
* @param options The data the forge starts with, and the support of individual operations.
|
|
212
|
+
* @example
|
|
213
|
+
* ```ts
|
|
214
|
+
* import { createForges } from 'forges'
|
|
215
|
+
* import { fake } from 'forges/fake'
|
|
216
|
+
*
|
|
217
|
+
* const factory = fake({
|
|
218
|
+
* seed: {
|
|
219
|
+
* repos: [{ repo: 'acme/widgets' }],
|
|
220
|
+
* threads: [{ repo: 'acme/widgets', kind: 'issue', title: 'Broken build' }],
|
|
221
|
+
* },
|
|
222
|
+
* })
|
|
223
|
+
* const forges = createForges([factory])
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
export declare function fake(options?: FakeOptions): FakeForgeFactory;
|
|
227
|
+
//#endregion
|