@minnovate/shadow-publisher 0.17.3 → 0.18.1
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.
|
|
4
|
+
"version": "0.18.1",
|
|
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"]
|
|
@@ -205,6 +205,8 @@ following, for when the person asks not to wait.
|
|
|
205
205
|
- `REF_FORBIDDEN`: the user may not publish this branch; tell them which branch and stop.
|
|
206
206
|
When it comes as `error.code` with a `hint`, a limit of the organization refused it: tell them
|
|
207
207
|
the reason and whom to ask that the `hint` gives, and stop.
|
|
208
|
+
When `error.details.feature` names a feature, that feature is off for the organization: pass on
|
|
209
|
+
the `hint` as it is, and stop. Nobody in the organization can turn it on, so name nobody to ask.
|
|
208
210
|
- `MISSING_OBJECTS`: the local copy is incomplete (for example a shallow clone). Tell the user to
|
|
209
211
|
publish from a complete copy: `publisher checkout <new folder> --repo <id>`.
|
|
210
212
|
- `LIMIT_EXCEEDED`, `PACK_INVALID`: quote the message; suggest removing very large files from the
|
|
@@ -75,7 +75,7 @@ publisher history --json # the versions that went live, newest
|
|
|
75
75
|
publisher go-back <version> --json # ask the person first; puts that version's code back
|
|
76
76
|
publisher suggestions --json # what colleagues asked for, still open
|
|
77
77
|
publisher suggestion decline <id> --json # when the person does not want one
|
|
78
|
-
publisher share
|
|
78
|
+
publisher share emails --add ann@example.com --json # who can open it
|
|
79
79
|
publisher columns <id> --json # the column names of connected data, before code reads it
|
|
80
80
|
publisher data add <sheet link> --app <app> --name "<name>" --json # a Google sheet the app reads
|
|
81
81
|
publisher data remove <id> --app <app> --json # the app stops reading that data
|
|
@@ -91,7 +91,7 @@ terminal, do what it says with the command that does the same thing:
|
|
|
91
91
|
| `app_history` / `go_back` | `publisher history --json` / `publisher go-back <version> --json` |
|
|
92
92
|
| `list_starters` / `use_starter` | `publisher starters` / `publisher start <starter>` |
|
|
93
93
|
| `resolve_suggestion` | `publisher suggestion done\|decline <id> --json` |
|
|
94
|
-
| `share_app` | `publisher share <
|
|
94
|
+
| `share_app` | `publisher share <app-rule> --json` |
|
|
95
95
|
| `list_apps` | `publisher list --json` |
|
|
96
96
|
| `data_columns` | `publisher columns <id> --json` |
|
|
97
97
|
| `connect_data_source` | `publisher data add <sheet link> --app <app> --name "<name>" --json` |
|
package/dist/publisher.cjs
CHANGED
|
@@ -5221,7 +5221,7 @@ var PortalSession = class {
|
|
|
5221
5221
|
continue;
|
|
5222
5222
|
}
|
|
5223
5223
|
}
|
|
5224
|
-
return { ...answer2,
|
|
5224
|
+
return { ...answer2, say: answer2.status === 403 ? mergedSay(answer2.body) ?? featureOffSay(answer2.body) : null };
|
|
5225
5225
|
}
|
|
5226
5226
|
}
|
|
5227
5227
|
};
|
|
@@ -5255,6 +5255,21 @@ function mergedSay(body) {
|
|
|
5255
5255
|
const say = isRecord(details) ? details["say"] : void 0;
|
|
5256
5256
|
return typeof say === "string" && say !== "" ? say : null;
|
|
5257
5257
|
}
|
|
5258
|
+
var TERMINAL_FEATURE = "terminal";
|
|
5259
|
+
function featureOffSay(body) {
|
|
5260
|
+
const error2 = isRecord(body) ? body["error"] : void 0;
|
|
5261
|
+
if (!isRecord(error2) || error2["code"] !== "feature-unavailable") {
|
|
5262
|
+
return null;
|
|
5263
|
+
}
|
|
5264
|
+
return featureOffWords(isRecord(error2["details"]) ? error2["details"]["feature"] : void 0);
|
|
5265
|
+
}
|
|
5266
|
+
function featureOffWords(feature) {
|
|
5267
|
+
if (feature === TERMINAL_FEATURE) {
|
|
5268
|
+
return "The publisher command is not available for this organization, and nobody in it can turn it on.";
|
|
5269
|
+
}
|
|
5270
|
+
const named = typeof feature === "string" && feature !== "" ? ` (the feature "${feature}")` : "";
|
|
5271
|
+
return `This is not available for this organization${named}, and nobody in it can turn it on.`;
|
|
5272
|
+
}
|
|
5258
5273
|
|
|
5259
5274
|
// ../client/src/portal-refusal.ts
|
|
5260
5275
|
function portalRefusalCode(body) {
|
|
@@ -5307,7 +5322,7 @@ async function createApplication(input, opts) {
|
|
|
5307
5322
|
const limit = portalRefusalLimit(answer2.body);
|
|
5308
5323
|
throw new PublisherError(
|
|
5309
5324
|
"FORBIDDEN",
|
|
5310
|
-
answer2.
|
|
5325
|
+
answer2.say ?? `the portal refused to make an application here (${limit?.permission ?? (code || "forbidden")})`,
|
|
5311
5326
|
limit === null ? {} : { details: limit }
|
|
5312
5327
|
);
|
|
5313
5328
|
}
|
|
@@ -5542,7 +5557,7 @@ async function followRun(input, opts) {
|
|
|
5542
5557
|
return { kind: "unavailable", reason: "no-route" };
|
|
5543
5558
|
}
|
|
5544
5559
|
if (answer2.status === 403) {
|
|
5545
|
-
return { kind: "forbidden", say: answer2.
|
|
5560
|
+
return { kind: "forbidden", say: answer2.say, limit: portalRefusalLimit(answer2.body) };
|
|
5546
5561
|
}
|
|
5547
5562
|
if (answer2.status === 200) {
|
|
5548
5563
|
const run2 = soleRun(answer2.body);
|
|
@@ -5652,7 +5667,7 @@ async function call(input, opts, body) {
|
|
|
5652
5667
|
return { kind: "unauthorized" };
|
|
5653
5668
|
}
|
|
5654
5669
|
if (answer2.status === 403) {
|
|
5655
|
-
return { kind: "forbidden", say: answer2.
|
|
5670
|
+
return { kind: "forbidden", say: answer2.say, limit: portalRefusalLimit(answer2.body) };
|
|
5656
5671
|
}
|
|
5657
5672
|
if (answer2.status === 409) {
|
|
5658
5673
|
return { kind: "moved-on" };
|
|
@@ -5757,7 +5772,7 @@ async function runCreatorTool(input, opts) {
|
|
|
5757
5772
|
return { kind: "unauthorized" };
|
|
5758
5773
|
}
|
|
5759
5774
|
if (answer2.status === 403) {
|
|
5760
|
-
return { kind: "forbidden", say: answer2.
|
|
5775
|
+
return { kind: "forbidden", say: answer2.say, limit: portalRefusalLimit(answer2.body) };
|
|
5761
5776
|
}
|
|
5762
5777
|
if (answer2.status === 404) {
|
|
5763
5778
|
return { kind: "unavailable", detail: "the portal does not serve this tool" };
|
|
@@ -5770,7 +5785,8 @@ async function runCreatorTool(input, opts) {
|
|
|
5770
5785
|
return { kind: "malformed", detail: "an answer with no say and next" };
|
|
5771
5786
|
}
|
|
5772
5787
|
const { say, next, isError, ...fields } = body;
|
|
5773
|
-
|
|
5788
|
+
const told = isError === true && fields["code"] === "feature-unavailable" ? featureOffWords(fields["feature"]) : say;
|
|
5789
|
+
return { kind: "answer", answer: { say: told, next, isError: isError === true, fields } };
|
|
5774
5790
|
}
|
|
5775
5791
|
|
|
5776
5792
|
// ../client/src/onboard.ts
|
|
@@ -7053,6 +7069,10 @@ var REFUSED = /* @__PURE__ */ new Set(["REF_FORBIDDEN", "FORBIDDEN"]);
|
|
|
7053
7069
|
var Limited = class _Limited {
|
|
7054
7070
|
/** The lines for a refusal with `code` and `details`, or null when it is not a permission's or names no reason and no contact. */
|
|
7055
7071
|
static hint(code, details) {
|
|
7072
|
+
const feature = details?.["feature"];
|
|
7073
|
+
if (REFUSED.has(code) && typeof feature === "string" && feature !== "") {
|
|
7074
|
+
return featureOffWords(feature);
|
|
7075
|
+
}
|
|
7056
7076
|
const lines = REFUSED.has(code) ? _Limited.lines(details) : [];
|
|
7057
7077
|
return lines.length === 0 ? null : lines.join("\n ");
|
|
7058
7078
|
}
|
|
@@ -8257,15 +8277,23 @@ var columns = {
|
|
|
8257
8277
|
git: false,
|
|
8258
8278
|
run: (inv) => run(inv, void 0, "data_columns", inv.cmd[1] === void 0 ? {} : { id: inv.cmd[1] })
|
|
8259
8279
|
};
|
|
8280
|
+
var APP_RULES = ["members", "emails", "link"];
|
|
8281
|
+
function shareArgs(cmd, app, add, remove) {
|
|
8282
|
+
return { app, appRule: appRuleOf(cmd), add, remove };
|
|
8283
|
+
}
|
|
8284
|
+
function appRuleOf(cmd) {
|
|
8285
|
+
const named = APP_RULES.find((rule) => rule === cmd[1]);
|
|
8286
|
+
if (named === void 0) {
|
|
8287
|
+
throw new PublisherError("INVALID_REQUEST", "share takes members, emails or link");
|
|
8288
|
+
}
|
|
8289
|
+
return named;
|
|
8290
|
+
}
|
|
8260
8291
|
var share = {
|
|
8261
8292
|
git: false,
|
|
8262
8293
|
async run(inv) {
|
|
8263
|
-
|
|
8264
|
-
if (access2 === void 0) {
|
|
8265
|
-
throw new PublisherError("INVALID_REQUEST", "share takes organization, invited or anyone-with-link");
|
|
8266
|
-
}
|
|
8294
|
+
appRuleOf(inv.cmd);
|
|
8267
8295
|
const { dir, app } = await folderApp(inv);
|
|
8268
|
-
return run(inv, dir, "share_app",
|
|
8296
|
+
return run(inv, dir, "share_app", shareArgs(inv.cmd, app, listFlag(inv, "add"), listFlag(inv, "remove")));
|
|
8269
8297
|
}
|
|
8270
8298
|
};
|
|
8271
8299
|
function dataCall(cmd, app, name) {
|
|
@@ -8646,7 +8674,7 @@ Usage:
|
|
|
8646
8674
|
(the data and who can open the app stay as they are)
|
|
8647
8675
|
publisher suggestions what colleagues suggested for this folder's app, still open
|
|
8648
8676
|
publisher suggestion done|decline <id> [--run <id>] close one; sync --answers <id> closes it with that publication
|
|
8649
|
-
publisher share
|
|
8677
|
+
publisher share members|emails|link [--add <emails>] [--remove <emails>]
|
|
8650
8678
|
who can open this folder's app; new invitees get the link by mail
|
|
8651
8679
|
publisher columns [<id>] the column names of connected data, for the code that reads it;
|
|
8652
8680
|
its first rows only to an owner or admin who allowed that
|