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 CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- const buildErrorSchema = z.object({
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 errorSchema = z.object({
16
- errors: z.array(buildErrorSchema).optional(),
17
- warnings: z.array(buildErrorSchema).optional(),
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 { printError } from "../util/typescript.js";
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: ({ self }) => {
29
+ buildFail: ({ context }) => {
30
30
  spinner.error("Build failed");
31
- const snapshot = self.getSnapshot();
32
- const { tsErrors = [] } = snapshot.context;
31
+ const { tsErrors = [], jsErrors } = context;
33
32
  process.stderr.write("\n");
34
- tsErrors.forEach(printError);
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
- setError: assign({
45
+ setFailed: assign({
41
46
  failed: ({ context }, params) => [...context.failed, params.process],
42
47
  }),
43
48
  setTypeScriptErrors: assign({
44
- tsErrors: ({ context }, params) => params.errors,
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
- type: "setError",
83
- params: { process: "javascript" },
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: "setError",
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: "setError",
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 { printError } from "../util/typescript.js";
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(printError);
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
- type: "setSuccess",
345
- params: ({ event }) => event,
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 { errorSchema } from "../build.js";
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.error),
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
- error: errorSchema.parse(e),
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
- clearError: assign({
135
- error: () => undefined,
134
+ clearErrors: assign({
135
+ errors: () => undefined,
136
136
  }),
137
- raiseErrored: sendTo(({ context }) => context.parentRef, { type: "JavaScript Error" }),
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
- error: (_, params) => params.error,
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 }) => ({ error: event.error }),
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
- "clearError",
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
- <React.Suspense fallback={<Loading />}>
20
+ <Suspense fallback={<Loading />}>
21
21
  <Advice recordId={recordId} />
22
- </React.Suspense>
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
- <React.Suspense fallback={<Loading />}>
20
+ <Suspense fallback={<Loading />}>
21
21
  <Advice recordId={recordId} />
22
- </React.Suspense>
22
+ </Suspense>
23
23
  </>
24
24
  )
25
25
  }
@@ -80,7 +80,7 @@ export const getDiagnostics = async (program) => {
80
80
  }));
81
81
  return errors;
82
82
  };
83
- export function printError(error) {
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.trimLeft();
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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "attio",
3
- "version": "0.0.1-experimental.20250108",
3
+ "version": "0.0.1-experimental.20250110",
4
4
  "bin": "lib/attio.js",
5
5
  "type": "module",
6
6
  "files": [