@cyberismo/data-handler 0.0.5 → 0.0.7
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 +1 -0
- package/dist/card-metadata-updater.d.ts +1 -0
- package/dist/card-metadata-updater.js +7 -2
- package/dist/card-metadata-updater.js.map +1 -1
- package/dist/command-handler.d.ts +6 -1
- package/dist/command-handler.js +16 -15
- package/dist/command-handler.js.map +1 -1
- package/dist/command-manager.d.ts +15 -4
- package/dist/command-manager.js +41 -9
- package/dist/command-manager.js.map +1 -1
- package/dist/commands/calculate.d.ts +4 -10
- package/dist/commands/calculate.js +67 -78
- package/dist/commands/calculate.js.map +1 -1
- package/dist/commands/export.js +3 -3
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/import.d.ts +3 -8
- package/dist/commands/import.js +10 -14
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/index.d.ts +1 -2
- package/dist/commands/index.js +1 -2
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/remove.js +1 -1
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/show.d.ts +6 -3
- package/dist/commands/show.js +8 -5
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/validate.js +6 -4
- package/dist/commands/validate.js.map +1 -1
- package/dist/containers/project/project-content-watcher.d.ts +28 -0
- package/dist/containers/project/project-content-watcher.js +54 -0
- package/dist/containers/project/project-content-watcher.js.map +1 -0
- package/dist/containers/project/project-paths.js +1 -1
- package/dist/containers/project/project-paths.js.map +1 -1
- package/dist/containers/project.d.ts +9 -2
- package/dist/containers/project.js +49 -1
- package/dist/containers/project.js.map +1 -1
- package/dist/containers/template.d.ts +1 -0
- package/dist/containers/template.js +7 -2
- package/dist/containers/template.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/macros.d.ts +2 -1
- package/dist/interfaces/project-interfaces.d.ts +5 -0
- package/dist/interfaces/project-interfaces.js.map +1 -1
- package/dist/interfaces/resource-interfaces.d.ts +14 -22
- package/dist/interfaces/resource-interfaces.js +10 -9
- package/dist/interfaces/resource-interfaces.js.map +1 -1
- package/dist/macros/graph/index.d.ts +1 -1
- package/dist/macros/graph/index.js +12 -12
- package/dist/macros/graph/index.js.map +1 -1
- package/dist/macros/index.d.ts +24 -3
- package/dist/macros/index.js +11 -4
- package/dist/macros/index.js.map +1 -1
- package/dist/macros/report/index.d.ts +13 -10
- package/dist/macros/report/index.js +26 -38
- package/dist/macros/report/index.js.map +1 -1
- package/dist/module-manager.d.ts +16 -7
- package/dist/module-manager.js +142 -112
- package/dist/module-manager.js.map +1 -1
- package/dist/project-settings.js +6 -0
- package/dist/project-settings.js.map +1 -1
- package/dist/resources/array-handler.js +6 -1
- package/dist/resources/array-handler.js.map +1 -1
- package/dist/resources/card-type-resource.d.ts +13 -9
- package/dist/resources/card-type-resource.js +47 -23
- package/dist/resources/card-type-resource.js.map +1 -1
- package/dist/resources/create-defaults.d.ts +10 -9
- package/dist/resources/create-defaults.js +15 -12
- package/dist/resources/create-defaults.js.map +1 -1
- package/dist/resources/field-type-resource.d.ts +0 -1
- package/dist/resources/field-type-resource.js +2 -10
- package/dist/resources/field-type-resource.js.map +1 -1
- package/dist/resources/file-resource.d.ts +7 -7
- package/dist/resources/file-resource.js +32 -7
- package/dist/resources/file-resource.js.map +1 -1
- package/dist/resources/folder-resource.d.ts +10 -9
- package/dist/resources/folder-resource.js +10 -9
- package/dist/resources/folder-resource.js.map +1 -1
- package/dist/resources/report-resource.d.ts +5 -6
- package/dist/resources/report-resource.js +16 -7
- package/dist/resources/report-resource.js.map +1 -1
- package/dist/resources/template-resource.d.ts +5 -6
- package/dist/resources/template-resource.js +7 -6
- package/dist/resources/template-resource.js.map +1 -1
- package/dist/resources/workflow-resource.d.ts +15 -8
- package/dist/resources/workflow-resource.js +124 -8
- package/dist/resources/workflow-resource.js.map +1 -1
- package/dist/types/queries.d.ts +11 -10
- package/dist/types/queries.js +10 -9
- package/dist/types/queries.js.map +1 -1
- package/dist/utils/clingo-fact-builder.d.ts +1 -0
- package/dist/utils/clingo-fact-builder.js +8 -3
- package/dist/utils/clingo-fact-builder.js.map +1 -1
- package/dist/utils/clingo-facts.js +15 -11
- package/dist/utils/clingo-facts.js.map +1 -1
- package/dist/utils/constants.d.ts +18 -12
- package/dist/utils/constants.js +18 -11
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/log-utils.d.ts +15 -2
- package/dist/utils/log-utils.js +20 -37
- package/dist/utils/log-utils.js.map +1 -1
- package/dist/utils/report.d.ts +27 -0
- package/dist/utils/report.js +60 -0
- package/dist/utils/report.js.map +1 -0
- package/dist/utils/resource-utils.js +3 -0
- package/dist/utils/resource-utils.js.map +1 -1
- package/dist/utils/sanitize-svg.d.ts +3 -4
- package/dist/utils/sanitize-svg.js +4 -7
- package/dist/utils/sanitize-svg.js.map +1 -1
- package/dist/utils/validate.js +2 -1
- package/dist/utils/validate.js.map +1 -1
- package/package.json +9 -10
- package/src/card-metadata-updater.ts +7 -2
- package/src/command-handler.ts +23 -13
- package/src/command-manager.ts +54 -13
- package/src/commands/calculate.ts +90 -106
- package/src/commands/export.ts +3 -2
- package/src/commands/import.ts +16 -16
- package/src/commands/index.ts +0 -2
- package/src/commands/remove.ts +1 -1
- package/src/commands/show.ts +13 -5
- package/src/commands/validate.ts +14 -9
- package/src/containers/project/project-content-watcher.ts +65 -0
- package/src/containers/project/project-paths.ts +1 -1
- package/src/containers/project.ts +60 -1
- package/src/containers/template.ts +7 -2
- package/src/index.ts +2 -0
- package/src/interfaces/macros.ts +2 -1
- package/src/interfaces/project-interfaces.ts +8 -0
- package/src/interfaces/resource-interfaces.ts +15 -22
- package/src/macros/graph/index.ts +17 -12
- package/src/macros/index.ts +32 -6
- package/src/macros/report/index.ts +32 -42
- package/src/module-manager.ts +183 -139
- package/src/project-settings.ts +7 -0
- package/src/resources/array-handler.ts +7 -2
- package/src/resources/card-type-resource.ts +61 -46
- package/src/resources/create-defaults.ts +15 -12
- package/src/resources/field-type-resource.ts +2 -17
- package/src/resources/file-resource.ts +46 -8
- package/src/resources/folder-resource.ts +11 -10
- package/src/resources/report-resource.ts +19 -7
- package/src/resources/template-resource.ts +7 -6
- package/src/resources/workflow-resource.ts +155 -8
- package/src/types/queries.ts +11 -10
- package/src/utils/clingo-fact-builder.ts +8 -3
- package/src/utils/clingo-facts.ts +18 -12
- package/src/utils/constants.ts +20 -12
- package/src/utils/log-utils.ts +24 -45
- package/src/utils/report.ts +86 -0
- package/src/utils/resource-utils.ts +4 -0
- package/src/utils/sanitize-svg.ts +4 -9
- package/src/utils/validate.ts +3 -2
- package/dist/commands/export-site.d.ts +0 -45
- package/dist/commands/export-site.js +0 -301
- package/dist/commands/export-site.js.map +0 -1
- package/src/commands/export-site.ts +0 -356
|
@@ -1,35 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
Cyberismo
|
|
3
|
+
Copyright © Cyberismo Ltd and contributors 2024
|
|
4
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
5
|
+
the terms of the GNU Affero General Public License version 3 as published by
|
|
6
|
+
the Free Software Foundation. This program is distributed in the hope that it
|
|
7
|
+
will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
8
|
+
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
9
|
+
See the GNU Affero General Public License for more details.
|
|
10
|
+
You should have received a copy of the GNU Affero General Public
|
|
11
|
+
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
11
12
|
*/
|
|
12
13
|
|
|
13
|
-
import {
|
|
14
|
+
import { validateMacroContent } from '../index.js';
|
|
14
15
|
import type { MacroOptions } from '../index.js';
|
|
16
|
+
|
|
15
17
|
import type { MacroGenerationContext } from '../../interfaces/macros.js';
|
|
16
18
|
import macroMetadata from './metadata.js';
|
|
17
|
-
import {
|
|
18
|
-
import { Calculate } from '../../commands/index.js';
|
|
19
|
-
import Handlebars from 'handlebars';
|
|
19
|
+
import type { Calculate } from '../../commands/index.js';
|
|
20
20
|
import BaseMacro from '../base-macro.js';
|
|
21
21
|
import { validateJson } from '../../utils/validate.js';
|
|
22
22
|
import type TaskQueue from '../task-queue.js';
|
|
23
23
|
import { ReportResource } from '../../resources/report-resource.js';
|
|
24
24
|
import { resourceName } from '../../utils/resource-utils.js';
|
|
25
|
+
import { generateReportContent } from '../../utils/report.js';
|
|
25
26
|
|
|
26
27
|
export interface ReportOptions extends MacroOptions {
|
|
27
28
|
name: string;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
class ReportMacro extends BaseMacro {
|
|
31
|
-
constructor(
|
|
32
|
-
|
|
32
|
+
constructor(
|
|
33
|
+
tasks: TaskQueue,
|
|
34
|
+
private readonly calculate: Calculate,
|
|
35
|
+
) {
|
|
36
|
+
super(macroMetadata, tasks);
|
|
33
37
|
}
|
|
34
38
|
handleValidate = (input: unknown) => {
|
|
35
39
|
this.validate(input);
|
|
@@ -41,11 +45,13 @@ class ReportMacro extends BaseMacro {
|
|
|
41
45
|
|
|
42
46
|
handleInject = async (context: MacroGenerationContext, data: unknown) => {
|
|
43
47
|
const options = this.validate(data);
|
|
44
|
-
const
|
|
45
|
-
|
|
48
|
+
const resource = new ReportResource(
|
|
49
|
+
context.project,
|
|
50
|
+
resourceName(options.name),
|
|
51
|
+
);
|
|
46
52
|
const report = await resource.show();
|
|
47
53
|
|
|
48
|
-
if (!report) throw new Error(`Report ${options} does not exist`);
|
|
54
|
+
if (!report) throw new Error(`Report ${options.name} does not exist`);
|
|
49
55
|
|
|
50
56
|
if (report.schema) {
|
|
51
57
|
validateJson(options, {
|
|
@@ -53,30 +59,14 @@ class ReportMacro extends BaseMacro {
|
|
|
53
59
|
});
|
|
54
60
|
}
|
|
55
61
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
strict: true,
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
const calculate = new Calculate(project);
|
|
68
|
-
const result = await calculate.runLogicProgram({
|
|
69
|
-
query: template(handlebarsContext),
|
|
70
|
-
});
|
|
71
|
-
if (result.error) {
|
|
72
|
-
throw new Error(result.error);
|
|
73
|
-
}
|
|
74
|
-
// register empty macros so that other macros aren't touched yet
|
|
75
|
-
registerEmptyMacros(handlebars);
|
|
76
|
-
|
|
77
|
-
return handlebars.compile(report.contentTemplate)({
|
|
78
|
-
...handlebarsContext,
|
|
79
|
-
...result,
|
|
62
|
+
return generateReportContent({
|
|
63
|
+
calculate: this.calculate,
|
|
64
|
+
contentTemplate: report.contentTemplate,
|
|
65
|
+
queryTemplate: report.queryTemplate,
|
|
66
|
+
options: {
|
|
67
|
+
cardKey: context.cardKey,
|
|
68
|
+
...options,
|
|
69
|
+
},
|
|
80
70
|
});
|
|
81
71
|
};
|
|
82
72
|
|
package/src/module-manager.ts
CHANGED
|
@@ -11,16 +11,14 @@
|
|
|
11
11
|
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import fs from 'node:fs';
|
|
15
14
|
import { join } from 'node:path';
|
|
16
15
|
import { mkdir, readdir, rm } from 'node:fs/promises';
|
|
17
16
|
|
|
18
|
-
import
|
|
19
|
-
import http from 'isomorphic-git/http/node/index.js';
|
|
17
|
+
import { simpleGit, type SimpleGit } from 'simple-git';
|
|
20
18
|
|
|
21
19
|
import { copyDir, deleteDir, pathExists } from './utils/file-utils.js';
|
|
22
|
-
import type { Import } from './commands/index.js';
|
|
23
20
|
import type {
|
|
21
|
+
Credentials,
|
|
24
22
|
ModuleSetting,
|
|
25
23
|
ModuleSettingOptions,
|
|
26
24
|
} from './interfaces/project-interfaces.js';
|
|
@@ -33,6 +31,8 @@ import { Validate } from './commands/index.js';
|
|
|
33
31
|
const FILE_PROTOCOL = 'file:';
|
|
34
32
|
// todo: add support for git's default branch.
|
|
35
33
|
const MAIN_BRANCH = 'main';
|
|
34
|
+
// timeout in milliseconds for git client (no stdout / stderr activity)
|
|
35
|
+
const DEFAULT_TIMEOUT = 10000;
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Class that handles module updates and imports.
|
|
@@ -40,10 +40,7 @@ const MAIN_BRANCH = 'main';
|
|
|
40
40
|
export class ModuleManager {
|
|
41
41
|
private modules: ModuleSetting[] = [];
|
|
42
42
|
private tempModulesDir: string = '';
|
|
43
|
-
constructor(
|
|
44
|
-
private project: Project,
|
|
45
|
-
private importCmd: Import,
|
|
46
|
-
) {
|
|
43
|
+
constructor(private project: Project) {
|
|
47
44
|
this.tempModulesDir = join(this.project.paths.tempFolder, 'modules');
|
|
48
45
|
}
|
|
49
46
|
|
|
@@ -56,87 +53,82 @@ export class ModuleManager {
|
|
|
56
53
|
await this.project.collectModuleResources();
|
|
57
54
|
}
|
|
58
55
|
|
|
59
|
-
// Handles a branch of a repository.
|
|
60
|
-
private async branch(module: ModuleSetting) {
|
|
61
|
-
if (module.branch === MAIN_BRANCH || module.branch === '' || !module.branch)
|
|
62
|
-
return;
|
|
63
|
-
|
|
64
|
-
await git.checkout({
|
|
65
|
-
fs,
|
|
66
|
-
dir: join(this.tempModulesDir, module.name),
|
|
67
|
-
ref: module.branch,
|
|
68
|
-
});
|
|
69
|
-
console.error(
|
|
70
|
-
`... Switched to '${module.branch}' branch for module '${module.name}'`,
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
56
|
// Handles cloning of a repository.
|
|
75
57
|
private async clone(
|
|
76
58
|
module: ModuleSetting,
|
|
77
59
|
verbose: boolean = true,
|
|
60
|
+
credentials?: Credentials,
|
|
78
61
|
): Promise<string> {
|
|
79
62
|
if (!module.name || module.name === '') {
|
|
80
63
|
module.name = this.repositoryName(module.location);
|
|
81
64
|
}
|
|
82
65
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
66
|
+
const destinationPath = join(this.tempModulesDir, module.name);
|
|
67
|
+
|
|
68
|
+
let remote = module.location;
|
|
69
|
+
if (module.private) {
|
|
70
|
+
if (credentials && credentials?.username && credentials?.token) {
|
|
71
|
+
if (verbose) {
|
|
72
|
+
console.log(
|
|
73
|
+
`... Using credentials '${credentials?.username}' for cloning '${module.name}'`,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const repoUrl = new URL(module.location);
|
|
78
|
+
const user = credentials?.username;
|
|
79
|
+
const pass = credentials?.token;
|
|
80
|
+
const host = repoUrl.host;
|
|
81
|
+
const path = repoUrl.pathname;
|
|
82
|
+
remote = `https://${user}:${pass}@${host}${path}`;
|
|
83
|
+
} catch {
|
|
84
|
+
throw new Error(`Invalid repository URL: ${module.location}`);
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
if (verbose) {
|
|
88
|
+
console.log(`... Not using credentials for cloning '${module.name}'`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
88
91
|
}
|
|
89
92
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
try {
|
|
94
|
+
await mkdir(this.tempModulesDir, { recursive: true });
|
|
95
|
+
const cloneOptions = this.setCloneOptions(module);
|
|
96
|
+
await rm(destinationPath, { recursive: true, force: true });
|
|
97
|
+
|
|
98
|
+
const git: SimpleGit = simpleGit({
|
|
99
|
+
timeout: {
|
|
100
|
+
block: DEFAULT_TIMEOUT,
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
await git
|
|
105
|
+
// turn off git prompts
|
|
106
|
+
.env({ GIT_TERMINAL_PROMPT: 0, GCM_INTERACTIVE: 'never' })
|
|
107
|
+
.clone(remote, destinationPath, cloneOptions);
|
|
108
|
+
|
|
95
109
|
if (verbose) {
|
|
96
|
-
console.log(
|
|
97
|
-
`... Using credentials '${process.env.CYBERISMO_GIT_USER}' for cloning '${module.name}'`,
|
|
98
|
-
);
|
|
110
|
+
console.log(`... Cloned '${module.name}' to a temporary folder`);
|
|
99
111
|
}
|
|
100
|
-
|
|
101
|
-
|
|
112
|
+
} catch (error) {
|
|
113
|
+
console.error(error);
|
|
114
|
+
if (error instanceof Error)
|
|
115
|
+
throw new Error(
|
|
116
|
+
`Failed to clone module '${module.name}': ${error.message}`,
|
|
117
|
+
);
|
|
102
118
|
}
|
|
103
|
-
await git.clone({
|
|
104
|
-
fs,
|
|
105
|
-
http,
|
|
106
|
-
dir: join(this.tempModulesDir, module.name),
|
|
107
|
-
url: repoUrl.toString(),
|
|
108
|
-
depth: 1,
|
|
109
|
-
onAuth: () => {
|
|
110
|
-
// Turn credentials 'off' when they are not available
|
|
111
|
-
if (
|
|
112
|
-
!process.env.CYBERISMO_GIT_USER ||
|
|
113
|
-
!process.env.CYBERISMO_GIT_TOKEN
|
|
114
|
-
) {
|
|
115
|
-
return undefined;
|
|
116
|
-
}
|
|
117
|
-
// Turn credentials 'off' for public repos
|
|
118
|
-
if (!module.private) {
|
|
119
|
-
return undefined;
|
|
120
|
-
}
|
|
121
|
-
return {
|
|
122
|
-
username: process.env.CYBERISMO_GIT_USER,
|
|
123
|
-
password: process.env.CYBERISMO_GIT_TOKEN,
|
|
124
|
-
};
|
|
125
|
-
},
|
|
126
|
-
});
|
|
127
119
|
|
|
128
|
-
if (verbose) {
|
|
129
|
-
console.log(`... Cloned '${module.name}' to a temporary folder`);
|
|
130
|
-
}
|
|
131
120
|
return module.name;
|
|
132
121
|
}
|
|
133
122
|
|
|
134
123
|
// Collects all module prefixes from module hierarchy into 'this.modules'.
|
|
135
124
|
// Note that collected result can contain duplicates.
|
|
136
|
-
private async collectModulePrefixes(
|
|
125
|
+
private async collectModulePrefixes(
|
|
126
|
+
modules: ModuleSetting[],
|
|
127
|
+
credentials?: Credentials,
|
|
128
|
+
) {
|
|
137
129
|
if (modules) {
|
|
138
130
|
for (const module of modules) {
|
|
139
|
-
await this.doCollectModulePrefix(module);
|
|
131
|
+
await this.doCollectModulePrefix(module, credentials);
|
|
140
132
|
}
|
|
141
133
|
}
|
|
142
134
|
}
|
|
@@ -153,21 +145,24 @@ export class ModuleManager {
|
|
|
153
145
|
|
|
154
146
|
// Collects one module's dependency prefixes to 'this.modules'.
|
|
155
147
|
// Note that there can be duplicate entries.
|
|
156
|
-
private async doCollectModulePrefix(
|
|
148
|
+
private async doCollectModulePrefix(
|
|
149
|
+
module: ModuleSetting,
|
|
150
|
+
credentials?: Credentials,
|
|
151
|
+
) {
|
|
157
152
|
let moduleRoot = '';
|
|
158
153
|
if (this.isFileModule(module)) {
|
|
159
154
|
const urlStart = FILE_PROTOCOL.length;
|
|
160
155
|
// Remove 'file:' from location
|
|
161
156
|
moduleRoot = module.location.substring(urlStart, module.location.length);
|
|
162
157
|
} else {
|
|
163
|
-
await this.clone(module, false);
|
|
158
|
+
await this.clone(module, false, credentials);
|
|
164
159
|
moduleRoot = join(this.tempModulesDir, module.name);
|
|
165
160
|
}
|
|
166
161
|
|
|
167
162
|
this.modules.push(module);
|
|
168
163
|
|
|
169
164
|
const configuration = await this.configuration(moduleRoot);
|
|
170
|
-
await this.collectModulePrefixes(configuration.modules);
|
|
165
|
+
await this.collectModulePrefixes(configuration.modules, credentials);
|
|
171
166
|
}
|
|
172
167
|
|
|
173
168
|
// Updates one module that is read from local file system.
|
|
@@ -180,21 +175,20 @@ export class ModuleManager {
|
|
|
180
175
|
// Updates one module that is received from Git.
|
|
181
176
|
private async handleGitModule(module: ModuleSetting) {
|
|
182
177
|
await this.clone(module);
|
|
183
|
-
await this.branch(module);
|
|
184
178
|
await this.remove(module);
|
|
185
179
|
await this.importFromTemp(module);
|
|
186
180
|
}
|
|
187
181
|
|
|
188
182
|
// Updates one module.
|
|
189
183
|
private async handleModule(module: ModuleSetting) {
|
|
190
|
-
return this.
|
|
191
|
-
? this.
|
|
192
|
-
: this.
|
|
184
|
+
return this.isGitModule(module)
|
|
185
|
+
? this.handleGitModule(module)
|
|
186
|
+
: this.handleFileModule(module);
|
|
193
187
|
}
|
|
194
188
|
|
|
195
189
|
// Handles importing a module from module settings 'location'
|
|
196
190
|
private async importFromFolder(module: ModuleSetting) {
|
|
197
|
-
await this.
|
|
191
|
+
await this.importFileModule(module.location);
|
|
198
192
|
console.log(
|
|
199
193
|
`... Imported module '${module.name}' to '${this.project.configuration.name}'`,
|
|
200
194
|
);
|
|
@@ -202,9 +196,7 @@ export class ModuleManager {
|
|
|
202
196
|
|
|
203
197
|
// Handles importing a module from '.temp' folder
|
|
204
198
|
private async importFromTemp(module: ModuleSetting) {
|
|
205
|
-
await this.
|
|
206
|
-
join(this.tempModulesDir, module.name),
|
|
207
|
-
);
|
|
199
|
+
await this.importFileModule(join(this.tempModulesDir, module.name));
|
|
208
200
|
console.log(
|
|
209
201
|
`... Imported module '${module.name}' to '${this.project.configuration.name}'`,
|
|
210
202
|
);
|
|
@@ -216,14 +208,26 @@ export class ModuleManager {
|
|
|
216
208
|
return module.location.startsWith('file:');
|
|
217
209
|
}
|
|
218
210
|
|
|
211
|
+
// Returns true if module is imported from git.
|
|
212
|
+
private isGitModule(module: ModuleSetting): boolean {
|
|
213
|
+
if (!module.location) return false;
|
|
214
|
+
return module.location.startsWith('https:');
|
|
215
|
+
}
|
|
216
|
+
|
|
219
217
|
// Prepares '.temp/modules' for cloning
|
|
220
218
|
private async prepare() {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
await
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
219
|
+
try {
|
|
220
|
+
await mkdir(this.tempModulesDir, { recursive: true });
|
|
221
|
+
const files = await readdir(this.tempModulesDir);
|
|
222
|
+
for (const file of files) {
|
|
223
|
+
const filePath = join(this.tempModulesDir, file);
|
|
224
|
+
await rm(filePath, {
|
|
225
|
+
force: true,
|
|
226
|
+
recursive: true,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
} catch (error) {
|
|
230
|
+
throw new Error(`Failed to prepare temporary directory: ${error}`);
|
|
227
231
|
}
|
|
228
232
|
}
|
|
229
233
|
|
|
@@ -281,11 +285,14 @@ export class ModuleManager {
|
|
|
281
285
|
for (const module of modules) {
|
|
282
286
|
const existingModule = moduleMap.get(module.name);
|
|
283
287
|
if (existingModule) {
|
|
284
|
-
if (
|
|
288
|
+
if (
|
|
289
|
+
(existingModule.private && !module.private) ||
|
|
290
|
+
(!existingModule.private && module.private)
|
|
291
|
+
) {
|
|
285
292
|
throw new Error(
|
|
286
293
|
`Module conflict: '${module.name}' has different access:\n` +
|
|
287
|
-
` - ${existingModule.private
|
|
288
|
-
` - ${module.private
|
|
294
|
+
` - ${existingModule.private === true ? 'true' : 'false'}\n` +
|
|
295
|
+
` - ${module.private === true ? 'true' : 'false'}`,
|
|
289
296
|
);
|
|
290
297
|
}
|
|
291
298
|
if (existingModule.location !== module.location) {
|
|
@@ -319,6 +326,66 @@ export class ModuleManager {
|
|
|
319
326
|
return repoName;
|
|
320
327
|
}
|
|
321
328
|
|
|
329
|
+
// Sets cloning options.
|
|
330
|
+
private setCloneOptions(module: ModuleSetting) {
|
|
331
|
+
const cloneOptions = ['--depth', '1'];
|
|
332
|
+
if (
|
|
333
|
+
module.branch &&
|
|
334
|
+
module.branch !== '' &&
|
|
335
|
+
module.branch !== MAIN_BRANCH
|
|
336
|
+
) {
|
|
337
|
+
cloneOptions.push('--branch', module.branch);
|
|
338
|
+
}
|
|
339
|
+
return cloneOptions;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Updates modules in the project.
|
|
343
|
+
private async update(module?: ModuleSetting, credentials?: Credentials) {
|
|
344
|
+
// Prints dots every half second so that user knows that something is ongoing
|
|
345
|
+
function start() {
|
|
346
|
+
console.log('... Collecting unique modules. This takes a moment.');
|
|
347
|
+
return setInterval(() => process.stdout.write(`.`), 500);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Stops the above, and shows results
|
|
351
|
+
function finished(interval: NodeJS.Timeout, modules: string[]) {
|
|
352
|
+
clearInterval(interval);
|
|
353
|
+
console.log(`\n... Found modules: ${modules.join(', ')}`);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
await this.prepare();
|
|
357
|
+
|
|
358
|
+
let modules = module ? [module] : this.project.configuration.modules;
|
|
359
|
+
if (modules.length === 0) {
|
|
360
|
+
throw new Error(`No modules in the project!`);
|
|
361
|
+
}
|
|
362
|
+
modules = modules.filter((module) => this.isGitModule(module));
|
|
363
|
+
|
|
364
|
+
const dotInterval = start();
|
|
365
|
+
|
|
366
|
+
let uniqueModules: ModuleSetting[] = [];
|
|
367
|
+
try {
|
|
368
|
+
await this.collectModulePrefixes(modules, credentials);
|
|
369
|
+
|
|
370
|
+
uniqueModules = this.removeDuplicates(this.modules);
|
|
371
|
+
} finally {
|
|
372
|
+
finished(
|
|
373
|
+
dotInterval,
|
|
374
|
+
uniqueModules.map((item) => item.name),
|
|
375
|
+
);
|
|
376
|
+
|
|
377
|
+
// Update modules parallel.
|
|
378
|
+
const promises: Promise<void>[] = [];
|
|
379
|
+
uniqueModules.forEach((module) =>
|
|
380
|
+
promises.push(this.handleModule(module)),
|
|
381
|
+
);
|
|
382
|
+
await Promise.all(promises);
|
|
383
|
+
|
|
384
|
+
await deleteDir(this.tempModulesDir);
|
|
385
|
+
await this.project.collectModuleResources();
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
322
389
|
// Checks that module prefix is not in use in the project
|
|
323
390
|
private async validatePrefix(modulePrefix: string) {
|
|
324
391
|
// Do not allow modules with same prefixes.
|
|
@@ -370,16 +437,24 @@ export class ModuleManager {
|
|
|
370
437
|
* Imports module from gitUrl.
|
|
371
438
|
* @param source Git URL to import from.
|
|
372
439
|
* @param options Modules setting options.
|
|
440
|
+
* @param credentials Credentials for private repositories.
|
|
373
441
|
* @returns module prefix as defined in its CardsConfig.json
|
|
374
442
|
*/
|
|
375
|
-
public async importGitModule(
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
443
|
+
public async importGitModule(
|
|
444
|
+
source: string,
|
|
445
|
+
options?: ModuleSettingOptions,
|
|
446
|
+
credentials?: Credentials,
|
|
447
|
+
) {
|
|
448
|
+
const clonedName = await this.clone(
|
|
449
|
+
{
|
|
450
|
+
name: this.repositoryName(source),
|
|
451
|
+
location: source,
|
|
452
|
+
...options,
|
|
453
|
+
},
|
|
454
|
+
undefined,
|
|
455
|
+
credentials,
|
|
456
|
+
);
|
|
457
|
+
const clonePath = join(this.tempModulesDir, clonedName);
|
|
383
458
|
const modulePrefix = (await this.configuration(clonePath)).cardKeyPrefix;
|
|
384
459
|
await this.validatePrefix(modulePrefix);
|
|
385
460
|
|
|
@@ -393,51 +468,20 @@ export class ModuleManager {
|
|
|
393
468
|
}
|
|
394
469
|
|
|
395
470
|
/**
|
|
396
|
-
*
|
|
471
|
+
* Imports module from a local file path or a git URL.
|
|
472
|
+
* @param module Module to update. If not provided, updates all modules.
|
|
473
|
+
* @param credentials Optional credentials for private repositories.
|
|
474
|
+
* @returns Module prefix as defined in its CardsConfig.json
|
|
397
475
|
*/
|
|
398
|
-
public async
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
console.log('... Collecting unique modules. This takes a moment.');
|
|
402
|
-
return setInterval(() => process.stdout.write(`.`), 500);
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
// Stops the above, and shows results
|
|
406
|
-
function finished(interval: NodeJS.Timeout, modules: string[]) {
|
|
407
|
-
clearInterval(interval);
|
|
408
|
-
console.log(`\n... Found modules: ${modules.join(', ')}`);
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
await this.prepare();
|
|
412
|
-
|
|
413
|
-
const modules = this.project.configuration.modules;
|
|
414
|
-
if (modules.length === 0) {
|
|
415
|
-
throw new Error(`No modules in the project!`);
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
const dotInterval = start();
|
|
419
|
-
|
|
420
|
-
// Collect prefixes from project's dependency modules.
|
|
421
|
-
await this.collectModulePrefixes(modules);
|
|
422
|
-
|
|
423
|
-
let uniqueModules: ModuleSetting[] = [];
|
|
424
|
-
try {
|
|
425
|
-
uniqueModules = this.removeDuplicates(this.modules);
|
|
426
|
-
} finally {
|
|
427
|
-
finished(
|
|
428
|
-
dotInterval,
|
|
429
|
-
uniqueModules.map((item) => item.name),
|
|
430
|
-
);
|
|
431
|
-
|
|
432
|
-
// Update modules parallel.
|
|
433
|
-
const promises: Promise<void>[] = [];
|
|
434
|
-
uniqueModules.forEach((module) =>
|
|
435
|
-
promises.push(this.handleModule(module)),
|
|
436
|
-
);
|
|
437
|
-
await Promise.all(promises);
|
|
476
|
+
public async updateModule(module: ModuleSetting, credentials?: Credentials) {
|
|
477
|
+
return this.update(module, credentials);
|
|
478
|
+
}
|
|
438
479
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
480
|
+
/**
|
|
481
|
+
* Updates all imported modules.
|
|
482
|
+
* @param credentials Optional credentials for private modules.
|
|
483
|
+
*/
|
|
484
|
+
public async updateModules(credentials?: Credentials) {
|
|
485
|
+
return this.update(undefined, credentials);
|
|
442
486
|
}
|
|
443
487
|
}
|
package/src/project-settings.ts
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
|
|
14
14
|
import { writeJsonFile as atomicWrite } from 'write-json-file';
|
|
15
15
|
|
|
16
|
+
import { resolve } from 'path';
|
|
17
|
+
|
|
16
18
|
import type {
|
|
17
19
|
ModuleSetting,
|
|
18
20
|
ProjectSettings,
|
|
@@ -103,6 +105,11 @@ export class ProjectConfiguration implements ProjectSettings {
|
|
|
103
105
|
if (exists) {
|
|
104
106
|
throw new Error(`Module '${module.name}' already imported`);
|
|
105
107
|
}
|
|
108
|
+
// Ensure that module file location is absolute
|
|
109
|
+
if (module.location && module.location.startsWith('file:')) {
|
|
110
|
+
const filePath = module.location.substring(5, module.location.length);
|
|
111
|
+
module.location = `file:${resolve(filePath)}`;
|
|
112
|
+
}
|
|
106
113
|
this.modules.push(module);
|
|
107
114
|
return this.save();
|
|
108
115
|
}
|
|
@@ -83,15 +83,20 @@ export class ArrayHandler<T> {
|
|
|
83
83
|
if (targetIndex === -1) {
|
|
84
84
|
throw new Error(`Item '${JSON.stringify(target)}' not found`);
|
|
85
85
|
}
|
|
86
|
+
const actualTarget = array[targetIndex];
|
|
86
87
|
const parsedTo = this.tryParseJSON(to);
|
|
87
88
|
|
|
88
89
|
if (typeof to === 'string' && (to.startsWith('[') || to.startsWith('{'))) {
|
|
89
90
|
return parsedTo as T[];
|
|
90
91
|
}
|
|
91
92
|
|
|
92
|
-
|
|
93
|
-
deepCompare(item as object,
|
|
93
|
+
const updatedArray = array.map((item) =>
|
|
94
|
+
deepCompare(item as object, actualTarget as object) ? parsedTo : item,
|
|
94
95
|
);
|
|
96
|
+
if (deepCompare(updatedArray, array)) {
|
|
97
|
+
throw new Error('Cannot change value. Target was not found.');
|
|
98
|
+
}
|
|
99
|
+
return updatedArray;
|
|
95
100
|
}
|
|
96
101
|
|
|
97
102
|
private handleRank(operation: RankOperation<T>, array: T[]): T[] {
|