-
Notifications
You must be signed in to change notification settings - Fork 367
/
v1-v2.js
executable file
·130 lines (114 loc) · 6.25 KB
/
v1-v2.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import { readFileSync, writeFileSync } from 'fs';
import * as yaml from 'js-yaml';
const args = process.argv.slice(2);
function extractScopes(description) {
const scopeRegex = /(?:Required )?scope\(s\): ([\w,:.-]+)/i;
const match = scopeRegex.exec(description);
return match ? match[1].split(',').map((s) => s.trim()) : '';
}
function convertYAML(inputYAML) {
let data = yaml.load(inputYAML);
const location = args[0].replace('nango.yaml', '');
let changeLog = [];
if (data.integrations) {
for (const integration in data.integrations) {
if (!data.integrations[integration]) {
continue;
}
for (const taskName in data.integrations[integration]) {
const task = data.integrations[integration][taskName];
let change = { integration, taskName, changes: [] }; // Track changes for each task
if (task.type === 'action') {
change.type = 'action';
if (task.returns) {
task.output = task.returns;
change.changes.push({
action: `Set output from returns for ${taskName}`,
explanation: `The returns field has been deprecated in v2 as it is potentially confusing. Syncs and actions now have an 'output' field. A sync's output is assumed to be an array.`
});
}
const scopes = extractScopes(task.description);
if (scopes) {
task.scopes = scopes;
}
task.endpoint = `/${integration}/${taskName.replace(`${integration}-`, '')}`;
change.changes.push({
action: `Set endpoint for ${taskName}`,
explanation: `Syncs and actions now have a REST endpoint which is user defined and can be called directly. A sync's HTTP method is assumed to be a GET and an action's HTTP method is assumed to be a POST.`
});
delete task.returns;
delete task.type;
change.changes.push({
action: 'Removed the type property',
explanation: `The type property has been deprecated in v2. Syncs and actions are now differentiated by a top level property at the integration level.`
});
if (!data.integrations[integration].actions) {
data.integrations[integration].actions = {};
}
data.integrations[integration].actions[taskName] = task;
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete data.integrations[integration][taskName];
} else if (task.runs) {
change.type = 'sync';
if (Array.isArray(task.returns)) {
task.output = task.returns.length === 1 ? task.returns[0] : task.returns;
} else {
task.output = task.returns;
}
change.changes.push({
action: `Set output from returns for ${taskName}`,
explanation: `The returns field has been deprecated in v2 as it is potentially confusing. Syncs and actions now have an 'output' field. A sync's output is assumed to be an array.`
});
const contents = readFileSync(`./${location}${taskName}.ts`, 'utf8');
task.sync_type = contents.includes('lastSyncDate') ? 'incremental' : 'full';
if (Array.isArray(task.output)) {
task.endpoint = task.output.map((o) => `/${integration}/${taskName.replace(`${integration}-`, '')}/${o.toLowerCase()}`);
} else {
task.endpoint = `/${integration}/${taskName.replace(`${integration}-`, '')}`;
}
change.changes.push({
action: `Set endpoint for ${taskName}`,
explanation: `Syncs and actions now have a REST endpoint which is user defined and can be called directly. A sync's HTTP method is assumed to be a GET and an action's HTTP method is assumed to be a POST.`
});
if (task.description) {
const scopes = extractScopes(task.description);
if (scopes) {
task.scopes = scopes;
}
change.changes.push({
action: 'Extracted scopes from description',
explanation: `Scopes are now extracted from the description field and can be set as an array on the script`
});
}
delete task.type;
delete task.returns;
change.changes.push({
action: 'Removed the type property',
explanation: `The type property has been deprecated in v2. Syncs and actions are now differentiated by a top level property at the integration level.`
});
if (!data.integrations[integration].syncs) {
data.integrations[integration].syncs = {};
}
data.integrations[integration].syncs[taskName] = task;
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete data.integrations[integration][taskName];
}
if (change.changes.length > 0) {
changeLog.push(change);
}
}
}
}
changeLog.forEach((log) => {
console.log(`Integration: ${log.integration}, ${log.type}: ${log.taskName}`);
log.changes.forEach((change) => {
console.log(`- Action: ${change.action}`);
console.log(` Reason: ${change.explanation}`);
});
console.log();
});
return yaml.dump(data);
}
const inputYAML = readFileSync(args[0], 'utf8');
const outputYAML = convertYAML(inputYAML);
writeFileSync(args[0], outputYAML);