@minnovate/shadow-publisher 0.18.2 → 0.18.3
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.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "git-publisher",
|
|
3
3
|
"displayName": "Git Publisher",
|
|
4
|
-
"version": "0.18.
|
|
4
|
+
"version": "0.18.3",
|
|
5
5
|
"description": "Publish an app folder's Git history to the serverless Git publishing backend and keep it updated (\"publish my app\", \"update my app\", \"fetch the engineered version\").",
|
|
6
6
|
"author": { "name": "git-publisher project" },
|
|
7
7
|
"keywords": ["git", "publish", "deploy", "serverless"]
|
package/dist/publisher.cjs
CHANGED
|
@@ -21651,8 +21651,107 @@ async function updateEntry(url2, change) {
|
|
|
21651
21651
|
await writeCredentials(file2);
|
|
21652
21652
|
}
|
|
21653
21653
|
|
|
21654
|
-
// ../client/src/clients/
|
|
21655
|
-
var
|
|
21654
|
+
// ../client/src/clients/applications/api.generated.ts
|
|
21655
|
+
var getApiTerminalRepositoriesRuns = {
|
|
21656
|
+
path: (params) => `/api/v1/terminal/repositories/${encodeURIComponent(params.repoId)}/runs`,
|
|
21657
|
+
query: external_exports.object({
|
|
21658
|
+
publication: external_exports.string().optional(),
|
|
21659
|
+
ref: external_exports.string().optional(),
|
|
21660
|
+
commit: external_exports.string().optional()
|
|
21661
|
+
}),
|
|
21662
|
+
answers: {
|
|
21663
|
+
200: external_exports.record(external_exports.string(), external_exports.unknown())
|
|
21664
|
+
}
|
|
21665
|
+
};
|
|
21666
|
+
var getApiTerminalRepositoriesPreparation = {
|
|
21667
|
+
path: (params) => `/api/v1/terminal/repositories/${encodeURIComponent(params.repoId)}/preparation`,
|
|
21668
|
+
answers: {
|
|
21669
|
+
200: external_exports.object({
|
|
21670
|
+
id: external_exports.string(),
|
|
21671
|
+
revision: external_exports.int(),
|
|
21672
|
+
status: external_exports.enum(["queued", "running", "needs-choice", "ready", "blocked", "canceled"]),
|
|
21673
|
+
message: external_exports.string(),
|
|
21674
|
+
questions: external_exports.array(external_exports.object({
|
|
21675
|
+
id: external_exports.string(),
|
|
21676
|
+
text: external_exports.string(),
|
|
21677
|
+
options: external_exports.array(external_exports.object({
|
|
21678
|
+
value: external_exports.string(),
|
|
21679
|
+
label: external_exports.string()
|
|
21680
|
+
}))
|
|
21681
|
+
})),
|
|
21682
|
+
publication: external_exports.object({
|
|
21683
|
+
status: external_exports.string(),
|
|
21684
|
+
message: external_exports.string(),
|
|
21685
|
+
url: external_exports.string().optional()
|
|
21686
|
+
}).nullable().optional(),
|
|
21687
|
+
canRetry: external_exports.boolean().optional(),
|
|
21688
|
+
answerable: external_exports.boolean().optional()
|
|
21689
|
+
})
|
|
21690
|
+
}
|
|
21691
|
+
};
|
|
21692
|
+
var postApiTerminalRepositoriesPreparation = {
|
|
21693
|
+
path: (params) => `/api/v1/terminal/repositories/${encodeURIComponent(params.repoId)}/preparation`,
|
|
21694
|
+
body: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
21695
|
+
answers: {
|
|
21696
|
+
200: external_exports.object({
|
|
21697
|
+
id: external_exports.string(),
|
|
21698
|
+
revision: external_exports.int(),
|
|
21699
|
+
status: external_exports.enum(["queued", "running", "needs-choice", "ready", "blocked", "canceled"]),
|
|
21700
|
+
message: external_exports.string(),
|
|
21701
|
+
questions: external_exports.array(external_exports.object({
|
|
21702
|
+
id: external_exports.string(),
|
|
21703
|
+
text: external_exports.string(),
|
|
21704
|
+
options: external_exports.array(external_exports.object({
|
|
21705
|
+
value: external_exports.string(),
|
|
21706
|
+
label: external_exports.string()
|
|
21707
|
+
}))
|
|
21708
|
+
})),
|
|
21709
|
+
publication: external_exports.object({
|
|
21710
|
+
status: external_exports.string(),
|
|
21711
|
+
message: external_exports.string(),
|
|
21712
|
+
url: external_exports.string().optional()
|
|
21713
|
+
}).nullable().optional(),
|
|
21714
|
+
canRetry: external_exports.boolean().optional(),
|
|
21715
|
+
answerable: external_exports.boolean().optional()
|
|
21716
|
+
})
|
|
21717
|
+
}
|
|
21718
|
+
};
|
|
21719
|
+
var postApiTerminalApplications = {
|
|
21720
|
+
path: () => "/api/v1/terminal/applications",
|
|
21721
|
+
body: external_exports.object({
|
|
21722
|
+
name: external_exports.string().min(1).max(80),
|
|
21723
|
+
creationId: external_exports.string().regex(new RegExp("^[0-9a-hjkmnp-tv-z]{26}$")),
|
|
21724
|
+
defaultBranch: external_exports.string().regex(new RegExp("^(?!.*\\.\\.)(?!\\/)(?!.*\\/$)[A-Za-z0-9._/-]{1,200}$")).nullable().optional()
|
|
21725
|
+
}),
|
|
21726
|
+
answers: {
|
|
21727
|
+
200: external_exports.object({
|
|
21728
|
+
application: external_exports.object({
|
|
21729
|
+
appId: external_exports.string(),
|
|
21730
|
+
name: external_exports.string()
|
|
21731
|
+
}),
|
|
21732
|
+
repository: external_exports.record(external_exports.string(), external_exports.unknown())
|
|
21733
|
+
}),
|
|
21734
|
+
201: external_exports.object({
|
|
21735
|
+
application: external_exports.object({
|
|
21736
|
+
appId: external_exports.string(),
|
|
21737
|
+
name: external_exports.string()
|
|
21738
|
+
}),
|
|
21739
|
+
repository: external_exports.record(external_exports.string(), external_exports.unknown())
|
|
21740
|
+
})
|
|
21741
|
+
}
|
|
21742
|
+
};
|
|
21743
|
+
var postApiTerminalTools = {
|
|
21744
|
+
path: (params) => `/api/v1/terminal/tools/${encodeURIComponent(params.tool)}`,
|
|
21745
|
+
body: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
21746
|
+
answers: {
|
|
21747
|
+
200: external_exports.object({
|
|
21748
|
+
isError: external_exports.boolean()
|
|
21749
|
+
}).catchall(external_exports.unknown())
|
|
21750
|
+
}
|
|
21751
|
+
};
|
|
21752
|
+
|
|
21753
|
+
// ../client/src/clients/applications/request.ts
|
|
21754
|
+
var TerminalSession = class {
|
|
21656
21755
|
constructor(credential) {
|
|
21657
21756
|
this.credential = credential;
|
|
21658
21757
|
}
|
|
@@ -21661,7 +21760,7 @@ var PortalSession = class {
|
|
|
21661
21760
|
async ask(url2, body) {
|
|
21662
21761
|
const { token, refresh } = this.credential;
|
|
21663
21762
|
for (; ; ) {
|
|
21664
|
-
const answer2 = await
|
|
21763
|
+
const answer2 = await askOnce(this.credential.fetch ?? fetch, url2, await token(), body);
|
|
21665
21764
|
if (answer2.status === 401 && !this.#refreshed && refresh !== void 0) {
|
|
21666
21765
|
this.#refreshed = true;
|
|
21667
21766
|
if (await refresh()) {
|
|
@@ -21672,7 +21771,7 @@ var PortalSession = class {
|
|
|
21672
21771
|
}
|
|
21673
21772
|
}
|
|
21674
21773
|
};
|
|
21675
|
-
async function
|
|
21774
|
+
async function askOnce(fetchImpl, url2, token, body) {
|
|
21676
21775
|
try {
|
|
21677
21776
|
const res = await fetchImpl(url2, {
|
|
21678
21777
|
method: body === void 0 ? "GET" : "POST",
|
|
@@ -21690,6 +21789,9 @@ async function askPortal(fetchImpl, url2, token, body) {
|
|
|
21690
21789
|
return { status: 0, body: null };
|
|
21691
21790
|
}
|
|
21692
21791
|
}
|
|
21792
|
+
function terminalUrl(portal, path) {
|
|
21793
|
+
return `${portal.replace(/\/+$/, "")}${path}`;
|
|
21794
|
+
}
|
|
21693
21795
|
function isRecord(value) {
|
|
21694
21796
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21695
21797
|
}
|
|
@@ -21718,8 +21820,8 @@ function featureOffWords(feature) {
|
|
|
21718
21820
|
return `This is not available for this organization${named}, and nobody in it can turn it on.`;
|
|
21719
21821
|
}
|
|
21720
21822
|
|
|
21721
|
-
// ../client/src/clients/
|
|
21722
|
-
function
|
|
21823
|
+
// ../client/src/clients/applications/refusal.ts
|
|
21824
|
+
function refusalCode(body) {
|
|
21723
21825
|
if (!isRecord(body)) {
|
|
21724
21826
|
return null;
|
|
21725
21827
|
}
|
|
@@ -21733,7 +21835,7 @@ function portalRefusalCode(body) {
|
|
|
21733
21835
|
const { code, message } = error62;
|
|
21734
21836
|
return typeof code === "string" && code !== "" && typeof message === "string" ? code : null;
|
|
21735
21837
|
}
|
|
21736
|
-
function
|
|
21838
|
+
function refusalLimit(body) {
|
|
21737
21839
|
const error62 = isRecord(body) ? body["error"] : null;
|
|
21738
21840
|
const details = isRecord(error62) ? error62["details"] : null;
|
|
21739
21841
|
if (!isRecord(details)) {
|
|
@@ -21744,7 +21846,7 @@ function portalRefusalLimit(body) {
|
|
|
21744
21846
|
return limit.permission === null && limit.reason === null && limit.contact === null ? null : limit;
|
|
21745
21847
|
}
|
|
21746
21848
|
|
|
21747
|
-
// ../client/src/clients/
|
|
21849
|
+
// ../client/src/clients/applications/application.ts
|
|
21748
21850
|
var APPLICATION_CREATION = "application-creation";
|
|
21749
21851
|
var ATTEMPTS = 3;
|
|
21750
21852
|
var REFUSALS = {
|
|
@@ -21752,21 +21854,21 @@ var REFUSALS = {
|
|
|
21752
21854
|
"repository-conflict": "REPOSITORY_CONFLICT"
|
|
21753
21855
|
};
|
|
21754
21856
|
async function createApplication(input2, opts) {
|
|
21755
|
-
const url2 =
|
|
21857
|
+
const url2 = terminalUrl(input2.portal, postApiTerminalApplications.path());
|
|
21756
21858
|
const body = { creationId: input2.creationId ?? newCreationId(), name: input2.name, defaultBranch: input2.defaultBranch ?? "main" };
|
|
21757
|
-
const
|
|
21859
|
+
const session = new TerminalSession(opts);
|
|
21758
21860
|
let lastOutage = "";
|
|
21759
21861
|
for (let attempt = 0; attempt < ATTEMPTS; ) {
|
|
21760
|
-
const answer2 = await
|
|
21862
|
+
const answer2 = await session.ask(url2, body);
|
|
21761
21863
|
if (answer2.status === 200 || answer2.status === 201) {
|
|
21762
21864
|
return read(answer2.body, answer2.status === 201);
|
|
21763
21865
|
}
|
|
21764
|
-
const code =
|
|
21866
|
+
const code = refusalCode(answer2.body) ?? "";
|
|
21765
21867
|
if (answer2.status === 401) {
|
|
21766
21868
|
throw new PublisherError("UNAUTHORIZED", 'the portal did not accept this credential; run "publisher login" again');
|
|
21767
21869
|
}
|
|
21768
21870
|
if (answer2.status === 403) {
|
|
21769
|
-
const limit =
|
|
21871
|
+
const limit = refusalLimit(answer2.body);
|
|
21770
21872
|
throw new PublisherError(
|
|
21771
21873
|
"FORBIDDEN",
|
|
21772
21874
|
answer2.say ?? `the portal refused to make an application here (${limit?.permission ?? (code || "forbidden")})`,
|
|
@@ -21788,12 +21890,12 @@ async function createApplication(input2, opts) {
|
|
|
21788
21890
|
throw new PublisherError("UNAVAILABLE", `could not make the application: ${lastOutage}; run init again`, { retryable: true });
|
|
21789
21891
|
}
|
|
21790
21892
|
function read(body, created) {
|
|
21791
|
-
const
|
|
21792
|
-
const repository = RepositoryInfo.safeParse(
|
|
21793
|
-
if (!
|
|
21893
|
+
const answer2 = postApiTerminalApplications.answers[created ? 201 : 200].safeParse(body);
|
|
21894
|
+
const repository = RepositoryInfo.safeParse(answer2.data?.repository);
|
|
21895
|
+
if (!answer2.success || !repository.success) {
|
|
21794
21896
|
throw new PublisherError("UNAVAILABLE", "the portal answered with an application this version cannot read");
|
|
21795
21897
|
}
|
|
21796
|
-
return { appId: application
|
|
21898
|
+
return { appId: answer2.data.application.appId, created, repository: repository.data };
|
|
21797
21899
|
}
|
|
21798
21900
|
|
|
21799
21901
|
// ../client/src/clients/git-publisher/errors.ts
|
|
@@ -21995,7 +22097,7 @@ function sleep(ms, signal) {
|
|
|
21995
22097
|
});
|
|
21996
22098
|
}
|
|
21997
22099
|
|
|
21998
|
-
// ../client/src/clients/
|
|
22100
|
+
// ../client/src/clients/applications/run-progress.ts
|
|
21999
22101
|
var RUN_STAGES = ["received", "running", "deploying", "live"];
|
|
22000
22102
|
var STAGE_WORDS = { received: "received", running: "checked", deploying: "going live", live: "live" };
|
|
22001
22103
|
var STATES = ["pending", "in-progress", "done", "failed", "skipped"];
|
|
@@ -22056,19 +22158,19 @@ function reasonOf(run2, end) {
|
|
|
22056
22158
|
}
|
|
22057
22159
|
var FOLLOW_TIMEOUT_MS = 15 * 6e4;
|
|
22058
22160
|
async function followRun(input2, opts) {
|
|
22059
|
-
const
|
|
22161
|
+
const session = new TerminalSession(opts);
|
|
22060
22162
|
const sleep2 = opts.sleep ?? sleep;
|
|
22061
22163
|
const now = opts.now ?? Date.now;
|
|
22062
22164
|
const interval2 = opts.intervalMs ?? POLL_INTERVAL_MS;
|
|
22063
22165
|
const deadline = now() + (opts.timeoutMs ?? FOLLOW_TIMEOUT_MS);
|
|
22064
22166
|
const query = new URLSearchParams({ publication: input2.publicationId, ref: input2.ref, commit: input2.commit });
|
|
22065
|
-
const url2 =
|
|
22167
|
+
const url2 = terminalUrl(input2.portal, `${getApiTerminalRepositoriesRuns.path({ repoId: input2.repoId })}?${query}`);
|
|
22066
22168
|
const seen = /* @__PURE__ */ new Map();
|
|
22067
22169
|
let last = null;
|
|
22068
22170
|
let lastError = null;
|
|
22069
22171
|
let answered2 = false;
|
|
22070
22172
|
for (; ; ) {
|
|
22071
|
-
const answer2 = await
|
|
22173
|
+
const answer2 = await session.ask(url2, void 0);
|
|
22072
22174
|
if (answer2.status === 401) {
|
|
22073
22175
|
return { kind: "unauthorized" };
|
|
22074
22176
|
}
|
|
@@ -22076,7 +22178,7 @@ async function followRun(input2, opts) {
|
|
|
22076
22178
|
return { kind: "unavailable", reason: "no-route" };
|
|
22077
22179
|
}
|
|
22078
22180
|
if (answer2.status === 403) {
|
|
22079
|
-
return { kind: "forbidden", say: answer2.say, limit:
|
|
22181
|
+
return { kind: "forbidden", say: answer2.say, limit: refusalLimit(answer2.body) };
|
|
22080
22182
|
}
|
|
22081
22183
|
if (answer2.status === 200) {
|
|
22082
22184
|
const run2 = soleRun(answer2.body);
|
|
@@ -22133,41 +22235,11 @@ function soleRun(body) {
|
|
|
22133
22235
|
}
|
|
22134
22236
|
return { run: runs[0] ?? null };
|
|
22135
22237
|
}
|
|
22136
|
-
function portalForEndpoint(endpoint) {
|
|
22137
|
-
let url2;
|
|
22138
|
-
try {
|
|
22139
|
-
url2 = new URL(endpoint);
|
|
22140
|
-
} catch {
|
|
22141
|
-
return null;
|
|
22142
|
-
}
|
|
22143
|
-
if (url2.protocol !== "https:" || url2.pathname.replace(/\/+$/, "") !== "/publish") {
|
|
22144
|
-
return null;
|
|
22145
|
-
}
|
|
22146
|
-
return url2.origin;
|
|
22147
|
-
}
|
|
22148
22238
|
var RUN_PROGRESS = "run-progress";
|
|
22149
|
-
async function confirmPortal(portal, endpoint, fetchImpl = fetch) {
|
|
22150
|
-
try {
|
|
22151
|
-
const res = await fetchImpl(`${portal}/api/v1/config`, { signal: AbortSignal.timeout(1e4) });
|
|
22152
|
-
if (!res.ok) {
|
|
22153
|
-
return null;
|
|
22154
|
-
}
|
|
22155
|
-
const body = await res.json();
|
|
22156
|
-
const named = body?.publishingEndpoint;
|
|
22157
|
-
const bare = (u) => u.replace(/\/+$/, "");
|
|
22158
|
-
if (typeof named !== "string" || bare(named) !== bare(endpoint)) {
|
|
22159
|
-
return null;
|
|
22160
|
-
}
|
|
22161
|
-
const terminal = body?.terminal;
|
|
22162
|
-
return { terminal: Array.isArray(terminal) && terminal.every((name) => typeof name === "string") ? terminal : [] };
|
|
22163
|
-
} catch {
|
|
22164
|
-
return null;
|
|
22165
|
-
}
|
|
22166
|
-
}
|
|
22167
22239
|
|
|
22168
|
-
// ../client/src/clients/
|
|
22240
|
+
// ../client/src/clients/applications/preparation.ts
|
|
22169
22241
|
var PREPARATION = "preparation";
|
|
22170
|
-
var
|
|
22242
|
+
var View = getApiTerminalRepositoriesPreparation.answers[200];
|
|
22171
22243
|
var MAX_FINDINGS = 10;
|
|
22172
22244
|
var MAX_TEXT = 500;
|
|
22173
22245
|
function readPreparation(input2, opts) {
|
|
@@ -22180,19 +22252,19 @@ function retryPreparation(input2, opts) {
|
|
|
22180
22252
|
return call(input2, opts, { id: input2.id, revision: input2.revision, action: "retry" });
|
|
22181
22253
|
}
|
|
22182
22254
|
async function call(input2, opts, body) {
|
|
22183
|
-
const url2 =
|
|
22184
|
-
const answer2 = await new
|
|
22255
|
+
const url2 = terminalUrl(input2.portal, getApiTerminalRepositoriesPreparation.path({ repoId: input2.repoId }));
|
|
22256
|
+
const answer2 = await new TerminalSession(opts).ask(url2, body);
|
|
22185
22257
|
if (answer2.status === 401) {
|
|
22186
22258
|
return { kind: "unauthorized" };
|
|
22187
22259
|
}
|
|
22188
22260
|
if (answer2.status === 403) {
|
|
22189
|
-
return { kind: "forbidden", say: answer2.say, limit:
|
|
22261
|
+
return { kind: "forbidden", say: answer2.say, limit: refusalLimit(answer2.body) };
|
|
22190
22262
|
}
|
|
22191
22263
|
if (answer2.status === 409) {
|
|
22192
22264
|
return { kind: "moved-on" };
|
|
22193
22265
|
}
|
|
22194
22266
|
if (answer2.status === 404) {
|
|
22195
|
-
return
|
|
22267
|
+
return refusalCode(answer2.body) === "no-such-application" ? { kind: "no-application" } : { kind: "unavailable", detail: "the portal does not serve this address" };
|
|
22196
22268
|
}
|
|
22197
22269
|
if (answer2.status === 200) {
|
|
22198
22270
|
const view = readView(answer2.body);
|
|
@@ -22201,52 +22273,26 @@ async function call(input2, opts, body) {
|
|
|
22201
22273
|
return { kind: "unavailable", detail: answer2.status === 0 ? "the portal could not be reached" : `the portal answered ${answer2.status}` };
|
|
22202
22274
|
}
|
|
22203
22275
|
function readView(body) {
|
|
22204
|
-
|
|
22276
|
+
const read2 = View.safeParse(body);
|
|
22277
|
+
if (!read2.success) {
|
|
22205
22278
|
return { detail: "an answer that is not a preparation" };
|
|
22206
22279
|
}
|
|
22207
|
-
const { id, revision, status: status2, message, questions, publication } =
|
|
22208
|
-
if (
|
|
22209
|
-
return { detail: "a preparation with no id" };
|
|
22210
|
-
}
|
|
22211
|
-
if (typeof revision !== "number" || !Number.isSafeInteger(revision) || revision < 1) {
|
|
22212
|
-
return { detail: "a preparation with no revision" };
|
|
22213
|
-
}
|
|
22214
|
-
if (!STATUSES.includes(status2)) {
|
|
22215
|
-
return { detail: "a preparation with an unknown status" };
|
|
22216
|
-
}
|
|
22217
|
-
if (typeof message !== "string") {
|
|
22218
|
-
return { detail: "a preparation with no message" };
|
|
22280
|
+
const { id, revision, status: status2, message, questions, publication, canRetry } = read2.data;
|
|
22281
|
+
if (id === "" || revision < 1) {
|
|
22282
|
+
return { detail: "a preparation with no id or revision" };
|
|
22219
22283
|
}
|
|
22220
|
-
if (
|
|
22221
|
-
return { detail: "a
|
|
22222
|
-
}
|
|
22223
|
-
const read2 = [];
|
|
22224
|
-
for (const q of questions) {
|
|
22225
|
-
if (!isRecord(q) || typeof q["id"] !== "string" || typeof q["text"] !== "string" || !Array.isArray(q["options"]) || q["options"].length === 0) {
|
|
22226
|
-
return { detail: "a question that cannot be answered" };
|
|
22227
|
-
}
|
|
22228
|
-
const options = [];
|
|
22229
|
-
for (const o of q["options"]) {
|
|
22230
|
-
if (!isRecord(o) || typeof o["value"] !== "string" || typeof o["label"] !== "string") {
|
|
22231
|
-
return { detail: "a question with an unreadable option" };
|
|
22232
|
-
}
|
|
22233
|
-
options.push({ value: o["value"], label: o["label"] });
|
|
22234
|
-
}
|
|
22235
|
-
read2.push({ id: q["id"], text: q["text"], options });
|
|
22236
|
-
}
|
|
22237
|
-
let pub = null;
|
|
22238
|
-
if (isRecord(publication) && typeof publication["status"] === "string" && typeof publication["message"] === "string") {
|
|
22239
|
-
pub = { status: publication["status"], message: publication["message"], ...typeof publication["url"] === "string" ? { url: publication["url"] } : {} };
|
|
22284
|
+
if (questions.some((question2) => question2.options.length === 0)) {
|
|
22285
|
+
return { detail: "a question that cannot be answered" };
|
|
22240
22286
|
}
|
|
22241
22287
|
return {
|
|
22242
22288
|
id,
|
|
22243
22289
|
revision,
|
|
22244
22290
|
status: status2,
|
|
22245
22291
|
message,
|
|
22246
|
-
questions
|
|
22247
|
-
publication:
|
|
22248
|
-
findings: readFindings(body["findings"]),
|
|
22249
|
-
canRetry:
|
|
22292
|
+
questions,
|
|
22293
|
+
publication: publication ?? null,
|
|
22294
|
+
findings: readFindings(isRecord(body) ? body["findings"] : void 0),
|
|
22295
|
+
canRetry: canRetry === true
|
|
22250
22296
|
};
|
|
22251
22297
|
}
|
|
22252
22298
|
function readFindings(value) {
|
|
@@ -22282,16 +22328,17 @@ function readFindings(value) {
|
|
|
22282
22328
|
return out;
|
|
22283
22329
|
}
|
|
22284
22330
|
|
|
22285
|
-
// ../client/src/clients/
|
|
22331
|
+
// ../client/src/clients/applications/creator-tools.ts
|
|
22286
22332
|
var CREATOR_TOOLS = "creator-tools";
|
|
22333
|
+
var ToolAnswer = postApiTerminalTools.answers[200].partial().extend({ say: external_exports.string(), next: external_exports.string() });
|
|
22287
22334
|
async function runCreatorTool(input2, opts) {
|
|
22288
|
-
const url2 =
|
|
22289
|
-
const answer2 = await new
|
|
22335
|
+
const url2 = terminalUrl(input2.portal, postApiTerminalTools.path({ tool: input2.tool }));
|
|
22336
|
+
const answer2 = await new TerminalSession(opts).ask(url2, input2.args);
|
|
22290
22337
|
if (answer2.status === 401) {
|
|
22291
22338
|
return { kind: "unauthorized" };
|
|
22292
22339
|
}
|
|
22293
22340
|
if (answer2.status === 403) {
|
|
22294
|
-
return { kind: "forbidden", say: answer2.say, limit:
|
|
22341
|
+
return { kind: "forbidden", say: answer2.say, limit: refusalLimit(answer2.body) };
|
|
22295
22342
|
}
|
|
22296
22343
|
if (answer2.status === 404) {
|
|
22297
22344
|
return { kind: "unavailable", detail: "the portal does not serve this tool" };
|
|
@@ -22299,11 +22346,11 @@ async function runCreatorTool(input2, opts) {
|
|
|
22299
22346
|
if (answer2.status !== 200) {
|
|
22300
22347
|
return { kind: "unavailable", detail: answer2.status === 0 ? "the portal could not be reached" : `the portal answered ${answer2.status}` };
|
|
22301
22348
|
}
|
|
22302
|
-
const
|
|
22303
|
-
if (!
|
|
22349
|
+
const read2 = ToolAnswer.safeParse(answer2.body);
|
|
22350
|
+
if (!read2.success) {
|
|
22304
22351
|
return { kind: "malformed", detail: "an answer with no say and next" };
|
|
22305
22352
|
}
|
|
22306
|
-
const { say, next, isError, ...fields } =
|
|
22353
|
+
const { say, next, isError, ...fields } = read2.data;
|
|
22307
22354
|
const told = isError === true && fields["code"] === "feature-unavailable" ? featureOffWords(fields["feature"]) : say;
|
|
22308
22355
|
return { kind: "answer", answer: { say: told, next, isError: isError === true, fields } };
|
|
22309
22356
|
}
|
|
@@ -23568,6 +23615,38 @@ async function removePendingLogin() {
|
|
|
23568
23615
|
await (0, import_promises9.rm)(pendingLoginPath(), { force: true });
|
|
23569
23616
|
}
|
|
23570
23617
|
|
|
23618
|
+
// ../client/src/clients/portal/config.ts
|
|
23619
|
+
function portalForEndpoint(endpoint) {
|
|
23620
|
+
let url2;
|
|
23621
|
+
try {
|
|
23622
|
+
url2 = new URL(endpoint);
|
|
23623
|
+
} catch {
|
|
23624
|
+
return null;
|
|
23625
|
+
}
|
|
23626
|
+
if (url2.protocol !== "https:" || url2.pathname.replace(/\/+$/, "") !== "/publish") {
|
|
23627
|
+
return null;
|
|
23628
|
+
}
|
|
23629
|
+
return url2.origin;
|
|
23630
|
+
}
|
|
23631
|
+
async function confirmPortal(portal, endpoint, fetchImpl = fetch) {
|
|
23632
|
+
try {
|
|
23633
|
+
const res = await fetchImpl(`${portal}/api/v1/config`, { signal: AbortSignal.timeout(1e4) });
|
|
23634
|
+
if (!res.ok) {
|
|
23635
|
+
return null;
|
|
23636
|
+
}
|
|
23637
|
+
const body = await res.json();
|
|
23638
|
+
const named = body?.publishingEndpoint;
|
|
23639
|
+
const bare = (u) => u.replace(/\/+$/, "");
|
|
23640
|
+
if (typeof named !== "string" || bare(named) !== bare(endpoint)) {
|
|
23641
|
+
return null;
|
|
23642
|
+
}
|
|
23643
|
+
const terminal = body?.terminal;
|
|
23644
|
+
return { terminal: Array.isArray(terminal) && terminal.every((name) => typeof name === "string") ? terminal : [] };
|
|
23645
|
+
} catch {
|
|
23646
|
+
return null;
|
|
23647
|
+
}
|
|
23648
|
+
}
|
|
23649
|
+
|
|
23571
23650
|
// src/args.ts
|
|
23572
23651
|
var import_node_util = require("node:util");
|
|
23573
23652
|
var OPTIONS = {
|