@devicecloud.dev/dcd 4.4.9 → 5.0.0-beta.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 (97) hide show
  1. package/README.md +40 -2
  2. package/dist/commands/artifacts.d.ts +47 -18
  3. package/dist/commands/artifacts.js +68 -60
  4. package/dist/commands/cloud.d.ts +228 -88
  5. package/dist/commands/cloud.js +389 -288
  6. package/dist/commands/list.d.ts +39 -38
  7. package/dist/commands/list.js +122 -127
  8. package/dist/commands/live.d.ts +2 -0
  9. package/dist/commands/live.js +513 -0
  10. package/dist/commands/login.d.ts +17 -0
  11. package/dist/commands/login.js +250 -0
  12. package/dist/commands/logout.d.ts +2 -0
  13. package/dist/commands/logout.js +32 -0
  14. package/dist/commands/status.d.ts +23 -42
  15. package/dist/commands/status.js +162 -173
  16. package/dist/commands/switch-org.d.ts +12 -0
  17. package/dist/commands/switch-org.js +78 -0
  18. package/dist/commands/upgrade.d.ts +2 -0
  19. package/dist/commands/upgrade.js +122 -0
  20. package/dist/commands/upload.d.ts +33 -18
  21. package/dist/commands/upload.js +62 -67
  22. package/dist/commands/whoami.d.ts +2 -0
  23. package/dist/commands/whoami.js +34 -0
  24. package/dist/config/environments.d.ts +31 -0
  25. package/dist/config/environments.js +58 -0
  26. package/dist/config/flags/api.flags.d.ts +10 -2
  27. package/dist/config/flags/api.flags.js +12 -10
  28. package/dist/config/flags/binary.flags.d.ts +17 -4
  29. package/dist/config/flags/binary.flags.js +13 -14
  30. package/dist/config/flags/device.flags.d.ts +49 -11
  31. package/dist/config/flags/device.flags.js +41 -33
  32. package/dist/config/flags/environment.flags.d.ts +27 -6
  33. package/dist/config/flags/environment.flags.js +23 -25
  34. package/dist/config/flags/execution.flags.d.ts +35 -8
  35. package/dist/config/flags/execution.flags.js +30 -37
  36. package/dist/config/flags/github.flags.d.ts +23 -5
  37. package/dist/config/flags/github.flags.js +18 -11
  38. package/dist/config/flags/output.flags.d.ts +57 -13
  39. package/dist/config/flags/output.flags.js +47 -43
  40. package/dist/constants.d.ts +218 -51
  41. package/dist/constants.js +2 -2
  42. package/dist/gateways/api-gateway.d.ts +43 -12
  43. package/dist/gateways/api-gateway.js +240 -100
  44. package/dist/gateways/cli-auth-gateway.d.ts +13 -0
  45. package/dist/gateways/cli-auth-gateway.js +57 -0
  46. package/dist/gateways/supabase-gateway.d.ts +11 -11
  47. package/dist/gateways/supabase-gateway.js +15 -39
  48. package/dist/index.d.ts +2 -1
  49. package/dist/index.js +93 -2
  50. package/dist/methods.d.ts +3 -5
  51. package/dist/methods.js +170 -178
  52. package/dist/services/device-validation.service.d.ts +8 -0
  53. package/dist/services/device-validation.service.js +55 -35
  54. package/dist/services/execution-plan.service.js +27 -15
  55. package/dist/services/execution-plan.utils.d.ts +3 -0
  56. package/dist/services/execution-plan.utils.js +10 -32
  57. package/dist/services/metadata-extractor.service.d.ts +0 -2
  58. package/dist/services/metadata-extractor.service.js +57 -57
  59. package/dist/services/moropo.service.js +25 -24
  60. package/dist/services/report-download.service.d.ts +12 -1
  61. package/dist/services/report-download.service.js +31 -20
  62. package/dist/services/results-polling.service.d.ts +6 -7
  63. package/dist/services/results-polling.service.js +80 -33
  64. package/dist/services/telemetry.service.d.ts +40 -0
  65. package/dist/services/telemetry.service.js +230 -0
  66. package/dist/services/test-submission.service.js +2 -1
  67. package/dist/services/version.service.d.ts +3 -2
  68. package/dist/services/version.service.js +27 -11
  69. package/dist/types/domain/auth.types.d.ts +12 -0
  70. package/dist/types/{schema.types.js → domain/auth.types.js} +0 -1
  71. package/dist/types/domain/live.types.d.ts +76 -0
  72. package/dist/types/domain/live.types.js +4 -0
  73. package/dist/utils/auth.d.ts +13 -0
  74. package/dist/utils/auth.js +142 -0
  75. package/dist/utils/cli.d.ts +35 -0
  76. package/dist/utils/cli.js +127 -0
  77. package/dist/utils/compatibility.d.ts +2 -1
  78. package/dist/utils/compatibility.js +2 -2
  79. package/dist/utils/config-store.d.ts +35 -0
  80. package/dist/utils/config-store.js +125 -0
  81. package/dist/utils/connectivity.js +7 -3
  82. package/dist/utils/expo.js +14 -3
  83. package/dist/utils/orgs.d.ts +11 -0
  84. package/dist/utils/orgs.js +40 -0
  85. package/dist/utils/paths.d.ts +11 -0
  86. package/dist/utils/paths.js +24 -0
  87. package/dist/utils/progress.d.ts +13 -0
  88. package/dist/utils/progress.js +50 -0
  89. package/dist/utils/styling.d.ts +13 -5
  90. package/dist/utils/styling.js +37 -7
  91. package/package.json +26 -38
  92. package/bin/dev.cmd +0 -3
  93. package/bin/dev.js +0 -6
  94. package/bin/run.cmd +0 -3
  95. package/bin/run.js +0 -7
  96. package/dist/types/schema.types.d.ts +0 -2702
  97. package/oclif.manifest.json +0 -884
@@ -1,62 +1,38 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SupabaseGateway = void 0;
4
+ const node_fs_1 = require("node:fs");
4
5
  const supabase_js_1 = require("@supabase/supabase-js");
5
6
  const tus = require("tus-js-client");
7
+ const environments_1 = require("../config/environments");
6
8
  class SupabaseGateway {
7
- static SB = {
8
- dev: {
9
- SUPABASE_PUBLIC_KEY: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImxibXNvd2VodGp3bnFsdXJwZW1iIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDkyMTg0ODcsImV4cCI6MjAyNDc5NDQ4N30.zeLTMAuZ_WwYvGdeP0kdvL_Zrs-RQee5APPyxmWq7qQ',
10
- SUPABASE_URL: 'https://lbmsowehtjwnqlurpemb.supabase.co',
11
- },
12
- prod: {
13
- SUPABASE_PUBLIC_KEY: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBneWRucGhiaW1ldGluc2dma2JvIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDc1OTQzNDYsImV4cCI6MjAyMzE3MDM0Nn0.hAYOMFxxwX1exkQkY9xyQJGC_GhGnyogkj2N-kBkMI8',
14
- SUPABASE_URL: 'https://cloud.devicecloud.dev',
15
- },
16
- };
17
- static getSupabaseKeys(env) {
18
- return this.SB[env];
19
- }
20
9
  /**
21
10
  * Upload to Supabase using resumable uploads (TUS protocol)
22
11
  * Uploads to staging location (uploads/{id}/) using anon key
23
12
  * File is later moved to final location by API after finalization
24
13
  * @param env - Environment (dev or prod)
25
14
  * @param path - Staging storage path (uploads/{id}/file.ext)
26
- * @param file - File to upload
15
+ * @param source - Upload source descriptor; the file is streamed from disk
27
16
  * @param debug - Enable debug logging
28
17
  * @param onProgress - Optional callback for upload progress (bytesUploaded, bytesTotal)
29
18
  * @returns Promise that resolves when upload completes
30
19
  */
31
- static async uploadResumable(env, path, file, debug = false, onProgress) {
32
- const { SUPABASE_PUBLIC_KEY, SUPABASE_URL } = this.getSupabaseKeys(env);
33
- // Extract project ID from Supabase URL for the storage endpoint
34
- // Format: https://project-id.supabase.co or https://cloud.devicecloud.dev (custom domain)
35
- let projectId;
36
- if (SUPABASE_URL.includes('.supabase.co')) {
37
- projectId = SUPABASE_URL.replace('https://', '').split('.')[0];
38
- }
39
- else {
40
- // For custom domains like cloud.devicecloud.dev, we need the project ref
41
- // This is the dev environment project ref
42
- projectId = env === 'dev' ? 'lbmsowehtjwnqlurpemb' : 'pgydnphbimetinsgfkbo';
43
- }
44
- const storageUrl = `https://${projectId}.storage.supabase.co`;
20
+ static async uploadResumable(env, path, source, debug = false, onProgress) {
21
+ const { anonKey: SUPABASE_PUBLIC_KEY, projectRef } = environments_1.ENVIRONMENTS[env].supabase;
22
+ const storageUrl = `https://${projectRef}.storage.supabase.co`;
45
23
  if (debug) {
46
24
  console.log(`[DEBUG] Resumable upload starting...`);
47
25
  console.log(`[DEBUG] Storage URL: ${storageUrl}`);
48
26
  console.log(`[DEBUG] Upload path: ${path}`);
49
- console.log(`[DEBUG] File name: ${file.name}`);
50
- console.log(`[DEBUG] File size: ${(file.size / 1024 / 1024).toFixed(2)} MB`);
51
- }
52
- // Convert File to Buffer for Node.js tus-js-client
53
- // In Node.js environment, tus-js-client expects Buffer or Readable stream, not File
54
- const fileBuffer = Buffer.from(await file.arrayBuffer());
55
- if (debug) {
56
- console.log(`[DEBUG] Converted File to Buffer (${fileBuffer.length} bytes)`);
27
+ console.log(`[DEBUG] File name: ${source.name}`);
28
+ console.log(`[DEBUG] File size: ${(source.size / 1024 / 1024).toFixed(2)} MB`);
29
+ console.log(`[DEBUG] Streaming from disk: ${source.diskPath}`);
57
30
  }
58
31
  return new Promise((resolve, reject) => {
59
- const upload = new tus.Upload(fileBuffer, {
32
+ // Stream from disk tus only buffers one chunk at a time. uploadSize
33
+ // is required because a stream's length can't be derived.
34
+ const upload = new tus.Upload((0, node_fs_1.createReadStream)(source.diskPath), {
35
+ uploadSize: source.size,
60
36
  // TUS endpoint for Supabase Storage
61
37
  endpoint: `${storageUrl}/storage/v1/upload/resumable`,
62
38
  // Retry configuration - will retry 5 times with increasing delays
@@ -71,7 +47,7 @@ class SupabaseGateway {
71
47
  metadata: {
72
48
  bucketName: 'organizations',
73
49
  objectName: path,
74
- contentType: file.type || 'application/octet-stream',
50
+ contentType: source.contentType || 'application/octet-stream',
75
51
  cacheControl: '3600',
76
52
  },
77
53
  // Chunk size must be 6MB for Supabase
@@ -120,7 +96,7 @@ class SupabaseGateway {
120
96
  });
121
97
  }
122
98
  static async uploadToSignedUrl(env, path, token, file, debug = false) {
123
- const { SUPABASE_PUBLIC_KEY, SUPABASE_URL } = this.getSupabaseKeys(env);
99
+ const { url: SUPABASE_URL, anonKey: SUPABASE_PUBLIC_KEY } = environments_1.ENVIRONMENTS[env].supabase;
124
100
  if (debug) {
125
101
  console.log(`[DEBUG] Supabase upload starting...`);
126
102
  console.log(`[DEBUG] Supabase URL: ${SUPABASE_URL}`);
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
- export { run } from '@oclif/core';
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js CHANGED
@@ -1,4 +1,95 @@
1
+ #!/usr/bin/env node
1
2
  "use strict";
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
- var core_1 = require("@oclif/core");
4
- Object.defineProperty(exports, "run", { enumerable: true, get: function () { return core_1.run; } });
4
+ const citty_1 = require("citty");
5
+ const artifacts_1 = require("./commands/artifacts");
6
+ const cloud_1 = require("./commands/cloud");
7
+ const list_1 = require("./commands/list");
8
+ const live_1 = require("./commands/live");
9
+ const login_1 = require("./commands/login");
10
+ const logout_1 = require("./commands/logout");
11
+ const status_1 = require("./commands/status");
12
+ const switch_org_1 = require("./commands/switch-org");
13
+ const upgrade_1 = require("./commands/upgrade");
14
+ const upload_1 = require("./commands/upload");
15
+ const whoami_1 = require("./commands/whoami");
16
+ const telemetry_service_1 = require("./services/telemetry.service");
17
+ const cli_1 = require("./utils/cli");
18
+ const main = (0, citty_1.defineCommand)({
19
+ meta: {
20
+ name: 'dcd',
21
+ version: (0, cli_1.getCliVersion)(),
22
+ description: 'devicecloud.dev CLI — a drop-in replacement for `maestro cloud`',
23
+ },
24
+ subCommands: {
25
+ cloud: cloud_1.cloudCommand,
26
+ upload: upload_1.uploadCommand,
27
+ list: list_1.listCommand,
28
+ status: status_1.statusCommand,
29
+ artifacts: artifacts_1.artifactsCommand,
30
+ live: live_1.liveCommand,
31
+ login: login_1.loginCommand,
32
+ logout: logout_1.logoutCommand,
33
+ whoami: whoami_1.whoamiCommand,
34
+ 'switch-org': switch_org_1.switchOrgCommand,
35
+ upgrade: upgrade_1.upgradeCommand,
36
+ },
37
+ });
38
+ // citty's runMain catches every error internally and calls process.exit(1),
39
+ // so its returned promise never rejects — failure telemetry hooked onto it
40
+ // would be dead code, CliError.exitCode would be ignored, and raw stack
41
+ // traces would be printed for usage errors. This replicates runMain's
42
+ // help/version/usage behaviour with those three problems fixed. Telemetry
43
+ // configure is deferred to `resolveAuth` (only authenticated commands ship
44
+ // telemetry — see telemetry.service.ts); unauthenticated invocations buffer
45
+ // in memory and drop on exit, which is the desired behaviour.
46
+ async function resolveValue(input) {
47
+ return typeof input === 'function'
48
+ ? input()
49
+ : input;
50
+ }
51
+ // Mirrors citty's internal (unexported) resolveSubCommand so usage errors can
52
+ // show the help of the subcommand that failed rather than the root command.
53
+ async function resolveSubCommand(cmd, rawArgs, parent) {
54
+ const subCommands = await resolveValue(cmd.subCommands);
55
+ if (subCommands && Object.keys(subCommands).length > 0) {
56
+ const subCommandArgIndex = rawArgs.findIndex((arg) => !arg.startsWith('-'));
57
+ const subCommandName = rawArgs[subCommandArgIndex];
58
+ const subCommand = await resolveValue(subCommands[subCommandName]);
59
+ if (subCommand) {
60
+ return resolveSubCommand(subCommand, rawArgs.slice(subCommandArgIndex + 1), cmd);
61
+ }
62
+ }
63
+ return [cmd, parent];
64
+ }
65
+ async function run() {
66
+ const rawArgs = process.argv.slice(2);
67
+ telemetry_service_1.telemetry.recordCommandStart();
68
+ try {
69
+ if (rawArgs.includes('--help') || rawArgs.includes('-h')) {
70
+ await (0, citty_1.showUsage)(...(await resolveSubCommand(main, rawArgs)));
71
+ }
72
+ else if (rawArgs.length === 1 && rawArgs[0] === '--version') {
73
+ cli_1.logger.log((0, cli_1.getCliVersion)());
74
+ }
75
+ else {
76
+ await (0, citty_1.runCommand)(main, { rawArgs });
77
+ }
78
+ telemetry_service_1.telemetry.recordCommandSuccess();
79
+ await telemetry_service_1.telemetry.flush();
80
+ }
81
+ catch (error) {
82
+ // citty throws CLIError (by name — the class isn't exported) for usage
83
+ // problems like unknown commands or missing required args.
84
+ if (error instanceof Error && error.name === 'CLIError') {
85
+ await (0, citty_1.showUsage)(...(await resolveSubCommand(main, rawArgs)));
86
+ }
87
+ const exitCode = error instanceof cli_1.CliError ? error.exitCode : 1;
88
+ // logger.error prints the message, records failure telemetry, flushes
89
+ // synchronously, and exits with the given code.
90
+ cli_1.logger.error(error instanceof Error ? error : String(error), {
91
+ exit: exitCode,
92
+ });
93
+ }
94
+ }
95
+ void run();
package/dist/methods.d.ts CHANGED
@@ -1,10 +1,8 @@
1
- import * as archiver from 'archiver';
2
- export declare const toBuffer: (archive: archiver.Archiver) => Promise<Buffer<ArrayBuffer>>;
3
- export declare const compressFolderToBlob: (sourceDir: string) => Promise<Blob>;
4
- export declare const compressFilesFromRelativePath: (basePath: string, files: string[], commonRoot: string) => Promise<Buffer<ArrayBuffer>>;
1
+ import type { AuthContext } from './types/domain/auth.types';
2
+ export declare const compressFilesFromRelativePath: (basePath: string, files: string[], commonRoot: string) => Promise<Buffer>;
5
3
  export declare const verifyAppZip: (zipPath: string) => Promise<void>;
6
4
  interface UploadBinaryConfig {
7
- apiKey: string;
5
+ auth: AuthContext;
8
6
  apiUrl: string;
9
7
  debug?: boolean;
10
8
  filePath: string;