@devicecloud.dev/dcd 4.0.0 → 4.0.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.
@@ -320,7 +320,7 @@ class Cloud extends core_1.Command {
320
320
  }
321
321
  throw error;
322
322
  }
323
- const { allExcludeTags, allIncludeTags, flowMetadata, flowsToRun: testFileNames, referencedFiles, sequence, workspaceConfig, } = executionPlan;
323
+ const { allExcludeTags, allIncludeTags, flowMetadata, flowOverrides, flowsToRun: testFileNames, referencedFiles, sequence, workspaceConfig, } = executionPlan;
324
324
  if (debug) {
325
325
  this.log(`DEBUG: All include tags: ${allIncludeTags?.join(', ') || 'none'}`);
326
326
  this.log(`DEBUG: All exclude tags: ${allExcludeTags?.join(', ') || 'none'}`);
@@ -370,6 +370,23 @@ class Cloud extends core_1.Command {
370
370
  flagLogs.push(`${k}: ${v}`);
371
371
  }
372
372
  }
373
+ // Format overrides information
374
+ const overridesEntries = Object.entries(flowOverrides);
375
+ const hasOverrides = overridesEntries.some(([, overrides]) => Object.keys(overrides).length > 0);
376
+ let overridesLog = '';
377
+ if (hasOverrides) {
378
+ overridesLog = '\n With overrides';
379
+ for (const [flowPath, overrides] of overridesEntries) {
380
+ if (Object.keys(overrides).length > 0) {
381
+ const relativePath = flowPath.replace(process.cwd(), '.');
382
+ overridesLog += `\n → ${relativePath}:`;
383
+ for (const [key, value] of Object.entries(overrides)) {
384
+ overridesLog += `\n ${key}: ${value}`;
385
+ }
386
+ }
387
+ }
388
+ overridesLog += '\n';
389
+ }
373
390
  this.log(`
374
391
 
375
392
  Submitting new job
@@ -381,7 +398,7 @@ class Cloud extends core_1.Command {
381
398
 
382
399
  With options
383
400
  → ${flagLogs.join(`
384
- → `)}
401
+ → `)}${overridesLog}
385
402
 
386
403
  `);
387
404
  if (dryRun) {
@@ -478,6 +495,10 @@ class Cloud extends core_1.Command {
478
495
  key.replaceAll(commonRoot, '.').split(path.sep).join('/'),
479
496
  value,
480
497
  ]))));
498
+ testFormData.set('testFileOverrides', JSON.stringify(Object.fromEntries(Object.entries(flowOverrides).map(([key, value]) => [
499
+ key.replaceAll(commonRoot, '.').split(path.sep).join('/'),
500
+ value,
501
+ ]))));
481
502
  testFormData.set('sequentialFlows', JSON.stringify(sequentialFlows.map((t) => t.replaceAll(commonRoot, '.').split(path.sep).join('/'))));
482
503
  testFormData.set('env', JSON.stringify(envObject));
483
504
  testFormData.set('googlePlay', googlePlay ? 'true' : 'false');
package/dist/methods.js CHANGED
@@ -251,9 +251,18 @@ const writeJSONFile = (filePath, data, logger) => {
251
251
  logger.log(`JSON output written to: ${path.resolve(filePath)}`);
252
252
  }
253
253
  catch (error) {
254
+ const errorMessage = error instanceof Error ? error.message : String(error);
255
+ const isPermissionError = errorMessage.includes('EACCES') || errorMessage.includes('EPERM');
256
+ const isNoSuchFileError = errorMessage.includes('ENOENT');
254
257
  logger.warn(`Failed to write JSON output to file: ${filePath}`);
255
- // Use console.debug instead of logger.debug since debug is protected in Command
256
- logger.warn(`Error details: ${error instanceof Error ? error.message : String(error)}`);
258
+ if (isPermissionError) {
259
+ logger.warn('Permission denied - check file/directory write permissions');
260
+ logger.warn('Try running with appropriate permissions or choose a different output location');
261
+ }
262
+ else if (isNoSuchFileError) {
263
+ logger.warn('Directory does not exist - create the directory first or choose an existing path');
264
+ }
265
+ logger.warn(`Error details: ${errorMessage}`);
257
266
  }
258
267
  };
259
268
  exports.writeJSONFile = writeJSONFile;
package/dist/plan.d.ts CHANGED
@@ -16,6 +16,7 @@ interface IExecutionPlan {
16
16
  allExcludeTags?: null | string[];
17
17
  allIncludeTags?: null | string[];
18
18
  flowMetadata: Record<string, Record<string, unknown>>;
19
+ flowOverrides: Record<string, Record<string, unknown>>;
19
20
  flowsToRun: string[];
20
21
  referencedFiles: string[];
21
22
  sequence?: IFlowSequence | null;
package/dist/plan.js CHANGED
@@ -42,16 +42,28 @@ function filterFlowFiles(unfilteredFlowFiles, excludeFlows) {
42
42
  return unfilteredFlowFiles;
43
43
  }
44
44
  function getWorkspaceConfig(input, unfilteredFlowFiles) {
45
- const possibleConfigPaths = new Set([
46
- path.join(input, 'config.yaml'),
47
- path.join(input, 'config.yml'),
48
- ].map((p) => path.normalize(p)));
45
+ const possibleConfigPaths = new Set([path.join(input, 'config.yaml'), path.join(input, 'config.yml')].map((p) => path.normalize(p)));
49
46
  const configFilePath = unfilteredFlowFiles.find((file) => possibleConfigPaths.has(path.normalize(file)));
50
47
  const config = configFilePath
51
48
  ? (0, planMethods_1.readYamlFileAsJson)(configFilePath)
52
49
  : {};
53
50
  return config;
54
51
  }
52
+ function extractDeviceCloudOverrides(config) {
53
+ if (!config || !config.env || typeof config.env !== 'object') {
54
+ return {};
55
+ }
56
+ const overrides = {};
57
+ const envVars = config.env;
58
+ for (const [key, value] of Object.entries(envVars)) {
59
+ if (key.startsWith('DEVICECLOUD_OVERRIDE_')) {
60
+ // Remove the DEVICECLOUD_OVERRIDE_ prefix and use the rest as the override key
61
+ const overrideKey = key.replace('DEVICECLOUD_OVERRIDE_', '');
62
+ overrides[overrideKey] = value;
63
+ }
64
+ }
65
+ return overrides;
66
+ }
55
67
  async function plan(input, includeTags, excludeTags, excludeFlows, configFile) {
56
68
  const normalizedInput = path.normalize(input);
57
69
  const flowMetadata = {};
@@ -64,12 +76,15 @@ async function plan(input, includeTags, excludeTags, excludeFlows, configFile) {
64
76
  throw new Error('If using config.yaml, pass the workspace folder path, not the config file or a custom path via --config');
65
77
  }
66
78
  const { config } = (0, planMethods_1.readTestYamlFileAsJson)(normalizedInput);
79
+ const flowOverrides = {};
67
80
  if (config) {
68
81
  flowMetadata[normalizedInput] = config;
82
+ flowOverrides[normalizedInput] = extractDeviceCloudOverrides(config);
69
83
  }
70
84
  const checkedDependancies = await checkDependencies(normalizedInput);
71
85
  return {
72
86
  flowMetadata,
87
+ flowOverrides,
73
88
  flowsToRun: [normalizedInput],
74
89
  referencedFiles: [...new Set(checkedDependancies)],
75
90
  totalFlowFiles: 1,
@@ -151,11 +166,13 @@ async function plan(input, includeTags, excludeTags, excludeFlows, configFile) {
151
166
  ...excludeTags,
152
167
  ...(workspaceConfig.excludeTags || []),
153
168
  ];
169
+ const flowOverrides = {};
154
170
  const allFlows = unfilteredFlowFiles.filter((filePath) => {
155
171
  const config = configPerFlowFile[filePath];
156
172
  const tags = config?.tags || [];
157
173
  if (config) {
158
174
  flowMetadata[filePath] = config;
175
+ flowOverrides[filePath] = extractDeviceCloudOverrides(config);
159
176
  }
160
177
  return ((allIncludeTags.length === 0 ||
161
178
  tags.some((tag) => allIncludeTags.includes(tag))) &&
@@ -185,6 +202,7 @@ async function plan(input, includeTags, excludeTags, excludeFlows, configFile) {
185
202
  allExcludeTags,
186
203
  allIncludeTags,
187
204
  flowMetadata,
205
+ flowOverrides,
188
206
  flowsToRun: normalFlows,
189
207
  referencedFiles: [...new Set(allFiles)],
190
208
  sequence: {
@@ -570,5 +570,5 @@
570
570
  ]
571
571
  }
572
572
  },
573
- "version": "4.0.0"
573
+ "version": "4.0.1"
574
574
  }
package/package.json CHANGED
@@ -80,7 +80,7 @@
80
80
  "version": "oclif readme && git add README.md",
81
81
  "test": "node scripts/test-runner.mjs"
82
82
  },
83
- "version": "4.0.0",
83
+ "version": "4.0.1",
84
84
  "bugs": {
85
85
  "url": "https://discord.gg/gm3mJwcNw8"
86
86
  },