@devicecloud.dev/dcd 0.0.4 → 0.0.5

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.
@@ -36,7 +36,7 @@ var EiOSDevices;
36
36
  class Cloud extends core_1.Command {
37
37
  static args = {
38
38
  firstFile: core_1.Args.string({
39
- description: 'The binary file of the app to run your flow against, e.g. app.apk for android or app.zip for ios',
39
+ description: 'The binary file of the app to run your flow against, e.g. test.apk for android or test.app/.zip for ios',
40
40
  hidden: true,
41
41
  name: 'App file',
42
42
  }),
@@ -98,8 +98,8 @@ class Cloud extends core_1.Command {
98
98
  if (!(flowFile && finalAppFile)) {
99
99
  throw new Error('You must provide a flow file and an app binary id');
100
100
  }
101
- if (!finalAppFile.endsWith('.apk') && !finalAppFile.endsWith('.zip')) {
102
- throw new Error('App file must be a .apk or .zip file');
101
+ if (!['apk', '.app', '.zip'].some((ext) => finalAppFile.endsWith(ext))) {
102
+ throw new Error('App file must be a .apk for android or .app/.zip file for iOS');
103
103
  }
104
104
  if (finalAppFile.endsWith('.zip')) {
105
105
  await (0, methods_1.verifyAppZip)(finalAppFile);
@@ -125,10 +125,16 @@ class Cloud extends core_1.Command {
125
125
  if (!finalBinaryId) {
126
126
  core_1.ux.action.start('Uploading binary', 'Initializing', { stdout: true });
127
127
  const binaryFormData = new FormData();
128
- const binaryBlob = new Blob([await (0, promises_1.readFile)(finalAppFile)], {
129
- type: mimeTypeLookupByExtension[finalAppFile.split('.').pop()],
130
- });
131
- binaryFormData.set('file', binaryBlob, finalAppFile);
128
+ if (finalAppFile?.endsWith('.app')) {
129
+ const zippedAppBlob = await (0, methods_1.compressFolderToBlob)(finalAppFile);
130
+ binaryFormData.set('file', zippedAppBlob, finalAppFile + '.zip');
131
+ }
132
+ else {
133
+ const binaryBlob = new Blob([await (0, promises_1.readFile)(finalAppFile)], {
134
+ type: mimeTypeLookupByExtension[finalAppFile.split('.').pop()],
135
+ });
136
+ binaryFormData.set('file', binaryBlob, finalAppFile);
137
+ }
132
138
  const options = {
133
139
  body: binaryFormData,
134
140
  headers: { 'x-app-api-key': apiKey },
package/dist/methods.d.ts CHANGED
@@ -11,5 +11,6 @@ export declare const typeSafeGet: <T extends keyof paths>(baseUrl: string, path:
11
11
  }) => Promise<paths[T]["get"]["responses"]["200"]["content"]["application/json"]>;
12
12
  export declare const toBuffer: (archive: archiver.Archiver) => Promise<Buffer>;
13
13
  export declare const compressDir: (sourceDir: string) => Promise<Buffer>;
14
+ export declare const compressFolderToBlob: (sourceDir: string) => Promise<Blob>;
14
15
  export declare const compressFilesFromRelativePath: (path: string, files: string[]) => Promise<Buffer>;
15
16
  export declare const verifyAppZip: (zipPath: string) => Promise<void>;
package/dist/methods.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.verifyAppZip = exports.compressFilesFromRelativePath = exports.compressDir = exports.toBuffer = exports.typeSafeGet = exports.typeSafePost = void 0;
3
+ exports.verifyAppZip = exports.compressFilesFromRelativePath = exports.compressFolderToBlob = exports.compressDir = exports.toBuffer = exports.typeSafeGet = exports.typeSafePost = void 0;
4
4
  const archiver = require("archiver");
5
5
  // import { writeFile } from 'node:fs/promises';
6
6
  const nodePath = require("node:path");
@@ -68,6 +68,18 @@ const compressDir = async (sourceDir) => {
68
68
  return buffer;
69
69
  };
70
70
  exports.compressDir = compressDir;
71
+ const compressFolderToBlob = async (sourceDir) => {
72
+ const archive = archiver('zip', {
73
+ zlib: { level: 9 },
74
+ });
75
+ archive.on('error', (err) => {
76
+ throw err;
77
+ });
78
+ archive.directory(sourceDir, sourceDir.split('/').pop());
79
+ const buffer = await (0, exports.toBuffer)(archive);
80
+ return new Blob([buffer], { type: 'application/zip' });
81
+ };
82
+ exports.compressFolderToBlob = compressFolderToBlob;
71
83
  const compressFilesFromRelativePath = async (path, files) => {
72
84
  const archive = archiver('zip', {
73
85
  zlib: { level: 9 },
package/dist/plan.js CHANGED
@@ -1,32 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.plan = void 0;
4
- /* eslint-disable complexity */
5
4
  const glob_1 = require("glob");
6
5
  const fs = require("node:fs");
7
6
  const path = require("node:path");
8
7
  const planMethods_1 = require("./planMethods");
9
- const commandsThatRequireFiles = new Set(['addMedia', 'runFlow', 'runScript']);
10
8
  async function plan(input, includeTags, excludeTags) {
11
9
  if (!fs.existsSync(input)) {
12
10
  throw new Error(`Flow path does not exist: ${path.resolve(input)}`);
13
11
  }
14
12
  if (fs.lstatSync(input).isFile()) {
15
- const directory = path.dirname(input);
16
- const { testSteps } = (0, planMethods_1.readTestYamlFileAsJson)(input);
17
- let errors = [];
18
- let allFiles = [];
19
- for (const command of testSteps) {
20
- if (typeof command === 'string')
21
- continue;
22
- for (const [commandName, commandValue] of Object.entries(command)) {
23
- if (commandsThatRequireFiles.has(commandName)) {
24
- const { errors: newErrors, files } = (0, planMethods_1.checkIfFilesExistInWorkspace)(commandName, commandValue, path.normalize(input), directory + '/');
25
- errors = [...errors, ...newErrors];
26
- allFiles = [...allFiles, ...files];
27
- }
28
- }
29
- }
13
+ const directory = path.dirname(input) + '/';
14
+ const { config, testSteps } = (0, planMethods_1.readTestYamlFileAsJson)(input);
15
+ const { allFiles, errors } = (0, planMethods_1.processDependencies)({
16
+ config,
17
+ directory,
18
+ input,
19
+ testSteps,
20
+ });
30
21
  if (errors.length > 0) {
31
22
  throw new Error('The following flow files are not present in the provided directory: \n' +
32
23
  errors.join('\n'));
@@ -84,20 +75,17 @@ async function plan(input, includeTags, excludeTags) {
84
75
  });
85
76
  let errors = [];
86
77
  let allFiles = [];
87
- for (const [filePath, commands] of Object.entries(testStepsPerFlowFile)) {
88
- if (!commands)
78
+ for (const [filePath, testSteps] of Object.entries(testStepsPerFlowFile)) {
79
+ if (!testSteps)
89
80
  break;
90
- for (const command of commands) {
91
- if (typeof command === 'string')
92
- continue;
93
- for (const [commandName, commandValue] of Object.entries(command)) {
94
- if (commandsThatRequireFiles.has(commandName)) {
95
- const { errors: newErrors, files } = (0, planMethods_1.checkIfFilesExistInWorkspace)(commandName, commandValue, filePath, cleanPath);
96
- errors = [...errors, ...newErrors];
97
- allFiles = [...allFiles, ...files];
98
- }
99
- }
100
- }
81
+ const { allFiles: deps, errors: errs } = (0, planMethods_1.processDependencies)({
82
+ config: configPerFlowFile[path.relative(cleanPath, filePath)],
83
+ directory: cleanPath,
84
+ input: filePath,
85
+ testSteps,
86
+ });
87
+ allFiles = [...allFiles, ...deps];
88
+ errors = [...errors, ...errs];
101
89
  }
102
90
  if (errors.length > 0) {
103
91
  throw new Error('The following flow files are not present in the provided directory: \n' +
@@ -132,19 +120,6 @@ async function plan(input, includeTags, excludeTags) {
132
120
  ?.map((flowOrder) => (0, planMethods_1.getFlowsToRunInSequence)(pathsByName, [flowOrder]))
133
121
  .flat() || [];
134
122
  const normalFlows = allFlows.filter((flow) => !flowsToRunInSequence.includes(flow));
135
- // for (const filePath of allFlows) {
136
- // const commands = YamlCommandReader.readCommands(filePath).filter(
137
- // (command) => command.addMediaCommand,
138
- // );
139
- // const mediaPaths = commands.flatMap(
140
- // (command) => command.addMediaCommand.mediaPaths,
141
- // );
142
- // YamlCommandsPathValidator.validatePathsExistInWorkspace(
143
- // input,
144
- // filePath,
145
- // mediaPaths,
146
- // );
147
- // }
148
123
  return {
149
124
  allExcludeTags,
150
125
  allIncludeTags,
@@ -15,3 +15,14 @@ export declare const checkIfFilesExistInWorkspace: (commandName: string, command
15
15
  errors: string[];
16
16
  files: string[];
17
17
  };
18
+ interface IProcessDependencies {
19
+ config?: Record<string, unknown> | null;
20
+ directory: string;
21
+ input: string;
22
+ testSteps: Record<string, unknown>[];
23
+ }
24
+ export declare const processDependencies: ({ config, directory, input, testSteps, }: IProcessDependencies) => {
25
+ allFiles: string[];
26
+ errors: string[];
27
+ };
28
+ export {};
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkIfFilesExistInWorkspace = exports.walk = exports.readTestYamlFileAsJson = exports.readYamlFileAsJson = exports.isFlowFile = exports.getFlowsToRunInSequence = void 0;
3
+ exports.processDependencies = exports.checkIfFilesExistInWorkspace = exports.walk = exports.readTestYamlFileAsJson = exports.readYamlFileAsJson = exports.isFlowFile = exports.getFlowsToRunInSequence = void 0;
4
4
  /* eslint-disable unicorn/filename-case */
5
5
  const yaml = require("js-yaml");
6
6
  const fs = require("node:fs");
7
7
  const path = require("node:path");
8
+ const commandsThatRequireFiles = new Set(['addMedia', 'runFlow', 'runScript']);
8
9
  function getFlowsToRunInSequence(paths, flowOrder) {
9
10
  if (flowOrder.length === 0)
10
11
  return [];
@@ -77,7 +78,7 @@ const checkIfFilesExistInWorkspace = (commandName, command, filePath, cleanPath)
77
78
  const errors = [];
78
79
  const files = [];
79
80
  const directory = path.dirname(filePath);
80
- const buildError = (error) => `Flow file "${filePath}" has a command "${commandName}" that references a ${error} "${command}"`;
81
+ const buildError = (error) => `Flow file "${filePath.replace(cleanPath, './')}" has a command "${commandName}" that references a ${error} ${JSON.stringify(command)}`;
81
82
  const processFilePath = (relativePath) => {
82
83
  const absoluteFilePath = path.resolve(directory, relativePath);
83
84
  const error = checkFile(absoluteFilePath, cleanPath);
@@ -107,3 +108,28 @@ const checkFile = (filePath, cleanPath) => {
107
108
  if (!filePath.startsWith(cleanPath))
108
109
  return `file outside the workspace`;
109
110
  };
111
+ const processDependencies = ({ config, directory, input, testSteps, }) => {
112
+ let errors = [];
113
+ let allFiles = [];
114
+ const { onFlowComplete, onFlowStart } = config ?? {};
115
+ const stepsArray = [testSteps];
116
+ if (onFlowStart)
117
+ stepsArray.push(onFlowStart);
118
+ if (onFlowComplete)
119
+ stepsArray.push(onFlowComplete);
120
+ for (const steps of stepsArray) {
121
+ for (const command of steps) {
122
+ if (typeof command === 'string')
123
+ continue;
124
+ for (const [commandName, commandValue] of Object.entries(command)) {
125
+ if (commandsThatRequireFiles.has(commandName)) {
126
+ const { errors: newErrors, files } = (0, exports.checkIfFilesExistInWorkspace)(commandName, commandValue, path.normalize(input), directory);
127
+ errors = [...errors, ...newErrors];
128
+ allFiles = [...allFiles, ...files];
129
+ }
130
+ }
131
+ }
132
+ }
133
+ return { allFiles, errors };
134
+ };
135
+ exports.processDependencies = processDependencies;
@@ -4,7 +4,7 @@
4
4
  "aliases": [],
5
5
  "args": {
6
6
  "firstFile": {
7
- "description": "The binary file of the app to run your flow against, e.g. app.apk for android or app.zip for ios",
7
+ "description": "The binary file of the app to run your flow against, e.g. test.apk for android or test.app/.zip for ios",
8
8
  "hidden": true,
9
9
  "name": "firstFile"
10
10
  },
@@ -220,5 +220,5 @@
220
220
  ]
221
221
  }
222
222
  },
223
- "version": "0.0.4"
223
+ "version": "0.0.5"
224
224
  }
package/package.json CHANGED
@@ -73,7 +73,7 @@
73
73
  "test": "mocha --forbid-only \"test/**/*.test.ts\"",
74
74
  "version": "oclif readme && git add README.md"
75
75
  },
76
- "version": "0.0.4",
76
+ "version": "0.0.5",
77
77
  "bugs": {
78
78
  "url": "https://discord.gg/gm3mJwcNw8"
79
79
  },