@homespunapps/cli 1.6.17 → 1.6.19
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/commands/members.js +22 -9
- package/dist/help-catalog.js +4 -4
- package/package.json +2 -2
package/dist/commands/members.js
CHANGED
|
@@ -104,29 +104,42 @@ async function runSetRole(args) {
|
|
|
104
104
|
assertKnownFlags(args, ...specFor("members", "set-role"));
|
|
105
105
|
const appArg = args.flags.get("app");
|
|
106
106
|
if (!appArg) {
|
|
107
|
-
fail("usage: homespun members set-role --app <idOrSlug> --human <humanId> (--custom-role <name> | --clear-role)", "invalid_args");
|
|
107
|
+
fail("usage: homespun members set-role --app <idOrSlug> --human <humanId> (--custom-role <name[,name...]> | --clear-role)", "invalid_args");
|
|
108
108
|
}
|
|
109
109
|
const humanId = args.flags.get("human");
|
|
110
110
|
if (!humanId) {
|
|
111
111
|
fail("--human is required", "invalid_args");
|
|
112
112
|
}
|
|
113
|
-
// Clearing a
|
|
114
|
-
// rather than being spelled as an omitted or empty
|
|
115
|
-
// value must never silently wipe someone's
|
|
113
|
+
// Clearing a member's roles is a real instruction, so it gets its own
|
|
114
|
+
// explicit flag rather than being spelled as an omitted or empty
|
|
115
|
+
// --custom-role: an omitted value must never silently wipe someone's roles.
|
|
116
116
|
const customRole = args.flags.get("custom-role");
|
|
117
117
|
const clear = args.bools.has("clear-role");
|
|
118
118
|
if (clear && customRole !== undefined) {
|
|
119
119
|
fail("--custom-role and --clear-role are mutually exclusive", "invalid_args");
|
|
120
120
|
}
|
|
121
121
|
if (!clear && customRole === undefined) {
|
|
122
|
-
fail("one of --custom-role <name> or --clear-role is required", "invalid_args");
|
|
123
|
-
}
|
|
122
|
+
fail("one of --custom-role <name[,name...]> or --clear-role is required", "invalid_args");
|
|
123
|
+
}
|
|
124
|
+
// A member may hold several roles, so the flag takes a comma-separated list.
|
|
125
|
+
// A role name can never contain a comma (the manifest validator's role-name
|
|
126
|
+
// grammar is lowercase letters, digits and underscore), so the split is
|
|
127
|
+
// unambiguous. An empty entry is rejected rather than dropped: a trailing
|
|
128
|
+
// comma is a typo, and silently ignoring it would apply a role set the caller
|
|
129
|
+
// did not write.
|
|
130
|
+
const customRoles = clear
|
|
131
|
+
? []
|
|
132
|
+
: customRole.split(",").map((r) => {
|
|
133
|
+
const trimmed = r.trim();
|
|
134
|
+
if (trimmed.length === 0) {
|
|
135
|
+
fail("--custom-role must not contain an empty role name", "invalid_args");
|
|
136
|
+
}
|
|
137
|
+
return trimmed;
|
|
138
|
+
});
|
|
124
139
|
const client = makeClient(args);
|
|
125
140
|
const appId = await resolveAppId(client, appArg);
|
|
126
141
|
try {
|
|
127
|
-
printJson(await client.setAppMemberRole(appId, humanId, {
|
|
128
|
-
customRole: clear ? null : customRole,
|
|
129
|
-
}));
|
|
142
|
+
printJson(await client.setAppMemberRole(appId, humanId, { customRoles }));
|
|
130
143
|
}
|
|
131
144
|
catch (e) {
|
|
132
145
|
failFromError(e);
|
package/dist/help-catalog.js
CHANGED
|
@@ -338,7 +338,7 @@ const MEMBERS = {
|
|
|
338
338
|
},
|
|
339
339
|
{
|
|
340
340
|
verb: "set-role",
|
|
341
|
-
summary: "
|
|
341
|
+
summary: "Replaces an existing member's declared roles in place.",
|
|
342
342
|
flags: [
|
|
343
343
|
{
|
|
344
344
|
name: "app",
|
|
@@ -352,8 +352,8 @@ const MEMBERS = {
|
|
|
352
352
|
},
|
|
353
353
|
{
|
|
354
354
|
name: "custom-role",
|
|
355
|
-
value: "<name>",
|
|
356
|
-
description: "
|
|
355
|
+
value: "<name[,name...]>",
|
|
356
|
+
description: "Declared role(s) to assign, comma-separated; each must be declared in the app's manifest",
|
|
357
357
|
},
|
|
358
358
|
],
|
|
359
359
|
bools: [
|
|
@@ -808,7 +808,7 @@ const DEPLOY = {
|
|
|
808
808
|
notes: [
|
|
809
809
|
"Packaging has one canonical shape and one escape hatch. A directory deploy (homespun deploy ./my-app) reads ./my-app/index.html and ./my-app/manifest.json: fixed filenames, no discovery heuristics, and both files are required. The single-file escape hatch (homespun deploy ./index.html --manifest ./manifest.json) takes the manifest from --manifest, which accepts a file path or inline JSON.",
|
|
810
810
|
"Create versus redeploy is decided by the presence of --app, not by two verbs. With no --app this creates an app (POST /v1/apps); new apps default to private (owner plus invited members, sign-in gated), --slug is accepted with private or public visibility including the default, and an explicit --visibility link always gets a server-generated slug and rejects --slug. With --app <id> this redeploys (POST /v1/apps/:id/versions), where --slug and --visibility are rejected because the slug is immutable and visibility changes go through 'homespun apps update'.",
|
|
811
|
-
"--check is a dry run. It runs the full manifest and asset-shape validation, the redeploy compat gate (with --app), and the schedule-timezone advisory, then prints { ok, warnings, compat, breaks } without creating a version or mutating anything. An invalid manifest fails the same way a real deploy would, and a
|
|
811
|
+
"--check is a dry run. It runs the full manifest and asset-shape validation, the redeploy compat gate (with --app), and the schedule-timezone advisory, then prints { ok, warnings, compat, breaks } without creating a version or mutating anything. An invalid manifest fails the same way a real deploy would, and a redeploy the compat gate would refuse reports the break instead of applying it.",
|
|
812
812
|
],
|
|
813
813
|
outputNote: 'Output is JSON: { app_id, slug, url, version, visibility, created, share_url, compat, breaks, warnings }. share_url is present only when creating a link-visibility app: it carries the app share token in its #k= fragment and is shown ONCE, it is not recoverable later, and it can be rotated with \'homespun apps share-link rotate <app>\'. warnings flags non-fatal issues, for example an app that declares schedules with no timezone set (reminders fire at 08:00 UTC until one is set). Errors go to stderr as {"error":{"code","message"}} with a non-zero exit.',
|
|
814
814
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@homespunapps/cli",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.19",
|
|
4
4
|
"description": "Command-line client for the Homespun relay: deploy a real multi-user web app from your agent, then keep reading and writing its data.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"test:unit": "vitest run"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@homespunapps/core": "^1.6.
|
|
39
|
+
"@homespunapps/core": "^1.6.19",
|
|
40
40
|
"qrcode-terminal": "^0.12.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|