@contrail/cli 1.0.63 → 1.0.65
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/cli.js +4 -0
- package/lib/types/types-extractor.d.ts +11 -40
- package/lib/types/types-extractor.js +34 -2
- package/lib/types/types-uploader.js +1 -1
- package/package.json +1 -1
- package/src/cli.ts +4 -0
- package/src/types/types-extractor.ts +50 -3
- package/src/types/types-uploader.ts +1 -1
- package/templates/typescript/Dockerfile +14 -0
- package/templates/typescript/README.md +10 -0
- package/templates/typescript/actions/handler.ts +65 -0
- package/templates/typescript/actions/utils/logger.ts +15 -0
- package/templates/typescript/app.yml +23 -26
- package/templates/typescript/package.json +21 -1
- package/templates/typescript/tsconfig.json +1 -1
- package/templates/typescript/actions/exampleAction.ts +0 -39
package/lib/cli.js
CHANGED
|
@@ -325,6 +325,10 @@ const helpSections = [
|
|
|
325
325
|
name: 'install',
|
|
326
326
|
summary: 'Install an app to your org.'
|
|
327
327
|
},
|
|
328
|
+
{
|
|
329
|
+
name: 'upgrade',
|
|
330
|
+
summary: 'Upgrades or downgrades an existing app in your org.'
|
|
331
|
+
},
|
|
328
332
|
{
|
|
329
333
|
name: 'uninstall',
|
|
330
334
|
summary: 'Uninstall an app from your org.'
|
|
@@ -8,49 +8,20 @@ export interface DataHolder {
|
|
|
8
8
|
typePropertyPolicies: any[];
|
|
9
9
|
typePropertyPolicyLinks: any[];
|
|
10
10
|
}
|
|
11
|
+
export interface ReducedDataHolder {
|
|
12
|
+
reducedTypes: any[];
|
|
13
|
+
reducedOptionSets: any[];
|
|
14
|
+
reducedOptionSetHierarchies: any[];
|
|
15
|
+
reducedRuleSets: any[];
|
|
16
|
+
reducedRuleSetLinks: any[];
|
|
17
|
+
reducedUsageInfo: any[];
|
|
18
|
+
reducedTypePropertyPolicies: any[];
|
|
19
|
+
reducedTypePropertyPolicyLinks: any[];
|
|
20
|
+
}
|
|
11
21
|
export declare function getAll(args: any): Promise<void>;
|
|
12
22
|
/**
|
|
13
23
|
* stores reduced option sets and returns full option sets */
|
|
14
24
|
export declare function getOptionSets(): Promise<any>;
|
|
15
25
|
export declare function getTypes(): Promise<any[]>;
|
|
16
26
|
export declare function reduceTypes(dataHolder: DataHolder): any[];
|
|
17
|
-
export declare function reduceData(data: DataHolder):
|
|
18
|
-
reducedTypes: any[];
|
|
19
|
-
reducedOptionSets: {
|
|
20
|
-
name: any;
|
|
21
|
-
isArchived: any;
|
|
22
|
-
optionSet: any;
|
|
23
|
-
}[];
|
|
24
|
-
reducedOptionSetHierarchies: {
|
|
25
|
-
hierarchy: any;
|
|
26
|
-
options: any;
|
|
27
|
-
name: any;
|
|
28
|
-
}[];
|
|
29
|
-
reducedRuleSets: {
|
|
30
|
-
ruleSet: any;
|
|
31
|
-
name: any;
|
|
32
|
-
}[];
|
|
33
|
-
reducedRuleSetLinks: any[];
|
|
34
|
-
reducedUsageInfo: {
|
|
35
|
-
used: any;
|
|
36
|
-
editable: any;
|
|
37
|
-
formulaFunction: any;
|
|
38
|
-
validationFunction: any;
|
|
39
|
-
numberFormat: any;
|
|
40
|
-
defaultValue: any;
|
|
41
|
-
label: any;
|
|
42
|
-
typeSlug: any;
|
|
43
|
-
typePropertySlug: any;
|
|
44
|
-
}[];
|
|
45
|
-
reducedTypePropertyPolicies: {
|
|
46
|
-
label: any;
|
|
47
|
-
policy: {
|
|
48
|
-
version: any;
|
|
49
|
-
statements: any;
|
|
50
|
-
};
|
|
51
|
-
}[];
|
|
52
|
-
reducedTypePropertyPolicyLinks: {
|
|
53
|
-
typePropertySlug: any;
|
|
54
|
-
typePropertyPolicyLabel: any;
|
|
55
|
-
}[];
|
|
56
|
-
};
|
|
27
|
+
export declare function reduceData(data: DataHolder): ReducedDataHolder;
|
|
@@ -247,9 +247,38 @@ export function reduceData(data) {
|
|
|
247
247
|
reducedTypePropertyPolicyLinks: reduceTypePropertyPolicyLinks(data),
|
|
248
248
|
};
|
|
249
249
|
}
|
|
250
|
+
const saveTypesFunction = function (data, dir) {
|
|
251
|
+
const roots = {};
|
|
252
|
+
for (const type of data.reducedTypes) {
|
|
253
|
+
const typePathParts = type.typePath.split(':');
|
|
254
|
+
if (!typePathParts) {
|
|
255
|
+
console.warn('skipping bad type with no path', type);
|
|
256
|
+
}
|
|
257
|
+
const root = typePathParts[0];
|
|
258
|
+
if (roots[root]) {
|
|
259
|
+
roots[root].push(type);
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
roots[root] = [type];
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
for (const [root, types] of Object.entries(roots)) {
|
|
266
|
+
const CURRENT_DIR = process.cwd();
|
|
267
|
+
const subDir = path.join(CURRENT_DIR, dir, 'types');
|
|
268
|
+
if (!fs.existsSync(subDir)) {
|
|
269
|
+
fs.mkdirSync(subDir);
|
|
270
|
+
}
|
|
271
|
+
const yamlStr = yaml.dump(types);
|
|
272
|
+
const fileLabel = root;
|
|
273
|
+
if (!fileLabel) {
|
|
274
|
+
console.warn('skipping bad type root:', root);
|
|
275
|
+
}
|
|
276
|
+
fs.writeFileSync(path.join(subDir, `${removeSlash(fileLabel)}.yml`), yamlStr, 'utf8');
|
|
277
|
+
}
|
|
278
|
+
};
|
|
250
279
|
function saveData(reducedData, dir) {
|
|
251
280
|
const propertyToFolderMap = {
|
|
252
|
-
reducedTypes: { filename: 'types', split:
|
|
281
|
+
reducedTypes: { filename: 'types', split: false, fileLabel: 'slug', saveFunction: saveTypesFunction },
|
|
253
282
|
reducedOptionSets: { filename: 'option-sets', split: true, fileLabel: 'name' },
|
|
254
283
|
reducedOptionSetHierarchies: { filename: 'option-set-hierarchies', split: true, fileLabel: 'name' },
|
|
255
284
|
reducedRuleSets: { filename: 'rule-sets', split: true, fileLabel: 'name' },
|
|
@@ -260,7 +289,10 @@ function saveData(reducedData, dir) {
|
|
|
260
289
|
};
|
|
261
290
|
for (const [key, folder] of Object.entries(propertyToFolderMap)) {
|
|
262
291
|
const CURRENT_DIR = process.cwd();
|
|
263
|
-
if (folder
|
|
292
|
+
if (folder['saveFunction']) {
|
|
293
|
+
folder['saveFunction'](reducedData, dir);
|
|
294
|
+
}
|
|
295
|
+
else if (folder.split) {
|
|
264
296
|
const subDir = path.join(CURRENT_DIR, dir, folder.filename);
|
|
265
297
|
if (!fs.existsSync(subDir)) {
|
|
266
298
|
fs.mkdirSync(subDir);
|
|
@@ -25,7 +25,7 @@ function loadReducedTypes() {
|
|
|
25
25
|
const files = fs.readdirSync(path.join(TARGET_DIR, 'types'));
|
|
26
26
|
const types = [];
|
|
27
27
|
for (const file of files) {
|
|
28
|
-
types.push(yaml.load(fs.readFileSync(path.join(TARGET_DIR, 'types', file), 'utf8')));
|
|
28
|
+
types.push(...yaml.load(fs.readFileSync(path.join(TARGET_DIR, 'types', file), 'utf8')));
|
|
29
29
|
}
|
|
30
30
|
return types;
|
|
31
31
|
}
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -340,6 +340,10 @@ const helpSections = [
|
|
|
340
340
|
name: 'install',
|
|
341
341
|
summary: 'Install an app to your org.'
|
|
342
342
|
},
|
|
343
|
+
{
|
|
344
|
+
name: 'upgrade',
|
|
345
|
+
summary: 'Upgrades or downgrades an existing app in your org.'
|
|
346
|
+
},
|
|
343
347
|
{
|
|
344
348
|
name: 'uninstall',
|
|
345
349
|
summary: 'Uninstall an app from your org.'
|
|
@@ -8,6 +8,10 @@ import pLimit from 'p-limit';
|
|
|
8
8
|
const limit = pLimit(30);
|
|
9
9
|
|
|
10
10
|
const yaml = require('js-yaml');
|
|
11
|
+
interface StoreFunction
|
|
12
|
+
{
|
|
13
|
+
(data: ReducedDataHolder, dir: string): void;
|
|
14
|
+
}
|
|
11
15
|
|
|
12
16
|
export interface DataHolder {
|
|
13
17
|
types: any[],
|
|
@@ -20,6 +24,17 @@ export interface DataHolder {
|
|
|
20
24
|
typePropertyPolicyLinks: any[],
|
|
21
25
|
}
|
|
22
26
|
|
|
27
|
+
export interface ReducedDataHolder {
|
|
28
|
+
reducedTypes: any[],
|
|
29
|
+
reducedOptionSets: any[],
|
|
30
|
+
reducedOptionSetHierarchies: any[],
|
|
31
|
+
reducedRuleSets: any[],
|
|
32
|
+
reducedRuleSetLinks: any[],
|
|
33
|
+
reducedUsageInfo: any[],
|
|
34
|
+
reducedTypePropertyPolicies: any[],
|
|
35
|
+
reducedTypePropertyPolicyLinks: any[],
|
|
36
|
+
}
|
|
37
|
+
|
|
23
38
|
export async function getAll(args) {
|
|
24
39
|
try {
|
|
25
40
|
const userConfig = await authUser();
|
|
@@ -268,7 +283,7 @@ export function reduceTypes(dataHolder: DataHolder) {
|
|
|
268
283
|
return reducedTypes;
|
|
269
284
|
}
|
|
270
285
|
|
|
271
|
-
export function reduceData(data: DataHolder) {
|
|
286
|
+
export function reduceData(data: DataHolder): ReducedDataHolder {
|
|
272
287
|
return {
|
|
273
288
|
reducedTypes: reduceTypes(data),
|
|
274
289
|
reducedOptionSets: reduceOptionSets(data),
|
|
@@ -281,10 +296,40 @@ export function reduceData(data: DataHolder) {
|
|
|
281
296
|
};
|
|
282
297
|
}
|
|
283
298
|
|
|
299
|
+
const saveTypesFunction: StoreFunction = function (data: ReducedDataHolder, dir: string) {
|
|
300
|
+
const roots = {};
|
|
301
|
+
for(const type of data.reducedTypes) {
|
|
302
|
+
const typePathParts = type.typePath.split(':');
|
|
303
|
+
if(!typePathParts) {
|
|
304
|
+
console.warn('skipping bad type with no path', type);
|
|
305
|
+
}
|
|
306
|
+
const root = typePathParts[0];
|
|
307
|
+
if(roots[root]) {
|
|
308
|
+
roots[root].push(type);
|
|
309
|
+
} else {
|
|
310
|
+
roots[root] = [type];
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
for(const [root, types] of Object.entries(roots)) {
|
|
314
|
+
const CURRENT_DIR = process.cwd();
|
|
315
|
+
const subDir = path.join(CURRENT_DIR, dir, 'types');
|
|
316
|
+
if(!fs.existsSync(subDir)) {
|
|
317
|
+
fs.mkdirSync(subDir);
|
|
318
|
+
}
|
|
319
|
+
const yamlStr = yaml.dump(types);
|
|
320
|
+
const fileLabel = root;
|
|
321
|
+
if(!fileLabel) {
|
|
322
|
+
console.warn('skipping bad type root:', root);
|
|
323
|
+
}
|
|
324
|
+
fs.writeFileSync(path.join(subDir, `${removeSlash(fileLabel)}.yml`), yamlStr, 'utf8');
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
};
|
|
328
|
+
|
|
284
329
|
function saveData(reducedData, dir: string) {
|
|
285
330
|
|
|
286
331
|
const propertyToFolderMap = {
|
|
287
|
-
reducedTypes: { filename: 'types', split:
|
|
332
|
+
reducedTypes: { filename: 'types', split: false, fileLabel: 'slug', saveFunction: saveTypesFunction},
|
|
288
333
|
reducedOptionSets: { filename: 'option-sets', split: true, fileLabel: 'name' },
|
|
289
334
|
reducedOptionSetHierarchies: { filename: 'option-set-hierarchies', split: true, fileLabel: 'name' },
|
|
290
335
|
reducedRuleSets: { filename: 'rule-sets', split: true, fileLabel: 'name' },
|
|
@@ -295,7 +340,9 @@ function saveData(reducedData, dir: string) {
|
|
|
295
340
|
};
|
|
296
341
|
for(const [key, folder] of Object.entries(propertyToFolderMap)) {
|
|
297
342
|
const CURRENT_DIR = process.cwd();
|
|
298
|
-
if(folder
|
|
343
|
+
if(folder['saveFunction']) {
|
|
344
|
+
folder['saveFunction'](reducedData, dir);
|
|
345
|
+
} else if(folder.split) {
|
|
299
346
|
const subDir = path.join(CURRENT_DIR, dir, folder.filename);
|
|
300
347
|
if(!fs.existsSync(subDir)) {
|
|
301
348
|
fs.mkdirSync(subDir);
|
|
@@ -32,7 +32,7 @@ function loadReducedTypes(){
|
|
|
32
32
|
const files = fs.readdirSync(path.join(TARGET_DIR, 'types'));
|
|
33
33
|
const types = [];
|
|
34
34
|
for(const file of files) {
|
|
35
|
-
types.push(yaml.load(fs.readFileSync(path.join(TARGET_DIR, 'types', file), 'utf8')));
|
|
35
|
+
types.push(...yaml.load(fs.readFileSync(path.join(TARGET_DIR, 'types', file), 'utf8')));
|
|
36
36
|
}
|
|
37
37
|
return types;
|
|
38
38
|
} catch (e) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# docker build -t app-name .
|
|
2
|
+
# docker run -p 9000:8080 app-name
|
|
3
|
+
FROM public.ecr.aws/lambda/nodejs:16
|
|
4
|
+
|
|
5
|
+
# Install NPM dependencies for function
|
|
6
|
+
COPY package* ${LAMBDA_TASK_ROOT}
|
|
7
|
+
RUN npm install
|
|
8
|
+
|
|
9
|
+
COPY tsconfig.json ${LAMBDA_TASK_ROOT}
|
|
10
|
+
COPY actions/ ${LAMBDA_TASK_ROOT}/actions
|
|
11
|
+
|
|
12
|
+
RUN npm run build
|
|
13
|
+
|
|
14
|
+
CMD ["dist/handler.execute"]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
### building and uploading docker image to ECR
|
|
2
|
+
1. set AWS_REGISTRY environment variable to be able to tag and/or push to ECR
|
|
3
|
+
### Example: xxx.dkr.ecr.us-east-1.amazonaws.com
|
|
4
|
+
1. To build, run, tag, and push using docker, there are npm scripts that can be used.
|
|
5
|
+
2. The npm scripts use the npm package name, version, and config fields to set the appropriate values
|
|
6
|
+
3. OPTIONAL: if you want to inspect the container you can run `npm run docker-run-entry`
|
|
7
|
+
4. OPTIONAL: if you want to run this locally using port 9000, you can run `npm run docker-run`
|
|
8
|
+
5. To tag the image for pushing to ECR `npm run docker-tag`
|
|
9
|
+
6. To push the image to ECR `npm run docker-push`
|
|
10
|
+
7. All the npm scripts have a ':win" version to run on windows
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { login } from '@contrail/sdk';
|
|
2
|
+
import { Logger } from './utils/logger';
|
|
3
|
+
|
|
4
|
+
export async function execute(data) {
|
|
5
|
+
const logger = new Logger();
|
|
6
|
+
logger.log(JSON.stringify(data))
|
|
7
|
+
const event = (typeof data.event === 'string')
|
|
8
|
+
? JSON.parse(data.event)
|
|
9
|
+
: data.event;
|
|
10
|
+
data = JSON.parse(JSON.stringify(data));
|
|
11
|
+
const config = data.config;
|
|
12
|
+
if (!config.apiHost || !config.userName || !config.password) {
|
|
13
|
+
const message = 'This action requires an api host, a username, and a password to run';
|
|
14
|
+
const body = {
|
|
15
|
+
message,
|
|
16
|
+
logs: [message]
|
|
17
|
+
};
|
|
18
|
+
return {
|
|
19
|
+
statusCode: 400,
|
|
20
|
+
body
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
login({ apiKey: config.apiKey, orgSlug: config.orgSlug });
|
|
26
|
+
const results = {};
|
|
27
|
+
|
|
28
|
+
logger.log('Sending message: ', event);
|
|
29
|
+
const response = await fetch(config.url, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
body: event,
|
|
32
|
+
headers: { 'Content-Type': 'application/json' }
|
|
33
|
+
});
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
logger.log('Webhook event failed to publish');
|
|
36
|
+
logger.log('Response: ', JSON.stringify(response));
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
logger.log('Published!');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
results['logs'] = logger.getEntries();
|
|
43
|
+
results['config'] = config;
|
|
44
|
+
|
|
45
|
+
logger.log('returning: ' + JSON.stringify(results));
|
|
46
|
+
return {
|
|
47
|
+
statusCode: 200,
|
|
48
|
+
body: JSON.stringify(results)
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
} catch (e) {
|
|
52
|
+
logger.log('returning failure: ' + e.message);
|
|
53
|
+
const body = {
|
|
54
|
+
message: 'failed',
|
|
55
|
+
error: e.message,
|
|
56
|
+
logs: logger.getEntries()
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
statusCode: 400,
|
|
61
|
+
body: JSON.stringify(body),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
}
|
|
@@ -4,54 +4,51 @@ appDescription: "Your app description."
|
|
|
4
4
|
visibility: public
|
|
5
5
|
publisher: "Your company name"
|
|
6
6
|
version: 1.0
|
|
7
|
-
|
|
7
|
+
dockerImageRef: CHANGE_ME
|
|
8
8
|
|
|
9
9
|
# eventWorkflowTriggerKeyMapping will be used to parse an incoming event into a key that can trigger workflows
|
|
10
10
|
# {} indicates a field on the event. You can use nested fields by separating the levels with a '.'
|
|
11
11
|
# i.e. an event {details: {eventType: 'apparel'}, actionType: 'create'} can be parsed to apparel|create with the following
|
|
12
|
-
eventWorkflowTriggerKeyMapping: "{details.eventType}|{actionType}"
|
|
12
|
+
eventWorkflowTriggerKeyMapping: "{details.eventType}|{actionType}"
|
|
13
13
|
|
|
14
|
-
appConfiguration:
|
|
15
|
-
apiHost:
|
|
14
|
+
appConfiguration:
|
|
15
|
+
apiHost:
|
|
16
16
|
label: "API Host"
|
|
17
17
|
propertyType: "string"
|
|
18
|
-
userName:
|
|
18
|
+
userName:
|
|
19
19
|
label: "User Name"
|
|
20
20
|
propertyType: "string"
|
|
21
|
-
password:
|
|
21
|
+
password:
|
|
22
22
|
label: "Password"
|
|
23
23
|
propertyType: "string"
|
|
24
24
|
|
|
25
25
|
# Actions can be written in .ts but must be compiled to .js before deployment.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
updateProduct:
|
|
29
|
-
handler: actions/exampleAction.js
|
|
26
|
+
actions:
|
|
27
|
+
updateProduct:
|
|
30
28
|
name: "Update Product"
|
|
31
29
|
description: "Updates a product in the destination system."
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
async: false # default is false
|
|
31
|
+
actionConfiguration:
|
|
32
|
+
email:
|
|
34
33
|
label: "Email Address"
|
|
35
34
|
propertyType: "string"
|
|
36
35
|
|
|
37
|
-
triggers:
|
|
38
|
-
trigger1:
|
|
36
|
+
triggers:
|
|
37
|
+
trigger1:
|
|
39
38
|
key: product|create
|
|
40
39
|
name: "External Product Created"
|
|
41
40
|
external: true
|
|
42
41
|
description: "Triggers on externally created products"
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
workflow1:
|
|
43
|
+
workflows:
|
|
44
|
+
workflow1:
|
|
47
45
|
name: "Update item on product creation"
|
|
48
46
|
triggerKey: product|create
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
47
|
+
isActive: true
|
|
48
|
+
public: true
|
|
49
|
+
workflowDefinition:
|
|
50
|
+
paths:
|
|
51
|
+
- conditional: "{retailPrice} > 10"
|
|
52
|
+
actionDefinitionConfigs:
|
|
53
|
+
- action: updateProduct
|
|
54
|
+
name: Update Product
|
|
@@ -7,20 +7,40 @@
|
|
|
7
7
|
"@contrail/contrail-cli": "bin/init",
|
|
8
8
|
"contrail": "bin/init"
|
|
9
9
|
},
|
|
10
|
+
"config": {
|
|
11
|
+
"wf": "/workflow-actions-prod"
|
|
12
|
+
},
|
|
10
13
|
"publishConfig": {
|
|
11
14
|
"access": "public"
|
|
12
15
|
},
|
|
13
16
|
"scripts": {
|
|
14
17
|
"build": "tsc",
|
|
15
|
-
"
|
|
18
|
+
"lint": "eslint . --fix",
|
|
19
|
+
"test": "jest",
|
|
20
|
+
"test-watch": "jest --watch",
|
|
21
|
+
"docker-build": "docker build . -t \"${npm_package_name}:${npm_package_version}\"",
|
|
22
|
+
"docker-build:win": "docker build . -t \"%npm_package_name%:%npm_package_version%\"",
|
|
23
|
+
"docker-run-entry": "docker run -it --entrypoint=/bin/bash \"${npm_package_name}:${npm_package_version}\"",
|
|
24
|
+
"docker-run-entry:win": "docker run -it --entrypoint=/bin/bash \"%npm_package_name%:%npm_package_version%\"",
|
|
25
|
+
"docker-run": "docker run --env CONTRAIL_CLI_ENV=DEV -p 9000:8080 \"${npm_package_name}:${npm_package_version}\"",
|
|
26
|
+
"docker-run:win": "docker run --env CONTRAIL_CLI_ENV=DEV -p 9000:8080 \"%npm_package_name%:%npm_package_version%\"",
|
|
27
|
+
"docker-ecr-login": "aws ecr get-login-password | docker login --username AWS --password-stdin ${AWS_REGISTRY}",
|
|
28
|
+
"docker-ecr-login:win": "aws ecr get-login-password | docker login --username AWS --password-stdin %AWS_REGISTRY%",
|
|
29
|
+
"docker-tag": "docker tag ${npm_package_name}:${npm_package_version} \"${AWS_REGISTRY}${npm_package_config_wf}:${npm_package_name}.${npm_package_version}\"",
|
|
30
|
+
"docker-tag:win": "docker tag %npm_package_name%:%npm_package_version% %AWS_REGISTRY%%npm_package_config_wf%:%npm_package_name%.%npm_package_version%",
|
|
31
|
+
"docker-push": "docker push \"${AWS_REGISTRY}${npm_package_config_wf}:${npm_package_name}.${npm_package_version}\"",
|
|
32
|
+
"docker-push:win": "docker push \"%AWS_REGISTRY%%npm_package_config_wf%:%npm_package_name%.%npm_package_version%\""
|
|
16
33
|
},
|
|
17
34
|
"keywords": [],
|
|
18
35
|
"author": "",
|
|
19
36
|
"license": "ISC",
|
|
20
37
|
"dependencies": {
|
|
38
|
+
"@contrail/sdk": "^1.1.53",
|
|
21
39
|
"chalk": "^4.0.0"
|
|
22
40
|
},
|
|
23
41
|
"devDependencies": {
|
|
42
|
+
"jest": "^29.2.2",
|
|
43
|
+
"ts-jest": "^29.0.3",
|
|
24
44
|
"typescript": "^4.7.4"
|
|
25
45
|
}
|
|
26
46
|
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
export { }; // Leave empty export - This allows for multiple files with a function named execute.
|
|
2
|
-
async function execute(config, event, Functions) {
|
|
3
|
-
const getBodyFromEvent = (config, event) => {
|
|
4
|
-
let body = Functions.stringUtil.parseVariables(config.message, event);
|
|
5
|
-
console.log('body: ', body);
|
|
6
|
-
if (config.sendDetails) {
|
|
7
|
-
const data = event;
|
|
8
|
-
const properties = {};
|
|
9
|
-
let addedProperty = false;
|
|
10
|
-
for (const property of config.fieldsToForward) {
|
|
11
|
-
const variableLevels = property.split('.');
|
|
12
|
-
let replacementValue = data;
|
|
13
|
-
for (let i = 0; i < variableLevels.length; i++) {
|
|
14
|
-
replacementValue = replacementValue[variableLevels[i]];
|
|
15
|
-
}
|
|
16
|
-
properties[property] = replacementValue;
|
|
17
|
-
addedProperty = true;
|
|
18
|
-
}
|
|
19
|
-
if (addedProperty) {
|
|
20
|
-
body = body + ' Properties: ' + JSON.stringify(properties) + '.';
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return JSON.stringify({ text: body });
|
|
24
|
-
};
|
|
25
|
-
const body = getBodyFromEvent(config, event);
|
|
26
|
-
console.log('Sending message: ', body);
|
|
27
|
-
const response = await Functions.fetch(config.url, {
|
|
28
|
-
method: 'POST',
|
|
29
|
-
body: body,
|
|
30
|
-
headers: { 'Content-Type': 'application/json' }
|
|
31
|
-
});
|
|
32
|
-
if (!response.ok) {
|
|
33
|
-
console.log('Webhook event failed to publish');
|
|
34
|
-
console.log('Response: ', JSON.stringify(response));
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
console.log('Published!');
|
|
38
|
-
}
|
|
39
|
-
}
|