@devicecloud.dev/dcd 5.4.0 → 5.5.0-beta.1

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.
@@ -21,7 +21,7 @@ import { isEncryptionEnabled } from '../utils/envelope.js';
21
21
  import { detectCiContext, isCI } from '../utils/ci.js';
22
22
  import { CliError, coerceArray, collectRepeatedFlag, getCliVersion, getUpgradeCommand, logger, parseIntFlag, validateEnum, } from '../utils/cli.js';
23
23
  import { fetchCompatibilityData, } from '../utils/compatibility.js';
24
- import { renderNotices } from '../services/notices.service.js';
24
+ import { platformFromAppFile, renderNotices } from '../services/notices.service.js';
25
25
  import { resolveApiUrl } from '../utils/config-store.js';
26
26
  import { downloadExpoUrl, extractTarGz, findAppBundle, isUrl } from '../utils/expo.js';
27
27
  import { colors, formatId, formatUrl, getConsoleUrl, } from '../utils/styling.js';
@@ -323,13 +323,28 @@ export const cloudCommand = defineCommand({
323
323
  // returned with the compatibility data. Replaces the previously hardcoded
324
324
  // iOS-16 deprecation warning — that is now a seeded notice gated on the
325
325
  // selected iOS version below. Honours --json via out/warnOut.
326
- renderNotices(compatibilityData.notices, {
326
+ const visibleNotices = renderNotices(compatibilityData.notices, {
327
+ platform: platformFromAppFile(finalAppFile),
327
328
  ios_version: iOSVersion,
329
+ ios_device: iOSDevice,
328
330
  android_api_level: androidApiLevel,
331
+ android_device: androidDevice,
332
+ // Resolved (what the run will use) and requested (undefined when the
333
+ // customer relied on the default), so a notice can target either.
334
+ maestro_version: resolvedMaestroVersion,
335
+ requested_maestro_version: maestroVersion,
329
336
  cli_version: cliVersion,
330
337
  ci_provider: ciContext.provider,
331
338
  ci_wrapper_version: ciContext.wrapperVersion,
332
339
  }, { out });
340
+ // --json suppresses the rendered lines, so the payload carries them instead.
341
+ const noticesForJson = visibleNotices.map((n) => ({
342
+ slug: n.slug,
343
+ level: n.level,
344
+ title: n.title,
345
+ body: n.body,
346
+ learnMoreUrl: n.learnMoreUrl,
347
+ }));
333
348
  deviceValidationService.validateAndroidDevice(androidApiLevel, androidDevice, googlePlay, compatibilityData, { debug, logger: (m) => out(m) });
334
349
  // Validate every device-matrix cell up front — each on its own, against
335
350
  // the same compatibility matrix — so an unsupported cell fails fast,
@@ -670,6 +685,7 @@ export const cloudCommand = defineCommand({
670
685
  tags: testMetadataMap[r.test_file_name]?.tags || [],
671
686
  })),
672
687
  uploadId: results[0].test_upload_id,
688
+ notices: noticesForJson,
673
689
  };
674
690
  if (jsonFileFlag) {
675
691
  const jsonFilePath = jsonFileName || `${results[0].test_upload_id}_dcd.json`;
@@ -775,7 +791,7 @@ export const cloudCommand = defineCommand({
775
791
  warnLogger: (m) => warnOut(m),
776
792
  });
777
793
  }
778
- const jsonOutput = pollingResult;
794
+ const jsonOutput = { ...pollingResult, notices: noticesForJson };
779
795
  if (jsonFileFlag) {
780
796
  const jsonFilePath = jsonFileName || `${results[0].test_upload_id}_dcd.json`;
781
797
  writeJSONFile(jsonFilePath, jsonOutput, {
@@ -1,14 +1,14 @@
1
- import bplistParser from 'bplist-parser';
1
+ import { parseBuffer } from 'bplist-parser';
2
2
  import nodeApk from 'node-apk';
3
3
  import { readFile, rm } from 'node:fs/promises';
4
4
  import * as path from 'node:path';
5
5
  import StreamZip from 'node-stream-zip';
6
6
  import { parse } from 'plist';
7
- // node-apk and bplist-parser are CJS with no `exports` map; Node's named-export
8
- // detection for CJS (cjs-module-lexer) is version-dependent, so destructure off
9
- // the default import instead — that interop is guaranteed on every Node version.
7
+ // node-apk is CJS with no `exports` map; Node's named-export detection for CJS
8
+ // (cjs-module-lexer) is version-dependent, so destructure off the default import
9
+ // instead — that interop is guaranteed on every Node version. bplist-parser 0.5
10
+ // is a real ESM/CJS dual package with named exports, so it imports directly.
10
11
  const { Apk } = nodeApk;
11
- const { parseBuffer } = bplistParser;
12
12
  /**
13
13
  * Parses an Info.plist buffer (XML, UTF-8 BOM'd XML, or binary bplist).
14
14
  * Shared by the .app and .zip extractors.
@@ -42,4 +42,10 @@ export interface RenderNoticesOptions {
42
42
  * payload instead of printing. `opts.out` is the caller's `--json`-gated
43
43
  * emitter, so under `--json` nothing prints but the list is still returned.
44
44
  */
45
+ /**
46
+ * Best-effort platform from the app artifact's extension, so a notice can be
47
+ * targeted at one platform (e.g. "you rely on the default Android API level")
48
+ * without firing on the other platform's runs.
49
+ */
50
+ export declare function platformFromAppFile(appFile: string | undefined): 'android' | 'ios' | undefined;
45
51
  export declare function renderNotices(notices: Notice[] | undefined, ctx: NoticeContext, opts: RenderNoticesOptions): Notice[];
@@ -72,6 +72,21 @@ function renderNotice(notice, opts) {
72
72
  * payload instead of printing. `opts.out` is the caller's `--json`-gated
73
73
  * emitter, so under `--json` nothing prints but the list is still returned.
74
74
  */
75
+ /**
76
+ * Best-effort platform from the app artifact's extension, so a notice can be
77
+ * targeted at one platform (e.g. "you rely on the default Android API level")
78
+ * without firing on the other platform's runs.
79
+ */
80
+ export function platformFromAppFile(appFile) {
81
+ if (!appFile)
82
+ return undefined;
83
+ const ext = appFile.split('?')[0].toLowerCase().match(/.([a-z0-9]+)$/)?.[1];
84
+ if (ext === 'apk' || ext === 'aab')
85
+ return 'android';
86
+ if (ext === 'zip' || ext === 'app' || ext === 'ipa')
87
+ return 'ios';
88
+ return undefined;
89
+ }
75
90
  export function renderNotices(notices, ctx, opts) {
76
91
  if (!notices || notices.length === 0)
77
92
  return [];
@@ -6,13 +6,13 @@ import { z } from 'zod';
6
6
  * payload.
7
7
  */
8
8
  export declare const WorkspaceConfigSchema: z.ZodObject<{
9
- excludeTags: z.ZodOptional<z.ZodNullable<z.ZodPreprocess<z.ZodArray<z.ZodString>>>>;
9
+ excludeTags: z.ZodOptional<z.ZodNullable<z.ZodPreprocess<z.ZodArray<z.ZodString>, unknown>>>;
10
10
  executionOrder: z.ZodOptional<z.ZodNullable<z.ZodObject<{
11
11
  continueOnFailure: z.ZodDefault<z.ZodBoolean>;
12
12
  flowsOrder: z.ZodArray<z.ZodString>;
13
13
  }, z.core.$strip>>>;
14
14
  flows: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
15
- includeTags: z.ZodOptional<z.ZodNullable<z.ZodPreprocess<z.ZodArray<z.ZodString>>>>;
15
+ includeTags: z.ZodOptional<z.ZodNullable<z.ZodPreprocess<z.ZodArray<z.ZodString>, unknown>>>;
16
16
  local: z.ZodOptional<z.ZodNullable<z.ZodObject<{
17
17
  deterministicOrder: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
18
18
  }, z.core.$loose>>>;
@@ -23,6 +23,7 @@ export declare enum EAndroidDevices {
23
23
  export declare enum EiOSVersions {
24
24
  'eighteen' = "18",
25
25
  'seventeen' = "17",
26
+ 'twentySeven' = "27",
26
27
  'twentySix' = "26"
27
28
  }
28
29
  export declare enum EAndroidApiLevels {
@@ -26,6 +26,7 @@ export var EiOSVersions;
26
26
  (function (EiOSVersions) {
27
27
  EiOSVersions["eighteen"] = "18";
28
28
  EiOSVersions["seventeen"] = "17";
29
+ EiOSVersions["twentySeven"] = "27";
29
30
  EiOSVersions["twentySix"] = "26";
30
31
  })(EiOSVersions || (EiOSVersions = {}));
31
32
  export var EAndroidApiLevels;
@@ -1647,7 +1647,7 @@ export interface components {
1647
1647
  appFile?: string;
1648
1648
  env: string;
1649
1649
  /** @enum {string} */
1650
- iOSVersion?: "17" | "18" | "26";
1650
+ iOSVersion?: "17" | "18" | "26" | "27";
1651
1651
  /** @enum {string} */
1652
1652
  iOSDevice?: "iphone-14" | "iphone-15" | "iphone-16" | "iphone-16-plus" | "iphone-16-pro" | "iphone-16-pro-max" | "ipad-pro-6th-gen";
1653
1653
  platform?: string;
@@ -1687,7 +1687,7 @@ export interface components {
1687
1687
  appFile?: string;
1688
1688
  env: string;
1689
1689
  /** @enum {string} */
1690
- iOSVersion?: "17" | "18" | "26";
1690
+ iOSVersion?: "17" | "18" | "26" | "27";
1691
1691
  /** @enum {string} */
1692
1692
  iOSDevice?: "iphone-14" | "iphone-15" | "iphone-16" | "iphone-16-plus" | "iphone-16-pro" | "iphone-16-pro-max" | "ipad-pro-6th-gen";
1693
1693
  platform?: string;
@@ -1738,7 +1738,7 @@ export interface components {
1738
1738
  appFile?: string;
1739
1739
  env: string;
1740
1740
  /** @enum {string} */
1741
- iOSVersion?: "17" | "18" | "26";
1741
+ iOSVersion?: "17" | "18" | "26" | "27";
1742
1742
  /** @enum {string} */
1743
1743
  iOSDevice?: "iphone-14" | "iphone-15" | "iphone-16" | "iphone-16-plus" | "iphone-16-pro" | "iphone-16-pro-max" | "ipad-pro-6th-gen";
1744
1744
  platform?: string;
@@ -3075,10 +3075,11 @@ export interface operations {
3075
3075
  * "2.6.0",
3076
3076
  * "2.6.1",
3077
3077
  * "2.7.0",
3078
- * "2.8.0"
3078
+ * "2.8.0",
3079
+ * "2.9.0"
3079
3080
  * ],
3080
3081
  * "defaultVersion": "2.2.0",
3081
- * "latestVersion": "2.8.0"
3082
+ * "latestVersion": "2.9.0"
3082
3083
  * }
3083
3084
  * }
3084
3085
  * }
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "@clack/prompts": "^1.6.0",
9
9
  "@modelcontextprotocol/sdk": "^1.29.0",
10
10
  "@supabase/supabase-js": "^2.108.2",
11
- "bplist-parser": "^0.3.2",
11
+ "bplist-parser": "^0.5.0",
12
12
  "chalk": "^6.0.0",
13
13
  "citty": "^0.2.2",
14
14
  "js-yaml": "^5.2.2",
@@ -31,9 +31,9 @@
31
31
  "chai": "^6.2.2",
32
32
  "eslint": "^10.5.0",
33
33
  "eslint-config-prettier": "^10.1.8",
34
- "eslint-plugin-unicorn": "^73.0.0",
34
+ "eslint-plugin-unicorn": "^74.0.0",
35
35
  "husky": "^9.1.7",
36
- "mocha": "^11.7.6",
36
+ "mocha": "^12.0.0",
37
37
  "prettier": "^3.8.4",
38
38
  "shx": "^0.4.0",
39
39
  "tsx": "^4.22.4",
@@ -59,7 +59,7 @@
59
59
  "type": "git",
60
60
  "url": "https://devicecloud.dev"
61
61
  },
62
- "version": "5.4.0",
62
+ "version": "5.5.0-beta.1",
63
63
  "bugs": {
64
64
  "url": "https://discord.gg/gm3mJwcNw8"
65
65
  },