declastruct-github 1.0.7 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access/daos/DeclaredGithubAppDao.d.ts +8 -0
- package/dist/access/daos/DeclaredGithubAppDao.js +32 -0
- package/dist/access/daos/DeclaredGithubAppDao.js.map +1 -0
- package/dist/access/daos/DeclaredGithubAppInstallationDao.d.ts +9 -0
- package/dist/access/daos/DeclaredGithubAppInstallationDao.js +33 -0
- package/dist/access/daos/DeclaredGithubAppInstallationDao.js.map +1 -0
- package/dist/access/daos/DeclaredGithubBranchDao.js +4 -4
- package/dist/access/daos/DeclaredGithubBranchDao.js.map +1 -1
- package/dist/access/daos/DeclaredGithubBranchProtectionDao.js +4 -4
- package/dist/access/daos/DeclaredGithubBranchProtectionDao.js.map +1 -1
- package/dist/access/daos/DeclaredGithubOrgDao.d.ts +10 -0
- package/dist/access/daos/DeclaredGithubOrgDao.js +44 -0
- package/dist/access/daos/DeclaredGithubOrgDao.js.map +1 -0
- package/dist/access/daos/DeclaredGithubOrgMemberPrivilegesDao.d.ts +10 -0
- package/dist/access/daos/DeclaredGithubOrgMemberPrivilegesDao.js +44 -0
- package/dist/access/daos/DeclaredGithubOrgMemberPrivilegesDao.js.map +1 -0
- package/dist/access/daos/DeclaredGithubOrgSecretDao.d.ts +10 -0
- package/dist/access/daos/DeclaredGithubOrgSecretDao.js +47 -0
- package/dist/access/daos/DeclaredGithubOrgSecretDao.js.map +1 -0
- package/dist/access/daos/DeclaredGithubOrgVariableDao.d.ts +9 -0
- package/dist/access/daos/DeclaredGithubOrgVariableDao.js +46 -0
- package/dist/access/daos/DeclaredGithubOrgVariableDao.js.map +1 -0
- package/dist/access/daos/DeclaredGithubRepoConfigDao.js +4 -4
- package/dist/access/daos/DeclaredGithubRepoConfigDao.js.map +1 -1
- package/dist/access/daos/DeclaredGithubRepoDao.js +4 -4
- package/dist/access/daos/DeclaredGithubRepoDao.js.map +1 -1
- package/dist/contract/sdks/index.d.ts +8 -0
- package/dist/contract/sdks/index.js +18 -3
- package/dist/contract/sdks/index.js.map +1 -1
- package/dist/domain.objects/DeclaredGithubApp.d.ts +75 -0
- package/dist/domain.objects/DeclaredGithubApp.js +16 -0
- package/dist/domain.objects/DeclaredGithubApp.js.map +1 -0
- package/dist/domain.objects/DeclaredGithubAppInstallation.d.ts +61 -0
- package/dist/domain.objects/DeclaredGithubAppInstallation.js +16 -0
- package/dist/domain.objects/DeclaredGithubAppInstallation.js.map +1 -0
- package/dist/domain.objects/DeclaredGithubAppPermissions.d.ts +130 -0
- package/dist/domain.objects/DeclaredGithubAppPermissions.js +12 -0
- package/dist/domain.objects/DeclaredGithubAppPermissions.js.map +1 -0
- package/dist/domain.objects/DeclaredGithubOrg.d.ts +59 -0
- package/dist/domain.objects/DeclaredGithubOrg.js +15 -0
- package/dist/domain.objects/DeclaredGithubOrg.js.map +1 -0
- package/dist/domain.objects/DeclaredGithubOrgMemberPrivileges.d.ts +85 -0
- package/dist/domain.objects/DeclaredGithubOrgMemberPrivileges.js +13 -0
- package/dist/domain.objects/DeclaredGithubOrgMemberPrivileges.js.map +1 -0
- package/dist/domain.objects/DeclaredGithubOrgSecret.d.ts +63 -0
- package/dist/domain.objects/DeclaredGithubOrgSecret.js +14 -0
- package/dist/domain.objects/DeclaredGithubOrgSecret.js.map +1 -0
- package/dist/domain.objects/DeclaredGithubOrgVariable.d.ts +54 -0
- package/dist/domain.objects/DeclaredGithubOrgVariable.js +13 -0
- package/dist/domain.objects/DeclaredGithubOrgVariable.js.map +1 -0
- package/dist/domain.objects/DeclaredGithubOwner.d.ts +17 -0
- package/dist/domain.objects/DeclaredGithubOwner.js +8 -0
- package/dist/domain.objects/DeclaredGithubOwner.js.map +1 -0
- package/dist/domain.objects/DeclaredGithubRepo.d.ts +1 -0
- package/dist/domain.objects/DeclaredGithubRepo.js +1 -0
- package/dist/domain.objects/DeclaredGithubRepo.js.map +1 -1
- package/dist/domain.objects/DeclaredGithubRepoConfig.d.ts +0 -4
- package/dist/domain.objects/DeclaredGithubRepoConfig.js.map +1 -1
- package/dist/domain.objects/DeclastructGithubProvider.d.ts +12 -0
- package/dist/domain.operations/app/castToDeclaredGithubApp.d.ts +12 -0
- package/dist/domain.operations/app/castToDeclaredGithubApp.js +134 -0
- package/dist/domain.operations/app/castToDeclaredGithubApp.js.map +1 -0
- package/dist/domain.operations/app/getOneApp.d.ts +15 -0
- package/dist/domain.operations/app/getOneApp.js +67 -0
- package/dist/domain.operations/app/getOneApp.js.map +1 -0
- package/dist/domain.operations/app/setApp.d.ts +13 -0
- package/dist/domain.operations/app/setApp.js +77 -0
- package/dist/domain.operations/app/setApp.js.map +1 -0
- package/dist/domain.operations/appInstallation/castToDeclaredGithubAppInstallation.d.ts +19 -0
- package/dist/domain.operations/appInstallation/castToDeclaredGithubAppInstallation.js +61 -0
- package/dist/domain.operations/appInstallation/castToDeclaredGithubAppInstallation.js.map +1 -0
- package/dist/domain.operations/appInstallation/deleteAppInstallation.d.ts +11 -0
- package/dist/domain.operations/appInstallation/deleteAppInstallation.js +30 -0
- package/dist/domain.operations/appInstallation/deleteAppInstallation.js.map +1 -0
- package/dist/domain.operations/appInstallation/getOneAppInstallation.d.ts +15 -0
- package/dist/domain.operations/appInstallation/getOneAppInstallation.js +92 -0
- package/dist/domain.operations/appInstallation/getOneAppInstallation.js.map +1 -0
- package/dist/domain.operations/appInstallation/setAppInstallation.d.ts +13 -0
- package/dist/domain.operations/appInstallation/setAppInstallation.js +131 -0
- package/dist/domain.operations/appInstallation/setAppInstallation.js.map +1 -0
- package/dist/domain.operations/branch/setBranch.js +19 -10
- package/dist/domain.operations/branch/setBranch.js.map +1 -1
- package/dist/domain.operations/context/hasContextWithAppToken.d.ts +6 -0
- package/dist/domain.operations/context/hasContextWithAppToken.js +15 -0
- package/dist/domain.operations/context/hasContextWithAppToken.js.map +1 -0
- package/dist/domain.operations/context/hasContextWithPatToken.d.ts +6 -0
- package/dist/domain.operations/context/hasContextWithPatToken.js +17 -0
- package/dist/domain.operations/context/hasContextWithPatToken.js.map +1 -0
- package/dist/domain.operations/org/castToDeclaredGithubOrg.d.ts +12 -0
- package/dist/domain.operations/org/castToDeclaredGithubOrg.js +29 -0
- package/dist/domain.operations/org/castToDeclaredGithubOrg.js.map +1 -0
- package/dist/domain.operations/org/getOneOrg.d.ts +14 -0
- package/dist/domain.operations/org/getOneOrg.js +31 -0
- package/dist/domain.operations/org/getOneOrg.js.map +1 -0
- package/dist/domain.operations/org/setOrg.d.ts +17 -0
- package/dist/domain.operations/org/setOrg.js +50 -0
- package/dist/domain.operations/org/setOrg.js.map +1 -0
- package/dist/domain.operations/orgMemberPrivileges/castToDeclaredGithubOrgMemberPrivileges.d.ts +15 -0
- package/dist/domain.operations/orgMemberPrivileges/castToDeclaredGithubOrgMemberPrivileges.js +47 -0
- package/dist/domain.operations/orgMemberPrivileges/castToDeclaredGithubOrgMemberPrivileges.js.map +1 -0
- package/dist/domain.operations/orgMemberPrivileges/getOneOrgMemberPrivileges.d.ts +14 -0
- package/dist/domain.operations/orgMemberPrivileges/getOneOrgMemberPrivileges.js +36 -0
- package/dist/domain.operations/orgMemberPrivileges/getOneOrgMemberPrivileges.js.map +1 -0
- package/dist/domain.operations/orgMemberPrivileges/setOrgMemberPrivileges.d.ts +16 -0
- package/dist/domain.operations/orgMemberPrivileges/setOrgMemberPrivileges.js +64 -0
- package/dist/domain.operations/orgMemberPrivileges/setOrgMemberPrivileges.js.map +1 -0
- package/dist/domain.operations/orgSecret/castToDeclaredGithubOrgSecret.d.ts +17 -0
- package/dist/domain.operations/orgSecret/castToDeclaredGithubOrgSecret.js +28 -0
- package/dist/domain.operations/orgSecret/castToDeclaredGithubOrgSecret.js.map +1 -0
- package/dist/domain.operations/orgSecret/delOrgSecret.d.ts +11 -0
- package/dist/domain.operations/orgSecret/delOrgSecret.js +27 -0
- package/dist/domain.operations/orgSecret/delOrgSecret.js.map +1 -0
- package/dist/domain.operations/orgSecret/getAllOrgSecrets.d.ts +14 -0
- package/dist/domain.operations/orgSecret/getAllOrgSecrets.js +27 -0
- package/dist/domain.operations/orgSecret/getAllOrgSecrets.js.map +1 -0
- package/dist/domain.operations/orgSecret/getOneOrgSecret.d.ts +15 -0
- package/dist/domain.operations/orgSecret/getOneOrgSecret.js +35 -0
- package/dist/domain.operations/orgSecret/getOneOrgSecret.js.map +1 -0
- package/dist/domain.operations/orgSecret/setOrgSecret.d.ts +17 -0
- package/dist/domain.operations/orgSecret/setOrgSecret.js +123 -0
- package/dist/domain.operations/orgSecret/setOrgSecret.js.map +1 -0
- package/dist/domain.operations/orgVariable/castToDeclaredGithubOrgVariable.d.ts +16 -0
- package/dist/domain.operations/orgVariable/castToDeclaredGithubOrgVariable.js +26 -0
- package/dist/domain.operations/orgVariable/castToDeclaredGithubOrgVariable.js.map +1 -0
- package/dist/domain.operations/orgVariable/delOrgVariable.d.ts +11 -0
- package/dist/domain.operations/orgVariable/delOrgVariable.js +27 -0
- package/dist/domain.operations/orgVariable/delOrgVariable.js.map +1 -0
- package/dist/domain.operations/orgVariable/getAllOrgVariables.d.ts +13 -0
- package/dist/domain.operations/orgVariable/getAllOrgVariables.js +28 -0
- package/dist/domain.operations/orgVariable/getAllOrgVariables.js.map +1 -0
- package/dist/domain.operations/orgVariable/getOneOrgVariable.d.ts +14 -0
- package/dist/domain.operations/orgVariable/getOneOrgVariable.js +34 -0
- package/dist/domain.operations/orgVariable/getOneOrgVariable.js.map +1 -0
- package/dist/domain.operations/orgVariable/setOrgVariable.d.ts +12 -0
- package/dist/domain.operations/orgVariable/setOrgVariable.js +69 -0
- package/dist/domain.operations/orgVariable/setOrgVariable.js.map +1 -0
- package/dist/domain.operations/provider/getDeclastructGithubProvider.js +13 -0
- package/dist/domain.operations/provider/getDeclastructGithubProvider.js.map +1 -1
- package/dist/domain.operations/repo/getRepos.js +22 -5
- package/dist/domain.operations/repo/getRepos.js.map +1 -1
- package/dist/domain.operations/repoConfig/castToDeclaredGithubRepoConfig.js +0 -1
- package/dist/domain.operations/repoConfig/castToDeclaredGithubRepoConfig.js.map +1 -1
- package/dist/domain.operations/repoConfig/setRepoConfig.js +0 -1
- package/dist/domain.operations/repoConfig/setRepoConfig.js.map +1 -1
- package/package.json +7 -5
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getOneAppInstallation = void 0;
|
|
4
|
+
const as_procedure_1 = require("as-procedure");
|
|
5
|
+
const helpful_errors_1 = require("helpful-errors");
|
|
6
|
+
const getGithubClient_1 = require("../../access/sdks/getGithubClient");
|
|
7
|
+
const hasContextWithAppToken_1 = require("../context/hasContextWithAppToken");
|
|
8
|
+
const hasContextWithPatToken_1 = require("../context/hasContextWithPatToken");
|
|
9
|
+
const castToDeclaredGithubAppInstallation_1 = require("./castToDeclaredGithubAppInstallation");
|
|
10
|
+
/**
|
|
11
|
+
* .what = gets a GitHub App installation by unique key
|
|
12
|
+
* .why = retrieves current state of an installation from GitHub API for declarative management
|
|
13
|
+
* .note = lookup by primary key (installation id) is not supported - requires App JWT auth
|
|
14
|
+
*/
|
|
15
|
+
exports.getOneAppInstallation = (0, as_procedure_1.asProcedure)(async (input, context) => {
|
|
16
|
+
// get cached GitHub client
|
|
17
|
+
const github = (0, getGithubClient_1.getGithubClient)({}, context);
|
|
18
|
+
// handle get by unique key
|
|
19
|
+
if (input.by.unique) {
|
|
20
|
+
const { app, target } = input.by.unique;
|
|
21
|
+
// list installations for the org/user and filter by app
|
|
22
|
+
// uses GET /orgs/{org}/installations which works with PAT (admin:read scope)
|
|
23
|
+
try {
|
|
24
|
+
if (target.type === 'organization') {
|
|
25
|
+
const response = await github.orgs.listAppInstallations({
|
|
26
|
+
org: target.slug,
|
|
27
|
+
per_page: 100,
|
|
28
|
+
});
|
|
29
|
+
// find installation matching app slug
|
|
30
|
+
const installation = response.data.installations.find((inst) => inst.app_slug === app.slug);
|
|
31
|
+
if (!installation)
|
|
32
|
+
return null;
|
|
33
|
+
// fetch repositories if selection is 'selected'
|
|
34
|
+
// (the list endpoint doesn't include repositories)
|
|
35
|
+
let repositories = null;
|
|
36
|
+
if (installation.repository_selection === 'selected') {
|
|
37
|
+
// detect token type
|
|
38
|
+
const isPatToken = (0, hasContextWithPatToken_1.hasContextWithPatToken)(null, context);
|
|
39
|
+
const isAppToken = (0, hasContextWithAppToken_1.hasContextWithAppToken)(null, context);
|
|
40
|
+
// fail fast on unknown token type
|
|
41
|
+
if (!isPatToken && !isAppToken) {
|
|
42
|
+
throw new helpful_errors_1.HelpfulError('Unknown token type. Expected PAT (ghp_* or github_pat_*) or installation token (ghs_*).', { tokenPrefix: context.github.token.slice(0, 10) + '...' });
|
|
43
|
+
}
|
|
44
|
+
// PAT: GET /user/installations/{id}/repositories
|
|
45
|
+
if (isPatToken) {
|
|
46
|
+
const reposResponse = await github.apps.listInstallationReposForAuthenticatedUser({
|
|
47
|
+
installation_id: installation.id,
|
|
48
|
+
per_page: 100,
|
|
49
|
+
});
|
|
50
|
+
repositories = reposResponse.data.repositories.map((r) => r.name);
|
|
51
|
+
}
|
|
52
|
+
// installation token: GET /installation/repositories
|
|
53
|
+
if (isAppToken) {
|
|
54
|
+
const reposResponse = await github.apps.listReposAccessibleToInstallation({
|
|
55
|
+
per_page: 100,
|
|
56
|
+
});
|
|
57
|
+
repositories = reposResponse.data.repositories.map((r) => r.name);
|
|
58
|
+
}
|
|
59
|
+
// fail fast if repositories weren't fetched
|
|
60
|
+
if (repositories === null) {
|
|
61
|
+
throw new helpful_errors_1.UnexpectedCodePathError('repositories not fetched for selected installation', { isPatToken, isAppToken, installation_id: installation.id });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return (0, castToDeclaredGithubAppInstallation_1.castToDeclaredGithubAppInstallation)({
|
|
65
|
+
installation,
|
|
66
|
+
app,
|
|
67
|
+
repositories,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
// for User targets, there's no PAT-accessible endpoint
|
|
71
|
+
if (target.type === 'user') {
|
|
72
|
+
throw new helpful_errors_1.HelpfulError('User installations are not supported. GitHub API has no PAT-accessible endpoint to read user installations.', { target });
|
|
73
|
+
}
|
|
74
|
+
// for unsupported target.type, fail fast
|
|
75
|
+
throw new helpful_errors_1.UnexpectedCodePathError('unsupported target.type', { input });
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
if (!(error instanceof Error))
|
|
79
|
+
throw error;
|
|
80
|
+
if (error.message.includes('Not Found'))
|
|
81
|
+
return null;
|
|
82
|
+
throw new helpful_errors_1.HelpfulError('github.getOneAppInstallation.byUnique error', {
|
|
83
|
+
cause: error,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// no valid key provided
|
|
88
|
+
helpful_errors_1.UnexpectedCodePathError.throw('getOneAppInstallation requires by.unique', {
|
|
89
|
+
input,
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
//# sourceMappingURL=getOneAppInstallation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getOneAppInstallation.js","sourceRoot":"","sources":["../../../src/domain.operations/appInstallation/getOneAppInstallation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { HasMetadata, PickOne } from 'type-fns';
|
|
2
|
+
import type { VisualogicContext } from 'visualogic';
|
|
3
|
+
import type { ContextGithubApi } from '../../domain.objects/ContextGithubApi';
|
|
4
|
+
import type { DeclaredGithubAppInstallation } from '../../domain.objects/DeclaredGithubAppInstallation';
|
|
5
|
+
/**
|
|
6
|
+
* .what = sets a GitHub App installation: finsert or upsert
|
|
7
|
+
* .why = provides declarative interface for managing installations with partial automation
|
|
8
|
+
* .note = installations cannot be created via API; repository selection can be synced for existing installations
|
|
9
|
+
*/
|
|
10
|
+
export declare const setAppInstallation: (input: PickOne<{
|
|
11
|
+
finsert: DeclaredGithubAppInstallation;
|
|
12
|
+
upsert: DeclaredGithubAppInstallation;
|
|
13
|
+
}>, context: ContextGithubApi & VisualogicContext) => Promise<HasMetadata<DeclaredGithubAppInstallation>>;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setAppInstallation = void 0;
|
|
4
|
+
const as_procedure_1 = require("as-procedure");
|
|
5
|
+
const helpful_errors_1 = require("helpful-errors");
|
|
6
|
+
const getGithubClient_1 = require("../../access/sdks/getGithubClient");
|
|
7
|
+
const getOneAppInstallation_1 = require("./getOneAppInstallation");
|
|
8
|
+
/**
|
|
9
|
+
* .what = sets a GitHub App installation: finsert or upsert
|
|
10
|
+
* .why = provides declarative interface for managing installations with partial automation
|
|
11
|
+
* .note = installations cannot be created via API; repository selection can be synced for existing installations
|
|
12
|
+
*/
|
|
13
|
+
exports.setAppInstallation = (0, as_procedure_1.asProcedure)(async (input, context) => {
|
|
14
|
+
const desired = input.finsert ??
|
|
15
|
+
input.upsert ??
|
|
16
|
+
helpful_errors_1.UnexpectedCodePathError.throw('no installation provided to setAppInstallation', { input });
|
|
17
|
+
// check whether it already exists
|
|
18
|
+
const foundBefore = await (0, getOneAppInstallation_1.getOneAppInstallation)({
|
|
19
|
+
by: {
|
|
20
|
+
unique: {
|
|
21
|
+
app: desired.app,
|
|
22
|
+
target: desired.target,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
}, context);
|
|
26
|
+
// if installation doesn't exist, throw HelpfulError with installation instructions
|
|
27
|
+
if (!foundBefore) {
|
|
28
|
+
const installUrl = `https://github.com/apps/${desired.app.slug}/installations/new`;
|
|
29
|
+
throw new helpful_errors_1.HelpfulError('GitHub App installations cannot be created via API. Please install the app manually.', {
|
|
30
|
+
installUrl,
|
|
31
|
+
instructions: [
|
|
32
|
+
`1. Navigate to: ${installUrl}`,
|
|
33
|
+
`2. Select the ${desired.target.type.toLowerCase()}: ${desired.target.slug}`,
|
|
34
|
+
desired.repositorySelection === 'selected'
|
|
35
|
+
? `3. Choose "Only select repositories" and select: ${desired.repositories?.join(', ') ?? '(none specified)'}`
|
|
36
|
+
: '3. Choose "All repositories" for full access',
|
|
37
|
+
'4. Click "Install" to complete the installation',
|
|
38
|
+
],
|
|
39
|
+
desired,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
// if it's a finsert and exists, return the found installation
|
|
43
|
+
if (input.finsert)
|
|
44
|
+
return foundBefore;
|
|
45
|
+
// if it's an upsert and exists, sync repository selection if needed
|
|
46
|
+
if (input.upsert) {
|
|
47
|
+
// check if we need to sync repository selection
|
|
48
|
+
if (desired.repositorySelection === 'selected') {
|
|
49
|
+
const result = await syncInstallationRepositories({
|
|
50
|
+
installationId: foundBefore.id,
|
|
51
|
+
desiredRepositories: desired.repositories ?? [],
|
|
52
|
+
currentRepositories: foundBefore.repositories ?? [],
|
|
53
|
+
app: desired.app,
|
|
54
|
+
}, context);
|
|
55
|
+
// get updated installation after sync
|
|
56
|
+
const foundAfter = await (0, getOneAppInstallation_1.getOneAppInstallation)({ by: { unique: { app: desired.app, target: desired.target } } }, context);
|
|
57
|
+
if (!foundAfter)
|
|
58
|
+
helpful_errors_1.UnexpectedCodePathError.throw('installation not found after sync. should not be possible', { desired, result });
|
|
59
|
+
return foundAfter;
|
|
60
|
+
}
|
|
61
|
+
// no sync needed, return as-is
|
|
62
|
+
return foundBefore;
|
|
63
|
+
}
|
|
64
|
+
// unreachable
|
|
65
|
+
helpful_errors_1.UnexpectedCodePathError.throw('unexpected code path in setAppInstallation', {
|
|
66
|
+
input,
|
|
67
|
+
foundBefore,
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
/**
|
|
71
|
+
* .what = syncs repositories for an installation by adding/removing as needed
|
|
72
|
+
* .why = enables declarative management of which repos an installation has access to
|
|
73
|
+
*/
|
|
74
|
+
const syncInstallationRepositories = async (input, context) => {
|
|
75
|
+
const github = (0, getGithubClient_1.getGithubClient)({}, context);
|
|
76
|
+
// determine repos to add and remove
|
|
77
|
+
const reposToAdd = input.desiredRepositories.filter((repo) => !input.currentRepositories.includes(repo));
|
|
78
|
+
const reposToRemove = input.currentRepositories.filter((repo) => !input.desiredRepositories.includes(repo));
|
|
79
|
+
// add repos that are missing
|
|
80
|
+
for (const repoName of reposToAdd) {
|
|
81
|
+
try {
|
|
82
|
+
// first get the repo id
|
|
83
|
+
const repoResponse = await github.repos.get({
|
|
84
|
+
owner: input.app.owner.slug,
|
|
85
|
+
repo: repoName,
|
|
86
|
+
});
|
|
87
|
+
const repoId = repoResponse.data.id;
|
|
88
|
+
// then add it to the installation
|
|
89
|
+
await github.apps.addRepoToInstallationForAuthenticatedUser({
|
|
90
|
+
installation_id: input.installationId,
|
|
91
|
+
repository_id: repoId,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
if (!(error instanceof Error))
|
|
96
|
+
throw error;
|
|
97
|
+
throw new helpful_errors_1.HelpfulError(`failed to add repository "${repoName}" to installation`, {
|
|
98
|
+
cause: error,
|
|
99
|
+
repoName,
|
|
100
|
+
installationId: input.installationId,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// remove repos that shouldn't be there
|
|
105
|
+
for (const repoName of reposToRemove) {
|
|
106
|
+
try {
|
|
107
|
+
// first get the repo id
|
|
108
|
+
const repoResponse = await github.repos.get({
|
|
109
|
+
owner: input.app.owner.slug,
|
|
110
|
+
repo: repoName,
|
|
111
|
+
});
|
|
112
|
+
const repoId = repoResponse.data.id;
|
|
113
|
+
// then remove it from the installation
|
|
114
|
+
await github.apps.removeRepoFromInstallationForAuthenticatedUser({
|
|
115
|
+
installation_id: input.installationId,
|
|
116
|
+
repository_id: repoId,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
if (!(error instanceof Error))
|
|
121
|
+
throw error;
|
|
122
|
+
throw new helpful_errors_1.HelpfulError(`failed to remove repository "${repoName}" from installation`, {
|
|
123
|
+
cause: error,
|
|
124
|
+
repoName,
|
|
125
|
+
installationId: input.installationId,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return { repositories: input.desiredRepositories };
|
|
130
|
+
};
|
|
131
|
+
//# sourceMappingURL=setAppInstallation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setAppInstallation.js","sourceRoot":"","sources":["../../../src/domain.operations/appInstallation/setAppInstallation.ts"],"names":[],"mappings":";;;AAAA,+CAA2C;AAC3C,mDAAuE;AAIvE,uEAAoE;AAGpE,mEAAgE;AAEhE;;;;GAIG;AACU,QAAA,kBAAkB,GAAG,IAAA,0BAAW,EAC3C,KAAK,EACH,KAGE,EACF,OAA6C,EACQ,EAAE;IACvD,MAAM,OAAO,GACX,KAAK,CAAC,OAAO;QACb,KAAK,CAAC,MAAM;QACZ,wCAAuB,CAAC,KAAK,CAC3B,gDAAgD,EAChD,EAAE,KAAK,EAAE,CACV,CAAC;IAEJ,kCAAkC;IAClC,MAAM,WAAW,GAAG,MAAM,IAAA,6CAAqB,EAC7C;QACE,EAAE,EAAE;YACF,MAAM,EAAE;gBACN,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB;SACF;KACF,EACD,OAAO,CACR,CAAC;IAEF,mFAAmF;IACnF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,UAAU,GAAG,2BAA2B,OAAO,CAAC,GAAG,CAAC,IAAI,oBAAoB,CAAC;QAEnF,MAAM,IAAI,6BAAY,CACpB,sFAAsF,EACtF;YACE,UAAU;YACV,YAAY,EAAE;gBACZ,mBAAmB,UAAU,EAAE;gBAC/B,iBAAiB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;gBAC5E,OAAO,CAAC,mBAAmB,KAAK,UAAU;oBACxC,CAAC,CAAC,oDAAoD,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,kBAAkB,EAAE;oBAC9G,CAAC,CAAC,8CAA8C;gBAClD,iDAAiD;aAClD;YACD,OAAO;SACR,CACF,CAAC;IACJ,CAAC;IAED,8DAA8D;IAC9D,IAAI,KAAK,CAAC,OAAO;QAAE,OAAO,WAAW,CAAC;IAEtC,oEAAoE;IACpE,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,gDAAgD;QAChD,IAAI,OAAO,CAAC,mBAAmB,KAAK,UAAU,EAAE,CAAC;YAC/C,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAC/C;gBACE,cAAc,EAAE,WAAW,CAAC,EAAE;gBAC9B,mBAAmB,EAAE,OAAO,CAAC,YAAY,IAAI,EAAE;gBAC/C,mBAAmB,EAAE,WAAW,CAAC,YAAY,IAAI,EAAE;gBACnD,GAAG,EAAE,OAAO,CAAC,GAAG;aACjB,EACD,OAAO,CACR,CAAC;YAEF,sCAAsC;YACtC,MAAM,UAAU,GAAG,MAAM,IAAA,6CAAqB,EAC5C,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,EAAE,EAChE,OAAO,CACR,CAAC;YACF,IAAI,CAAC,UAAU;gBACb,wCAAuB,CAAC,KAAK,CAC3B,2DAA2D,EAC3D,EAAE,OAAO,EAAE,MAAM,EAAE,CACpB,CAAC;YACJ,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,+BAA+B;QAC/B,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,cAAc;IACd,wCAAuB,CAAC,KAAK,CAC3B,4CAA4C,EAC5C;QACE,KAAK;QACL,WAAW;KACZ,CACF,CAAC;AACJ,CAAC,CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,4BAA4B,GAAG,KAAK,EACxC,KAKC,EACD,OAA6C,EACR,EAAE;IACvC,MAAM,MAAM,GAAG,IAAA,iCAAe,EAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAE5C,oCAAoC;IACpC,MAAM,UAAU,GAAG,KAAK,CAAC,mBAAmB,CAAC,MAAM,CACjD,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,CACpD,CAAC;IACF,MAAM,aAAa,GAAG,KAAK,CAAC,mBAAmB,CAAC,MAAM,CACpD,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,CACpD,CAAC;IAEF,6BAA6B;IAC7B,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,wBAAwB;YACxB,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;gBAC1C,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI;gBAC3B,IAAI,EAAE,QAAQ;aACf,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YAEpC,kCAAkC;YAClC,MAAM,MAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC;gBAC1D,eAAe,EAAE,KAAK,CAAC,cAAc;gBACrC,aAAa,EAAE,MAAM;aACtB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;gBAAE,MAAM,KAAK,CAAC;YAC3C,MAAM,IAAI,6BAAY,CACpB,6BAA6B,QAAQ,mBAAmB,EACxD;gBACE,KAAK,EAAE,KAAK;gBACZ,QAAQ;gBACR,cAAc,EAAE,KAAK,CAAC,cAAc;aACrC,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,KAAK,MAAM,QAAQ,IAAI,aAAa,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,wBAAwB;YACxB,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;gBAC1C,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI;gBAC3B,IAAI,EAAE,QAAQ;aACf,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YAEpC,uCAAuC;YACvC,MAAM,MAAM,CAAC,IAAI,CAAC,8CAA8C,CAAC;gBAC/D,eAAe,EAAE,KAAK,CAAC,cAAc;gBACrC,aAAa,EAAE,MAAM;aACtB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;gBAAE,MAAM,KAAK,CAAC;YAC3C,MAAM,IAAI,6BAAY,CACpB,gCAAgC,QAAQ,qBAAqB,EAC7D;gBACE,KAAK,EAAE,KAAK;gBACZ,QAAQ;gBACR,cAAc,EAAE,KAAK,CAAC,cAAc;aACrC,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,KAAK,CAAC,mBAAmB,EAAE,CAAC;AACrD,CAAC,CAAC"}
|
|
@@ -50,7 +50,7 @@ exports.setBranch = (0, as_procedure_1.asProcedure)(async (input, context) => {
|
|
|
50
50
|
name: desired.name,
|
|
51
51
|
},
|
|
52
52
|
},
|
|
53
|
-
}, context)) ?? undefined, { timeout: { seconds:
|
|
53
|
+
}, context)) ?? undefined, { timeout: { seconds: 10 } });
|
|
54
54
|
}
|
|
55
55
|
catch (error) {
|
|
56
56
|
if (!(error instanceof Error))
|
|
@@ -61,20 +61,29 @@ exports.setBranch = (0, as_procedure_1.asProcedure)(async (input, context) => {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
// otherwise, create it
|
|
64
|
+
// determine commit SHA to create branch from
|
|
65
|
+
const commitSha = desired.commit?.sha ??
|
|
66
|
+
(await (0, getBranchCommitShaByRepoDefault_1.getBranchCommitShaByRepoDefault)({
|
|
67
|
+
repo: desired.repo,
|
|
68
|
+
}, context));
|
|
69
|
+
// create the branch using git refs API
|
|
64
70
|
try {
|
|
65
|
-
// determine commit SHA to create branch from
|
|
66
|
-
const commitSha = desired.commit?.sha ??
|
|
67
|
-
(await (0, getBranchCommitShaByRepoDefault_1.getBranchCommitShaByRepoDefault)({
|
|
68
|
-
repo: desired.repo,
|
|
69
|
-
}, context));
|
|
70
|
-
// create the branch using git refs API
|
|
71
71
|
await github.git.createRef({
|
|
72
72
|
owner: desired.repo.owner,
|
|
73
73
|
repo: desired.repo.name,
|
|
74
74
|
ref: `refs/heads/${desired.name}`,
|
|
75
75
|
sha: commitSha,
|
|
76
76
|
});
|
|
77
|
-
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
if (!(error instanceof Error))
|
|
80
|
+
throw error;
|
|
81
|
+
throw new helpful_errors_1.HelpfulError('github.setBranch.createRef error', {
|
|
82
|
+
cause: error,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
// fetch the created branch to return full metadata (with retry for eventual consistency)
|
|
86
|
+
try {
|
|
78
87
|
return await (0, uni_time_1.waitFor)(async () => (await (0, getBranch_1.getBranch)({
|
|
79
88
|
by: {
|
|
80
89
|
unique: {
|
|
@@ -82,12 +91,12 @@ exports.setBranch = (0, as_procedure_1.asProcedure)(async (input, context) => {
|
|
|
82
91
|
name: desired.name,
|
|
83
92
|
},
|
|
84
93
|
},
|
|
85
|
-
}, context)) ?? undefined, { timeout: { seconds:
|
|
94
|
+
}, context)) ?? undefined, { timeout: { seconds: 10 } });
|
|
86
95
|
}
|
|
87
96
|
catch (error) {
|
|
88
97
|
if (!(error instanceof Error))
|
|
89
98
|
throw error;
|
|
90
|
-
throw new helpful_errors_1.HelpfulError('github.setBranch.
|
|
99
|
+
throw new helpful_errors_1.HelpfulError('github.setBranch.waitForBranch error', {
|
|
91
100
|
cause: error,
|
|
92
101
|
});
|
|
93
102
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setBranch.js","sourceRoot":"","sources":["../../../src/domain.operations/branch/setBranch.ts"],"names":[],"mappings":";;;AAAA,iDAA6C;AAC7C,+CAA2C;AAC3C,mDAA8C;AAI9C,uEAAoE;AAGpE,2CAAwC;AACxC,uFAAoF;AAEpF;;;GAGG;AACU,QAAA,SAAS,GAAG,IAAA,0BAAW,EAClC,KAAK,EACH,KAGE,EACF,OAA6C,EACD,EAAE;IAC9C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC;IAE9C,2BAA2B;IAC3B,MAAM,MAAM,GAAG,IAAA,iCAAe,EAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAE5C,sCAAsC;IACtC,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAS,EAC5B;QACE,EAAE,EAAE;YACF,MAAM,EAAE;gBACN,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,IAAI,EAAE,OAAO,CAAC,IAAI;aACnB;SACF;KACF,EACD,OAAO,CACR,CAAC;IAEF,uDAAuD;IACvD,IAAI,MAAM,IAAI,KAAK,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC;IAE3C,8EAA8E;IAC9E,IAAI,MAAM,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG;QAAE,OAAO,MAAM,CAAC;IAClE,IAAI,MAAM,IAAI,KAAK,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,GAAG,KAAK,MAAM,CAAC,MAAM,EAAE,GAAG;QACtE,OAAO,MAAM,CAAC;IAEhB,+DAA+D;IAC/D,IAAI,MAAM,IAAI,KAAK,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC;QAClD,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;gBACzB,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK;gBACzB,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI;gBACvB,GAAG,EAAE,SAAS,OAAO,CAAC,IAAI,EAAE;gBAC5B,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG;gBACvB,KAAK,EAAE,KAAK,EAAE,gDAAgD;aAC/D,CAAC,CAAC;YAEH,yFAAyF;YACzF,OAAO,MAAM,IAAA,kBAAO,EAClB,KAAK,IAAI,EAAE,CACT,CAAC,MAAM,IAAA,qBAAS,EACd;gBACE,EAAE,EAAE;oBACF,MAAM,EAAE;wBACN,IAAI,EAAE,OAAO,CAAC,IAAI;wBAClB,IAAI,EAAE,OAAO,CAAC,IAAI;qBACnB;iBACF;aACF,EACD,OAAO,CACR,CAAC,IAAI,SAAS,EACjB,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"setBranch.js","sourceRoot":"","sources":["../../../src/domain.operations/branch/setBranch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ContextGithubApi } from '../../domain.objects/ContextGithubApi';
|
|
2
|
+
/**
|
|
3
|
+
* .what = checks if context contains a GitHub App installation token
|
|
4
|
+
* .why = different GitHub API endpoints require different token types; app tokens have different scopes than PATs
|
|
5
|
+
*/
|
|
6
|
+
export declare const hasContextWithAppToken: (_input: null, context: ContextGithubApi) => boolean;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasContextWithAppToken = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* .what = checks if context contains a GitHub App installation token
|
|
6
|
+
* .why = different GitHub API endpoints require different token types; app tokens have different scopes than PATs
|
|
7
|
+
*/
|
|
8
|
+
const hasContextWithAppToken = (_input, context) => {
|
|
9
|
+
const token = context.github.token;
|
|
10
|
+
// GitHub App installation token format (server-to-server token)
|
|
11
|
+
const isAppToken = token.startsWith('ghs_');
|
|
12
|
+
return isAppToken;
|
|
13
|
+
};
|
|
14
|
+
exports.hasContextWithAppToken = hasContextWithAppToken;
|
|
15
|
+
//# sourceMappingURL=hasContextWithAppToken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hasContextWithAppToken.js","sourceRoot":"","sources":["../../../src/domain.operations/context/hasContextWithAppToken.ts"],"names":[],"mappings":";;;AAEA;;;GAGG;AACI,MAAM,sBAAsB,GAAG,CACpC,MAAY,EACZ,OAAyB,EAChB,EAAE;IACX,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;IAEnC,gEAAgE;IAChE,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAE5C,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AAVW,QAAA,sBAAsB,0BAUjC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ContextGithubApi } from '../../domain.objects/ContextGithubApi';
|
|
2
|
+
/**
|
|
3
|
+
* .what = checks if context contains a GitHub Personal Access Token (PAT)
|
|
4
|
+
* .why = different GitHub API endpoints require different token types; PATs have different permissions than app tokens
|
|
5
|
+
*/
|
|
6
|
+
export declare const hasContextWithPatToken: (_input: null, context: ContextGithubApi) => boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasContextWithPatToken = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* .what = checks if context contains a GitHub Personal Access Token (PAT)
|
|
6
|
+
* .why = different GitHub API endpoints require different token types; PATs have different permissions than app tokens
|
|
7
|
+
*/
|
|
8
|
+
const hasContextWithPatToken = (_input, context) => {
|
|
9
|
+
const token = context.github.token;
|
|
10
|
+
// classic PAT format
|
|
11
|
+
const isClassicPat = token.startsWith('ghp_');
|
|
12
|
+
// fine-grained PAT format
|
|
13
|
+
const isFineGrainedPat = token.startsWith('github_pat_');
|
|
14
|
+
return isClassicPat || isFineGrainedPat;
|
|
15
|
+
};
|
|
16
|
+
exports.hasContextWithPatToken = hasContextWithPatToken;
|
|
17
|
+
//# sourceMappingURL=hasContextWithPatToken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hasContextWithPatToken.js","sourceRoot":"","sources":["../../../src/domain.operations/context/hasContextWithPatToken.ts"],"names":[],"mappings":";;;AAEA;;;GAGG;AACI,MAAM,sBAAsB,GAAG,CACpC,MAAY,EACZ,OAAyB,EAChB,EAAE;IACX,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;IAEnC,qBAAqB;IACrB,MAAM,YAAY,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAE9C,0BAA0B;IAC1B,MAAM,gBAAgB,GAAG,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAEzD,OAAO,YAAY,IAAI,gBAAgB,CAAC;AAC1C,CAAC,CAAC;AAbW,QAAA,sBAAsB,0BAajC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Endpoints } from '@octokit/types';
|
|
2
|
+
import { type HasMetadata } from 'type-fns';
|
|
3
|
+
import { DeclaredGithubOrg } from '../../domain.objects/DeclaredGithubOrg';
|
|
4
|
+
type GithubOrgResponse = Endpoints['GET /orgs/{org}']['response']['data'];
|
|
5
|
+
/**
|
|
6
|
+
* .what = casts GitHub API org response to DeclaredGithubOrg
|
|
7
|
+
* .why = transforms external API shape to our domain model with type safety and validation
|
|
8
|
+
*/
|
|
9
|
+
export declare const castToDeclaredGithubOrg: (input: {
|
|
10
|
+
data: GithubOrgResponse;
|
|
11
|
+
}) => HasMetadata<DeclaredGithubOrg>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.castToDeclaredGithubOrg = void 0;
|
|
4
|
+
const uni_time_1 = require("@ehmpathy/uni-time");
|
|
5
|
+
const type_fns_1 = require("type-fns");
|
|
6
|
+
const DeclaredGithubOrg_1 = require("../../domain.objects/DeclaredGithubOrg");
|
|
7
|
+
/**
|
|
8
|
+
* .what = casts GitHub API org response to DeclaredGithubOrg
|
|
9
|
+
* .why = transforms external API shape to our domain model with type safety and validation
|
|
10
|
+
*/
|
|
11
|
+
const castToDeclaredGithubOrg = (input) => {
|
|
12
|
+
return DeclaredGithubOrg_1.DeclaredGithubOrg.as({
|
|
13
|
+
id: (0, type_fns_1.assure)(input.data.id, type_fns_1.isPresent),
|
|
14
|
+
login: (0, type_fns_1.assure)(input.data.login, type_fns_1.isPresent),
|
|
15
|
+
name: input.data.name ?? null,
|
|
16
|
+
description: input.data.description ?? null,
|
|
17
|
+
billingEmail: undefined, // write-only: not read back from API
|
|
18
|
+
twoFactorRequirementEnabled: input.data.two_factor_requirement_enabled ?? undefined,
|
|
19
|
+
publicRepos: input.data.public_repos ?? undefined,
|
|
20
|
+
createdAt: input.data.created_at
|
|
21
|
+
? (0, uni_time_1.asUniDateTime)(input.data.created_at)
|
|
22
|
+
: undefined,
|
|
23
|
+
updatedAt: input.data.updated_at
|
|
24
|
+
? (0, uni_time_1.asUniDateTime)(input.data.updated_at)
|
|
25
|
+
: undefined,
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
exports.castToDeclaredGithubOrg = castToDeclaredGithubOrg;
|
|
29
|
+
//# sourceMappingURL=castToDeclaredGithubOrg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"castToDeclaredGithubOrg.js","sourceRoot":"","sources":["../../../src/domain.operations/org/castToDeclaredGithubOrg.ts"],"names":[],"mappings":";;;AAAA,iDAAmD;AAEnD,uCAA+D;AAE/D,8EAA2E;AAI3E;;;GAGG;AACI,MAAM,uBAAuB,GAAG,CAAC,KAEvC,EAAkC,EAAE;IACnC,OAAO,qCAAiB,CAAC,EAAE,CAAC;QAC1B,EAAE,EAAE,IAAA,iBAAM,EAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,oBAAS,CAAC;QACpC,KAAK,EAAE,IAAA,iBAAM,EAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,oBAAS,CAAC;QAC1C,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI;QAC7B,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI;QAC3C,YAAY,EAAE,SAAS,EAAE,qCAAqC;QAC9D,2BAA2B,EACzB,KAAK,CAAC,IAAI,CAAC,8BAA8B,IAAI,SAAS;QACxD,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,SAAS;QACjD,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU;YAC9B,CAAC,CAAC,IAAA,wBAAa,EAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;YACtC,CAAC,CAAC,SAAS;QACb,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU;YAC9B,CAAC,CAAC,IAAA,wBAAa,EAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;YACtC,CAAC,CAAC,SAAS;KACd,CAAmC,CAAC;AACvC,CAAC,CAAC;AAnBW,QAAA,uBAAuB,2BAmBlC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { RefByUnique } from 'domain-objects';
|
|
2
|
+
import type { HasMetadata, PickOne } from 'type-fns';
|
|
3
|
+
import type { VisualogicContext } from 'visualogic';
|
|
4
|
+
import type { ContextGithubApi } from '../../domain.objects/ContextGithubApi';
|
|
5
|
+
import type { DeclaredGithubOrg } from '../../domain.objects/DeclaredGithubOrg';
|
|
6
|
+
/**
|
|
7
|
+
* .what = gets a GitHub Organization's settings
|
|
8
|
+
* .why = retrieves current state of org for declarative management
|
|
9
|
+
*/
|
|
10
|
+
export declare const getOneOrg: (input: {
|
|
11
|
+
by: PickOne<{
|
|
12
|
+
unique: RefByUnique<typeof DeclaredGithubOrg>;
|
|
13
|
+
}>;
|
|
14
|
+
}, context: ContextGithubApi & VisualogicContext) => Promise<HasMetadata<DeclaredGithubOrg> | null>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getOneOrg = void 0;
|
|
4
|
+
const as_procedure_1 = require("as-procedure");
|
|
5
|
+
const helpful_errors_1 = require("helpful-errors");
|
|
6
|
+
const getGithubClient_1 = require("../../access/sdks/getGithubClient");
|
|
7
|
+
const castToDeclaredGithubOrg_1 = require("./castToDeclaredGithubOrg");
|
|
8
|
+
/**
|
|
9
|
+
* .what = gets a GitHub Organization's settings
|
|
10
|
+
* .why = retrieves current state of org for declarative management
|
|
11
|
+
*/
|
|
12
|
+
exports.getOneOrg = (0, as_procedure_1.asProcedure)(async (input, context) => {
|
|
13
|
+
const github = (0, getGithubClient_1.getGithubClient)({}, context);
|
|
14
|
+
const login = (() => {
|
|
15
|
+
if (input.by.unique)
|
|
16
|
+
return input.by.unique.login;
|
|
17
|
+
helpful_errors_1.UnexpectedCodePathError.throw('not referenced by unique', { input });
|
|
18
|
+
})();
|
|
19
|
+
try {
|
|
20
|
+
const response = await github.orgs.get({ org: login });
|
|
21
|
+
return (0, castToDeclaredGithubOrg_1.castToDeclaredGithubOrg)({ data: response.data });
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
if (!(error instanceof Error))
|
|
25
|
+
throw error;
|
|
26
|
+
if (error.message.includes('Not Found'))
|
|
27
|
+
return null;
|
|
28
|
+
throw new helpful_errors_1.HelpfulError('github.getOrg error', { cause: error });
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
//# sourceMappingURL=getOneOrg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getOneOrg.js","sourceRoot":"","sources":["../../../src/domain.operations/org/getOneOrg.ts"],"names":[],"mappings":";;;AAAA,+CAA2C;AAE3C,mDAAuE;AAIvE,uEAAoE;AAGpE,uEAAoE;AAEpE;;;GAGG;AACU,QAAA,SAAS,GAAG,IAAA,0BAAW,EAClC,KAAK,EACH,KAIC,EACD,OAA6C,EACG,EAAE;IAClD,MAAM,MAAM,GAAG,IAAA,iCAAe,EAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAE5C,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE;QAClB,IAAI,KAAK,CAAC,EAAE,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;QAClD,wCAAuB,CAAC,KAAK,CAAC,0BAA0B,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACvE,CAAC,CAAC,EAAE,CAAC;IAEL,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QACvD,OAAO,IAAA,iDAAuB,EAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;YAAE,MAAM,KAAK,CAAC;QAC3C,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,OAAO,IAAI,CAAC;QACrD,MAAM,IAAI,6BAAY,CAAC,qBAAqB,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAClE,CAAC;AACH,CAAC,CACF,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { HasMetadata, PickOne } from 'type-fns';
|
|
2
|
+
import type { VisualogicContext } from 'visualogic';
|
|
3
|
+
import type { ContextGithubApi } from '../../domain.objects/ContextGithubApi';
|
|
4
|
+
import type { DeclaredGithubOrg } from '../../domain.objects/DeclaredGithubOrg';
|
|
5
|
+
/**
|
|
6
|
+
* .what = sets GitHub Organization profile settings
|
|
7
|
+
* .why = enables declarative management of org profile
|
|
8
|
+
*
|
|
9
|
+
* AUTOMATION BOUNDARIES:
|
|
10
|
+
* - AUTOMATED: Profile settings via PATCH /orgs/{org}
|
|
11
|
+
* - NOTE: Cannot create organizations via API (only update existing)
|
|
12
|
+
* - NOTE: Member privileges are managed via DeclaredGithubOrgMemberPrivileges
|
|
13
|
+
*/
|
|
14
|
+
export declare const setOrg: (input: PickOne<{
|
|
15
|
+
finsert: DeclaredGithubOrg;
|
|
16
|
+
upsert: DeclaredGithubOrg;
|
|
17
|
+
}>, context: ContextGithubApi & VisualogicContext) => Promise<HasMetadata<DeclaredGithubOrg>>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setOrg = void 0;
|
|
4
|
+
const as_procedure_1 = require("as-procedure");
|
|
5
|
+
const helpful_errors_1 = require("helpful-errors");
|
|
6
|
+
const getGithubClient_1 = require("../../access/sdks/getGithubClient");
|
|
7
|
+
const castToDeclaredGithubOrg_1 = require("./castToDeclaredGithubOrg");
|
|
8
|
+
const getOneOrg_1 = require("./getOneOrg");
|
|
9
|
+
/**
|
|
10
|
+
* .what = sets GitHub Organization profile settings
|
|
11
|
+
* .why = enables declarative management of org profile
|
|
12
|
+
*
|
|
13
|
+
* AUTOMATION BOUNDARIES:
|
|
14
|
+
* - AUTOMATED: Profile settings via PATCH /orgs/{org}
|
|
15
|
+
* - NOTE: Cannot create organizations via API (only update existing)
|
|
16
|
+
* - NOTE: Member privileges are managed via DeclaredGithubOrgMemberPrivileges
|
|
17
|
+
*/
|
|
18
|
+
exports.setOrg = (0, as_procedure_1.asProcedure)(async (input, context) => {
|
|
19
|
+
const desired = input.finsert ?? input.upsert;
|
|
20
|
+
const github = (0, getGithubClient_1.getGithubClient)({}, context);
|
|
21
|
+
// Check if org exists
|
|
22
|
+
const before = await (0, getOneOrg_1.getOneOrg)({ by: { unique: { login: desired.login } } }, context);
|
|
23
|
+
// Cannot create orgs via API - must exist
|
|
24
|
+
if (!before) {
|
|
25
|
+
throw new helpful_errors_1.HelpfulError('GitHub Organization does not exist and cannot be created via API.\n' +
|
|
26
|
+
'Organizations must be created manually via the GitHub UI.', {
|
|
27
|
+
createUrl: 'https://github.com/organizations/plan',
|
|
28
|
+
desiredOrg: desired,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
// If finsert and found, return as-is (no changes)
|
|
32
|
+
if (before && input.finsert)
|
|
33
|
+
return before;
|
|
34
|
+
// Apply profile updates via PATCH
|
|
35
|
+
try {
|
|
36
|
+
const response = await github.orgs.update({
|
|
37
|
+
org: desired.login,
|
|
38
|
+
name: desired.name ?? undefined,
|
|
39
|
+
description: desired.description ?? undefined,
|
|
40
|
+
billing_email: desired.billingEmail ?? undefined,
|
|
41
|
+
});
|
|
42
|
+
return (0, castToDeclaredGithubOrg_1.castToDeclaredGithubOrg)({ data: response.data });
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (!(error instanceof Error))
|
|
46
|
+
throw error;
|
|
47
|
+
throw new helpful_errors_1.HelpfulError('github.setOrg.update error', { cause: error });
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=setOrg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setOrg.js","sourceRoot":"","sources":["../../../src/domain.operations/org/setOrg.ts"],"names":[],"mappings":";;;AAAA,+CAA2C;AAC3C,mDAA8C;AAI9C,uEAAoE;AAGpE,uEAAoE;AACpE,2CAAwC;AAExC;;;;;;;;GAQG;AACU,QAAA,MAAM,GAAG,IAAA,0BAAW,EAC/B,KAAK,EACH,KAGE,EACF,OAA6C,EACJ,EAAE;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAA,iCAAe,EAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAE5C,sBAAsB;IACtB,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAS,EAC5B,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,EAAE,EAC5C,OAAO,CACR,CAAC;IAEF,0CAA0C;IAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,6BAAY,CACpB,qEAAqE;YACnE,2DAA2D,EAC7D;YACE,SAAS,EAAE,uCAAuC;YAClD,UAAU,EAAE,OAAO;SACpB,CACF,CAAC;IACJ,CAAC;IAED,kDAAkD;IAClD,IAAI,MAAM,IAAI,KAAK,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC;IAE3C,kCAAkC;IAClC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;YACxC,GAAG,EAAE,OAAO,CAAC,KAAK;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,SAAS;YAC/B,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,SAAS;YAC7C,aAAa,EAAE,OAAO,CAAC,YAAY,IAAI,SAAS;SACjD,CAAC,CAAC;QAEH,OAAO,IAAA,iDAAuB,EAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;YAAE,MAAM,KAAK,CAAC;QAC3C,MAAM,IAAI,6BAAY,CAAC,4BAA4B,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACzE,CAAC;AACH,CAAC,CACF,CAAC"}
|
package/dist/domain.operations/orgMemberPrivileges/castToDeclaredGithubOrgMemberPrivileges.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Endpoints } from '@octokit/types';
|
|
2
|
+
import type { RefByUnique } from 'domain-objects';
|
|
3
|
+
import type { HasMetadata } from 'type-fns';
|
|
4
|
+
import type { DeclaredGithubOrg } from '../../domain.objects/DeclaredGithubOrg';
|
|
5
|
+
import { DeclaredGithubOrgMemberPrivileges } from '../../domain.objects/DeclaredGithubOrgMemberPrivileges';
|
|
6
|
+
type GithubOrgResponse = Endpoints['GET /orgs/{org}']['response']['data'];
|
|
7
|
+
/**
|
|
8
|
+
* .what = casts GitHub API org response to DeclaredGithubOrgMemberPrivileges
|
|
9
|
+
* .why = extracts member privilege fields from org API response
|
|
10
|
+
*/
|
|
11
|
+
export declare const castToDeclaredGithubOrgMemberPrivileges: (input: {
|
|
12
|
+
data: GithubOrgResponse;
|
|
13
|
+
org: RefByUnique<typeof DeclaredGithubOrg>;
|
|
14
|
+
}) => HasMetadata<DeclaredGithubOrgMemberPrivileges>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.castToDeclaredGithubOrgMemberPrivileges = void 0;
|
|
4
|
+
const uni_time_1 = require("@ehmpathy/uni-time");
|
|
5
|
+
const DeclaredGithubOrgMemberPrivileges_1 = require("../../domain.objects/DeclaredGithubOrgMemberPrivileges");
|
|
6
|
+
/**
|
|
7
|
+
* .what = casts GitHub API org response to DeclaredGithubOrgMemberPrivileges
|
|
8
|
+
* .why = extracts member privilege fields from org API response
|
|
9
|
+
*/
|
|
10
|
+
const castToDeclaredGithubOrgMemberPrivileges = (input) => {
|
|
11
|
+
return DeclaredGithubOrgMemberPrivileges_1.DeclaredGithubOrgMemberPrivileges.as({
|
|
12
|
+
org: input.org,
|
|
13
|
+
updatedAt: input.data.updated_at
|
|
14
|
+
? (0, uni_time_1.asUniDateTime)(input.data.updated_at)
|
|
15
|
+
: undefined,
|
|
16
|
+
// Repository creation
|
|
17
|
+
membersCanCreateRepositories: input.data.members_can_create_repositories ?? true,
|
|
18
|
+
membersCanCreatePublicRepositories: input.data.members_can_create_public_repositories ?? true,
|
|
19
|
+
membersCanCreatePrivateRepositories: input.data.members_can_create_private_repositories ?? true,
|
|
20
|
+
membersCanCreateInternalRepositories: (() => {
|
|
21
|
+
// internal repos only available for enterprise orgs
|
|
22
|
+
const isEnterprise = input.data.plan?.name
|
|
23
|
+
?.toLowerCase()
|
|
24
|
+
.includes('enterprise');
|
|
25
|
+
if (!isEnterprise)
|
|
26
|
+
return null;
|
|
27
|
+
return input.data.members_can_create_internal_repositories ?? null;
|
|
28
|
+
})(),
|
|
29
|
+
// Repository management (KEY SECURITY)
|
|
30
|
+
membersCanDeleteRepositories:
|
|
31
|
+
// Note: GitHub API uses 'members_can_delete_repositories' field
|
|
32
|
+
input.data
|
|
33
|
+
.members_can_delete_repositories ?? true,
|
|
34
|
+
membersCanChangeRepoVisibility: input.data
|
|
35
|
+
.members_can_change_repo_visibility ?? true,
|
|
36
|
+
membersCanForkPrivateRepositories: input.data.members_can_fork_private_repositories ?? false,
|
|
37
|
+
// Collaboration
|
|
38
|
+
membersCanInviteOutsideCollaborators: true, // Not directly exposed in API
|
|
39
|
+
// GitHub Pages
|
|
40
|
+
membersCanCreatePages: input.data.members_can_create_pages ?? true,
|
|
41
|
+
membersCanCreatePublicPages: input.data.members_can_create_public_pages ?? true,
|
|
42
|
+
membersCanCreatePrivatePages: input.data.members_can_create_private_pages ?? true,
|
|
43
|
+
defaultRepositoryPermission: input.data.default_repository_permission ?? 'read',
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
exports.castToDeclaredGithubOrgMemberPrivileges = castToDeclaredGithubOrgMemberPrivileges;
|
|
47
|
+
//# sourceMappingURL=castToDeclaredGithubOrgMemberPrivileges.js.map
|