@prismatic-io/prism 3.3.0 → 4.1.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.
Files changed (207) hide show
  1. package/bin/run +9 -8
  2. package/lib/auth.js +183 -199
  3. package/lib/commands/alerts/events/list.js +27 -57
  4. package/lib/commands/alerts/groups/create.js +18 -49
  5. package/lib/commands/alerts/groups/delete.js +10 -41
  6. package/lib/commands/alerts/groups/list.js +15 -47
  7. package/lib/commands/alerts/monitors/clear.js +10 -41
  8. package/lib/commands/alerts/monitors/create.js +27 -58
  9. package/lib/commands/alerts/monitors/delete.js +10 -41
  10. package/lib/commands/alerts/monitors/list.js +16 -48
  11. package/lib/commands/alerts/triggers/list.js +15 -47
  12. package/lib/commands/alerts/webhooks/create.js +18 -49
  13. package/lib/commands/alerts/webhooks/delete.js +10 -41
  14. package/lib/commands/alerts/webhooks/list.js +25 -57
  15. package/lib/commands/authorization-methods/list.js +20 -51
  16. package/lib/commands/components/actions/list.js +29 -61
  17. package/lib/commands/components/delete.js +10 -41
  18. package/lib/commands/components/dev/run.js +75 -0
  19. package/lib/commands/components/dev/test.js +218 -0
  20. package/lib/commands/components/init/action.js +12 -0
  21. package/lib/commands/components/init/component.js +12 -0
  22. package/lib/commands/components/init/connection.js +12 -0
  23. package/lib/commands/components/init/index.js +203 -0
  24. package/lib/commands/components/init/trigger.js +12 -0
  25. package/lib/commands/components/list.js +31 -60
  26. package/lib/commands/components/publish.js +29 -279
  27. package/lib/commands/components/triggers/list.js +29 -61
  28. package/lib/commands/customers/create.js +14 -45
  29. package/lib/commands/customers/credentials/create.js +19 -50
  30. package/lib/commands/customers/credentials/delete.js +10 -41
  31. package/lib/commands/customers/credentials/list.js +30 -59
  32. package/lib/commands/customers/credentials/update.js +16 -47
  33. package/lib/commands/customers/delete.js +10 -41
  34. package/lib/commands/customers/list.js +16 -48
  35. package/lib/commands/customers/update.js +15 -46
  36. package/lib/commands/customers/users/create.js +18 -49
  37. package/lib/commands/customers/users/delete.js +10 -41
  38. package/lib/commands/customers/users/list.js +21 -51
  39. package/lib/commands/customers/users/roles.js +18 -48
  40. package/lib/commands/customers/users/update.js +19 -50
  41. package/lib/commands/executions/step-result/get.js +36 -66
  42. package/lib/commands/instances/config-vars/list.js +32 -62
  43. package/lib/commands/instances/create.js +20 -51
  44. package/lib/commands/instances/delete.js +10 -41
  45. package/lib/commands/instances/deploy.js +20 -44
  46. package/lib/commands/instances/disable.js +11 -42
  47. package/lib/commands/instances/enable.js +11 -42
  48. package/lib/commands/instances/flow-configs/list.js +25 -55
  49. package/lib/commands/instances/flow-configs/test.js +62 -97
  50. package/lib/commands/instances/list.js +31 -59
  51. package/lib/commands/instances/update.js +15 -46
  52. package/lib/commands/integrations/available.js +13 -44
  53. package/lib/commands/integrations/create.js +14 -45
  54. package/lib/commands/integrations/delete.js +10 -41
  55. package/lib/commands/integrations/export.js +11 -68
  56. package/lib/commands/integrations/flows/list.js +22 -52
  57. package/lib/commands/integrations/flows/test.js +62 -96
  58. package/lib/commands/integrations/fork.js +15 -46
  59. package/lib/commands/integrations/import.js +12 -63
  60. package/lib/commands/integrations/list.js +25 -54
  61. package/lib/commands/integrations/publish.js +13 -44
  62. package/lib/commands/integrations/update.js +18 -49
  63. package/lib/commands/integrations/versions/index.js +26 -58
  64. package/lib/commands/login.js +16 -32
  65. package/lib/commands/logout.js +10 -22
  66. package/lib/commands/logs/severities/list.js +15 -47
  67. package/lib/commands/me/index.js +13 -60
  68. package/lib/commands/me/token/revoke.js +12 -0
  69. package/lib/commands/me/token.js +10 -22
  70. package/lib/commands/organization/credentials/create.js +17 -48
  71. package/lib/commands/organization/credentials/delete.js +10 -41
  72. package/lib/commands/organization/credentials/list.js +22 -54
  73. package/lib/commands/organization/credentials/update.js +16 -47
  74. package/lib/commands/organization/update.js +12 -43
  75. package/lib/commands/organization/updateAvatarUrl.js +14 -45
  76. package/lib/commands/organization/users/create.js +16 -47
  77. package/lib/commands/organization/users/delete.js +10 -41
  78. package/lib/commands/organization/users/list.js +16 -48
  79. package/lib/commands/organization/users/roles.js +18 -48
  80. package/lib/commands/organization/users/update.js +19 -50
  81. package/lib/config.js +24 -30
  82. package/lib/errors.js +48 -27
  83. package/lib/fields.js +6 -4
  84. package/lib/fs.js +6 -14
  85. package/lib/generate/action.js +36 -41
  86. package/lib/generate/client.js +11 -16
  87. package/lib/generate/connection.js +4 -13
  88. package/lib/generate/index.js +29 -19
  89. package/lib/generate/input.js +28 -43
  90. package/lib/generate/parse.js +38 -44
  91. package/lib/generate/sourceFile.js +11 -7
  92. package/lib/generate/util.js +9 -7
  93. package/lib/graphql.js +37 -65
  94. package/lib/index.js +3 -3
  95. package/lib/utils/component/publish.js +219 -0
  96. package/lib/utils/component/query.js +23 -0
  97. package/lib/utils/date.js +14 -0
  98. package/lib/utils/execution/logs.js +86 -0
  99. package/lib/utils/integration/definition.js +101 -0
  100. package/lib/utils/integration/export.js +36 -0
  101. package/lib/utils/integration/import.js +46 -0
  102. package/lib/utils/integration/invoke.js +64 -0
  103. package/lib/utils/integration/query.js +59 -0
  104. package/lib/utils/serialize.js +8 -0
  105. package/lib/utils/user/query.js +24 -0
  106. package/lib/yeoman.js +23 -0
  107. package/oclif.manifest.json +1 -1
  108. package/package.json +48 -54
  109. package/templates/component/openapi/client.ts +11 -9
  110. package/templates/component/openapi/request.ts +6 -4
  111. package/lib/auth.js.map +0 -1
  112. package/lib/commands/alerts/events/list.js.map +0 -1
  113. package/lib/commands/alerts/groups/create.js.map +0 -1
  114. package/lib/commands/alerts/groups/delete.js.map +0 -1
  115. package/lib/commands/alerts/groups/list.js.map +0 -1
  116. package/lib/commands/alerts/monitors/clear.js.map +0 -1
  117. package/lib/commands/alerts/monitors/create.js.map +0 -1
  118. package/lib/commands/alerts/monitors/delete.js.map +0 -1
  119. package/lib/commands/alerts/monitors/list.js.map +0 -1
  120. package/lib/commands/alerts/triggers/list.js.map +0 -1
  121. package/lib/commands/alerts/webhooks/create.js.map +0 -1
  122. package/lib/commands/alerts/webhooks/delete.js.map +0 -1
  123. package/lib/commands/alerts/webhooks/list.js.map +0 -1
  124. package/lib/commands/authorization-methods/list.js.map +0 -1
  125. package/lib/commands/components/actions/list.js.map +0 -1
  126. package/lib/commands/components/delete.js.map +0 -1
  127. package/lib/commands/components/init.js +0 -224
  128. package/lib/commands/components/init.js.map +0 -1
  129. package/lib/commands/components/list.js.map +0 -1
  130. package/lib/commands/components/publish.js.map +0 -1
  131. package/lib/commands/components/triggers/list.js.map +0 -1
  132. package/lib/commands/customers/create.js.map +0 -1
  133. package/lib/commands/customers/credentials/create.js.map +0 -1
  134. package/lib/commands/customers/credentials/delete.js.map +0 -1
  135. package/lib/commands/customers/credentials/list.js.map +0 -1
  136. package/lib/commands/customers/credentials/update.js.map +0 -1
  137. package/lib/commands/customers/delete.js.map +0 -1
  138. package/lib/commands/customers/list.js.map +0 -1
  139. package/lib/commands/customers/update.js.map +0 -1
  140. package/lib/commands/customers/users/create.js.map +0 -1
  141. package/lib/commands/customers/users/delete.js.map +0 -1
  142. package/lib/commands/customers/users/list.js.map +0 -1
  143. package/lib/commands/customers/users/roles.js.map +0 -1
  144. package/lib/commands/customers/users/update.js.map +0 -1
  145. package/lib/commands/executions/step-result/get.js.map +0 -1
  146. package/lib/commands/instances/config-vars/list.js.map +0 -1
  147. package/lib/commands/instances/create.js.map +0 -1
  148. package/lib/commands/instances/delete.js.map +0 -1
  149. package/lib/commands/instances/deploy.js.map +0 -1
  150. package/lib/commands/instances/disable.js.map +0 -1
  151. package/lib/commands/instances/enable.js.map +0 -1
  152. package/lib/commands/instances/flow-configs/list.js.map +0 -1
  153. package/lib/commands/instances/flow-configs/test.js.map +0 -1
  154. package/lib/commands/instances/list.js.map +0 -1
  155. package/lib/commands/instances/update.js.map +0 -1
  156. package/lib/commands/integrations/available.js.map +0 -1
  157. package/lib/commands/integrations/create.js.map +0 -1
  158. package/lib/commands/integrations/delete.js.map +0 -1
  159. package/lib/commands/integrations/export.js.map +0 -1
  160. package/lib/commands/integrations/flows/list.js.map +0 -1
  161. package/lib/commands/integrations/flows/test.js.map +0 -1
  162. package/lib/commands/integrations/fork.js.map +0 -1
  163. package/lib/commands/integrations/import.js.map +0 -1
  164. package/lib/commands/integrations/list.js.map +0 -1
  165. package/lib/commands/integrations/publish.js.map +0 -1
  166. package/lib/commands/integrations/update.js.map +0 -1
  167. package/lib/commands/integrations/versions/index.js.map +0 -1
  168. package/lib/commands/login.js.map +0 -1
  169. package/lib/commands/logout.js.map +0 -1
  170. package/lib/commands/logs/severities/list.js.map +0 -1
  171. package/lib/commands/me/index.js.map +0 -1
  172. package/lib/commands/me/token.js.map +0 -1
  173. package/lib/commands/organization/credentials/create.js.map +0 -1
  174. package/lib/commands/organization/credentials/delete.js.map +0 -1
  175. package/lib/commands/organization/credentials/list.js.map +0 -1
  176. package/lib/commands/organization/credentials/update.js.map +0 -1
  177. package/lib/commands/organization/update.js.map +0 -1
  178. package/lib/commands/organization/updateAvatarUrl.js.map +0 -1
  179. package/lib/commands/organization/users/create.js.map +0 -1
  180. package/lib/commands/organization/users/delete.js.map +0 -1
  181. package/lib/commands/organization/users/list.js.map +0 -1
  182. package/lib/commands/organization/users/roles.js.map +0 -1
  183. package/lib/commands/organization/users/update.js.map +0 -1
  184. package/lib/config.js.map +0 -1
  185. package/lib/errors.js.map +0 -1
  186. package/lib/fields.js.map +0 -1
  187. package/lib/fs.js.map +0 -1
  188. package/lib/generate/action.js.map +0 -1
  189. package/lib/generate/client.js.map +0 -1
  190. package/lib/generate/connection.js.map +0 -1
  191. package/lib/generate/index.js.map +0 -1
  192. package/lib/generate/input.js.map +0 -1
  193. package/lib/generate/parse.js.map +0 -1
  194. package/lib/generate/sourceFile.js.map +0 -1
  195. package/lib/generate/util.js.map +0 -1
  196. package/lib/graphql.js.map +0 -1
  197. package/lib/index.js.map +0 -1
  198. package/templates/component/jest.config.js +0 -4
  199. package/templates/component/package.json +0 -24
  200. package/templates/component/src/actions.ts +0 -33
  201. package/templates/component/src/client.ts +0 -7
  202. package/templates/component/src/connections.ts +0 -25
  203. package/templates/component/src/index.test.ts +0 -32
  204. package/templates/component/src/index.ts +0 -17
  205. package/templates/component/src/triggers.ts +0 -18
  206. package/templates/component/tsconfig.json +0 -19
  207. package/templates/component/webpack.config.js +0 -44
@@ -0,0 +1,219 @@
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.uploadConnectionIcons = exports.uploadFile = exports.publishDefinition = exports.confirmPublish = exports.checkSignature = exports.createComponentPackage = exports.validateDefinition = exports.loadEntrypoint = exports.seekComponentPackageDistDirectory = void 0;
7
+ const core_1 = require("@oclif/core");
8
+ const fs_1 = require("../../fs");
9
+ const path_1 = require("path");
10
+ const tempy_1 = __importDefault(require("tempy"));
11
+ const crypto_1 = __importDefault(require("crypto"));
12
+ const archiver_1 = __importDefault(require("archiver"));
13
+ const graphql_1 = require("../../graphql");
14
+ const axios_1 = __importDefault(require("axios"));
15
+ const mime_types_1 = __importDefault(require("mime-types"));
16
+ const path_2 = require("path");
17
+ const seekComponentPackageDistDirectory = async () => {
18
+ while (!(await (0, fs_1.exists)("package.json"))) {
19
+ const tempDir = process.cwd();
20
+ process.chdir("../");
21
+ if (process.cwd() == tempDir) {
22
+ core_1.CliUx.ux.error("Failed to find 'package.json' file. Is the current path a component?", { exit: 1 });
23
+ }
24
+ }
25
+ if (!(await (0, fs_1.exists)("./dist"))) {
26
+ core_1.CliUx.ux.error("Failed to find 'dist' folder. Is the current path a component?", {
27
+ exit: 1,
28
+ });
29
+ }
30
+ process.chdir("./dist");
31
+ };
32
+ exports.seekComponentPackageDistDirectory = seekComponentPackageDistDirectory;
33
+ const loadEntrypoint = async () => {
34
+ // If we don't have an index.js in cwd seek directories to find package.json of component
35
+ if (!(await (0, fs_1.exists)("index.js"))) {
36
+ await (0, exports.seekComponentPackageDistDirectory)();
37
+ }
38
+ // If we still didn't find index.js error out
39
+ if (!(await (0, fs_1.exists)("index.js"))) {
40
+ core_1.CliUx.ux.error("Failed to find 'index.js' entrypoint file. Is the current path a component?", { exit: 1 });
41
+ }
42
+ // Require index.js and access its root-most default export which should be the Component config
43
+ const cwd = process.cwd();
44
+ const entrypointPath = (0, path_1.resolve)(cwd, "./index.js");
45
+ const { default: definition } = require(entrypointPath); // eslint-disable-line @typescript-eslint/no-var-requires
46
+ return definition;
47
+ };
48
+ exports.loadEntrypoint = loadEntrypoint;
49
+ const validateDefinition = async (definition) => {
50
+ // Output basic information to the user to confirm that this component is what they want to publish
51
+ const { display: { label, description, iconPath },
52
+ // connections,
53
+ } = definition;
54
+ if (!label || !description) {
55
+ core_1.CliUx.ux.error("Missing required values `label` or `description`. Exiting.", { exit: 1 });
56
+ }
57
+ if (iconPath && !(await (0, fs_1.exists)(iconPath))) {
58
+ core_1.CliUx.ux.error("Icon was specified (iconPath) but a file was not found at specified path. Exiting.", { exit: 1 });
59
+ }
60
+ // TODO: Check if all Connection icons exist.
61
+ };
62
+ exports.validateDefinition = validateDefinition;
63
+ const createComponentPackage = async () => {
64
+ const zip = (0, archiver_1.default)("zip", { zlib: { level: 9 } });
65
+ const pathPromise = tempy_1.default.write(zip, { extension: "zip" });
66
+ // Zip all files in the current directory (since we found the index.js entrypoint)
67
+ zip.directory(process.cwd(), false);
68
+ await zip.finalize();
69
+ return pathPromise;
70
+ };
71
+ exports.createComponentPackage = createComponentPackage;
72
+ const checkSignature = async ({ key }, packagePath) => {
73
+ // Retrieve the existing signature of the component if it exists.
74
+ const result = await (0, graphql_1.gqlRequest)({
75
+ document: (0, graphql_1.gql) `
76
+ query component($key: String!) {
77
+ components(key: $key) {
78
+ nodes {
79
+ signature
80
+ }
81
+ }
82
+ }
83
+ `,
84
+ variables: {
85
+ key,
86
+ },
87
+ });
88
+ const { components: { nodes: [{ signature: existingSignature } = { signature: null }], }, } = result;
89
+ // Generate the signature of the package so we may compare it against the existing one.
90
+ const packageSignature = crypto_1.default
91
+ .createHash("sha1")
92
+ .update(await fs_1.fs.readFile(packagePath))
93
+ .digest("hex");
94
+ return existingSignature === packageSignature;
95
+ };
96
+ exports.checkSignature = checkSignature;
97
+ const confirmPublish = async ({ display: { label, description } }, confirm = true) => {
98
+ if (!confirm)
99
+ return;
100
+ core_1.CliUx.ux.log(label, "-", description);
101
+ const continuePublish = await core_1.CliUx.ux.confirm(`Would you like to publish ${label}? (y/N)`);
102
+ if (!continuePublish)
103
+ core_1.CliUx.ux.exit(0);
104
+ };
105
+ exports.confirmPublish = confirmPublish;
106
+ const publishDefinition = async ({ actions, triggers, connections, ...rest }, comment) => {
107
+ // FIXME: Ideally we should just pass the entire configuration blob but Graphene can't represent
108
+ // a dictionary having arbitrary keys. For now, split actions and triggers out.
109
+ const actionDefinitions = Object.values(actions || {}).map((action) => {
110
+ return {
111
+ ...action,
112
+ examplePayload: (action === null || action === void 0 ? void 0 : action.examplePayload)
113
+ ? JSON.stringify(action === null || action === void 0 ? void 0 : action.examplePayload)
114
+ : JSON.stringify({}),
115
+ };
116
+ });
117
+ const triggerDefinitions = Object.values(triggers || {}).map((trigger) => {
118
+ return {
119
+ ...trigger,
120
+ examplePayload: (trigger === null || trigger === void 0 ? void 0 : trigger.examplePayload)
121
+ ? JSON.stringify(trigger === null || trigger === void 0 ? void 0 : trigger.examplePayload)
122
+ : JSON.stringify({}),
123
+ };
124
+ });
125
+ const connectionDefinitions = connections || [];
126
+ // Initiate start of the publish procedure by sending config data and receive back presigned s3 URL
127
+ const result = await (0, graphql_1.gqlRequest)({
128
+ document: (0, graphql_1.gql) `
129
+ mutation publishComponent(
130
+ $definition: ComponentDefinitionInput!
131
+ $actions: [ActionDefinitionInput]!
132
+ $triggers: [TriggerDefinitionInput]
133
+ $connections: [ConnectionDefinitionInput]
134
+ $comment: String
135
+ ) {
136
+ publishComponent(
137
+ input: {
138
+ definition: $definition
139
+ actions: $actions
140
+ triggers: $triggers
141
+ connections: $connections
142
+ comment: $comment
143
+ }
144
+ ) {
145
+ publishResult {
146
+ component {
147
+ id
148
+ versionNumber
149
+ }
150
+ iconUploadUrl
151
+ packageUploadUrl
152
+ connectionIconUploadUrls {
153
+ connectionKey
154
+ iconUploadUrl
155
+ }
156
+ }
157
+ errors {
158
+ field
159
+ messages
160
+ }
161
+ }
162
+ }
163
+ `,
164
+ variables: {
165
+ definition: rest,
166
+ actions: actionDefinitions,
167
+ triggers: triggerDefinitions,
168
+ connections: connectionDefinitions,
169
+ comment,
170
+ },
171
+ });
172
+ const { iconUploadUrl, packageUploadUrl, connectionIconUploadUrls, component: { versionNumber }, } = result.publishComponent.publishResult;
173
+ const uploadUrls = connectionIconUploadUrls.reduce((result, { connectionKey, iconUploadUrl }) => ({
174
+ ...result,
175
+ [connectionKey]: iconUploadUrl,
176
+ }), {});
177
+ return {
178
+ iconUploadUrl,
179
+ packageUploadUrl,
180
+ connectionIconUploadUrls: uploadUrls,
181
+ versionNumber,
182
+ };
183
+ };
184
+ exports.publishDefinition = publishDefinition;
185
+ const uploadFile = async (filePath, destinationUrl) => {
186
+ try {
187
+ // TODO: Stream instead of Buffer.
188
+ const response = await axios_1.default.put(destinationUrl, await fs_1.fs.readFile(filePath), { headers: { "Content-Type": mime_types_1.default.contentType((0, path_2.extname)(filePath)) } });
189
+ return response;
190
+ }
191
+ catch (error) {
192
+ if (axios_1.default.isAxiosError(error)) {
193
+ const { message } = error;
194
+ throw new Error(message);
195
+ }
196
+ throw error;
197
+ }
198
+ };
199
+ exports.uploadFile = uploadFile;
200
+ const uploadConnectionIcons = async ({ connections }, connectionIconUploadUrls) => {
201
+ if (!connections ||
202
+ !connections.length ||
203
+ !connectionIconUploadUrls ||
204
+ !Object.keys(connectionIconUploadUrls).length) {
205
+ return;
206
+ }
207
+ const iconPaths = connections.reduce((result, { key, iconPath }) => {
208
+ if (!iconPath) {
209
+ return result;
210
+ }
211
+ return {
212
+ ...result,
213
+ [key]: iconPath,
214
+ };
215
+ }, {});
216
+ const promises = Object.entries(connectionIconUploadUrls).map(async ([connectionKey, uploadUrl]) => (0, exports.uploadFile)(iconPaths[connectionKey], uploadUrl));
217
+ await Promise.all(promises);
218
+ };
219
+ exports.uploadConnectionIcons = uploadConnectionIcons;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.queryComponentKeys = void 0;
4
+ const graphql_1 = require("../../graphql");
5
+ const queryComponentKeys = async (keys) => {
6
+ const result = await (0, graphql_1.gqlRequest)({
7
+ document: (0, graphql_1.gql) `
8
+ query components($keys: [String]!) {
9
+ components(key_In: $keys) {
10
+ nodes {
11
+ id
12
+ key
13
+ versionNumber
14
+ public
15
+ }
16
+ }
17
+ }
18
+ `,
19
+ variables: { keys },
20
+ });
21
+ return result.components.nodes;
22
+ };
23
+ exports.queryComponentKeys = queryComponentKeys;
@@ -0,0 +1,14 @@
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.formatTimestamp = void 0;
7
+ const dayjs_1 = __importDefault(require("dayjs"));
8
+ const utc_1 = __importDefault(require("dayjs/plugin/utc"));
9
+ const timezone_1 = __importDefault(require("dayjs/plugin/timezone"));
10
+ dayjs_1.default.extend(utc_1.default);
11
+ dayjs_1.default.extend(timezone_1.default);
12
+ const formatTimestamp = (timestamp) => (0, dayjs_1.default)(timestamp, "YYYY-MM-DDTHH:mm:ss.SSS000+Z", true).format("HH:mm:ss.SSS");
13
+ exports.formatTimestamp = formatTimestamp;
14
+ exports.default = dayjs_1.default;
@@ -0,0 +1,86 @@
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.displayLogs = exports.waitForExecutionCompletion = void 0;
7
+ const core_1 = require("@oclif/core");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const date_1 = require("../date");
10
+ const graphql_1 = require("../../graphql");
11
+ const util_1 = require("util");
12
+ const setTimeoutPromise = (0, util_1.promisify)(setTimeout);
13
+ const waitForExecutionCompletion = (executionId) => {
14
+ return new Promise((resolve, reject) => {
15
+ const interval = setInterval(async () => {
16
+ try {
17
+ const result = await (0, graphql_1.gqlRequest)({
18
+ document: (0, graphql_1.gql) `
19
+ query pollExecution($executionId: ID!) {
20
+ executionResult(id: $executionId) {
21
+ endedAt
22
+ }
23
+ }
24
+ `,
25
+ variables: { executionId },
26
+ });
27
+ const { endedAt } = result.executionResult;
28
+ if (endedAt) {
29
+ clearInterval(interval);
30
+ // Grace period to let logs finish flowing; logs are fully async and are
31
+ // not guaranteed to be added in chronological order.
32
+ await setTimeoutPromise(1000);
33
+ resolve();
34
+ }
35
+ }
36
+ catch (error) {
37
+ clearInterval(interval);
38
+ reject(error);
39
+ }
40
+ }, 1000);
41
+ });
42
+ };
43
+ exports.waitForExecutionCompletion = waitForExecutionCompletion;
44
+ const displayLogs = async (executionId) => {
45
+ await (0, exports.waitForExecutionCompletion)(executionId);
46
+ // TODO: Add paging
47
+ const result = await (0, graphql_1.gqlRequest)({
48
+ document: (0, graphql_1.gql) `
49
+ query logs($executionId: ID!) {
50
+ executionResult(id: $executionId) {
51
+ logs(orderBy: { field: TIMESTAMP, direction: ASC }) {
52
+ nodes {
53
+ timestamp
54
+ severity
55
+ message
56
+ }
57
+ }
58
+ }
59
+ }
60
+ `,
61
+ variables: { executionId },
62
+ });
63
+ const logs = result.executionResult.logs.nodes;
64
+ core_1.CliUx.ux.table(logs, {
65
+ timestamp: {
66
+ get: ({ timestamp }) => (0, date_1.formatTimestamp)(timestamp),
67
+ },
68
+ severity: {
69
+ minWidth: 12,
70
+ get: ({ severity }) => {
71
+ if (severity == "INFO") {
72
+ return chalk_1.default.blue("info");
73
+ }
74
+ if (severity == "WARN") {
75
+ return chalk_1.default.yellow("warn");
76
+ }
77
+ if (severity == "ERROR") {
78
+ return chalk_1.default.red("error");
79
+ }
80
+ return severity.toLowerCase();
81
+ },
82
+ },
83
+ message: {},
84
+ }, { "no-header": true });
85
+ };
86
+ exports.displayLogs = displayLogs;
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildComponentTestHarnessIntegration = exports.defaultDefinition = exports.buildStep = exports.buildConnectionConfigVar = exports.componentTestIntegrationName = void 0;
4
+ const serialize_1 = require("../serialize");
5
+ const lodash_1 = require("lodash");
6
+ const export_1 = require("./export");
7
+ const componentTestIntegrationName = (componentKey, name) => `Component Test Harness - ${componentKey} - ${name}`;
8
+ exports.componentTestIntegrationName = componentTestIntegrationName;
9
+ const buildConnectionConfigVar = ({ key: componentKey, isPublic }, { key, values }) => {
10
+ return {
11
+ key: "testConnection",
12
+ description: "Test Connection",
13
+ dataType: "connection",
14
+ connection: {
15
+ component: {
16
+ key: componentKey,
17
+ isPublic,
18
+ version: "LATEST",
19
+ },
20
+ key,
21
+ },
22
+ inputs: values,
23
+ };
24
+ };
25
+ exports.buildConnectionConfigVar = buildConnectionConfigVar;
26
+ const buildStep = ({ key: componentKey, isPublic }, { key, values }) => {
27
+ return {
28
+ name: "Test Step",
29
+ action: {
30
+ component: {
31
+ key: componentKey,
32
+ isPublic,
33
+ version: "LATEST",
34
+ },
35
+ key,
36
+ },
37
+ inputs: values,
38
+ };
39
+ };
40
+ exports.buildStep = buildStep;
41
+ const defaultDefinition = ({ integrationInfo: { name: integrationName }, componentInfo, actionInfo, connectionInfo, }) => {
42
+ const requiredConfigVars = connectionInfo
43
+ ? [(0, exports.buildConnectionConfigVar)(componentInfo, connectionInfo)]
44
+ : [];
45
+ const { key: componentKey } = componentInfo;
46
+ const definition = {
47
+ definitionVersion: 6,
48
+ name: integrationName,
49
+ description: `Test Harness for the ${componentKey} Component`,
50
+ category: "Component Development",
51
+ requiredConfigVars,
52
+ flows: [
53
+ {
54
+ name: "Flow 1",
55
+ steps: [
56
+ {
57
+ name: "Trigger",
58
+ isTrigger: true,
59
+ action: {
60
+ component: {
61
+ key: "webhook-triggers",
62
+ isPublic: true,
63
+ version: "LATEST",
64
+ },
65
+ key: "webhook",
66
+ },
67
+ },
68
+ (0, exports.buildStep)(componentInfo, actionInfo),
69
+ ],
70
+ },
71
+ ],
72
+ };
73
+ return definition;
74
+ };
75
+ exports.defaultDefinition = defaultDefinition;
76
+ const buildComponentTestHarnessIntegration = async (info) => {
77
+ var _a, _b;
78
+ const { integrationInfo: { id: integrationId }, componentInfo, actionInfo, connectionInfo, } = info;
79
+ const definition = integrationId
80
+ ? await (0, export_1.exportDefinition)({ integrationId })
81
+ : (0, exports.defaultDefinition)(info);
82
+ // Update "current definition" accordingly.
83
+ if (connectionInfo) {
84
+ const connection = (0, exports.buildConnectionConfigVar)(componentInfo, connectionInfo);
85
+ const existingConnection = (_b = (_a = definition.requiredConfigVars) === null || _a === void 0 ? void 0 : _a.filter(({ key }) => key === "testConnection")) === null || _b === void 0 ? void 0 : _b[0];
86
+ if (existingConnection) {
87
+ (0, lodash_1.merge)(existingConnection, connection);
88
+ }
89
+ else if (definition.requiredConfigVars) {
90
+ definition.requiredConfigVars.push(connection);
91
+ }
92
+ else {
93
+ definition.requiredConfigVars = [connection];
94
+ }
95
+ }
96
+ const step = (0, exports.buildStep)(componentInfo, actionInfo);
97
+ const existingStep = definition.flows[0].steps.filter(({ name }) => name === "Test Step")[0];
98
+ (0, lodash_1.merge)(existingStep, step);
99
+ return (0, serialize_1.dumpYaml)(definition);
100
+ };
101
+ exports.buildComponentTestHarnessIntegration = buildComponentTestHarnessIntegration;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.exportDefinition = exports.INTEGRATION_DEFINITION_VERSION = void 0;
4
+ const graphql_1 = require("../../graphql");
5
+ const serialize_1 = require("../serialize");
6
+ /** The version of the Integration definition to request.
7
+ * It's important to request a version that corresponds with the
8
+ * feature set in this version.
9
+ */
10
+ exports.INTEGRATION_DEFINITION_VERSION = 6;
11
+ const exportDefinition = async ({ integrationId, latestComponents = false, definitionVersion = exports.INTEGRATION_DEFINITION_VERSION, }) => {
12
+ const result = await (0, graphql_1.gqlRequest)({
13
+ document: (0, graphql_1.gql) `
14
+ query export(
15
+ $id: ID!
16
+ $version: Int!
17
+ $useLatestComponentVersions: Boolean!
18
+ ) {
19
+ integration(id: $id) {
20
+ definition(
21
+ version: $version
22
+ useLatestComponentVersions: $useLatestComponentVersions
23
+ )
24
+ }
25
+ }
26
+ `,
27
+ variables: {
28
+ id: integrationId,
29
+ version: definitionVersion,
30
+ useLatestComponentVersions: latestComponents,
31
+ },
32
+ });
33
+ const definition = result.integration.definition;
34
+ return (0, serialize_1.loadYaml)(definition);
35
+ };
36
+ exports.exportDefinition = exportDefinition;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.importDefinition = void 0;
4
+ const graphql_1 = require("../../graphql");
5
+ const importDefinition = async (definition, integrationId) => {
6
+ const result = await (0, graphql_1.gqlRequest)({
7
+ document: (0, graphql_1.gql) `
8
+ mutation importIntegration($definition: String!, $integrationId: ID) {
9
+ importIntegration(
10
+ input: { definition: $definition, integrationId: $integrationId }
11
+ ) {
12
+ integration {
13
+ id
14
+ flows {
15
+ nodes {
16
+ id
17
+ name
18
+ }
19
+ }
20
+ testConfigVariables(status: "pending") {
21
+ nodes {
22
+ id
23
+ authorizeUrl
24
+ }
25
+ }
26
+ }
27
+ errors {
28
+ field
29
+ messages
30
+ }
31
+ }
32
+ }
33
+ `,
34
+ variables: {
35
+ definition,
36
+ integrationId,
37
+ },
38
+ });
39
+ const integration = result.importIntegration.integration;
40
+ return {
41
+ integrationId: integration.id,
42
+ flows: integration.flows.nodes,
43
+ pendingAuthorizations: integration.testConfigVariables.nodes.map(({ id, authorizeUrl: url }) => ({ id, url })),
44
+ };
45
+ };
46
+ exports.importDefinition = importDefinition;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runIntegrationFlow = exports.getIntegrationFlow = void 0;
4
+ const graphql_1 = require("../../graphql");
5
+ /** Return Flow ID of given flow name on specified Integration. */
6
+ const getIntegrationFlow = async (integrationId, flowName) => {
7
+ // TODO: Make flows searchable by name.
8
+ const result = await (0, graphql_1.gqlRequest)({
9
+ document: (0, graphql_1.gql) `
10
+ query flowId($integrationID: ID!) {
11
+ integration(id: $id) {
12
+ flows {
13
+ nodes {
14
+ id
15
+ name
16
+ }
17
+ }
18
+ }
19
+ }
20
+ `,
21
+ variables: { integrationID: integrationId },
22
+ });
23
+ const integration = result.integration;
24
+ const flows = integration.flows.nodes
25
+ .map(({ id, name }) => ({
26
+ id,
27
+ name: name.toLowerCase().trim(),
28
+ }))
29
+ .filter(({ name }) => name === flowName);
30
+ if (flows.length > 1) {
31
+ throw new Error(`Found more than one result for Flow name: ${flowName}`);
32
+ }
33
+ if (flows.length === 0) {
34
+ throw new Error(`Failed to find a Flow with the given name: ${flowName}`);
35
+ }
36
+ return flows[0].id;
37
+ };
38
+ exports.getIntegrationFlow = getIntegrationFlow;
39
+ const runIntegrationFlow = async ({ integrationId, flowId, flowName, }) => {
40
+ const integrationFlowId = flowName
41
+ ? await (0, exports.getIntegrationFlow)(integrationId, flowName)
42
+ : flowId;
43
+ const result = await (0, graphql_1.gqlRequest)({
44
+ document: (0, graphql_1.gql) `
45
+ mutation testIntegrationFlow($id: ID!) {
46
+ testIntegrationFlow(input: { id: $id }) {
47
+ testIntegrationFlowResult {
48
+ execution {
49
+ id
50
+ }
51
+ }
52
+ errors {
53
+ field
54
+ messages
55
+ }
56
+ }
57
+ }
58
+ `,
59
+ variables: { id: integrationFlowId },
60
+ });
61
+ const executionId = result.testIntegrationFlow.testIntegrationFlowResult.execution.id;
62
+ return { executionId };
63
+ };
64
+ exports.runIntegrationFlow = runIntegrationFlow;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pollForActiveConfigVarState = exports.integrationByName = void 0;
4
+ const graphql_1 = require("../../graphql");
5
+ const integrationByName = async (name) => {
6
+ const result = await (0, graphql_1.gqlRequest)({
7
+ document: (0, graphql_1.gql) `
8
+ query integration($name: String!) {
9
+ integrations(name: $name) {
10
+ nodes {
11
+ id
12
+ }
13
+ }
14
+ }
15
+ `,
16
+ variables: { name },
17
+ });
18
+ const [integration, ...rest] = result.integrations.nodes;
19
+ if (rest.length !== 0) {
20
+ throw new Error(`Found more than one Integration with name: ${name}`);
21
+ }
22
+ return integration;
23
+ };
24
+ exports.integrationByName = integrationByName;
25
+ const pollForActiveConfigVarState = async (integrationId, configVarId) => {
26
+ return new Promise((resolve, reject) => {
27
+ const interval = setInterval(async () => {
28
+ try {
29
+ const result = await (0, graphql_1.gqlRequest)({
30
+ document: (0, graphql_1.gql) `
31
+ query state($integrationId: ID!) {
32
+ integration(id: $integrationId) {
33
+ testConfigVariables(status_In: ["pending", "active", "error"]) {
34
+ nodes {
35
+ id
36
+ status
37
+ }
38
+ }
39
+ }
40
+ }
41
+ `,
42
+ variables: { integrationId },
43
+ });
44
+ const testConfigVariables = result.integration.testConfigVariables.nodes;
45
+ const [{ status: serverStatus }] = testConfigVariables.filter(({ id }) => id === configVarId);
46
+ const status = serverStatus.toLowerCase();
47
+ if (status !== "pending") {
48
+ clearInterval(interval);
49
+ resolve(status === "active");
50
+ }
51
+ }
52
+ catch (error) {
53
+ clearInterval(interval);
54
+ reject(error);
55
+ }
56
+ }, 5000);
57
+ });
58
+ };
59
+ exports.pollForActiveConfigVarState = pollForActiveConfigVarState;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadYaml = exports.dumpYaml = void 0;
4
+ const js_yaml_1 = require("js-yaml");
5
+ const dumpYaml = (value, extraOptions) => (0, js_yaml_1.dump)(value, { ...extraOptions, noRefs: true });
6
+ exports.dumpYaml = dumpYaml;
7
+ const loadYaml = (value, extraOptions) => (0, js_yaml_1.load)(value, { ...extraOptions });
8
+ exports.loadYaml = loadYaml;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.whoAmI = void 0;
4
+ const graphql_1 = require("../../graphql");
5
+ const whoAmI = async () => {
6
+ const { authenticatedUser } = await (0, graphql_1.gqlRequest)({
7
+ document: (0, graphql_1.gql) `
8
+ query whoami {
9
+ authenticatedUser {
10
+ name
11
+ email
12
+ org {
13
+ name
14
+ }
15
+ customer {
16
+ name
17
+ }
18
+ }
19
+ }
20
+ `,
21
+ });
22
+ return authenticatedUser;
23
+ };
24
+ exports.whoAmI = whoAmI;