@antasphere/chassis-cli 0.0.0-stage → 1.0.0
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/LICENSE +82 -0
- package/dist/commands/auth.d.ts +6 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +582 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/completion.d.ts +5 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +85 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/demo.d.ts +12 -0
- package/dist/commands/demo.d.ts.map +1 -0
- package/dist/commands/demo.js +210 -0
- package/dist/commands/demo.js.map +1 -0
- package/dist/commands/files.d.ts +21 -0
- package/dist/commands/files.d.ts.map +1 -0
- package/dist/commands/files.js +178 -0
- package/dist/commands/files.js.map +1 -0
- package/dist/commands/projects.d.ts +38 -0
- package/dist/commands/projects.d.ts.map +1 -0
- package/dist/commands/projects.js +386 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/teams.d.ts +46 -0
- package/dist/commands/teams.d.ts.map +1 -0
- package/dist/commands/teams.js +265 -0
- package/dist/commands/teams.js.map +1 -0
- package/dist/commands/workspaces.d.ts +22 -0
- package/dist/commands/workspaces.d.ts.map +1 -0
- package/dist/commands/workspaces.js +116 -0
- package/dist/commands/workspaces.js.map +1 -0
- package/dist/config.d.ts +29 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +54 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +152 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +456 -0
- package/dist/context.js.map +1 -0
- package/dist/identity.d.ts +36 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +18 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/kit.d.ts +46 -0
- package/dist/kit.d.ts.map +1 -0
- package/dist/kit.js +2 -0
- package/dist/kit.js.map +1 -0
- package/dist/open.d.ts +27 -0
- package/dist/open.d.ts.map +1 -0
- package/dist/open.js +45 -0
- package/dist/open.js.map +1 -0
- package/dist/owner-session.d.ts +34 -0
- package/dist/owner-session.d.ts.map +1 -0
- package/dist/owner-session.js +106 -0
- package/dist/owner-session.js.map +1 -0
- package/dist/program.d.ts +5 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +150 -0
- package/dist/program.js.map +1 -0
- package/dist/safe-write.d.ts +46 -0
- package/dist/safe-write.d.ts.map +1 -0
- package/dist/safe-write.js +127 -0
- package/dist/safe-write.js.map +1 -0
- package/dist/stdin.d.ts +4 -0
- package/dist/stdin.d.ts.map +1 -0
- package/dist/stdin.js +36 -0
- package/dist/stdin.js.map +1 -0
- package/dist/testing/index.d.ts +70 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +67 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/workspace.d.ts +79 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +139 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +43 -3
- package/src/commands/auth.ts +687 -0
- package/src/commands/completion.ts +102 -0
- package/src/commands/demo.ts +271 -0
- package/src/commands/files.ts +197 -0
- package/src/commands/projects.ts +460 -0
- package/src/commands/teams.ts +320 -0
- package/src/commands/workspaces.ts +140 -0
- package/src/config.ts +81 -0
- package/src/context.ts +616 -0
- package/src/identity.ts +48 -0
- package/src/index.ts +70 -0
- package/src/kit.ts +50 -0
- package/src/open.ts +48 -0
- package/src/owner-session.ts +152 -0
- package/src/program.ts +183 -0
- package/src/safe-write.ts +136 -0
- package/src/stdin.ts +39 -0
- package/src/testing/index.ts +129 -0
- package/src/workspace.ts +229 -0
- package/test/host/identity.test.ts +229 -0
- package/test/host/minimal-host.ts +16 -0
- package/test/host/minimal-tool.ts +40 -0
- package/test/suite/cli.test.ts +301 -0
- package/test/suite/config.test.ts +59 -0
- package/test/suite/demo.test.ts +467 -0
- package/test/suite/hub-profile-shared.test.ts +123 -0
- package/test/suite/login.test.ts +743 -0
- package/test/suite/logout.test.ts +247 -0
- package/test/suite/migration.test.ts +109 -0
- package/test/suite/open.test.ts +59 -0
- package/test/suite/profiles.test.ts +380 -0
- package/test/suite/projects.test.ts +550 -0
- package/test/suite/recovery.test.ts +348 -0
- package/test/suite/security.test.ts +199 -0
- package/test/suite/signin-fixtures.ts +204 -0
- package/test/suite/teams.test.ts +354 -0
- package/test/suite/whoami.test.ts +159 -0
- package/test/suite/workspace.test.ts +402 -0
- package/README.md +0 -3
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ToolIdentity } from '@antasphere/chassis-contract';
|
|
2
|
+
/**
|
|
3
|
+
* What a tool is called, in every place the generic CLI spells it. ONE object,
|
|
4
|
+
* passed by the tool to `defineCli` (index.ts): the chassis holds no product
|
|
5
|
+
* literal of its own, so each field below is read where the literal used to
|
|
6
|
+
* sit and the bytes a person or a script sees are the tool's own.
|
|
7
|
+
*/
|
|
8
|
+
export interface CliIdentity {
|
|
9
|
+
/** The binary's name: `program.name()`, and every `\`<bin> …\`` hint. */
|
|
10
|
+
bin: string;
|
|
11
|
+
/** The tool's namespace in the shared config home, and its cli-core connect name. */
|
|
12
|
+
tool: string;
|
|
13
|
+
/** The pre-cli-core config directory (`$XDG_CONFIG_HOME/<dir>/config.json`), imported once. */
|
|
14
|
+
legacyConfigDir: string;
|
|
15
|
+
/** The product's name in a sentence. */
|
|
16
|
+
displayName: string;
|
|
17
|
+
/** The environment variables' prefix: `<PREFIX>_URL`, `<PREFIX>_API_KEY`, `<PREFIX>_WORKSPACE`. */
|
|
18
|
+
envPrefix: string;
|
|
19
|
+
/** The API key prefix, without the underscore: `<prefix>_…`. */
|
|
20
|
+
keyPrefix: string;
|
|
21
|
+
/** The scope a key needs for the full-workspace export, as `export --help` names it. */
|
|
22
|
+
exportScope: string;
|
|
23
|
+
/**
|
|
24
|
+
* The tool's cloud home (`identity.cloud.url`): the last step of the URL
|
|
25
|
+
* resolution and the instance of the implicit `cloud` profile, so a clean
|
|
26
|
+
* machine with an `antasphere login` needs no flag (PRDCT-2947).
|
|
27
|
+
*/
|
|
28
|
+
cloudUrl: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The CLI's identity, BUILT from the tool's one definition (`ToolIdentity`,
|
|
32
|
+
* written in the tool's contract package): a tool passes
|
|
33
|
+
* `cliIdentity(IDENTITY)` to `defineCli` and spells nothing a second time.
|
|
34
|
+
*/
|
|
35
|
+
export declare function cliIdentity(identity: ToolIdentity): CliIdentity;
|
|
36
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,yEAAyE;IACzE,GAAG,EAAE,MAAM,CAAC;IACZ,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;IACb,+FAA+F;IAC/F,eAAe,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,mGAAmG;IACnG,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,YAAY,GAAG,WAAW,CAW/D"}
|
package/dist/identity.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CLI's identity, BUILT from the tool's one definition (`ToolIdentity`,
|
|
3
|
+
* written in the tool's contract package): a tool passes
|
|
4
|
+
* `cliIdentity(IDENTITY)` to `defineCli` and spells nothing a second time.
|
|
5
|
+
*/
|
|
6
|
+
export function cliIdentity(identity) {
|
|
7
|
+
return {
|
|
8
|
+
bin: identity.cli.bin,
|
|
9
|
+
tool: identity.slug,
|
|
10
|
+
legacyConfigDir: identity.cli.legacyConfigDir,
|
|
11
|
+
displayName: identity.displayName,
|
|
12
|
+
envPrefix: identity.cli.envPrefix,
|
|
13
|
+
keyPrefix: identity.apiKeyPrefix,
|
|
14
|
+
exportScope: identity.scopes.dataExport,
|
|
15
|
+
cloudUrl: identity.cloud.url
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AA+BA;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,QAAsB;IAChD,OAAO;QACL,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG;QACrB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,eAAe,EAAE,QAAQ,CAAC,GAAG,CAAC,eAAe;QAC7C,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,SAAS;QACjC,SAAS,EAAE,QAAQ,CAAC,YAAY;QAChC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU;QACvC,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG;KAC7B,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ChassisClient } from '@antasphere/chassis-sdk';
|
|
2
|
+
import type { Cli, CliDefinition } from './kit.js';
|
|
3
|
+
/**
|
|
4
|
+
* `@antasphere/chassis-cli`: the generic half of a tool's command line. The
|
|
5
|
+
* profiles and the config file, the context (instance, key, workspace), the
|
|
6
|
+
* workspace selection, secrets on stdin, the contained writes, the browser
|
|
7
|
+
* opener, the generic command groups, the program and the runner. A tool
|
|
8
|
+
* instantiates it ONCE (`defineCli`) with its identity and its client, and
|
|
9
|
+
* its command modules read the kit that comes back.
|
|
10
|
+
*/
|
|
11
|
+
export { cliIdentity, type CliIdentity } from './identity.js';
|
|
12
|
+
export { redactKey, type CliConfigStore } from './config.js';
|
|
13
|
+
export type { CliConfig, CliConnectKey, CliEnv, CliProfile } from './config.js';
|
|
14
|
+
export { CliUsageError, fmtBytes, printJson, sanitizeForTty, setStdinApiKey, stdinApiKey, table, ttySafeIo, type CliContext, type CliContextKit, type CliIo, type CredentialSource } from './context.js';
|
|
15
|
+
export { findWorkspace, isWorkspaceId, matchWorkspace, workspaceLines, type CliWorkspace, type MeResponse, type MeWorkspace, type SelectionKind, type WorkspaceSelection, type WorkspaceSource } from './workspace.js';
|
|
16
|
+
export { readSecretFromStdin } from './stdin.js';
|
|
17
|
+
export { resolveInside, streamContained, UnsafeWriteError, writeContained, writeNoFollow } from './safe-write.js';
|
|
18
|
+
export { isInteractive, openInBrowser, platformOpener } from './open.js';
|
|
19
|
+
export { safeDownloadName } from './commands/files.js';
|
|
20
|
+
export { explainProjectRefusal, roleNamedBy, memberRef, type ProjectLookup } from './commands/projects.js';
|
|
21
|
+
export { CliApiRefusal, drainPages } from './context.js';
|
|
22
|
+
export type { Cli, CliDefinition, CliKit, RegisterTool } from './kit.js';
|
|
23
|
+
export declare function defineCli<TClient extends ChassisClient<string>>(definition: CliDefinition<TClient>): Cli<TClient>;
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D,OAAO,KAAK,EAAE,GAAG,EAAE,aAAa,EAAU,MAAM,UAAU,CAAC;AAI3D;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,EACL,aAAa,EACb,QAAQ,EACR,SAAS,EACT,cAAc,EACd,cAAc,EACd,WAAW,EACX,KAAK,EACL,SAAS,EACT,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,KAAK,gBAAgB,EACtB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EACL,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,aAAa,EACd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC3G,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACzD,YAAY,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEzE,wBAAgB,SAAS,CAAC,OAAO,SAAS,aAAa,CAAC,MAAM,CAAC,EAC7D,UAAU,EAAE,aAAa,CAAC,OAAO,CAAC,GACjC,GAAG,CAAC,OAAO,CAAC,CAOd"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createConfig } from './config.js';
|
|
2
|
+
import { createContext } from './context.js';
|
|
3
|
+
import { createProgram } from './program.js';
|
|
4
|
+
import { createWorkspace } from './workspace.js';
|
|
5
|
+
/**
|
|
6
|
+
* `@antasphere/chassis-cli`: the generic half of a tool's command line. The
|
|
7
|
+
* profiles and the config file, the context (instance, key, workspace), the
|
|
8
|
+
* workspace selection, secrets on stdin, the contained writes, the browser
|
|
9
|
+
* opener, the generic command groups, the program and the runner. A tool
|
|
10
|
+
* instantiates it ONCE (`defineCli`) with its identity and its client, and
|
|
11
|
+
* its command modules read the kit that comes back.
|
|
12
|
+
*/
|
|
13
|
+
export { cliIdentity } from './identity.js';
|
|
14
|
+
export { redactKey } from './config.js';
|
|
15
|
+
export { CliUsageError, fmtBytes, printJson, sanitizeForTty, setStdinApiKey, stdinApiKey, table, ttySafeIo } from './context.js';
|
|
16
|
+
export { findWorkspace, isWorkspaceId, matchWorkspace, workspaceLines } from './workspace.js';
|
|
17
|
+
export { readSecretFromStdin } from './stdin.js';
|
|
18
|
+
export { resolveInside, streamContained, UnsafeWriteError, writeContained, writeNoFollow } from './safe-write.js';
|
|
19
|
+
export { isInteractive, openInBrowser, platformOpener } from './open.js';
|
|
20
|
+
export { safeDownloadName } from './commands/files.js';
|
|
21
|
+
export { explainProjectRefusal, roleNamedBy, memberRef } from './commands/projects.js';
|
|
22
|
+
export { CliApiRefusal, drainPages } from './context.js';
|
|
23
|
+
export function defineCli(definition) {
|
|
24
|
+
const { identity, createClient } = definition;
|
|
25
|
+
const config = createConfig(identity);
|
|
26
|
+
const workspace = createWorkspace(identity);
|
|
27
|
+
const context = createContext({ identity, createClient, config, workspace });
|
|
28
|
+
const kit = { identity, createClient, ...config, workspace, ...context };
|
|
29
|
+
return { ...kit, ...createProgram(kit, definition) };
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAoB,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAuB,MAAM,aAAa,CAAC;AAE7D,OAAO,EACL,aAAa,EACb,QAAQ,EACR,SAAS,EACT,cAAc,EACd,cAAc,EACd,WAAW,EACX,KAAK,EACL,SAAS,EAKV,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EAOf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EACL,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,aAAa,EACd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,SAAS,EAAsB,MAAM,wBAAwB,CAAC;AAC3G,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAGzD,MAAM,UAAU,SAAS,CACvB,UAAkC;IAElC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,UAAU,CAAC;IAC9C,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7E,MAAM,GAAG,GAAoB,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,EAAE,CAAC;IAC1F,OAAO,EAAE,GAAG,GAAG,EAAE,GAAG,aAAa,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,CAAC;AACvD,CAAC"}
|
package/dist/kit.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { CliAuthError } from '@antasphere/cli-core';
|
|
2
|
+
import type { ChassisClient, ClientOptions, PlatformApiError } from '@antasphere/chassis-sdk';
|
|
3
|
+
import type { Command } from 'commander';
|
|
4
|
+
import type { CliConfigStore } from './config.js';
|
|
5
|
+
import type { CliContextKit, CliIo } from './context.js';
|
|
6
|
+
import type { CliIdentity } from './identity.js';
|
|
7
|
+
import type { CliWorkspace } from './workspace.js';
|
|
8
|
+
/** The tool's hook in the command tree: it registers its own groups on the program. */
|
|
9
|
+
export type RegisterTool = (program: Command, io: CliIo) => void;
|
|
10
|
+
export interface CliDefinition<TClient extends ChassisClient<string>> {
|
|
11
|
+
/** What the tool is called, everywhere the generic CLI spells it (identity.ts). */
|
|
12
|
+
identity: CliIdentity;
|
|
13
|
+
/** The program's one-line description (`--help`'s first line after the usage). */
|
|
14
|
+
description: string;
|
|
15
|
+
/** The tool's client: every place the generic CLI builds one goes through this. */
|
|
16
|
+
createClient: (options: ClientOptions) => TClient;
|
|
17
|
+
/**
|
|
18
|
+
* The tool's own hint for a refused request, as it is appended to the error
|
|
19
|
+
* line (leading space and parentheses included), or undefined for none. The
|
|
20
|
+
* runner asks after the 403 hint and before the 401 one.
|
|
21
|
+
*/
|
|
22
|
+
errorHint?: (e: PlatformApiError | CliAuthError) => string | undefined;
|
|
23
|
+
}
|
|
24
|
+
/** The generic functions bound to one tool, as the command modules read them. */
|
|
25
|
+
export interface CliKit<TClient extends ChassisClient<string>> extends CliConfigStore, CliContextKit<TClient> {
|
|
26
|
+
identity: CliIdentity;
|
|
27
|
+
createClient: (options: ClientOptions) => TClient;
|
|
28
|
+
/** The workspace functions that spell the tool (workspace.ts). */
|
|
29
|
+
workspace: CliWorkspace;
|
|
30
|
+
}
|
|
31
|
+
/** What `defineCli` hands back: the kit, plus the program and the runner. */
|
|
32
|
+
export interface Cli<TClient extends ChassisClient<string>> extends CliKit<TClient> {
|
|
33
|
+
/**
|
|
34
|
+
* The command tree, built once per run: the global options, the auth,
|
|
35
|
+
* workspace, project and demo groups, THE TOOL'S GROUPS, then
|
|
36
|
+
* instance/export/files, and the completion command last (it prints the
|
|
37
|
+
* tree, so it must see all of it).
|
|
38
|
+
*/
|
|
39
|
+
buildProgram(io: CliIo, registerTool: RegisterTool, version: string): Command;
|
|
40
|
+
/**
|
|
41
|
+
* Run the CLI with injected I/O and return a process exit code. The bin calls
|
|
42
|
+
* this with real process streams; tests call it in-process.
|
|
43
|
+
*/
|
|
44
|
+
run(argv: string[], rawIo: CliIo, registerTool: RegisterTool, version: string): Promise<number>;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=kit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kit.d.ts","sourceRoot":"","sources":["../src/kit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC9F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,uFAAuF;AACvF,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,KAAK,IAAI,CAAC;AAEjE,MAAM,WAAW,aAAa,CAAC,OAAO,SAAS,aAAa,CAAC,MAAM,CAAC;IAClE,mFAAmF;IACnF,QAAQ,EAAE,WAAW,CAAC;IACtB,kFAAkF;IAClF,WAAW,EAAE,MAAM,CAAC;IACpB,mFAAmF;IACnF,YAAY,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC;IAClD;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,gBAAgB,GAAG,YAAY,KAAK,MAAM,GAAG,SAAS,CAAC;CACxE;AAED,iFAAiF;AACjF,MAAM,WAAW,MAAM,CAAC,OAAO,SAAS,aAAa,CAAC,MAAM,CAAC,CAC3D,SAAQ,cAAc,EAAE,aAAa,CAAC,OAAO,CAAC;IAC9C,QAAQ,EAAE,WAAW,CAAC;IACtB,YAAY,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC;IAClD,kEAAkE;IAClE,SAAS,EAAE,YAAY,CAAC;CACzB;AAED,6EAA6E;AAC7E,MAAM,WAAW,GAAG,CAAC,OAAO,SAAS,aAAa,CAAC,MAAM,CAAC,CAAE,SAAQ,MAAM,CAAC,OAAO,CAAC;IACjF;;;;;OAKG;IACH,YAAY,CAAC,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9E;;;OAGG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACjG"}
|
package/dist/kit.js
ADDED
package/dist/kit.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kit.js","sourceRoot":"","sources":["../src/kit.ts"],"names":[],"mappings":""}
|
package/dist/open.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import type { CliIo } from './context.js';
|
|
3
|
+
/**
|
|
4
|
+
* Opening a URL in the person's default browser (PRDCT-2280): the first push
|
|
5
|
+
* of a folder opens the pushed resource's page, the tool's `open` command opens
|
|
6
|
+
* it on demand, its `dev` command opens the local preview.
|
|
7
|
+
*
|
|
8
|
+
* The URL is always ONE argv item handed to the platform's opener binary,
|
|
9
|
+
* never a string a shell interprets: a resource title or an instance URL is
|
|
10
|
+
* somebody else's text, and `sh -c "open $url"` would run whatever it
|
|
11
|
+
* carries. On Windows `start` is a cmd.exe builtin that `spawn` cannot run
|
|
12
|
+
* without a shell, so the URL handler is invoked through `rundll32`
|
|
13
|
+
* instead, which is a real executable taking the URL as an argument.
|
|
14
|
+
*/
|
|
15
|
+
export declare function platformOpener(platform?: NodeJS.Platform): {
|
|
16
|
+
command: string;
|
|
17
|
+
args: string[];
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Best effort: a missing opener (a headless box) must never fail the
|
|
21
|
+
* command that already did its real work. The runner can inject `io.openUrl`
|
|
22
|
+
* (tests record the call; nothing is spawned).
|
|
23
|
+
*/
|
|
24
|
+
export declare function openInBrowser(io: CliIo, url: string, spawnImpl?: typeof spawn): void;
|
|
25
|
+
/** A stdout that is a terminal: the only place a browser may pop up unasked. */
|
|
26
|
+
export declare function isInteractive(io: CliIo): boolean;
|
|
27
|
+
//# sourceMappingURL=open.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../src/open.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG;IAC5E,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,CAIA;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,GAAE,OAAO,KAAa,GAAG,IAAI,CAa3F;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,EAAE,EAAE,KAAK,GAAG,OAAO,CAEhD"}
|
package/dist/open.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
/**
|
|
3
|
+
* Opening a URL in the person's default browser (PRDCT-2280): the first push
|
|
4
|
+
* of a folder opens the pushed resource's page, the tool's `open` command opens
|
|
5
|
+
* it on demand, its `dev` command opens the local preview.
|
|
6
|
+
*
|
|
7
|
+
* The URL is always ONE argv item handed to the platform's opener binary,
|
|
8
|
+
* never a string a shell interprets: a resource title or an instance URL is
|
|
9
|
+
* somebody else's text, and `sh -c "open $url"` would run whatever it
|
|
10
|
+
* carries. On Windows `start` is a cmd.exe builtin that `spawn` cannot run
|
|
11
|
+
* without a shell, so the URL handler is invoked through `rundll32`
|
|
12
|
+
* instead, which is a real executable taking the URL as an argument.
|
|
13
|
+
*/
|
|
14
|
+
export function platformOpener(platform = process.platform) {
|
|
15
|
+
if (platform === 'darwin')
|
|
16
|
+
return { command: 'open', args: [] };
|
|
17
|
+
if (platform === 'win32')
|
|
18
|
+
return { command: 'rundll32', args: ['url.dll,FileProtocolHandler'] };
|
|
19
|
+
return { command: 'xdg-open', args: [] };
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Best effort: a missing opener (a headless box) must never fail the
|
|
23
|
+
* command that already did its real work. The runner can inject `io.openUrl`
|
|
24
|
+
* (tests record the call; nothing is spawned).
|
|
25
|
+
*/
|
|
26
|
+
export function openInBrowser(io, url, spawnImpl = spawn) {
|
|
27
|
+
if (io.openUrl) {
|
|
28
|
+
io.openUrl(url);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const { command, args } = platformOpener();
|
|
32
|
+
try {
|
|
33
|
+
const child = spawnImpl(command, [...args, url], { stdio: 'ignore', detached: true });
|
|
34
|
+
child.on('error', () => undefined);
|
|
35
|
+
child.unref();
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// best-effort
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** A stdout that is a terminal: the only place a browser may pop up unasked. */
|
|
42
|
+
export function isInteractive(io) {
|
|
43
|
+
return io.out.isTTY === true;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=open.js.map
|
package/dist/open.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open.js","sourceRoot":"","sources":["../src/open.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG3C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAAC,WAA4B,OAAO,CAAC,QAAQ;IAIzE,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IAChE,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,6BAA6B,CAAC,EAAE,CAAC;IAChG,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,EAAS,EAAE,GAAW,EAAE,YAA0B,KAAK;IACnF,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QACf,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IACD,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,cAAc,EAAE,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACtF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACnC,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,cAAc;IAChB,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,aAAa,CAAC,EAAS;IACrC,OAAO,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ChassisClient } from '@antasphere/chassis-sdk';
|
|
2
|
+
import { type CliContext } from './context.js';
|
|
3
|
+
import type { CliIdentity } from './identity.js';
|
|
4
|
+
/**
|
|
5
|
+
* A command that acts as a SIGNED-IN OWNER, never with an API key.
|
|
6
|
+
*
|
|
7
|
+
* Some owner acts are refused to every machine credential by design (the
|
|
8
|
+
* demo pass routes: nothing in the scope allowlist opens them, and the
|
|
9
|
+
* handler checks `via === 'session'` again). The CLI reaches them the way a
|
|
10
|
+
* browser does: one password sign-in, the session cookie held in memory for
|
|
11
|
+
* the length of the command, a sign-out when it ends, success or failure.
|
|
12
|
+
*
|
|
13
|
+
* The address comes from `--owner-email` or `<PREFIX>_OWNER_EMAIL`, the
|
|
14
|
+
* password from `<PREFIX>_OWNER_PASSWORD` or, with `--owner-password-stdin`,
|
|
15
|
+
* the first line of stdin. There is no password flag: a value on the command
|
|
16
|
+
* line is visible in `ps` and lands in the shell history. None of the three
|
|
17
|
+
* (address, password, cookie) is ever written to the profile, a file, a log
|
|
18
|
+
* or the terminal: they live in this function's locals and in the one
|
|
19
|
+
* client's header map, and die with the command.
|
|
20
|
+
*/
|
|
21
|
+
export interface OwnerSessionOptions {
|
|
22
|
+
/** The tool's identity: `<PREFIX>_OWNER_EMAIL` / `<PREFIX>_OWNER_PASSWORD` are built from it. */
|
|
23
|
+
identity: Pick<CliIdentity, 'envPrefix'>;
|
|
24
|
+
/** `--owner-email`. */
|
|
25
|
+
ownerEmail?: string;
|
|
26
|
+
/** `--owner-password-stdin`. */
|
|
27
|
+
ownerPasswordStdin?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Sign in as the owner, run `run` with a client that carries the session
|
|
31
|
+
* cookie and the origin (and no authorization header), then sign out.
|
|
32
|
+
*/
|
|
33
|
+
export declare function withOwnerSession<T>(ctx: CliContext, options: OwnerSessionOptions, run: (client: ChassisClient<string>) => Promise<T>): Promise<T>;
|
|
34
|
+
//# sourceMappingURL=owner-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"owner-session.d.ts","sourceRoot":"","sources":["../src/owner-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAsB,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAIjD;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,mBAAmB;IAClC,iGAAiG;IACjG,QAAQ,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACzC,uBAAuB;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAqDD;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,mBAAmB,EAC5B,GAAG,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GACjD,OAAO,CAAC,CAAC,CAAC,CA2DZ"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { ChassisClient, DEFAULT_TIMEOUT_MS } from '@antasphere/chassis-sdk';
|
|
2
|
+
import { CliApiRefusal, CliUsageError } from './context.js';
|
|
3
|
+
import { readSecretFromStdin } from './stdin.js';
|
|
4
|
+
import { isWorkspaceId, matchWorkspace } from './workspace.js';
|
|
5
|
+
/**
|
|
6
|
+
* The sign-in library allows three sign-ins per ten seconds per address, and
|
|
7
|
+
* a script that makes links for several people signs in once per command:
|
|
8
|
+
* the fourth command in a row meets the wall. It is a wall of seconds, so the
|
|
9
|
+
* command waits it out, three times at most, and says so on stderr.
|
|
10
|
+
*/
|
|
11
|
+
const SIGN_IN_WAITS_MS = [4_000, 8_000, 12_000];
|
|
12
|
+
/** The session cookie the sign-in library sets, whatever prefix the instance gives it. */
|
|
13
|
+
const SESSION_COOKIE = /session_token$/;
|
|
14
|
+
/** `name=value` of the session cookie among the answer's `set-cookie` lines, or null. */
|
|
15
|
+
function sessionCookie(res) {
|
|
16
|
+
for (const line of res.headers.getSetCookie()) {
|
|
17
|
+
const pair = line.split(';', 1)[0].trim();
|
|
18
|
+
const eq = pair.indexOf('=');
|
|
19
|
+
if (eq > 0 && SESSION_COOKIE.test(pair.slice(0, eq)))
|
|
20
|
+
return pair;
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
/** The sign-in library's own refusals are `{ code, message }`; the API's are `{ error: {…} }`. */
|
|
25
|
+
async function refusalMessage(res) {
|
|
26
|
+
const body = (await res.json().catch(() => null));
|
|
27
|
+
const message = body?.error?.message ?? body?.message;
|
|
28
|
+
return typeof message === 'string' && message ? message : null;
|
|
29
|
+
}
|
|
30
|
+
async function ownerCredentials(ctx, options) {
|
|
31
|
+
const { envPrefix } = options.identity;
|
|
32
|
+
const emailVar = `${envPrefix}_OWNER_EMAIL`;
|
|
33
|
+
const passwordVar = `${envPrefix}_OWNER_PASSWORD`;
|
|
34
|
+
const email = (options.ownerEmail ?? ctx.io.env[emailVar] ?? '').trim();
|
|
35
|
+
const password = options.ownerPasswordStdin
|
|
36
|
+
? await readSecretFromStdin(ctx.io, 'owner password')
|
|
37
|
+
: (ctx.io.env[passwordVar] ?? '');
|
|
38
|
+
if (!email || !password) {
|
|
39
|
+
throw new CliUsageError(`This command signs in as an owner of the workspace, never with an API key. Set ${emailVar} ` +
|
|
40
|
+
`(or pass --owner-email) and ${passwordVar} (or pipe it with --owner-password-stdin).`);
|
|
41
|
+
}
|
|
42
|
+
return { email, password };
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Sign in as the owner, run `run` with a client that carries the session
|
|
46
|
+
* cookie and the origin (and no authorization header), then sign out.
|
|
47
|
+
*/
|
|
48
|
+
export async function withOwnerSession(ctx, options, run) {
|
|
49
|
+
const base = ctx.baseUrl.replace(/\/+$/, '');
|
|
50
|
+
const origin = new URL(base).origin;
|
|
51
|
+
const fetchImpl = ctx.io.fetch ?? globalThis.fetch.bind(globalThis);
|
|
52
|
+
const { email, password } = await ownerCredentials(ctx, options);
|
|
53
|
+
// The server refuses a sign-in that carries no Origin (the cross-site guard).
|
|
54
|
+
const signIn = () => fetchImpl(`${base}/api/v1/auth/sign-in/email`, {
|
|
55
|
+
method: 'POST',
|
|
56
|
+
headers: { origin, 'content-type': 'application/json' },
|
|
57
|
+
body: JSON.stringify({ email, password }),
|
|
58
|
+
signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS)
|
|
59
|
+
});
|
|
60
|
+
const sleep = ctx.io.sleep ?? ((ms) => new Promise((done) => setTimeout(done, ms)));
|
|
61
|
+
let res = await signIn();
|
|
62
|
+
for (const wait of SIGN_IN_WAITS_MS) {
|
|
63
|
+
if (res.status !== 429)
|
|
64
|
+
break;
|
|
65
|
+
ctx.io.err.write(`The instance limits sign-ins: waiting ${wait / 1000} seconds.\n`);
|
|
66
|
+
await sleep(wait);
|
|
67
|
+
res = await signIn();
|
|
68
|
+
}
|
|
69
|
+
if (res.status === 429) {
|
|
70
|
+
throw new CliApiRefusal('Too many sign-in attempts for now: wait a few minutes, then try again.', 429);
|
|
71
|
+
}
|
|
72
|
+
if (!res.ok) {
|
|
73
|
+
const message = (await refusalMessage(res)) ?? `The sign-in failed (HTTP ${res.status}).`;
|
|
74
|
+
throw new CliApiRefusal(message, res.status);
|
|
75
|
+
}
|
|
76
|
+
const answer = (await res.json().catch(() => null));
|
|
77
|
+
if (answer?.twoFactorRedirect === true) {
|
|
78
|
+
throw new CliUsageError('This owner has a second factor: mint demo links from the dashboard.');
|
|
79
|
+
}
|
|
80
|
+
const cookie = sessionCookie(res);
|
|
81
|
+
if (!cookie)
|
|
82
|
+
throw new CliUsageError('The instance answered the sign-in without a session.');
|
|
83
|
+
const headers = { cookie, origin };
|
|
84
|
+
const client = new ChassisClient({ baseUrl: base, fetch: fetchImpl, headers });
|
|
85
|
+
try {
|
|
86
|
+
// The workspace selection applies here as it does to every command
|
|
87
|
+
// (context.ts `applyWorkspace`): an id as it is, a name through `/me`.
|
|
88
|
+
const selection = ctx.workspaceSelection;
|
|
89
|
+
if (selection) {
|
|
90
|
+
client.setWorkspace(isWorkspaceId(selection.value)
|
|
91
|
+
? selection.value
|
|
92
|
+
: matchWorkspace((await client.me()).workspaces, selection.value).id);
|
|
93
|
+
}
|
|
94
|
+
return await run(client);
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
// The session ends with the command; its outcome changes nothing.
|
|
98
|
+
await fetchImpl(`${base}/api/v1/auth/sign-out`, {
|
|
99
|
+
method: 'POST',
|
|
100
|
+
headers: { ...headers, 'content-type': 'application/json' },
|
|
101
|
+
body: '{}',
|
|
102
|
+
signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS)
|
|
103
|
+
}).catch(() => undefined);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=owner-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"owner-session.js","sourceRoot":"","sources":["../src/owner-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type ChassisClient } from '@antasphere/chassis-sdk';
|
|
2
|
+
import type { Cli, CliDefinition, CliKit } from './kit.js';
|
|
3
|
+
/** The program and the runner of one tool, over its kit (kit.ts). */
|
|
4
|
+
export declare function createProgram<TClient extends ChassisClient<string>>(kit: CliKit<TClient>, definition: Pick<CliDefinition<TClient>, 'description' | 'errorHint'>): Pick<Cli<TClient>, 'buildProgram' | 'run'>;
|
|
5
|
+
//# sourceMappingURL=program.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE/E,OAAO,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,EAAgB,MAAM,UAAU,CAAC;AAmBzE,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,OAAO,SAAS,aAAa,CAAC,MAAM,CAAC,EACjE,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,EACpB,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,WAAW,CAAC,GACpE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,KAAK,CAAC,CA2J5C"}
|
package/dist/program.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { Command, CommanderError } from 'commander';
|
|
2
|
+
import { CliAuthError, CliConnectError } from '@antasphere/cli-core';
|
|
3
|
+
import { PlatformApiError } from '@antasphere/chassis-sdk';
|
|
4
|
+
import { CliApiRefusal, CliUsageError, setStdinApiKey, ttySafeIo } from './context.js';
|
|
5
|
+
import { readSecretFromStdin } from './stdin.js';
|
|
6
|
+
import { registerAuthCommands } from './commands/auth.js';
|
|
7
|
+
import { registerWorkspaceCommands } from './commands/workspaces.js';
|
|
8
|
+
import { registerProjectCommands } from './commands/projects.js';
|
|
9
|
+
import { registerTeamCommands } from './commands/teams.js';
|
|
10
|
+
import { registerDemoCommands } from './commands/demo.js';
|
|
11
|
+
import { registerFileCommands } from './commands/files.js';
|
|
12
|
+
import { registerCompletionCommand } from './commands/completion.js';
|
|
13
|
+
/** The price and the balance of a credit refusal, each only when it is a number (the code review). */
|
|
14
|
+
function creditFigures(credit) {
|
|
15
|
+
const parts = [
|
|
16
|
+
typeof credit?.credits === 'number' ? `this needs ${credit.credits} credits` : null,
|
|
17
|
+
typeof credit?.balance === 'number' ? `the organization holds ${credit.balance}` : null
|
|
18
|
+
].filter((x) => x !== null);
|
|
19
|
+
return parts.length > 0 ? `${parts.join(' and ')}; ` : '';
|
|
20
|
+
}
|
|
21
|
+
/** The program and the runner of one tool, over its kit (kit.ts). */
|
|
22
|
+
export function createProgram(kit, definition) {
|
|
23
|
+
const { identity, explainWorkspaceRefusal, workspaceNotFoundHint } = kit;
|
|
24
|
+
const { description, errorHint } = definition;
|
|
25
|
+
function buildProgram(io, registerTool, version) {
|
|
26
|
+
const program = new Command();
|
|
27
|
+
program
|
|
28
|
+
.name(identity.bin)
|
|
29
|
+
.description(description)
|
|
30
|
+
.version(version)
|
|
31
|
+
.option('--api-url <url>', `instance base URL (or ${identity.envPrefix}_URL / the profile's; default: the cloud, ${identity.cloudUrl})`)
|
|
32
|
+
.option('--url <url>', 'alias of --api-url')
|
|
33
|
+
.option('--api-key <key>', `API key (or ${identity.envPrefix}_API_KEY / profile apiKey)`)
|
|
34
|
+
.option('--api-key-stdin', 'read the API key from the first line of stdin (keeps it out of argv)', false)
|
|
35
|
+
.option('--profile <name>', 'use this saved profile (an instance) instead of the active one')
|
|
36
|
+
.option('--org <id-or-name>', `run in this Antasphere organization, by its id or name (or ${identity.envPrefix}_ORG; default: your default organization)`)
|
|
37
|
+
.option('--workspace <id-or-name>', `run in this workspace of the instance, by its id or name (or ${identity.envPrefix}_WORKSPACE; default: the server's)`)
|
|
38
|
+
.option('--json', 'machine-readable JSON output', false);
|
|
39
|
+
// Identity + profiles: login, logout, whoami, verify, use, profiles,
|
|
40
|
+
// config show/clear.
|
|
41
|
+
registerAuthCommands(kit, program, io);
|
|
42
|
+
// Which workspace the commands run in: workspaces, workspace default.
|
|
43
|
+
registerWorkspaceCommands(kit, program, io);
|
|
44
|
+
// The subgroups of the workspace: projects *, projects members *.
|
|
45
|
+
registerProjectCommands(kit, program, io);
|
|
46
|
+
// The named groups of the workspace's people: teams *.
|
|
47
|
+
registerTeamCommands(kit, program, io);
|
|
48
|
+
// Demo links, as a signed-in owner (never a key): demo link, list, revoke.
|
|
49
|
+
registerDemoCommands(kit, program, io);
|
|
50
|
+
// The tool's own groups, where they have always sat in `--help`.
|
|
51
|
+
registerTool(program, io);
|
|
52
|
+
// Platform substrate (template heritage): instance, export, files *.
|
|
53
|
+
registerFileCommands(kit, program, io);
|
|
54
|
+
// Shell completion — registered LAST so the tree it prints is complete.
|
|
55
|
+
registerCompletionCommand(identity, program, io);
|
|
56
|
+
return program;
|
|
57
|
+
}
|
|
58
|
+
async function run(argv, rawIo, registerTool, version) {
|
|
59
|
+
// Every human sink is wrapped ONCE, here: resource titles, annotation bodies,
|
|
60
|
+
// stored filenames and server error messages are all somebody else's text
|
|
61
|
+
// heading for a terminal (context.ts `sanitizeForTty`). `--json` keeps the
|
|
62
|
+
// raw sink through `printJson`.
|
|
63
|
+
const io = ttySafeIo(rawIo);
|
|
64
|
+
// `--api-key-stdin` is resolved BEFORE commander parses: `resolveContext`
|
|
65
|
+
// is synchronous, so the key must already be parked against this io by
|
|
66
|
+
// the time a command asks for it. Reading stdin is the whole point — an
|
|
67
|
+
// argv-borne secret is visible in `ps` and lands in the shell history.
|
|
68
|
+
if (argv.includes('--api-key-stdin')) {
|
|
69
|
+
try {
|
|
70
|
+
setStdinApiKey(io, await readSecretFromStdin(io, 'API key'));
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
io.err.write(`Error: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
74
|
+
return 1;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const program = buildProgram(io, registerTool, version);
|
|
78
|
+
program.exitOverride();
|
|
79
|
+
program.configureOutput({
|
|
80
|
+
writeOut: (s) => io.out.write(s),
|
|
81
|
+
writeErr: (s) => io.err.write(s)
|
|
82
|
+
});
|
|
83
|
+
try {
|
|
84
|
+
await program.parseAsync(argv, { from: 'user' });
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
87
|
+
catch (e) {
|
|
88
|
+
if (e instanceof CommanderError) {
|
|
89
|
+
// --help / --version and usage errors already wrote their output.
|
|
90
|
+
return e.exitCode;
|
|
91
|
+
}
|
|
92
|
+
if (e instanceof CliConnectError && e.refusal) {
|
|
93
|
+
// The hub (or the instance's connect door) refused the PERSON, not
|
|
94
|
+
// the credential: the server's own sentence, as it is, and exit 3,
|
|
95
|
+
// the code the docs promise for a refusal. No hint: no key fixes it.
|
|
96
|
+
io.err.write(`Error: ${e.message}\n`);
|
|
97
|
+
return e.exitCode;
|
|
98
|
+
}
|
|
99
|
+
if (e instanceof PlatformApiError || e instanceof CliAuthError) {
|
|
100
|
+
// A refusal the workspace SELECTION caused reads as a bad key (401) or
|
|
101
|
+
// a forbidden one (403) on the wire; say what it really was.
|
|
102
|
+
const explained = await explainWorkspaceRefusal(io, e);
|
|
103
|
+
if (explained) {
|
|
104
|
+
io.err.write(`Error: ${explained}\n`);
|
|
105
|
+
return 1;
|
|
106
|
+
}
|
|
107
|
+
// A plan refusal (the billing rail, 403 `plan_required`) is not a
|
|
108
|
+
// key's fault: the sentence carries the upgrade link, the hub's
|
|
109
|
+
// organization page, where a human raises the plan.
|
|
110
|
+
const upgradeUrl = (e instanceof PlatformApiError && e.code === 'plan_required'
|
|
111
|
+
? e.details?.upgradeUrl
|
|
112
|
+
: undefined);
|
|
113
|
+
// A credit refusal (402 `entitlement_denied`, PRDCT-2664) carries the
|
|
114
|
+
// price, the balance and the top-up link, the hub's billing page. The
|
|
115
|
+
// self-hosted cap's 413 has no details and keeps its message alone.
|
|
116
|
+
const credit = (e instanceof PlatformApiError && e.code === 'entitlement_denied' ? e.details : undefined);
|
|
117
|
+
const topUpUrl = typeof credit?.topUpUrl === 'string' && credit.topUpUrl ? credit.topUpUrl : null;
|
|
118
|
+
// The gate's own message already spells the price, the balance and
|
|
119
|
+
// the link; the hint repeats them only for a message that does not
|
|
120
|
+
// (verifier round 1: the URL was printed twice).
|
|
121
|
+
const hint = typeof upgradeUrl === 'string' && upgradeUrl
|
|
122
|
+
? ` — upgrade the plan at ${upgradeUrl}`
|
|
123
|
+
: topUpUrl && !e.message.includes(topUpUrl)
|
|
124
|
+
? ` — ${creditFigures(credit)}top up at ${topUpUrl}`
|
|
125
|
+
: e.status === 403
|
|
126
|
+
? ' (this API key is not allowed to do that)'
|
|
127
|
+
: (errorHint?.(e) ??
|
|
128
|
+
(e.status === 401
|
|
129
|
+
? ` (check the key: \`${identity.bin} verify\`)`
|
|
130
|
+
: e.status === 404
|
|
131
|
+
? workspaceNotFoundHint(io)
|
|
132
|
+
: ''));
|
|
133
|
+
io.err.write(`Error: ${e.message}${hint}\n`);
|
|
134
|
+
return 1;
|
|
135
|
+
}
|
|
136
|
+
if (e instanceof CliUsageError) {
|
|
137
|
+
// A refusal a command already worded keeps the one thing the command
|
|
138
|
+
// cannot know: the workspace a 404 was asked of. The thrower says the
|
|
139
|
+
// exit code (cli-core: 1 a usage or wire error, 3 a refusal).
|
|
140
|
+
const hint = e instanceof CliApiRefusal && e.status === 404 ? workspaceNotFoundHint(io) : '';
|
|
141
|
+
io.err.write(`Error: ${e.message}${hint}\n`);
|
|
142
|
+
return e.exitCode;
|
|
143
|
+
}
|
|
144
|
+
io.err.write(`Error: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
145
|
+
return 1;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return { buildProgram, run };
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=program.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program.js","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"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"}
|