@ethlete/cli 2.1.0-next.5 → 2.1.0-next.7
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/CHANGELOG.md +37 -0
- package/README.md +39 -4
- package/package.json +1 -1
- package/src/index.js +51 -11
- package/src/index.js.map +1 -1
- package/src/lib/api/api-command.d.ts +2 -1
- package/src/lib/api/api-command.js +2 -2
- package/src/lib/api/api-command.js.map +1 -1
- package/src/lib/api/auth-hint.d.ts +7 -0
- package/src/lib/api/auth-hint.js +27 -1
- package/src/lib/api/auth-hint.js.map +1 -1
- package/src/lib/api/clear.d.ts +36 -0
- package/src/lib/api/clear.js +121 -0
- package/src/lib/api/clear.js.map +1 -0
- package/src/lib/api/compose.d.ts +29 -0
- package/src/lib/api/compose.js +44 -1
- package/src/lib/api/compose.js.map +1 -1
- package/src/lib/api/definition.d.ts +8 -3
- package/src/lib/api/definition.js +28 -4
- package/src/lib/api/definition.js.map +1 -1
- package/src/lib/api/git.d.ts +4 -0
- package/src/lib/api/git.js +14 -2
- package/src/lib/api/git.js.map +1 -1
- package/src/lib/api/help.d.ts +9 -1
- package/src/lib/api/help.js +43 -10
- package/src/lib/api/help.js.map +1 -1
- package/src/lib/api/index.d.ts +5 -0
- package/src/lib/api/index.js +5 -0
- package/src/lib/api/index.js.map +1 -1
- package/src/lib/api/ports.d.ts +13 -0
- package/src/lib/api/ports.js +98 -0
- package/src/lib/api/ports.js.map +1 -0
- package/src/lib/api/resolve-checkout.d.ts +19 -9
- package/src/lib/api/resolve-checkout.js +18 -5
- package/src/lib/api/resolve-checkout.js.map +1 -1
- package/src/lib/api/run.js +240 -57
- package/src/lib/api/run.js.map +1 -1
- package/src/lib/api/setup.d.ts +15 -0
- package/src/lib/api/setup.js +41 -0
- package/src/lib/api/setup.js.map +1 -0
- package/src/lib/api/state.d.ts +20 -0
- package/src/lib/api/state.js +33 -0
- package/src/lib/api/state.js.map +1 -0
- package/src/lib/api/suggest.d.ts +7 -0
- package/src/lib/api/suggest.js +35 -0
- package/src/lib/api/suggest.js.map +1 -0
- package/src/lib/auth/auth-command.d.ts +11 -0
- package/src/lib/auth/auth-command.js +165 -0
- package/src/lib/auth/auth-command.js.map +1 -0
- package/src/lib/auth/composer-auth.d.ts +30 -0
- package/src/lib/auth/composer-auth.js +70 -0
- package/src/lib/auth/composer-auth.js.map +1 -0
- package/src/lib/auth/composer-repositories.d.ts +5 -0
- package/src/lib/auth/composer-repositories.js +33 -0
- package/src/lib/auth/composer-repositories.js.map +1 -0
- package/src/lib/auth/gitlab-token.d.ts +43 -0
- package/src/lib/auth/gitlab-token.js +72 -0
- package/src/lib/auth/gitlab-token.js.map +1 -0
- package/src/lib/auth/index.d.ts +4 -0
- package/src/lib/auth/index.js +8 -0
- package/src/lib/auth/index.js.map +1 -0
- package/src/lib/doctor/doctor-command.d.ts +2 -1
- package/src/lib/doctor/doctor-command.js +4 -7
- package/src/lib/doctor/doctor-command.js.map +1 -1
- package/src/lib/index.d.ts +2 -0
- package/src/lib/index.js +2 -0
- package/src/lib/index.js.map +1 -1
- package/src/lib/invocation.d.ts +9 -0
- package/src/lib/invocation.js +47 -0
- package/src/lib/invocation.js.map +1 -0
- package/src/lib/utils.d.ts +14 -0
- package/src/lib/utils.js +14 -1
- package/src/lib/utils.js.map +1 -1
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.authCommand = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const auth_hint_1 = require("../api/auth-hint");
|
|
6
|
+
const load_definitions_1 = require("../api/load-definitions");
|
|
7
|
+
const resolve_checkout_1 = require("../api/resolve-checkout");
|
|
8
|
+
const utils_1 = require("../utils");
|
|
9
|
+
const composer_auth_1 = require("./composer-auth");
|
|
10
|
+
const composer_repositories_1 = require("./composer-repositories");
|
|
11
|
+
const gitlab_token_1 = require("./gitlab-token");
|
|
12
|
+
const usage = (invocation) => [
|
|
13
|
+
`Usage: ${invocation} [host] <token>`,
|
|
14
|
+
'',
|
|
15
|
+
"Writes a GitLab token into composer's auth.json, which the API containers mount, so a",
|
|
16
|
+
'private dependency can be downloaded. The token is checked against the host first.',
|
|
17
|
+
'',
|
|
18
|
+
'The host is optional when every API in ethlete.apis.js sits on the same one.',
|
|
19
|
+
'',
|
|
20
|
+
'A host may be written as a url. Only its host name is used.',
|
|
21
|
+
'',
|
|
22
|
+
'Flags',
|
|
23
|
+
' --force Write the token even when the check says it cannot fetch code, and replace',
|
|
24
|
+
' a token the file already holds for that host without asking',
|
|
25
|
+
].join('\n');
|
|
26
|
+
/**
|
|
27
|
+
* Every host in play, and the projects on each one that a token is needed for. The projects come from
|
|
28
|
+
* the `repositories` of each checkout's composer.json, never from the API's own repoUrl: a developer
|
|
29
|
+
* fetches that one with their own credential, while the token is for its private dependencies.
|
|
30
|
+
*/
|
|
31
|
+
const surveyHosts = (root) => {
|
|
32
|
+
var _a;
|
|
33
|
+
const loaded = (0, load_definitions_1.loadApiDefinitions)(root);
|
|
34
|
+
const hosts = new Set();
|
|
35
|
+
const projects = new Map();
|
|
36
|
+
if (!loaded.found)
|
|
37
|
+
return { hosts: [...hosts], projects };
|
|
38
|
+
for (const [name, api] of Object.entries(loaded.apis)) {
|
|
39
|
+
const apiHost = api.repoUrl ? (0, auth_hint_1.gitUrlHost)(api.repoUrl) : undefined;
|
|
40
|
+
if (apiHost)
|
|
41
|
+
hosts.add(apiHost);
|
|
42
|
+
const checkout = (0, resolve_checkout_1.resolveApiCheckout)({ root, name, api, needs: 'repo' });
|
|
43
|
+
if (!checkout.ok)
|
|
44
|
+
continue;
|
|
45
|
+
for (const url of (0, composer_repositories_1.composerGitRepositories)(checkout.checkout.repoPath)) {
|
|
46
|
+
const host = (0, auth_hint_1.gitUrlHost)(url);
|
|
47
|
+
const projectPath = (0, auth_hint_1.gitUrlProjectPath)(url);
|
|
48
|
+
if (!host || !projectPath)
|
|
49
|
+
continue;
|
|
50
|
+
hosts.add(host);
|
|
51
|
+
projects.set(host, ((_a = projects.get(host)) !== null && _a !== void 0 ? _a : new Set()).add(projectPath));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return { hosts: [...hosts], projects };
|
|
55
|
+
};
|
|
56
|
+
const describeClone = (check) => {
|
|
57
|
+
switch (check.state) {
|
|
58
|
+
case 'clonable':
|
|
59
|
+
return { line: 'can be fetched', ok: true };
|
|
60
|
+
case 'forbidden':
|
|
61
|
+
return { line: '403: this token cannot fetch it', ok: false };
|
|
62
|
+
case 'unauthorized':
|
|
63
|
+
return { line: '401: the token was rejected', ok: false };
|
|
64
|
+
case 'missing':
|
|
65
|
+
return { line: '404: this token cannot see it', ok: false };
|
|
66
|
+
case 'unreachable':
|
|
67
|
+
return { line: `not checked: ${check.reason}`, ok: true };
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const printTokenLine = (host, token) => (0, gitlab_token_1.describeGitlabToken)({ host, token }).then((check) => {
|
|
71
|
+
if (check.state === 'unauthorized')
|
|
72
|
+
return false;
|
|
73
|
+
if (check.state === 'unreachable')
|
|
74
|
+
console.log(` token not checked: ${check.reason}`);
|
|
75
|
+
else if (check.state === 'undisclosed')
|
|
76
|
+
console.log(' token accepted, and keeps its own details private');
|
|
77
|
+
else {
|
|
78
|
+
const named = check.name ? `"${check.name}", ` : '';
|
|
79
|
+
const expires = check.expiresAt ? `, expires ${check.expiresAt}` : '';
|
|
80
|
+
console.log(` token ${named}scopes: ${check.scopes.join(', ') || 'none'}${expires}`);
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
});
|
|
84
|
+
/** Writes a GitLab token into composer's auth.json, after asking the host whether it can fetch code. */
|
|
85
|
+
const authCommand = (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ argv, root = process.cwd(), invocation = 'et auth', home = (0, composer_auth_1.defaultComposerHome)(), }) {
|
|
86
|
+
var _b, _c, _d;
|
|
87
|
+
if (argv.includes('--help') || argv.includes('-h')) {
|
|
88
|
+
console.log(usage(invocation));
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
const positional = argv.filter((arg) => !arg.startsWith('--'));
|
|
92
|
+
if (positional.length === 0 || positional.length > 2) {
|
|
93
|
+
console.error(usage(invocation));
|
|
94
|
+
return 1;
|
|
95
|
+
}
|
|
96
|
+
const force = argv.includes('--force');
|
|
97
|
+
const survey = surveyHosts(root);
|
|
98
|
+
const named = positional.length === 2;
|
|
99
|
+
const host = named ? (0, auth_hint_1.gitHostFromInput)((_b = positional[0]) !== null && _b !== void 0 ? _b : '') : survey.hosts[0];
|
|
100
|
+
const token = (_c = positional[named ? 1 : 0]) !== null && _c !== void 0 ? _c : '';
|
|
101
|
+
if (named && host === undefined) {
|
|
102
|
+
console.error(`"${positional[0]}" holds no host name. Name the host itself:\n\n ${invocation} gitlab.example.com <token>`);
|
|
103
|
+
return 1;
|
|
104
|
+
}
|
|
105
|
+
if (host === undefined) {
|
|
106
|
+
console.error(`No host to write a token for. ethlete.apis.js declares no repoUrl, so name the host:\n\n` +
|
|
107
|
+
` ${invocation} gitlab.example.com <token>`);
|
|
108
|
+
return 1;
|
|
109
|
+
}
|
|
110
|
+
if (!named && survey.hosts.length > 1) {
|
|
111
|
+
console.error(`${survey.hosts.length} hosts are in use, so name the one this token is for:\n\n` +
|
|
112
|
+
survey.hosts.map((known) => ` ${invocation} ${known} <token>`).join('\n'));
|
|
113
|
+
return 1;
|
|
114
|
+
}
|
|
115
|
+
console.log(`\n${host}`);
|
|
116
|
+
if (!(yield printTokenLine(host, token))) {
|
|
117
|
+
console.error(' token rejected with 401. It is wrong, expired or revoked.\n\nNothing was written.');
|
|
118
|
+
return 1;
|
|
119
|
+
}
|
|
120
|
+
const projectPaths = [...((_d = survey.projects.get(host)) !== null && _d !== void 0 ? _d : [])];
|
|
121
|
+
let fetchable = projectPaths.length === 0;
|
|
122
|
+
if (projectPaths.length === 0) {
|
|
123
|
+
console.log(' fetch no private dependency on that host to try');
|
|
124
|
+
}
|
|
125
|
+
for (const projectPath of projectPaths) {
|
|
126
|
+
const described = describeClone(yield (0, gitlab_token_1.checkGitCloneAccess)({ host, projectPath, token }));
|
|
127
|
+
fetchable = fetchable || described.ok;
|
|
128
|
+
console.log(` fetch ${projectPath} ${described.line}`);
|
|
129
|
+
}
|
|
130
|
+
if (!fetchable && !force) {
|
|
131
|
+
console.error(`\nNothing was written. A token that cannot fetch those repositories cannot install them.\n` +
|
|
132
|
+
`Give it read access to the code, or re-run with --force to write it anyway.`);
|
|
133
|
+
return 1;
|
|
134
|
+
}
|
|
135
|
+
const stored = (0, composer_auth_1.storedGitlabToken)({ home, host });
|
|
136
|
+
if (stored !== undefined && stored !== token && !force) {
|
|
137
|
+
const accepted = yield (0, utils_1.confirm)({
|
|
138
|
+
problem: `\n${(0, composer_auth_1.composerAuthPath)(home)} already holds a different token for ${host}.`,
|
|
139
|
+
question: 'Replace it?',
|
|
140
|
+
hint: 'Re-run in a terminal to answer the question, or re-run with --force to replace it.',
|
|
141
|
+
defaultsToYes: false,
|
|
142
|
+
});
|
|
143
|
+
if (!accepted) {
|
|
144
|
+
console.error('\nNothing was written. The token already in the file was kept.');
|
|
145
|
+
return 1;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const written = (0, composer_auth_1.writeGitlabToken)({ home, host, token });
|
|
149
|
+
if (!written.ok) {
|
|
150
|
+
console.error(`\n${written.problem}`);
|
|
151
|
+
return 1;
|
|
152
|
+
}
|
|
153
|
+
const strays = (0, composer_auth_1.gitlabTokenHosts)(home).filter((key) => key !== host && (0, auth_hint_1.gitHostFromInput)(key) === host);
|
|
154
|
+
const single = strays.length === 1;
|
|
155
|
+
const unused = single ? 'that entry is' : 'those entries are';
|
|
156
|
+
console.log(`\n${written.replaced ? 'Replaced' : 'Wrote'} the ${host} token in ${(0, composer_auth_1.composerAuthPath)(home)}.\n` +
|
|
157
|
+
`The API containers mount that directory, so composer inside them reads it.` +
|
|
158
|
+
(strays.length === 0
|
|
159
|
+
? ''
|
|
160
|
+
: `\n\nThe file also holds ${strays.map((key) => `"${key}"`).join(', ')} for the same host. Composer ` +
|
|
161
|
+
`matches a gitlab-token by host name, so ${unused} never used. You can remove ${single ? 'it' : 'them'}.`));
|
|
162
|
+
return 0;
|
|
163
|
+
});
|
|
164
|
+
exports.authCommand = authCommand;
|
|
165
|
+
//# sourceMappingURL=auth-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-command.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/auth/auth-command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The compose file of every API here mounts `$HOME/.composer` into its container, so this is the
|
|
3
|
+
* directory the container's composer reads, whatever `COMPOSER_HOME` says on the host.
|
|
4
|
+
*/
|
|
5
|
+
export declare const defaultComposerHome: () => string;
|
|
6
|
+
export declare const composerAuthPath: (home: string) => string;
|
|
7
|
+
export type WriteTokenResult = {
|
|
8
|
+
ok: true;
|
|
9
|
+
path: string;
|
|
10
|
+
replaced: boolean;
|
|
11
|
+
} | {
|
|
12
|
+
ok: false;
|
|
13
|
+
problem: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Adds one host's GitLab token to composer's auth.json, keeping every other credential in the file.
|
|
17
|
+
* A file that cannot be parsed is reported rather than replaced, so nothing already in it is lost.
|
|
18
|
+
*/
|
|
19
|
+
export declare const writeGitlabToken: (options: {
|
|
20
|
+
home: string;
|
|
21
|
+
host: string;
|
|
22
|
+
token: string;
|
|
23
|
+
}) => WriteTokenResult;
|
|
24
|
+
/** The token composer already holds for one host, or undefined when it holds none. */
|
|
25
|
+
export declare const storedGitlabToken: (options: {
|
|
26
|
+
home: string;
|
|
27
|
+
host: string;
|
|
28
|
+
}) => string | undefined;
|
|
29
|
+
/** The hosts composer already holds a GitLab token for. */
|
|
30
|
+
export declare const gitlabTokenHosts: (home: string) => string[];
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.gitlabTokenHosts = exports.storedGitlabToken = exports.writeGitlabToken = exports.composerAuthPath = exports.defaultComposerHome = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const os_1 = require("os");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
/**
|
|
8
|
+
* The compose file of every API here mounts `$HOME/.composer` into its container, so this is the
|
|
9
|
+
* directory the container's composer reads, whatever `COMPOSER_HOME` says on the host.
|
|
10
|
+
*/
|
|
11
|
+
const defaultComposerHome = () => (0, path_1.join)((0, os_1.homedir)(), '.composer');
|
|
12
|
+
exports.defaultComposerHome = defaultComposerHome;
|
|
13
|
+
const composerAuthPath = (home) => (0, path_1.join)(home, 'auth.json');
|
|
14
|
+
exports.composerAuthPath = composerAuthPath;
|
|
15
|
+
const GITLAB_TOKENS = 'gitlab-token';
|
|
16
|
+
const storedTokens = (auth) => auth[GITLAB_TOKENS];
|
|
17
|
+
const readAuth = (path) => {
|
|
18
|
+
if (!(0, fs_1.existsSync)(path))
|
|
19
|
+
return { auth: {} };
|
|
20
|
+
let parsed;
|
|
21
|
+
try {
|
|
22
|
+
parsed = JSON.parse((0, fs_1.readFileSync)(path, 'utf8'));
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
return { unreadable: `${path} is not valid JSON: ${error instanceof Error ? error.message : String(error)}` };
|
|
26
|
+
}
|
|
27
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
28
|
+
return { unreadable: `${path} does not hold a JSON object.` };
|
|
29
|
+
}
|
|
30
|
+
return { auth: parsed };
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Adds one host's GitLab token to composer's auth.json, keeping every other credential in the file.
|
|
34
|
+
* A file that cannot be parsed is reported rather than replaced, so nothing already in it is lost.
|
|
35
|
+
*/
|
|
36
|
+
const writeGitlabToken = (options) => {
|
|
37
|
+
const { home, host, token } = options;
|
|
38
|
+
const path = (0, exports.composerAuthPath)(home);
|
|
39
|
+
const read = readAuth(path);
|
|
40
|
+
if ('unreadable' in read) {
|
|
41
|
+
return { ok: false, problem: `${read.unreadable}\nFix it or move it aside, so no other credential in it is lost.` };
|
|
42
|
+
}
|
|
43
|
+
const tokens = Object.assign({}, storedTokens(read.auth));
|
|
44
|
+
const replaced = tokens[host] !== undefined && tokens[host] !== token;
|
|
45
|
+
tokens[host] = token;
|
|
46
|
+
(0, fs_1.mkdirSync)(home, { recursive: true });
|
|
47
|
+
(0, fs_1.writeFileSync)(path, `${JSON.stringify(Object.assign(Object.assign({}, read.auth), { [GITLAB_TOKENS]: tokens }), null, 4)}\n`, {
|
|
48
|
+
encoding: 'utf8',
|
|
49
|
+
mode: 0o600,
|
|
50
|
+
});
|
|
51
|
+
// writeFileSync only applies mode when it creates the file, and this one usually already exists.
|
|
52
|
+
(0, fs_1.chmodSync)(path, 0o600);
|
|
53
|
+
return { ok: true, path, replaced };
|
|
54
|
+
};
|
|
55
|
+
exports.writeGitlabToken = writeGitlabToken;
|
|
56
|
+
/** The token composer already holds for one host, or undefined when it holds none. */
|
|
57
|
+
const storedGitlabToken = (options) => {
|
|
58
|
+
var _a;
|
|
59
|
+
const read = readAuth((0, exports.composerAuthPath)(options.home));
|
|
60
|
+
return 'unreadable' in read ? undefined : (_a = storedTokens(read.auth)) === null || _a === void 0 ? void 0 : _a[options.host];
|
|
61
|
+
};
|
|
62
|
+
exports.storedGitlabToken = storedGitlabToken;
|
|
63
|
+
/** The hosts composer already holds a GitLab token for. */
|
|
64
|
+
const gitlabTokenHosts = (home) => {
|
|
65
|
+
var _a;
|
|
66
|
+
const read = readAuth((0, exports.composerAuthPath)(home));
|
|
67
|
+
return 'unreadable' in read ? [] : Object.keys((_a = storedTokens(read.auth)) !== null && _a !== void 0 ? _a : {});
|
|
68
|
+
};
|
|
69
|
+
exports.gitlabTokenHosts = gitlabTokenHosts;
|
|
70
|
+
//# sourceMappingURL=composer-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composer-auth.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/auth/composer-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The git urls a checkout's composer.json pulls packages from. These are the repositories a token is
|
|
3
|
+
* needed for; the API's own repository is not one of them, because the developer already has it.
|
|
4
|
+
*/
|
|
5
|
+
export declare const composerGitRepositories: (repoPath: string) => string[];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.composerGitRepositories = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const urlOf = (entry) => typeof entry === 'object' && entry !== null ? entry['url'] : undefined;
|
|
7
|
+
/**
|
|
8
|
+
* The git urls a checkout's composer.json pulls packages from. These are the repositories a token is
|
|
9
|
+
* needed for; the API's own repository is not one of them, because the developer already has it.
|
|
10
|
+
*/
|
|
11
|
+
const composerGitRepositories = (repoPath) => {
|
|
12
|
+
const path = (0, path_1.join)(repoPath, 'composer.json');
|
|
13
|
+
if (!(0, fs_1.existsSync)(path))
|
|
14
|
+
return [];
|
|
15
|
+
let parsed;
|
|
16
|
+
try {
|
|
17
|
+
parsed = JSON.parse((0, fs_1.readFileSync)(path, 'utf8'));
|
|
18
|
+
}
|
|
19
|
+
catch (_a) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
const declared = typeof parsed === 'object' && parsed !== null ? parsed : {};
|
|
23
|
+
const repositories = declared['repositories'];
|
|
24
|
+
// composer accepts both a list and a name-keyed map here.
|
|
25
|
+
const entries = Array.isArray(repositories)
|
|
26
|
+
? repositories
|
|
27
|
+
: typeof repositories === 'object' && repositories !== null
|
|
28
|
+
? Object.values(repositories)
|
|
29
|
+
: [];
|
|
30
|
+
return entries.map(urlOf).filter((url) => typeof url === 'string');
|
|
31
|
+
};
|
|
32
|
+
exports.composerGitRepositories = composerGitRepositories;
|
|
33
|
+
//# sourceMappingURL=composer-repositories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composer-repositories.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/auth/composer-repositories.ts"],"names":[],"mappings":";;;AAAA,2BAA8C;AAC9C,+BAA4B;AAE5B,MAAM,KAAK,GAAG,CAAC,KAAc,EAAE,EAAE,CAC/B,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAE,KAAiC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAEtG;;;GAGG;AACI,MAAM,uBAAuB,GAAG,CAAC,QAAgB,EAAY,EAAE;IACpE,MAAM,IAAI,GAAG,IAAA,WAAI,EAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IAE7C,IAAI,CAAC,IAAA,eAAU,EAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAEjC,IAAI,MAAe,CAAC;IAEpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,CAAC;IAAC,WAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAE,MAAkC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1G,MAAM,YAAY,GAAG,QAAQ,CAAC,cAAc,CAAC,CAAC;IAC9C,0DAA0D;IAC1D,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC;QACzC,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,KAAK,IAAI;YACzD,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC;YAC7B,CAAC,CAAC,EAAE,CAAC;IAET,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAiB,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC;AACpF,CAAC,CAAC;AAvBW,QAAA,uBAAuB,2BAuBlC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export type TokenCheck = {
|
|
2
|
+
state: 'valid';
|
|
3
|
+
name?: string;
|
|
4
|
+
scopes: string[];
|
|
5
|
+
expiresAt?: string;
|
|
6
|
+
} | {
|
|
7
|
+
state: 'undisclosed';
|
|
8
|
+
} | {
|
|
9
|
+
state: 'unauthorized';
|
|
10
|
+
} | {
|
|
11
|
+
state: 'unreachable';
|
|
12
|
+
reason: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Asks GitLab what the token is. A project or group access token answers 403 here, and so does a
|
|
16
|
+
* token without an api scope, so only 401 proves the token itself is wrong.
|
|
17
|
+
*/
|
|
18
|
+
export declare const describeGitlabToken: (options: {
|
|
19
|
+
host: string;
|
|
20
|
+
token: string;
|
|
21
|
+
}) => Promise<TokenCheck>;
|
|
22
|
+
export type CloneCheck = {
|
|
23
|
+
state: 'clonable';
|
|
24
|
+
} | {
|
|
25
|
+
state: 'forbidden';
|
|
26
|
+
} | {
|
|
27
|
+
state: 'unauthorized';
|
|
28
|
+
} | {
|
|
29
|
+
state: 'missing';
|
|
30
|
+
} | {
|
|
31
|
+
state: 'unreachable';
|
|
32
|
+
reason: string;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Asks the host for a repository's refs with the token as a basic credential. This is the first
|
|
36
|
+
* request `git clone` over https makes, so it proves the token can fetch code and needs no api scope,
|
|
37
|
+
* which a project access token does not have.
|
|
38
|
+
*/
|
|
39
|
+
export declare const checkGitCloneAccess: (options: {
|
|
40
|
+
host: string;
|
|
41
|
+
projectPath: string;
|
|
42
|
+
token: string;
|
|
43
|
+
}) => Promise<CloneCheck>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkGitCloneAccess = exports.describeGitlabToken = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const TIMEOUT_MS = 10000;
|
|
6
|
+
const request = (options) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
7
|
+
const { url, headers } = options;
|
|
8
|
+
try {
|
|
9
|
+
const response = yield fetch(url, { headers, signal: AbortSignal.timeout(TIMEOUT_MS) });
|
|
10
|
+
return { response };
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
return { reason: error instanceof Error ? error.message : String(error) };
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* Asks GitLab what the token is. A project or group access token answers 403 here, and so does a
|
|
18
|
+
* token without an api scope, so only 401 proves the token itself is wrong.
|
|
19
|
+
*/
|
|
20
|
+
const describeGitlabToken = (options) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
21
|
+
const { host, token } = options;
|
|
22
|
+
const result = yield request({
|
|
23
|
+
url: `https://${host}/api/v4/personal_access_tokens/self`,
|
|
24
|
+
headers: { 'PRIVATE-TOKEN': token },
|
|
25
|
+
});
|
|
26
|
+
if ('reason' in result)
|
|
27
|
+
return { state: 'unreachable', reason: result.reason };
|
|
28
|
+
if (result.response.status === 401)
|
|
29
|
+
return { state: 'unauthorized' };
|
|
30
|
+
if (result.response.status === 403)
|
|
31
|
+
return { state: 'undisclosed' };
|
|
32
|
+
if (!result.response.ok) {
|
|
33
|
+
return { state: 'unreachable', reason: `${host} answered ${result.response.status} for the token itself.` };
|
|
34
|
+
}
|
|
35
|
+
const body = yield result.response.json().catch(() => undefined);
|
|
36
|
+
const record = typeof body === 'object' && body !== null ? body : {};
|
|
37
|
+
return {
|
|
38
|
+
state: 'valid',
|
|
39
|
+
name: typeof record['name'] === 'string' ? record['name'] : undefined,
|
|
40
|
+
scopes: Array.isArray(record['scopes']) ? record['scopes'].map(String) : [],
|
|
41
|
+
expiresAt: typeof record['expires_at'] === 'string' ? record['expires_at'] : undefined,
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
exports.describeGitlabToken = describeGitlabToken;
|
|
45
|
+
/**
|
|
46
|
+
* Asks the host for a repository's refs with the token as a basic credential. This is the first
|
|
47
|
+
* request `git clone` over https makes, so it proves the token can fetch code and needs no api scope,
|
|
48
|
+
* which a project access token does not have.
|
|
49
|
+
*/
|
|
50
|
+
const checkGitCloneAccess = (options) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
51
|
+
var _a;
|
|
52
|
+
const { host, projectPath, token } = options;
|
|
53
|
+
const result = yield request({
|
|
54
|
+
url: `https://${host}/${projectPath}.git/info/refs?service=git-upload-pack`,
|
|
55
|
+
headers: { Authorization: `Basic ${Buffer.from(`oauth2:${token}`).toString('base64')}` },
|
|
56
|
+
});
|
|
57
|
+
if ('reason' in result)
|
|
58
|
+
return { state: 'unreachable', reason: result.reason };
|
|
59
|
+
const { status } = result.response;
|
|
60
|
+
yield ((_a = result.response.body) === null || _a === void 0 ? void 0 : _a.cancel());
|
|
61
|
+
if (status === 200)
|
|
62
|
+
return { state: 'clonable' };
|
|
63
|
+
if (status === 401)
|
|
64
|
+
return { state: 'unauthorized' };
|
|
65
|
+
if (status === 403)
|
|
66
|
+
return { state: 'forbidden' };
|
|
67
|
+
if (status === 404)
|
|
68
|
+
return { state: 'missing' };
|
|
69
|
+
return { state: 'unreachable', reason: `${host} answered ${status} for ${projectPath}.` };
|
|
70
|
+
});
|
|
71
|
+
exports.checkGitCloneAccess = checkGitCloneAccess;
|
|
72
|
+
//# sourceMappingURL=gitlab-token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitlab-token.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/auth/gitlab-token.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./auth-command"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./composer-auth"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./composer-repositories"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./gitlab-token"), exports);
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/auth/index.ts"],"names":[],"mappings":";;;AAAA,yDAA+B;AAC/B,0DAAgC;AAChC,kEAAwC;AACxC,yDAA+B"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/** Reports every problem with this machine's setup, so `et api` does not have to find them one at a time. */
|
|
2
|
-
export declare const doctorCommand: ({ root }: {
|
|
2
|
+
export declare const doctorCommand: ({ root, apiInvocation }: {
|
|
3
3
|
root: string;
|
|
4
|
+
apiInvocation?: string;
|
|
4
5
|
}) => 0 | 1;
|
|
@@ -14,7 +14,7 @@ const describeComposeTool = () => {
|
|
|
14
14
|
? { line: `container engine: ${(0, compose_1.composeBinary)(tool.compose).join(' ')}`, problems: [] }
|
|
15
15
|
: { line: undefined, problems: [`No compose tool found. Tried: ${(0, compose_1.composeToolNames)().join(', ')}.`] };
|
|
16
16
|
};
|
|
17
|
-
const describeApis = (root) => {
|
|
17
|
+
const describeApis = (root, apiInvocation) => {
|
|
18
18
|
const { found, apis, fileName } = (0, load_definitions_1.loadApiDefinitions)(root);
|
|
19
19
|
if (!found)
|
|
20
20
|
return { lines: [], problems: [] };
|
|
@@ -25,17 +25,14 @@ const describeApis = (root) => {
|
|
|
25
25
|
if (checkout.ok) {
|
|
26
26
|
lines.push(`${fileName}: ${name} → ${checkout.checkout.composePath}`);
|
|
27
27
|
}
|
|
28
|
-
else if (checkout.clonable) {
|
|
29
|
-
problems.push(`${checkout.problem} Run "et api clone ${name}".`);
|
|
30
|
-
}
|
|
31
28
|
else {
|
|
32
|
-
problems.push(
|
|
29
|
+
problems.push((0, resolve_checkout_1.checkoutProblem)({ failure: checkout, name, invocation: apiInvocation }));
|
|
33
30
|
}
|
|
34
31
|
}
|
|
35
32
|
return { lines, problems };
|
|
36
33
|
};
|
|
37
34
|
/** Reports every problem with this machine's setup, so `et api` does not have to find them one at a time. */
|
|
38
|
-
const doctorCommand = ({ root }) => {
|
|
35
|
+
const doctorCommand = ({ root, apiInvocation = 'et api' }) => {
|
|
39
36
|
// A file that exists but cannot be parsed still has to be reported, so this asks whether the file
|
|
40
37
|
// is there rather than whether it could be read.
|
|
41
38
|
const hasConfig = [local_config_1.LOCAL_CONFIG_FILE_NAME, local_config_1.LEGACY_LOCAL_CONFIG_FILE_NAME].some((fileName) => (0, local_config_1.readLocalConfigFile)((0, path_1.join)(root, fileName)).status !== 'absent');
|
|
@@ -46,7 +43,7 @@ const doctorCommand = ({ root }) => {
|
|
|
46
43
|
}
|
|
47
44
|
const configProblems = (0, diagnose_1.diagnoseLocalConfig)({ root });
|
|
48
45
|
const compose = describeComposeTool();
|
|
49
|
-
const apis = describeApis(root);
|
|
46
|
+
const apis = describeApis(root, apiInvocation);
|
|
50
47
|
const problems = [...configProblems, ...compose.problems, ...apis.problems];
|
|
51
48
|
for (const line of [compose.line, ...apis.lines].filter(Boolean)) {
|
|
52
49
|
console.log(` ${line}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-command.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/doctor/doctor-command.ts"],"names":[],"mappings":";;;AAAA,4CAAqF;AACrF,+BAA4B;AAC5B,8DAAyF;AACzF,
|
|
1
|
+
{"version":3,"file":"doctor-command.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/doctor/doctor-command.ts"],"names":[],"mappings":"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"}
|
package/src/lib/index.d.ts
CHANGED
package/src/lib/index.js
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
tslib_1.__exportStar(require("./api"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./auth"), exports);
|
|
5
6
|
tslib_1.__exportStar(require("./config"), exports);
|
|
6
7
|
tslib_1.__exportStar(require("./doctor"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./invocation"), exports);
|
|
7
9
|
tslib_1.__exportStar(require("./release"), exports);
|
|
8
10
|
//# sourceMappingURL=index.js.map
|
package/src/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/cli/src/lib/index.ts"],"names":[],"mappings":";;;AAAA,gDAAsB;AACtB,mDAAyB;AACzB,mDAAyB;AACzB,oDAA0B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/cli/src/lib/index.ts"],"names":[],"mappings":";;;AAAA,gDAAsB;AACtB,iDAAuB;AACvB,mDAAyB;AACzB,mDAAyB;AACzB,uDAA6B;AAC7B,oDAA0B"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the reader of a message can type to reach `et <subcommand>` in this repo, because `et` itself
|
|
3
|
+
* is rarely on the PATH: the package script that wraps it, or the package manager's own way to run
|
|
4
|
+
* the binary, for example `npx et api`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const repoInvocation: (options: {
|
|
7
|
+
root: string;
|
|
8
|
+
subcommand: string;
|
|
9
|
+
}) => string;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.repoInvocation = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
/**
|
|
7
|
+
* How each package manager runs a script, and how it runs a binary from `node_modules` when no
|
|
8
|
+
* script wraps it.
|
|
9
|
+
*/
|
|
10
|
+
const RUNNERS = [
|
|
11
|
+
{ name: 'yarn', script: 'yarn', binary: 'yarn et' },
|
|
12
|
+
{ name: 'pnpm', script: 'pnpm', binary: 'pnpm exec et' },
|
|
13
|
+
{ name: 'bun', script: 'bun run', binary: 'bunx et' },
|
|
14
|
+
{ name: 'npm', script: 'npm run', binary: 'npx et' },
|
|
15
|
+
];
|
|
16
|
+
const readManifest = (root) => {
|
|
17
|
+
let parsed;
|
|
18
|
+
try {
|
|
19
|
+
parsed = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(root, 'package.json'), 'utf8'));
|
|
20
|
+
}
|
|
21
|
+
catch (_a) {
|
|
22
|
+
return {};
|
|
23
|
+
}
|
|
24
|
+
return typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed) ? parsed : {};
|
|
25
|
+
};
|
|
26
|
+
const runnerFor = (manifest) => {
|
|
27
|
+
var _a;
|
|
28
|
+
const declared = (_a = manifest.packageManager) !== null && _a !== void 0 ? _a : process.env['npm_config_user_agent'];
|
|
29
|
+
return declared ? RUNNERS.find((runner) => declared.startsWith(runner.name)) : undefined;
|
|
30
|
+
};
|
|
31
|
+
const scriptFor = (manifest, command) => { var _a, _b; return (_b = Object.entries((_a = manifest.scripts) !== null && _a !== void 0 ? _a : {}).find(([, value]) => value.trim() === command)) === null || _b === void 0 ? void 0 : _b[0]; };
|
|
32
|
+
/**
|
|
33
|
+
* What the reader of a message can type to reach `et <subcommand>` in this repo, because `et` itself
|
|
34
|
+
* is rarely on the PATH: the package script that wraps it, or the package manager's own way to run
|
|
35
|
+
* the binary, for example `npx et api`.
|
|
36
|
+
*/
|
|
37
|
+
const repoInvocation = (options) => {
|
|
38
|
+
const { root, subcommand } = options;
|
|
39
|
+
const manifest = readManifest(root);
|
|
40
|
+
const runner = runnerFor(manifest);
|
|
41
|
+
if (!runner)
|
|
42
|
+
return `et ${subcommand}`;
|
|
43
|
+
const script = scriptFor(manifest, `et ${subcommand}`);
|
|
44
|
+
return script ? `${runner.script} ${script}` : `${runner.binary} ${subcommand}`;
|
|
45
|
+
};
|
|
46
|
+
exports.repoInvocation = repoInvocation;
|
|
47
|
+
//# sourceMappingURL=invocation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invocation.js","sourceRoot":"","sources":["../../../../../libs/cli/src/lib/invocation.ts"],"names":[],"mappings":";;;AAAA,2BAAkC;AAClC,+BAA4B;AAI5B;;;GAGG;AACH,MAAM,OAAO,GAAG;IACd,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE;IACnD,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE;IACxD,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;IACrD,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE;CACrD,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,IAAY,EAAY,EAAE;IAC9C,IAAI,MAAe,CAAC;IAEpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,IAAA,WAAI,EAAC,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACxE,CAAC;IAAC,WAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,MAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7G,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,QAAkB,EAAE,EAAE;;IACvC,MAAM,QAAQ,GAAG,MAAA,QAAQ,CAAC,cAAc,mCAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IAEjF,OAAO,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3F,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,QAAkB,EAAE,OAAe,EAAE,EAAE,eACxD,OAAA,MAAA,MAAM,CAAC,OAAO,CAAC,MAAA,QAAQ,CAAC,OAAO,mCAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,0CAAG,CAAC,CAAC,CAAA,EAAA,CAAC;AAE5F;;;;GAIG;AACI,MAAM,cAAc,GAAG,CAAC,OAA6C,EAAE,EAAE;IAC9E,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IACrC,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAEnC,IAAI,CAAC,MAAM;QAAE,OAAO,MAAM,UAAU,EAAE,CAAC;IAEvC,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,MAAM,UAAU,EAAE,CAAC,CAAC;IAEvD,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC;AAClF,CAAC,CAAC;AAVW,QAAA,cAAc,kBAUzB"}
|