doc-detective-common 1.21.0-openapi.9 → 1.21.1-dev.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.
package/README.md CHANGED
@@ -52,6 +52,10 @@ const object = {
52
52
  console.log(common.validate(schemaKey, object));
53
53
  ```
54
54
 
55
+ ### `.readFile(fileURL)`
56
+
57
+ Load file contents from a URL or a file path. If a JSON or YAML file, returns an object. If a different file, returns a string.
58
+
55
59
  ## Objects
56
60
 
57
61
  ### `.schemas`
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "doc-detective-common",
3
- "version": "1.21.0-openapi.9",
3
+ "version": "1.21.1-dev.0",
4
4
  "description": "Shared components for Doc Detective projects.",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
7
7
  "dereferenceSchemas": "node ./src/schemas/dereferenceSchemas.js",
8
8
  "test:full": "npm run dereferenceSchemas && npm run test",
9
- "test": "jest"
9
+ "test": "mocha"
10
10
  },
11
11
  "repository": {
12
12
  "type": "git",
@@ -19,14 +19,18 @@
19
19
  },
20
20
  "homepage": "https://github.com/doc-detective/doc-detective-common#readme",
21
21
  "devDependencies": {
22
- "jest": "^29.7.0"
22
+ "chai": "^5.1.2",
23
+ "mocha": "^10.8.2",
24
+ "sinon": "^19.0.2"
23
25
  },
24
26
  "dependencies": {
25
- "@apidevtools/json-schema-ref-parser": "^11.7.0",
26
- "ajv": "8.16.0",
27
+ "@apidevtools/json-schema-ref-parser": "^11.7.2",
28
+ "ajv": "^8.17.1",
27
29
  "ajv-errors": "^3.0.0",
28
30
  "ajv-formats": "^3.0.1",
29
31
  "ajv-keywords": "^5.1.0",
30
- "uuid": "^10.0.0"
32
+ "axios": "^1.7.7",
33
+ "uuid": "^11.0.3",
34
+ "yaml": "^2.6.0"
31
35
  }
32
36
  }
package/src/files.js ADDED
@@ -0,0 +1,64 @@
1
+ const fs = require("fs");
2
+ const YAML = require("yaml");
3
+ const axios = require("axios");
4
+ const { URL } = require("url");
5
+
6
+ /**
7
+ * Reads a file from a given URL or local file path and returns its content.
8
+ * Supports JSON and YAML file formats.
9
+ *
10
+ * @param {string} fileURL - The URL or local file path of the file to read.
11
+ * @returns {Promise<Object|string|null>} - The parsed content of the file if it's JSON or YAML,
12
+ * the raw content if it's another format,
13
+ * or null if an error occurs.
14
+ */
15
+ async function readFile(fileURL) {
16
+
17
+ let content;
18
+ let isRemote = false;
19
+
20
+ try {
21
+ const parsedURL = new URL(fileURL);
22
+ isRemote = parsedURL.protocol === "http:" || parsedURL.protocol === "https:";
23
+ } catch (error) {
24
+ // Not a valid URL, assume local file path
25
+ }
26
+
27
+ if (isRemote) {
28
+ try {
29
+ const response = await axios.get(fileURL);
30
+ content = response.data;
31
+ } catch (error) {
32
+ console.warn(`Error reading remote file from ${fileURL}: ${error.message}`);
33
+ return null;
34
+ }
35
+ } else {
36
+ try {
37
+ content = await fs.promises.readFile(fileURL, "utf8");
38
+ } catch (error) {
39
+ if (error.code === 'ENOENT') {
40
+ console.warn(`File not found: ${fileURL}`);
41
+ } else {
42
+ console.warn(`Error reading file: ${error.message}`);
43
+ }
44
+ return null;
45
+ }
46
+ }
47
+
48
+ // Parse based on file content, and return either object or string
49
+ try {
50
+ // Try to parse as JSON
51
+ return JSON.parse(content);
52
+ } catch (error) {
53
+ try {
54
+ // Try to parse as YAML
55
+ return YAML.parse(content);
56
+ } catch (error) {
57
+ // Return raw content if not JSON or YAML
58
+ return content;
59
+ }
60
+ }
61
+
62
+ }
63
+
64
+ module.exports = { readFile };
package/src/index.js CHANGED
@@ -1,7 +1,11 @@
1
1
  const { schemas } = require("./schemas");
2
2
  const { validate } = require("./validate");
3
3
  const { resolvePaths } = require("./resolvePaths");
4
+ const { readFile } = require("./files");
4
5
 
5
- exports.schemas = schemas;
6
- exports.validate = validate;
7
- exports.resolvePaths = resolvePaths;
6
+ module.exports = {
7
+ schemas,
8
+ validate,
9
+ resolvePaths,
10
+ readFile,
11
+ };
@@ -30,7 +30,7 @@ async function resolvePaths(
30
30
  "cleanup",
31
31
  "mediaDirectory",
32
32
  "downloadDirectory",
33
- "definitionPath",
33
+ "descriptionPath",
34
34
  "path",
35
35
  ];
36
36
  // Spec properties that contain paths
@@ -42,7 +42,7 @@ async function resolvePaths(
42
42
  "cleanup",
43
43
  "savePath",
44
44
  "saveDirectory",
45
- "definitionPath",
45
+ "descriptionPath",
46
46
  "workingDirectory",
47
47
  ];
48
48
  // Spec objects that are configurable by the user and shouldn't be resolved
@@ -139,8 +139,7 @@ async function resolvePaths(
139
139
  object[pathProperty]
140
140
  );
141
141
  }
142
- }
143
- if (pathProperty === "savePath" && object.saveDirectory) {
142
+ } else if (pathProperty === "savePath" && object.saveDirectory) {
144
143
  if (path.isAbsolute(object.saveDirectory)) {
145
144
  object[pathProperty] = resolve(
146
145
  relativePathBase,
@@ -153,12 +152,13 @@ async function resolvePaths(
153
152
  object[pathProperty]
154
153
  );
155
154
  }
155
+ } else {
156
+ object[pathProperty] = resolve(
157
+ relativePathBase,
158
+ object[pathProperty],
159
+ filePath
160
+ );
156
161
  }
157
- object[pathProperty] = resolve(
158
- relativePathBase,
159
- object[pathProperty],
160
- filePath
161
- );
162
162
  }
163
163
  });
164
164
  }
@@ -1,115 +1,115 @@
1
- const parser = require("@apidevtools/json-schema-ref-parser");
2
- const path = require("path");
3
- const fs = require("fs");
4
-
5
- (async () => {
6
- await dereferenceSchemas();
7
- })();
8
-
9
- /*
10
- * Walks through all schema in src/src_schema
11
- * For each schema, dereferences it and writes it to src/schema
12
- */
13
- async function dereferenceSchemas() {
14
- const inputDir = path.resolve(`${__dirname}/src_schemas`);
15
- const buildDir = path.resolve(`${__dirname}/build`);
16
- fs.mkdir(buildDir, { recursive: true }, (err) => {
17
- if (err) throw err;
18
- });
19
- const outputDir = path.resolve(`${__dirname}/output_schemas`);
20
- var files = [
21
- "checkLink_v2.schema.json",
22
- "config_v2.schema.json",
23
- "context_v2.schema.json",
24
- "find_v2.schema.json",
25
- "goTo_v2.schema.json",
26
- "httpRequest_v2.schema.json",
27
- "moveTo_v2.schema.json",
28
- "openApi_v2.schema.json",
29
- "runShell_v2.schema.json",
30
- "saveScreenshot_v2.schema.json",
31
- "setVariables_v2.schema.json",
32
- "startRecording_v2.schema.json",
33
- "stopRecording_v2.schema.json",
34
- "spec_v2.schema.json",
35
- "test_v2.schema.json",
36
- "typeKeys_v2.schema.json",
37
- "wait_v2.schema.json",
38
- ];
39
- // Update schema reference paths
40
- for (const file of files) {
41
- // console.log(`File: ${file}`)
42
- const filePath = path.resolve(`${inputDir}/${file}`);
43
- // Load from file
44
- let schema = fs.readFileSync(filePath).toString();
45
- // Convert to JSON
46
- schema = JSON.parse(schema);
47
- // Set ID
48
- schema.$id = `${filePath}`;
49
- // Update references to current relative path
50
- schema = updateRefPaths(schema);
51
- // Write to file
52
- fs.writeFileSync(`${buildDir}/${file}`, JSON.stringify(schema, null, 2));
53
- }
54
- // Dereference schemas
55
- for await (const file of files) {
56
- const filePath = path.resolve(`${buildDir}/${file}`);
57
- // Load from file
58
- let schema = fs.readFileSync(filePath).toString();
59
- // Convert to JSON
60
- schema = JSON.parse(schema);
61
- // Dereference schema
62
- schema = await parser.dereference(schema);
63
- // Delete $id attributes
64
- schema = deleteDollarIds(schema);
65
- // Write to file
66
- fs.writeFileSync(`${outputDir}/${file}`, JSON.stringify(schema, null, 2));
67
- }
68
- // Build final schemas.json file
69
- const schemas = {};
70
- files.forEach(async (file) => {
71
- const key = file.replace(".schema.json", "");
72
- // Load schema from file
73
- let schema = require(`${outputDir}/${file}`);
74
- // Load into `schema` object
75
- schemas[key] = schema;
76
- });
77
- fs.writeFileSync(`${__dirname}/schemas.json`, JSON.stringify(schemas,null,2));
78
-
79
- // Clean up build dir
80
- // fs.rm(buildDir, { recursive: true }, (err) => {
81
- // if (err) throw err;
82
- // });
83
- }
84
-
85
- // Prepend app-root path to referenced relative paths
86
- function updateRefPaths(schema) {
87
- for (let [key, value] of Object.entries(schema)) {
88
- if (typeof value === "object") {
89
- updateRefPaths(value);
90
- }
91
- if (key === "$ref" && !value.startsWith("#")) {
92
- // File name of the referenced schema
93
- valueFile = value.split("#")[0];
94
- // Attribute path in the referenced schema
95
- valueAttribute = value.split("#")[1];
96
- valuePath = path.resolve(`${__dirname}/build/${valueFile}`);
97
- schema[key] = `${valuePath}#${valueAttribute}`;
98
- // console.log({value, valueFile, valueAttribute, final: schema[key]})
99
- }
100
- }
101
- return schema;
102
- }
103
-
104
- // Prepend app-root path to referenced relative paths
105
- function deleteDollarIds(schema) {
106
- for (let [key, value] of Object.entries(schema)) {
107
- if (typeof value === "object") {
108
- deleteDollarIds(value);
109
- }
110
- if (key === "$id") {
111
- delete schema[key]
112
- }
113
- }
114
- return schema;
115
- }
1
+ const parser = require("@apidevtools/json-schema-ref-parser");
2
+ const path = require("path");
3
+ const fs = require("fs");
4
+
5
+ (async () => {
6
+ await dereferenceSchemas();
7
+ })();
8
+
9
+ /*
10
+ * Walks through all schema in src/src_schema
11
+ * For each schema, dereferences it and writes it to src/schema
12
+ */
13
+ async function dereferenceSchemas() {
14
+ const inputDir = path.resolve(`${__dirname}/src_schemas`);
15
+ const buildDir = path.resolve(`${__dirname}/build`);
16
+ fs.mkdir(buildDir, { recursive: true }, (err) => {
17
+ if (err) throw err;
18
+ });
19
+ const outputDir = path.resolve(`${__dirname}/output_schemas`);
20
+ var files = [
21
+ "checkLink_v2.schema.json",
22
+ "config_v2.schema.json",
23
+ "context_v2.schema.json",
24
+ "find_v2.schema.json",
25
+ "goTo_v2.schema.json",
26
+ "httpRequest_v2.schema.json",
27
+ "moveTo_v2.schema.json",
28
+ "openApi_v2.schema.json",
29
+ "runShell_v2.schema.json",
30
+ "saveScreenshot_v2.schema.json",
31
+ "setVariables_v2.schema.json",
32
+ "startRecording_v2.schema.json",
33
+ "stopRecording_v2.schema.json",
34
+ "spec_v2.schema.json",
35
+ "test_v2.schema.json",
36
+ "typeKeys_v2.schema.json",
37
+ "wait_v2.schema.json",
38
+ ];
39
+ // Update schema reference paths
40
+ for (const file of files) {
41
+ // console.log(`File: ${file}`)
42
+ const filePath = path.resolve(`${inputDir}/${file}`);
43
+ // Load from file
44
+ let schema = fs.readFileSync(filePath).toString();
45
+ // Convert to JSON
46
+ schema = JSON.parse(schema);
47
+ // Set ID
48
+ schema.$id = `${filePath}`;
49
+ // Update references to current relative path
50
+ schema = updateRefPaths(schema);
51
+ // Write to file
52
+ fs.writeFileSync(`${buildDir}/${file}`, JSON.stringify(schema, null, 2));
53
+ }
54
+ // Dereference schemas
55
+ for await (const file of files) {
56
+ const filePath = path.resolve(`${buildDir}/${file}`);
57
+ // Load from file
58
+ let schema = fs.readFileSync(filePath).toString();
59
+ // Convert to JSON
60
+ schema = JSON.parse(schema);
61
+ // Dereference schema
62
+ schema = await parser.dereference(schema);
63
+ // Delete $id attributes
64
+ schema = deleteDollarIds(schema);
65
+ // Write to file
66
+ fs.writeFileSync(`${outputDir}/${file}`, JSON.stringify(schema, null, 2));
67
+ }
68
+ // Build final schemas.json file
69
+ const schemas = {};
70
+ files.forEach(async (file) => {
71
+ const key = file.replace(".schema.json", "");
72
+ // Load schema from file
73
+ let schema = require(`${outputDir}/${file}`);
74
+ // Load into `schema` object
75
+ schemas[key] = schema;
76
+ });
77
+ fs.writeFileSync(`${__dirname}/schemas.json`, JSON.stringify(schemas,null,2));
78
+
79
+ // Clean up build dir
80
+ // fs.rm(buildDir, { recursive: true }, (err) => {
81
+ // if (err) throw err;
82
+ // });
83
+ }
84
+
85
+ // Prepend app-root path to referenced relative paths
86
+ function updateRefPaths(schema) {
87
+ for (let [key, value] of Object.entries(schema)) {
88
+ if (typeof value === "object") {
89
+ updateRefPaths(value);
90
+ }
91
+ if (key === "$ref" && !value.startsWith("#")) {
92
+ // File name of the referenced schema
93
+ valueFile = value.split("#")[0];
94
+ // Attribute path in the referenced schema
95
+ valueAttribute = value.split("#")[1];
96
+ valuePath = path.resolve(`${__dirname}/build/${valueFile}`);
97
+ schema[key] = `${valuePath}#${valueAttribute}`;
98
+ // console.log({value, valueFile, valueAttribute, final: schema[key]})
99
+ }
100
+ }
101
+ return schema;
102
+ }
103
+
104
+ // Prepend app-root path to referenced relative paths
105
+ function deleteDollarIds(schema) {
106
+ for (let [key, value] of Object.entries(schema)) {
107
+ if (typeof value === "object") {
108
+ deleteDollarIds(value);
109
+ }
110
+ if (key === "$id") {
111
+ delete schema[key]
112
+ }
113
+ }
114
+ return schema;
115
+ }