attio 0.0.1-experimental.20241219 → 0.0.1-experimental.20250101
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/api/create-version.js +2 -2
- package/lib/attio-logo.js +24 -0
- package/lib/attio.js +17 -8
- package/lib/commands/build.js +18 -35
- package/lib/commands/connection/add.js +51 -168
- package/lib/commands/connection/index.js +9 -1
- package/lib/commands/connection/list.js +17 -47
- package/lib/commands/connection/remove.js +17 -65
- package/lib/commands/create.js +27 -126
- package/lib/commands/dev.js +17 -106
- package/lib/commands/version/create.js +17 -68
- package/lib/commands/version/index.js +11 -1
- package/lib/commands/version/invite.js +40 -84
- package/lib/commands/version/list.js +18 -40
- package/lib/commands/version/publish.js +40 -64
- package/lib/machines/actions.js +7 -0
- package/lib/machines/actors.js +7 -1
- package/lib/machines/add-connection-machine.js +169 -201
- package/lib/machines/build-machine.js +35 -4
- package/lib/machines/create-machine.js +95 -70
- package/lib/machines/create-version-machine.js +121 -4
- package/lib/machines/dev-machine.js +173 -53
- package/lib/machines/generate-invite-machine.js +64 -10
- package/lib/machines/list-connections-machine.js +57 -2
- package/lib/machines/list-versions-machine.js +33 -0
- package/lib/machines/publish-version-machine.js +45 -16
- package/lib/machines/remove-connection-machine.js +64 -17
- package/lib/machines/ts-machine.js +4 -1
- package/lib/schema.js +2 -2
- package/lib/util/clear-terminal.js +4 -0
- package/lib/util/load-developer-config.js +2 -2
- package/lib/util/print-install-instructions.js +32 -0
- package/lib/util/print-message.js +9 -0
- package/lib/util/set-terminal-title.js +8 -0
- package/lib/util/text-gradient.js +28 -0
- package/lib/util/typescript.js +25 -0
- package/package.json +13 -12
- package/schema.graphql +8 -1
- package/lib/components/BuildError.js +0 -46
- package/lib/components/BuildLog.js +0 -6
- package/lib/components/CodeGenErrors.js +0 -22
- package/lib/components/Disclaimer.js +0 -9
- package/lib/components/InitialInstructions.js +0 -69
- package/lib/components/Log.js +0 -69
- package/lib/components/Logo.js +0 -10
- package/lib/components/MultiSelect.js +0 -65
- package/lib/components/ScrollBox.js +0 -87
- package/lib/components/ScrollBox.store.js +0 -36
- package/lib/components/ScrollBox.util.js +0 -27
- package/lib/components/Select.js +0 -6
- package/lib/components/Table.js +0 -33
- package/lib/components/TypeScriptErrors.js +0 -38
- package/lib/hooks/useFullScreen.js +0 -22
- package/lib/hooks/useTerminalTitle.js +0 -11
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import readline from "readline";
|
|
2
1
|
import { assign, setup, fromCallback } from "xstate";
|
|
3
2
|
import { addConnectionDefinition } from "../api/add-connection-definition.js";
|
|
4
3
|
import { fetchConnections } from "../api/fetch-connections.js";
|
|
5
|
-
import {
|
|
6
|
-
import { loadAppConfig, loadDeveloperConfig } from "./actors.js";
|
|
4
|
+
import { optionsSchema } from "../commands/connection/add.js";
|
|
5
|
+
import { ask, askPassword, askWithChoices, loadAppConfig, loadDeveloperConfig } from "./actors.js";
|
|
6
|
+
import { printInstallInstructions } from "../util/print-install-instructions.js";
|
|
7
|
+
import { printLogo, showError } from "./actions.js";
|
|
8
|
+
import Spinner from "tiny-spinner";
|
|
9
|
+
import chalk from "chalk";
|
|
7
10
|
export const connectionTypes = [
|
|
8
11
|
{ value: "secret", label: "Secret" },
|
|
9
12
|
{ value: "oauth2-code", label: "OAuth2" },
|
|
@@ -15,8 +18,13 @@ export const addConnectionMachine = setup({
|
|
|
15
18
|
input: {},
|
|
16
19
|
},
|
|
17
20
|
actors: {
|
|
18
|
-
|
|
21
|
+
ask,
|
|
22
|
+
askWithChoices,
|
|
23
|
+
askPassword,
|
|
24
|
+
createConnectionDefinition: fromCallback(({ sendBack, input: { developer: { token, slug: devSlug }, config, connectionType: connection_type, label, description, global, authorizeUrl, accessTokenUrl, clientId, clientSecret, scopes, }, }) => {
|
|
25
|
+
const spinner = new Spinner();
|
|
19
26
|
const add = async () => {
|
|
27
|
+
spinner.start("Creating connection definition...");
|
|
20
28
|
try {
|
|
21
29
|
await addConnectionDefinition({
|
|
22
30
|
token,
|
|
@@ -33,9 +41,11 @@ export const addConnectionMachine = setup({
|
|
|
33
41
|
clientSecret,
|
|
34
42
|
scopes,
|
|
35
43
|
});
|
|
44
|
+
spinner.success("Connection definition created");
|
|
36
45
|
sendBack({ type: "Success" });
|
|
37
46
|
}
|
|
38
47
|
catch (error) {
|
|
48
|
+
spinner.error(`Failed to create connection definition: ${chalk.red(error.message)}`);
|
|
39
49
|
sendBack({ type: "Error", error: error.message });
|
|
40
50
|
}
|
|
41
51
|
};
|
|
@@ -43,95 +53,78 @@ export const addConnectionMachine = setup({
|
|
|
43
53
|
}),
|
|
44
54
|
loadDeveloperConfig,
|
|
45
55
|
loadAppConfig,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if
|
|
49
|
-
process.stdin.setRawMode(true);
|
|
50
|
-
}
|
|
51
|
-
const handleKeyPress = (_, key) => {
|
|
52
|
-
if (key.meta) {
|
|
53
|
-
switch (key.name) {
|
|
54
|
-
case "down":
|
|
55
|
-
sendBack({ type: "Next" });
|
|
56
|
-
break;
|
|
57
|
-
case "up":
|
|
58
|
-
sendBack({ type: "Previous" });
|
|
59
|
-
break;
|
|
60
|
-
default:
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
process.stdin.on("keypress", handleKeyPress);
|
|
66
|
-
return () => {
|
|
67
|
-
process.stdin.removeListener("keypress", handleKeyPress);
|
|
68
|
-
if (process.stdin.isTTY) {
|
|
69
|
-
process.stdin.setRawMode(false);
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
}),
|
|
73
|
-
"validateGlobal": fromCallback(({ sendBack, input: { developer, config, global } }) => {
|
|
56
|
+
validateGlobal: fromCallback(({ sendBack, input: { developer, config, global } }) => {
|
|
57
|
+
const spinner = new Spinner();
|
|
58
|
+
spinner.start("Checking if global connection already exists..." + global);
|
|
74
59
|
fetchConnections({
|
|
75
60
|
token: developer.token,
|
|
76
61
|
devSlug: developer.slug,
|
|
77
62
|
appId: config.id,
|
|
78
63
|
major: config.major,
|
|
79
|
-
})
|
|
80
|
-
|
|
64
|
+
})
|
|
65
|
+
.then((connections) => {
|
|
66
|
+
const weHaveGlobal = connections.some((connection) => connection.global);
|
|
67
|
+
const weHaveUser = connections.some((connection) => !connection.global);
|
|
68
|
+
if (weHaveGlobal && weHaveUser) {
|
|
69
|
+
spinner.stop();
|
|
70
|
+
sendBack({
|
|
71
|
+
type: "Error",
|
|
72
|
+
error: "Both global and user connections already exist",
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
else if (weHaveGlobal && global) {
|
|
76
|
+
spinner.error("Global connection already exists");
|
|
77
|
+
sendBack({ type: "Global Taken" });
|
|
78
|
+
}
|
|
79
|
+
else if (weHaveUser && !global) {
|
|
80
|
+
spinner.error("A user connection already exists");
|
|
81
81
|
sendBack({ type: "Global Taken" });
|
|
82
82
|
}
|
|
83
83
|
else {
|
|
84
|
+
spinner.success("All good.");
|
|
84
85
|
sendBack({ type: "Valid Global" });
|
|
85
86
|
}
|
|
87
|
+
})
|
|
88
|
+
.catch((error) => {
|
|
89
|
+
spinner.stop();
|
|
90
|
+
sendBack({ type: "Error", error: error.message });
|
|
86
91
|
});
|
|
87
92
|
}),
|
|
88
93
|
},
|
|
89
94
|
actions: {
|
|
95
|
+
printLogo,
|
|
96
|
+
showError,
|
|
97
|
+
showConfigInstructions: ({ context }) => printInstallInstructions(context.configError),
|
|
90
98
|
clearError: assign({
|
|
91
99
|
error: () => undefined,
|
|
92
100
|
}),
|
|
93
|
-
initializeLabel: assign({
|
|
94
|
-
label: (_, params) => {
|
|
95
|
-
if (params.label?.trim())
|
|
96
|
-
return params.label;
|
|
97
|
-
switch (params.connectionType) {
|
|
98
|
-
case "oauth2-code":
|
|
99
|
-
return "Connection";
|
|
100
|
-
case "secret":
|
|
101
|
-
case undefined:
|
|
102
|
-
return "Access Token";
|
|
103
|
-
default:
|
|
104
|
-
return params.connectionType;
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
}),
|
|
108
101
|
setError: assign({
|
|
109
102
|
error: (_, params) => params.error,
|
|
110
103
|
}),
|
|
111
104
|
setConnectionType: assign({
|
|
112
|
-
connectionType: (_, params) => params.
|
|
105
|
+
connectionType: (_, params) => params.output,
|
|
113
106
|
}),
|
|
114
107
|
setAuthorizeUrl: assign({
|
|
115
|
-
authorizeUrl: (_, params) => params.
|
|
108
|
+
authorizeUrl: (_, params) => params.output,
|
|
116
109
|
}),
|
|
117
110
|
setAccessTokenUrl: assign({
|
|
118
|
-
accessTokenUrl: (_, params) => params.
|
|
111
|
+
accessTokenUrl: (_, params) => params.output,
|
|
119
112
|
}),
|
|
120
113
|
setScopes: assign({
|
|
121
|
-
scopes: (_, params) => params.
|
|
114
|
+
scopes: (_, params) => params.output,
|
|
122
115
|
}),
|
|
123
116
|
setClientId: assign({
|
|
124
|
-
clientId: (_, params) => params.
|
|
117
|
+
clientId: (_, params) => params.output,
|
|
125
118
|
}),
|
|
126
119
|
setClientSecret: assign({
|
|
127
|
-
clientSecret: (_, params) => params.
|
|
120
|
+
clientSecret: (_, params) => params.output,
|
|
128
121
|
}),
|
|
129
122
|
setDeveloperConfig: assign({
|
|
130
123
|
developer: (_, params) => params,
|
|
131
124
|
}),
|
|
132
125
|
setInvalidAuthorizeUrl: assign({
|
|
133
126
|
error: (_, params) => {
|
|
134
|
-
const result =
|
|
127
|
+
const result = optionsSchema.shape.authorizeUrl
|
|
135
128
|
.unwrap()
|
|
136
129
|
.safeParse(params.authorizeUrl?.trim());
|
|
137
130
|
return result.success ? undefined : result.error.errors[0].message;
|
|
@@ -139,7 +132,7 @@ export const addConnectionMachine = setup({
|
|
|
139
132
|
}),
|
|
140
133
|
setInvalidAccessTokenUrl: assign({
|
|
141
134
|
error: (_, params) => {
|
|
142
|
-
const result =
|
|
135
|
+
const result = optionsSchema.shape.accessTokenUrl
|
|
143
136
|
.unwrap()
|
|
144
137
|
.safeParse(params.accessTokenUrl?.trim());
|
|
145
138
|
return result.success ? undefined : result.error.errors[0].message;
|
|
@@ -147,19 +140,21 @@ export const addConnectionMachine = setup({
|
|
|
147
140
|
}),
|
|
148
141
|
setInvalidScopes: assign({
|
|
149
142
|
error: (_, params) => {
|
|
150
|
-
const result =
|
|
143
|
+
const result = optionsSchema.shape.scopes.unwrap().safeParse(params.scopes?.trim());
|
|
151
144
|
return result.success ? undefined : result.error.errors[0].message;
|
|
152
145
|
},
|
|
153
146
|
}),
|
|
154
147
|
setInvalidClientId: assign({
|
|
155
148
|
error: (_, params) => {
|
|
156
|
-
const result =
|
|
149
|
+
const result = optionsSchema.shape.clientId
|
|
150
|
+
.unwrap()
|
|
151
|
+
.safeParse(params.clientId?.trim());
|
|
157
152
|
return result.success ? undefined : result.error.errors[0].message;
|
|
158
153
|
},
|
|
159
154
|
}),
|
|
160
155
|
setInvalidClientSecret: assign({
|
|
161
156
|
error: (_, params) => {
|
|
162
|
-
const result =
|
|
157
|
+
const result = optionsSchema.shape.clientSecret
|
|
163
158
|
.unwrap()
|
|
164
159
|
.safeParse(params.clientSecret?.trim());
|
|
165
160
|
return result.success ? undefined : result.error.errors[0].message;
|
|
@@ -169,13 +164,13 @@ export const addConnectionMachine = setup({
|
|
|
169
164
|
configError: (_, params) => params.configError,
|
|
170
165
|
}),
|
|
171
166
|
setLabel: assign({
|
|
172
|
-
label: (_, params) => params.
|
|
167
|
+
label: (_, params) => params.output,
|
|
173
168
|
}),
|
|
174
169
|
setDescription: assign({
|
|
175
|
-
description: (_, params) => params.
|
|
170
|
+
description: (_, params) => params.output,
|
|
176
171
|
}),
|
|
177
172
|
setGlobal: assign({
|
|
178
|
-
global: (_, params) => params.
|
|
173
|
+
global: (_, params) => params.output === "true",
|
|
179
174
|
}),
|
|
180
175
|
setAppConfig: assign({
|
|
181
176
|
config: (_, params) => params.config,
|
|
@@ -189,16 +184,19 @@ export const addConnectionMachine = setup({
|
|
|
189
184
|
"have label": (_, params) => Boolean(params.label),
|
|
190
185
|
"have description": (_, params) => Boolean(params.description),
|
|
191
186
|
"have authorize url": (_, params) => params.connectionType === "secret" ||
|
|
192
|
-
|
|
187
|
+
optionsSchema.shape.authorizeUrl.unwrap().safeParse(params.authorizeUrl?.trim())
|
|
188
|
+
.success,
|
|
193
189
|
"have access token url": (_, params) => params.connectionType === "secret" ||
|
|
194
|
-
|
|
190
|
+
optionsSchema.shape.accessTokenUrl.unwrap().safeParse(params.accessTokenUrl?.trim())
|
|
191
|
+
.success,
|
|
195
192
|
"have scopes": (_, params) => params.connectionType === "secret" ||
|
|
196
|
-
|
|
193
|
+
optionsSchema.shape.scopes.unwrap().safeParse(params.scopes?.trim()).success,
|
|
197
194
|
"have client id": (_, params) => params.connectionType === "secret" ||
|
|
198
|
-
|
|
195
|
+
optionsSchema.shape.clientId.unwrap().safeParse(params.clientId?.trim()).success,
|
|
199
196
|
"have global": (_, params) => params.global !== undefined,
|
|
200
197
|
"have client secret": (_, params) => params.connectionType === "secret" ||
|
|
201
|
-
|
|
198
|
+
optionsSchema.shape.clientSecret.unwrap().safeParse(params.clientSecret?.trim())
|
|
199
|
+
.success,
|
|
202
200
|
"is oauth": (_, params) => params.connectionType === "oauth2-code",
|
|
203
201
|
},
|
|
204
202
|
}).createMachine({
|
|
@@ -225,6 +223,7 @@ export const addConnectionMachine = setup({
|
|
|
225
223
|
},
|
|
226
224
|
"Show config instructions": {
|
|
227
225
|
type: "final",
|
|
226
|
+
entry: "showConfigInstructions",
|
|
228
227
|
},
|
|
229
228
|
"Loading App Config": {
|
|
230
229
|
invoke: {
|
|
@@ -244,6 +243,7 @@ export const addConnectionMachine = setup({
|
|
|
244
243
|
},
|
|
245
244
|
"Error": {
|
|
246
245
|
type: "final",
|
|
246
|
+
entry: { type: "showError", params: ({ context }) => ({ error: context.error }) },
|
|
247
247
|
},
|
|
248
248
|
"Creating connection definition": {
|
|
249
249
|
invoke: {
|
|
@@ -274,114 +274,84 @@ export const addConnectionMachine = setup({
|
|
|
274
274
|
type: "final",
|
|
275
275
|
},
|
|
276
276
|
"Ask for Authorize URL": {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
{
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
{
|
|
288
|
-
target: "Ask for Authorize URL",
|
|
289
|
-
actions: { type: "setInvalidAuthorizeUrl", params: ({ context }) => context },
|
|
277
|
+
invoke: {
|
|
278
|
+
src: "ask",
|
|
279
|
+
input: {
|
|
280
|
+
message: "e.g. https://authorization-server.com/oauth/authorize\nOAuth Authorize URL:",
|
|
281
|
+
required: true,
|
|
282
|
+
validate: (value) => {
|
|
283
|
+
const result = optionsSchema.shape.authorizeUrl
|
|
284
|
+
.unwrap()
|
|
285
|
+
.safeParse(value.trim());
|
|
286
|
+
return result.success ? true : result.error.errors[0].message;
|
|
290
287
|
},
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
guard: { type: "have authorize url", params: ({ context }) => context },
|
|
288
|
+
},
|
|
289
|
+
onDone: {
|
|
290
|
+
target: "Do we have an access token url?",
|
|
291
|
+
actions: { type: "setAuthorizeUrl", params: ({ event }) => event },
|
|
296
292
|
},
|
|
297
293
|
},
|
|
298
294
|
},
|
|
299
295
|
"Ask for Access Token URL": {
|
|
300
|
-
|
|
301
|
-
"
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
296
|
+
invoke: {
|
|
297
|
+
src: "ask",
|
|
298
|
+
input: {
|
|
299
|
+
message: "e.g. https://authorization-server.com/oauth/token\nOAuth Access Token URL:",
|
|
300
|
+
required: true,
|
|
301
|
+
validate: (value) => {
|
|
302
|
+
const result = optionsSchema.shape.accessTokenUrl
|
|
303
|
+
.unwrap()
|
|
304
|
+
.safeParse(value.trim());
|
|
305
|
+
return result.success ? true : result.error.errors[0].message;
|
|
310
306
|
},
|
|
311
|
-
],
|
|
312
|
-
"Update Access Token URL": {
|
|
313
|
-
actions: { type: "setAccessTokenUrl", params: ({ event }) => event },
|
|
314
307
|
},
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
guard: { type: "have access token url", params: ({ context }) => context },
|
|
308
|
+
onDone: {
|
|
309
|
+
target: "Do we have scopes?",
|
|
310
|
+
actions: { type: "setAccessTokenUrl", params: ({ event }) => event },
|
|
319
311
|
},
|
|
320
312
|
},
|
|
321
313
|
},
|
|
322
314
|
"Ask for Scopes": {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
{
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
actions: "clearError",
|
|
332
|
-
},
|
|
333
|
-
{
|
|
334
|
-
target: "Ask for Scopes",
|
|
335
|
-
actions: { type: "setInvalidScopes", params: ({ context }) => context },
|
|
315
|
+
invoke: {
|
|
316
|
+
src: "ask",
|
|
317
|
+
input: {
|
|
318
|
+
message: "e.g. read:user,read:org\nOAuth Scopes:",
|
|
319
|
+
required: true,
|
|
320
|
+
validate: (value) => {
|
|
321
|
+
const result = optionsSchema.shape.scopes.unwrap().safeParse(value.trim());
|
|
322
|
+
return result.success ? true : result.error.errors[0].message;
|
|
336
323
|
},
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
guard: { type: "have scopes", params: ({ context }) => context },
|
|
324
|
+
},
|
|
325
|
+
onDone: {
|
|
326
|
+
target: "Do we have a client id?",
|
|
327
|
+
actions: { type: "setScopes", params: ({ event }) => event },
|
|
342
328
|
},
|
|
343
329
|
},
|
|
344
330
|
},
|
|
345
331
|
"Ask for Client ID": {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
332
|
+
invoke: {
|
|
333
|
+
src: "ask",
|
|
334
|
+
input: {
|
|
335
|
+
message: "OAuth Client ID:",
|
|
336
|
+
required: true,
|
|
349
337
|
},
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
guard: { type: "have client id", params: ({ context }) => context },
|
|
354
|
-
actions: "clearError",
|
|
355
|
-
},
|
|
356
|
-
{
|
|
357
|
-
target: "Ask for Client ID",
|
|
358
|
-
actions: { type: "setInvalidClientId", params: ({ context }) => context },
|
|
359
|
-
},
|
|
360
|
-
],
|
|
361
|
-
"Previous": "Ask for Scopes",
|
|
362
|
-
"Next": {
|
|
363
|
-
target: "Ask for Client Secret",
|
|
364
|
-
guard: { type: "have client id", params: ({ context }) => context },
|
|
338
|
+
onDone: {
|
|
339
|
+
target: "Do we have a client secret?",
|
|
340
|
+
actions: { type: "setClientId", params: ({ event }) => event },
|
|
365
341
|
},
|
|
366
342
|
},
|
|
367
343
|
},
|
|
368
344
|
"Ask for Client Secret": {
|
|
369
|
-
|
|
370
|
-
|
|
345
|
+
invoke: {
|
|
346
|
+
src: "askPassword",
|
|
347
|
+
input: {
|
|
348
|
+
message: "OAuth Client Secret:",
|
|
349
|
+
required: true,
|
|
350
|
+
},
|
|
351
|
+
onDone: {
|
|
352
|
+
target: "Creating connection definition",
|
|
371
353
|
actions: { type: "setClientSecret", params: ({ event }) => event },
|
|
372
354
|
},
|
|
373
|
-
"Submit": [
|
|
374
|
-
{
|
|
375
|
-
target: "Creating connection definition",
|
|
376
|
-
guard: { type: "have client secret", params: ({ context }) => context },
|
|
377
|
-
actions: "clearError",
|
|
378
|
-
},
|
|
379
|
-
{
|
|
380
|
-
target: "Ask for Client Secret",
|
|
381
|
-
actions: { type: "setInvalidClientSecret", params: ({ context }) => context },
|
|
382
|
-
},
|
|
383
|
-
],
|
|
384
|
-
"Previous": "Ask for Client ID",
|
|
385
355
|
},
|
|
386
356
|
},
|
|
387
357
|
"Do we have an authorize url?": {
|
|
@@ -450,15 +420,18 @@ export const addConnectionMachine = setup({
|
|
|
450
420
|
],
|
|
451
421
|
},
|
|
452
422
|
"Ask for connection type": {
|
|
453
|
-
|
|
454
|
-
|
|
423
|
+
invoke: {
|
|
424
|
+
src: "askWithChoices",
|
|
425
|
+
input: {
|
|
426
|
+
message: "What type of connection would you like to add?",
|
|
427
|
+
choices: [
|
|
428
|
+
{ name: "OAuth2 Code", value: "oauth2-code" },
|
|
429
|
+
{ name: "Secret", value: "secret" },
|
|
430
|
+
],
|
|
431
|
+
},
|
|
432
|
+
onDone: {
|
|
455
433
|
target: "Do we have a label?",
|
|
456
|
-
actions:
|
|
457
|
-
reenter: true,
|
|
458
|
-
},
|
|
459
|
-
"Next": {
|
|
460
|
-
target: "Ask for label",
|
|
461
|
-
guard: { type: "have connection type", params: ({ context }) => context },
|
|
434
|
+
actions: { type: "setConnectionType", params: ({ event }) => event },
|
|
462
435
|
},
|
|
463
436
|
},
|
|
464
437
|
},
|
|
@@ -509,57 +482,49 @@ export const addConnectionMachine = setup({
|
|
|
509
482
|
],
|
|
510
483
|
},
|
|
511
484
|
"Ask for label": {
|
|
512
|
-
|
|
513
|
-
"
|
|
485
|
+
invoke: {
|
|
486
|
+
src: "ask",
|
|
487
|
+
input: ({ context }) => ({
|
|
488
|
+
message: "What would you like to call this connection?",
|
|
489
|
+
required: true,
|
|
490
|
+
default: context.connectionType === "oauth2-code"
|
|
491
|
+
? "Connection"
|
|
492
|
+
: context.connectionType === "secret"
|
|
493
|
+
? "Access Token"
|
|
494
|
+
: "",
|
|
495
|
+
}),
|
|
496
|
+
onDone: {
|
|
514
497
|
target: "Do we have a description?",
|
|
515
|
-
guard: { type: "have label", params: ({ context }) => context },
|
|
516
|
-
reenter: true,
|
|
517
|
-
},
|
|
518
|
-
"Update Label": {
|
|
519
498
|
actions: { type: "setLabel", params: ({ event }) => event },
|
|
520
499
|
},
|
|
521
|
-
"Previous": "Ask for connection type",
|
|
522
|
-
"Next": {
|
|
523
|
-
target: "Ask for description",
|
|
524
|
-
guard: { type: "have label", params: ({ context }) => context },
|
|
525
|
-
},
|
|
526
500
|
},
|
|
527
|
-
entry: [
|
|
528
|
-
{
|
|
529
|
-
type: "initializeLabel",
|
|
530
|
-
params: ({ context }) => context,
|
|
531
|
-
},
|
|
532
|
-
],
|
|
533
501
|
},
|
|
534
502
|
"Ask for description": {
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
503
|
+
invoke: {
|
|
504
|
+
src: "ask",
|
|
505
|
+
input: {
|
|
506
|
+
message: "Description: (will be displayed in the UI)",
|
|
507
|
+
required: true,
|
|
538
508
|
},
|
|
539
|
-
|
|
509
|
+
onDone: {
|
|
540
510
|
target: "Do we have global?",
|
|
541
|
-
|
|
542
|
-
actions: "clearError",
|
|
543
|
-
},
|
|
544
|
-
"Previous": "Ask for label",
|
|
545
|
-
"Next": {
|
|
546
|
-
target: "Ask for global",
|
|
547
|
-
guard: { type: "have description", params: ({ context }) => context },
|
|
511
|
+
actions: { type: "setDescription", params: ({ event }) => event },
|
|
548
512
|
},
|
|
549
513
|
},
|
|
550
514
|
},
|
|
551
515
|
"Ask for global": {
|
|
552
|
-
|
|
553
|
-
|
|
516
|
+
invoke: {
|
|
517
|
+
src: "askWithChoices",
|
|
518
|
+
input: ({ context }) => ({
|
|
519
|
+
message: `A ${context.connectionType === "secret" ? "secret" : "token"} will be created for:`,
|
|
520
|
+
choices: [
|
|
521
|
+
{ name: "The entire workspace", value: "true" },
|
|
522
|
+
{ name: "An individual user", value: "false" },
|
|
523
|
+
],
|
|
524
|
+
}),
|
|
525
|
+
onDone: {
|
|
554
526
|
target: "Validating Global",
|
|
555
527
|
actions: { type: "setGlobal", params: ({ event }) => event },
|
|
556
|
-
reenter: true,
|
|
557
|
-
},
|
|
558
|
-
"Previous": "Ask for description",
|
|
559
|
-
"Next": {
|
|
560
|
-
target: "Validating Global",
|
|
561
|
-
guard: { type: "have global", params: ({ context }) => context },
|
|
562
|
-
reenter: true,
|
|
563
528
|
},
|
|
564
529
|
},
|
|
565
530
|
},
|
|
@@ -573,6 +538,11 @@ export const addConnectionMachine = setup({
|
|
|
573
538
|
target: "Split on connection type",
|
|
574
539
|
reenter: true,
|
|
575
540
|
},
|
|
541
|
+
"Error": {
|
|
542
|
+
target: "Error",
|
|
543
|
+
reenter: true,
|
|
544
|
+
actions: { type: "setError", params: ({ event }) => event },
|
|
545
|
+
},
|
|
576
546
|
},
|
|
577
547
|
invoke: {
|
|
578
548
|
src: "validateGlobal",
|
|
@@ -585,7 +555,5 @@ export const addConnectionMachine = setup({
|
|
|
585
555
|
},
|
|
586
556
|
},
|
|
587
557
|
initial: "Loading Developer Config",
|
|
588
|
-
|
|
589
|
-
src: "keyboard-navigation",
|
|
590
|
-
},
|
|
558
|
+
entry: "printLogo",
|
|
591
559
|
});
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { assign, setup } from "xstate";
|
|
2
|
+
import Spinner from "tiny-spinner";
|
|
2
3
|
import { codeGenMachine } from "./code-gen-machine.js";
|
|
3
4
|
import { jsMachine } from "./js-machine.js";
|
|
4
5
|
import { tsMachine } from "./ts-machine.js";
|
|
6
|
+
import { printError } from "../util/typescript.js";
|
|
7
|
+
import { printLogo } from "./actions.js";
|
|
5
8
|
const processes = ["javascript", "typescript"];
|
|
9
|
+
const spinner = new Spinner();
|
|
6
10
|
export const buildMachine = setup({
|
|
7
11
|
types: {
|
|
8
12
|
context: {},
|
|
@@ -19,9 +23,26 @@ export const buildMachine = setup({
|
|
|
19
23
|
"all success": ({ context }) => context.successful.length === processes.length,
|
|
20
24
|
},
|
|
21
25
|
actions: {
|
|
26
|
+
buildingStart: () => {
|
|
27
|
+
spinner.start("🔨 Building...");
|
|
28
|
+
},
|
|
29
|
+
buildFail: ({ self }) => {
|
|
30
|
+
spinner.error("Build failed");
|
|
31
|
+
const snapshot = self.getSnapshot();
|
|
32
|
+
const { tsErrors = [] } = snapshot.context;
|
|
33
|
+
process.stderr.write("\n");
|
|
34
|
+
tsErrors.forEach(printError);
|
|
35
|
+
},
|
|
36
|
+
buildSuccess: () => {
|
|
37
|
+
spinner.success("Build succeeded");
|
|
38
|
+
},
|
|
39
|
+
printLogo,
|
|
22
40
|
setError: assign({
|
|
23
41
|
failed: ({ context }, params) => [...context.failed, params.process],
|
|
24
42
|
}),
|
|
43
|
+
setTypeScriptErrors: assign({
|
|
44
|
+
tsErrors: ({ context }, params) => params.errors,
|
|
45
|
+
}),
|
|
25
46
|
setSuccess: assign({
|
|
26
47
|
successful: ({ context }, params) => [
|
|
27
48
|
...context.successful,
|
|
@@ -35,9 +56,11 @@ export const buildMachine = setup({
|
|
|
35
56
|
states: {
|
|
36
57
|
"Errored": {
|
|
37
58
|
type: "final",
|
|
59
|
+
entry: "buildFail",
|
|
38
60
|
},
|
|
39
61
|
"Success": {
|
|
40
62
|
type: "final",
|
|
63
|
+
entry: "buildSuccess",
|
|
41
64
|
},
|
|
42
65
|
"Building": {
|
|
43
66
|
type: "parallel",
|
|
@@ -89,10 +112,16 @@ export const buildMachine = setup({
|
|
|
89
112
|
},
|
|
90
113
|
"TypeScript Error": {
|
|
91
114
|
target: "Waiting",
|
|
92
|
-
actions:
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
115
|
+
actions: [
|
|
116
|
+
{
|
|
117
|
+
type: "setError",
|
|
118
|
+
params: { process: "typescript" },
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
type: "setTypeScriptErrors",
|
|
122
|
+
params: ({ event }) => event,
|
|
123
|
+
},
|
|
124
|
+
],
|
|
96
125
|
},
|
|
97
126
|
},
|
|
98
127
|
invoke: {
|
|
@@ -129,6 +158,7 @@ export const buildMachine = setup({
|
|
|
129
158
|
initial: "Code Generating",
|
|
130
159
|
},
|
|
131
160
|
},
|
|
161
|
+
entry: "buildingStart",
|
|
132
162
|
},
|
|
133
163
|
"All Done": {
|
|
134
164
|
always: [
|
|
@@ -144,4 +174,5 @@ export const buildMachine = setup({
|
|
|
144
174
|
},
|
|
145
175
|
},
|
|
146
176
|
initial: "Building",
|
|
177
|
+
entry: "printLogo",
|
|
147
178
|
});
|