attio 0.0.1-experimental.20250108 → 0.0.1-experimental.20250110
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/build.js +4 -4
- package/lib/machines/build-machine.js +27 -13
- package/lib/machines/dev-machine.js +36 -10
- package/lib/machines/js-machine.js +16 -10
- package/lib/templates/javascript/src/hello-world-dialog.jsx +3 -3
- package/lib/templates/typescript/src/hello-world-dialog.tsx +3 -3
- package/lib/util/typescript.js +22 -2
- package/package.json +1 -1
package/lib/build.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
const
|
|
2
|
+
const jsErrorSchema = z.object({
|
|
3
3
|
text: z.string(),
|
|
4
4
|
location: z.object({
|
|
5
5
|
column: z.number(),
|
|
@@ -12,7 +12,7 @@ const buildErrorSchema = z.object({
|
|
|
12
12
|
suggestion: z.string(),
|
|
13
13
|
}),
|
|
14
14
|
});
|
|
15
|
-
export const
|
|
16
|
-
errors: z.array(
|
|
17
|
-
warnings: z.array(
|
|
15
|
+
export const errorsAndWarningsSchema = z.object({
|
|
16
|
+
errors: z.array(jsErrorSchema).optional(),
|
|
17
|
+
warnings: z.array(jsErrorSchema).optional(),
|
|
18
18
|
});
|
|
@@ -3,7 +3,7 @@ import Spinner from "tiny-spinner";
|
|
|
3
3
|
import { codeGenMachine } from "./code-gen-machine.js";
|
|
4
4
|
import { jsMachine } from "./js-machine.js";
|
|
5
5
|
import { tsMachine } from "./ts-machine.js";
|
|
6
|
-
import {
|
|
6
|
+
import { printJsError, printTsError } from "../util/typescript.js";
|
|
7
7
|
import { printLogo } from "./actions.js";
|
|
8
8
|
const processes = ["javascript", "typescript"];
|
|
9
9
|
const spinner = new Spinner();
|
|
@@ -26,22 +26,30 @@ export const buildMachine = setup({
|
|
|
26
26
|
buildingStart: () => {
|
|
27
27
|
spinner.start("🔨 Building...");
|
|
28
28
|
},
|
|
29
|
-
buildFail: ({
|
|
29
|
+
buildFail: ({ context }) => {
|
|
30
30
|
spinner.error("Build failed");
|
|
31
|
-
const
|
|
32
|
-
const { tsErrors = [] } = snapshot.context;
|
|
31
|
+
const { tsErrors = [], jsErrors } = context;
|
|
33
32
|
process.stderr.write("\n");
|
|
34
|
-
tsErrors.forEach(
|
|
33
|
+
tsErrors.forEach(printTsError);
|
|
34
|
+
jsErrors?.errors?.forEach((error) => {
|
|
35
|
+
printJsError(error, "error");
|
|
36
|
+
});
|
|
37
|
+
jsErrors?.warnings?.forEach((warning) => {
|
|
38
|
+
printJsError(warning, "warning");
|
|
39
|
+
});
|
|
35
40
|
},
|
|
36
41
|
buildSuccess: () => {
|
|
37
42
|
spinner.success("Build succeeded");
|
|
38
43
|
},
|
|
39
44
|
printLogo,
|
|
40
|
-
|
|
45
|
+
setFailed: assign({
|
|
41
46
|
failed: ({ context }, params) => [...context.failed, params.process],
|
|
42
47
|
}),
|
|
43
48
|
setTypeScriptErrors: assign({
|
|
44
|
-
tsErrors: (
|
|
49
|
+
tsErrors: (_, params) => params.errors,
|
|
50
|
+
}),
|
|
51
|
+
setJavaScriptErrors: assign({
|
|
52
|
+
jsErrors: (_, params) => params.errors,
|
|
45
53
|
}),
|
|
46
54
|
setSuccess: assign({
|
|
47
55
|
successful: ({ context }, params) => [
|
|
@@ -78,10 +86,16 @@ export const buildMachine = setup({
|
|
|
78
86
|
},
|
|
79
87
|
"JavaScript Error": {
|
|
80
88
|
target: "Waiting",
|
|
81
|
-
actions:
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
89
|
+
actions: [
|
|
90
|
+
{
|
|
91
|
+
type: "setFailed",
|
|
92
|
+
params: { process: "javascript" },
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
type: "setJavaScriptErrors",
|
|
96
|
+
params: ({ event }) => event,
|
|
97
|
+
},
|
|
98
|
+
],
|
|
85
99
|
},
|
|
86
100
|
},
|
|
87
101
|
},
|
|
@@ -114,7 +128,7 @@ export const buildMachine = setup({
|
|
|
114
128
|
target: "Waiting",
|
|
115
129
|
actions: [
|
|
116
130
|
{
|
|
117
|
-
type: "
|
|
131
|
+
type: "setFailed",
|
|
118
132
|
params: { process: "typescript" },
|
|
119
133
|
},
|
|
120
134
|
{
|
|
@@ -142,7 +156,7 @@ export const buildMachine = setup({
|
|
|
142
156
|
"Error": {
|
|
143
157
|
target: "Waiting",
|
|
144
158
|
actions: {
|
|
145
|
-
type: "
|
|
159
|
+
type: "setFailed",
|
|
146
160
|
params: { process: "typescript" },
|
|
147
161
|
},
|
|
148
162
|
reenter: true,
|
|
@@ -17,7 +17,7 @@ import { tsMachine } from "./ts-machine.js";
|
|
|
17
17
|
import { fetchInstallation } from "../api/fetch-installation.js";
|
|
18
18
|
import Spinner from "tiny-spinner";
|
|
19
19
|
import { printMessage } from "../util/print-message.js";
|
|
20
|
-
import {
|
|
20
|
+
import { printJsError, printTsError } from "../util/typescript.js";
|
|
21
21
|
import { clearTerminal } from "../util/clear-terminal.js";
|
|
22
22
|
import { setTerminalTitle } from "../util/set-terminal-title.js";
|
|
23
23
|
import { printInstallInstructions } from "../util/print-install-instructions.js";
|
|
@@ -97,9 +97,7 @@ export const devMachine = setup({
|
|
|
97
97
|
};
|
|
98
98
|
}),
|
|
99
99
|
"prepareUpload": fromCallback(({ sendBack }) => {
|
|
100
|
-
const spinner = new Spinner();
|
|
101
100
|
const prepareUpload = async () => {
|
|
102
|
-
spinner.start("Preparing upload...");
|
|
103
101
|
const config = await loadDeveloperConfig();
|
|
104
102
|
if (typeof config === "string")
|
|
105
103
|
throw config;
|
|
@@ -116,14 +114,12 @@ export const devMachine = setup({
|
|
|
116
114
|
targetWorkspaceId: config.target_workspace_id,
|
|
117
115
|
environmentVariables,
|
|
118
116
|
});
|
|
119
|
-
spinner.success("Upload prepared");
|
|
120
117
|
sendBack({
|
|
121
118
|
type: "Upload Prepared",
|
|
122
119
|
devVersion: { ...devVersion, app_slug: app.slug },
|
|
123
120
|
});
|
|
124
121
|
};
|
|
125
122
|
prepareUpload().catch((error) => {
|
|
126
|
-
spinner.error(`Upload failed: ${error.message}`);
|
|
127
123
|
sendBack({
|
|
128
124
|
type: "Upload Error",
|
|
129
125
|
error: typeof error === "string" ? new Error(error) : error,
|
|
@@ -242,13 +238,24 @@ export const devMachine = setup({
|
|
|
242
238
|
printTypeScriptErrors: (_, params) => {
|
|
243
239
|
if (params.errors.length) {
|
|
244
240
|
clearTerminal();
|
|
245
|
-
params.errors.forEach(
|
|
241
|
+
params.errors.forEach(printTsError);
|
|
246
242
|
notifier.notify({
|
|
247
243
|
title: "TypeScript Errors",
|
|
248
244
|
message: `There were ${params.errors.length === 1 ? "one error" : `${params.errors.length} errors`} in your TypeScript code`,
|
|
249
245
|
});
|
|
250
246
|
}
|
|
251
247
|
},
|
|
248
|
+
printJavaScriptErrors: (_, params) => {
|
|
249
|
+
if (params.errors.errors?.length || params.errors.warnings?.length) {
|
|
250
|
+
clearTerminal();
|
|
251
|
+
params.errors.errors?.forEach((error) => {
|
|
252
|
+
printJsError(error, "error");
|
|
253
|
+
});
|
|
254
|
+
params.errors.warnings?.forEach((warning) => {
|
|
255
|
+
printJsError(warning, "warning");
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
},
|
|
252
259
|
promptToInstall: (_) => {
|
|
253
260
|
process.stdout.write(`\n\n🚨 IMPORTANT: You will need to install your app in your workspace. Press "i" to open the app settings page, and then click "Install".\n\n`);
|
|
254
261
|
},
|
|
@@ -264,9 +271,15 @@ export const devMachine = setup({
|
|
|
264
271
|
saveTypeScriptErrors: assign({
|
|
265
272
|
typeScriptErrors: (_, params) => params.errors,
|
|
266
273
|
}),
|
|
274
|
+
saveJavaScriptErrors: assign({
|
|
275
|
+
javaScriptErrors: (_, params) => params.errors,
|
|
276
|
+
}),
|
|
267
277
|
clearTypeScriptErrors: assign({
|
|
268
278
|
typeScriptErrors: () => [],
|
|
269
279
|
}),
|
|
280
|
+
clearJavaScriptErrors: assign({
|
|
281
|
+
javaScriptErrors: () => undefined,
|
|
282
|
+
}),
|
|
270
283
|
sendChange: enqueueActions(({ enqueue, event }) => {
|
|
271
284
|
enqueue.sendTo("javascript", event);
|
|
272
285
|
enqueue.sendTo("typescript", event);
|
|
@@ -340,14 +353,27 @@ export const devMachine = setup({
|
|
|
340
353
|
on: {
|
|
341
354
|
"JavaScript Success": {
|
|
342
355
|
target: "Upload When Ready",
|
|
343
|
-
actions:
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
356
|
+
actions: [
|
|
357
|
+
{
|
|
358
|
+
type: "setSuccess",
|
|
359
|
+
params: ({ event }) => event,
|
|
360
|
+
},
|
|
361
|
+
"clearJavaScriptErrors",
|
|
362
|
+
],
|
|
347
363
|
reenter: true,
|
|
348
364
|
},
|
|
349
365
|
"JavaScript Error": {
|
|
350
366
|
target: "Watching",
|
|
367
|
+
actions: [
|
|
368
|
+
{
|
|
369
|
+
type: "saveJavaScriptErrors",
|
|
370
|
+
params: ({ event }) => event,
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
type: "printJavaScriptErrors",
|
|
374
|
+
params: ({ event }) => event,
|
|
375
|
+
},
|
|
376
|
+
],
|
|
351
377
|
},
|
|
352
378
|
},
|
|
353
379
|
},
|
|
@@ -3,7 +3,7 @@ import fs from "fs/promises";
|
|
|
3
3
|
import path from "path";
|
|
4
4
|
import tmp from "tmp-promise";
|
|
5
5
|
import { assign, setup, fromCallback, sendTo } from "xstate";
|
|
6
|
-
import {
|
|
6
|
+
import { errorsAndWarningsSchema } from "../build.js";
|
|
7
7
|
import { createClientBuildConfig } from "../build/client/create-client-build-config.js";
|
|
8
8
|
import { generateClientEntry } from "../build/client/generate-client-entry.js";
|
|
9
9
|
import { createServerBuildConfig } from "../build/server/create-server-build-config.js";
|
|
@@ -15,7 +15,7 @@ export const jsMachine = setup({
|
|
|
15
15
|
input: {},
|
|
16
16
|
},
|
|
17
17
|
guards: {
|
|
18
|
-
"has errors": (_, params) => Boolean(params.
|
|
18
|
+
"has errors": (_, params) => Boolean(params.errors),
|
|
19
19
|
},
|
|
20
20
|
actors: {
|
|
21
21
|
prepareBuildContext: fromCallback(({ sendBack, input: { write } }) => {
|
|
@@ -122,7 +122,7 @@ export const jsMachine = setup({
|
|
|
122
122
|
catch (e) {
|
|
123
123
|
sendBack({
|
|
124
124
|
type: "Result",
|
|
125
|
-
|
|
125
|
+
errors: errorsAndWarningsSchema.parse(e),
|
|
126
126
|
time: new Date(),
|
|
127
127
|
});
|
|
128
128
|
}
|
|
@@ -131,10 +131,13 @@ export const jsMachine = setup({
|
|
|
131
131
|
}),
|
|
132
132
|
},
|
|
133
133
|
actions: {
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
clearErrors: assign({
|
|
135
|
+
errors: () => undefined,
|
|
136
136
|
}),
|
|
137
|
-
raiseErrored: sendTo(({ context }) => context.parentRef,
|
|
137
|
+
raiseErrored: sendTo(({ context }) => context.parentRef, (_, params) => ({
|
|
138
|
+
type: "JavaScript Error",
|
|
139
|
+
errors: params.errors,
|
|
140
|
+
})),
|
|
138
141
|
raiseSuccess: sendTo(({ context }, _params) => context.parentRef, (_, params) => ({
|
|
139
142
|
type: "JavaScript Success",
|
|
140
143
|
contents: params.contents,
|
|
@@ -144,7 +147,7 @@ export const jsMachine = setup({
|
|
|
144
147
|
buildContexts: (_, params) => params.buildContexts,
|
|
145
148
|
}),
|
|
146
149
|
setError: assign({
|
|
147
|
-
|
|
150
|
+
errors: (_, params) => params.errors,
|
|
148
151
|
}),
|
|
149
152
|
setTime: assign({
|
|
150
153
|
time: (_, params) => params.time,
|
|
@@ -184,9 +187,12 @@ export const jsMachine = setup({
|
|
|
184
187
|
actions: [
|
|
185
188
|
{
|
|
186
189
|
type: "setError",
|
|
187
|
-
params: ({ event }) => ({
|
|
190
|
+
params: ({ event }) => ({ errors: event.errors }),
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
type: "raiseErrored",
|
|
194
|
+
params: ({ event }) => ({ errors: event.errors }),
|
|
188
195
|
},
|
|
189
|
-
"raiseErrored",
|
|
190
196
|
],
|
|
191
197
|
},
|
|
192
198
|
{
|
|
@@ -200,7 +206,7 @@ export const jsMachine = setup({
|
|
|
200
206
|
time: event.time,
|
|
201
207
|
}),
|
|
202
208
|
},
|
|
203
|
-
"
|
|
209
|
+
"clearErrors",
|
|
204
210
|
],
|
|
205
211
|
},
|
|
206
212
|
],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react"
|
|
2
|
-
import {TextBlock} from "attio/client"
|
|
2
|
+
import {TextBlock, Suspense} from "attio/client"
|
|
3
3
|
import {Advice} from "./advice"
|
|
4
4
|
|
|
5
5
|
const Loading = () => <TextBlock>Loading advice...</TextBlock>
|
|
@@ -17,9 +17,9 @@ export function HelloWorldDialog ({recordId}) {
|
|
|
17
17
|
I am a dialog. I have been open for: {seconds} second{seconds === 1 ? "" : "s"}
|
|
18
18
|
</TextBlock>
|
|
19
19
|
{/* The hook in Advice will suspend until the advice is loaded. */}
|
|
20
|
-
<
|
|
20
|
+
<Suspense fallback={<Loading />}>
|
|
21
21
|
<Advice recordId={recordId} />
|
|
22
|
-
</
|
|
22
|
+
</Suspense>
|
|
23
23
|
</>
|
|
24
24
|
)
|
|
25
25
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react"
|
|
2
|
-
import {TextBlock} from "attio/client"
|
|
2
|
+
import {TextBlock, Suspense} from "attio/client"
|
|
3
3
|
import {Advice} from "./advice"
|
|
4
4
|
|
|
5
5
|
const Loading = () => <TextBlock>Loading advice...</TextBlock>
|
|
@@ -17,9 +17,9 @@ export function HelloWorldDialog({recordId}: {recordId: string}) {
|
|
|
17
17
|
I am a dialog. I have been open for: {seconds} second{seconds === 1 ? "" : "s"}
|
|
18
18
|
</TextBlock>
|
|
19
19
|
{/* The hook in Advice will suspend until the advice is loaded. */}
|
|
20
|
-
<
|
|
20
|
+
<Suspense fallback={<Loading />}>
|
|
21
21
|
<Advice recordId={recordId} />
|
|
22
|
-
</
|
|
22
|
+
</Suspense>
|
|
23
23
|
</>
|
|
24
24
|
)
|
|
25
25
|
}
|
package/lib/util/typescript.js
CHANGED
|
@@ -80,7 +80,7 @@ export const getDiagnostics = async (program) => {
|
|
|
80
80
|
}));
|
|
81
81
|
return errors;
|
|
82
82
|
};
|
|
83
|
-
export function
|
|
83
|
+
export function printTsError(error) {
|
|
84
84
|
if (!error.location) {
|
|
85
85
|
process.stderr.write(`${chalk.red("×")} – ${error.text}\n`);
|
|
86
86
|
return;
|
|
@@ -90,7 +90,7 @@ export function printError(error) {
|
|
|
90
90
|
const emptyLine = " ".repeat(lineStringLength);
|
|
91
91
|
const lineText = error.location.lineText;
|
|
92
92
|
const leadingSpaces = lineText.match(/^\s*/)?.[0].length || 0;
|
|
93
|
-
const trimmedLineText = lineText.
|
|
93
|
+
const trimmedLineText = lineText.trimStart();
|
|
94
94
|
const beforeError = trimmedLineText.slice(0, error.location.character - leadingSpaces);
|
|
95
95
|
const errorText = trimmedLineText.slice(error.location.character - leadingSpaces, error.location.endCharacter - leadingSpaces);
|
|
96
96
|
const afterError = trimmedLineText.slice(error.location.endCharacter - leadingSpaces);
|
|
@@ -100,3 +100,23 @@ export function printError(error) {
|
|
|
100
100
|
process.stderr.write(`${emptyLine} │ ${" ".repeat(Math.max(0, error.location.character - leadingSpaces))}${chalk.red("~".repeat(error.location.endCharacter - error.location.character))}\n`);
|
|
101
101
|
process.stderr.write(`${emptyLine} ╰───\n\n`);
|
|
102
102
|
}
|
|
103
|
+
export function printJsError(error, type) {
|
|
104
|
+
if (!error.location) {
|
|
105
|
+
process.stderr.write(`${chalk.red("×")} – ${error.text}\n`);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const lineString = error.location.line.toLocaleString().padStart(3, " ");
|
|
109
|
+
const lineStringLength = lineString.length;
|
|
110
|
+
const emptyLine = " ".repeat(lineStringLength);
|
|
111
|
+
const lineText = error.location.lineText;
|
|
112
|
+
const leadingSpaces = lineText.match(/^\s*/)?.[0].length || 0;
|
|
113
|
+
const trimmedLineText = lineText.trimStart();
|
|
114
|
+
const beforeError = trimmedLineText.slice(0, error.location.column - leadingSpaces);
|
|
115
|
+
const errorText = trimmedLineText.slice(error.location.column - leadingSpaces, error.location.column + error.location.length - leadingSpaces);
|
|
116
|
+
const afterError = trimmedLineText.slice(error.location.column + error.location.length - leadingSpaces);
|
|
117
|
+
process.stderr.write(`${" ".repeat(lineStringLength - 2)} ${type === "error" ? chalk.red("×") : "🚧"} ${error.text}\n\n`);
|
|
118
|
+
process.stderr.write(`${emptyLine} ╭─── ${chalk.bold(error.location.file)}\n`);
|
|
119
|
+
process.stderr.write(`${lineString} │ ${beforeError}${chalk.red(errorText)}${afterError}\n`);
|
|
120
|
+
process.stderr.write(`${emptyLine} │ ${" ".repeat(Math.max(0, error.location.column - leadingSpaces))}${chalk.red("~".repeat(error.location.length))}\n`);
|
|
121
|
+
process.stderr.write(`${emptyLine} ╰───\n\n`);
|
|
122
|
+
}
|