@liquidmetal-ai/raindrop 0.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.
Files changed (89) hide show
  1. package/README.md +777 -0
  2. package/bin/dev.cmd +3 -0
  3. package/bin/dev.js +6 -0
  4. package/bin/run.cmd +3 -0
  5. package/bin/run.js +5 -0
  6. package/dist/base-command.d.ts +27 -0
  7. package/dist/base-command.d.ts.map +1 -0
  8. package/dist/base-command.js +69 -0
  9. package/dist/build.d.ts +13 -0
  10. package/dist/build.d.ts.map +1 -0
  11. package/dist/build.js +86 -0
  12. package/dist/build.test.d.ts +2 -0
  13. package/dist/build.test.d.ts.map +1 -0
  14. package/dist/build.test.js +41 -0
  15. package/dist/codegen.d.ts +32 -0
  16. package/dist/codegen.d.ts.map +1 -0
  17. package/dist/codegen.js +212 -0
  18. package/dist/codegen.test.d.ts +2 -0
  19. package/dist/codegen.test.d.ts.map +1 -0
  20. package/dist/codegen.test.js +97 -0
  21. package/dist/commands/auth/list.d.ts +10 -0
  22. package/dist/commands/auth/list.d.ts.map +1 -0
  23. package/dist/commands/auth/list.js +55 -0
  24. package/dist/commands/auth/login.d.ts +10 -0
  25. package/dist/commands/auth/login.d.ts.map +1 -0
  26. package/dist/commands/auth/login.js +69 -0
  27. package/dist/commands/auth/logout.d.ts +8 -0
  28. package/dist/commands/auth/logout.d.ts.map +1 -0
  29. package/dist/commands/auth/logout.js +15 -0
  30. package/dist/commands/auth/select.d.ts +10 -0
  31. package/dist/commands/auth/select.d.ts.map +1 -0
  32. package/dist/commands/auth/select.js +39 -0
  33. package/dist/commands/build/branch.d.ts +16 -0
  34. package/dist/commands/build/branch.d.ts.map +1 -0
  35. package/dist/commands/build/branch.js +81 -0
  36. package/dist/commands/build/delete.d.ts +19 -0
  37. package/dist/commands/build/delete.d.ts.map +1 -0
  38. package/dist/commands/build/delete.js +99 -0
  39. package/dist/commands/build/deploy.d.ts +18 -0
  40. package/dist/commands/build/deploy.d.ts.map +1 -0
  41. package/dist/commands/build/deploy.js +144 -0
  42. package/dist/commands/build/env/get.d.ts +19 -0
  43. package/dist/commands/build/env/get.d.ts.map +1 -0
  44. package/dist/commands/build/env/get.js +101 -0
  45. package/dist/commands/build/env/set.d.ts +20 -0
  46. package/dist/commands/build/env/set.d.ts.map +1 -0
  47. package/dist/commands/build/env/set.js +115 -0
  48. package/dist/commands/build/find.d.ts +24 -0
  49. package/dist/commands/build/find.d.ts.map +1 -0
  50. package/dist/commands/build/find.js +110 -0
  51. package/dist/commands/build/generate.d.ts +13 -0
  52. package/dist/commands/build/generate.d.ts.map +1 -0
  53. package/dist/commands/build/generate.js +38 -0
  54. package/dist/commands/build/init.d.ts +15 -0
  55. package/dist/commands/build/init.d.ts.map +1 -0
  56. package/dist/commands/build/init.js +57 -0
  57. package/dist/commands/build/list.d.ts +17 -0
  58. package/dist/commands/build/list.d.ts.map +1 -0
  59. package/dist/commands/build/list.js +100 -0
  60. package/dist/commands/build/start.d.ts +16 -0
  61. package/dist/commands/build/start.d.ts.map +1 -0
  62. package/dist/commands/build/start.js +71 -0
  63. package/dist/commands/build/stop.d.ts +15 -0
  64. package/dist/commands/build/stop.d.ts.map +1 -0
  65. package/dist/commands/build/stop.js +67 -0
  66. package/dist/commands/build/token.d.ts +9 -0
  67. package/dist/commands/build/token.d.ts.map +1 -0
  68. package/dist/commands/build/token.js +42 -0
  69. package/dist/commands/build/upload.d.ts +17 -0
  70. package/dist/commands/build/upload.d.ts.map +1 -0
  71. package/dist/commands/build/upload.js +75 -0
  72. package/dist/commands/build/validate.d.ts +13 -0
  73. package/dist/commands/build/validate.d.ts.map +1 -0
  74. package/dist/commands/build/validate.js +26 -0
  75. package/dist/config.d.ts +13 -0
  76. package/dist/config.d.ts.map +1 -0
  77. package/dist/config.js +34 -0
  78. package/dist/config.test.d.ts +2 -0
  79. package/dist/config.test.d.ts.map +1 -0
  80. package/dist/config.test.js +24 -0
  81. package/dist/index.d.ts +18 -0
  82. package/dist/index.d.ts.map +1 -0
  83. package/dist/index.js +140 -0
  84. package/dist/index.test.d.ts +2 -0
  85. package/dist/index.test.d.ts.map +1 -0
  86. package/dist/index.test.js +4 -0
  87. package/dist/tsconfig.tsbuildinfo +1 -0
  88. package/oclif.manifest.json +1208 -0
  89. package/package.json +107 -0
@@ -0,0 +1,55 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../base-command.js';
3
+ import { readState } from '../../index.js';
4
+ export default class List extends BaseCommand {
5
+ static args = {};
6
+ static description = 'List authentications';
7
+ static flags = {
8
+ output: Flags.string({
9
+ char: 'o',
10
+ description: 'output format',
11
+ default: 'table',
12
+ options: ['text', 'table', 'json'],
13
+ }),
14
+ };
15
+ async run() {
16
+ const state = await readState(this.config.configDir);
17
+ switch (this.flags.output) {
18
+ case 'text':
19
+ for (const [orgId, token] of Object.entries(state.organizationIdToBearerToken)) {
20
+ const isSelected = token.organizationId === state.currentOrganizationId;
21
+ console.log(`${orgId}${isSelected ? ' (current)' : ''} - ${token.userEmail} ${token.organizationName}`);
22
+ }
23
+ break;
24
+ case 'json':
25
+ console.log(JSON.stringify(Object.entries(state.organizationIdToBearerToken).map(([_, token]) => {
26
+ const isSelected = token.organizationId === state.currentOrganizationId;
27
+ return {
28
+ organizationId: token.organizationId,
29
+ organizationName: token.organizationName,
30
+ userEmail: token.userEmail,
31
+ isSelected,
32
+ };
33
+ })));
34
+ break;
35
+ case 'table':
36
+ console.table(Object.entries(state.organizationIdToBearerToken)
37
+ .map(([_, token]) => {
38
+ const isSelected = token.organizationId === state.currentOrganizationId;
39
+ return {
40
+ organizationId: token.organizationId,
41
+ organizationName: token.organizationName,
42
+ userEmail: token.userEmail,
43
+ isSelected,
44
+ };
45
+ })
46
+ .reduce((memo, row) => {
47
+ memo[row.organizationId] = row;
48
+ return memo;
49
+ },
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
+ {}), ['organizationName', 'userEmail', 'isSelected']);
52
+ break;
53
+ }
54
+ }
55
+ }
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ export default class Login extends BaseCommand<typeof Login> {
3
+ static args: {};
4
+ static description: string;
5
+ static flags: {
6
+ rainbowAuthService: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/login.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAQpD,MAAM,CAAC,OAAO,OAAO,KAAM,SAAQ,WAAW,CAAC,OAAO,KAAK,CAAC;IAC1D,MAAM,CAAC,IAAI,KAAM;IAEjB,MAAM,CAAC,WAAW,SAAuF;IAEzG,MAAM,CAAC,KAAK;;MAMV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA8D3B"}
@@ -0,0 +1,69 @@
1
+ import { RainbowAuthService } from '@liquidmetal-ai/drizzle/liquidmetal/v1alpha1/rainbow_auth_connect';
2
+ import { Flags } from '@oclif/core';
3
+ import open from 'open';
4
+ import qrcode from 'qrcode-terminal';
5
+ import { spinner } from 'zx';
6
+ import { BaseCommand } from '../../base-command.js';
7
+ import { readState, replaceState, useClient } from '../../index.js';
8
+ function sleep(dur) {
9
+ const ms = dur.nanos / 1e6 + Number(dur.seconds * 1000n);
10
+ return new Promise((resolve) => setTimeout(resolve, ms));
11
+ }
12
+ export default class Login extends BaseCommand {
13
+ static args = {};
14
+ static description = 'Logs a user into the LiquidMetal platform. Supports browser-based authentication.';
15
+ static flags = {
16
+ rainbowAuthService: Flags.string({
17
+ default: 'https://liquidmetal.run/api/connect',
18
+ hidden: true,
19
+ env: 'LIQUIDMETAL_RAINBOW_AUTH_SERVICE',
20
+ }),
21
+ };
22
+ async run() {
23
+ const rainbowAuth = useClient(RainbowAuthService, this.flags.rainbowAuthService);
24
+ const clientId = `raindrop@${this.config.version}`;
25
+ const { deviceCode, verificationUriComplete, expiresAt, interval: initialInterval, } = await rainbowAuth.deviceAuthorization({
26
+ clientId,
27
+ });
28
+ if (!expiresAt || !initialInterval) {
29
+ throw new Error(`expected expiresAt and interval to be set`);
30
+ }
31
+ qrcode.generate(verificationUriComplete, { small: true });
32
+ console.log(`Scan the QR code or, using a browser visit: ${verificationUriComplete}`);
33
+ console.log('\n\nopening url...');
34
+ open(verificationUriComplete);
35
+ await spinner('Waiting for session...', async () => {
36
+ let interval = initialInterval;
37
+ let done = false;
38
+ while (!done) {
39
+ if (new Date() > expiresAt.toDate()) {
40
+ console.error('failed to authenticate in time');
41
+ this.exit(1);
42
+ }
43
+ await sleep(interval);
44
+ const { response } = await rainbowAuth.deviceAccessToken({
45
+ deviceCode,
46
+ });
47
+ switch (response.case) {
48
+ case 'authorizationPending':
49
+ if (response.value.interval) {
50
+ interval = response.value.interval;
51
+ }
52
+ break;
53
+ case 'bearerToken':
54
+ {
55
+ const state = await readState(this.config.configDir);
56
+ state.currentOrganizationId = response.value.organizationId;
57
+ state.organizationIdToBearerToken[response.value.organizationId] = response.value;
58
+ await replaceState(this.config.configDir, state);
59
+ console.log(`Logged in as ${response.value.userEmail} to ${response.value.organizationName}`);
60
+ }
61
+ done = true;
62
+ break;
63
+ default:
64
+ console.error(`unhandled device access token response case=${response.case}`);
65
+ }
66
+ }
67
+ });
68
+ }
69
+ }
@@ -0,0 +1,8 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ export default class Logout extends BaseCommand<typeof Logout> {
3
+ static args: {};
4
+ static description: string;
5
+ static flags: {};
6
+ run(): Promise<void>;
7
+ }
8
+ //# sourceMappingURL=logout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW,CAAC,OAAO,MAAM,CAAC;IAC5D,MAAM,CAAC,IAAI,KAAM;IAEjB,MAAM,CAAC,WAAW,SAA4B;IAE9C,MAAM,CAAC,KAAK,KAAM;IAEZ,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAU3B"}
@@ -0,0 +1,15 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ import { readState, replaceState } from '../../index.js';
3
+ export default class Logout extends BaseCommand {
4
+ static args = {};
5
+ static description = 'Logout authentications';
6
+ static flags = {};
7
+ async run() {
8
+ const state = await readState(this.config.configDir);
9
+ if (state.currentOrganizationId) {
10
+ delete state.organizationIdToBearerToken[state.currentOrganizationId];
11
+ state.currentOrganizationId = undefined;
12
+ }
13
+ await replaceState(this.config.configDir, state);
14
+ }
15
+ }
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ export default class Select extends BaseCommand<typeof Select> {
3
+ static args: {};
4
+ static description: string;
5
+ static flags: {
6
+ organizationId: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/select.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW,CAAC,OAAO,MAAM,CAAC;IAC5D,MAAM,CAAC,IAAI,KAAM;IAEjB,MAAM,CAAC,WAAW,SAAgC;IAElD,MAAM,CAAC,KAAK;;MAIV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA+B3B"}
@@ -0,0 +1,39 @@
1
+ import { select } from '@inquirer/prompts';
2
+ import { Flags } from '@oclif/core';
3
+ import { BaseCommand } from '../../base-command.js';
4
+ import { readState, replaceState } from '../../index.js';
5
+ export default class Select extends BaseCommand {
6
+ static args = {};
7
+ static description = 'Select active organization';
8
+ static flags = {
9
+ organizationId: Flags.string({
10
+ description: 'organizationId to select as active',
11
+ }),
12
+ };
13
+ async run() {
14
+ const state = await readState(this.config.configDir);
15
+ let organizationId = this.flags.organizationId;
16
+ if (!organizationId) {
17
+ if (Object.entries(state.organizationIdToBearerToken).length === 0) {
18
+ this.error(`no organizations are authorized. see raindrop auth login.`);
19
+ }
20
+ organizationId = await select({
21
+ message: 'Select an organization',
22
+ default: state.currentOrganizationId,
23
+ choices: Object.entries(state.organizationIdToBearerToken)
24
+ .map(([_, token]) => {
25
+ return {
26
+ name: `${token.userEmail} - ${token.organizationName}`,
27
+ value: token.organizationId,
28
+ };
29
+ })
30
+ .sort((a, b) => a.name.localeCompare(b.name)),
31
+ });
32
+ }
33
+ if (!state.organizationIdToBearerToken[organizationId]) {
34
+ this.error(`${organizationId} not authenticated`);
35
+ }
36
+ state.currentOrganizationId = organizationId;
37
+ await replaceState(this.config.configDir, state);
38
+ }
39
+ }
@@ -0,0 +1,16 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ export default class Branch extends BaseCommand<typeof Branch> {
3
+ static args: {};
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ previousVersionId: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ select: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ impersonate: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ rainbowAuthService: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ config: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
12
+ manifest: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=branch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch.d.ts","sourceRoot":"","sources":["../../../src/commands/build/branch.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW,CAAC,OAAO,MAAM,CAAC;IAC5D,MAAM,CAAC,IAAI,KAAM;IAEjB,MAAM,CAAC,WAAW,SAAiD;IAEnE,MAAM,CAAC,QAAQ,WAGb;IAEF,MAAM,CAAC,KAAK;;;;;;;MA8BV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA2C3B"}
@@ -0,0 +1,81 @@
1
+ import { valueOf } from '@liquidmetal-ai/drizzle/appify/build';
2
+ import { Flags } from '@oclif/core';
3
+ import { BaseCommand } from '../../base-command.js';
4
+ export default class Branch extends BaseCommand {
5
+ static args = {};
6
+ static description = 'create a new branch in the Raindrop catalog';
7
+ static examples = [
8
+ `<%= config.bin %> <%= command.id %> .
9
+ Create a new branch in the Raindrop catalog.`,
10
+ ];
11
+ static flags = {
12
+ previousVersionId: Flags.string({
13
+ char: 'p',
14
+ aliases: ['prev'],
15
+ description: 'previous version ID',
16
+ required: false,
17
+ exclusive: ['select'],
18
+ }),
19
+ select: Flags.string({
20
+ char: 's',
21
+ description: 'select a specific version ID',
22
+ required: false,
23
+ exclusive: ['previousVersionId'],
24
+ }),
25
+ impersonate: Flags.string({
26
+ char: 'i',
27
+ description: 'impersonate organization',
28
+ required: false,
29
+ hidden: true,
30
+ }),
31
+ rainbowAuthService: Flags.string({
32
+ default: 'https://liquidmetal.run/api/connect',
33
+ hidden: true,
34
+ env: 'LIQUIDMETAL_RAINBOW_AUTH_SERVICE',
35
+ }),
36
+ config: Flags.string({
37
+ default: '.raindrop/config.json',
38
+ hidden: true,
39
+ }),
40
+ manifest: Flags.string({ default: 'raindrop.manifest', description: 'project manifest' }),
41
+ };
42
+ async run() {
43
+ const { client: catalogService, userId, organizationId: defaultOrganizationId } = await this.catalogService();
44
+ const organizationId = this.flags.impersonate ?? defaultOrganizationId;
45
+ const config = await this.loadConfig();
46
+ // If we're selecting a version, just update config.
47
+ if (this.flags.select) {
48
+ // Check if this is a valid version.
49
+ const resp = await catalogService.versions({ userId, organizationId });
50
+ const validVersion = resp.versions.some((app) => {
51
+ if (app.versionId === this.flags.select) {
52
+ return true;
53
+ }
54
+ });
55
+ if (!validVersion) {
56
+ this.error(`Version ${this.flags.select} does not exist`, { exit: 1 });
57
+ }
58
+ // We have a valid version, check to see if it exists against
59
+ // this application or none.
60
+ const apps = await this.loadManifest();
61
+ const app = apps[0];
62
+ if (app === undefined) {
63
+ this.error('No application found in manifest', { exit: 1 });
64
+ }
65
+ const applicationResp = await catalogService.applications({ userId, organizationId });
66
+ if (applicationResp.applications.some((a) => (a.name !== valueOf(app.name) && a.versionId === this.flags.select))) {
67
+ this.error(`Cannot select version ${this.flags.select} belonging to another application`, { exit: 1 });
68
+ }
69
+ config.versionId = this.flags.select;
70
+ await this.saveConfig(config);
71
+ return;
72
+ }
73
+ const resp = await catalogService.createVersion({
74
+ userId,
75
+ organizationId,
76
+ previousVersionId: this.flags.previousVersionId || config.versionId,
77
+ });
78
+ config.versionId = resp.versionId;
79
+ await this.saveConfig(config);
80
+ }
81
+ }
@@ -0,0 +1,19 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ export default class Delete extends BaseCommand<typeof Delete> {
3
+ static args: {
4
+ application: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ version: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ impersonate: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ rainbowAuthService: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
14
+ manifest: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
15
+ config: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
16
+ };
17
+ run(): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=delete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/build/delete.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW,CAAC,OAAO,MAAM,CAAC;IAC5D,MAAM,CAAC,IAAI;;MAET;IAEF,MAAM,CAAC,WAAW,SAAkC;IAEpD,MAAM,CAAC,QAAQ,WAIb;IAEF,MAAM,CAAC,KAAK;;;;;;;;MAgCV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAqD3B"}
@@ -0,0 +1,99 @@
1
+ import { valueOf } from '@liquidmetal-ai/drizzle/appify/build';
2
+ import { Args, Flags } from '@oclif/core';
3
+ import { BaseCommand } from '../../base-command.js';
4
+ import { defaultConfig } from '../../config.js';
5
+ export default class Delete extends BaseCommand {
6
+ static args = {
7
+ application: Args.string({ char: 'a', description: 'application name', required: false }),
8
+ };
9
+ static description = 'delete Raindrop applications';
10
+ static examples = [
11
+ `<%= config.bin %> <%= command.id %> .
12
+ Deleted (application) at version (version)
13
+ `,
14
+ ];
15
+ static flags = {
16
+ output: Flags.string({
17
+ char: 'o',
18
+ description: 'output format',
19
+ default: 'table',
20
+ options: ['text', 'table', 'json'],
21
+ }),
22
+ version: Flags.string({
23
+ char: 'v',
24
+ description: 'application version to delete',
25
+ required: false,
26
+ exclusive: ['all'],
27
+ }),
28
+ all: Flags.boolean({
29
+ char: 'a',
30
+ description: 'delete all application versions',
31
+ required: false,
32
+ exclusive: ['version'],
33
+ }),
34
+ impersonate: Flags.string({
35
+ char: 'i',
36
+ description: 'impersonate organization',
37
+ required: false,
38
+ hidden: true,
39
+ }),
40
+ rainbowAuthService: Flags.string({
41
+ default: 'https://liquidmetal.run/api/connect',
42
+ hidden: true,
43
+ env: 'LIQUIDMETAL_RAINBOW_AUTH_SERVICE',
44
+ }),
45
+ manifest: Flags.string({ default: 'raindrop.manifest', description: 'project manifest' }),
46
+ config: Flags.string({ default: '.raindrop/config.json', hidden: true }),
47
+ };
48
+ async run() {
49
+ const { client: catalogService, userId, organizationId } = await this.catalogService();
50
+ // Get the version ID to delete, or undefined if all versions
51
+ // should be deleted. Flags.all and Flags.versionId are exclusive,
52
+ // and the default versionId is the one in the config.
53
+ let versionId = this.flags.version;
54
+ if (this.flags.all) {
55
+ versionId = undefined;
56
+ }
57
+ else if (this.flags.version === undefined) {
58
+ const config = await this.loadConfig();
59
+ versionId = config.versionId;
60
+ }
61
+ // Don't allow deleting the epoch version.
62
+ if (versionId === defaultConfig.versionId) {
63
+ this.error('There are no applications at the epoch version', { exit: 1 });
64
+ }
65
+ if (this.args.application === undefined) {
66
+ const apps = await this.loadManifest();
67
+ const app = apps[0];
68
+ if (app === undefined) {
69
+ this.error('No application found in manifest and no application name specified', { exit: 1 });
70
+ }
71
+ this.args.application = valueOf(app.name);
72
+ }
73
+ try {
74
+ const resp = await catalogService.deleteApplications({
75
+ userId,
76
+ organizationId: this.flags.impersonate ?? organizationId,
77
+ // Omitting versionId will delete all versions of the application
78
+ applications: [{ name: this.args.application, versionId }],
79
+ });
80
+ if (resp.failure.length) {
81
+ this.error(`Failed to delete applications: ${resp.failure.map((f) => `${f.name}@${f.versionId}`).join(', ')}`, {
82
+ exit: 1,
83
+ });
84
+ }
85
+ }
86
+ catch (e) {
87
+ if (e instanceof Error) {
88
+ this.error(`Failed to delete application ${this.args.application}: ${e.message}`, { exit: 1 });
89
+ }
90
+ throw e;
91
+ }
92
+ if (this.flags.all) {
93
+ this.log(`Deleted all versions of ${this.args.application}`);
94
+ }
95
+ else {
96
+ this.log(`Deleted ${this.args.application} at version ${versionId}`);
97
+ }
98
+ }
99
+ }
@@ -0,0 +1,18 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ export default class Deploy extends BaseCommand<typeof Deploy> {
3
+ static args: {};
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ root: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
+ manifest: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
+ output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ versionId: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ impersonate: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ rainbowAuthService: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
+ start: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ config: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
15
+ };
16
+ run(): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=deploy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../../src/commands/build/deploy.ts"],"names":[],"mappings":"AASA,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;;;;;;;;;MAiCV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAkG3B"}
@@ -0,0 +1,144 @@
1
+ import { valueOf } from '@liquidmetal-ai/drizzle/appify/build';
2
+ import { JSONTranslator, Parser, Tokenizer } from '@liquidmetal-ai/drizzle/appify/parse';
3
+ import { archive } from '@liquidmetal-ai/drizzle/codestore';
4
+ import { BundleArchiveType } from '@liquidmetal-ai/drizzle/liquidmetal/v1alpha1/catalog_pb';
5
+ import { FileSystemBundle } from '@liquidmetal-ai/drizzle/unsafe/codestore';
6
+ import { Flags } from '@oclif/core';
7
+ import fs from 'node:fs/promises';
8
+ import * as path from 'node:path';
9
+ import { BaseCommand } from '../../base-command.js';
10
+ import { buildHandlers } from '../../build.js';
11
+ import { defaultConfig } from '../../config.js';
12
+ export default class Deploy extends BaseCommand {
13
+ static args = {};
14
+ static description = 'deploy a Raindrop application';
15
+ static examples = [
16
+ `<%= config.bin %> <%= command.id %> .
17
+ Deploy a Raindrop application.
18
+ `,
19
+ ];
20
+ static flags = {
21
+ root: Flags.string({ char: 'r', description: 'root directory', required: false, default: process.cwd() }),
22
+ manifest: Flags.string({
23
+ char: 'm',
24
+ description: 'project manifest',
25
+ required: false,
26
+ default: 'raindrop.manifest',
27
+ }),
28
+ output: Flags.string({ char: 'o', description: 'output directory', required: false, default: 'dist' }),
29
+ versionId: Flags.string({
30
+ char: 'v',
31
+ aliases: ['version'],
32
+ description: 'version ID',
33
+ required: false,
34
+ }),
35
+ impersonate: Flags.string({
36
+ char: 'i',
37
+ description: 'impersonate organization',
38
+ required: false,
39
+ hidden: true,
40
+ }),
41
+ rainbowAuthService: Flags.string({
42
+ default: 'https://liquidmetal.run/api/connect',
43
+ hidden: true,
44
+ env: 'LIQUIDMETAL_RAINBOW_AUTH_SERVICE',
45
+ }),
46
+ start: Flags.boolean({
47
+ char: 's',
48
+ description: 'start the application after deploying',
49
+ required: false,
50
+ default: false,
51
+ }),
52
+ config: Flags.string({ default: '.raindrop/config.json', hidden: true }),
53
+ };
54
+ async run() {
55
+ // Build then deploy
56
+ const manifestPath = path.isAbsolute(this.flags.manifest)
57
+ ? this.flags.manifest
58
+ : path.join(this.flags.root, this.flags.manifest);
59
+ // Do this first to check for errors.
60
+ const apps = await this.loadManifest();
61
+ const manifestContents = await fs.readFile(manifestPath, 'utf8');
62
+ // Now do a translate to get the JSON version of the manifest.
63
+ const tokenizer = new Tokenizer(await fs.readFile(manifestPath, 'utf8'));
64
+ const parser = new Parser(tokenizer);
65
+ const manifestJson = new JSONTranslator().translate(parser.parse());
66
+ const buildDir = path.isAbsolute(this.flags.output)
67
+ ? this.flags.output
68
+ : path.join(this.flags.root, this.flags.output);
69
+ await buildHandlers(this, apps, buildDir, this.flags.root);
70
+ const config = await this.loadConfig();
71
+ const versionId = this.flags.versionId || config.versionId;
72
+ if (versionId === defaultConfig.versionId) {
73
+ this.error('You must create a new version with `raindrop build branch` before deploying your first application', {
74
+ exit: 1,
75
+ });
76
+ }
77
+ const { client: catalogService, userId, organizationId: defaultOrganizationId } = await this.catalogService();
78
+ const organizationId = this.flags.impersonate ?? defaultOrganizationId;
79
+ const applications = apps.map((app) => ({
80
+ name: valueOf(app.name),
81
+ manifest: manifestContents,
82
+ manifestJson: JSON.stringify(manifestJson),
83
+ version: {
84
+ case: 'versionId',
85
+ value: versionId,
86
+ },
87
+ isActive: this.flags.start,
88
+ }));
89
+ const appsResp = await catalogService.createApplications({
90
+ applications,
91
+ userId,
92
+ organizationId,
93
+ suite: undefined, // TODO [bosgood] Provide suite name once available
94
+ });
95
+ // Upload bundle to this version's store.
96
+ for (const [i, app] of apps.entries()) {
97
+ const appResp = appsResp.applications[i];
98
+ if (!appResp) {
99
+ // TODO [bosgood] We'll be able to basically eliminate the possibility of this happening
100
+ // by converting createApplications in the API and State to a createMany function.
101
+ this.error(`Failed to create application ${valueOf(app.name)}, not uploading code bundle`, { exit: false });
102
+ continue;
103
+ }
104
+ const versionId = appResp.versionId;
105
+ this.log(`Created application "${valueOf(app.name)}" with version ID "${versionId}"`);
106
+ for (const handler of app.handlers()) {
107
+ const bundle = new FileSystemBundle(path.join(buildDir, valueOf(handler.name)));
108
+ await catalogService.uploadBundle({
109
+ organizationId,
110
+ applicationName: valueOf(app.name),
111
+ applicationVersionId: versionId,
112
+ archiveType: BundleArchiveType.ZIP,
113
+ bundleName: valueOf(handler.name),
114
+ archive: Buffer.from(await archive(bundle)),
115
+ });
116
+ this.log(`Uploaded bundle "${handler}"`);
117
+ }
118
+ // Per above, each application gets the same db bundle, which is
119
+ // boneheaded. src/db is pretty arbitrary.
120
+ const srcDir = path.join(this.flags.root, 'src');
121
+ const dbDir = path.join(srcDir, 'db');
122
+ let dbExists = false;
123
+ try {
124
+ const stat = await fs.lstat(dbDir);
125
+ dbExists = stat.isDirectory();
126
+ }
127
+ catch (_e) {
128
+ // Nothing to do
129
+ }
130
+ if (dbExists) {
131
+ const dbBundle = new FileSystemBundle(path.join(srcDir, 'db'));
132
+ await catalogService.uploadBundle({
133
+ organizationId,
134
+ applicationName: valueOf(app.name),
135
+ applicationVersionId: versionId,
136
+ archiveType: BundleArchiveType.ZIP,
137
+ bundleName: 'db',
138
+ archive: Buffer.from(await archive(dbBundle)),
139
+ });
140
+ this.log(`Uploaded bundle "db"`);
141
+ }
142
+ }
143
+ }
144
+ }
@@ -0,0 +1,19 @@
1
+ import { BaseCommand } from '../../../base-command.js';
2
+ export default class Get extends BaseCommand<typeof Get> {
3
+ static args: {
4
+ var: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ rainbowAuthService: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ manifest: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
12
+ versionId: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ application: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
+ impersonate: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
+ config: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
16
+ };
17
+ run(): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=get.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../../src/commands/build/env/get.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,MAAM,CAAC,OAAO,OAAO,GAAI,SAAQ,WAAW,CAAC,OAAO,GAAG,CAAC;IACtD,MAAM,CAAC,IAAI;;MAET;IAEF,MAAM,CAAC,WAAW,SAA2B;IAE7C,MAAM,CAAC,QAAQ,WAIb;IAEF,MAAM,CAAC,KAAK;;;;;;;;MA+BV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAwD3B"}