@skillcdn/console 0.4.4 → 0.4.5
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/README.md +3 -3
- package/dist/api.d.ts +3 -3
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +3 -3
- package/dist/api.js.map +1 -1
- package/dist/cli/cli.d.ts.map +1 -1
- package/dist/cli/cli.js +162 -15
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/format.d.ts +16 -3
- package/dist/cli/format.d.ts.map +1 -1
- package/dist/cli/format.js +68 -19
- package/dist/cli/format.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +26 -5
- package/dist/cli/help.js.map +1 -1
- package/dist/client.d.ts +28 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +12 -2
- package/dist/client.js.map +1 -1
- package/dist/compat.js +1 -1
- package/dist/components/board.d.ts.map +1 -1
- package/dist/components/board.js +46 -15
- package/dist/components/board.js.map +1 -1
- package/dist/components/decision-form.d.ts +0 -3
- package/dist/components/decision-form.d.ts.map +1 -1
- package/dist/components/decision-form.js +3 -15
- package/dist/components/decision-form.js.map +1 -1
- package/dist/components/event-feed.d.ts.map +1 -1
- package/dist/components/event-feed.js +30 -10
- package/dist/components/event-feed.js.map +1 -1
- package/dist/components/my-decisions.d.ts +20 -3
- package/dist/components/my-decisions.d.ts.map +1 -1
- package/dist/components/my-decisions.js +14 -1
- package/dist/components/my-decisions.js.map +1 -1
- package/dist/components/people.d.ts +43 -1
- package/dist/components/people.d.ts.map +1 -1
- package/dist/components/people.js +117 -9
- package/dist/components/people.js.map +1 -1
- package/dist/components/picker.d.ts +8 -0
- package/dist/components/picker.d.ts.map +1 -1
- package/dist/components/picker.js +2 -2
- package/dist/components/picker.js.map +1 -1
- package/dist/components/plugin-frame.d.ts +0 -1
- package/dist/components/plugin-frame.d.ts.map +1 -1
- package/dist/components/plugin-frame.js +22 -1
- package/dist/components/plugin-frame.js.map +1 -1
- package/dist/components/plugin-settings.d.ts +5 -1
- package/dist/components/plugin-settings.d.ts.map +1 -1
- package/dist/components/plugin-settings.js +143 -30
- package/dist/components/plugin-settings.js.map +1 -1
- package/dist/components/projects.d.ts.map +1 -1
- package/dist/components/projects.js +3 -1
- package/dist/components/projects.js.map +1 -1
- package/dist/components/searches.d.ts +11 -0
- package/dist/components/searches.d.ts.map +1 -0
- package/dist/components/searches.js +30 -0
- package/dist/components/searches.js.map +1 -0
- package/dist/components/task-form.d.ts.map +1 -1
- package/dist/components/task-form.js +6 -5
- package/dist/components/task-form.js.map +1 -1
- package/dist/components/ui.d.ts +16 -0
- package/dist/components/ui.d.ts.map +1 -1
- package/dist/components/ui.js +10 -0
- package/dist/components/ui.js.map +1 -1
- package/dist/console.css +362 -67
- package/dist/console.d.ts +2 -1
- package/dist/console.d.ts.map +1 -1
- package/dist/console.js +90 -14
- package/dist/console.js.map +1 -1
- package/dist/data.d.ts +14 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +36 -1
- package/dist/data.js.map +1 -1
- package/dist/i18n/en.d.ts +89 -0
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +87 -2
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/ko.d.ts.map +1 -1
- package/dist/i18n/ko.js +87 -3
- package/dist/i18n/ko.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/limits.d.ts +6 -0
- package/dist/limits.d.ts.map +1 -1
- package/dist/limits.js +6 -0
- package/dist/limits.js.map +1 -1
- package/dist/plugin/args.d.ts +6 -1
- package/dist/plugin/args.d.ts.map +1 -1
- package/dist/plugin/args.js +16 -11
- package/dist/plugin/args.js.map +1 -1
- package/dist/plugin/bridge.d.ts +20 -1
- package/dist/plugin/bridge.d.ts.map +1 -1
- package/dist/plugin/bridge.js +28 -0
- package/dist/plugin/bridge.js.map +1 -1
- package/dist/plugin/capabilities.d.ts +1 -1
- package/dist/plugin/capabilities.d.ts.map +1 -1
- package/dist/plugin/capabilities.js +10 -0
- package/dist/plugin/capabilities.js.map +1 -1
- package/dist/plugin/context.d.ts +158 -13
- package/dist/plugin/context.d.ts.map +1 -1
- package/dist/plugin/define.d.ts +13 -1
- package/dist/plugin/define.d.ts.map +1 -1
- package/dist/plugin/define.js +17 -1
- package/dist/plugin/define.js.map +1 -1
- package/dist/plugin/limits.d.ts +4 -0
- package/dist/plugin/limits.d.ts.map +1 -1
- package/dist/plugin/limits.js +4 -0
- package/dist/plugin/limits.js.map +1 -1
- package/dist/plugin/manifest.d.ts +15 -0
- package/dist/plugin/manifest.d.ts.map +1 -1
- package/dist/plugin/manifest.js +61 -4
- package/dist/plugin/manifest.js.map +1 -1
- package/dist/plugin/rest-schemas.d.ts +44 -0
- package/dist/plugin/rest-schemas.d.ts.map +1 -1
- package/dist/plugin/rest-schemas.js +55 -3
- package/dist/plugin/rest-schemas.js.map +1 -1
- package/dist/plugin/testing.d.ts +15 -1
- package/dist/plugin/testing.d.ts.map +1 -1
- package/dist/plugin/testing.js +40 -4
- package/dist/plugin/testing.js.map +1 -1
- package/dist/plugin/web.d.ts +6 -0
- package/dist/plugin/web.d.ts.map +1 -1
- package/dist/plugin/web.js +10 -1
- package/dist/plugin/web.js.map +1 -1
- package/dist/plugin.d.ts +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +1 -1
- package/dist/plugin.js.map +1 -1
- package/dist/router.d.ts +19 -0
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +18 -0
- package/dist/router.js.map +1 -1
- package/dist/routes.d.ts +11 -2
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +14 -1
- package/dist/routes.js.map +1 -1
- package/dist/schemas.d.ts +367 -0
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +62 -2
- package/dist/schemas.js.map +1 -1
- package/dist/vocabulary.d.ts +1 -1
- package/dist/vocabulary.d.ts.map +1 -1
- package/dist/vocabulary.js +6 -0
- package/dist/vocabulary.js.map +1 -1
- package/docs/specs/cli.md +7 -4
- package/docs/specs/plugins.md +47 -39
- package/docs/specs/rest.md +22 -5
- package/package.json +1 -1
- package/skills/building-a-plugin/SKILL.md +8 -6
- package/skills/working-the-board/SKILL.md +1 -1
- package/src/api.ts +17 -0
- package/src/cli/cli.ts +200 -12
- package/src/cli/format.ts +82 -19
- package/src/cli/help.ts +30 -5
- package/src/client.ts +70 -0
- package/src/compat.ts +1 -1
- package/src/components/board.tsx +83 -42
- package/src/components/decision-form.tsx +13 -32
- package/src/components/event-feed.tsx +36 -9
- package/src/components/my-decisions.tsx +50 -5
- package/src/components/people.tsx +394 -37
- package/src/components/picker.tsx +11 -2
- package/src/components/plugin-frame.tsx +23 -0
- package/src/components/plugin-settings.tsx +346 -137
- package/src/components/projects.tsx +14 -14
- package/src/components/searches.ts +47 -0
- package/src/components/task-form.tsx +23 -28
- package/src/components/ui.tsx +36 -0
- package/src/console.tsx +229 -40
- package/src/data.ts +53 -1
- package/src/i18n/en.ts +98 -2
- package/src/i18n/ko.ts +95 -3
- package/src/index.ts +11 -0
- package/src/limits.ts +6 -0
- package/src/plugin/args.ts +16 -11
- package/src/plugin/bridge.ts +45 -0
- package/src/plugin/capabilities.ts +11 -0
- package/src/plugin/context.ts +170 -10
- package/src/plugin/define.ts +34 -0
- package/src/plugin/limits.ts +4 -0
- package/src/plugin/manifest.ts +74 -3
- package/src/plugin/rest-schemas.ts +62 -5
- package/src/plugin/testing.ts +61 -5
- package/src/plugin/web.ts +17 -0
- package/src/plugin.ts +1 -0
- package/src/router.ts +25 -0
- package/src/routes.ts +17 -2
- package/src/schemas.ts +81 -2
- package/src/styles/console.css +362 -67
- package/src/vocabulary.ts +6 -0
package/src/data.ts
CHANGED
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
type RestProjectInput,
|
|
45
45
|
type RestProjectPatch,
|
|
46
46
|
type RestProjectRules,
|
|
47
|
+
type RestReachedDecision,
|
|
47
48
|
type RestRules,
|
|
48
49
|
type RestRulesInput,
|
|
49
50
|
type RestRulesPlugin,
|
|
@@ -53,6 +54,9 @@ import {
|
|
|
53
54
|
type RestTaskInput,
|
|
54
55
|
type RestTaskPatch,
|
|
55
56
|
type RestTasks,
|
|
57
|
+
type RestTeam,
|
|
58
|
+
type RestTeamInput,
|
|
59
|
+
type RestTeamPatch,
|
|
56
60
|
type RestToken,
|
|
57
61
|
type RestTokenCreated,
|
|
58
62
|
type RestTokenInput,
|
|
@@ -148,6 +152,10 @@ export interface ConsoleActions {
|
|
|
148
152
|
},
|
|
149
153
|
signal?: AbortSignal,
|
|
150
154
|
): Promise<RestMyDecisions>;
|
|
155
|
+
/** One decision wherever it is (ADR-0068), with its project and whether the person may answer it, read when the page asks. */
|
|
156
|
+
reachDecision(id: string, signal?: AbortSignal): Promise<RestReachedDecision>;
|
|
157
|
+
/** Answers a decision wherever it is, as whoever it reaches (ADR-0068). */
|
|
158
|
+
answerReachedDecision(id: string, input: RestAnswerInput): Promise<RestDecision>;
|
|
151
159
|
/** The categories tasks are sorted into: kept by an administrator. */
|
|
152
160
|
createCategory(input: RestCategoryInput): Promise<RestCategory>;
|
|
153
161
|
updateCategory(key: string, patch: RestCategoryPatch): Promise<RestCategory>;
|
|
@@ -173,6 +181,13 @@ export interface ConsoleActions {
|
|
|
173
181
|
createListing(input: RestListingInput): Promise<RestListing>;
|
|
174
182
|
/** Takes a listing away that nobody signed in with; for an administrator. */
|
|
175
183
|
removeListing(id: string): Promise<void>;
|
|
184
|
+
/** The teams (ADR-0073): made, renamed and removed, a person put in or taken out; for an administrator. */
|
|
185
|
+
createTeam(input: RestTeamInput): Promise<RestTeam>;
|
|
186
|
+
/** A team is called by its key (ADR-0074), which never changes. */
|
|
187
|
+
renameTeam(key: string, patch: RestTeamPatch): Promise<RestTeam>;
|
|
188
|
+
removeTeam(key: string): Promise<void>;
|
|
189
|
+
addTeamMember(key: string, personId: string): Promise<RestTeam>;
|
|
190
|
+
removeTeamMember(key: string, personId: string): Promise<RestTeam>;
|
|
176
191
|
/** Keeps the person's language (ADR-0065) or their front page. */
|
|
177
192
|
updateMe(patch: RestMePatch): Promise<RestMe>;
|
|
178
193
|
/** Changes the workspace's settings (ADR-0035); for an administrator. `me` says them from then on. */
|
|
@@ -226,6 +241,8 @@ export interface ConsoleData {
|
|
|
226
241
|
readonly people: readonly RestPerson[];
|
|
227
242
|
/** The logins let in that nobody has signed in with yet. */
|
|
228
243
|
readonly listed: readonly RestListing[];
|
|
244
|
+
/** The teams of the workspace (ADR-0073), by name, each with the members the person may see. */
|
|
245
|
+
readonly teams: readonly RestTeam[];
|
|
229
246
|
/** The organization at the git host that says who is in, where the deployment names one. */
|
|
230
247
|
readonly organization: RestOrganization | null;
|
|
231
248
|
/** The categories tasks are sorted into, by name. */
|
|
@@ -364,6 +381,7 @@ export function useConsoleData(client: ConsoleClient, projectKey: string | undef
|
|
|
364
381
|
const [projects, setProjects] = useState<readonly RestProject[]>([]);
|
|
365
382
|
const [people, setPeople] = useState<readonly RestPerson[]>([]);
|
|
366
383
|
const [listed, setListed] = useState<readonly RestListing[]>([]);
|
|
384
|
+
const [teams, setTeams] = useState<readonly RestTeam[]>([]);
|
|
367
385
|
const [organization, setOrganization] = useState<RestOrganization | null>(null);
|
|
368
386
|
const [categories, setCategories] = useState<readonly RestCategory[]>([]);
|
|
369
387
|
const [plugins, setPlugins] = useState<readonly RestPlugin[]>([]);
|
|
@@ -403,12 +421,14 @@ export function useConsoleData(client: ConsoleClient, projectKey: string | undef
|
|
|
403
421
|
/** Loads the workspace's lists again. What fails stays as it was. */
|
|
404
422
|
const refreshWorkspace = useCallback(
|
|
405
423
|
async (signal?: AbortSignal) => {
|
|
406
|
-
const [nextProjects, nextPeople, nextCategories, nextPlugins] = await Promise.all([
|
|
424
|
+
const [nextProjects, nextPeople, nextCategories, nextPlugins, nextTeams] = await Promise.all([
|
|
407
425
|
client.projects(signal),
|
|
408
426
|
client.people(signal),
|
|
409
427
|
client.categories(signal),
|
|
410
428
|
// A console without plugins answers none; one older than them answers nothing, which is none too.
|
|
411
429
|
client.plugins(signal).catch(() => ({ items: [], sql: false })),
|
|
430
|
+
// A console older than teams (ADR-0073) answers nothing, which is no team.
|
|
431
|
+
client.teams(signal).catch(() => ({ items: [] })),
|
|
412
432
|
]);
|
|
413
433
|
if (signal?.aborted === true) {
|
|
414
434
|
return;
|
|
@@ -416,6 +436,7 @@ export function useConsoleData(client: ConsoleClient, projectKey: string | undef
|
|
|
416
436
|
setProjects(nextProjects.items);
|
|
417
437
|
setPeople(nextPeople.items);
|
|
418
438
|
setListed(nextPeople.listed);
|
|
439
|
+
setTeams(nextTeams.items);
|
|
419
440
|
setOrganization(nextPeople.organization);
|
|
420
441
|
setCategories(nextCategories.items);
|
|
421
442
|
setPlugins(nextPlugins.items);
|
|
@@ -744,6 +765,12 @@ export function useConsoleData(client: ConsoleClient, projectKey: string | undef
|
|
|
744
765
|
},
|
|
745
766
|
work: (signal) => client.work(signal),
|
|
746
767
|
myDecisions: (filter, signal) => client.myDecisions(filter, signal),
|
|
768
|
+
reachDecision: (id, signal) => client.decision(id, signal),
|
|
769
|
+
async answerReachedDecision(id, input) {
|
|
770
|
+
const decision = await client.answerDecision(id, input);
|
|
771
|
+
await refreshMe().catch(() => undefined);
|
|
772
|
+
return decision;
|
|
773
|
+
},
|
|
747
774
|
async createCategory(input) {
|
|
748
775
|
const category = await client.createCategory(input);
|
|
749
776
|
setCategories((await client.categories()).items);
|
|
@@ -781,6 +808,30 @@ export function useConsoleData(client: ConsoleClient, projectKey: string | undef
|
|
|
781
808
|
await client.removeListing(id);
|
|
782
809
|
await refreshWorkspace();
|
|
783
810
|
},
|
|
811
|
+
async createTeam(input) {
|
|
812
|
+
const team = await client.createTeam(input);
|
|
813
|
+
await refreshWorkspace();
|
|
814
|
+
return team;
|
|
815
|
+
},
|
|
816
|
+
async renameTeam(key, patch) {
|
|
817
|
+
const team = await client.renameTeam(key, patch);
|
|
818
|
+
await refreshWorkspace();
|
|
819
|
+
return team;
|
|
820
|
+
},
|
|
821
|
+
async removeTeam(key) {
|
|
822
|
+
await client.removeTeam(key);
|
|
823
|
+
await refreshWorkspace();
|
|
824
|
+
},
|
|
825
|
+
async addTeamMember(key, personId) {
|
|
826
|
+
const team = await client.addTeamMember(key, personId);
|
|
827
|
+
await refreshWorkspace();
|
|
828
|
+
return team;
|
|
829
|
+
},
|
|
830
|
+
async removeTeamMember(key, personId) {
|
|
831
|
+
const team = await client.removeTeamMember(key, personId);
|
|
832
|
+
await refreshWorkspace();
|
|
833
|
+
return team;
|
|
834
|
+
},
|
|
784
835
|
async updateMe(patch) {
|
|
785
836
|
const answer = await client.updateMe(patch);
|
|
786
837
|
setMe(answer);
|
|
@@ -873,6 +924,7 @@ export function useConsoleData(client: ConsoleClient, projectKey: string | undef
|
|
|
873
924
|
projects,
|
|
874
925
|
people,
|
|
875
926
|
listed,
|
|
927
|
+
teams,
|
|
876
928
|
organization,
|
|
877
929
|
categories,
|
|
878
930
|
plugins,
|
package/src/i18n/en.ts
CHANGED
|
@@ -207,6 +207,14 @@ export const en = {
|
|
|
207
207
|
"member.open_project": "The project is open to the workspace, so everyone is already a member.",
|
|
208
208
|
"mount.ref_not_found": "That version of the pack was not found.",
|
|
209
209
|
"mount.repo_not_found": "The pack was not found.",
|
|
210
|
+
"person.email_taken": "That address is another person's in this workspace.",
|
|
211
|
+
"team.not_found": "The team was not found.",
|
|
212
|
+
"team.name_taken": "A team of that name is there already.",
|
|
213
|
+
"team.key_taken": "A team or a project of that key is there already.",
|
|
214
|
+
"team.invalid_name": "A team's name is one line of words.",
|
|
215
|
+
"team.too_many": "The workspace holds as many teams as one may.",
|
|
216
|
+
"team.invalid_member": "Only an active person of the workspace is put in a team.",
|
|
217
|
+
"team.not_a_member": "The person is not in the team.",
|
|
210
218
|
"person.invalid_manager":
|
|
211
219
|
"A manager must be another active person, and not one of this person's own team.",
|
|
212
220
|
"person.last_admin": "The workspace needs at least one administrator.",
|
|
@@ -229,7 +237,7 @@ export const en = {
|
|
|
229
237
|
"plugin.unavailable": "The plugin can't be reached right now.",
|
|
230
238
|
"project.invalid_address": "That is not the address of a pack.",
|
|
231
239
|
"project.invalid_icon": "That file can't be used as the project's image.",
|
|
232
|
-
"project.key_taken": "A project with this key already exists.",
|
|
240
|
+
"project.key_taken": "A project or a team with this key already exists.",
|
|
233
241
|
"project.no_icon": "The project has no image.",
|
|
234
242
|
"project.not_found": "The project was not found.",
|
|
235
243
|
"project.pack_connect_refused": "SkillCDN refused the connection.",
|
|
@@ -324,6 +332,10 @@ export const en = {
|
|
|
324
332
|
projectsSome: "Some projects",
|
|
325
333
|
settingsForm: "Settings",
|
|
326
334
|
secretSet: (when: string) => `Set ${when}`,
|
|
335
|
+
secretSealedFrom: (host: string, when: string) => `Received from ${host} ${when}`,
|
|
336
|
+
secretExpires: (when: string) => `expires ${when}`,
|
|
337
|
+
secretExpired: (when: string) => `expired ${when}`,
|
|
338
|
+
secretHosts: (hosts: string) => `Sent to ${hosts} only.`,
|
|
327
339
|
secretUnset: "Not set",
|
|
328
340
|
secretNew: "New value",
|
|
329
341
|
enable: "Enable",
|
|
@@ -332,11 +344,24 @@ export const en = {
|
|
|
332
344
|
rolesNone: "No roles: every member may use it.",
|
|
333
345
|
roleDefault: "Default",
|
|
334
346
|
everyMember: "Every member",
|
|
347
|
+
roleManagers: "Reporting line",
|
|
348
|
+
whoeverManages: "Whoever someone reports to",
|
|
335
349
|
grantEveryone: "Everyone",
|
|
336
350
|
grantMembersOf: (project: string) => `Members of ${project}`,
|
|
337
351
|
grantPeople: "People",
|
|
338
352
|
grantProjects: "Members of a project",
|
|
339
353
|
grantWhom: "Grant to…",
|
|
354
|
+
grantPlugins: "Plugins",
|
|
355
|
+
grantTeams: "Teams",
|
|
356
|
+
grantTeam: (team: string) => `The team ${team}`,
|
|
357
|
+
grantPlugin: (plugin: string) => `The plugin ${plugin}`,
|
|
358
|
+
asks: "Roles asked of other plugins",
|
|
359
|
+
asksHint:
|
|
360
|
+
"Roles of other plugins this plugin asks to hold, to act as itself in them; each is an administrator's to grant, here or when enabling.",
|
|
361
|
+
askGranted: "Granted",
|
|
362
|
+
askUngranted: "Not granted",
|
|
363
|
+
askUnavailable: (plugin: string) => `${plugin} is not enabled; grant it here once it is.`,
|
|
364
|
+
askGrantNow: "Grant it now",
|
|
340
365
|
grant: "Grant",
|
|
341
366
|
revoke: "Revoke",
|
|
342
367
|
events: "What happened",
|
|
@@ -356,9 +381,16 @@ export const en = {
|
|
|
356
381
|
console: "Console versions",
|
|
357
382
|
consoleRange: (range: string) => `console ${range}`,
|
|
358
383
|
timeZoneHint: "In the workspace's time zone.",
|
|
384
|
+
keeps: "Kept for",
|
|
385
|
+
keepsFor: (collection: string, days: number) =>
|
|
386
|
+
`${collection}: ${days} ${days === 1 ? "day" : "days"}, then removed`,
|
|
387
|
+
needsTimeZone:
|
|
388
|
+
"The workspace has no time zone, so this plugin's times of day run on UTC until one is set.",
|
|
389
|
+
setTimeZone: "Set the time zone",
|
|
359
390
|
addItem: "Add",
|
|
360
391
|
itemPlaceholder: "Type, then add",
|
|
361
392
|
choose: "Choose…",
|
|
393
|
+
addOne: "Add…",
|
|
362
394
|
},
|
|
363
395
|
/** What stands in for a frame the console has nothing to show in. */
|
|
364
396
|
frameUnavailable: "This can't be shown right now.",
|
|
@@ -373,6 +405,16 @@ export const en = {
|
|
|
373
405
|
name: "Everyone",
|
|
374
406
|
opens: "Reads everyone in the workspace, from its jobs and hooks too.",
|
|
375
407
|
},
|
|
408
|
+
"people:read:email": {
|
|
409
|
+
name: "Work email",
|
|
410
|
+
opens:
|
|
411
|
+
"Reads the work email of the people it may read, to match them to accounts elsewhere.",
|
|
412
|
+
},
|
|
413
|
+
"people:act": {
|
|
414
|
+
name: "Acting for a person",
|
|
415
|
+
opens:
|
|
416
|
+
"Runs a command and answers a decision for a person who did it elsewhere, within what they may do, recorded as theirs through the plugin.",
|
|
417
|
+
},
|
|
376
418
|
"projects:read": {
|
|
377
419
|
name: "Projects",
|
|
378
420
|
opens: "Reads the projects and members the person may see.",
|
|
@@ -941,8 +983,13 @@ export const en = {
|
|
|
941
983
|
console: "The console",
|
|
942
984
|
as: (agent: string) => `as ${agent}`,
|
|
943
985
|
asTitle: "The agent the person acted through",
|
|
986
|
+
via: (plugin: string) => `through ${plugin}`,
|
|
987
|
+
viaTitle: "The plugin that acted for the person",
|
|
988
|
+
thePlugin: (plugin: string) => `the plugin ${plugin}`,
|
|
944
989
|
aTask: "a task",
|
|
945
990
|
aPlugin: "a plugin",
|
|
991
|
+
aTeam: "a team",
|
|
992
|
+
theTeam: (team: string) => `the team ${team}`,
|
|
946
993
|
/** After the sentence of a board's event a plugin caused (ADR-0052). */
|
|
947
994
|
throughPlugin: (plugin: string) => `through the plugin ${plugin}`,
|
|
948
995
|
everyone: "everyone",
|
|
@@ -1000,6 +1047,13 @@ export const en = {
|
|
|
1000
1047
|
personReactivated: (login: string) => `reactivated ${login}`,
|
|
1001
1048
|
managerChanged: (login: string, manager: string) => `set ${login}'s manager to ${manager}`,
|
|
1002
1049
|
managerCleared: (login: string) => `cleared ${login}'s manager`,
|
|
1050
|
+
emailChanged: (login: string) => `changed ${login}'s work email`,
|
|
1051
|
+
emailCleared: (login: string) => `cleared ${login}'s work email`,
|
|
1052
|
+
teamCreated: (team: string) => `made the team ${team}`,
|
|
1053
|
+
teamRenamed: (from: string, team: string) => `renamed the team ${from} to ${team}`,
|
|
1054
|
+
teamRemoved: (team: string) => `deleted the team ${team}`,
|
|
1055
|
+
teamMemberAdded: (login: string, team: string) => `put ${login} in the team ${team}`,
|
|
1056
|
+
teamMemberRemoved: (login: string, team: string) => `took ${login} out of the team ${team}`,
|
|
1003
1057
|
projectCreated: (project: string) => `made the project ${project}`,
|
|
1004
1058
|
projectUpdated: (fields: string, project: string) =>
|
|
1005
1059
|
`changed ${fields} of the project ${project}`,
|
|
@@ -1045,6 +1099,8 @@ export const en = {
|
|
|
1045
1099
|
pluginConsented: (plugin: string) => `changed the capabilities of the plugin ${plugin}`,
|
|
1046
1100
|
pluginConfigured: (fields: string, plugin: string) =>
|
|
1047
1101
|
`changed ${fields} of the plugin ${plugin}`,
|
|
1102
|
+
pluginSealed: (fields: string, plugin: string, host: string) =>
|
|
1103
|
+
`stored ${fields} of the plugin ${plugin}, received from ${host}`,
|
|
1048
1104
|
pluginGranted: (role: string, who: string, plugin: string) =>
|
|
1049
1105
|
`gave ${who} the role ${role} in the plugin ${plugin}`,
|
|
1050
1106
|
pluginRevoked: (role: string, who: string, plugin: string) =>
|
|
@@ -1238,7 +1294,17 @@ export const en = {
|
|
|
1238
1294
|
role: "Role",
|
|
1239
1295
|
manager: "Manager",
|
|
1240
1296
|
managerOf: (name: string) => `Manager of ${name}`,
|
|
1241
|
-
|
|
1297
|
+
email: "Work email",
|
|
1298
|
+
emailOf: (name: string) => `Work email of ${name}`,
|
|
1299
|
+
emailHint:
|
|
1300
|
+
"Google's at sign-in; written here otherwise. Read by an administrator, the person, and a plugin allowed to.",
|
|
1301
|
+
team: "Direct reports",
|
|
1302
|
+
teams: "Teams",
|
|
1303
|
+
joinTeam: "Add to a team…",
|
|
1304
|
+
joinTeamOf: (name: string) => `Add ${name} to a team`,
|
|
1305
|
+
leaveTeam: (name: string, team: string) => `Take ${name} out of ${team}`,
|
|
1306
|
+
howMany: (count: number) => (count === 1 ? "1 person" : `${count} people`),
|
|
1307
|
+
views: { aria: "People and teams", people: "People", teams: "Teams" },
|
|
1242
1308
|
nobody: "None",
|
|
1243
1309
|
letIn: "Add a person",
|
|
1244
1310
|
letInAria: "Add a person",
|
|
@@ -1289,6 +1355,36 @@ export const en = {
|
|
|
1289
1355
|
},
|
|
1290
1356
|
},
|
|
1291
1357
|
|
|
1358
|
+
/** The teams of the workspace (ADR-0073), a view of the people page of their own. */
|
|
1359
|
+
teams: {
|
|
1360
|
+
list: "Teams",
|
|
1361
|
+
none: {
|
|
1362
|
+
title: "No teams yet",
|
|
1363
|
+
body: "A team puts people under one name: a plugin finds them by it, and a role of a plugin granted to the team is held by everyone in it.",
|
|
1364
|
+
},
|
|
1365
|
+
members: (count: number) => (count === 1 ? "1 member" : `${count} members`),
|
|
1366
|
+
nobody: "Nobody in it yet.",
|
|
1367
|
+
nameOf: (team: string) => `Name of the team ${team}`,
|
|
1368
|
+
keyTitle:
|
|
1369
|
+
"The team's key: what a grant, a plugin and the command call it by. It never changes.",
|
|
1370
|
+
addMember: "Add a person…",
|
|
1371
|
+
addMemberTo: (team: string) => `Add a person to ${team}`,
|
|
1372
|
+
removeMember: (name: string, team: string) => `Take ${name} out of ${team}`,
|
|
1373
|
+
remove: "Delete team",
|
|
1374
|
+
removeAsk: (team: string) =>
|
|
1375
|
+
`Delete the team ${team}? The roles of plugins granted to it go with it; its people stay.`,
|
|
1376
|
+
newTeam: "New team",
|
|
1377
|
+
newAria: "New team",
|
|
1378
|
+
form: {
|
|
1379
|
+
name: "Team name",
|
|
1380
|
+
key: "Key",
|
|
1381
|
+
keyHint:
|
|
1382
|
+
"Lowercase letters, digits and hyphens: what a grant, a plugin and the command call the team by. No other team and no project has it, and it never changes.",
|
|
1383
|
+
hint: "The name is what people read, and can change; the key stays. People are added on the team's card once it is made.",
|
|
1384
|
+
submit: "Make the team",
|
|
1385
|
+
},
|
|
1386
|
+
},
|
|
1387
|
+
|
|
1292
1388
|
agents: {
|
|
1293
1389
|
title: "Agents",
|
|
1294
1390
|
makeByHand: "Make a token by hand",
|
package/src/i18n/ko.ts
CHANGED
|
@@ -163,6 +163,14 @@ export const ko: Messages = {
|
|
|
163
163
|
"member.open_project": "공개 프로젝트라서 워크스페이스의 모든 사람이 이미 멤버입니다.",
|
|
164
164
|
"mount.ref_not_found": "팩의 그 버전을 찾을 수 없습니다.",
|
|
165
165
|
"mount.repo_not_found": "팩을 찾을 수 없습니다.",
|
|
166
|
+
"person.email_taken": "이 워크스페이스의 다른 사람이 쓰는 주소입니다.",
|
|
167
|
+
"team.not_found": "팀을 찾을 수 없습니다.",
|
|
168
|
+
"team.name_taken": "같은 이름의 팀이 이미 있습니다.",
|
|
169
|
+
"team.key_taken": "같은 키의 팀이나 프로젝트가 이미 있습니다.",
|
|
170
|
+
"team.invalid_name": "팀 이름은 한 줄의 글자여야 합니다.",
|
|
171
|
+
"team.too_many": "워크스페이스가 가질 수 있는 만큼의 팀이 이미 있습니다.",
|
|
172
|
+
"team.invalid_member": "활성 상태인 워크스페이스의 사람만 팀에 넣을 수 있습니다.",
|
|
173
|
+
"team.not_a_member": "그 사람은 이 팀에 없습니다.",
|
|
166
174
|
"person.invalid_manager": "본인, 본인의 팀원, 비활성화된 사람은 매니저로 지정할 수 없습니다.",
|
|
167
175
|
"person.last_admin": "관리자가 한 명은 있어야 합니다.",
|
|
168
176
|
"person.not_found": "사람을 찾을 수 없습니다.",
|
|
@@ -185,7 +193,7 @@ export const ko: Messages = {
|
|
|
185
193
|
"plugin.unavailable": "지금은 플러그인을 쓸 수 없습니다.",
|
|
186
194
|
"project.invalid_address": "팩 주소가 아닙니다.",
|
|
187
195
|
"project.invalid_icon": "프로젝트 이미지로 쓸 수 없는 파일입니다.",
|
|
188
|
-
"project.key_taken": "같은 키의
|
|
196
|
+
"project.key_taken": "같은 키의 프로젝트나 팀이 이미 있습니다.",
|
|
189
197
|
"project.no_icon": "프로젝트에 이미지가 없습니다.",
|
|
190
198
|
"project.not_found": "프로젝트를 찾을 수 없습니다.",
|
|
191
199
|
"project.pack_connect_refused": "SkillCDN이 연결을 거부했습니다.",
|
|
@@ -279,6 +287,10 @@ export const ko: Messages = {
|
|
|
279
287
|
projectsSome: "일부 프로젝트",
|
|
280
288
|
settingsForm: "설정",
|
|
281
289
|
secretSet: (when) => `${when} 설정됨`,
|
|
290
|
+
secretSealedFrom: (host, when) => `${when} ${host}에서 받아 저장됨`,
|
|
291
|
+
secretExpires: (when) => `${when} 만료 예정`,
|
|
292
|
+
secretExpired: (when) => `${when} 만료됨`,
|
|
293
|
+
secretHosts: (hosts) => `${hosts}에만 보냅니다.`,
|
|
282
294
|
secretUnset: "설정 안 됨",
|
|
283
295
|
secretNew: "새 값",
|
|
284
296
|
enable: "활성화",
|
|
@@ -287,11 +299,24 @@ export const ko: Messages = {
|
|
|
287
299
|
rolesNone: "역할이 없어 모든 멤버가 쓸 수 있습니다.",
|
|
288
300
|
roleDefault: "기본",
|
|
289
301
|
everyMember: "모든 멤버",
|
|
302
|
+
roleManagers: "보고 라인",
|
|
303
|
+
whoeverManages: "누군가의 매니저인 사람",
|
|
290
304
|
grantEveryone: "모두",
|
|
291
305
|
grantMembersOf: (project) => `${project}의 멤버`,
|
|
292
306
|
grantPeople: "사람",
|
|
293
307
|
grantProjects: "프로젝트의 멤버",
|
|
294
308
|
grantWhom: "부여할 대상…",
|
|
309
|
+
grantPlugins: "플러그인",
|
|
310
|
+
grantTeams: "팀",
|
|
311
|
+
grantTeam: (team) => `팀 ${team}`,
|
|
312
|
+
grantPlugin: (plugin) => `플러그인 ${plugin}`,
|
|
313
|
+
asks: "다른 플러그인에 요청한 역할",
|
|
314
|
+
asksHint:
|
|
315
|
+
"이 플러그인이 다른 플러그인에서 자기 이름으로 쓰려고 요청한 역할입니다. 관리자가 여기서, 또는 켤 때 부여합니다.",
|
|
316
|
+
askGranted: "부여됨",
|
|
317
|
+
askUngranted: "부여되지 않음",
|
|
318
|
+
askUnavailable: (plugin) => `${plugin}이(가) 꺼져 있습니다. 켜진 뒤 여기서 부여하세요.`,
|
|
319
|
+
askGrantNow: "지금 부여",
|
|
295
320
|
grant: "부여",
|
|
296
321
|
revoke: "회수",
|
|
297
322
|
events: "일어난 일",
|
|
@@ -310,9 +335,15 @@ export const ko: Messages = {
|
|
|
310
335
|
console: "콘솔 버전",
|
|
311
336
|
consoleRange: (range) => `콘솔 ${range}`,
|
|
312
337
|
timeZoneHint: "워크스페이스 시간대 기준입니다.",
|
|
338
|
+
keeps: "보관 기간",
|
|
339
|
+
keepsFor: (collection, days) => `${collection}: ${days}일이 지나면 삭제`,
|
|
340
|
+
needsTimeZone:
|
|
341
|
+
"워크스페이스에 시간대가 없어서, 시간대를 정하기 전까지 이 플러그인의 시각은 UTC 기준으로 실행됩니다.",
|
|
342
|
+
setTimeZone: "시간대 정하기",
|
|
313
343
|
addItem: "추가",
|
|
314
344
|
itemPlaceholder: "입력한 뒤 추가",
|
|
315
345
|
choose: "선택…",
|
|
346
|
+
addOne: "추가…",
|
|
316
347
|
},
|
|
317
348
|
frameUnavailable: "지금은 표시할 수 없습니다.",
|
|
318
349
|
capability: {
|
|
@@ -322,6 +353,15 @@ export const ko: Messages = {
|
|
|
322
353
|
name: "모든 사람 읽기",
|
|
323
354
|
opens: "워크스페이스의 모든 사람을 읽습니다. 예약 실행과 훅에서도.",
|
|
324
355
|
},
|
|
356
|
+
"people:read:email": {
|
|
357
|
+
name: "업무 이메일",
|
|
358
|
+
opens: "읽을 수 있는 사람의 업무 이메일을 읽습니다. 다른 서비스의 계정과 맞추는 데 씁니다.",
|
|
359
|
+
},
|
|
360
|
+
"people:act": {
|
|
361
|
+
name: "사람 대신 실행",
|
|
362
|
+
opens:
|
|
363
|
+
"다른 곳에서 한 일을 그 사람 대신 실행하고 결정에 답합니다. 그 사람이 할 수 있는 범위 안에서, 플러그인을 거친 것으로 기록됩니다.",
|
|
364
|
+
},
|
|
325
365
|
"projects:read": {
|
|
326
366
|
name: "프로젝트 읽기",
|
|
327
367
|
opens: "보는 사람이 볼 수 있는 프로젝트와 멤버를 읽습니다.",
|
|
@@ -516,7 +556,7 @@ export const ko: Messages = {
|
|
|
516
556
|
filters: {
|
|
517
557
|
aria: "보드 좁혀 보기",
|
|
518
558
|
words: "제목, 번호, 사람",
|
|
519
|
-
everyone: "
|
|
559
|
+
everyone: "모든 사람",
|
|
520
560
|
mine: "내 작업",
|
|
521
561
|
anyCategory: "모든 카테고리",
|
|
522
562
|
noCategory: "카테고리 없음",
|
|
@@ -874,8 +914,13 @@ export const ko: Messages = {
|
|
|
874
914
|
console: "콘솔",
|
|
875
915
|
as: (agent) => `${agent}(으)로`,
|
|
876
916
|
asTitle: "그 사람이 사용한 에이전트",
|
|
917
|
+
via: (plugin) => `${plugin} 플러그인을 통해`,
|
|
918
|
+
viaTitle: "그 사람 대신 실행한 플러그인",
|
|
919
|
+
thePlugin: (plugin) => `플러그인 ${plugin}`,
|
|
877
920
|
aTask: "작업",
|
|
878
921
|
aPlugin: "플러그인",
|
|
922
|
+
aTeam: "팀",
|
|
923
|
+
theTeam: (team) => `팀 ${team}`,
|
|
879
924
|
throughPlugin: (plugin) => `플러그인 ${plugin}을(를) 통해`,
|
|
880
925
|
everyone: "모든 구성원",
|
|
881
926
|
membersOf: (project) => `${project}의 구성원`,
|
|
@@ -932,6 +977,13 @@ export const ko: Messages = {
|
|
|
932
977
|
personReactivated: (login) => `${login}을(를) 다시 활성화했습니다`,
|
|
933
978
|
managerChanged: (login, manager) => `${login}의 매니저를 ${manager}(으)로 지정했습니다`,
|
|
934
979
|
managerCleared: (login) => `${login}의 매니저 지정을 해제했습니다`,
|
|
980
|
+
emailChanged: (login) => `${login}의 업무 이메일을 바꿨습니다`,
|
|
981
|
+
emailCleared: (login) => `${login}의 업무 이메일을 지웠습니다`,
|
|
982
|
+
teamCreated: (team) => `팀 ${team}을(를) 만들었습니다`,
|
|
983
|
+
teamRenamed: (from, team) => `팀 ${from}의 이름을 ${team}(으)로 바꿨습니다`,
|
|
984
|
+
teamRemoved: (team) => `팀 ${team}을(를) 삭제했습니다`,
|
|
985
|
+
teamMemberAdded: (login, team) => `${login}을(를) 팀 ${team}에 추가했습니다`,
|
|
986
|
+
teamMemberRemoved: (login, team) => `${login}을(를) 팀 ${team}에서 뺐습니다`,
|
|
935
987
|
projectCreated: (project) => `프로젝트 ${project}을(를) 만들었습니다`,
|
|
936
988
|
projectUpdated: (fields, project) => `프로젝트 ${project}의 ${fields}을(를) 바꿨습니다`,
|
|
937
989
|
memberAdded: (login, project, role) =>
|
|
@@ -973,6 +1025,8 @@ export const ko: Messages = {
|
|
|
973
1025
|
pluginDisabled: (plugin) => `플러그인 ${plugin}을(를) 비활성화했습니다`,
|
|
974
1026
|
pluginConsented: (plugin) => `플러그인 ${plugin}의 권한을 바꿨습니다`,
|
|
975
1027
|
pluginConfigured: (fields, plugin) => `플러그인 ${plugin}의 ${fields}을(를) 바꿨습니다`,
|
|
1028
|
+
pluginSealed: (fields, plugin, host) =>
|
|
1029
|
+
`플러그인 ${plugin}의 ${fields}을(를) ${host}에서 받아 저장했습니다`,
|
|
976
1030
|
pluginGranted: (role, who, plugin) =>
|
|
977
1031
|
`${who}에게 플러그인 ${plugin}의 ${role} 역할을 부여했습니다`,
|
|
978
1032
|
pluginRevoked: (role, who, plugin) =>
|
|
@@ -1164,7 +1218,17 @@ export const ko: Messages = {
|
|
|
1164
1218
|
role: "역할",
|
|
1165
1219
|
manager: "매니저",
|
|
1166
1220
|
managerOf: (name) => `${name}의 매니저`,
|
|
1167
|
-
|
|
1221
|
+
email: "업무 이메일",
|
|
1222
|
+
emailOf: (name) => `${name}의 업무 이메일`,
|
|
1223
|
+
emailHint:
|
|
1224
|
+
"Google 로그인은 로그인 주소가 들어오고, 그 밖은 여기서 적습니다. 관리자, 본인, 권한 있는 플러그인만 읽습니다.",
|
|
1225
|
+
team: "직속 구성원",
|
|
1226
|
+
teams: "팀",
|
|
1227
|
+
joinTeam: "팀 추가…",
|
|
1228
|
+
joinTeamOf: (name) => `${name}을(를) 추가할 팀`,
|
|
1229
|
+
leaveTeam: (name, team) => `${team}에서 ${name} 빼기`,
|
|
1230
|
+
howMany: (count) => `${count}명`,
|
|
1231
|
+
views: { aria: "사람과 팀", people: "사람", teams: "팀" },
|
|
1168
1232
|
nobody: "없음",
|
|
1169
1233
|
letIn: "사람 추가",
|
|
1170
1234
|
letInAria: "사람 추가",
|
|
@@ -1213,6 +1277,34 @@ export const ko: Messages = {
|
|
|
1213
1277
|
},
|
|
1214
1278
|
},
|
|
1215
1279
|
|
|
1280
|
+
teams: {
|
|
1281
|
+
list: "팀",
|
|
1282
|
+
none: {
|
|
1283
|
+
title: "아직 팀이 없습니다",
|
|
1284
|
+
body: "팀은 사람들을 한 이름으로 묶습니다. 플러그인은 팀 이름으로 사람을 찾고, 팀에 준 플러그인 역할은 그 팀의 모든 사람이 갖습니다.",
|
|
1285
|
+
},
|
|
1286
|
+
members: (count) => `${count}명`,
|
|
1287
|
+
nobody: "아직 아무도 없습니다.",
|
|
1288
|
+
nameOf: (team) => `팀 ${team}의 이름`,
|
|
1289
|
+
keyTitle: "팀의 키: 부여, 플러그인, 명령이 팀을 부르는 이름이며 바뀌지 않습니다.",
|
|
1290
|
+
addMember: "사람 추가…",
|
|
1291
|
+
addMemberTo: (team) => `${team}에 추가할 사람`,
|
|
1292
|
+
removeMember: (name, team) => `${team}에서 ${name} 빼기`,
|
|
1293
|
+
remove: "팀 삭제",
|
|
1294
|
+
removeAsk: (team) =>
|
|
1295
|
+
`팀 ${team}을(를) 삭제할까요? 이 팀에 준 플러그인 역할도 함께 사라지고, 사람들은 그대로 남습니다.`,
|
|
1296
|
+
newTeam: "새 팀",
|
|
1297
|
+
newAria: "새 팀",
|
|
1298
|
+
form: {
|
|
1299
|
+
name: "팀 이름",
|
|
1300
|
+
key: "키",
|
|
1301
|
+
keyHint:
|
|
1302
|
+
"소문자, 숫자, 하이픈. 부여, 플러그인, 명령이 팀을 부르는 이름입니다. 다른 팀이나 프로젝트와 겹칠 수 없고 바뀌지 않습니다.",
|
|
1303
|
+
hint: "이름은 사람이 읽는 것이라 바꿀 수 있고, 키는 바뀌지 않습니다. 사람은 팀을 만든 뒤 팀 카드에서 추가합니다.",
|
|
1304
|
+
submit: "팀 만들기",
|
|
1305
|
+
},
|
|
1306
|
+
},
|
|
1307
|
+
|
|
1216
1308
|
agents: {
|
|
1217
1309
|
title: "에이전트",
|
|
1218
1310
|
makeByHand: "토큰 직접 만들기",
|
package/src/index.ts
CHANGED
|
@@ -109,6 +109,10 @@ export {
|
|
|
109
109
|
type ListingFormProps,
|
|
110
110
|
PeopleList,
|
|
111
111
|
type PeopleListProps,
|
|
112
|
+
TeamForm,
|
|
113
|
+
type TeamFormProps,
|
|
114
|
+
TeamList,
|
|
115
|
+
type TeamListProps,
|
|
112
116
|
} from "./components/people.js";
|
|
113
117
|
export {
|
|
114
118
|
PICKER_PAGE_LIMIT,
|
|
@@ -178,6 +182,12 @@ export {
|
|
|
178
182
|
type RunListProps,
|
|
179
183
|
RunStatusBadge,
|
|
180
184
|
} from "./components/runs.js";
|
|
185
|
+
export {
|
|
186
|
+
goalsSearch,
|
|
187
|
+
listSearch,
|
|
188
|
+
peopleSearch,
|
|
189
|
+
projectsSearch,
|
|
190
|
+
} from "./components/searches.js";
|
|
181
191
|
export {
|
|
182
192
|
type Brand,
|
|
183
193
|
isPlainClick,
|
|
@@ -212,6 +222,7 @@ export {
|
|
|
212
222
|
Button,
|
|
213
223
|
Callout,
|
|
214
224
|
CategoryBadge,
|
|
225
|
+
Chip,
|
|
215
226
|
CopyButton,
|
|
216
227
|
cx,
|
|
217
228
|
Day,
|
package/src/limits.ts
CHANGED
|
@@ -48,6 +48,12 @@ export const MAX_FILE_NAME_LENGTH = 200;
|
|
|
48
48
|
export const MAX_TOKEN_NAME_LENGTH = 80;
|
|
49
49
|
/** A login at a git host, or an address at a Workspace, as an administrator lists one. */
|
|
50
50
|
export const MAX_LOGIN_LENGTH = 254;
|
|
51
|
+
/** A team's name (ADR-0073). */
|
|
52
|
+
export const MAX_TEAM_NAME_LENGTH = 60;
|
|
53
|
+
/** A team's key (ADR-0074), as long as a project's may be: the two are one set of names. */
|
|
54
|
+
export const MAX_TEAM_KEY_LENGTH = 40;
|
|
55
|
+
/** How many teams one workspace may hold. */
|
|
56
|
+
export const MAX_TEAMS = 200;
|
|
51
57
|
/** How long a token may be good for, in days, and how long one is when nothing is said. */
|
|
52
58
|
export const MAX_TOKEN_DAYS = 365;
|
|
53
59
|
export const DEFAULT_TOKEN_DAYS = 90;
|
package/src/plugin/args.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// crosses from the plugin's thread to the console is exactly that object.
|
|
5
5
|
import { PluginDefinitionError } from "./definition-error.js";
|
|
6
6
|
import { MAX_PLUGIN_ABOUT_LENGTH, MAX_PLUGIN_OPTIONS } from "./limits.js";
|
|
7
|
-
import { PLUGIN_KEY_PATTERN } from "./manifest.js";
|
|
7
|
+
import { isCalendarDay, PLUGIN_KEY_PATTERN } from "./manifest.js";
|
|
8
8
|
|
|
9
9
|
export const ARG_TYPES = [
|
|
10
10
|
"text",
|
|
@@ -269,7 +269,6 @@ export const arg = {
|
|
|
269
269
|
},
|
|
270
270
|
};
|
|
271
271
|
|
|
272
|
-
const DAY = /^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$/;
|
|
273
272
|
const DEFAULT_TEXT_MAX = 2000;
|
|
274
273
|
const DEFAULT_MARKDOWN_MAX = 20_000;
|
|
275
274
|
const DEFAULT_LIST_MAX = 100;
|
|
@@ -304,9 +303,8 @@ export function argProblem(
|
|
|
304
303
|
return undefined;
|
|
305
304
|
}
|
|
306
305
|
case "day":
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
: `${name} is not a day as YYYY-MM-DD`;
|
|
306
|
+
// The shape, and the calendar: February 30 fits the shape and is no day.
|
|
307
|
+
return isCalendarDay(value) ? undefined : `${name} is not a day as YYYY-MM-DD`;
|
|
310
308
|
case "number": {
|
|
311
309
|
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
312
310
|
return `${name} is not a number`;
|
|
@@ -512,15 +510,22 @@ export function parseArgv(
|
|
|
512
510
|
return { values };
|
|
513
511
|
}
|
|
514
512
|
|
|
515
|
-
/**
|
|
513
|
+
/**
|
|
514
|
+
* The usage of an argument, as help prints it: `<from>` for a positional, `--to <day>` for a
|
|
515
|
+
* flag, in brackets where optional; a file as `--file <path>`, the flag the command itself takes,
|
|
516
|
+
* since the command uploads the file first and hands the plugin a handle, never a flag of the
|
|
517
|
+
* argument's name.
|
|
518
|
+
*/
|
|
516
519
|
export function argUsage(name: string, description: ArgDescription): string {
|
|
517
520
|
const placeholder =
|
|
518
521
|
description.type === "list" ? `${description.of?.type ?? "item"},...` : description.type;
|
|
519
522
|
const form =
|
|
520
|
-
description.type === "
|
|
521
|
-
?
|
|
522
|
-
: description.positional
|
|
523
|
-
?
|
|
524
|
-
:
|
|
523
|
+
description.type === "file"
|
|
524
|
+
? "--file <path>"
|
|
525
|
+
: description.type === "boolean" && !description.positional
|
|
526
|
+
? `--${name}`
|
|
527
|
+
: description.positional
|
|
528
|
+
? `<${name}>`
|
|
529
|
+
: `--${name} <${placeholder}>`;
|
|
525
530
|
return description.optional ? `[${form}]` : form;
|
|
526
531
|
}
|