cob-cli 2.50.0 → 2.51.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.
@@ -8,7 +8,7 @@ function validateUpdateFromServerConditions(cmdEnv) {
8
8
  return new Listr([
9
9
  { title: "Check connectivity and permissions".bold, task: () => checkConnectivity(cmdEnv.server) },
10
10
  { title: "Check there's no cob-cli test' running".bold, task: () => checkNoTestsRunningOnServer(cmdEnv.server) },
11
- { title: "Check git status".bold, task: () => checkWorkingCopyCleanliness() },
12
- ])
11
+ { title: "Check git status".bold, task: () => checkWorkingCopyCleanliness() },
12
+ ])
13
13
  }
14
- exports.validateUpdateFromServerConditions = validateUpdateFromServerConditions
14
+ exports.validateUpdateFromServerConditions = validateUpdateFromServerConditions
@@ -36,7 +36,7 @@ module.exports = env => {
36
36
  },
37
37
  proxy: {
38
38
  [ "**/" + process.env.dash_dir + "/**"]: {
39
- target: "http://localhost:" + (process.env.dash_port || 8041),
39
+ target: "http://localhost:8041",
40
40
  secure: false
41
41
  },
42
42
  [ "/docs/**"]: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cob-cli",
3
- "version": "2.50.0",
3
+ "version": "2.51.0",
4
4
  "description": "A command line utility to help Cult of Bits partners develop with higher speed and reusing common code and best practices.",
5
5
  "preferGlobal": true,
6
6
  "repository": {
@@ -18,7 +18,6 @@
18
18
  "dependencies": {
19
19
  "@webpack-cli/serve": "^2.0.1",
20
20
  "axios": "^0.21.1",
21
- "axios-cookiejar-support": "^5.0.5",
22
21
  "chokidar": "^3.5.3",
23
22
  "cmd-line-importer": "^1.0.0",
24
23
  "colors": "^1.4.0",
@@ -29,14 +28,11 @@
29
28
  "file-cookie-store": "^0.2.1",
30
29
  "fs-extra": "^9.0.1",
31
30
  "inquirer": "^7.3.3",
32
- "js-yaml": "^4.1.0",
33
31
  "listr": "^0.14.3",
34
32
  "ncp": "^2.0.0",
35
33
  "omelette": "^0.4.15-1",
36
34
  "open": "^8.4.0",
37
35
  "simple-git": "^3.15.1",
38
- "tar": "^7.4.3",
39
- "tough-cookie": "^5.1.2",
40
36
  "webpack": "^5.75.0",
41
37
  "webpack-cli": "^5.0.1",
42
38
  "webpack-dev-server": "^4.11.1",
@@ -1,106 +0,0 @@
1
- require('colors');
2
- const git = require('simple-git');
3
- const fs = require('fs-extra');
4
- const fg = require('fast-glob');
5
- const execa = require('execa');
6
- const Listr = require('listr');
7
- const UpdaterRenderer = require('listr-update-renderer');
8
- const verboseRenderer = require('listr-verbose-renderer');
9
- const { getCurrentCommandEnviroment } = require("../task_lists/common_enviromentHandler");
10
- const { SERVER_COB_CLI_DIRECTORY } = require("../task_lists/common_helpers");
11
- const { restoreServerFilesToLastDeployed } = require("../task_lists/test_otherFilesContiousReload");
12
- const { loadOperationState, clearOperationState } = require("../task_lists/common_operationState");
13
- const { checkRepoVersion } = require("../commands/upgradeRepo");
14
-
15
- const LOCAL_TEST_LOCK_FILE = ".test.in.execution";
16
- const SERVER_TEST_LOCK_FILE = SERVER_COB_CLI_DIRECTORY + "test.in.execution";
17
-
18
- async function cleanup(args) {
19
- try {
20
- checkRepoVersion()
21
-
22
- const savedState = loadOperationState();
23
- if (savedState) {
24
- if (!args.environment) args.environment = savedState.environment;
25
- if (!args.servername) args.servername = savedState.servername;
26
- }
27
-
28
- console.log("Cleaning up interrupted test/deploy state...".bold)
29
-
30
- const cmdEnv = await getCurrentCommandEnviroment(args)
31
- console.log(` environment: ${cmdEnv.name.bold} server: ${cmdEnv.serverStr}`)
32
-
33
- await new Listr([
34
- {
35
- title: "Undo environment-specific file changes".bold,
36
- skip: async () => {
37
- const backupFiles = await fg(
38
- ['**/*.ENV__ORIGINAL_BACKUP__.*', '**/*.ENV__DELETE__.*'],
39
- { onlyFiles: false, dot: true }
40
- );
41
- return backupFiles.length === 0 ? "No environment-specific changes found" : false;
42
- },
43
- task: () => cmdEnv.unApplyCurrentCommandEnvironmentChanges()
44
- },
45
- {
46
- // Runs after the local env undo so the working tree is clean before
47
- // stashing and checking out the last-deployed SHA.
48
- title: "Restore server files to last deployed version".bold,
49
- skip: () => args.localOnly ? "Skipping server restore (--localOnly)" : false,
50
- task: async () => {
51
- let changedFiles = [];
52
- try {
53
- const result = await execa('ssh', [cmdEnv.server, "cat " + SERVER_TEST_LOCK_FILE]);
54
- changedFiles = result.stdout.split("\n")
55
- .map(l => l.split(" ")[0].trim())
56
- .filter(f => f);
57
- } catch { /* no test.in.execution on server = nothing to restore */ }
58
-
59
- if (changedFiles.length === 0) return;
60
-
61
- await restoreServerFilesToLastDeployed(cmdEnv, changedFiles);
62
- }
63
- },
64
- {
65
- title: "Restore git branch from detached HEAD".bold,
66
- skip: async () => {
67
- const branch = await git().revparse(["--abbrev-ref", "HEAD"]);
68
- return branch.trim() !== "HEAD" ? "Not in detached HEAD state" : false;
69
- },
70
- task: () => git().checkout("-")
71
- },
72
- {
73
- title: "Remove local test lock file".bold,
74
- skip: () => !fs.existsSync(LOCAL_TEST_LOCK_FILE) ? "No local test lock file found" : false,
75
- task: () => fs.unlinkSync(LOCAL_TEST_LOCK_FILE)
76
- },
77
- {
78
- title: "Remove server test lock file".bold,
79
- skip: () => args.localOnly ? "Skipping server cleanup (--localOnly)" : false,
80
- task: () => execa('ssh', [cmdEnv.server, "rm -f " + SERVER_TEST_LOCK_FILE])
81
- .catch(() => {}) // non-critical if server unreachable
82
- },
83
- ], {
84
- renderer: args.verbose ? verboseRenderer : UpdaterRenderer,
85
- collapse: false
86
- }).run()
87
-
88
- clearOperationState()
89
-
90
- // Inform about stashes — don't auto-pop since user may have unrelated stashes
91
- const stashList = await git().stash(["list"]);
92
- if (stashList) {
93
- console.log("\n" + "Note:".yellow.bold
94
- + " Stashed changes detected (may be from the interrupted operation):")
95
- console.log(stashList.split("\n").slice(0, 3).map(l => " " + l).join("\n"))
96
- console.log("Run " + "git stash pop".yellow + " if you want to restore your uncommitted changes.\n")
97
- }
98
-
99
- console.log("\nDone!".green, "\nYou can now run 'cob-cli test' or 'cob-cli deploy' again.\n")
100
-
101
- } catch(err) {
102
- console.error("\n", err.message)
103
- }
104
- }
105
-
106
- module.exports = cleanup;
@@ -1,20 +0,0 @@
1
- require('colors');
2
- const { checkRepoVersion } = require("../commands/upgradeRepo");
3
- const { getCurrentCommandEnviroment } = require("../task_lists/common_enviromentHandler");
4
- const { executeTasks } = require("../task_lists/package_execute");
5
-
6
- async function package(args) {
7
- try {
8
- checkRepoVersion()
9
- const cmdEnv = await getCurrentCommandEnviroment(args)
10
- if(args.resync) args.force = true;
11
-
12
- await executeTasks(cmdEnv, args).run();
13
-
14
- console.log("\nDone!".green, "\nEnjoy!")
15
-
16
- } catch(err) {
17
- console.error("\n",err.message);
18
- }
19
- }
20
- module.exports = package;
@@ -1,67 +0,0 @@
1
- require('colors');
2
- const { getCurrentCommandEnviroment } = require("../task_lists/common_enviromentHandler");
3
- const { promptCredentials, readYamlFile } = require("../task_lists/common_helpers.js");
4
- const { tagDefinitions } = require("../task_lists/tagDefs_execute.js");
5
- const { checkRepoVersion } = require("../commands/upgradeRepo");
6
- const axios = require('axios');
7
- const tough = require('tough-cookie');
8
- const axiosCookieJarSupport = require('axios-cookiejar-support')
9
- const path = require('path')
10
- const FileCookieStore = require('file-cookie-store');
11
-
12
- async function tagDefs(args) {
13
- try {
14
- checkRepoVersion()
15
- const cmdEnv = await getCurrentCommandEnviroment(args)
16
-
17
- axiosCookieJarSupport.wrapper(axios)
18
- axios.defaults.ignoreCookieErrors = true
19
- axios.defaults.withCredentials = true
20
- const cookieJar = new tough.CookieJar()
21
- axios.defaults.jar = cookieJar
22
-
23
- if( args.cookie ) {
24
- const p = path.resolve(args.cookie);
25
- const cookieFile = new FileCookieStore(p, {auto_sync: false, force_parse: true});
26
- try{
27
- let c = await new Promise((resolve, reject) => {
28
- cookieFile.findCookie(`${cmdEnv.servername}.cultofbits.com`, '/', 'cobtoken', (err, result) => {
29
- if(err != null) reject(err);
30
- else resolve(result)
31
- })
32
- });
33
- if(!c){
34
- throw Error( `couldn't find a cookie for ${cmdEnv.servername} in ${p}`)
35
- }
36
- cookieJar.setCookie(c.toString(), `https://${cmdEnv.servername}.cultofbits.com`)
37
- } catch(e){
38
- console.error(e)
39
- return
40
- }
41
-
42
- } else {
43
-
44
- const credentials = await promptCredentials()
45
-
46
- await axios.post(`https://${cmdEnv.servername}.cultofbits.com/recordm/security/auth`, credentials, {
47
- headers: {
48
- "Content-Type": "application/json",
49
- },
50
- })
51
- }
52
-
53
- const solutions = await readYamlFile("solutions.yml")
54
-
55
- for (const solution of solutions) {
56
- console.log("\nStarting to tag Defs of solution " + solution.name, solution.definitions)
57
- if (solution.definitions) {
58
- await tagDefinitions(cmdEnv.servername, solution.name, solution.definitions, args)
59
- }
60
- }
61
-
62
- } catch (err) {
63
- console.error("\n", err.message);
64
- }
65
- }
66
-
67
- module.exports = tagDefs;
@@ -1,26 +0,0 @@
1
- const axios = require("axios");
2
-
3
- async function getFilteredDefinitions(servername, defConfigs) {
4
- const uri = `https://${servername}.cultofbits.com/recordm/recordm/definitions`
5
- const response = await axios.get( uri );
6
-
7
- if(response.status != 200){
8
- throw new Error(`HTTP Error Response: ${response.status} ${response.statusText}`);
9
- }
10
-
11
- let result = defConfigs.flatMap(c => {
12
- return response.data.filter(def => match(c.filter, def))
13
- .map(m => ({...m, ...c}))
14
- });
15
-
16
- return result
17
- }
18
-
19
- function match(query, definition) {
20
- // simple matching for now
21
- return definition.name.includes(query) || definition.description?.includes(query)
22
- }
23
-
24
- module.exports = {
25
- getFilteredDefinitions: getFilteredDefinitions
26
- }
@@ -1,28 +0,0 @@
1
- const fs = require('fs-extra');
2
- const fg = require('fast-glob');
3
- const STATE_FILE = ".git/cob-cli-state";
4
-
5
- function saveOperationState(environment, servername) {
6
- try { fs.writeJsonSync(STATE_FILE, { environment, servername }); } catch {}
7
- }
8
-
9
- function loadOperationState() {
10
- try { return fs.readJsonSync(STATE_FILE); } catch { return null; }
11
- }
12
-
13
- function clearOperationState() {
14
- try { fs.unlinkSync(STATE_FILE); } catch {}
15
- }
16
-
17
- async function checkNoInterruptedRun() {
18
- const stateExists = !!loadOperationState();
19
- const envBackupFiles = await fg(['**/*.ENV__ORIGINAL_BACKUP__.*', '**/*.ENV__DELETE__.*'], { onlyFiles: false, dot: true });
20
- if (stateExists || envBackupFiles.length > 0) {
21
- throw new Error(
22
- "\nAborted:".red + " found traces of a previous interrupted test/deploy.\n"
23
- + "Run " + "cob-cli cleanup".yellow + " to restore the repo to a clean state first.\n"
24
- );
25
- }
26
- }
27
-
28
- module.exports = { saveOperationState, loadOperationState, clearOperationState, checkNoInterruptedRun };
@@ -1,45 +0,0 @@
1
- const Listr = require('listr');
2
- const UpdaterRenderer = require('listr-update-renderer');
3
- const verboseRenderer = require('listr-verbose-renderer');
4
- const { copyFiles } = require("./common_syncFiles");
5
- const fs = require("fs");
6
- const tar = require('tar');
7
- const { format } = require('date-fns');
8
-
9
-
10
- function executeTasks(cmdEnv, args) {
11
- console.log("\nPackaging ...");
12
-
13
- return new Listr([
14
- {title: "Apply new enviroment specifics", task: () => cmdEnv.applyCurrentCommandEnvironmentChanges() },
15
- {title: "Create staging dir", task: () => fs.existsSync('.staging') || fs.mkdirSync('.staging') },
16
- {title: "Copy files to staging dir", task: () => copyFiles(cmdEnv, "localCopy", "staging")},
17
- {title: "Create package", task: async () => { const filename = await createPackage(cmdEnv, args); console.log("created " + filename) }},
18
- {title: "Sign package", task: () => console.log("lololo")},
19
- {title: "Delete staging dir", task: () => fs.rmSync('.staging', {recursive: true, force: true})},
20
- {title: "Undo new enviroment specifics", task: () => cmdEnv.unApplyCurrentCommandEnvironmentChanges() },
21
- ], {
22
- renderer: args.verbose ? verboseRenderer : UpdaterRenderer,
23
- collapse: false
24
- });
25
- }
26
- exports.executeTasks = executeTasks;
27
-
28
- const createPackage = async function(cmdEnv, args){
29
- const filename = `${cmdEnv.servername}-${cmdEnv.name}-${format(new Date(), 'yyyy-MM-dd_HH_mm')}.tar.gz`;
30
- const files = fs.readdirSync('.staging')
31
- if (args.verbose > 0){
32
- console.log("packaging " + files)
33
- }
34
-
35
- await tar.create({
36
- gzip: true,
37
- file: filename,
38
- cwd: '.staging',
39
- onWriteEntry(entry) {
40
- if (args.verbose > 2) console.log('adding', entry.path, entry.stat.mode.toString(8))
41
- }
42
- }, files)
43
-
44
- return filename;
45
- }
@@ -1,121 +0,0 @@
1
- require('colors');
2
- const Listr = require('listr');
3
- const UpdaterRenderer = require('listr-update-renderer');
4
- const VerboseRenderer = require('listr-verbose-renderer');
5
- const { getFilteredDefinitions } = require('./common_definitions.js')
6
- const axios = require("axios");
7
- const inquirer = require("inquirer")
8
-
9
- async function getUntaggedChanges(servername, defId) {
10
- const uri = `https://${servername}.cultofbits.com/recordm/recordm/definitions/${defId}/changes?tagged=false`
11
-
12
- const response = await axios.get(uri, {params: {tagged: false}});
13
-
14
- if(response.status % 200 > 100){
15
- throw new Error(`HTTP Error Response: ${response.status} ${response.statusText}`);
16
- }
17
-
18
- return ( response.data || []).filter(c => !c.tag)
19
- }
20
-
21
- async function tagDefinition(servername, defId, until) {
22
- const uri = `https://${servername}.cultofbits.com/recordm/recordm/definitions/${defId}/tag`
23
-
24
- const params = {}
25
- if(until) {
26
- params.until = until
27
- }
28
-
29
- const response = await axios.put(uri, "", {headers: {'Content-Type': 'application/json'}, params: params});
30
-
31
- if(response.status != 200){
32
- throw new Error(`HTTP Error Response: ${response.status} ${response.statusText}`);
33
- }
34
-
35
- return response.data
36
- }
37
-
38
- async function tagDefinitions(servername, customization, defs, args) {
39
- return new Listr([
40
- {
41
- title: `(${customization}) Definitions: `.bold + "searching for definitions matching queries",
42
- task: async ctx => ctx.defs = (await getFilteredDefinitions(servername, defs))
43
- .map(d => ({id: d.id, name: d.name}))
44
- },
45
- {
46
- title: `(${customization}) Definitions: `.bold + "enriching metadata",
47
- task: async ctx => {
48
- for (const def of ctx.defs){
49
- def.changes = await getUntaggedChanges(servername, def.id)
50
- if(args.verbose) console.log(`definition ${def.name}: ${def.changes.length} untagged changes`)
51
- }
52
- }
53
- },
54
- {
55
- title: `(${customization}) Definitions: `.bold + "tagging un-tagged changes",
56
- task: async ctx => {
57
- const subtasks = ctx.defs.map(d => ({
58
- title: "Tagging changes to " + d.name.bold,
59
- task: async (_, task) => {
60
- if (d.changes.length == 0) {
61
- task.skip("no untagged changes")
62
- return
63
- }
64
-
65
- if(args.all) {
66
- await tagDefinition(servername, d.id)
67
- task.output = 'Tagged by all'
68
- return
69
- }
70
-
71
- d.changes.forEach(c => console.log(JSON.stringify(c)))
72
-
73
- const answer = await inquirer.prompt([
74
- {
75
- type: 'rawlist',
76
- name: 'action',
77
- message: `Do you wish to tag the ${d.changes.length} changes? (^c to abort)`,
78
- choices: [
79
- 'Tag Changes',
80
- 'Choose Changes',
81
- 'Skip',
82
- ]
83
- }
84
- ])
85
- if (answer.action == 'Skip') {
86
- task.skip()
87
-
88
- } else if (answer.action == 'Tag Changes') {
89
- await tagDefinition(servername, d.id)
90
- task.output = 'Tagged'
91
-
92
- } else if (answer.action == 'Choose Changes') {
93
- const dates = d.changes.reduce((acc, cur) => {
94
- if(!acc.includes(cur.date)) acc.push(cur.date)
95
- return acc
96
- }, [])
97
- const answerDate = await inquirer.prompt([
98
- {
99
- type: 'rawlist',
100
- name: 'date',
101
- message: `Choose the oldest date to tag`,
102
- choices: dates
103
- }
104
- ])
105
- await tagDefinition(servername, d.id, answerDate.date)
106
- task.output = 'Tagged until ' + answerDate.date
107
- }
108
- }
109
- }))
110
- return new Listr(subtasks)
111
- }
112
- },
113
- ],{
114
- // we need to list changes and read user input, the VerboseRenderer is needed
115
- renderer: VerboseRenderer,
116
- collapse: false
117
- }).run()
118
- }
119
-
120
-
121
- exports.tagDefinitions = tagDefinitions
@@ -1,135 +0,0 @@
1
- require('colors');
2
- const Listr = require('listr');
3
- const UpdaterRenderer = require('listr-update-renderer');
4
- const VerboseRenderer = require('listr-verbose-renderer');
5
- const { getFilteredDefinitions } = require('./common_definitions.js')
6
- const axios = require("axios");
7
- const fs = require("fs/promises");
8
-
9
- async function getRefs(servername, def) {
10
- const uri = `https://${servername}.cultofbits.com/recordm/recordm/definitions/${def.id}`
11
- const response = await axios.get(uri);
12
-
13
- if(response.status != 200){
14
- throw new Error(`HTTP Error Response: ${response.status} ${response.statusText}`);
15
- }
16
-
17
- const fields = response.data.fieldDefinitions;
18
- return [...new Set(get$Refs(fields))];
19
- }
20
- function get$Refs(fields){
21
- let refs = [];
22
- for(f of fields){
23
- if(f.configuration.keys.Reference){
24
- refs.push(f.configuration.keys.Reference.args.definition);
25
- }
26
- if(f.fields) {
27
- const childRefs = get$Refs(f.fields);
28
- if(childRefs.length > 0) refs.push(...childRefs)
29
- }
30
- }
31
- return refs
32
- }
33
-
34
- async function exportDefinitionChanges(servername, def, dataPath) {
35
-
36
- const uri = `https://${servername}.cultofbits.com/recordm/recordm/definitions/${def.id}/changes`
37
- const response = await axios.get(uri);
38
-
39
- if(response.status == 204){
40
- // this is probably an error
41
- throw new Error(`Definition "${def.name}" [${def.id}] has no tagged Changes.`);
42
-
43
- } else if(response.status != 200){
44
- throw new Error(`HTTP Error Response: ${response.status} ${response.statusText}`);
45
- }
46
-
47
- // write every change on a single line
48
- const stringified = "[\n" + response.data.map(change => " " + JSON.stringify(change)).join(',\n') + "\n]\n";
49
-
50
- await fs.writeFile(dataPath, stringified, 'utf-8');
51
- }
52
-
53
- async function exportDefinitionIdx(defs, dataPath) {
54
- await fs.writeFile(dataPath, defs.map(d => d.name).join('\n'), 'utf-8')
55
- }
56
-
57
- async function getViewsForDef(servername, definition, dataPath) {
58
- const definitionId = definition.id
59
- const uri = `https://${servername}.cultofbits.com/recordm/user/settings/${definition.views}/definitions-${definitionId}/views?`
60
-
61
- const response = await axios.get(uri);
62
-
63
- if(response.status != 200){
64
- throw new Error(`HTTP Error Response: ${response.status} ${response.statusText}`);
65
- }
66
-
67
- let userViews = response.data.filter(v => v.isShared)
68
-
69
- if(response.data.length == 0)
70
- return
71
-
72
- userViews = response.data.map(v => {
73
- v.value = JSON.stringify( JSON.parse(v.value).filter(f => f.visible == true) )
74
- return v
75
- })
76
-
77
- const jsonLines = userViews.map(v => JSON.stringify({
78
- key: v.key,
79
- value: v.value,
80
- user: v.user,
81
- })) .join('\n');
82
-
83
- await fs.writeFile(dataPath, jsonLines)
84
- }
85
-
86
- function getDefinitionsFromServer(servername, defs, definitionsPath, viewsPath, customization, args) {
87
-
88
- return new Listr(
89
- [
90
- {
91
- title: `(${customization}) Definitions: `.bold + "searching for definitions matching queries",
92
- task: async ctx => ctx.defs = await getFilteredDefinitions(servername, defs)
93
- },
94
- {
95
- title: `(${customization}) Definitions: `.bold + "enriching metadata",
96
- task: async ctx => {
97
- const definitions = await Promise.all(ctx.defs
98
- .map(async d => ({id: d.id, name: d.name, views: d.views, refs: await getRefs(servername, d)}))
99
- )
100
-
101
- // we'll sort by refs, Defs that reference others must come after them
102
- definitions.sort((a, b) => {
103
- if (a.refs.includes(b.name)){
104
- return 1;
105
- }
106
-
107
- if(b.refs.includes(a.name)){
108
- return -1;
109
- }
110
-
111
- return a.refs.length - b.refs.length;
112
- })
113
-
114
- ctx.defs = definitions
115
- }
116
- },
117
- {
118
- title: `(${customization}) Definitions: `.bold + "exporting changes",
119
- task: async ctx => {
120
- for( d of ctx.defs ){ await exportDefinitionChanges(servername, d, definitionsPath + `${d.name}.json`)}
121
- await exportDefinitionIdx(ctx.defs, definitionsPath + "_index")
122
- }
123
- },
124
- {
125
- title: `(${customization}) Definitions: `.bold + "exporting views",
126
- task: async ctx => { for (d of ctx.defs.filter(d => d.views )){ await getViewsForDef(servername, d, viewsPath + `${d.name}.jsonl`)} }
127
- },
128
- ],{
129
- renderer: args.verbose ? VerboseRenderer : UpdaterRenderer,
130
- collapse: false
131
- })
132
- }
133
-
134
-
135
- exports.getDefinitionsFromServer = getDefinitionsFromServer
@@ -1,50 +0,0 @@
1
- require('colors');
2
- const Listr = require('listr');
3
- const UpdaterRenderer = require('listr-update-renderer');
4
- const VerboseRenderer = require('listr-verbose-renderer');
5
- const axios = require("axios");
6
- const fs = require("fs/promises");
7
-
8
- async function domainsFromServer(servername, domainsFilter, exportPath, customization, args) {
9
- await new Listr(
10
- [
11
- { title: `(${customization}) Domains: `.bold + "searching for domains matching the queries" ,
12
- task: async ctx => ctx.domains = await getDomains(servername, domainsFilter, exportPath) },
13
- { title: `(${customization}) Domains: `.bold + "exporting domains " ,
14
- task: ctx => ctx.domains.forEach( d => exportDomain(d, exportPath)) }
15
- ],{
16
- renderer: args.verbose ? VerboseRenderer : UpdaterRenderer,
17
- collapse: false
18
- })
19
- .run()
20
- }
21
-
22
- function match(query, domain) {
23
- // simple matching for now
24
- return (domain.name && domain.name.includes(query)) ||
25
- (domain.description && domain.description.includes(query) )
26
- }
27
-
28
- async function getDomains(servername, filters, exportPath) {
29
-
30
- const uri = `https://${servername}.cultofbits.com/recordm/recordm/domains`
31
- const response = await axios.get( uri );
32
-
33
- if(response.status != 200){
34
- throw new Error(`HTTP Error Response: ${response.status} ${response.statusText}`);
35
- }
36
-
37
- const matchesAny = (domain) => filters.filter(q => match(q, domain)).length > 0;
38
-
39
- return response.data.filter( matchesAny )
40
- }
41
-
42
- async function exportDomain(domain, rootPath) {
43
- const d = {
44
- name: domain.name,
45
- definitions: domain.definitions.map(d => d.name).sort()
46
- }
47
- await fs.writeFile(rootPath + domain.name + ".json", JSON.stringify(d, null, 2) )
48
- }
49
-
50
- exports.getDomainsFromServer = domainsFromServer