@objectstack/cli 4.0.4 → 4.0.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 +12 -25
- package/dist/commands/build.d.ts +5 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +6 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/compile.d.ts +3 -0
- package/dist/commands/compile.d.ts.map +1 -1
- package/dist/commands/compile.js +128 -6
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/create.js +1 -1
- package/dist/commands/data/create.js +2 -2
- package/dist/commands/data/create.js.map +1 -1
- package/dist/commands/data/delete.js +2 -2
- package/dist/commands/data/delete.js.map +1 -1
- package/dist/commands/data/get.js +2 -2
- package/dist/commands/data/get.js.map +1 -1
- package/dist/commands/data/query.js +2 -2
- package/dist/commands/data/query.js.map +1 -1
- package/dist/commands/data/update.js +2 -2
- package/dist/commands/data/update.js.map +1 -1
- package/dist/commands/dev.d.ts +3 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +48 -19
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/generate.js +9 -9
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/i18n/check.d.ts +18 -0
- package/dist/commands/i18n/check.d.ts.map +1 -0
- package/dist/commands/i18n/check.js +153 -0
- package/dist/commands/i18n/check.js.map +1 -0
- package/dist/commands/init.js +2 -2
- package/dist/commands/lint.d.ts +3 -0
- package/dist/commands/lint.d.ts.map +1 -1
- package/dist/commands/lint.js +24 -0
- package/dist/commands/lint.js.map +1 -1
- package/dist/commands/login.d.ts +17 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +313 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/{auth/logout.js → logout.js} +14 -2
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/meta/delete.js +2 -2
- package/dist/commands/meta/delete.js.map +1 -1
- package/dist/commands/meta/get.js +2 -2
- package/dist/commands/meta/get.js.map +1 -1
- package/dist/commands/meta/list.js +2 -2
- package/dist/commands/meta/list.js.map +1 -1
- package/dist/commands/meta/register.js +2 -2
- package/dist/commands/meta/register.js.map +1 -1
- package/dist/commands/projects/bind.d.ts +30 -0
- package/dist/commands/projects/bind.d.ts.map +1 -0
- package/dist/commands/projects/bind.js +132 -0
- package/dist/commands/projects/bind.js.map +1 -0
- package/dist/commands/projects/create.d.ts +28 -0
- package/dist/commands/projects/create.d.ts.map +1 -0
- package/dist/commands/projects/create.js +120 -0
- package/dist/commands/projects/create.js.map +1 -0
- package/dist/commands/projects/list.d.ts +21 -0
- package/dist/commands/projects/list.d.ts.map +1 -0
- package/dist/commands/projects/list.js +79 -0
- package/dist/commands/projects/list.js.map +1 -0
- package/dist/commands/projects/projects.test.d.ts +2 -0
- package/dist/commands/projects/projects.test.d.ts.map +1 -0
- package/dist/commands/projects/projects.test.js +56 -0
- package/dist/commands/projects/projects.test.js.map +1 -0
- package/dist/commands/projects/show.d.ts +21 -0
- package/dist/commands/projects/show.d.ts.map +1 -0
- package/dist/commands/projects/show.js +72 -0
- package/dist/commands/projects/show.js.map +1 -0
- package/dist/commands/projects/switch.d.ts +24 -0
- package/dist/commands/projects/switch.d.ts.map +1 -0
- package/dist/commands/projects/switch.js +64 -0
- package/dist/commands/projects/switch.js.map +1 -0
- package/dist/commands/publish.d.ts +14 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +91 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/{auth/login.d.ts → register.d.ts} +3 -2
- package/dist/commands/register.d.ts.map +1 -0
- package/dist/commands/{auth/login.js → register.js} +44 -61
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/serve.d.ts +8 -0
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +606 -44
- package/dist/commands/serve.js.map +1 -1
- package/dist/commands/start.d.ts +11 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +43 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/{auth/whoami.js → whoami.js} +5 -5
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.d.ts +7 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -5
- package/dist/index.js.map +1 -1
- package/dist/utils/account.d.ts +31 -0
- package/dist/utils/account.d.ts.map +1 -0
- package/dist/utils/account.js +154 -0
- package/dist/utils/account.js.map +1 -0
- package/dist/utils/api-client.d.ts +10 -4
- package/dist/utils/api-client.d.ts.map +1 -1
- package/dist/utils/api-client.js +13 -7
- package/dist/utils/api-client.js.map +1 -1
- package/dist/utils/auth-config.d.ts +6 -0
- package/dist/utils/auth-config.d.ts.map +1 -1
- package/dist/utils/auth-config.js.map +1 -1
- package/dist/utils/build-runtime.d.ts +45 -0
- package/dist/utils/build-runtime.d.ts.map +1 -0
- package/dist/utils/build-runtime.js +154 -0
- package/dist/utils/build-runtime.js.map +1 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +17 -2
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/console.d.ts +32 -0
- package/dist/utils/console.d.ts.map +1 -0
- package/dist/utils/console.js +169 -0
- package/dist/utils/console.js.map +1 -0
- package/dist/utils/extract-hook-body.d.ts +13 -0
- package/dist/utils/extract-hook-body.d.ts.map +1 -0
- package/dist/utils/extract-hook-body.js +175 -0
- package/dist/utils/extract-hook-body.js.map +1 -0
- package/dist/utils/format.d.ts +8 -0
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js +15 -2
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/i18n-coverage.d.ts +61 -0
- package/dist/utils/i18n-coverage.d.ts.map +1 -0
- package/dist/utils/i18n-coverage.js +176 -0
- package/dist/utils/i18n-coverage.js.map +1 -0
- package/dist/utils/lower-callables.d.ts +17 -0
- package/dist/utils/lower-callables.d.ts.map +1 -0
- package/dist/utils/lower-callables.js +181 -0
- package/dist/utils/lower-callables.js.map +1 -0
- package/dist/utils/plugin-detection.d.ts +1 -0
- package/dist/utils/plugin-detection.d.ts.map +1 -1
- package/dist/utils/plugin-detection.js +41 -0
- package/dist/utils/plugin-detection.js.map +1 -1
- package/dist/utils/studio.d.ts +1 -0
- package/dist/utils/studio.d.ts.map +1 -1
- package/dist/utils/studio.js +25 -9
- package/dist/utils/studio.js.map +1 -1
- package/package.json +55 -21
- package/.turbo/turbo-build.log +0 -4
- package/CHANGELOG.md +0 -821
- package/bin/run-dev.js +0 -5
- package/dist/commands/auth/login.d.ts.map +0 -1
- package/dist/commands/auth/login.js.map +0 -1
- package/dist/commands/auth/logout.d.ts.map +0 -1
- package/dist/commands/auth/logout.js.map +0 -1
- package/dist/commands/auth/whoami.d.ts.map +0 -1
- package/dist/commands/auth/whoami.js.map +0 -1
- package/dist/commands/codemod/v2-to-v3.d.ts +0 -10
- package/dist/commands/codemod/v2-to-v3.d.ts.map +0 -1
- package/dist/commands/codemod/v2-to-v3.js +0 -145
- package/dist/commands/codemod/v2-to-v3.js.map +0 -1
- package/dist/commands/plugin/add.d.ts +0 -22
- package/dist/commands/plugin/add.d.ts.map +0 -1
- package/dist/commands/plugin/add.js +0 -93
- package/dist/commands/plugin/add.js.map +0 -1
- package/dist/commands/plugin/build.d.ts +0 -29
- package/dist/commands/plugin/build.d.ts.map +0 -1
- package/dist/commands/plugin/build.js +0 -170
- package/dist/commands/plugin/build.js.map +0 -1
- package/dist/commands/plugin/info.d.ts +0 -10
- package/dist/commands/plugin/info.d.ts.map +0 -1
- package/dist/commands/plugin/info.js +0 -65
- package/dist/commands/plugin/info.js.map +0 -1
- package/dist/commands/plugin/list.d.ts +0 -13
- package/dist/commands/plugin/list.d.ts.map +0 -1
- package/dist/commands/plugin/list.js +0 -78
- package/dist/commands/plugin/list.js.map +0 -1
- package/dist/commands/plugin/publish.d.ts +0 -27
- package/dist/commands/plugin/publish.d.ts.map +0 -1
- package/dist/commands/plugin/publish.js +0 -152
- package/dist/commands/plugin/publish.js.map +0 -1
- package/dist/commands/plugin/remove.d.ts +0 -20
- package/dist/commands/plugin/remove.d.ts.map +0 -1
- package/dist/commands/plugin/remove.js +0 -79
- package/dist/commands/plugin/remove.js.map +0 -1
- package/dist/commands/plugin/validate.d.ts +0 -23
- package/dist/commands/plugin/validate.d.ts.map +0 -1
- package/dist/commands/plugin/validate.js +0 -251
- package/dist/commands/plugin/validate.js.map +0 -1
- package/src/bin.ts +0 -13
- package/src/commands/auth/login.ts +0 -188
- package/src/commands/auth/logout.ts +0 -51
- package/src/commands/auth/whoami.ts +0 -85
- package/src/commands/codemod/v2-to-v3.ts +0 -171
- package/src/commands/compile.ts +0 -114
- package/src/commands/create.ts +0 -281
- package/src/commands/data/create.ts +0 -110
- package/src/commands/data/delete.ts +0 -84
- package/src/commands/data/get.ts +0 -84
- package/src/commands/data/query.ts +0 -127
- package/src/commands/data/update.ts +0 -114
- package/src/commands/dev.ts +0 -83
- package/src/commands/diff.ts +0 -294
- package/src/commands/doctor.ts +0 -572
- package/src/commands/explain.ts +0 -412
- package/src/commands/generate.ts +0 -924
- package/src/commands/info.ts +0 -124
- package/src/commands/init.ts +0 -327
- package/src/commands/lint.ts +0 -315
- package/src/commands/meta/delete.ts +0 -79
- package/src/commands/meta/get.ts +0 -73
- package/src/commands/meta/list.ts +0 -105
- package/src/commands/meta/register.ts +0 -97
- package/src/commands/plugin/add.ts +0 -112
- package/src/commands/plugin/build.ts +0 -193
- package/src/commands/plugin/info.ts +0 -79
- package/src/commands/plugin/list.ts +0 -93
- package/src/commands/plugin/publish.ts +0 -176
- package/src/commands/plugin/remove.ts +0 -97
- package/src/commands/plugin/validate.ts +0 -268
- package/src/commands/serve.ts +0 -411
- package/src/commands/studio.ts +0 -52
- package/src/commands/test.ts +0 -135
- package/src/commands/validate.ts +0 -143
- package/src/index.ts +0 -22
- package/src/utils/api-client.ts +0 -88
- package/src/utils/auth-config.ts +0 -107
- package/src/utils/config.ts +0 -80
- package/src/utils/format.ts +0 -267
- package/src/utils/output-formatter.ts +0 -91
- package/src/utils/plugin-detection.ts +0 -16
- package/src/utils/plugin-helpers.ts +0 -37
- package/src/utils/studio.ts +0 -350
- package/test/commands.test.ts +0 -128
- package/test/create.test.ts +0 -25
- package/test/plugin-commands.test.ts +0 -44
- package/test/plugin.test.ts +0 -169
- package/test/remote-api-commands.test.ts +0 -188
- package/test/remote-api-utils.test.ts +0 -196
- package/test/serve-host-config.test.ts +0 -77
- package/tsconfig.build.json +0 -20
- package/tsconfig.json +0 -25
- package/tsup.config.ts +0 -23
- /package/dist/commands/{auth/logout.d.ts → logout.d.ts} +0 -0
- /package/dist/commands/{auth/whoami.d.ts → whoami.d.ts} +0 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
import { Command, Flags, Args } from '@oclif/core';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import fs from 'node:fs/promises';
|
|
5
|
+
import { spawnSync } from 'node:child_process';
|
|
6
|
+
import { printError, printStep, printKV } from '../../utils/format.js';
|
|
7
|
+
import { createApiClient, requireAuth } from '../../utils/api-client.js';
|
|
8
|
+
import { formatOutput } from '../../utils/output-formatter.js';
|
|
9
|
+
/**
|
|
10
|
+
* `os projects bind` — bind a locally-compiled artifact to an existing
|
|
11
|
+
* multi-project server project.
|
|
12
|
+
*
|
|
13
|
+
* Equivalent to `PATCH /api/v1/cloud/projects/<id>` with
|
|
14
|
+
* `metadata.artifact_path = <absolute-path>`. The server's
|
|
15
|
+
* AppBundleResolver picks up the path on the next per-project kernel
|
|
16
|
+
* boot, registering the bundle's objects, views, and seed data.
|
|
17
|
+
*
|
|
18
|
+
* Use `--build` to compile `objectstack.config.ts` first so the artifact
|
|
19
|
+
* reflects the latest source.
|
|
20
|
+
*/
|
|
21
|
+
export default class ProjectsBind extends Command {
|
|
22
|
+
static description = 'Bind a local objectstack artifact to an existing project';
|
|
23
|
+
static examples = [
|
|
24
|
+
'$ os projects bind <project-id> --artifact ./dist/objectstack.json',
|
|
25
|
+
'$ os projects bind <project-id> --artifact ./dist/objectstack.json --build',
|
|
26
|
+
'$ os projects bind <project-id> --reseed',
|
|
27
|
+
];
|
|
28
|
+
static args = {
|
|
29
|
+
projectId: Args.string({
|
|
30
|
+
description: 'Target project id (UUID)',
|
|
31
|
+
required: true,
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
static flags = {
|
|
35
|
+
url: Flags.string({ char: 'u', description: 'Server URL', env: 'OS_CLOUD_URL' }),
|
|
36
|
+
token: Flags.string({ char: 't', description: 'Authentication token', env: 'OS_TOKEN' }),
|
|
37
|
+
artifact: Flags.string({
|
|
38
|
+
description: 'Path to a compiled objectstack.json artifact (default: ./dist/objectstack.json)',
|
|
39
|
+
}),
|
|
40
|
+
build: Flags.boolean({
|
|
41
|
+
description: 'Run `objectstack compile` before binding',
|
|
42
|
+
default: false,
|
|
43
|
+
}),
|
|
44
|
+
reseed: Flags.boolean({
|
|
45
|
+
description: 'After binding, also re-run schema sync + bundle seeding via /cloud/projects/:id/reseed',
|
|
46
|
+
default: false,
|
|
47
|
+
}),
|
|
48
|
+
format: Flags.string({
|
|
49
|
+
char: 'f',
|
|
50
|
+
description: 'Output format',
|
|
51
|
+
options: ['json', 'table', 'yaml'],
|
|
52
|
+
default: 'table',
|
|
53
|
+
}),
|
|
54
|
+
};
|
|
55
|
+
async run() {
|
|
56
|
+
const { args, flags } = await this.parse(ProjectsBind);
|
|
57
|
+
try {
|
|
58
|
+
const artifactRel = flags.artifact ?? './dist/objectstack.json';
|
|
59
|
+
const artifactAbs = path.isAbsolute(artifactRel)
|
|
60
|
+
? artifactRel
|
|
61
|
+
: path.resolve(process.cwd(), artifactRel);
|
|
62
|
+
if (flags.build) {
|
|
63
|
+
printStep('Compiling objectstack.config.ts → ' + artifactAbs);
|
|
64
|
+
const binPath = process.argv[1];
|
|
65
|
+
const r = spawnSync(process.execPath, [binPath, 'compile', '--output', artifactAbs], { stdio: 'inherit', env: { ...process.env, NODE_ENV: 'development' } });
|
|
66
|
+
if (r.status !== 0) {
|
|
67
|
+
printError('Compile failed — fix errors above before binding');
|
|
68
|
+
this.exit(1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
await fs.access(artifactAbs);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
printError(`Artifact not found: ${artifactAbs}`);
|
|
76
|
+
if (!flags.build) {
|
|
77
|
+
console.error(' Hint: pass --build to compile first, or check the path with --artifact.');
|
|
78
|
+
}
|
|
79
|
+
this.exit(1);
|
|
80
|
+
}
|
|
81
|
+
const { client, token } = await createApiClient({ url: flags.url, token: flags.token });
|
|
82
|
+
requireAuth(token);
|
|
83
|
+
// Fetch existing metadata so we don't blow it away.
|
|
84
|
+
const current = await client.projects.get(args.projectId);
|
|
85
|
+
const existingMeta = (current?.project?.metadata && typeof current.project.metadata === 'object')
|
|
86
|
+
? { ...current.project.metadata }
|
|
87
|
+
: {};
|
|
88
|
+
// Drop the prior bind error so the UI doesn't show a stale failure.
|
|
89
|
+
delete existingMeta.artifactBindError;
|
|
90
|
+
existingMeta.artifact_path = artifactAbs;
|
|
91
|
+
printKV('Project', args.projectId, '🎯');
|
|
92
|
+
printKV('Artifact', artifactAbs, '📦');
|
|
93
|
+
const res = await client.projects.update(args.projectId, {
|
|
94
|
+
metadata: existingMeta,
|
|
95
|
+
});
|
|
96
|
+
if (flags.reseed) {
|
|
97
|
+
printStep('Reseeding bundle (POST /cloud/projects/:id/reseed)…');
|
|
98
|
+
try {
|
|
99
|
+
// Best-effort: server may not expose a reseed endpoint yet.
|
|
100
|
+
const reseed = await client.fetch?.(`${client.baseUrl}/api/v1/cloud/projects/${encodeURIComponent(args.projectId)}/reseed`, { method: 'POST' });
|
|
101
|
+
if (reseed && typeof reseed.ok === 'boolean' && !reseed.ok) {
|
|
102
|
+
console.error(' ⚠ reseed endpoint returned ' + reseed.status + ' — bundle will be applied on next kernel boot.');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
console.error(' ⚠ reseed failed: ' + (e?.message ?? e) + ' — bundle will be applied on next kernel boot.');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (flags.format === 'json') {
|
|
110
|
+
formatOutput(res, 'json');
|
|
111
|
+
}
|
|
112
|
+
else if (flags.format === 'yaml') {
|
|
113
|
+
formatOutput(res, 'yaml');
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
console.log(`\n✓ Project bound to artifact`);
|
|
117
|
+
console.log(` ${args.projectId} → ${artifactAbs}`);
|
|
118
|
+
console.log(` The next request to this project will load the new bundle.`);
|
|
119
|
+
console.log('');
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
if (flags.format === 'json') {
|
|
124
|
+
console.log(JSON.stringify({ success: false, error: error.message }, null, 2));
|
|
125
|
+
this.exit(1);
|
|
126
|
+
}
|
|
127
|
+
printError(error.message || String(error));
|
|
128
|
+
this.exit(1);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=bind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bind.js","sourceRoot":"","sources":["../../../src/commands/projects/bind.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
/**
|
|
3
|
+
* `os projects create` — provision a new project.
|
|
4
|
+
*
|
|
5
|
+
* Delegates to `ProjectProvisioningService.provisionProject` on the server.
|
|
6
|
+
* On success, optionally activates the new project for the current session
|
|
7
|
+
* and persists `activeProjectId` into `~/.objectstack/credentials.json`
|
|
8
|
+
* (unless `--no-activate` is passed).
|
|
9
|
+
*/
|
|
10
|
+
export default class ProjectsCreate extends Command {
|
|
11
|
+
static description: string;
|
|
12
|
+
static examples: string[];
|
|
13
|
+
static flags: {
|
|
14
|
+
url: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
org: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
name: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
|
+
plan: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
|
+
driver: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
|
+
template: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
21
|
+
artifact: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
22
|
+
'clone-from': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
23
|
+
activate: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
24
|
+
format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
25
|
+
};
|
|
26
|
+
run(): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=create.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/projects/create.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAM7C;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,OAAO;IACjD,OAAgB,WAAW,SAA6B;IAExD,OAAgB,QAAQ,WAKtB;IAEF,OAAgB,KAAK;;;;;;;;;;;;MAuBnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAwE3B"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
import { Command, Flags } from '@oclif/core';
|
|
3
|
+
import { printError } from '../../utils/format.js';
|
|
4
|
+
import { createApiClient, requireAuth } from '../../utils/api-client.js';
|
|
5
|
+
import { formatOutput } from '../../utils/output-formatter.js';
|
|
6
|
+
import { readAuthConfig, writeAuthConfig } from '../../utils/auth-config.js';
|
|
7
|
+
/**
|
|
8
|
+
* `os projects create` — provision a new project.
|
|
9
|
+
*
|
|
10
|
+
* Delegates to `ProjectProvisioningService.provisionProject` on the server.
|
|
11
|
+
* On success, optionally activates the new project for the current session
|
|
12
|
+
* and persists `activeProjectId` into `~/.objectstack/credentials.json`
|
|
13
|
+
* (unless `--no-activate` is passed).
|
|
14
|
+
*/
|
|
15
|
+
export default class ProjectsCreate extends Command {
|
|
16
|
+
static description = 'Provision a new project';
|
|
17
|
+
static examples = [
|
|
18
|
+
'$ os projects create --org 00000000-0000-0000-0000-000000000000 --name Staging',
|
|
19
|
+
'$ os projects create --org $ORG --name Dev --plan free',
|
|
20
|
+
'$ os projects create --org $ORG --name "Clone" --clone-from <source-id> --no-activate',
|
|
21
|
+
'$ os projects create --org $ORG --name CRM --artifact ./examples/app-crm/dist/objectstack.json',
|
|
22
|
+
];
|
|
23
|
+
static flags = {
|
|
24
|
+
url: Flags.string({ char: 'u', description: 'Server URL', env: 'OS_CLOUD_URL' }),
|
|
25
|
+
token: Flags.string({ char: 't', description: 'Authentication token', env: 'OS_TOKEN' }),
|
|
26
|
+
org: Flags.string({ description: 'Organization id', required: true }),
|
|
27
|
+
name: Flags.string({ description: 'Display name', required: true }),
|
|
28
|
+
plan: Flags.string({ description: 'Billing plan', default: 'free' }),
|
|
29
|
+
driver: Flags.string({ description: 'Data-plane driver id' }),
|
|
30
|
+
template: Flags.string({ description: 'Built-in template id (e.g. crm, todo, blank)' }),
|
|
31
|
+
artifact: Flags.string({
|
|
32
|
+
description: 'Path to a locally-compiled objectstack.json artifact to bind into this project',
|
|
33
|
+
}),
|
|
34
|
+
'clone-from': Flags.string({ description: 'Clone schema from an existing project id' }),
|
|
35
|
+
activate: Flags.boolean({
|
|
36
|
+
description: 'Activate the new project for subsequent CLI calls',
|
|
37
|
+
default: true,
|
|
38
|
+
allowNo: true,
|
|
39
|
+
}),
|
|
40
|
+
format: Flags.string({
|
|
41
|
+
char: 'f',
|
|
42
|
+
description: 'Output format',
|
|
43
|
+
options: ['json', 'table', 'yaml'],
|
|
44
|
+
default: 'table',
|
|
45
|
+
}),
|
|
46
|
+
};
|
|
47
|
+
async run() {
|
|
48
|
+
const { flags } = await this.parse(ProjectsCreate);
|
|
49
|
+
try {
|
|
50
|
+
const { client, token } = await createApiClient({ url: flags.url, token: flags.token });
|
|
51
|
+
requireAuth(token);
|
|
52
|
+
// Resolve the artifact to an absolute path so the server can read it
|
|
53
|
+
// regardless of its CWD. Bail early if the file is missing — better
|
|
54
|
+
// to fail before provisioning than leave a half-bound project.
|
|
55
|
+
let metadata;
|
|
56
|
+
if (flags.artifact) {
|
|
57
|
+
const path = await import('node:path');
|
|
58
|
+
const fs = await import('node:fs/promises');
|
|
59
|
+
const abs = path.isAbsolute(flags.artifact)
|
|
60
|
+
? flags.artifact
|
|
61
|
+
: path.resolve(process.cwd(), flags.artifact);
|
|
62
|
+
try {
|
|
63
|
+
await fs.access(abs);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
printError(`Artifact not found: ${abs}`);
|
|
67
|
+
this.exit(1);
|
|
68
|
+
}
|
|
69
|
+
metadata = { artifact_path: abs };
|
|
70
|
+
}
|
|
71
|
+
const res = await client.projects.create({
|
|
72
|
+
organization_id: flags.org,
|
|
73
|
+
display_name: flags.name,
|
|
74
|
+
plan: flags.plan,
|
|
75
|
+
driver: flags.driver,
|
|
76
|
+
template_id: flags.template,
|
|
77
|
+
clone_from_project_id: flags['clone-from'],
|
|
78
|
+
...(metadata ? { metadata } : {}),
|
|
79
|
+
});
|
|
80
|
+
if (flags.activate && res?.project?.id) {
|
|
81
|
+
try {
|
|
82
|
+
await client.projects.activate(res.project.id);
|
|
83
|
+
const cfg = await readAuthConfig().catch(() => null);
|
|
84
|
+
if (cfg) {
|
|
85
|
+
cfg.activeProjectId = res.project.id;
|
|
86
|
+
cfg.lastUsedAt = new Date().toISOString();
|
|
87
|
+
await writeAuthConfig(cfg);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (activateError) {
|
|
91
|
+
// Creation succeeded — surface activation failure as a warning
|
|
92
|
+
console.error(` ⚠ activation failed: ${activateError.message}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (flags.format === 'json') {
|
|
96
|
+
formatOutput(res, 'json');
|
|
97
|
+
}
|
|
98
|
+
else if (flags.format === 'yaml') {
|
|
99
|
+
formatOutput(res, 'yaml');
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
const p = res?.project ?? {};
|
|
103
|
+
console.log(`\n✓ Project created: ${p.display_name ?? p.id} (${p.id})`);
|
|
104
|
+
if (flags.activate) {
|
|
105
|
+
console.log(` active project set to ${p.id}`);
|
|
106
|
+
}
|
|
107
|
+
console.log('');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
if (flags.format === 'json') {
|
|
112
|
+
console.log(JSON.stringify({ success: false, error: error.message }, null, 2));
|
|
113
|
+
this.exit(1);
|
|
114
|
+
}
|
|
115
|
+
printError(error.message || String(error));
|
|
116
|
+
this.exit(1);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/projects/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
/**
|
|
3
|
+
* `os projects list` — list projects visible to the current session.
|
|
4
|
+
*
|
|
5
|
+
* Filters by organization via `--org`. Output format is the same
|
|
6
|
+
* table/json/yaml shape used by other metadata commands, for a
|
|
7
|
+
* consistent DX.
|
|
8
|
+
*/
|
|
9
|
+
export default class ProjectsList extends Command {
|
|
10
|
+
static description: string;
|
|
11
|
+
static examples: string[];
|
|
12
|
+
static flags: {
|
|
13
|
+
url: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
org: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
status: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
|
+
};
|
|
19
|
+
run(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/projects/list.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAK7C;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IAC/C,OAAgB,WAAW,SAAkD;IAE7E,OAAgB,QAAQ,WAItB;IAEF,OAAgB,KAAK;;;;;;MAWnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAiD3B"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
import { Command, Flags } from '@oclif/core';
|
|
3
|
+
import { printError } from '../../utils/format.js';
|
|
4
|
+
import { createApiClient, requireAuth } from '../../utils/api-client.js';
|
|
5
|
+
import { formatOutput } from '../../utils/output-formatter.js';
|
|
6
|
+
/**
|
|
7
|
+
* `os projects list` — list projects visible to the current session.
|
|
8
|
+
*
|
|
9
|
+
* Filters by organization via `--org`. Output format is the same
|
|
10
|
+
* table/json/yaml shape used by other metadata commands, for a
|
|
11
|
+
* consistent DX.
|
|
12
|
+
*/
|
|
13
|
+
export default class ProjectsList extends Command {
|
|
14
|
+
static description = 'List projects visible to the current session';
|
|
15
|
+
static examples = [
|
|
16
|
+
'$ os projects list',
|
|
17
|
+
'$ os projects list --org 00000000-0000-0000-0000-000000000000',
|
|
18
|
+
'$ os projects list --format json',
|
|
19
|
+
];
|
|
20
|
+
static flags = {
|
|
21
|
+
url: Flags.string({ char: 'u', description: 'Server URL', env: 'OS_CLOUD_URL' }),
|
|
22
|
+
token: Flags.string({ char: 't', description: 'Authentication token', env: 'OS_TOKEN' }),
|
|
23
|
+
org: Flags.string({ description: 'Filter by organization id' }),
|
|
24
|
+
status: Flags.string({ description: 'Filter by project status (active|provisioning|failed|…)' }),
|
|
25
|
+
format: Flags.string({
|
|
26
|
+
char: 'f',
|
|
27
|
+
description: 'Output format',
|
|
28
|
+
options: ['json', 'table', 'yaml'],
|
|
29
|
+
default: 'table',
|
|
30
|
+
}),
|
|
31
|
+
};
|
|
32
|
+
async run() {
|
|
33
|
+
const { flags } = await this.parse(ProjectsList);
|
|
34
|
+
try {
|
|
35
|
+
const { client, token, projectId: activeId } = await createApiClient({
|
|
36
|
+
url: flags.url,
|
|
37
|
+
token: flags.token,
|
|
38
|
+
});
|
|
39
|
+
requireAuth(token);
|
|
40
|
+
const res = await client.projects.list({
|
|
41
|
+
organization_id: flags.org,
|
|
42
|
+
status: flags.status,
|
|
43
|
+
});
|
|
44
|
+
const projects = res?.projects ?? [];
|
|
45
|
+
if (flags.format === 'json') {
|
|
46
|
+
formatOutput(res, 'json');
|
|
47
|
+
}
|
|
48
|
+
else if (flags.format === 'yaml') {
|
|
49
|
+
formatOutput(res, 'yaml');
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
console.log(`\nProjects (${projects.length}):\n`);
|
|
53
|
+
if (projects.length === 0) {
|
|
54
|
+
console.log(' (no projects)');
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
for (const p of projects) {
|
|
58
|
+
const active = p.id === activeId ? ' ★' : '';
|
|
59
|
+
const defaultTag = p.is_default ? ' [default]' : '';
|
|
60
|
+
const systemTag = p.is_system ? ' [system]' : '';
|
|
61
|
+
console.log(` • ${p.display_name ?? p.id}${active}${defaultTag}${systemTag}`);
|
|
62
|
+
console.log(` id: ${p.id}`);
|
|
63
|
+
console.log(` status: ${p.status ?? '—'} plan: ${p.plan ?? '—'}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
console.log('');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (flags.format === 'json') {
|
|
71
|
+
console.log(JSON.stringify({ success: false, error: error.message }, null, 2));
|
|
72
|
+
this.exit(1);
|
|
73
|
+
}
|
|
74
|
+
printError(error.message || String(error));
|
|
75
|
+
this.exit(1);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/projects/list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.test.d.ts","sourceRoot":"","sources":["../../../src/commands/projects/projects.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
import { describe, it, expect } from 'vitest';
|
|
3
|
+
import ProjectsList from './list.js';
|
|
4
|
+
import ProjectsShow from './show.js';
|
|
5
|
+
import ProjectsCreate from './create.js';
|
|
6
|
+
import ProjectsSwitch from './switch.js';
|
|
7
|
+
/**
|
|
8
|
+
* Metadata-only smoke tests for the `os projects ...` commands. We do
|
|
9
|
+
* not run the commands end-to-end (that would require an oclif Config
|
|
10
|
+
* with hooks wired up); instead we assert that each command is a
|
|
11
|
+
* well-formed oclif Command class with the flags / args we expect.
|
|
12
|
+
*
|
|
13
|
+
* This catches typos and missing-arg regressions without the heavy
|
|
14
|
+
* lifting of a full oclif harness. Full runtime coverage lives in
|
|
15
|
+
* `client.project-scoping.test.ts` (which exercises the HTTP surface)
|
|
16
|
+
* and the Chrome DevTools MCP smoke test in the PR description.
|
|
17
|
+
*/
|
|
18
|
+
describe('os projects commands', () => {
|
|
19
|
+
describe('list', () => {
|
|
20
|
+
it('has the expected description and flags', () => {
|
|
21
|
+
expect(ProjectsList.description).toMatch(/list/i);
|
|
22
|
+
expect(ProjectsList.flags).toHaveProperty('org');
|
|
23
|
+
expect(ProjectsList.flags).toHaveProperty('status');
|
|
24
|
+
expect(ProjectsList.flags).toHaveProperty('format');
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
describe('show', () => {
|
|
28
|
+
it('requires an id arg', () => {
|
|
29
|
+
expect(ProjectsShow.args).toHaveProperty('id');
|
|
30
|
+
expect(ProjectsShow.args.id.required).toBe(true);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe('create', () => {
|
|
34
|
+
it('requires --org and --name', () => {
|
|
35
|
+
expect(ProjectsCreate.flags.org.required).toBe(true);
|
|
36
|
+
expect(ProjectsCreate.flags.name.required).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
it('activates by default with --no-activate opt-out', () => {
|
|
39
|
+
const flag = ProjectsCreate.flags.activate;
|
|
40
|
+
expect(flag.default).toBe(true);
|
|
41
|
+
expect(flag.allowNo).toBe(true);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe('switch', () => {
|
|
45
|
+
it('requires an id arg', () => {
|
|
46
|
+
expect(ProjectsSwitch.args).toHaveProperty('id');
|
|
47
|
+
expect(ProjectsSwitch.args.id.required).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
it('calls the activate endpoint by default with --no-remote opt-out', () => {
|
|
50
|
+
const flag = ProjectsSwitch.flags.remote;
|
|
51
|
+
expect(flag.default).toBe(true);
|
|
52
|
+
expect(flag.allowNo).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=projects.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.test.js","sourceRoot":"","sources":["../../../src/commands/projects/projects.test.ts"],"names":[],"mappings":"AAAA,yEAAyE;AAEzE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,YAAY,MAAM,WAAW,CAAC;AACrC,OAAO,YAAY,MAAM,WAAW,CAAC;AACrC,OAAO,cAAc,MAAM,aAAa,CAAC;AACzC,OAAO,cAAc,MAAM,aAAa,CAAC;AAEzC;;;;;;;;;;GAUG;AAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAClD,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;YACjD,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;YACpD,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;YAC5B,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;YAC/C,MAAM,CAAE,YAAY,CAAC,IAAY,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;YACnC,MAAM,CAAE,cAAc,CAAC,KAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9D,MAAM,CAAE,cAAc,CAAC,KAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,IAAI,GAAI,cAAc,CAAC,KAAa,CAAC,QAAQ,CAAC;YACpD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;YAC5B,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;YACjD,MAAM,CAAE,cAAc,CAAC,IAAY,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;YACzE,MAAM,IAAI,GAAI,cAAc,CAAC,KAAa,CAAC,MAAM,CAAC;YAClD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
/**
|
|
3
|
+
* `os projects show <id>` — show detailed information for a single project.
|
|
4
|
+
*
|
|
5
|
+
* Renders the project row plus its database, active credential, and
|
|
6
|
+
* membership row (same shape as `client.projects.get(id)`).
|
|
7
|
+
*/
|
|
8
|
+
export default class ProjectsShow extends Command {
|
|
9
|
+
static description: string;
|
|
10
|
+
static examples: string[];
|
|
11
|
+
static args: {
|
|
12
|
+
id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
13
|
+
};
|
|
14
|
+
static flags: {
|
|
15
|
+
url: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
|
+
};
|
|
19
|
+
run(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=show.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"show.d.ts","sourceRoot":"","sources":["../../../src/commands/projects/show.ts"],"names":[],"mappings":"AAEA,OAAO,EAAQ,OAAO,EAAS,MAAM,aAAa,CAAC;AAKnD;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IAC/C,OAAgB,WAAW,SAA6C;IAExE,OAAgB,QAAQ,WAGtB;IAEF,OAAgB,IAAI;;MAElB;IAEF,OAAgB,KAAK;;;;MASnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAwC3B"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
import { Args, Command, Flags } from '@oclif/core';
|
|
3
|
+
import { printError } from '../../utils/format.js';
|
|
4
|
+
import { createApiClient, requireAuth } from '../../utils/api-client.js';
|
|
5
|
+
import { formatOutput } from '../../utils/output-formatter.js';
|
|
6
|
+
/**
|
|
7
|
+
* `os projects show <id>` — show detailed information for a single project.
|
|
8
|
+
*
|
|
9
|
+
* Renders the project row plus its database, active credential, and
|
|
10
|
+
* membership row (same shape as `client.projects.get(id)`).
|
|
11
|
+
*/
|
|
12
|
+
export default class ProjectsShow extends Command {
|
|
13
|
+
static description = 'Show detailed information for a project';
|
|
14
|
+
static examples = [
|
|
15
|
+
'$ os projects show 00000000-0000-0000-0000-000000000001',
|
|
16
|
+
'$ os projects show proj-123 --format json',
|
|
17
|
+
];
|
|
18
|
+
static args = {
|
|
19
|
+
id: Args.string({ description: 'Project id', required: true }),
|
|
20
|
+
};
|
|
21
|
+
static flags = {
|
|
22
|
+
url: Flags.string({ char: 'u', description: 'Server URL', env: 'OS_CLOUD_URL' }),
|
|
23
|
+
token: Flags.string({ char: 't', description: 'Authentication token', env: 'OS_TOKEN' }),
|
|
24
|
+
format: Flags.string({
|
|
25
|
+
char: 'f',
|
|
26
|
+
description: 'Output format',
|
|
27
|
+
options: ['json', 'table', 'yaml'],
|
|
28
|
+
default: 'table',
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
31
|
+
async run() {
|
|
32
|
+
const { args, flags } = await this.parse(ProjectsShow);
|
|
33
|
+
try {
|
|
34
|
+
const { client, token } = await createApiClient({ url: flags.url, token: flags.token });
|
|
35
|
+
requireAuth(token);
|
|
36
|
+
const res = await client.projects.get(args.id);
|
|
37
|
+
if (flags.format === 'json') {
|
|
38
|
+
formatOutput(res, 'json');
|
|
39
|
+
}
|
|
40
|
+
else if (flags.format === 'yaml') {
|
|
41
|
+
formatOutput(res, 'yaml');
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const p = res?.project ?? {};
|
|
45
|
+
console.log(`\nProject: ${p.display_name ?? p.id}`);
|
|
46
|
+
console.log('─'.repeat(60));
|
|
47
|
+
console.log(` id: ${p.id}`);
|
|
48
|
+
console.log(` organization: ${p.organization_id ?? '—'}`);
|
|
49
|
+
console.log(` status: ${p.status ?? '—'}`);
|
|
50
|
+
console.log(` plan: ${p.plan ?? '—'}`);
|
|
51
|
+
console.log(` is_default: ${Boolean(p.is_default)}`);
|
|
52
|
+
console.log(` is_system: ${Boolean(p.is_system)}`);
|
|
53
|
+
if (res?.database) {
|
|
54
|
+
console.log(` database: ${res.database.driver ?? '—'} @ ${res.database.database_url ?? '—'}`);
|
|
55
|
+
}
|
|
56
|
+
if (res?.membership) {
|
|
57
|
+
console.log(` yourRole: ${res.membership.role ?? '—'}`);
|
|
58
|
+
}
|
|
59
|
+
console.log('');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
if (flags.format === 'json') {
|
|
64
|
+
console.log(JSON.stringify({ success: false, error: error.message }, null, 2));
|
|
65
|
+
this.exit(1);
|
|
66
|
+
}
|
|
67
|
+
printError(error.message || String(error));
|
|
68
|
+
this.exit(1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=show.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"show.js","sourceRoot":"","sources":["../../../src/commands/projects/show.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
/**
|
|
3
|
+
* `os projects switch <id>` — set the active project for this CLI session.
|
|
4
|
+
*
|
|
5
|
+
* Calls `POST /api/v1/cloud/projects/:id/activate` to update the
|
|
6
|
+
* server-side session, then persists `activeProjectId` into
|
|
7
|
+
* `~/.objectstack/credentials.json` so subsequent CLI commands (and any
|
|
8
|
+
* client they create via `createApiClient`) automatically target this
|
|
9
|
+
* project.
|
|
10
|
+
*/
|
|
11
|
+
export default class ProjectsSwitch extends Command {
|
|
12
|
+
static description: string;
|
|
13
|
+
static examples: string[];
|
|
14
|
+
static args: {
|
|
15
|
+
id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
16
|
+
};
|
|
17
|
+
static flags: {
|
|
18
|
+
url: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
|
+
token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
|
+
remote: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
21
|
+
};
|
|
22
|
+
run(): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=switch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../../src/commands/projects/switch.ts"],"names":[],"mappings":"AAEA,OAAO,EAAQ,OAAO,EAAS,MAAM,aAAa,CAAC;AAKnD;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,OAAO;IACjD,OAAgB,WAAW,SAAiD;IAE5E,OAAgB,QAAQ,WAGtB;IAEF,OAAgB,IAAI;;MAElB;IAEF,OAAgB,KAAK;;;;MAQnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAkC3B"}
|