@liquidmetal-ai/raindrop 0.4.10 → 0.4.12
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 +203 -51
- package/dist/base-command.d.ts +6 -0
- package/dist/base-command.d.ts.map +1 -1
- package/dist/base-command.js +16 -1
- package/dist/codegen.js +3 -3
- package/dist/codegen.test.js +6 -6
- package/dist/commands/bucket/create-credential.d.ts +25 -0
- package/dist/commands/bucket/create-credential.d.ts.map +1 -0
- package/dist/commands/bucket/create-credential.js +171 -0
- package/dist/commands/bucket/delete-credential.d.ts +24 -0
- package/dist/commands/bucket/delete-credential.d.ts.map +1 -0
- package/dist/commands/bucket/delete-credential.js +140 -0
- package/dist/commands/bucket/get-credential.d.ts +24 -0
- package/dist/commands/bucket/get-credential.d.ts.map +1 -0
- package/dist/commands/bucket/get-credential.js +149 -0
- package/dist/commands/bucket/list-credentials.d.ts +23 -0
- package/dist/commands/bucket/list-credentials.d.ts.map +1 -0
- package/dist/commands/bucket/list-credentials.js +146 -0
- package/dist/commands/build/branch.d.ts +1 -0
- package/dist/commands/build/branch.d.ts.map +1 -1
- package/dist/commands/build/branch.js +17 -0
- package/dist/commands/build/deploy.d.ts +1 -0
- package/dist/commands/build/deploy.d.ts.map +1 -1
- package/dist/commands/build/deploy.js +17 -0
- package/dist/commands/build/find.d.ts +2 -0
- package/dist/commands/build/find.d.ts.map +1 -1
- package/dist/commands/build/find.js +143 -16
- package/dist/commands/build/list.d.ts +6 -0
- package/dist/commands/build/list.d.ts.map +1 -1
- package/dist/commands/build/list.js +280 -99
- package/dist/commands/build/status.d.ts +0 -4
- package/dist/commands/build/status.d.ts.map +1 -1
- package/dist/commands/build/status.js +30 -80
- package/dist/commands/object/delete.d.ts.map +1 -1
- package/dist/commands/object/delete.js +10 -8
- package/dist/commands/object/get.d.ts.map +1 -1
- package/dist/commands/object/get.js +9 -8
- package/dist/commands/object/list.d.ts.map +1 -1
- package/dist/commands/object/list.js +8 -6
- package/dist/commands/object/put.d.ts.map +1 -1
- package/dist/commands/object/put.js +12 -10
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/status.d.ts +21 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +137 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/oclif.manifest.json +2219 -1204
- package/package.json +4 -3
- package/templates/db/node_modules/.bin/tsc +17 -0
- package/templates/db/node_modules/.bin/tsserver +17 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { toJsonString } from '@bufbuild/protobuf';
|
|
2
|
+
import { timestampDate } from '@bufbuild/protobuf/wkt';
|
|
3
|
+
import { valueOf } from '@liquidmetal-ai/drizzle/appify/build';
|
|
4
|
+
import { ListCredentialsResponseSchema } from '@liquidmetal-ai/drizzle/liquidmetal/v1alpha1/bucket_api_pb';
|
|
5
|
+
import { Flags } from '@oclif/core';
|
|
6
|
+
import { BaseCommand } from '../../base-command.js';
|
|
7
|
+
export default class ListCredentials extends BaseCommand {
|
|
8
|
+
static description = 'List S3 credentials for a bucket';
|
|
9
|
+
static examples = [
|
|
10
|
+
`<%= config.bin %> bucket list-credentials --bucket my-bucket
|
|
11
|
+
List all credentials for my-bucket
|
|
12
|
+
`,
|
|
13
|
+
`<%= config.bin %> bucket list-credentials --api-url https://bucket.example.com
|
|
14
|
+
List all credentials using a direct API URL
|
|
15
|
+
`,
|
|
16
|
+
];
|
|
17
|
+
static flags = {
|
|
18
|
+
...BaseCommand.HIDDEN_FLAGS,
|
|
19
|
+
bucket: Flags.string({
|
|
20
|
+
char: 'b',
|
|
21
|
+
description: 'bucket name',
|
|
22
|
+
required: false,
|
|
23
|
+
exclusive: ['api-url'],
|
|
24
|
+
}),
|
|
25
|
+
'api-url': Flags.string({
|
|
26
|
+
description: 'direct API URL (bypasses bucket discovery)',
|
|
27
|
+
required: false,
|
|
28
|
+
exclusive: ['bucket', 'application', 'version'],
|
|
29
|
+
}),
|
|
30
|
+
application: Flags.string({
|
|
31
|
+
char: 'a',
|
|
32
|
+
description: 'application name',
|
|
33
|
+
required: false,
|
|
34
|
+
exclusive: ['api-url'],
|
|
35
|
+
}),
|
|
36
|
+
version: Flags.string({
|
|
37
|
+
char: 'v',
|
|
38
|
+
description: 'application version',
|
|
39
|
+
required: false,
|
|
40
|
+
exclusive: ['api-url'],
|
|
41
|
+
}),
|
|
42
|
+
output: Flags.string({
|
|
43
|
+
char: 'o',
|
|
44
|
+
description: 'output format',
|
|
45
|
+
default: 'text',
|
|
46
|
+
options: ['text', 'json'],
|
|
47
|
+
}),
|
|
48
|
+
impersonate: Flags.string({
|
|
49
|
+
char: 'i',
|
|
50
|
+
description: 'impersonate organization',
|
|
51
|
+
required: false,
|
|
52
|
+
hidden: true,
|
|
53
|
+
}),
|
|
54
|
+
manifest: Flags.string({
|
|
55
|
+
char: 'M',
|
|
56
|
+
description: 'project manifest',
|
|
57
|
+
required: false,
|
|
58
|
+
default: 'raindrop.manifest',
|
|
59
|
+
hidden: true,
|
|
60
|
+
}),
|
|
61
|
+
};
|
|
62
|
+
async run() {
|
|
63
|
+
const { flags } = await this.parse(ListCredentials);
|
|
64
|
+
// Validate that we have either api-url or bucket
|
|
65
|
+
if (!flags['api-url'] && !flags.bucket) {
|
|
66
|
+
this.error('Either --api-url or --bucket must be specified');
|
|
67
|
+
}
|
|
68
|
+
let apiUrl;
|
|
69
|
+
let bucketName;
|
|
70
|
+
if (flags['api-url']) {
|
|
71
|
+
// Direct API URL provided, skip discovery
|
|
72
|
+
apiUrl = flags['api-url'];
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
// Need to discover the bucket
|
|
76
|
+
bucketName = flags.bucket;
|
|
77
|
+
// Get application info from flags or config/manifest
|
|
78
|
+
let applicationName = flags.application;
|
|
79
|
+
let applicationVersionId = flags.version;
|
|
80
|
+
if (!applicationVersionId) {
|
|
81
|
+
const config = await this.loadConfig();
|
|
82
|
+
applicationVersionId = config.versionId;
|
|
83
|
+
}
|
|
84
|
+
if (!applicationName) {
|
|
85
|
+
const apps = await this.loadManifest();
|
|
86
|
+
const app = apps[0];
|
|
87
|
+
if (app === undefined) {
|
|
88
|
+
this.error('No application provided or found in manifest', { exit: 1 });
|
|
89
|
+
}
|
|
90
|
+
applicationName = valueOf(app.name);
|
|
91
|
+
}
|
|
92
|
+
// Query for the bucket module
|
|
93
|
+
const { client: catalogService, userId, organizationId: defaultOrganizationId } = await this.catalogService();
|
|
94
|
+
const organizationId = flags.impersonate ?? defaultOrganizationId;
|
|
95
|
+
const modulesResp = await catalogService.queryModules({
|
|
96
|
+
userId,
|
|
97
|
+
applicationName,
|
|
98
|
+
applicationVersionId,
|
|
99
|
+
organizationId,
|
|
100
|
+
moduleType: 'bucket',
|
|
101
|
+
});
|
|
102
|
+
// Find the specific bucket
|
|
103
|
+
const bucketModule = modulesResp.modules.find(m => m.name === bucketName && m.type === 'bucket');
|
|
104
|
+
if (!bucketModule) {
|
|
105
|
+
this.error(`Bucket '${bucketName}' not found in application ${applicationName}@${applicationVersionId}`);
|
|
106
|
+
}
|
|
107
|
+
// Extract the API URL from the bucket module
|
|
108
|
+
apiUrl = bucketModule.bucket?.s3?.apiUrl;
|
|
109
|
+
if (!apiUrl) {
|
|
110
|
+
this.error(`Bucket '${bucketName}' does not have an API URL configured`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Create the S3 credential service client
|
|
114
|
+
const { client: credentialService } = await this.bucketApiService(apiUrl);
|
|
115
|
+
try {
|
|
116
|
+
const response = await credentialService.listCredentials({});
|
|
117
|
+
// Output the result
|
|
118
|
+
if (flags.output === 'json') {
|
|
119
|
+
console.log(toJsonString(ListCredentialsResponseSchema, response, { prettySpaces: 2 }));
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
const credentials = response.credentials;
|
|
123
|
+
if (credentials.length === 0) {
|
|
124
|
+
console.log(`No credentials found${bucketName ? ` for bucket '${bucketName}'` : ''}`);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
console.log(`Found ${credentials.length} credential${credentials.length === 1 ? '' : 's'}${bucketName ? ` for bucket '${bucketName}'` : ''}:\n`);
|
|
128
|
+
for (const cred of credentials) {
|
|
129
|
+
console.log(`Access Key: ${cred.accessKey}`);
|
|
130
|
+
console.log(`Name: ${cred.name}`);
|
|
131
|
+
if (cred.createdAt) {
|
|
132
|
+
console.log(`Created: ${timestampDate(cred.createdAt).toISOString()}`);
|
|
133
|
+
}
|
|
134
|
+
if (cred.expiresAt) {
|
|
135
|
+
console.log(`Expires: ${timestampDate(cred.expiresAt).toISOString()}`);
|
|
136
|
+
}
|
|
137
|
+
console.log('---');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
const err = error;
|
|
143
|
+
this.error(`Failed to list credentials: ${err.message}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -12,6 +12,7 @@ export default class Branch extends BaseCommand<typeof Branch> {
|
|
|
12
12
|
versionId: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
13
|
impersonate: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
14
|
start: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
15
|
+
'no-watch': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
15
16
|
show: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
16
17
|
config: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
18
|
rainbowAuthService: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branch.d.ts","sourceRoot":"","sources":["../../../src/commands/build/branch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"branch.d.ts","sourceRoot":"","sources":["../../../src/commands/build/branch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW,CAAC,OAAO,MAAM,CAAC;IAC5D,MAAM,CAAC,IAAI;;MAET;IAEF,MAAM,CAAC,WAAW,SAAmC;IAErD,MAAM,CAAC,QAAQ,WAIb;IAEF,MAAM,CAAC,KAAK;;;;;;;;;;;;;;;;MAiCV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA+D3B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
2
|
import { BaseCommand } from '../../base-command.js';
|
|
3
3
|
import { deploy, sandbox } from '../../deploy.js';
|
|
4
|
+
import { watchStatus } from '../../status.js';
|
|
4
5
|
export default class Branch extends BaseCommand {
|
|
5
6
|
static args = {
|
|
6
7
|
branch: Args.string({ description: 'branch name', required: true }),
|
|
@@ -38,6 +39,11 @@ Branch a Raindrop application.
|
|
|
38
39
|
default: false,
|
|
39
40
|
required: false,
|
|
40
41
|
}),
|
|
42
|
+
'no-watch': Flags.boolean({
|
|
43
|
+
description: 'skip watching deployment status after branch',
|
|
44
|
+
required: false,
|
|
45
|
+
default: false,
|
|
46
|
+
}),
|
|
41
47
|
show: Flags.boolean({ description: 'show the current branch', required: false }),
|
|
42
48
|
};
|
|
43
49
|
async run() {
|
|
@@ -87,5 +93,16 @@ Branch a Raindrop application.
|
|
|
87
93
|
throw error;
|
|
88
94
|
}
|
|
89
95
|
this.log(`🔔 Branch is in Sandbox mode`);
|
|
96
|
+
// Show status with watch output
|
|
97
|
+
if (!this.flags['no-watch']) {
|
|
98
|
+
this.log('\n📊 Watching deployment status...\n');
|
|
99
|
+
await watchStatus({
|
|
100
|
+
command: this,
|
|
101
|
+
root: this.flags.root,
|
|
102
|
+
manifest: this.flags.manifest,
|
|
103
|
+
output: 'watch',
|
|
104
|
+
impersonate: this.flags.impersonate,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
90
107
|
}
|
|
91
108
|
}
|
|
@@ -10,6 +10,7 @@ export default class Deploy extends BaseCommand<typeof Deploy> {
|
|
|
10
10
|
versionId: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
11
|
impersonate: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
12
|
start: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
'no-watch': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
14
|
resume: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
15
|
lock: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
16
|
amend: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../../src/commands/build/deploy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../../src/commands/build/deploy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW,CAAC,OAAO,MAAM,CAAC;IAC5D,MAAM,CAAC,IAAI,KAAM;IAEjB,MAAM,CAAC,WAAW,SAAmC;IAErD,MAAM,CAAC,QAAQ,WAIb;IAEF,MAAM,CAAC,KAAK;;;;;;;;;;;;;;;;;;MA2CV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAuD3B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
2
|
import { BaseCommand } from '../../base-command.js';
|
|
3
3
|
import { deploy } from '../../deploy.js';
|
|
4
|
+
import { watchStatus } from '../../status.js';
|
|
4
5
|
export default class Deploy extends BaseCommand {
|
|
5
6
|
static args = {};
|
|
6
7
|
static description = 'deploy a Raindrop application';
|
|
@@ -37,6 +38,11 @@ Deploy a Raindrop application version.
|
|
|
37
38
|
required: false,
|
|
38
39
|
default: false,
|
|
39
40
|
}),
|
|
41
|
+
'no-watch': Flags.boolean({
|
|
42
|
+
description: 'skip watching deployment status after deploy',
|
|
43
|
+
required: false,
|
|
44
|
+
default: false,
|
|
45
|
+
}),
|
|
40
46
|
resume: Flags.boolean({
|
|
41
47
|
description: 'resume a deployment',
|
|
42
48
|
required: false,
|
|
@@ -81,5 +87,16 @@ Deploy a Raindrop application version.
|
|
|
81
87
|
if (!amend) {
|
|
82
88
|
this.log(`🔔 You deployed a full version, updates will require a full versioned deployment to work`);
|
|
83
89
|
}
|
|
90
|
+
// Show status with watch output
|
|
91
|
+
if (!this.flags['no-watch']) {
|
|
92
|
+
this.log('\n📊 Watching deployment status...\n');
|
|
93
|
+
await watchStatus({
|
|
94
|
+
command: this,
|
|
95
|
+
root: this.flags.root,
|
|
96
|
+
manifest: this.flags.manifest,
|
|
97
|
+
output: 'watch',
|
|
98
|
+
impersonate: this.flags.impersonate,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
84
101
|
}
|
|
85
102
|
}
|
|
@@ -29,6 +29,8 @@ export default class Find extends BaseCommand<typeof Find> {
|
|
|
29
29
|
moduleType?: string;
|
|
30
30
|
all?: boolean;
|
|
31
31
|
}): Promise<void>;
|
|
32
|
+
private extractModuleAttributes;
|
|
33
|
+
private flattenObject;
|
|
32
34
|
queryResources(flags: {
|
|
33
35
|
output: string;
|
|
34
36
|
rainbowAuthService: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../../src/commands/build/find.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../../src/commands/build/find.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,WAAW,CAAC,OAAO,IAAI,CAAC;IACxD,MAAM,CAAC,IAAI,KAAM;IAEjB,MAAM,CAAC,WAAW,SAAgC;IAElD,MAAM,CAAC,QAAQ,WAab;IAEF,MAAM,CAAC,KAAK;;;;;;;;;;;;;;;;;MA6CV;IAEI,YAAY,CAAC,KAAK,EAAE;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,kBAAkB,EAAE,MAAM,CAAC;QAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,GAAG,CAAC,EAAE,OAAO,CAAC;KACf;IAuID,OAAO,CAAC,uBAAuB;IAe/B,OAAO,CAAC,aAAa;IAsBf,cAAc,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE;IA+C5G,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAO3B"}
|
|
@@ -1,15 +1,26 @@
|
|
|
1
|
+
import { toJsonString } from '@bufbuild/protobuf';
|
|
1
2
|
import { timestampDate } from '@bufbuild/protobuf/wkt';
|
|
2
3
|
import { valueOf } from '@liquidmetal-ai/drizzle/appify/build';
|
|
4
|
+
import { QueryModulesResponseSchema, QueryResourcesResponseSchema, } from '@liquidmetal-ai/drizzle/liquidmetal/v1alpha1/catalog_pb';
|
|
3
5
|
import { Flags } from '@oclif/core';
|
|
6
|
+
import chalk from 'chalk';
|
|
4
7
|
import { BaseCommand } from '../../base-command.js';
|
|
5
8
|
import { EPOCH_TS } from '../../index.js';
|
|
6
|
-
import { toJsonString } from '@bufbuild/protobuf';
|
|
7
|
-
import { QueryModulesResponseSchema, QueryResourcesResponseSchema, } from '@liquidmetal-ai/drizzle/liquidmetal/v1alpha1/catalog_pb';
|
|
8
9
|
export default class Find extends BaseCommand {
|
|
9
10
|
static args = {};
|
|
10
11
|
static description = 'find resources in Raindrop';
|
|
11
12
|
static examples = [
|
|
12
|
-
`<%= config.bin %> <%= command.id %>
|
|
13
|
+
`<%= config.bin %> <%= command.id %>
|
|
14
|
+
Find all modules with full details (default).
|
|
15
|
+
|
|
16
|
+
<%= config.bin %> <%= command.id %> -o compact
|
|
17
|
+
Find all modules in compact view.
|
|
18
|
+
|
|
19
|
+
<%= config.bin %> <%= command.id %> --moduleType smartbucket
|
|
20
|
+
Find only smartbucket modules.
|
|
21
|
+
|
|
22
|
+
<%= config.bin %> <%= command.id %> -a myapp -v 1.0.0
|
|
23
|
+
Find modules for a specific application and version.
|
|
13
24
|
`,
|
|
14
25
|
];
|
|
15
26
|
static flags = {
|
|
@@ -38,8 +49,8 @@ export default class Find extends BaseCommand {
|
|
|
38
49
|
output: Flags.string({
|
|
39
50
|
char: 'o',
|
|
40
51
|
description: 'output format',
|
|
41
|
-
default: '
|
|
42
|
-
options: ['text', '
|
|
52
|
+
default: 'full',
|
|
53
|
+
options: ['text', 'full', 'json', 'compact'],
|
|
43
54
|
}),
|
|
44
55
|
sudo: Flags.boolean({
|
|
45
56
|
char: 's',
|
|
@@ -84,26 +95,142 @@ export default class Find extends BaseCommand {
|
|
|
84
95
|
organizationId,
|
|
85
96
|
moduleType: flags.moduleType || '',
|
|
86
97
|
});
|
|
87
|
-
if (flags.output === '
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
98
|
+
if (flags.output === 'compact') {
|
|
99
|
+
// Group modules by application
|
|
100
|
+
const modulesByApp = resp.modules.reduce((acc, module) => {
|
|
101
|
+
const appKey = `${module.applicationName}@${module.applicationVersionId}`;
|
|
102
|
+
if (!acc[appKey]) {
|
|
103
|
+
acc[appKey] = [];
|
|
104
|
+
}
|
|
105
|
+
acc[appKey].push(module);
|
|
94
106
|
return acc;
|
|
95
|
-
},
|
|
96
|
-
//
|
|
97
|
-
|
|
107
|
+
}, {});
|
|
108
|
+
// Display grouped modules in compact format
|
|
109
|
+
for (const [appKey, modules] of Object.entries(modulesByApp)) {
|
|
110
|
+
console.log(`\n${chalk.bold(appKey)} ${chalk.dim(`(${modules.length} module${modules.length !== 1 ? 's' : ''})`)}`);
|
|
111
|
+
for (const module of modules) {
|
|
112
|
+
const convergedStatus = module.convergedAt
|
|
113
|
+
? chalk.green('converged')
|
|
114
|
+
: chalk.yellow('pending');
|
|
115
|
+
const date = module.convergedAt
|
|
116
|
+
? timestampDate(module.convergedAt).toLocaleDateString()
|
|
117
|
+
: 'N/A';
|
|
118
|
+
console.log(` └─ ${chalk.cyan(module.name)} ${chalk.dim(`(${module.moduleId.substring(0, 8)}...)`)} ${chalk.yellow(module.type)} - ${convergedStatus} - ${chalk.dim(date)}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Add summary at the end
|
|
122
|
+
const totalApps = Object.keys(modulesByApp).length;
|
|
123
|
+
const totalModules = resp.modules.length;
|
|
124
|
+
const convergedModules = resp.modules.filter(m => m.convergedAt).length;
|
|
125
|
+
console.log('');
|
|
126
|
+
console.log(chalk.dim('─'.repeat(50)));
|
|
127
|
+
console.log(chalk.dim(`Total: ${totalApps} application${totalApps !== 1 ? 's' : ''}, ${totalModules} modules (${convergedModules} converged)`));
|
|
128
|
+
}
|
|
129
|
+
else if (flags.output === 'full') {
|
|
130
|
+
// Group modules by application
|
|
131
|
+
const modulesByApp = resp.modules.reduce((acc, module) => {
|
|
132
|
+
const appKey = `${module.applicationName}@${module.applicationVersionId}`;
|
|
133
|
+
if (!acc[appKey]) {
|
|
134
|
+
acc[appKey] = [];
|
|
135
|
+
}
|
|
136
|
+
acc[appKey].push(module);
|
|
137
|
+
return acc;
|
|
138
|
+
}, {});
|
|
139
|
+
// Display grouped modules in full format (compact style with all details)
|
|
140
|
+
for (const [appKey, modules] of Object.entries(modulesByApp)) {
|
|
141
|
+
console.log(`\n${chalk.bold(appKey)} ${chalk.dim(`(${modules.length} module${modules.length !== 1 ? 's' : ''})`)}`);
|
|
142
|
+
for (const module of modules) {
|
|
143
|
+
const convergedStatus = module.convergedAt
|
|
144
|
+
? chalk.green('converged')
|
|
145
|
+
: chalk.yellow('pending');
|
|
146
|
+
const date = module.convergedAt
|
|
147
|
+
? timestampDate(module.convergedAt).toISOString()
|
|
148
|
+
: 'N/A';
|
|
149
|
+
// First line with basic info
|
|
150
|
+
console.log(` └─ ${chalk.cyan(module.name)} ${chalk.dim(`(${module.moduleId})`)} ${chalk.yellow(module.type)}`);
|
|
151
|
+
console.log(` Status: ${convergedStatus} at ${chalk.dim(date)}`);
|
|
152
|
+
// Module-specific attributes
|
|
153
|
+
const attrs = this.extractModuleAttributes(module);
|
|
154
|
+
if (Object.keys(attrs).length > 0) {
|
|
155
|
+
console.log(` ${chalk.bold('Attributes:')}`);
|
|
156
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
157
|
+
console.log(` ${key}: ${chalk.yellow(String(value))}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Add summary at the end
|
|
163
|
+
const totalApps = Object.keys(modulesByApp).length;
|
|
164
|
+
const totalModules = resp.modules.length;
|
|
165
|
+
const convergedModules = resp.modules.filter(m => m.convergedAt).length;
|
|
166
|
+
console.log('');
|
|
167
|
+
console.log(chalk.dim('─'.repeat(50)));
|
|
168
|
+
console.log(chalk.dim(`Total: ${totalApps} application${totalApps !== 1 ? 's' : ''}, ${totalModules} modules (${convergedModules} converged)`));
|
|
98
169
|
}
|
|
99
170
|
else if (flags.output === 'json') {
|
|
100
171
|
console.log(toJsonString(QueryModulesResponseSchema, resp, { prettySpaces: 2 }));
|
|
101
172
|
}
|
|
102
173
|
else {
|
|
103
174
|
for (const m of resp.modules) {
|
|
104
|
-
|
|
175
|
+
// Build a detailed text output
|
|
176
|
+
let details = `${m.name} ${m.moduleId} ${m.type}`;
|
|
177
|
+
// Add module-specific details
|
|
178
|
+
const attrs = this.extractModuleAttributes(m);
|
|
179
|
+
const attrString = Object.entries(attrs)
|
|
180
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
181
|
+
.join(' ');
|
|
182
|
+
if (attrString) {
|
|
183
|
+
details += ` ${attrString}`;
|
|
184
|
+
}
|
|
185
|
+
if (m.convergedAt) {
|
|
186
|
+
details += ` converged=${timestampDate(m.convergedAt).toISOString()}`;
|
|
187
|
+
}
|
|
188
|
+
console.log(details);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
extractModuleAttributes(module) {
|
|
193
|
+
// Check each possible module field and extract attributes
|
|
194
|
+
if (module.smartBucket)
|
|
195
|
+
return this.flattenObject(module.smartBucket);
|
|
196
|
+
if (module.bucket)
|
|
197
|
+
return this.flattenObject(module.bucket);
|
|
198
|
+
if (module.service)
|
|
199
|
+
return this.flattenObject(module.service);
|
|
200
|
+
if (module.observer)
|
|
201
|
+
return this.flattenObject(module.observer);
|
|
202
|
+
if (module.task)
|
|
203
|
+
return this.flattenObject(module.task);
|
|
204
|
+
if (module.sqlDatabase)
|
|
205
|
+
return this.flattenObject(module.sqlDatabase);
|
|
206
|
+
if (module.vectorIndex)
|
|
207
|
+
return this.flattenObject(module.vectorIndex);
|
|
208
|
+
if (module.queue)
|
|
209
|
+
return this.flattenObject(module.queue);
|
|
210
|
+
if (module.kvStore)
|
|
211
|
+
return this.flattenObject(module.kvStore);
|
|
212
|
+
if (module.smartMemory)
|
|
213
|
+
return this.flattenObject(module.smartMemory);
|
|
214
|
+
return {};
|
|
215
|
+
}
|
|
216
|
+
flattenObject(obj, parentKey = '') {
|
|
217
|
+
const result = {};
|
|
218
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
219
|
+
if (value === null || value === undefined)
|
|
220
|
+
continue;
|
|
221
|
+
// Skip protobuf internal fields
|
|
222
|
+
if (key === '$typeName' || key === '$unknown')
|
|
223
|
+
continue;
|
|
224
|
+
const newKey = parentKey ? `${parentKey}.${key}` : key;
|
|
225
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
226
|
+
// Recursively flatten nested objects
|
|
227
|
+
Object.assign(result, this.flattenObject(value, newKey));
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
result[newKey] = value;
|
|
105
231
|
}
|
|
106
232
|
}
|
|
233
|
+
return result;
|
|
107
234
|
}
|
|
108
235
|
async queryResources(flags) {
|
|
109
236
|
if (!flags.version) {
|
|
@@ -15,6 +15,9 @@ export default class List extends BaseCommand<typeof List> {
|
|
|
15
15
|
static flags: {
|
|
16
16
|
all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
17
17
|
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
|
+
app: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
|
+
limit: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
|
+
active: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
18
21
|
impersonate: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
22
|
manifest: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
23
|
config: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -30,6 +33,9 @@ export default class List extends BaseCommand<typeof List> {
|
|
|
30
33
|
nodesMap: Map<string, VersionNode>;
|
|
31
34
|
};
|
|
32
35
|
renderGitLogStyle(applications: ApplicationsResponse_Application[]): string;
|
|
36
|
+
groupApplicationsByName(applications: ApplicationsResponse_Application[]): Map<string, ApplicationsResponse_Application[]>;
|
|
37
|
+
renderCompactView(applications: ApplicationsResponse_Application[]): string;
|
|
38
|
+
renderTreeView(applications: ApplicationsResponse_Application[]): string;
|
|
33
39
|
listApplications(): Promise<void>;
|
|
34
40
|
run(): Promise<void>;
|
|
35
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/build/list.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/build/list.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,gCAAgC,EAEhC,SAAS,EACV,MAAM,yDAAyD,CAAC;AAGjE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,UAAU,WAAW;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,gCAAgC,CAAC;IAC9C,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CASzC,CAAC;AAEX,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,WAAW,CAAC,OAAO,IAAI,CAAC;IACxD,MAAM,CAAC,IAAI,KAAM;IAEjB,MAAM,CAAC,WAAW,SAAqC;IAEvD,MAAM,CAAC,QAAQ,WAgBb;IAEF,MAAM,CAAC,KAAK;;;;;;;;;;;;;;;MAmCV;IAEF,gBAAgB,CAAC,YAAY,EAAE,gCAAgC,EAAE;;;;IAkCjE,iBAAiB,CAAC,YAAY,EAAE,gCAAgC,EAAE;IAuIlE,uBAAuB,CAAC,YAAY,EAAE,gCAAgC,EAAE;IAwBxE,iBAAiB,CAAC,YAAY,EAAE,gCAAgC,EAAE;IA+DlE,cAAc,CAAC,YAAY,EAAE,gCAAgC,EAAE;IAiDzD,gBAAgB;IA8DhB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAG3B"}
|