attio 0.0.1-experimental.20241226 → 0.0.1-experimental.20250108

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 (54) hide show
  1. package/lib/api/create-version.js +2 -2
  2. package/lib/attio-logo.js +24 -0
  3. package/lib/attio.js +17 -8
  4. package/lib/commands/build.js +18 -35
  5. package/lib/commands/connection/add.js +51 -168
  6. package/lib/commands/connection/index.js +9 -1
  7. package/lib/commands/connection/list.js +17 -47
  8. package/lib/commands/connection/remove.js +17 -65
  9. package/lib/commands/create.js +27 -126
  10. package/lib/commands/dev.js +17 -106
  11. package/lib/commands/version/create.js +17 -68
  12. package/lib/commands/version/index.js +11 -1
  13. package/lib/commands/version/invite.js +40 -84
  14. package/lib/commands/version/list.js +18 -40
  15. package/lib/commands/version/publish.js +40 -64
  16. package/lib/machines/actions.js +7 -0
  17. package/lib/machines/actors.js +26 -1
  18. package/lib/machines/add-connection-machine.js +169 -201
  19. package/lib/machines/build-machine.js +35 -4
  20. package/lib/machines/create-machine.js +95 -70
  21. package/lib/machines/create-version-machine.js +152 -7
  22. package/lib/machines/dev-machine.js +173 -53
  23. package/lib/machines/generate-invite-machine.js +64 -10
  24. package/lib/machines/list-connections-machine.js +57 -2
  25. package/lib/machines/list-versions-machine.js +47 -14
  26. package/lib/machines/publish-version-machine.js +45 -16
  27. package/lib/machines/remove-connection-machine.js +64 -17
  28. package/lib/machines/ts-machine.js +4 -1
  29. package/lib/server/attio-fetch.d.ts +3 -2
  30. package/lib/tsconfig.tsbuildinfo +1 -1
  31. package/lib/util/clear-terminal.js +4 -0
  32. package/lib/util/load-developer-config.js +2 -2
  33. package/lib/util/print-install-instructions.js +32 -0
  34. package/lib/util/print-message.js +9 -0
  35. package/lib/util/set-terminal-title.js +8 -0
  36. package/lib/util/text-gradient.js +28 -0
  37. package/lib/util/typescript.js +25 -0
  38. package/package.json +13 -12
  39. package/lib/components/BuildError.js +0 -46
  40. package/lib/components/BuildLog.js +0 -6
  41. package/lib/components/CodeGenErrors.js +0 -22
  42. package/lib/components/Disclaimer.js +0 -9
  43. package/lib/components/InitialInstructions.js +0 -69
  44. package/lib/components/Log.js +0 -69
  45. package/lib/components/Logo.js +0 -10
  46. package/lib/components/MultiSelect.js +0 -65
  47. package/lib/components/ScrollBox.js +0 -87
  48. package/lib/components/ScrollBox.store.js +0 -36
  49. package/lib/components/ScrollBox.util.js +0 -27
  50. package/lib/components/Select.js +0 -6
  51. package/lib/components/Table.js +0 -33
  52. package/lib/components/TypeScriptErrors.js +0 -38
  53. package/lib/hooks/useFullScreen.js +0 -22
  54. package/lib/hooks/useTerminalTitle.js +0 -11
@@ -1,69 +0,0 @@
1
- import { Box, Text } from "ink";
2
- import React from "react";
3
- const emojis = {
4
- log: "📝",
5
- info: "💬",
6
- warn: "🔸",
7
- error: "🚨",
8
- };
9
- class GlobalLog {
10
- constructor() {
11
- this._messages = [];
12
- this._listeners = new Map();
13
- this._nextListenerId = 0;
14
- }
15
- notifyListeners() {
16
- this._listeners.forEach((listener) => listener());
17
- }
18
- addMessage(level, messages) {
19
- this._messages.push({
20
- level,
21
- message: messages
22
- .map((message) => typeof message === "string"
23
- ? message
24
- : typeof message === "number"
25
- ? message.toString()
26
- : JSON.stringify(message, null, 2))
27
- .join(" "),
28
- });
29
- this.notifyListeners();
30
- }
31
- log(...messages) {
32
- this.addMessage("log", messages);
33
- }
34
- info(...messages) {
35
- this.addMessage("info", messages);
36
- }
37
- warn(...messages) {
38
- this.addMessage("warn", messages);
39
- }
40
- error(...messages) {
41
- this.addMessage("error", messages);
42
- }
43
- clear() {
44
- this._messages = [];
45
- this.notifyListeners();
46
- }
47
- getMessages() {
48
- return this._messages;
49
- }
50
- listen(listener) {
51
- const id = this._nextListenerId++;
52
- this._listeners.set(id, listener);
53
- return () => this._listeners.delete(id);
54
- }
55
- }
56
- const globalLog = new GlobalLog();
57
- export const log = (...messages) => globalLog.log(...messages);
58
- export const info = (...messages) => globalLog.info(...messages);
59
- export const warn = (...messages) => globalLog.warn(...messages);
60
- export const error = (...messages) => globalLog.error(...messages);
61
- export const Log = () => {
62
- const messages = React.useSyncExternalStore(() => globalLog.listen(() => {
63
- }), () => globalLog.getMessages(), () => []);
64
- if (messages.length === 0)
65
- return null;
66
- return (React.createElement(Box, { flexDirection: "column", paddingY: 1 }, messages.map((message, index) => (React.createElement(Box, { key: index, flexDirection: "row", gap: 1 },
67
- React.createElement(Text, null, emojis[message.level]),
68
- React.createElement(Text, null, message.message))))));
69
- };
@@ -1,10 +0,0 @@
1
- import { Box } from "ink";
2
- import BigText from "ink-big-text";
3
- import Gradient from "ink-gradient";
4
- import React from "react";
5
- import { Disclaimer } from "./Disclaimer.js";
6
- export const Logo = () => (React.createElement(Box, { flexDirection: "column" },
7
- React.createElement(Box, null,
8
- React.createElement(Gradient, { name: "morning" },
9
- React.createElement(BigText, { text: "/. Attio" }))),
10
- React.createElement(Disclaimer, null)));
@@ -1,65 +0,0 @@
1
- import figures from "figures";
2
- import { Box, Text, useStdin } from "ink";
3
- import React from "react";
4
- const ARROW_UP = "\u001B[A";
5
- const ARROW_DOWN = "\u001B[B";
6
- const ENTER = "\r";
7
- const SPACE = " ";
8
- export function MultiSelect({ items, requiredMin = 0, onSubmit, }) {
9
- const [activeIndex, setActiveIndex] = React.useState(0);
10
- const [selectedValues, setSelectedValues] = React.useState(new Set());
11
- const { stdin, setRawMode } = useStdin();
12
- React.useEffect(() => {
13
- setRawMode(true);
14
- return () => setRawMode(false);
15
- }, [setRawMode]);
16
- React.useEffect(() => {
17
- const handleInput = (data) => {
18
- switch (data) {
19
- case ARROW_UP:
20
- case "k":
21
- setActiveIndex((prev) => (prev - 1 + items.length) % items.length);
22
- break;
23
- case ARROW_DOWN:
24
- case "j":
25
- setActiveIndex((prev) => (prev + 1) % items.length);
26
- break;
27
- case SPACE:
28
- setSelectedValues((prev) => {
29
- const newSelectedValues = new Set(prev);
30
- const item = items[activeIndex];
31
- if (newSelectedValues.has(item.value)) {
32
- newSelectedValues.delete(item.value);
33
- }
34
- else {
35
- newSelectedValues.add(item.value);
36
- }
37
- return newSelectedValues;
38
- });
39
- break;
40
- case ENTER:
41
- if (selectedValues.size < requiredMin)
42
- break;
43
- onSubmit(Array.from(selectedValues));
44
- break;
45
- }
46
- };
47
- stdin.on("data", handleInput);
48
- return () => {
49
- stdin.removeListener("data", handleInput);
50
- };
51
- }, [activeIndex, items, onSubmit, requiredMin, selectedValues, stdin]);
52
- return (React.createElement(Box, { flexDirection: "column" }, items.map((item, index) => {
53
- const isHighlighted = index === activeIndex;
54
- const isSelected = selectedValues.has(item.value);
55
- return (React.createElement(Box, { key: item.value },
56
- React.createElement(Text, { color: isSelected ? "yellow" : isHighlighted ? "green" : "white" },
57
- React.createElement(Text, null,
58
- isHighlighted ? figures.pointer : " ",
59
- " "),
60
- React.createElement(Text, { color: isSelected ? "yellow" : undefined },
61
- isSelected ? figures.circleFilled : figures.circle,
62
- " "),
63
- React.createElement(Text, null, item.label))));
64
- })));
65
- }
@@ -1,87 +0,0 @@
1
- import { useSelector } from "@xstate/react";
2
- import { Box, Text, measureElement, useInput } from "ink";
3
- import React from "react";
4
- import { useFullScreen } from "../hooks/useFullScreen.js";
5
- import { useScrollBoxStore } from "./ScrollBox.store.js";
6
- import { calculateChildRange } from "./ScrollBox.util.js";
7
- const GAP = 1;
8
- export const ScrollBox = React.memo(({ padding, ...props }) => {
9
- const { height: screenHeight, width } = useFullScreen();
10
- const [top, setTop] = React.useState(0);
11
- const height = Number(screenHeight) - top;
12
- const availableHeight = height - (props.borderStyle ? 2 : 0) - (padding ?? 0) * 2;
13
- const children = React.useMemo(() => React.Children.toArray(props.children).filter((element) => Boolean(element) && React.isValidElement(element)), [props.children]);
14
- const store = useScrollBoxStore(children.length, availableHeight, Number(width ?? ""));
15
- const boxRef = React.useCallback((element) => setTop(element?.yogaNode?.getComputedTop() ?? 0), []);
16
- const heights = useSelector(store, (state) => state.context.heights);
17
- const offset = useSelector(store, (state) => state.context.offset);
18
- const allMeasured = heights.length === children.length;
19
- const haveOverflow = allMeasured && heights.reduce((a, b) => a + b, 0) > availableHeight;
20
- const childRange = calculateChildRange(heights, offset, availableHeight);
21
- const itemsShown = childRange[1] - childRange[0];
22
- const hiddenAbove = offset;
23
- const hiddenBelow = children.length - (offset + itemsShown);
24
- useInput((input, key) => {
25
- if (input === "j" || key.downArrow) {
26
- if (key.meta) {
27
- store.send({ type: "Page Down" });
28
- }
29
- else {
30
- store.send({ type: "Down" });
31
- }
32
- }
33
- else if (input === "k" || key.upArrow) {
34
- if (key.meta) {
35
- store.send({ type: "Page Up" });
36
- }
37
- else {
38
- store.send({ type: "Up" });
39
- }
40
- }
41
- else if (input === " " || (input === "d" && key.ctrl)) {
42
- store.send({ type: "Page Down" });
43
- }
44
- else if (input === "b" || (input === "u" && key.ctrl)) {
45
- store.send({ type: "Page Up" });
46
- }
47
- else if (input === "G") {
48
- store.send({ type: "Bottom" });
49
- }
50
- });
51
- return (React.createElement(Box, { ...props, height: height, ref: boxRef, flexDirection: "column" },
52
- haveOverflow && (React.createElement(Box, { flexDirection: "column", alignItems: "center", marginBottom: -1 }, hiddenAbove > 0 ? (React.createElement(Text, null,
53
- "+ ",
54
- hiddenAbove,
55
- " item",
56
- hiddenAbove === 1 ? "" : "s",
57
- " ... press \u2191 to scroll",
58
- " ")) : (React.createElement(Text, null, " ")))),
59
- React.createElement(Box, { flexDirection: "column", gap: GAP, flexGrow: 1, padding: padding }, allMeasured
60
- ? children.map((child, index) => index >= childRange[0] && index < childRange[1]
61
- ? React.cloneElement(child, {
62
- ref: (element) => {
63
- const height = element
64
- ? measureElement(element).height + GAP
65
- : 0;
66
- if (!height)
67
- return;
68
- store.send({ type: "Item Measured", index, height });
69
- },
70
- })
71
- : null)
72
- :
73
- React.cloneElement(children[heights.length], {
74
- ref: (element) => {
75
- const height = element ? measureElement(element).height + GAP : 0;
76
- if (!height)
77
- return;
78
- store.send({ type: "Item Measured", index: heights.length, height });
79
- },
80
- })),
81
- haveOverflow && (React.createElement(Box, { flexDirection: "column", alignItems: "center", marginTop: -1 }, hiddenBelow > 0 ? (React.createElement(Text, null,
82
- "+ ",
83
- hiddenBelow,
84
- " item",
85
- hiddenBelow === 1 ? "" : "s",
86
- " ... press \u2193 to scroll")) : (React.createElement(Text, null, " "))))));
87
- });
@@ -1,36 +0,0 @@
1
- import { createStoreWithProducer } from "@xstate/store";
2
- import { produce } from "immer";
3
- import React from "react";
4
- import { calculateChildRange, calculateLastPageOffset, calculatePreviousPageOffset, } from "./ScrollBox.util.js";
5
- const initial = {
6
- offset: 0,
7
- heights: [],
8
- };
9
- export function useScrollBoxStore(numChildren, availableHeight, width) {
10
- return React.useMemo(() => createStoreWithProducer(produce, initial, {
11
- "Down": (context) => {
12
- const [, end] = calculateChildRange(context.heights, context.offset, availableHeight);
13
- if (end < numChildren) {
14
- context.offset = Math.min(context.offset + 1, numChildren - 1);
15
- }
16
- },
17
- "Up": (context) => {
18
- context.offset = Math.max(context.offset - 1, 0);
19
- },
20
- "Page Down": (context) => {
21
- const [, end] = calculateChildRange(context.heights, context.offset, availableHeight);
22
- if (end < numChildren - 1) {
23
- context.offset = end;
24
- }
25
- },
26
- "Page Up": (context) => {
27
- context.offset = calculatePreviousPageOffset(context.heights, context.offset, availableHeight);
28
- },
29
- "Bottom": (context) => {
30
- context.offset = calculateLastPageOffset(context.heights, context.offset, availableHeight);
31
- },
32
- "Item Measured": (context, { index, height }) => {
33
- context.heights[index] = height;
34
- },
35
- }), [availableHeight, numChildren, width]);
36
- }
@@ -1,27 +0,0 @@
1
- export function calculateChildRange(heights, offset, availableHeight) {
2
- let heightUsed = 0;
3
- for (let index = offset; index < heights.length; index++) {
4
- heightUsed += heights[index];
5
- if (heightUsed > availableHeight)
6
- return [offset, Math.max(index, 1)];
7
- }
8
- return [offset, heights.length];
9
- }
10
- export function calculatePreviousPageOffset(heights, offset, availableHeight) {
11
- let heightUsed = 0;
12
- for (let index = offset - 1; index > 0; index--) {
13
- heightUsed += heights[index];
14
- if (heightUsed > availableHeight)
15
- return index + 1;
16
- }
17
- return 0;
18
- }
19
- export function calculateLastPageOffset(heights, offset, availableHeight) {
20
- let heightUsed = 0;
21
- for (let index = heights.length - 1; index > 0; index--) {
22
- heightUsed += heights[index];
23
- if (heightUsed > availableHeight)
24
- return index + 1;
25
- }
26
- return 0;
27
- }
@@ -1,6 +0,0 @@
1
- import { Text } from "ink";
2
- import SelectInput from "ink-select-input";
3
- import React from "react";
4
- export function Select({ initialValue, items, onSelect }) {
5
- return (React.createElement(SelectInput, { items: items.map((item) => ({ ...item, key: item.label })), onSelect: ({ value }) => onSelect(value), initialIndex: initialValue ? items.findIndex((item) => item.value === initialValue) : 0, indicatorComponent: ({ isSelected }) => isSelected ? React.createElement(Text, { color: "green" }, "> ") : React.createElement(Text, null, " "), itemComponent: ({ isSelected, label }) => (React.createElement(Text, { color: isSelected ? "green" : "white" }, label)) }));
6
- }
@@ -1,33 +0,0 @@
1
- import { Box, Text } from "ink";
2
- import React from "react";
3
- export function Table({ rows, }) {
4
- const columns = React.useMemo(() => (rows.length > 0 ? Object.keys(rows[0]) : []), [rows]);
5
- const widths = React.useMemo(() => {
6
- return rows.reduce((acc, row) => {
7
- columns.forEach((column) => {
8
- acc[column] = Math.max(acc[column] ?? 0, row[column].length);
9
- });
10
- return acc;
11
- }, columns.reduce((acc, column) => {
12
- acc[column] = column.length;
13
- return acc;
14
- }, {}));
15
- }, [rows, columns]);
16
- const flexWidths = React.useMemo(() => {
17
- return columns.reduce((acc, column) => {
18
- acc[column] = {
19
- flexDirection: "row",
20
- flexGrow: widths[column],
21
- flexShrink: widths[column],
22
- flexBasis: widths[column],
23
- justifyContent: "center",
24
- };
25
- return acc;
26
- }, {});
27
- }, [columns, widths]);
28
- return (React.createElement(Box, { flexDirection: "column", width: "100%" },
29
- React.createElement(Box, { flexDirection: "row", width: "100%" }, columns.map((column, index) => (React.createElement(Box, { key: index, ...flexWidths[column], borderTop: false, borderLeft: false, borderRight: false, borderStyle: "single" },
30
- React.createElement(Text, { color: "blue" }, column))))),
31
- rows.map((row, rowIndex) => (React.createElement(Box, { key: rowIndex, flexDirection: "row", width: "100%", borderStyle: "single", borderTop: rowIndex > 0, borderLeft: false, borderRight: false, borderBottom: rowIndex === rows.length - 1 }, columns.map((column, columnIndex) => (React.createElement(Box, { key: columnIndex, ...flexWidths[column] },
32
- React.createElement(Text, null, row[column])))))))));
33
- }
@@ -1,38 +0,0 @@
1
- import { Box, Text } from "ink";
2
- import React from "react";
3
- const Error = React.forwardRef(({ error }, ref) => {
4
- return (React.createElement(Box, { flexDirection: "column", ref: ref },
5
- React.createElement(Box, null,
6
- React.createElement(Text, { color: "red" },
7
- React.createElement(Text, { backgroundColor: "red", color: "white" },
8
- " ",
9
- "TYPESCRIPT ERROR",
10
- " "),
11
- " "),
12
- React.createElement(Text, { bold: true }, error.text)),
13
- error.location && (React.createElement(Box, { paddingTop: 1, flexDirection: "column" },
14
- React.createElement(Box, { marginLeft: 4 },
15
- React.createElement(Text, null,
16
- error.location.file,
17
- ":",
18
- error.location.line,
19
- ":",
20
- error.location.character)),
21
- React.createElement(Box, { marginLeft: 4, marginTop: 1 },
22
- React.createElement(Box, { flexDirection: "column", marginRight: 1 },
23
- React.createElement(Text, null, error.location.line)),
24
- React.createElement(Box, { flexDirection: "column" },
25
- React.createElement(Text, null,
26
- "| ",
27
- error.location.lineText.trim()),
28
- React.createElement(Box, null,
29
- React.createElement(Text, null, "|"),
30
- React.createElement(Box, { paddingLeft: error.location.character +
31
- error.location.lineText.trim().length -
32
- error.location.lineText.length +
33
- 1 },
34
- React.createElement(Text, { color: "greenBright" }, "^")))))))));
35
- });
36
- export function renderTypeScriptErrors(errors) {
37
- return errors.map((error, index) => React.createElement(Error, { key: `TypeScriptError-${index}`, error: error }));
38
- }
@@ -1,22 +0,0 @@
1
- import { useStdout } from "ink";
2
- import React from "react";
3
- export const useFullScreen = () => {
4
- const { stdout } = useStdout();
5
- const [columns, setColumns] = React.useState(stdout.columns);
6
- const [rows, setRows] = React.useState(stdout.rows);
7
- React.useEffect(() => {
8
- const handleResize = () => {
9
- setColumns(stdout.columns);
10
- setRows(stdout.rows);
11
- };
12
- stdout.addListener("resize", handleResize);
13
- stdout.write("\x1b[?1049h");
14
- process.on("beforeExit", () => {
15
- stdout.write("\x1b[?1049l");
16
- });
17
- return () => {
18
- stdout.removeListener("resize", handleResize);
19
- };
20
- }, []);
21
- return { width: columns, height: rows };
22
- };
@@ -1,11 +0,0 @@
1
- import React from "react";
2
- export function useTerminalTitle(title) {
3
- React.useEffect(() => {
4
- if (process.platform === "win32") {
5
- process.title = title;
6
- }
7
- else {
8
- process.stdout.write(`\x1B]2;${title}\x1B\x5C`);
9
- }
10
- }, [title]);
11
- }