dataverse-utils 4.0.1 → 5.0.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/lib/assemblyDeploy.js +22 -29
- package/lib/auth.js +14 -22
- package/lib/cachePlugin.js +25 -35
- package/lib/dataverse.service.js +12 -18
- package/lib/deploy.js +20 -26
- package/lib/generate.js +23 -29
- package/lib/index.js +12 -17
- package/lib/logger.js +12 -18
- package/lib/models/customApi.js +12 -17
- package/lib/models/pluginAssembly.js +17 -25
- package/lib/models/pluginImage.js +8 -12
- package/lib/models/pluginPackage.js +20 -27
- package/lib/models/pluginStep.js +14 -18
- package/lib/models/pluginType.js +11 -16
- package/lib/models/webResource.js +17 -24
- package/lib/webResourceDeploy.js +12 -19
- package/package.json +11 -11
package/lib/assemblyDeploy.js
CHANGED
|
@@ -1,57 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const pluginAssembly_1 = require("./models/pluginAssembly");
|
|
10
|
-
const pluginPackage_1 = require("./models/pluginPackage");
|
|
11
|
-
const customApi_1 = require("./models/customApi");
|
|
12
|
-
const logger_1 = require("./logger");
|
|
13
|
-
async function assemblyDeploy(creds, apiConfig) {
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { deployAssembly } from './models/pluginAssembly.js';
|
|
4
|
+
import { deployPluginPackage } from './models/pluginPackage.js';
|
|
5
|
+
import { deployApi } from './models/customApi.js';
|
|
6
|
+
import { logger } from './logger.js';
|
|
7
|
+
export async function assemblyDeploy(creds, apiConfig) {
|
|
14
8
|
const currentPath = '.';
|
|
15
|
-
const configFile = await
|
|
9
|
+
const configFile = await fs.promises.readFile(path.resolve(currentPath, 'dataverse.config.json'), 'utf8');
|
|
16
10
|
if (configFile == null) {
|
|
17
|
-
|
|
11
|
+
logger.warn('unable to find dataverse.config.json file');
|
|
18
12
|
return;
|
|
19
13
|
}
|
|
20
14
|
const config = JSON.parse(configFile);
|
|
21
15
|
if (config.assembly) {
|
|
22
|
-
|
|
16
|
+
logger.info('deploy plugin package');
|
|
23
17
|
try {
|
|
24
|
-
await
|
|
18
|
+
await deployPluginPackage(config, apiConfig, creds.solution);
|
|
25
19
|
}
|
|
26
20
|
catch (error) {
|
|
27
|
-
|
|
21
|
+
logger.error(error.message);
|
|
28
22
|
return;
|
|
29
23
|
}
|
|
30
|
-
|
|
24
|
+
logger.done(`deployed plugin package ${config.prefix}_${config.name}\r\n`);
|
|
31
25
|
}
|
|
32
26
|
else {
|
|
33
|
-
|
|
27
|
+
logger.info(`deploy assembly to ${creds.server}`);
|
|
34
28
|
try {
|
|
35
|
-
await
|
|
29
|
+
await deployAssembly(config, apiConfig, creds.solution);
|
|
36
30
|
}
|
|
37
31
|
catch (error) {
|
|
38
|
-
|
|
32
|
+
logger.error(error.message);
|
|
39
33
|
return;
|
|
40
34
|
}
|
|
41
|
-
|
|
35
|
+
logger.done(`deployed assembly ${config.name}`);
|
|
42
36
|
}
|
|
43
37
|
if (config.customapis?.length > 0 && (config.pluginassemblyid || config.assembly?.pluginassemblyid)) {
|
|
44
|
-
|
|
38
|
+
logger.info('deploy custom api');
|
|
45
39
|
const assemblyId = config.pluginassemblyid ?? config.assembly.pluginassemblyid;
|
|
46
40
|
try {
|
|
47
|
-
const promises = config.customapis.map((a) =>
|
|
41
|
+
const promises = config.customapis.map((a) => deployApi(a, assemblyId, apiConfig, creds.solution));
|
|
48
42
|
await Promise.all(promises);
|
|
49
43
|
}
|
|
50
44
|
catch (error) {
|
|
51
|
-
|
|
45
|
+
logger.error(error.message);
|
|
52
46
|
}
|
|
53
|
-
|
|
47
|
+
logger.done('deployed custom api');
|
|
54
48
|
}
|
|
55
|
-
await
|
|
49
|
+
await fs.promises.writeFile(path.resolve(currentPath, 'dataverse.config.json'), JSON.stringify(config, null, 4), 'utf8');
|
|
56
50
|
}
|
|
57
|
-
exports.assemblyDeploy = assemblyDeploy;
|
package/lib/auth.js
CHANGED
|
@@ -1,44 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getAccessToken = exports.onTokenFailure = void 0;
|
|
7
|
-
const prompts_1 = __importDefault(require("prompts"));
|
|
8
|
-
const cachePlugin_1 = require("./cachePlugin");
|
|
9
|
-
const msal_node_1 = require("@azure/msal-node");
|
|
10
|
-
const logger_1 = require("./logger");
|
|
1
|
+
import prompts from 'prompts';
|
|
2
|
+
import { cacheExists, cachePlugin, deleteCache } from './cachePlugin.js';
|
|
3
|
+
import { PublicClientApplication } from '@azure/msal-node';
|
|
4
|
+
import { logger } from './logger.js';
|
|
11
5
|
const clientId = '51f81489-12ee-4a9e-aaae-a2591f45987d';
|
|
12
|
-
const onTokenFailure = async (url, error) => {
|
|
6
|
+
export const onTokenFailure = async (url, error) => {
|
|
13
7
|
if (error) {
|
|
14
|
-
|
|
8
|
+
logger.error(`failed to acquire access token: ${error}`);
|
|
15
9
|
}
|
|
16
10
|
else {
|
|
17
|
-
|
|
11
|
+
logger.error('failed to acquire access token');
|
|
18
12
|
}
|
|
19
|
-
if (
|
|
20
|
-
const { deleteToken } = await (
|
|
13
|
+
if (cacheExists(url)) {
|
|
14
|
+
const { deleteToken } = await prompts({
|
|
21
15
|
type: 'confirm',
|
|
22
16
|
name: 'deleteToken',
|
|
23
17
|
message: `delete current token cache for ${url}?`
|
|
24
18
|
});
|
|
25
19
|
if (deleteToken) {
|
|
26
|
-
|
|
20
|
+
deleteCache(url);
|
|
27
21
|
}
|
|
28
22
|
}
|
|
29
23
|
};
|
|
30
|
-
|
|
31
|
-
const getAccessToken = async (authEndpoint, url) => {
|
|
24
|
+
export const getAccessToken = async (authEndpoint, url) => {
|
|
32
25
|
const config = {
|
|
33
26
|
auth: {
|
|
34
27
|
clientId: clientId,
|
|
35
28
|
authority: authEndpoint
|
|
36
29
|
},
|
|
37
30
|
cache: {
|
|
38
|
-
cachePlugin:
|
|
31
|
+
cachePlugin: cachePlugin(url)
|
|
39
32
|
}
|
|
40
33
|
};
|
|
41
|
-
const pca = new
|
|
34
|
+
const pca = new PublicClientApplication(config);
|
|
42
35
|
const cache = pca.getTokenCache();
|
|
43
36
|
const accounts = await cache?.getAllAccounts().catch(ex => {
|
|
44
37
|
throw new Error(ex.message);
|
|
@@ -64,7 +57,7 @@ const getAccessToken = async (authEndpoint, url) => {
|
|
|
64
57
|
try {
|
|
65
58
|
const token = await pca.acquireTokenByDeviceCode({
|
|
66
59
|
scopes: [`${url}/.default`],
|
|
67
|
-
deviceCodeCallback: (response) =>
|
|
60
|
+
deviceCodeCallback: (response) => logger.info(response.message)
|
|
68
61
|
});
|
|
69
62
|
return token;
|
|
70
63
|
}
|
|
@@ -72,4 +65,3 @@ const getAccessToken = async (authEndpoint, url) => {
|
|
|
72
65
|
throw new Error(ex.message);
|
|
73
66
|
}
|
|
74
67
|
};
|
|
75
|
-
exports.getAccessToken = getAccessToken;
|
package/lib/cachePlugin.js
CHANGED
|
@@ -1,55 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.cachePlugin = exports.deleteCache = exports.cacheExists = exports.getCachePath = void 0;
|
|
7
|
-
const os_1 = __importDefault(require("os"));
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const fs_1 = __importDefault(require("fs"));
|
|
10
|
-
const cryptr_1 = __importDefault(require("cryptr"));
|
|
1
|
+
import os from 'os';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import Cryptr from 'cryptr';
|
|
11
5
|
const encrypt = (text) => {
|
|
12
|
-
const user =
|
|
13
|
-
const cryptr = new
|
|
6
|
+
const user = os.userInfo().username;
|
|
7
|
+
const cryptr = new Cryptr(user);
|
|
14
8
|
const encrypted = cryptr.encrypt(text);
|
|
15
9
|
return encrypted;
|
|
16
10
|
};
|
|
17
11
|
const decrypt = (text) => {
|
|
18
|
-
const user =
|
|
19
|
-
const cryptr = new
|
|
12
|
+
const user = os.userInfo().username;
|
|
13
|
+
const cryptr = new Cryptr(user);
|
|
20
14
|
const decrypted = cryptr.decrypt(text);
|
|
21
15
|
return decrypted;
|
|
22
16
|
};
|
|
23
|
-
const getCachePath = (url) => {
|
|
17
|
+
export const getCachePath = (url) => {
|
|
24
18
|
const org = new URL(url).hostname.split('.')[0];
|
|
25
|
-
if (!
|
|
26
|
-
|
|
19
|
+
if (!fs.existsSync(path.join(os.homedir(), './.dataverse-utils/'))) {
|
|
20
|
+
fs.mkdirSync(path.join(os.homedir(), './.dataverse-utils/'));
|
|
27
21
|
}
|
|
28
|
-
return
|
|
22
|
+
return path.join(os.homedir(), `./.dataverse-utils/${org}.json`);
|
|
29
23
|
};
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
return fs_1.default.existsSync(cacheLocation);
|
|
24
|
+
export const cacheExists = (url) => {
|
|
25
|
+
const cacheLocation = getCachePath(url);
|
|
26
|
+
return fs.existsSync(cacheLocation);
|
|
34
27
|
};
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
fs_1.default.unlinkSync(cacheLocation);
|
|
28
|
+
export const deleteCache = (url) => {
|
|
29
|
+
const cacheLocation = getCachePath(url);
|
|
30
|
+
if (fs.existsSync(cacheLocation)) {
|
|
31
|
+
fs.unlinkSync(cacheLocation);
|
|
40
32
|
return true;
|
|
41
33
|
}
|
|
42
34
|
else {
|
|
43
35
|
return false;
|
|
44
36
|
}
|
|
45
37
|
};
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
const cacheLocation = (0, exports.getCachePath)(url);
|
|
38
|
+
export const cachePlugin = (url) => {
|
|
39
|
+
const cacheLocation = getCachePath(url);
|
|
49
40
|
const beforeCacheAccess = (tokenCacheContext) => {
|
|
50
41
|
return new Promise((resolve, reject) => {
|
|
51
|
-
if (
|
|
52
|
-
|
|
42
|
+
if (fs.existsSync(cacheLocation)) {
|
|
43
|
+
fs.readFile(cacheLocation, 'utf-8', (err, data) => {
|
|
53
44
|
if (err) {
|
|
54
45
|
reject();
|
|
55
46
|
}
|
|
@@ -68,7 +59,7 @@ const cachePlugin = (url) => {
|
|
|
68
59
|
else {
|
|
69
60
|
try {
|
|
70
61
|
const encrypted = encrypt(tokenCacheContext.tokenCache.serialize());
|
|
71
|
-
|
|
62
|
+
fs.writeFile(cacheLocation, encrypted, (err) => {
|
|
72
63
|
if (err) {
|
|
73
64
|
reject();
|
|
74
65
|
}
|
|
@@ -87,7 +78,7 @@ const cachePlugin = (url) => {
|
|
|
87
78
|
return new Promise((resolve, reject) => {
|
|
88
79
|
if (tokenCacheContext.cacheHasChanged) {
|
|
89
80
|
const encrypted = encrypt(tokenCacheContext.tokenCache.serialize());
|
|
90
|
-
|
|
81
|
+
fs.writeFile(cacheLocation, encrypted, (err) => {
|
|
91
82
|
if (err) {
|
|
92
83
|
reject(err);
|
|
93
84
|
}
|
|
@@ -104,4 +95,3 @@ const cachePlugin = (url) => {
|
|
|
104
95
|
afterCacheAccess
|
|
105
96
|
};
|
|
106
97
|
};
|
|
107
|
-
exports.cachePlugin = cachePlugin;
|
package/lib/dataverse.service.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const node_1 = require("dataverse-webapi/lib/node");
|
|
5
|
-
const logger_1 = require("./logger");
|
|
6
|
-
var ComponentType;
|
|
1
|
+
import { retrieveMultiple, unboundAction } from 'dataverse-webapi/lib/node';
|
|
2
|
+
import { logger } from './logger.js';
|
|
3
|
+
export var ComponentType;
|
|
7
4
|
(function (ComponentType) {
|
|
8
5
|
ComponentType[ComponentType["WebResource"] = 61] = "WebResource";
|
|
9
6
|
ComponentType[ComponentType["PluginType"] = 90] = "PluginType";
|
|
@@ -11,8 +8,8 @@ var ComponentType;
|
|
|
11
8
|
ComponentType[ComponentType["SDKMessageProcessingStep"] = 92] = "SDKMessageProcessingStep";
|
|
12
9
|
ComponentType[ComponentType["SDKMessageProcessingStepImage"] = 93] = "SDKMessageProcessingStepImage";
|
|
13
10
|
ComponentType[ComponentType["PluginPackage"] = 10865] = "PluginPackage";
|
|
14
|
-
})(ComponentType
|
|
15
|
-
async function addToSolution(id, solution, type, apiConfig) {
|
|
11
|
+
})(ComponentType || (ComponentType = {}));
|
|
12
|
+
export async function addToSolution(id, solution, type, apiConfig) {
|
|
16
13
|
const data = {
|
|
17
14
|
ComponentId: id,
|
|
18
15
|
ComponentType: type,
|
|
@@ -20,23 +17,21 @@ async function addToSolution(id, solution, type, apiConfig) {
|
|
|
20
17
|
AddRequiredComponents: false,
|
|
21
18
|
IncludedComponentSettingsValues: null
|
|
22
19
|
};
|
|
23
|
-
|
|
24
|
-
await
|
|
20
|
+
logger.info(`add component ${id} to solution ${solution}`);
|
|
21
|
+
await unboundAction(apiConfig, 'AddSolutionComponent', data);
|
|
25
22
|
}
|
|
26
|
-
|
|
27
|
-
async function publish(publishXml, apiConfig) {
|
|
23
|
+
export async function publish(publishXml, apiConfig) {
|
|
28
24
|
const data = {
|
|
29
25
|
ParameterXml: `<importexportxml><webresources>${publishXml}</webresources></importexportxml>`
|
|
30
26
|
};
|
|
31
|
-
await
|
|
27
|
+
await unboundAction(apiConfig, 'PublishXml', data);
|
|
32
28
|
}
|
|
33
|
-
|
|
34
|
-
async function getTableMetadata(table, apiConfig) {
|
|
29
|
+
export async function getTableMetadata(table, apiConfig) {
|
|
35
30
|
const options = [
|
|
36
31
|
'?$select=DisplayName,LogicalName,EntitySetName,SchemaName',
|
|
37
32
|
'&$expand=Attributes($select=LogicalName,SchemaName)'
|
|
38
33
|
].join('');
|
|
39
|
-
const metadata = await
|
|
34
|
+
const metadata = await retrieveMultiple(apiConfig, `EntityDefinitions(LogicalName='${table}')`, options);
|
|
40
35
|
if (metadata == null) {
|
|
41
36
|
throw Error(`Table ${table} not found in metadata cache`);
|
|
42
37
|
}
|
|
@@ -44,7 +39,7 @@ async function getTableMetadata(table, apiConfig) {
|
|
|
44
39
|
'?$select=attributevalue,value,attributename',
|
|
45
40
|
`&$filter=objecttypecode eq '${table}'`
|
|
46
41
|
].join('');
|
|
47
|
-
const choiceMetadata = await
|
|
42
|
+
const choiceMetadata = await retrieveMultiple(apiConfig, 'stringmaps', choiceOptions);
|
|
48
43
|
const tableMetadata = {
|
|
49
44
|
logicalName: metadata.LogicalName,
|
|
50
45
|
schemaName: metadata.SchemaName,
|
|
@@ -68,4 +63,3 @@ async function getTableMetadata(table, apiConfig) {
|
|
|
68
63
|
});
|
|
69
64
|
return tableMetadata;
|
|
70
65
|
}
|
|
71
|
-
exports.getTableMetadata = getTableMetadata;
|
package/lib/deploy.js
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const assemblyDeploy_1 = require("./assemblyDeploy");
|
|
11
|
-
const webResourceDeploy_1 = require("./webResourceDeploy");
|
|
12
|
-
const node_1 = require("dataverse-webapi/lib/node");
|
|
13
|
-
const auth_1 = require("./auth");
|
|
14
|
-
async function deploy(type, files) {
|
|
1
|
+
import prompts from 'prompts';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { logger } from './logger.js';
|
|
5
|
+
import { assemblyDeploy } from './assemblyDeploy.js';
|
|
6
|
+
import { webResourceDeploy } from './webResourceDeploy.js';
|
|
7
|
+
import { WebApiConfig } from 'dataverse-webapi/lib/node';
|
|
8
|
+
import { getAccessToken, onTokenFailure } from './auth.js';
|
|
9
|
+
export default async function deploy(type, files) {
|
|
15
10
|
if (!type || (type !== 'webresource' && type !== 'assembly' && type !== 'pcf')) {
|
|
16
11
|
const invalid = type !== undefined && type !== 'webresource' && type !== 'assembly' && type !== 'pcf';
|
|
17
12
|
const invalidMessage = invalid ? `${type} is not a valid project type. ` : '';
|
|
18
|
-
const { typePrompt } = await (
|
|
13
|
+
const { typePrompt } = await prompts({
|
|
19
14
|
type: 'select',
|
|
20
15
|
name: 'typePrompt',
|
|
21
16
|
message: `${invalidMessage}select project type to deploy`,
|
|
@@ -28,14 +23,14 @@ async function deploy(type, files) {
|
|
|
28
23
|
type = typePrompt;
|
|
29
24
|
}
|
|
30
25
|
const currentPath = '.';
|
|
31
|
-
const credsFile = await
|
|
26
|
+
const credsFile = await fs.promises.readFile(path.resolve(currentPath, 'dataverse.config.json'), 'utf8');
|
|
32
27
|
if (credsFile == null) {
|
|
33
|
-
|
|
28
|
+
logger.warn('unable to find dataverse.config.json file');
|
|
34
29
|
return;
|
|
35
30
|
}
|
|
36
31
|
const creds = JSON.parse(credsFile).connection;
|
|
37
32
|
if (!creds.authEndpoint) {
|
|
38
|
-
|
|
33
|
+
logger.error(('authEndpoint not found in dataverse.config.json. if you recently updated the package, please update the config file and replace tenant with authEndpoint with full authorization URL.'));
|
|
39
34
|
return;
|
|
40
35
|
}
|
|
41
36
|
let token = null;
|
|
@@ -45,30 +40,29 @@ async function deploy(type, files) {
|
|
|
45
40
|
}
|
|
46
41
|
else {
|
|
47
42
|
try {
|
|
48
|
-
token = await
|
|
43
|
+
token = await getAccessToken(creds.authEndpoint, creds.server);
|
|
49
44
|
}
|
|
50
45
|
catch (error) {
|
|
51
|
-
|
|
46
|
+
onTokenFailure(creds.server, error.message);
|
|
52
47
|
return;
|
|
53
48
|
}
|
|
54
49
|
if (token == null || token.accessToken == null) {
|
|
55
|
-
|
|
50
|
+
onTokenFailure(creds.server);
|
|
56
51
|
return;
|
|
57
52
|
}
|
|
58
53
|
}
|
|
59
|
-
const apiConfig = new
|
|
54
|
+
const apiConfig = new WebApiConfig('8.2', token.accessToken, creds.server);
|
|
60
55
|
switch (type) {
|
|
61
56
|
case 'webresource':
|
|
62
|
-
await
|
|
57
|
+
await webResourceDeploy(creds, apiConfig, files);
|
|
63
58
|
break;
|
|
64
59
|
case 'assembly':
|
|
65
|
-
await
|
|
60
|
+
await assemblyDeploy(creds, apiConfig);
|
|
66
61
|
break;
|
|
67
62
|
case 'pcf':
|
|
68
|
-
|
|
63
|
+
logger.error('PCF deploy coming soon');
|
|
69
64
|
break;
|
|
70
65
|
default:
|
|
71
66
|
break;
|
|
72
67
|
}
|
|
73
68
|
}
|
|
74
|
-
exports.default = deploy;
|
package/lib/generate.js
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const logger_1 = require("./logger");
|
|
10
|
-
const dataverse_service_1 = require("./dataverse.service");
|
|
11
|
-
const node_1 = require("dataverse-webapi/lib/node");
|
|
12
|
-
const auth_1 = require("./auth");
|
|
13
|
-
async function generate(table) {
|
|
1
|
+
import prompts from 'prompts';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { logger } from './logger.js';
|
|
5
|
+
import { getTableMetadata } from './dataverse.service.js';
|
|
6
|
+
import { WebApiConfig } from 'dataverse-webapi/lib/node';
|
|
7
|
+
import { getAccessToken, onTokenFailure } from './auth.js';
|
|
8
|
+
export default async function generate(table) {
|
|
14
9
|
while (!table) {
|
|
15
|
-
const { tablePrompt } = await (
|
|
10
|
+
const { tablePrompt } = await prompts({
|
|
16
11
|
type: 'text',
|
|
17
12
|
name: 'tablePrompt',
|
|
18
13
|
message: `enter table to generate`
|
|
@@ -20,36 +15,36 @@ async function generate(table) {
|
|
|
20
15
|
table = tablePrompt;
|
|
21
16
|
}
|
|
22
17
|
const currentPath = '.';
|
|
23
|
-
const credsFile = await
|
|
18
|
+
const credsFile = await fs.promises.readFile(path.resolve(currentPath, 'dataverse.config.json'), 'utf8');
|
|
24
19
|
if (credsFile == null) {
|
|
25
|
-
|
|
20
|
+
logger.warn('unable to find dataverse.config.json file');
|
|
26
21
|
return;
|
|
27
22
|
}
|
|
28
23
|
const creds = JSON.parse(credsFile).connection;
|
|
29
24
|
if (!creds.authEndpoint) {
|
|
30
|
-
|
|
25
|
+
logger.error(('authEndpoint not found in dataverse.config.json. if you recently updated the package, please update the config file and replace tenant with authEndpoint with full authorization URL.'));
|
|
31
26
|
return;
|
|
32
27
|
}
|
|
33
28
|
let token = null;
|
|
34
29
|
try {
|
|
35
|
-
token = await
|
|
30
|
+
token = await getAccessToken(creds.authEndpoint, creds.server);
|
|
36
31
|
}
|
|
37
32
|
catch (error) {
|
|
38
|
-
|
|
33
|
+
onTokenFailure(creds.server, error.message);
|
|
39
34
|
return;
|
|
40
35
|
}
|
|
41
36
|
if (token == null || token.accessToken == null) {
|
|
42
|
-
|
|
37
|
+
onTokenFailure(creds.server);
|
|
43
38
|
return;
|
|
44
39
|
}
|
|
45
|
-
const apiConfig = new
|
|
40
|
+
const apiConfig = new WebApiConfig('8.2', token.accessToken, creds.server);
|
|
46
41
|
let metadata = {};
|
|
47
|
-
|
|
42
|
+
logger.info('Retrieve table metadata');
|
|
48
43
|
try {
|
|
49
|
-
metadata = await
|
|
44
|
+
metadata = await getTableMetadata(table, apiConfig);
|
|
50
45
|
}
|
|
51
46
|
catch (error) {
|
|
52
|
-
|
|
47
|
+
logger.error(error.message);
|
|
53
48
|
return;
|
|
54
49
|
}
|
|
55
50
|
// Build code file from metadata
|
|
@@ -94,10 +89,9 @@ async function generate(table) {
|
|
|
94
89
|
'\r\n',
|
|
95
90
|
`export default new ${metadata.schemaName}();`
|
|
96
91
|
].join('');
|
|
97
|
-
if (!
|
|
98
|
-
|
|
92
|
+
if (!fs.existsSync(path.resolve(currentPath, 'src', 'scripts', 'models'))) {
|
|
93
|
+
fs.mkdirSync(path.resolve(currentPath, 'src', 'scripts', 'models'));
|
|
99
94
|
}
|
|
100
|
-
|
|
101
|
-
|
|
95
|
+
fs.writeFileSync(path.resolve(currentPath, 'src', 'scripts', 'models', `${metadata.schemaName}.ts`), codeFile);
|
|
96
|
+
logger.done(`Table metadata output to models/${metadata.schemaName}.ts`);
|
|
102
97
|
}
|
|
103
|
-
exports.default = generate;
|
package/lib/index.js
CHANGED
|
@@ -1,44 +1,39 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
const commander_1 = require("commander");
|
|
8
|
-
const deploy_1 = __importDefault(require("./deploy"));
|
|
9
|
-
const generate_1 = __importDefault(require("./generate"));
|
|
2
|
+
import { program } from 'commander';
|
|
3
|
+
import deploy from './deploy.js';
|
|
4
|
+
import generate from './generate.js';
|
|
10
5
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
11
6
|
const packageJson = require('../package.json');
|
|
12
|
-
|
|
7
|
+
program
|
|
13
8
|
.version(packageJson.version)
|
|
14
9
|
.usage('<command> [options]');
|
|
15
10
|
// Deploy command
|
|
16
|
-
|
|
11
|
+
program
|
|
17
12
|
.command('deploy')
|
|
18
13
|
.description('Deploy file(s) to dataverse (webresource, assembly, pcf)')
|
|
19
14
|
.argument('[type]', 'Type of project to deploy')
|
|
20
15
|
.argument('[files]', 'Comma separate list of files to deploy')
|
|
21
16
|
.action((type, files) => {
|
|
22
|
-
(
|
|
17
|
+
deploy(type, files);
|
|
23
18
|
});
|
|
24
19
|
// Generate command
|
|
25
|
-
|
|
20
|
+
program
|
|
26
21
|
.command('generate')
|
|
27
22
|
.description('Generate early-bound TypeScript file for specified table')
|
|
28
23
|
.argument('[table]', 'Table to generate')
|
|
29
24
|
.action((table) => {
|
|
30
|
-
(
|
|
25
|
+
generate(table);
|
|
31
26
|
});
|
|
32
27
|
// Show help on unknown command
|
|
33
|
-
|
|
28
|
+
program
|
|
34
29
|
.arguments('<command>')
|
|
35
30
|
.action((cmd) => {
|
|
36
|
-
|
|
31
|
+
program.outputHelp();
|
|
37
32
|
console.log();
|
|
38
33
|
console.log(`Unknown command ${cmd}.`);
|
|
39
34
|
console.log();
|
|
40
35
|
});
|
|
41
|
-
|
|
36
|
+
program.parse(process.argv);
|
|
42
37
|
if (!process.argv.slice(2).length) {
|
|
43
|
-
|
|
38
|
+
program.outputHelp();
|
|
44
39
|
}
|
package/lib/logger.js
CHANGED
|
@@ -1,37 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.logger = exports.icons = void 0;
|
|
7
|
-
const kleur_1 = __importDefault(require("kleur"));
|
|
8
|
-
const figures_1 = __importDefault(require("figures"));
|
|
1
|
+
import kleur from 'kleur';
|
|
2
|
+
import figures from 'figures';
|
|
9
3
|
const isTest = process.env.JEST_WORKER_ID !== undefined;
|
|
10
|
-
|
|
11
|
-
done:
|
|
12
|
-
info:
|
|
13
|
-
error:
|
|
14
|
-
warn:
|
|
4
|
+
export const icons = {
|
|
5
|
+
done: kleur.green(figures.tick),
|
|
6
|
+
info: kleur.cyan(figures.pointer),
|
|
7
|
+
error: kleur.red(figures.cross),
|
|
8
|
+
warn: kleur.yellow(figures.warning)
|
|
15
9
|
};
|
|
16
|
-
|
|
10
|
+
export const logger = {
|
|
17
11
|
info(...args) {
|
|
18
12
|
if (!isTest) {
|
|
19
|
-
console.info(
|
|
13
|
+
console.info(icons.info, ...args);
|
|
20
14
|
}
|
|
21
15
|
},
|
|
22
16
|
warn(...args) {
|
|
23
17
|
if (!isTest) {
|
|
24
|
-
console.warn(
|
|
18
|
+
console.warn(icons.warn, ...args);
|
|
25
19
|
}
|
|
26
20
|
},
|
|
27
21
|
error(...args) {
|
|
28
22
|
if (!isTest) {
|
|
29
|
-
console.error(
|
|
23
|
+
console.error(icons.error, ...args);
|
|
30
24
|
}
|
|
31
25
|
},
|
|
32
26
|
done(...args) {
|
|
33
27
|
if (!isTest) {
|
|
34
|
-
console.info(
|
|
28
|
+
console.info(icons.done, ...args);
|
|
35
29
|
}
|
|
36
30
|
},
|
|
37
31
|
};
|
package/lib/models/customApi.js
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const pluginType_1 = require("./pluginType");
|
|
6
|
-
const logger_1 = require("../logger");
|
|
7
|
-
async function deployApi(config, assemblyId, apiConfig, solution) {
|
|
1
|
+
import { retrieveMultiple, createWithReturnData, update } from 'dataverse-webapi/lib/node';
|
|
2
|
+
import { retrieveType } from './pluginType.js';
|
|
3
|
+
import { logger } from '../logger.js';
|
|
4
|
+
export async function deployApi(config, assemblyId, apiConfig, solution) {
|
|
8
5
|
const api = structuredClone(config);
|
|
9
6
|
if (!config.customapiid) {
|
|
10
7
|
config.customapiid = await retrieveApi(api.name, apiConfig);
|
|
11
8
|
}
|
|
12
9
|
if (config.plugintype && !config.plugintypeid) {
|
|
13
|
-
config.plugintypeid = await
|
|
10
|
+
config.plugintypeid = await retrieveType(config.plugintype, assemblyId, apiConfig);
|
|
14
11
|
if (config.plugintypeid === '') {
|
|
15
|
-
|
|
12
|
+
logger.error(`unable to find plugin type ${api.plugintype}`);
|
|
16
13
|
return;
|
|
17
14
|
}
|
|
18
15
|
}
|
|
@@ -37,27 +34,25 @@ async function deployApi(config, assemblyId, apiConfig, solution) {
|
|
|
37
34
|
}
|
|
38
35
|
}
|
|
39
36
|
}
|
|
40
|
-
|
|
41
|
-
async function retrieveApi(name, apiConfig) {
|
|
37
|
+
export async function retrieveApi(name, apiConfig) {
|
|
42
38
|
const options = `$select=customapiid&$filter=name eq '${name}'`;
|
|
43
|
-
const result = await
|
|
39
|
+
const result = await retrieveMultiple(apiConfig, 'customapis', options);
|
|
44
40
|
return result.value.length > 0 ? result.value[0].customapiid : '';
|
|
45
41
|
}
|
|
46
|
-
exports.retrieveApi = retrieveApi;
|
|
47
42
|
async function createApi(api, apiConfig, solution) {
|
|
48
|
-
|
|
43
|
+
logger.info(`create custom api ${api.name}`);
|
|
49
44
|
const options = {};
|
|
50
45
|
if (solution) {
|
|
51
46
|
options.customHeaders = { 'MSCRM.SolutionUniqueName': solution };
|
|
52
47
|
}
|
|
53
|
-
const result = await
|
|
48
|
+
const result = await createWithReturnData(apiConfig, 'customapis', api, '$select=customapiid', options);
|
|
54
49
|
if (result?.error) {
|
|
55
50
|
throw new Error(result.error.message);
|
|
56
51
|
}
|
|
57
52
|
return result.customapiid;
|
|
58
53
|
}
|
|
59
54
|
async function updateApi(id, api, apiConfig) {
|
|
60
|
-
|
|
55
|
+
logger.info(`update custom api ${api.name}`);
|
|
61
56
|
const record = {
|
|
62
57
|
displayname: api.displayname,
|
|
63
58
|
description: api.description,
|
|
@@ -70,7 +65,7 @@ async function updateApi(id, api, apiConfig) {
|
|
|
70
65
|
else {
|
|
71
66
|
record['PluginTypeId@odata.bind'] = null;
|
|
72
67
|
}
|
|
73
|
-
const result = await
|
|
68
|
+
const result = await update(apiConfig, 'customapis', id, record);
|
|
74
69
|
if (result?.error) {
|
|
75
70
|
throw new Error(result.error.message);
|
|
76
71
|
}
|
|
@@ -1,22 +1,16 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.retrieveAssembly = exports.deployAssembly = void 0;
|
|
7
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
async function deployAssembly(config, apiConfig, solution) {
|
|
14
|
-
const files = await
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { glob } from 'glob';
|
|
4
|
+
import { retrieveMultiple, createWithReturnData, update } from 'dataverse-webapi/lib/node';
|
|
5
|
+
import { deployType } from './pluginType.js';
|
|
6
|
+
import { logger } from '../logger.js';
|
|
7
|
+
export async function deployAssembly(config, apiConfig, solution) {
|
|
8
|
+
const files = await glob(`bin/Debug/**/${config.name}.dll`);
|
|
15
9
|
if (files.length === 0) {
|
|
16
|
-
|
|
10
|
+
logger.warn(`assembly ${config.name}.dll not found`);
|
|
17
11
|
return;
|
|
18
12
|
}
|
|
19
|
-
const content = (await
|
|
13
|
+
const content = (await fs.promises.readFile(files[0])).toString('base64');
|
|
20
14
|
if (!config.pluginassemblyid) {
|
|
21
15
|
config.pluginassemblyid = await retrieveAssembly(config.name, apiConfig);
|
|
22
16
|
}
|
|
@@ -38,24 +32,22 @@ async function deployAssembly(config, apiConfig, solution) {
|
|
|
38
32
|
}
|
|
39
33
|
if (config.types != null) {
|
|
40
34
|
try {
|
|
41
|
-
const promises = config.types.map((type) =>
|
|
35
|
+
const promises = config.types.map((type) => deployType(type, config.pluginassemblyid, apiConfig, solution));
|
|
42
36
|
await Promise.all(promises);
|
|
43
37
|
}
|
|
44
38
|
catch (error) {
|
|
45
|
-
|
|
39
|
+
logger.error(error.message);
|
|
46
40
|
return;
|
|
47
41
|
}
|
|
48
42
|
}
|
|
49
43
|
}
|
|
50
|
-
|
|
51
|
-
async function retrieveAssembly(name, apiConfig) {
|
|
44
|
+
export async function retrieveAssembly(name, apiConfig) {
|
|
52
45
|
const options = `$select=pluginassemblyid&$filter=name eq '${name}'`;
|
|
53
|
-
const result = await
|
|
46
|
+
const result = await retrieveMultiple(apiConfig, 'pluginassemblies', options);
|
|
54
47
|
return result.value.length > 0 ? result.value[0].pluginassemblyid : '';
|
|
55
48
|
}
|
|
56
|
-
exports.retrieveAssembly = retrieveAssembly;
|
|
57
49
|
async function createAssembly(config, content, apiConfig, solution) {
|
|
58
|
-
|
|
50
|
+
logger.info(`create assembly ${config.name}`);
|
|
59
51
|
const assembly = {
|
|
60
52
|
name: config.name,
|
|
61
53
|
content: content,
|
|
@@ -69,19 +61,19 @@ async function createAssembly(config, content, apiConfig, solution) {
|
|
|
69
61
|
if (solution) {
|
|
70
62
|
options.customHeaders = { 'MSCRM.SolutionUniqueName': solution };
|
|
71
63
|
}
|
|
72
|
-
const result = await
|
|
64
|
+
const result = await createWithReturnData(apiConfig, 'pluginassemblies', assembly, '$select=pluginassemblyid', options);
|
|
73
65
|
if (result?.error) {
|
|
74
66
|
throw new Error(result.error.message);
|
|
75
67
|
}
|
|
76
68
|
return result.pluginassemblyid;
|
|
77
69
|
}
|
|
78
70
|
async function updateAssembly(config, content, apiConfig) {
|
|
79
|
-
|
|
71
|
+
logger.info(`update assembly ${config.name}`);
|
|
80
72
|
const assembly = {
|
|
81
73
|
content: content,
|
|
82
74
|
version: config.version
|
|
83
75
|
};
|
|
84
|
-
const result = await
|
|
76
|
+
const result = await update(apiConfig, 'pluginassemblies', config.pluginassemblyid, assembly);
|
|
85
77
|
if (result?.error) {
|
|
86
78
|
throw new Error(result.error.message);
|
|
87
79
|
}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const logger_1 = require("../logger");
|
|
5
|
-
const node_1 = require("dataverse-webapi/lib/node");
|
|
6
|
-
async function deployImage(stepId, stepName, config, message, apiConfig) {
|
|
1
|
+
import { logger } from '../logger.js';
|
|
2
|
+
import { retrieveMultiple, createWithReturnData, update } from 'dataverse-webapi/lib/node';
|
|
3
|
+
export async function deployImage(stepId, stepName, config, message, apiConfig) {
|
|
7
4
|
const image = structuredClone(config);
|
|
8
5
|
image['sdkmessageprocessingstepid@odata.bind'] = `/sdkmessageprocessingsteps(${stepId})`;
|
|
9
6
|
switch (message) {
|
|
@@ -43,25 +40,24 @@ async function deployImage(stepId, stepName, config, message, apiConfig) {
|
|
|
43
40
|
}
|
|
44
41
|
}
|
|
45
42
|
}
|
|
46
|
-
exports.deployImage = deployImage;
|
|
47
43
|
async function retrieveImage(stepId, image, apiConfig) {
|
|
48
44
|
const options = `$select=sdkmessageprocessingstepimageid&$filter=name eq '${image.name}' and _sdkmessageprocessingstepid_value eq ${stepId}`;
|
|
49
|
-
const result = await
|
|
45
|
+
const result = await retrieveMultiple(apiConfig, 'sdkmessageprocessingstepimages', options);
|
|
50
46
|
return result.value.length > 0 ? result.value[0].sdkmessageprocessingstepimageid : '';
|
|
51
47
|
}
|
|
52
48
|
async function createImage(image, stepName, apiConfig) {
|
|
53
|
-
|
|
54
|
-
const result = await
|
|
49
|
+
logger.info(`create plugin image ${image.name} for step ${stepName}`);
|
|
50
|
+
const result = await createWithReturnData(apiConfig, 'sdkmessageprocessingstepimages', image, '$select=sdkmessageprocessingstepimageid');
|
|
55
51
|
if (result?.error) {
|
|
56
52
|
throw new Error(result.error.message);
|
|
57
53
|
}
|
|
58
54
|
return result.sdkmessageprocessingstepimageid;
|
|
59
55
|
}
|
|
60
56
|
async function updateImage(id, image, stepName, apiConfig) {
|
|
61
|
-
|
|
57
|
+
logger.info(`update plugin image ${image.name} for step ${stepName}`);
|
|
62
58
|
const entity = { ...image };
|
|
63
59
|
delete entity.sdkmessageprocessingstepimageid;
|
|
64
|
-
const result = await
|
|
60
|
+
const result = await update(apiConfig, 'sdkmessageprocessingstepimages', id, entity);
|
|
65
61
|
if (result?.error) {
|
|
66
62
|
throw new Error(result.error.message);
|
|
67
63
|
}
|
|
@@ -1,23 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const pluginAssembly_1 = require("./pluginAssembly");
|
|
11
|
-
const logger_1 = require("../logger");
|
|
12
|
-
const pluginType_1 = require("./pluginType");
|
|
13
|
-
const pluginStep_1 = require("./pluginStep");
|
|
14
|
-
async function deployPluginPackage(config, apiConfig, solution) {
|
|
15
|
-
const files = await (0, glob_1.glob)(`**/${config.name}.*.nupkg`);
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import { glob } from 'glob';
|
|
3
|
+
import { createWithReturnData, retrieveMultiple, update } from 'dataverse-webapi/lib/node';
|
|
4
|
+
import { retrieveAssembly } from './pluginAssembly.js';
|
|
5
|
+
import { logger } from '../logger.js';
|
|
6
|
+
import { retrieveType } from './pluginType.js';
|
|
7
|
+
import { deployStep } from './pluginStep.js';
|
|
8
|
+
export async function deployPluginPackage(config, apiConfig, solution) {
|
|
9
|
+
const files = await glob(`**/${config.name}.*.nupkg`);
|
|
16
10
|
if (files.length === 0) {
|
|
17
|
-
|
|
11
|
+
logger.warn(`package ${config.name}.nupkg not found`);
|
|
18
12
|
return;
|
|
19
13
|
}
|
|
20
|
-
const content = (await
|
|
14
|
+
const content = (await fs.promises.readFile(files[0])).toString('base64');
|
|
21
15
|
if (!config.pluginpackageid) {
|
|
22
16
|
config.pluginpackageid = await retrievePackage(config.prefix, config.name, apiConfig);
|
|
23
17
|
}
|
|
@@ -40,31 +34,30 @@ async function deployPluginPackage(config, apiConfig, solution) {
|
|
|
40
34
|
if (config.assembly != null) {
|
|
41
35
|
try {
|
|
42
36
|
if (!config.assembly.pluginassemblyid) {
|
|
43
|
-
config.assembly.pluginassemblyid = await
|
|
37
|
+
config.assembly.pluginassemblyid = await retrieveAssembly(config.assembly.name, apiConfig);
|
|
44
38
|
}
|
|
45
39
|
const promises = config.assembly.types?.map(async (t) => {
|
|
46
40
|
if (!t.plugintypeid && config.assembly?.pluginassemblyid) {
|
|
47
|
-
t.plugintypeid = await
|
|
41
|
+
t.plugintypeid = await retrieveType(t.typename, config.assembly.pluginassemblyid, apiConfig);
|
|
48
42
|
}
|
|
49
|
-
const stepPromises = t.steps?.map((s) =>
|
|
43
|
+
const stepPromises = t.steps?.map((s) => deployStep(s, t.plugintypeid, apiConfig, solution)) ?? [];
|
|
50
44
|
await Promise.all(stepPromises);
|
|
51
45
|
}) ?? [];
|
|
52
46
|
await Promise.all(promises);
|
|
53
47
|
}
|
|
54
48
|
catch (error) {
|
|
55
|
-
|
|
49
|
+
logger.error(error.message);
|
|
56
50
|
return;
|
|
57
51
|
}
|
|
58
52
|
}
|
|
59
53
|
}
|
|
60
|
-
exports.deployPluginPackage = deployPluginPackage;
|
|
61
54
|
async function retrievePackage(prefix, name, apiConfig) {
|
|
62
55
|
const options = `$select=pluginpackageid&$filter=contains(name, '${prefix}_${name}')`;
|
|
63
|
-
const result = await
|
|
56
|
+
const result = await retrieveMultiple(apiConfig, 'pluginpackages', options);
|
|
64
57
|
return result.value.length > 0 ? result.value[0].pluginpackageid : '';
|
|
65
58
|
}
|
|
66
59
|
async function createPackage(config, content, apiConfig, solution) {
|
|
67
|
-
|
|
60
|
+
logger.info(`create package ${config.name}`);
|
|
68
61
|
const pluginPackage = {
|
|
69
62
|
name: `${config.prefix}_${config.name}`,
|
|
70
63
|
version: config.version,
|
|
@@ -74,19 +67,19 @@ async function createPackage(config, content, apiConfig, solution) {
|
|
|
74
67
|
if (solution) {
|
|
75
68
|
options.customHeaders = { 'MSCRM.SolutionUniqueName': solution };
|
|
76
69
|
}
|
|
77
|
-
const result = await
|
|
70
|
+
const result = await createWithReturnData(apiConfig, 'pluginpackages', pluginPackage, '$select=pluginpackageid', options);
|
|
78
71
|
if (result?.error) {
|
|
79
72
|
throw new Error(result.error.message);
|
|
80
73
|
}
|
|
81
74
|
return result.pluginpackageid;
|
|
82
75
|
}
|
|
83
76
|
async function updatePackage(config, content, apiConfig) {
|
|
84
|
-
|
|
77
|
+
logger.info(`update package ${config.name}`);
|
|
85
78
|
const updated = {
|
|
86
79
|
content: content,
|
|
87
80
|
version: config.version
|
|
88
81
|
};
|
|
89
|
-
const result = await
|
|
82
|
+
const result = await update(apiConfig, 'pluginpackages', config.pluginpackageid, updated);
|
|
90
83
|
if (result?.error) {
|
|
91
84
|
throw new Error(result.error.message);
|
|
92
85
|
}
|
package/lib/models/pluginStep.js
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const logger_1 = require("../logger");
|
|
6
|
-
const pluginImage_1 = require("./pluginImage");
|
|
7
|
-
async function deployStep(config, pluginTypeId, apiConfig, solution) {
|
|
1
|
+
import { retrieveMultiple, createWithReturnData, update } from 'dataverse-webapi/lib/node';
|
|
2
|
+
import { logger } from '../logger.js';
|
|
3
|
+
import { deployImage } from './pluginImage.js';
|
|
4
|
+
export async function deployStep(config, pluginTypeId, apiConfig, solution) {
|
|
8
5
|
const step = structuredClone(config);
|
|
9
6
|
step['plugintypeid@odata.bind'] = `/plugintypes(${pluginTypeId})`;
|
|
10
7
|
const messageId = await getSdkMessageId(step.message ?? '', apiConfig);
|
|
11
8
|
if (messageId == '') {
|
|
12
|
-
|
|
9
|
+
logger.warn(`sdk message ${step.message} not found`);
|
|
13
10
|
return;
|
|
14
11
|
}
|
|
15
12
|
if (step.entity !== '' && step.entity !== 'none') {
|
|
16
13
|
const filterId = await getSdkMessageFilterId(messageId, step.entity ?? '', apiConfig);
|
|
17
14
|
if (filterId == '') {
|
|
18
|
-
|
|
15
|
+
logger.warn(`sdk message ${step.message} for entity ${step.entity} not found`);
|
|
19
16
|
return;
|
|
20
17
|
}
|
|
21
18
|
step['sdkmessagefilterid@odata.bind'] = `/sdkmessagefilters(${filterId})`;
|
|
@@ -47,7 +44,7 @@ async function deployStep(config, pluginTypeId, apiConfig, solution) {
|
|
|
47
44
|
}
|
|
48
45
|
if (config.images && config.images.length > 0) {
|
|
49
46
|
try {
|
|
50
|
-
const promises = config.images.map((image) =>
|
|
47
|
+
const promises = config.images.map((image) => deployImage(config.sdkmessageprocessingstepid, step.name, image, config.message, apiConfig));
|
|
51
48
|
await Promise.all(promises);
|
|
52
49
|
}
|
|
53
50
|
catch (error) {
|
|
@@ -55,42 +52,41 @@ async function deployStep(config, pluginTypeId, apiConfig, solution) {
|
|
|
55
52
|
}
|
|
56
53
|
}
|
|
57
54
|
}
|
|
58
|
-
exports.deployStep = deployStep;
|
|
59
55
|
async function getSdkMessageFilterId(messageId, entityName, apiConfig) {
|
|
60
56
|
const options = [
|
|
61
57
|
`?$filter=primaryobjecttypecode eq '${entityName}' and _sdkmessageid_value eq ${messageId}`,
|
|
62
58
|
'&$select=sdkmessagefilterid'
|
|
63
59
|
].join('');
|
|
64
|
-
const message = await
|
|
60
|
+
const message = await retrieveMultiple(apiConfig, 'sdkmessagefilters', options);
|
|
65
61
|
return message.value.length > 0 ? message.value[0].sdkmessagefilterid : '';
|
|
66
62
|
}
|
|
67
63
|
async function getSdkMessageId(name, apiConfig) {
|
|
68
64
|
const options = [`?$filter=name eq '${name}'`, '&$select=sdkmessageid'].join('');
|
|
69
|
-
const message = await
|
|
65
|
+
const message = await retrieveMultiple(apiConfig, 'sdkmessages', options);
|
|
70
66
|
return message.value.length > 0 ? message.value[0].sdkmessageid : '';
|
|
71
67
|
}
|
|
72
68
|
async function retrieveStep(name, typeId, apiConfig) {
|
|
73
69
|
const options = `$select=sdkmessageprocessingstepid&$filter=name eq '${name}' and _plugintypeid_value eq ${typeId}`;
|
|
74
|
-
const result = await
|
|
70
|
+
const result = await retrieveMultiple(apiConfig, 'sdkmessageprocessingsteps', options);
|
|
75
71
|
return result.value.length > 0 ? result.value[0].sdkmessageprocessingstepid : '';
|
|
76
72
|
}
|
|
77
73
|
async function createStep(step, apiConfig, solution) {
|
|
78
|
-
|
|
74
|
+
logger.info(`create plugin step ${step.name}`);
|
|
79
75
|
const options = {};
|
|
80
76
|
if (solution) {
|
|
81
77
|
options.customHeaders = { 'MSCRM.SolutionUniqueName': solution };
|
|
82
78
|
}
|
|
83
|
-
const result = await
|
|
79
|
+
const result = await createWithReturnData(apiConfig, 'sdkmessageprocessingsteps', step, '$select=sdkmessageprocessingstepid', options);
|
|
84
80
|
if (result?.error) {
|
|
85
81
|
throw new Error(result.error.message);
|
|
86
82
|
}
|
|
87
83
|
return result.sdkmessageprocessingstepid;
|
|
88
84
|
}
|
|
89
85
|
async function updateStep(id, step, apiConfig) {
|
|
90
|
-
|
|
86
|
+
logger.info(`update plugin step ${step.name}`);
|
|
91
87
|
const entity = { ...step };
|
|
92
88
|
delete entity.sdkmessageprocessingstepid;
|
|
93
|
-
const result = await
|
|
89
|
+
const result = await update(apiConfig, 'sdkmessageprocessingsteps', id, entity);
|
|
94
90
|
if (result?.error) {
|
|
95
91
|
throw new Error(result.error.message);
|
|
96
92
|
}
|
package/lib/models/pluginType.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const pluginStep_1 = require("./pluginStep");
|
|
6
|
-
const logger_1 = require("../logger");
|
|
7
|
-
async function deployType(config, assemblyId, apiConfig, solution) {
|
|
1
|
+
import { retrieveMultiple, createWithReturnData, update } from 'dataverse-webapi/lib/node';
|
|
2
|
+
import { deployStep } from './pluginStep.js';
|
|
3
|
+
import { logger } from '../logger.js';
|
|
4
|
+
export async function deployType(config, assemblyId, apiConfig, solution) {
|
|
8
5
|
const type = {
|
|
9
6
|
name: config.name,
|
|
10
7
|
friendlyname: config.friendlyname,
|
|
@@ -33,7 +30,7 @@ async function deployType(config, assemblyId, apiConfig, solution) {
|
|
|
33
30
|
}
|
|
34
31
|
try {
|
|
35
32
|
if (config.steps) {
|
|
36
|
-
const promises = config.steps.map((step) =>
|
|
33
|
+
const promises = config.steps.map((step) => deployStep(step, config.plugintypeid, apiConfig, solution));
|
|
37
34
|
await Promise.all(promises);
|
|
38
35
|
}
|
|
39
36
|
}
|
|
@@ -41,26 +38,24 @@ async function deployType(config, assemblyId, apiConfig, solution) {
|
|
|
41
38
|
throw new Error(error.message);
|
|
42
39
|
}
|
|
43
40
|
}
|
|
44
|
-
|
|
45
|
-
async function retrieveType(name, assemblyId, apiConfig) {
|
|
41
|
+
export async function retrieveType(name, assemblyId, apiConfig) {
|
|
46
42
|
const options = `$select=plugintypeid&$filter=typename eq '${name}' and _pluginassemblyid_value eq ${assemblyId}`;
|
|
47
|
-
const result = await
|
|
43
|
+
const result = await retrieveMultiple(apiConfig, 'plugintypes', options);
|
|
48
44
|
return result.value.length > 0 ? result.value[0].plugintypeid : '';
|
|
49
45
|
}
|
|
50
|
-
exports.retrieveType = retrieveType;
|
|
51
46
|
async function createType(type, apiConfig) {
|
|
52
|
-
|
|
53
|
-
const result = await
|
|
47
|
+
logger.info(`create assembly type ${type.name}`);
|
|
48
|
+
const result = await createWithReturnData(apiConfig, 'plugintypes', type, '$select=plugintypeid');
|
|
54
49
|
if (result?.error) {
|
|
55
50
|
throw new Error(result.error.message);
|
|
56
51
|
}
|
|
57
52
|
return result.plugintypeid;
|
|
58
53
|
}
|
|
59
54
|
async function updateType(id, type, apiConfig) {
|
|
60
|
-
|
|
55
|
+
logger.info(`update assembly type ${type.name}`);
|
|
61
56
|
const entity = { ...type };
|
|
62
57
|
delete entity.plugintypeid;
|
|
63
|
-
const result = await
|
|
58
|
+
const result = await update(apiConfig, 'plugintypes', id, entity);
|
|
64
59
|
if (result?.error) {
|
|
65
60
|
throw new Error(result.error.message);
|
|
66
61
|
}
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.deploy = void 0;
|
|
7
|
-
const dataverse_service_1 = require("../dataverse.service");
|
|
8
|
-
const node_1 = require("dataverse-webapi/lib/node");
|
|
9
|
-
const logger_1 = require("../logger");
|
|
10
|
-
const fs_1 = __importDefault(require("fs"));
|
|
1
|
+
import { publish } from '../dataverse.service.js';
|
|
2
|
+
import { retrieveMultiple, createWithReturnData, update } from 'dataverse-webapi/lib/node';
|
|
3
|
+
import { logger } from '../logger.js';
|
|
4
|
+
import fs from 'fs';
|
|
11
5
|
function getWebResourceType(type) {
|
|
12
6
|
switch (type) {
|
|
13
7
|
case 'HTML':
|
|
@@ -38,7 +32,7 @@ function getWebResourceType(type) {
|
|
|
38
32
|
return 0;
|
|
39
33
|
}
|
|
40
34
|
}
|
|
41
|
-
async function deploy(webResources, apiConfig, solution, files) {
|
|
35
|
+
export async function deploy(webResources, apiConfig, solution, files) {
|
|
42
36
|
const publishXml = [];
|
|
43
37
|
let resources = webResources;
|
|
44
38
|
// Use list of files if provided
|
|
@@ -47,7 +41,7 @@ async function deploy(webResources, apiConfig, solution, files) {
|
|
|
47
41
|
for (const file of files.split(',')) {
|
|
48
42
|
const resource = webResources.filter((r) => r.path?.endsWith(file));
|
|
49
43
|
if (resource.length === 0) {
|
|
50
|
-
|
|
44
|
+
logger.warn(`web resource ${file} not found in dataverse.config.json`);
|
|
51
45
|
continue;
|
|
52
46
|
}
|
|
53
47
|
resources.push(resource[0]);
|
|
@@ -60,10 +54,10 @@ async function deploy(webResources, apiConfig, solution, files) {
|
|
|
60
54
|
}
|
|
61
55
|
}
|
|
62
56
|
catch (error) {
|
|
63
|
-
|
|
57
|
+
logger.error(`failed to retrieve resource ${resource.name}: ${error.message}`);
|
|
64
58
|
return;
|
|
65
59
|
}
|
|
66
|
-
const fileContent = await
|
|
60
|
+
const fileContent = await fs.promises.readFile(resource.path, 'utf8');
|
|
67
61
|
const content = Buffer.from(fileContent).toString('base64');
|
|
68
62
|
if (resource.webresourceid !== '') {
|
|
69
63
|
try {
|
|
@@ -71,7 +65,7 @@ async function deploy(webResources, apiConfig, solution, files) {
|
|
|
71
65
|
publishXml.push(updated);
|
|
72
66
|
}
|
|
73
67
|
catch (error) {
|
|
74
|
-
|
|
68
|
+
logger.error(`failed to update resource: ${error.message}`);
|
|
75
69
|
}
|
|
76
70
|
}
|
|
77
71
|
else {
|
|
@@ -79,7 +73,7 @@ async function deploy(webResources, apiConfig, solution, files) {
|
|
|
79
73
|
resource.webresourceid = await createResource(resource, content, apiConfig, solution);
|
|
80
74
|
}
|
|
81
75
|
catch (error) {
|
|
82
|
-
|
|
76
|
+
logger.error(`failed to create resource: ${error.message}`);
|
|
83
77
|
}
|
|
84
78
|
}
|
|
85
79
|
});
|
|
@@ -87,21 +81,20 @@ async function deploy(webResources, apiConfig, solution, files) {
|
|
|
87
81
|
// publish resources
|
|
88
82
|
if (publishXml.length > 0) {
|
|
89
83
|
try {
|
|
90
|
-
await
|
|
84
|
+
await publish(publishXml.join(''), apiConfig);
|
|
91
85
|
}
|
|
92
86
|
catch (error) {
|
|
93
|
-
|
|
87
|
+
logger.error(error.message);
|
|
94
88
|
}
|
|
95
89
|
}
|
|
96
90
|
}
|
|
97
|
-
exports.deploy = deploy;
|
|
98
91
|
async function retrieveResource(name, apiConfig) {
|
|
99
92
|
const options = `$select=webresourceid&$filter=name eq '${name}'`;
|
|
100
|
-
const result = await
|
|
93
|
+
const result = await retrieveMultiple(apiConfig, 'webresourceset', options);
|
|
101
94
|
return result.value.length > 0 ? result.value[0].webresourceid : '';
|
|
102
95
|
}
|
|
103
96
|
async function createResource(resource, content, apiConfig, solution) {
|
|
104
|
-
|
|
97
|
+
logger.info(`create web resource ${resource.name}`);
|
|
105
98
|
const webResource = {
|
|
106
99
|
webresourcetype: getWebResourceType(resource.type),
|
|
107
100
|
name: resource.name,
|
|
@@ -112,20 +105,20 @@ async function createResource(resource, content, apiConfig, solution) {
|
|
|
112
105
|
if (solution) {
|
|
113
106
|
options.customHeaders = { 'MSCRM.SolutionUniqueName': solution };
|
|
114
107
|
}
|
|
115
|
-
const result = await
|
|
108
|
+
const result = await createWithReturnData(apiConfig, 'webresourceset', webResource, '$select=webresourceid', options);
|
|
116
109
|
if (result?.error) {
|
|
117
110
|
throw new Error(result.error.message);
|
|
118
111
|
}
|
|
119
112
|
return result.webresourceid;
|
|
120
113
|
}
|
|
121
114
|
async function updateResource(resource, content, apiConfig) {
|
|
122
|
-
|
|
115
|
+
logger.info(`update web resource ${resource.name}`);
|
|
123
116
|
const webResource = {
|
|
124
117
|
content: content,
|
|
125
118
|
name: resource.name,
|
|
126
119
|
displayname: resource.displayname || resource.name
|
|
127
120
|
};
|
|
128
|
-
const result = await
|
|
121
|
+
const result = await update(apiConfig, 'webresourceset', resource.webresourceid, webResource);
|
|
129
122
|
if (result?.error) {
|
|
130
123
|
throw new Error(result.error.message);
|
|
131
124
|
}
|
package/lib/webResourceDeploy.js
CHANGED
|
@@ -1,31 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
exports.webResourceDeploy = void 0;
|
|
7
|
-
const path_1 = __importDefault(require("path"));
|
|
8
|
-
const fs_1 = __importDefault(require("fs"));
|
|
9
|
-
const logger_1 = require("./logger");
|
|
10
|
-
const webResource_1 = require("./models/webResource");
|
|
11
|
-
async function webResourceDeploy(creds, apiConfig, files) {
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { logger } from './logger.js';
|
|
4
|
+
import { deploy } from './models/webResource.js';
|
|
5
|
+
export async function webResourceDeploy(creds, apiConfig, files) {
|
|
12
6
|
const currentPath = '.';
|
|
13
|
-
const configFile = await
|
|
7
|
+
const configFile = await fs.promises.readFile(path.resolve(currentPath, 'dataverse.config.json'), 'utf8');
|
|
14
8
|
if (configFile == null) {
|
|
15
|
-
|
|
9
|
+
logger.warn('unable to find dataverse.config.json file');
|
|
16
10
|
return;
|
|
17
11
|
}
|
|
18
12
|
const config = JSON.parse(configFile);
|
|
19
13
|
const resources = config.webResources;
|
|
20
|
-
|
|
14
|
+
logger.info('deploy web resources');
|
|
21
15
|
try {
|
|
22
|
-
await
|
|
16
|
+
await deploy(resources, apiConfig, creds.solution, files);
|
|
23
17
|
}
|
|
24
18
|
catch (error) {
|
|
25
|
-
|
|
19
|
+
logger.error(error.message);
|
|
26
20
|
return;
|
|
27
21
|
}
|
|
28
|
-
|
|
29
|
-
await
|
|
22
|
+
logger.done('deployed web resources');
|
|
23
|
+
await fs.promises.writeFile(path.resolve(currentPath, 'dataverse.config.json'), JSON.stringify(config, null, 4), 'utf8');
|
|
30
24
|
}
|
|
31
|
-
exports.webResourceDeploy = webResourceDeploy;
|
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dataverse-utils",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Utilities for interacting with Dataverse environments",
|
|
6
|
-
"
|
|
6
|
+
"exports": "./lib/index.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"dataverse-utils": "lib/index.js"
|
|
9
9
|
},
|
|
10
10
|
"engines": {
|
|
11
|
-
"node": ">=
|
|
11
|
+
"node": ">=20.0.0"
|
|
12
12
|
},
|
|
13
|
+
"type": "module",
|
|
13
14
|
"files": [
|
|
14
15
|
"/lib"
|
|
15
16
|
],
|
|
@@ -24,19 +25,18 @@
|
|
|
24
25
|
},
|
|
25
26
|
"dependencies": {
|
|
26
27
|
"@azure/msal-node": "^2.10.0",
|
|
27
|
-
"commander": "^
|
|
28
|
-
"cryptr": "^6.
|
|
29
|
-
"dataverse-webapi": "^
|
|
30
|
-
"figures": "^
|
|
31
|
-
"glob": "^
|
|
28
|
+
"commander": "^13.1.0",
|
|
29
|
+
"cryptr": "^6.3.0",
|
|
30
|
+
"dataverse-webapi": "^3.0.0",
|
|
31
|
+
"figures": "^6.1.0",
|
|
32
|
+
"glob": "^11.0.1",
|
|
32
33
|
"kleur": "^4.1.5",
|
|
33
34
|
"prompts": "^2.4.2"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
|
-
"@types/cryptr": "^4.0.
|
|
37
|
+
"@types/cryptr": "^4.0.3",
|
|
37
38
|
"@types/glob": "^8.1.0",
|
|
38
|
-
"@types/
|
|
39
|
-
"@types/prompts": "^2.4.4"
|
|
39
|
+
"@types/prompts": "^2.4.9"
|
|
40
40
|
},
|
|
41
41
|
"volta": {
|
|
42
42
|
"extends": "../../package.json"
|