@factorialco/fcode-cli 1.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 (234) hide show
  1. package/README.md +1021 -0
  2. package/bin/dev +17 -0
  3. package/bin/dev.cmd +3 -0
  4. package/bin/run +7 -0
  5. package/bin/run.cmd +3 -0
  6. package/dist/commands/add.d.ts +6 -0
  7. package/dist/commands/add.js +22 -0
  8. package/dist/commands/clone.d.ts +26 -0
  9. package/dist/commands/clone.js +177 -0
  10. package/dist/commands/dependencies/add.d.ts +9 -0
  11. package/dist/commands/dependencies/add.js +13 -0
  12. package/dist/commands/dependencies/install.d.ts +14 -0
  13. package/dist/commands/dependencies/install.js +44 -0
  14. package/dist/commands/dependencies/pull.d.ts +12 -0
  15. package/dist/commands/dependencies/pull.js +14 -0
  16. package/dist/commands/dependencies/push.d.ts +12 -0
  17. package/dist/commands/dependencies/push.js +14 -0
  18. package/dist/commands/dependencies/reset.d.ts +9 -0
  19. package/dist/commands/dependencies/reset.js +13 -0
  20. package/dist/commands/dependencies/status.d.ts +9 -0
  21. package/dist/commands/dependencies/status.js +13 -0
  22. package/dist/commands/http.d.ts +22 -0
  23. package/dist/commands/http.js +272 -0
  24. package/dist/commands/login.d.ts +18 -0
  25. package/dist/commands/login.js +62 -0
  26. package/dist/commands/logout.d.ts +10 -0
  27. package/dist/commands/logout.js +34 -0
  28. package/dist/commands/modules/add.d.ts +9 -0
  29. package/dist/commands/modules/add.js +13 -0
  30. package/dist/commands/modules/pull.d.ts +13 -0
  31. package/dist/commands/modules/pull.js +43 -0
  32. package/dist/commands/modules/push.d.ts +13 -0
  33. package/dist/commands/modules/push.js +35 -0
  34. package/dist/commands/modules/remove.d.ts +9 -0
  35. package/dist/commands/modules/remove.js +19 -0
  36. package/dist/commands/modules/reset.d.ts +9 -0
  37. package/dist/commands/modules/reset.js +13 -0
  38. package/dist/commands/modules/status.d.ts +11 -0
  39. package/dist/commands/modules/status.js +40 -0
  40. package/dist/commands/pre-debug.d.ts +20 -0
  41. package/dist/commands/pre-debug.js +120 -0
  42. package/dist/commands/process-metadata.d.ts +18 -0
  43. package/dist/commands/process-metadata.js +63 -0
  44. package/dist/commands/processes/add.d.ts +9 -0
  45. package/dist/commands/processes/add.js +13 -0
  46. package/dist/commands/processes/install-dependencies.d.ts +14 -0
  47. package/dist/commands/processes/install-dependencies.js +30 -0
  48. package/dist/commands/processes/pull.d.ts +13 -0
  49. package/dist/commands/processes/pull.js +47 -0
  50. package/dist/commands/processes/push.d.ts +13 -0
  51. package/dist/commands/processes/push.js +39 -0
  52. package/dist/commands/processes/remove.d.ts +9 -0
  53. package/dist/commands/processes/remove.js +19 -0
  54. package/dist/commands/processes/reset.d.ts +9 -0
  55. package/dist/commands/processes/reset.js +13 -0
  56. package/dist/commands/processes/status.d.ts +11 -0
  57. package/dist/commands/processes/status.js +58 -0
  58. package/dist/commands/pull.d.ts +9 -0
  59. package/dist/commands/pull.js +32 -0
  60. package/dist/commands/push.d.ts +9 -0
  61. package/dist/commands/push.js +29 -0
  62. package/dist/commands/remote/add.d.ts +10 -0
  63. package/dist/commands/remote/add.js +32 -0
  64. package/dist/commands/remote/list.d.ts +7 -0
  65. package/dist/commands/remote/list.js +33 -0
  66. package/dist/commands/remote/set.d.ts +10 -0
  67. package/dist/commands/remote/set.js +28 -0
  68. package/dist/commands/reset.d.ts +6 -0
  69. package/dist/commands/reset.js +19 -0
  70. package/dist/commands/run.d.ts +16 -0
  71. package/dist/commands/run.js +56 -0
  72. package/dist/commands/runtime-env.d.ts +12 -0
  73. package/dist/commands/runtime-env.js +42 -0
  74. package/dist/commands/settings/get.d.ts +12 -0
  75. package/dist/commands/settings/get.js +67 -0
  76. package/dist/commands/settings/remove.d.ts +9 -0
  77. package/dist/commands/settings/remove.js +35 -0
  78. package/dist/commands/settings/set.d.ts +10 -0
  79. package/dist/commands/settings/set.js +39 -0
  80. package/dist/commands/setup-debug.d.ts +12 -0
  81. package/dist/commands/setup-debug.js +118 -0
  82. package/dist/commands/status.d.ts +6 -0
  83. package/dist/commands/status.js +22 -0
  84. package/dist/commands/team/pull.d.ts +8 -0
  85. package/dist/commands/team/pull.js +23 -0
  86. package/dist/commands/team/push.d.ts +11 -0
  87. package/dist/commands/team/push.js +41 -0
  88. package/dist/commands/team/status.d.ts +8 -0
  89. package/dist/commands/team/status.js +40 -0
  90. package/dist/commands/test/scaffold.d.ts +9 -0
  91. package/dist/commands/test/scaffold.js +61 -0
  92. package/dist/commands/test.d.ts +13 -0
  93. package/dist/commands/test.js +72 -0
  94. package/dist/commands/variables/add.d.ts +12 -0
  95. package/dist/commands/variables/add.js +21 -0
  96. package/dist/commands/variables/pull.d.ts +12 -0
  97. package/dist/commands/variables/pull.js +14 -0
  98. package/dist/commands/variables/push.d.ts +12 -0
  99. package/dist/commands/variables/push.js +14 -0
  100. package/dist/commands/variables/remove.d.ts +9 -0
  101. package/dist/commands/variables/remove.js +19 -0
  102. package/dist/commands/variables/reset.d.ts +9 -0
  103. package/dist/commands/variables/reset.js +13 -0
  104. package/dist/commands/variables/status.d.ts +12 -0
  105. package/dist/commands/variables/status.js +58 -0
  106. package/dist/config/global.d.ts +15 -0
  107. package/dist/config/global.js +77 -0
  108. package/dist/config/index.d.ts +14 -0
  109. package/dist/config/index.js +44 -0
  110. package/dist/config/remote.d.ts +15 -0
  111. package/dist/config/remote.js +60 -0
  112. package/dist/config/settings.d.ts +16 -0
  113. package/dist/config/settings.js +54 -0
  114. package/dist/config/workspace.d.ts +28 -0
  115. package/dist/config/workspace.js +158 -0
  116. package/dist/core/commands/api-client-command.d.ts +6 -0
  117. package/dist/core/commands/api-client-command.js +30 -0
  118. package/dist/core/commands/base-command.d.ts +11 -0
  119. package/dist/core/commands/base-command.js +61 -0
  120. package/dist/core/commands/dependency-command.d.ts +5 -0
  121. package/dist/core/commands/dependency-command.js +16 -0
  122. package/dist/core/commands/modules-command.d.ts +7 -0
  123. package/dist/core/commands/modules-command.js +18 -0
  124. package/dist/core/commands/processes-command.d.ts +8 -0
  125. package/dist/core/commands/processes-command.js +27 -0
  126. package/dist/core/commands/resource-command.d.ts +24 -0
  127. package/dist/core/commands/resource-command.js +92 -0
  128. package/dist/core/commands/variables-command.d.ts +5 -0
  129. package/dist/core/commands/variables-command.js +16 -0
  130. package/dist/core/dependencies/env-dependencies-command.d.ts +19 -0
  131. package/dist/core/dependencies/env-dependencies-command.js +70 -0
  132. package/dist/core/dependencies/env-process-dependencies-command.d.ts +15 -0
  133. package/dist/core/dependencies/env-process-dependencies-command.js +78 -0
  134. package/dist/core/dependencies/javascript-env-dependencies.d.ts +8 -0
  135. package/dist/core/dependencies/javascript-env-dependencies.js +77 -0
  136. package/dist/core/dependencies/python-env-dependencies.d.ts +9 -0
  137. package/dist/core/dependencies/python-env-dependencies.js +91 -0
  138. package/dist/core/errors.d.ts +55 -0
  139. package/dist/core/errors.js +144 -0
  140. package/dist/core/executors/execution-task.d.ts +29 -0
  141. package/dist/core/executors/execution-task.js +139 -0
  142. package/dist/core/executors/javascript-execution-task.d.ts +13 -0
  143. package/dist/core/executors/javascript-execution-task.js +618 -0
  144. package/dist/core/executors/python/context.d.ts +2 -0
  145. package/dist/core/executors/python/context.js +3 -0
  146. package/dist/core/executors/python/datastore.d.ts +2 -0
  147. package/dist/core/executors/python/datastore.js +4 -0
  148. package/dist/core/executors/python-execution-task.d.ts +11 -0
  149. package/dist/core/executors/python-execution-task.js +173 -0
  150. package/dist/core/executors/source-code-sanitizer.d.ts +4 -0
  151. package/dist/core/executors/source-code-sanitizer.js +45 -0
  152. package/dist/core/resource-merger.d.ts +14 -0
  153. package/dist/core/resource-merger.js +155 -0
  154. package/dist/core/resource-pusher.d.ts +12 -0
  155. package/dist/core/resource-pusher.js +133 -0
  156. package/dist/core/resource-repository.d.ts +8 -0
  157. package/dist/core/resource-repository.js +2 -0
  158. package/dist/core/types.d.ts +290 -0
  159. package/dist/core/types.js +238 -0
  160. package/dist/core/utils/dependencies.d.ts +5 -0
  161. package/dist/core/utils/dependencies.js +82 -0
  162. package/dist/core/utils/variables.d.ts +4 -0
  163. package/dist/core/utils/variables.js +10 -0
  164. package/dist/hooks/init/auth.d.ts +3 -0
  165. package/dist/hooks/init/auth.js +28 -0
  166. package/dist/hooks/init/update.d.ts +3 -0
  167. package/dist/hooks/init/update.js +42 -0
  168. package/dist/index.d.ts +1 -0
  169. package/dist/index.js +4 -0
  170. package/dist/repositories/process.d.ts +36 -0
  171. package/dist/repositories/process.js +339 -0
  172. package/dist/repositories/programming-language-manifest.d.ts +17 -0
  173. package/dist/repositories/programming-language-manifest.js +95 -0
  174. package/dist/repositories/resource.d.ts +29 -0
  175. package/dist/repositories/resource.js +79 -0
  176. package/dist/repositories/script-library.d.ts +28 -0
  177. package/dist/repositories/script-library.js +164 -0
  178. package/dist/repositories/team.d.ts +23 -0
  179. package/dist/repositories/team.js +74 -0
  180. package/dist/repositories/variable.d.ts +26 -0
  181. package/dist/repositories/variable.js +174 -0
  182. package/dist/runtime/executor.js +87 -0
  183. package/dist/runtime/executor.py +81 -0
  184. package/dist/runtime/libs/node/fcode/index.js +1 -0
  185. package/dist/runtime/libs/python/fcode/__init__.py +75 -0
  186. package/dist/runtime/libs/python/fcode/context.py +98 -0
  187. package/dist/runtime/libs/python/fcode/datastore.py +35 -0
  188. package/dist/runtime/libs/python/fcode/schedule.py +45 -0
  189. package/dist/runtime/libs/python/fcode/storage.py +271 -0
  190. package/dist/runtime/libs/python/fcode/variables.py +102 -0
  191. package/dist/services/auth-service.d.ts +12 -0
  192. package/dist/services/auth-service.js +114 -0
  193. package/dist/services/credential-prompter.d.ts +6 -0
  194. package/dist/services/credential-prompter.js +60 -0
  195. package/dist/services/fcode-graphql-client.d.ts +45 -0
  196. package/dist/services/fcode-graphql-client.js +721 -0
  197. package/dist/services/http-server.d.ts +3 -0
  198. package/dist/services/http-server.js +17 -0
  199. package/dist/services/oauth-browser-service.d.ts +9 -0
  200. package/dist/services/oauth-browser-service.js +164 -0
  201. package/dist/services/process-parameters-sampler.d.ts +2 -0
  202. package/dist/services/process-parameters-sampler.js +41 -0
  203. package/dist/services/process-runner.d.ts +22 -0
  204. package/dist/services/process-runner.js +97 -0
  205. package/dist/services/resource-checker.d.ts +8 -0
  206. package/dist/services/resource-checker.js +82 -0
  207. package/dist/services/test-runner.d.ts +17 -0
  208. package/dist/services/test-runner.js +228 -0
  209. package/dist/utils/canonical-hash.d.ts +9 -0
  210. package/dist/utils/canonical-hash.js +30 -0
  211. package/dist/utils/cli/index.d.ts +14 -0
  212. package/dist/utils/cli/index.js +50 -0
  213. package/dist/utils/cli/screen.d.ts +2 -0
  214. package/dist/utils/cli/screen.js +25 -0
  215. package/dist/utils/cli/styled/table.d.ts +23 -0
  216. package/dist/utils/cli/styled/table.js +272 -0
  217. package/dist/utils/colorize-resource.d.ts +1 -0
  218. package/dist/utils/colorize-resource.js +7 -0
  219. package/dist/utils/env-utils.d.ts +2 -0
  220. package/dist/utils/env-utils.js +16 -0
  221. package/dist/utils/file-utils.d.ts +11 -0
  222. package/dist/utils/file-utils.js +33 -0
  223. package/dist/utils/filenamify.d.ts +4 -0
  224. package/dist/utils/filenamify.js +73 -0
  225. package/dist/utils/gitignore.d.ts +17 -0
  226. package/dist/utils/gitignore.js +60 -0
  227. package/dist/utils/promise.d.ts +4 -0
  228. package/dist/utils/promise.js +38 -0
  229. package/dist/utils/url-utils.d.ts +2 -0
  230. package/dist/utils/url-utils.js +10 -0
  231. package/dist/utils/variable-warnings.d.ts +8 -0
  232. package/dist/utils/variable-warnings.js +38 -0
  233. package/oclif.manifest.json +1783 -0
  234. package/package.json +129 -0
@@ -0,0 +1,721 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const graphql_request_1 = require("graphql-request");
4
+ const types_1 = require("../core/types");
5
+ const _ = require("lodash");
6
+ // Shared process selection so pull queries and push mutations return the same
7
+ // fields, keeping mapProcess (and therefore contentHash) consistent.
8
+ const PROCESS_FIELDS = `
9
+ id
10
+ slug
11
+ name
12
+ description
13
+ tags
14
+ resolvingTeamSlug
15
+ script {
16
+ parametersSchema
17
+ sourceCode
18
+ programmingLanguage
19
+ }
20
+ readme
21
+ triggers {
22
+ webhook {
23
+ enabled
24
+ auth {
25
+ basicAuth {
26
+ username
27
+ password
28
+ expression {
29
+ username
30
+ password
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
36
+ manifest {
37
+ dependencies {
38
+ name
39
+ semVer
40
+ gitUrl
41
+ }
42
+ }
43
+ settings {
44
+ formSettings {
45
+ enabled
46
+ }
47
+ publicationConfig {
48
+ isPublic
49
+ }
50
+ dependencies {
51
+ scopedToProcess
52
+ }
53
+ }
54
+ `;
55
+ const NETWORK_ERROR_CODES = ['ECONNREFUSED', 'ENOTFOUND', 'ECONNRESET', 'ETIMEDOUT', 'EAI_AGAIN'];
56
+ class FcodeGraphQLClient {
57
+ constructor(options) {
58
+ if (!options.url) {
59
+ throw new Error('FcodeGraphQLClient needs the url.');
60
+ }
61
+ if (!options.accessToken) {
62
+ throw new Error('FcodeGraphQLClient needs the accessToken to authenticate.');
63
+ }
64
+ this.teamSlug = options.teamSlug;
65
+ this.url = options.url;
66
+ this.client = new graphql_request_1.GraphQLClient(`${options.url}/api/graphql`, {
67
+ headers: {
68
+ 'Fcode-Team': options.teamSlug,
69
+ authorization: `Bearer ${options.accessToken}`,
70
+ },
71
+ });
72
+ }
73
+ isDuplicatedError(error) {
74
+ return (error &&
75
+ error.response &&
76
+ error.response.errors &&
77
+ error.response.errors[0] &&
78
+ error.response.errors[0].message &&
79
+ error.response.errors[0].message.includes('Duplicated value'));
80
+ }
81
+ isEmptyValueError(error) {
82
+ return (error &&
83
+ error.response &&
84
+ error.response.errors &&
85
+ error.response.errors[0] &&
86
+ (error.response.errors[0].message == 'Value cannot be blank' || error.response.errors[0].message.includes('has coerced Null value for NonNull type')));
87
+ }
88
+ cleanError(error) {
89
+ // GraphQL-level errors carry a server message we can surface directly.
90
+ const graphqlMessage = error?.response?.errors?.[0]?.message;
91
+ if (graphqlMessage) {
92
+ return new Error(graphqlMessage);
93
+ }
94
+ // HTTP-level failures (bad gateway, service unavailable, server error) have no
95
+ // GraphQL errors array, so graphql-request dumps the whole query + response into
96
+ // error.message. Replace that with a short, actionable message.
97
+ const status = error?.response?.status;
98
+ if (typeof status === 'number' && status >= 500) {
99
+ return new Error(this.cloudUnavailableMessage(status));
100
+ }
101
+ // Network-level failures (cloud down/unreachable) reject before any response.
102
+ if (this.isNetworkError(error)) {
103
+ return new Error(`Could not reach the Factorial Code cloud at ${this.url}. Check that it is running and reachable.`);
104
+ }
105
+ return error;
106
+ }
107
+ cloudUnavailableMessage(status) {
108
+ const reason = status === 502 || status === 503 || status === 504 ? 'is temporarily unavailable' : 'returned a server error';
109
+ return `The Factorial Code cloud at ${this.url} ${reason} (HTTP ${status}). Please try again in a few moments.`;
110
+ }
111
+ isNetworkError(error) {
112
+ if (error?.response) {
113
+ return false;
114
+ }
115
+ if (typeof error?.code === 'string' && NETWORK_ERROR_CODES.includes(error.code)) {
116
+ return true;
117
+ }
118
+ const message = typeof error?.message === 'string' ? error.message : '';
119
+ return NETWORK_ERROR_CODES.some((code) => message.includes(code)) || message.includes('fetch failed');
120
+ }
121
+ allProcesses() {
122
+ return this.client
123
+ .request((0, graphql_request_1.gql) `
124
+ query processes($first: Int!, $after: String) {
125
+ processes(first: $first, after: $after) {
126
+ edges {
127
+ node {
128
+ ${PROCESS_FIELDS}
129
+ }
130
+ }
131
+ }
132
+ }
133
+ `, {
134
+ after: null,
135
+ first: 200,
136
+ })
137
+ .then(({ processes: { edges } }) => edges.map(({ node: process }) => this.mapProcess(process)))
138
+ .catch((error) => {
139
+ return Promise.reject(this.cleanError(error));
140
+ });
141
+ }
142
+ allVersionedProcesses(processId) {
143
+ return this.client
144
+ .request((0, graphql_request_1.gql) `
145
+ query allVersionedProcesses($processId: ID!) {
146
+ allVersionedProcesses(processId: $processId) {
147
+ id
148
+ tag
149
+ readme
150
+ script {
151
+ parametersSchema
152
+ programmingLanguage
153
+ sourceCode
154
+ }
155
+ }
156
+ }
157
+ `, {
158
+ processId,
159
+ })
160
+ .then(({ allVersionedProcesses }) => allVersionedProcesses.map(({ id, tag, readme, script }) => new types_1.VersionedProcess(id, tag, script, readme)))
161
+ .catch((error) => {
162
+ return Promise.reject(this.cleanError(error));
163
+ });
164
+ }
165
+ createVersionedProcesses(versionedProcess) {
166
+ return this.client
167
+ .request((0, graphql_request_1.gql) `
168
+ mutation publishProcess($processId: ID!, $tag: String!, $sourceCode: String, $parametersSchema: JSON, $readme: String) {
169
+ publishProcess(processId: $processId, tag: $tag, input: { sourceCode: $sourceCode, parametersSchema: $parametersSchema, readme: $readme }) {
170
+ id
171
+ }
172
+ }
173
+ `, {
174
+ processId: versionedProcess.id,
175
+ tag: versionedProcess.tag,
176
+ parametersSchema: versionedProcess.script.parametersSchema,
177
+ readme: versionedProcess.readme,
178
+ sourceCode: versionedProcess.script.sourceCode,
179
+ })
180
+ .catch((error) => {
181
+ return Promise.reject(this.cleanError(error));
182
+ });
183
+ }
184
+ allScriptLibraries() {
185
+ return this.client
186
+ .request((0, graphql_request_1.gql) `
187
+ query scriptLibraries($first: Int!, $after: String) {
188
+ scriptLibraries(first: $first, after: $after) {
189
+ edges {
190
+ node {
191
+ id
192
+ name
193
+ sourceCode
194
+ programmingLanguage
195
+ resolvingTeamSlug
196
+ }
197
+ }
198
+ }
199
+ }
200
+ `, {
201
+ after: null,
202
+ first: 200,
203
+ })
204
+ .then(({ scriptLibraries: { edges } }) => edges.map(({ node: { id, name, programmingLanguage, sourceCode, resolvingTeamSlug } }) => new types_1.ScriptLibrary(id, name, sourceCode || '', programmingLanguage, this.inheritedTeam(resolvingTeamSlug))))
205
+ .catch((error) => {
206
+ return Promise.reject(this.cleanError(error));
207
+ });
208
+ }
209
+ allVersionedScriptLibraries(scriptLibraryId) {
210
+ return this.client
211
+ .request((0, graphql_request_1.gql) `
212
+ query allVersionedScriptLibraries($scriptLibraryId: ID!) {
213
+ allVersionedScriptLibraries(scriptLibraryId: $scriptLibraryId) {
214
+ id
215
+ tag
216
+ programmingLanguage
217
+ sourceCode
218
+ }
219
+ }
220
+ `, {
221
+ scriptLibraryId,
222
+ })
223
+ .then(({ allVersionedScriptLibraries }) => allVersionedScriptLibraries.map(({ id, tag, sourceCode, programmingLanguage }) => new types_1.VersionedScriptLibrary(id, tag, sourceCode, programmingLanguage)))
224
+ .catch((error) => {
225
+ return Promise.reject(this.cleanError(error));
226
+ });
227
+ }
228
+ createVersionedScriptLibrary(versionedScriptLibrary) {
229
+ return this.client
230
+ .request((0, graphql_request_1.gql) `
231
+ mutation publishScriptLibrary($scriptLibraryId: ID!, $tag: String!, $sourceCode: String) {
232
+ publishScriptLibrary(scriptLibraryId: $scriptLibraryId, tag: $tag, input: { sourceCode: $sourceCode }) {
233
+ id
234
+ }
235
+ }
236
+ `, {
237
+ scriptLibraryId: versionedScriptLibrary.id,
238
+ tag: versionedScriptLibrary.tag,
239
+ sourceCode: versionedScriptLibrary.sourceCode,
240
+ })
241
+ .catch((error) => {
242
+ return Promise.reject(this.cleanError(error));
243
+ });
244
+ }
245
+ allVariables() {
246
+ return this.client
247
+ .request((0, graphql_request_1.gql) `
248
+ query teamVariables($first: Int!, $after: String) {
249
+ teamVariables(first: $first, after: $after) {
250
+ edges {
251
+ node {
252
+ id
253
+ key
254
+ value
255
+ isSensitive
256
+ }
257
+ }
258
+ pageInfo {
259
+ hasNextPage
260
+ endCursor
261
+ }
262
+ }
263
+ }
264
+ `, {
265
+ after: null,
266
+ first: 200,
267
+ })
268
+ .then(({ teamVariables: { edges } }) => edges.map(({ node: { id, isSensitive, key, value } }) => new types_1.Variable(id, key, value, isSensitive)))
269
+ .catch((error) => {
270
+ return Promise.reject(this.cleanError(error));
271
+ });
272
+ }
273
+ toProcessInput(process, includeCreateOnly) {
274
+ const settings = {
275
+ dependencies: { scopedToProcess: process.settings.dependencies.scopedToProcess },
276
+ };
277
+ if (process.form) {
278
+ settings.formSettings = { enabled: process.form.enabled };
279
+ }
280
+ if (process.visibility) {
281
+ settings.publicationConfig = { isPublic: process.visibility.isPublic };
282
+ }
283
+ const input = {
284
+ name: process.name,
285
+ parametersSchema: process.script.parametersSchema,
286
+ readme: process.readme,
287
+ tags: process.tags,
288
+ sourceCode: process.script.sourceCode,
289
+ manifest: process.settings.dependencies.scopedToProcess ? process.manifest : null,
290
+ settings,
291
+ };
292
+ if (process.description !== undefined) {
293
+ input.description = process.description;
294
+ }
295
+ if (process.webhook) {
296
+ const webhook = { enabled: process.webhook.enabled };
297
+ if (process.webhook.username !== undefined) {
298
+ webhook.username = process.webhook.username;
299
+ }
300
+ if (process.webhook.password !== undefined) {
301
+ webhook.password = process.webhook.password;
302
+ }
303
+ input.webhook = webhook;
304
+ }
305
+ if (includeCreateOnly) {
306
+ input.slug = process.slug;
307
+ input.programmingLanguage = process.script.programmingLanguage;
308
+ }
309
+ return input;
310
+ }
311
+ pushProcess(process) {
312
+ if (process.id) {
313
+ return this.client
314
+ .request((0, graphql_request_1.gql) `
315
+ mutation updateProcess($id: ID!, $input: ProcessInput!) {
316
+ updateProcess(id: $id, input: $input) {
317
+ ${PROCESS_FIELDS}
318
+ }
319
+ }
320
+ `, {
321
+ id: process.id,
322
+ input: this.toProcessInput(process, false),
323
+ })
324
+ .then(({ updateProcess: process }) => this.mapProcess(process))
325
+ .catch((error) => {
326
+ return Promise.reject(this.cleanError(error));
327
+ });
328
+ }
329
+ return this.client
330
+ .request((0, graphql_request_1.gql) `
331
+ mutation createProcess($input: ProcessInput!) {
332
+ createProcess(input: $input) {
333
+ ${PROCESS_FIELDS}
334
+ }
335
+ }
336
+ `, {
337
+ input: this.toProcessInput(process, true),
338
+ })
339
+ .then(({ createProcess: process }) => this.mapProcess(process))
340
+ .catch((error) => {
341
+ return Promise.reject(this.cleanError(error));
342
+ });
343
+ }
344
+ removeProcess(id) {
345
+ if (!id) {
346
+ return Promise.reject(new Error('id is required during remove'));
347
+ }
348
+ return this.client
349
+ .request((0, graphql_request_1.gql) `
350
+ mutation deleteProcess($id: ID!) {
351
+ deleteProcess(id: $id) {
352
+ id
353
+ }
354
+ }
355
+ `, {
356
+ id,
357
+ })
358
+ .catch((error) => {
359
+ return Promise.reject(this.cleanError(error));
360
+ });
361
+ }
362
+ pushScriptLibrary(scriptLibrary) {
363
+ if (scriptLibrary.id) {
364
+ return this.client
365
+ .request((0, graphql_request_1.gql) `
366
+ mutation updateScriptLibrary($id: ID!, $sourceCode: String) {
367
+ updateScriptLibrary(id: $id, input: { sourceCode: $sourceCode }) {
368
+ id
369
+ name
370
+ programmingLanguage
371
+ sourceCode
372
+ }
373
+ }
374
+ `, {
375
+ id: scriptLibrary.id,
376
+ sourceCode: scriptLibrary.sourceCode,
377
+ })
378
+ .then(({ updateScriptLibrary: scriptLibrary }) => new types_1.ScriptLibrary(scriptLibrary.id, scriptLibrary.name, scriptLibrary.sourceCode, scriptLibrary.programmingLanguage))
379
+ .catch((error) => {
380
+ return Promise.reject(this.cleanError(error));
381
+ });
382
+ }
383
+ return this.client
384
+ .request((0, graphql_request_1.gql) `
385
+ mutation createScriptLibrary($name: String!, $sourceCode: String, $programmingLanguage: ProgrammingLanguage) {
386
+ createScriptLibrary(name: $name, programmingLanguage: $programmingLanguage, sourceCode: $sourceCode) {
387
+ id
388
+ name
389
+ sourceCode
390
+ programmingLanguage
391
+ }
392
+ }
393
+ `, {
394
+ name: scriptLibrary.name,
395
+ sourceCode: scriptLibrary.sourceCode,
396
+ programmingLanguage: scriptLibrary.programmingLanguage,
397
+ })
398
+ .then(({ createScriptLibrary: scriptLibrary }) => new types_1.ScriptLibrary(scriptLibrary.id, scriptLibrary.name, scriptLibrary.sourceCode, scriptLibrary.programmingLanguage))
399
+ .catch((error) => {
400
+ return Promise.reject(this.cleanError(error));
401
+ });
402
+ }
403
+ removeScriptLibrary(id) {
404
+ if (!id) {
405
+ return Promise.reject(new Error('id is required during remove'));
406
+ }
407
+ return this.client
408
+ .request((0, graphql_request_1.gql) `
409
+ mutation deleteScriptLibrary($id: ID!) {
410
+ deleteScriptLibrary(id: $id) {
411
+ id
412
+ }
413
+ }
414
+ `, {
415
+ id,
416
+ })
417
+ .catch((error) => {
418
+ return Promise.reject(this.cleanError(error));
419
+ });
420
+ }
421
+ pushVariable(variable) {
422
+ return this.client
423
+ .request((0, graphql_request_1.gql) `
424
+ mutation createTeamVariable($key: String!, $value: String!, $isSensitive: Boolean!) {
425
+ createTeamVariable(key: $key, value: $value, isSensitive: $isSensitive) {
426
+ id
427
+ key
428
+ value
429
+ isSensitive
430
+ }
431
+ }
432
+ `, {
433
+ key: variable.key,
434
+ value: variable.value,
435
+ isSensitive: variable.isSensitive,
436
+ })
437
+ .then(({ createTeamVariable: variable }) => new types_1.Variable(variable.id, variable.key, variable.value, variable.isSensitive))
438
+ .catch((error) => {
439
+ return Promise.reject(this.cleanError(error));
440
+ });
441
+ }
442
+ updateVariable(variable) {
443
+ return this.client
444
+ .request((0, graphql_request_1.gql) `
445
+ mutation updateTeamVariable($id: ID!, $key: String, $value: String) {
446
+ updateTeamVariable(id: $id, key: $key, value: $value) {
447
+ id
448
+ key
449
+ value
450
+ }
451
+ }
452
+ `, {
453
+ id: variable.id,
454
+ key: variable.key,
455
+ value: variable.value,
456
+ })
457
+ .then(({ updateTeamVariable: updated }) => new types_1.Variable(updated.id, updated.key, updated.value, variable.isSensitive))
458
+ .catch((error) => {
459
+ return Promise.reject(this.cleanError(error));
460
+ });
461
+ }
462
+ removeVariable(id) {
463
+ if (!id) {
464
+ return Promise.reject(new Error('id is required during remove'));
465
+ }
466
+ return this.client
467
+ .request((0, graphql_request_1.gql) `
468
+ mutation deleteTeamVariable($id: ID!) {
469
+ deleteTeamVariable(id: $id) {
470
+ id
471
+ }
472
+ }
473
+ `, {
474
+ id,
475
+ })
476
+ .catch((error) => {
477
+ return Promise.reject(this.cleanError(error));
478
+ });
479
+ }
480
+ programmingLanguageManifest(programmingLanguage) {
481
+ return this.client
482
+ .request((0, graphql_request_1.gql) `
483
+ query getProgrammingLanguageManifest($programmingLanguage: ProgrammingLanguage!) {
484
+ programmingLanguageManifest(programmingLanguage: $programmingLanguage) {
485
+ id
486
+ programmingLanguage
487
+ dependencies {
488
+ name
489
+ semVer
490
+ isNative
491
+ gitUrl
492
+ }
493
+ }
494
+ }
495
+ `, { programmingLanguage })
496
+ .then(({ programmingLanguageManifest }) => {
497
+ return this.mapProgrammingLanguageManifest(programmingLanguageManifest);
498
+ })
499
+ .catch((error) => {
500
+ // TODO: This is a workaround backward compatibility with old versions of fcode-api.
501
+ // Remove when full on-premises installations are updated.
502
+ if (error.response && error.response.errors && error.response.errors[0] && error.response.errors[0].message.includes('isNative')) {
503
+ return this.client
504
+ .request((0, graphql_request_1.gql) `
505
+ query getProgrammingLanguageManifest($programmingLanguage: ProgrammingLanguage!) {
506
+ programmingLanguageManifest(programmingLanguage: $programmingLanguage) {
507
+ id
508
+ programmingLanguage
509
+ dependencies {
510
+ name
511
+ semVer
512
+ gitUrl
513
+ }
514
+ }
515
+ }
516
+ `, { programmingLanguage })
517
+ .then(({ programmingLanguageManifest }) => {
518
+ programmingLanguageManifest.dependencies.forEach((dependency) => {
519
+ if (programmingLanguage === 'PYTHON') {
520
+ if (dependency.name === 'smtplib') {
521
+ dependency.isNative = true;
522
+ }
523
+ }
524
+ });
525
+ return this.mapProgrammingLanguageManifest(programmingLanguageManifest);
526
+ })
527
+ .catch((error) => {
528
+ return Promise.reject(this.cleanError(error));
529
+ });
530
+ }
531
+ return Promise.reject(this.cleanError(error));
532
+ });
533
+ }
534
+ inheritedTeam(resolvingTeamSlug) {
535
+ return resolvingTeamSlug && resolvingTeamSlug !== this.teamSlug ? resolvingTeamSlug : undefined;
536
+ }
537
+ mapWebhook(triggers) {
538
+ const webhookTrigger = triggers?.webhook;
539
+ if (!webhookTrigger) {
540
+ return undefined;
541
+ }
542
+ const webhook = { enabled: Boolean(webhookTrigger.enabled) };
543
+ const basicAuth = webhookTrigger.auth?.basicAuth;
544
+ if (basicAuth) {
545
+ // Prefer the expression form (env-var placeholders like $WEBHOOK_PASSWORD)
546
+ // over the resolved literal so placeholders round-trip on pull.
547
+ const username = basicAuth.expression?.username ?? basicAuth.username;
548
+ const password = basicAuth.expression?.password ?? basicAuth.password;
549
+ if (username != null) {
550
+ webhook.username = username;
551
+ }
552
+ if (password != null) {
553
+ webhook.password = password;
554
+ }
555
+ }
556
+ return webhook;
557
+ }
558
+ mapProcess({ id, slug, name, description, tags, script, readme, manifest, settings, triggers, resolvingTeamSlug }) {
559
+ const dependencies = _.map(manifest?.dependencies, (dependency) => {
560
+ return { name: dependency.name, specifier: dependency.gitUrl ?? dependency.semVer };
561
+ });
562
+ const metadata = { name, tags: tags ?? [] };
563
+ if (description != null) {
564
+ metadata.description = description;
565
+ }
566
+ const webhook = this.mapWebhook(triggers);
567
+ if (webhook) {
568
+ metadata.webhook = webhook;
569
+ }
570
+ if (settings?.formSettings) {
571
+ metadata.form = { enabled: Boolean(settings.formSettings.enabled) };
572
+ }
573
+ if (settings?.publicationConfig) {
574
+ metadata.visibility = { isPublic: Boolean(settings.publicationConfig.isPublic) };
575
+ }
576
+ return new types_1.Process(id, slug, script, readme, { dependencies }, settings, metadata, this.inheritedTeam(resolvingTeamSlug));
577
+ }
578
+ team() {
579
+ return this.client
580
+ .request((0, graphql_request_1.gql) `
581
+ query team($slug: ID!) {
582
+ team(slug: $slug) {
583
+ slug
584
+ zoneId
585
+ errorHandlerConfig {
586
+ processId
587
+ tag
588
+ }
589
+ parentTeamSlugs
590
+ }
591
+ }
592
+ `, { slug: this.teamSlug })
593
+ .then(({ team }) => team)
594
+ .catch((error) => {
595
+ return Promise.reject(this.cleanError(error));
596
+ });
597
+ }
598
+ pushTeam(update) {
599
+ return this.client
600
+ .request((0, graphql_request_1.gql) `
601
+ mutation updateTeam($slug: String!, $update: TeamUpdateInput!) {
602
+ updateTeam(slug: $slug, update: $update) {
603
+ slug
604
+ zoneId
605
+ errorHandlerConfig {
606
+ processId
607
+ tag
608
+ }
609
+ parentTeamSlugs
610
+ }
611
+ }
612
+ `, { slug: this.teamSlug, update })
613
+ .then(({ updateTeam: team }) => team)
614
+ .catch((error) => {
615
+ return Promise.reject(this.cleanError(error));
616
+ });
617
+ }
618
+ mapProgrammingLanguageManifest(programmingLanguageManifest) {
619
+ const allDependencies = programmingLanguageManifest.nextInstallation?.dependencies || programmingLanguageManifest.dependencies;
620
+ const dependencies = _.map(allDependencies, (dependency) => {
621
+ if (!dependency.isNative) {
622
+ return { name: dependency.name, specifier: dependency.gitUrl ?? dependency.semVer };
623
+ }
624
+ return null;
625
+ })
626
+ .filter(Boolean)
627
+ .sort((a, b) => a && b && a.name.localeCompare(b.name));
628
+ return new types_1.ProgrammingLanguageManifest(programmingLanguageManifest.id, programmingLanguageManifest.programmingLanguage, programmingLanguageManifest.programmingLanguage, dependencies);
629
+ }
630
+ allProgrammingLanguageManifest() {
631
+ const result = [];
632
+ result.push(this.programmingLanguageManifest('JAVASCRIPT'));
633
+ result.push(this.programmingLanguageManifest('PYTHON'));
634
+ return Promise.all(result);
635
+ }
636
+ pushProgrammingLanguageManifest(programmingLanguageManifest) {
637
+ return this.client
638
+ .request((0, graphql_request_1.gql) `
639
+ mutation updateManifest($id: ID!, $input: ProgrammingLanguageManifestUpdateInput!) {
640
+ updateProgrammingLanguageManifest(id: $id, input: $input) {
641
+ id
642
+ programmingLanguage
643
+ dependencies {
644
+ name
645
+ semVer
646
+ gitUrl
647
+ }
648
+ nextInstallation {
649
+ status
650
+ error
651
+ dependencies {
652
+ name
653
+ semVer
654
+ isNative
655
+ gitUrl
656
+ }
657
+ }
658
+ }
659
+ }
660
+ `, {
661
+ id: programmingLanguageManifest.id,
662
+ input: { dependencies: programmingLanguageManifest.dependencies },
663
+ })
664
+ .then(({ updateProgrammingLanguageManifest: programmingLanguageManifest }) => {
665
+ return this.client
666
+ .request((0, graphql_request_1.gql) `
667
+ mutation installManifest($id: ID!) {
668
+ installProgrammingLanguageManifest(id: $id)
669
+ }
670
+ `, {
671
+ id: programmingLanguageManifest.id,
672
+ })
673
+ .then(() => {
674
+ return this.mapProgrammingLanguageManifest(programmingLanguageManifest);
675
+ })
676
+ .catch((error) => {
677
+ return Promise.reject(this.cleanError(error));
678
+ });
679
+ })
680
+ .catch((error) => {
681
+ return Promise.reject(this.cleanError(error));
682
+ });
683
+ }
684
+ allServiceAccounts() {
685
+ return this.client
686
+ .request((0, graphql_request_1.gql) `
687
+ query allServiceAccounts {
688
+ allServiceAccounts {
689
+ id
690
+ name
691
+ clientId
692
+ clientSecret
693
+ }
694
+ }
695
+ `)
696
+ .then(({ allServiceAccounts }) => allServiceAccounts.map(({ id, name, clientId, clientSecret }) => new types_1.ServiceAccount(id, name, clientId, clientSecret)))
697
+ .catch((error) => {
698
+ return Promise.reject(this.cleanError(error));
699
+ });
700
+ }
701
+ createServiceAccount(name) {
702
+ return this.client
703
+ .request((0, graphql_request_1.gql) `
704
+ mutation createServiceAccount($input: ServiceAccountInput!) {
705
+ createServiceAccount(input: $input) {
706
+ id
707
+ name
708
+ clientId
709
+ clientSecret
710
+ }
711
+ }
712
+ `, {
713
+ input: { name: name },
714
+ })
715
+ .then(({ createServiceAccount: serviceAccount }) => new types_1.ServiceAccount(serviceAccount.id, serviceAccount.name, serviceAccount.clientId, serviceAccount.clientSecret))
716
+ .catch((error) => {
717
+ return Promise.reject(this.cleanError(error));
718
+ });
719
+ }
720
+ }
721
+ exports.default = FcodeGraphQLClient;