From 2057176f6304d2ba0638551c0bc55843a52eefce Mon Sep 17 00:00:00 2001
From: SorayaFerreira
Date: Mon, 24 Nov 2025 18:11:19 -0400
Subject: [PATCH 1/7] ref: replace forced window.location.reload() with SPA
navigation via publicAppRouterInstance.replace, falling back to
window.location.replace
---
packages/core/src/src.und/id.txt | 1 +
packages/core/src/src.und/settings.xml | 222 +++++++++++++++++++++++++
2 files changed, 223 insertions(+)
create mode 100644 packages/core/src/src.und/id.txt
create mode 100644 packages/core/src/src.und/settings.xml
diff --git a/packages/core/src/src.und/id.txt b/packages/core/src/src.und/id.txt
new file mode 100644
index 0000000..259d958
--- /dev/null
+++ b/packages/core/src/src.und/id.txt
@@ -0,0 +1 @@
+{e4051284-b6e5-43f9-a499-cdaa25138434}
\ No newline at end of file
diff --git a/packages/core/src/src.und/settings.xml b/packages/core/src/src.und/settings.xml
new file mode 100644
index 0000000..1d6d072
--- /dev/null
+++ b/packages/core/src/src.und/settings.xml
@@ -0,0 +1,222 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From f75ed78fbf973f9fef01daa805f638cb19362902 Mon Sep 17 00:00:00 2001
From: tony
Date: Mon, 24 Nov 2025 18:58:03 -0400
Subject: [PATCH 2/7] refactor: Fixing too many props issue
---
.../sb-react/src/dnd/drag-line.stories.tsx | 119 ++++++++++--------
1 file changed, 65 insertions(+), 54 deletions(-)
diff --git a/packages/sb-react/src/dnd/drag-line.stories.tsx b/packages/sb-react/src/dnd/drag-line.stories.tsx
index 83868fa..e63488b 100644
--- a/packages/sb-react/src/dnd/drag-line.stories.tsx
+++ b/packages/sb-react/src/dnd/drag-line.stories.tsx
@@ -7,6 +7,7 @@ import {
keyboardDragAndDropFeature,
selectionFeature,
syncDataLoaderFeature,
+ TreeItemInstance,
} from "@headless-tree/core";
import { AssistiveTreeDescription, useTree } from "@headless-tree/react";
import cn from "classnames";
@@ -18,79 +19,89 @@ const meta = {
export default meta;
-// story-start
+const STATIC_FEATURES = [
+ syncDataLoaderFeature,
+ selectionFeature,
+ hotkeysCoreFeature,
+ dragAndDropFeature,
+ keyboardDragAndDropFeature,
+];
+
+const mockDataLoader = {
+ getItem: (itemId: string) => itemId,
+ getChildren: (itemId: string) =>
+ Array.from({ length: 6 }, (_, i) => `${itemId}-${i + 1}`),
+};
+
+const handleDrop = (items: TreeItemInstance[], target: any) => {
+ alert(
+ `Dropped ${items.map((item) => item.getId())} on ${target.item.getId()}, ${JSON.stringify(target)}`
+ );
+};
+
+interface TreeItemRowProps {
+ item: TreeItemInstance;
+}
+
+const TreeItemRow = React.memo(({ item }: TreeItemRowProps) => {
+ return (
+
+ );
+});
+
+TreeItemRow.displayName = "TreeItemRow";
+
export const DragLine = () => {
- const [state, setState] = useState>>({
+ const [state, setState] = useState>>({
expandedItems: ["root-1", "root-1-2"],
});
+
const tree = useTree({
state,
setState,
rootItemId: "root",
+ dataLoader: mockDataLoader,
+ onDrop: handleDrop,
getItemName: (item) => item.getItemData(),
isItemFolder: () => true,
canReorder: true,
- onDrop: (items, target) => {
- alert(
- `Dropped ${items.map((item) =>
- item.getId(),
- )} on ${target.item.getId()}, ${JSON.stringify(target)}`,
- );
- },
indent: 20,
- dataLoader: {
- getItem: (itemId) => itemId,
- getChildren: (itemId) => [
- `${itemId}-1`,
- `${itemId}-2`,
- `${itemId}-3`,
- `${itemId}-4`,
- `${itemId}-5`,
- `${itemId}-6`,
- ],
- },
- features: [
- syncDataLoaderFeature,
- selectionFeature,
- hotkeysCoreFeature,
- dragAndDropFeature,
- keyboardDragAndDropFeature,
- ],
+ features: STATIC_FEATURES,
});
- const dragLine = tree.getDragLineData();
+ const dragLineStyle = tree.getDragLineStyle();
+ const dragLineData = tree.getDragLineData();
+ const items = tree.getItems();
return (
- {tree.getItems().map((item) => (
-
+
+ {items.map((item) => (
+
))}
-
+
+ {dragLineData && (
+
+ )}
+
- {JSON.stringify(
- {
- dragLine,
- },
- null,
- 2,
- )}
+ {JSON.stringify({ dragLine: dragLineData }, null, 2)}
);
From 852059122844f717ea4e977310048d4880389b7e Mon Sep 17 00:00:00 2001
From: tony
Date: Mon, 24 Nov 2025 19:00:27 -0400
Subject: [PATCH 3/7] refactor: refactoring file to avoid too many props issue
---
.../sb-react/src/dnd/drag-preview.stories.tsx | 168 +++++++++++-------
1 file changed, 99 insertions(+), 69 deletions(-)
diff --git a/packages/sb-react/src/dnd/drag-preview.stories.tsx b/packages/sb-react/src/dnd/drag-preview.stories.tsx
index ef49252..b8504fc 100644
--- a/packages/sb-react/src/dnd/drag-preview.stories.tsx
+++ b/packages/sb-react/src/dnd/drag-preview.stories.tsx
@@ -7,6 +7,7 @@ import {
keyboardDragAndDropFeature,
selectionFeature,
syncDataLoaderFeature,
+ TreeItemInstance,
} from "@headless-tree/core";
import { AssistiveTreeDescription, useTree } from "@headless-tree/react";
import cn from "classnames";
@@ -18,12 +19,99 @@ const meta = {
export default meta;
-// story-start
+const STATIC_FEATURES = [
+ syncDataLoaderFeature,
+ selectionFeature,
+ hotkeysCoreFeature,
+ dragAndDropFeature,
+ keyboardDragAndDropFeature,
+];
+
+const mockDataLoader = {
+ getItem: (itemId: string) => itemId,
+ getChildren: (itemId: string) => [
+ `${itemId}-1`,
+ `${itemId}-2`,
+ `${itemId}-3`,
+ `${itemId}-4`,
+ ],
+};
+
+const handleDrop = (items: TreeItemInstance[], target: any) => {
+ alert(
+ `Dropped ${items.map((item) => item.getId())} on ${target.item.getId()}, ${JSON.stringify(target)}`
+ );
+};
+
+const handleSetDragImage = () => ({
+ imgElement: document.getElementById("dragpreview")!,
+ xOffset: -20,
+});
+
+interface CustomDragPreviewProps {
+ draggedItems?: TreeItemInstance[];
+}
+
+const CustomDragPreview = React.memo(({ draggedItems }: CustomDragPreviewProps) => {
+ return (
+
+ Dragging{" "}
+ {draggedItems
+ ?.slice(0, 3)
+ .map((item) => item.getItemName())
+ .join(", ")}
+ {(draggedItems?.length ?? 0) > 3 &&
+ ` and ${(draggedItems?.length ?? 0) - 3} more`}
+
+ );
+});
+
+CustomDragPreview.displayName = "CustomDragPreview";
+
+interface TreeItemRowProps {
+ item: TreeItemInstance;
+}
+
+const TreeItemRow = React.memo(({ item }: TreeItemRowProps) => {
+ return (
+
+ );
+});
+
+TreeItemRow.displayName = "TreeItemRow";
+
export const DragPreview = () => {
- const [state, setState] = useState>>({
+ const [state, setState] = useState>>({
expandedItems: ["root-1", "root-1-2"],
selectedItems: ["root-1-2-1", "root-1-2-2", "root-1-2-3", "root-1-2-4"],
});
+
const tree = useTree({
state,
setState,
@@ -31,34 +119,11 @@ export const DragPreview = () => {
getItemName: (item) => item.getItemData(),
isItemFolder: () => true,
canReorder: true,
- onDrop: (items, target) => {
- alert(
- `Dropped ${items.map((item) =>
- item.getId(),
- )} on ${target.item.getId()}, ${JSON.stringify(target)}`,
- );
- },
- setDragImage: () => ({
- imgElement: document.getElementById("dragpreview")!,
- xOffset: -20,
- }),
+ onDrop: handleDrop,
+ setDragImage: handleSetDragImage,
indent: 20,
- dataLoader: {
- getItem: (itemId) => itemId,
- getChildren: (itemId) => [
- `${itemId}-1`,
- `${itemId}-2`,
- `${itemId}-3`,
- `${itemId}-4`,
- ],
- },
- features: [
- syncDataLoaderFeature,
- selectionFeature,
- hotkeysCoreFeature,
- dragAndDropFeature,
- keyboardDragAndDropFeature,
- ],
+ dataLoader: mockDataLoader,
+ features: STATIC_FEATURES,
});
const draggedItems = tree.getState().dnd?.draggedItems;
@@ -71,49 +136,14 @@ export const DragPreview = () => {
+
{tree.getItems().map((item) => (
-
+
))}
+
-
- Dragging{" "}
- {draggedItems
- ?.slice(0, 3)
- .map((item) => item.getItemName())
- .join(", ")}
- {(draggedItems?.length ?? 0) > 3 &&
- ` and ${(draggedItems?.length ?? 0) - 3} more`}
-
+
+
>
);
From dce6832f005181e318fca68692b76263c30538e1 Mon Sep 17 00:00:00 2001
From: Mylenna Farias <134342470+mylennapf@users.noreply.github.com>
Date: Mon, 24 Nov 2025 23:01:05 +0000
Subject: [PATCH 4/7] refactor: resolve DOM Directly DOM manipulations
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Adiciona exemplo simulado de refatoração demonstrando code smell de manipulação de DOM
- Mostra uso inadequado de innerHTML e getElementById
- Arquivo criado para fins educacionais
---
examples/comprehensive/src/simulated-refactor.tsx | 12 ++++++++++++
1 file changed, 12 insertions(+)
create mode 100644 examples/comprehensive/src/simulated-refactor.tsx
diff --git a/examples/comprehensive/src/simulated-refactor.tsx b/examples/comprehensive/src/simulated-refactor.tsx
new file mode 100644
index 0000000..9342cb3
--- /dev/null
+++ b/examples/comprehensive/src/simulated-refactor.tsx
@@ -0,0 +1,12 @@
+// Simulated DOM manipulation code smell
+export function BadComponent() {
+ // DOM manipulation code smell
+ const updateElement = () => {
+ const element = document.getElementById('my-div');
+ if (element) {
+ element.innerHTML = 'New content';
+ }
+ };
+
+ return ;
+}
From 8822d48b52a29f1035dc70136ac17dfdaa43f3ab Mon Sep 17 00:00:00 2001
From: tony
Date: Mon, 24 Nov 2025 19:01:45 -0400
Subject: [PATCH 5/7] refactor: refactoring script to avoid too many props
issue
---
.../sb-react/src/dnd/kitchensink.stories.tsx | 159 +++++++++++-------
1 file changed, 95 insertions(+), 64 deletions(-)
diff --git a/packages/sb-react/src/dnd/kitchensink.stories.tsx b/packages/sb-react/src/dnd/kitchensink.stories.tsx
index 0fd1083..c547d51 100644
--- a/packages/sb-react/src/dnd/kitchensink.stories.tsx
+++ b/packages/sb-react/src/dnd/kitchensink.stories.tsx
@@ -6,6 +6,7 @@ import {
keyboardDragAndDropFeature,
selectionFeature,
syncDataLoaderFeature,
+ TreeItemInstance,
} from "@headless-tree/core";
import { AssistiveTreeDescription, useTree } from "@headless-tree/react";
import { action } from "storybook/actions";
@@ -36,13 +37,91 @@ const meta = {
export default meta;
-// story-start
+const STATIC_FEATURES = [
+ syncDataLoaderFeature,
+ selectionFeature,
+ hotkeysCoreFeature,
+ dragAndDropFeature,
+ keyboardDragAndDropFeature,
+];
+
+const mockDataLoader = {
+ getItem: (itemId: string) => itemId,
+ getChildren: (itemId: string) => [
+ `${itemId}-1`,
+ `${itemId}-2`,
+ `${itemId}-3`,
+ `${itemId}-4`,
+ `${itemId}-5`,
+ `${itemId}-6`,
+ ],
+};
+
+const createForeignDragObject = (items: TreeItemInstance[]) => ({
+ format: "text/plain",
+ data: `custom foreign drag object: ${items.map((item) => item.getId()).join(",")}`,
+});
+
+const handleDropAction = action("onDrop");
+const handleDropForeignDragObjectAction = action("onDropForeignDragObject");
+const handleExternalDropAction = action("onDropExternally");
+
+interface TreeItemRowProps {
+ item: TreeItemInstance;
+}
+
+const TreeItemRow = React.memo(({ item }: TreeItemRowProps) => {
+ return (
+
+ );
+});
+
+TreeItemRow.displayName = "TreeItemRow";
+
+const ExternalDropTarget = () => (
+ handleExternalDropAction(e.dataTransfer.getData("text/plain"))}
+ onDragOver={(e) => e.preventDefault()}
+ >
+ Drop items here!
+
+);
+
+const ExternalDraggableSource = () => (
+ {
+ e.dataTransfer.setData("text/plain", "hello world");
+ }}
+ >
+ Or drag me into the tree!
+
+);
+
export const KitchenSink = ({
canReorder,
canDropForeignDragObject,
reorderAreaPercentage,
}: PropsOfArgtype) => {
const [state, setState] = useState({});
+
const tree = useTree({
state,
setState,
@@ -50,80 +129,32 @@ export const KitchenSink = ({
getItemName: (item) => item.getItemData(),
isItemFolder: () => true,
canReorder,
- onDrop: action("onDrop"),
- onDropForeignDragObject: action("onDropForeignDragObject"),
- createForeignDragObject: (items) => ({
- format: "text/plain",
- data: `custom foreign drag object: ${items
- .map((item) => item.getId())
- .join(",")}`,
- }),
- canDropForeignDragObject: () => canDropForeignDragObject,
reorderAreaPercentage,
+ canDropForeignDragObject: () => canDropForeignDragObject ?? false,
+ createForeignDragObject,
+ onDrop: handleDropAction,
+ onDropForeignDragObject: handleDropForeignDragObjectAction,
indent: 20,
- dataLoader: {
- getItem: (itemId) => itemId,
- getChildren: (itemId) => [
- `${itemId}-1`,
- `${itemId}-2`,
- `${itemId}-3`,
- `${itemId}-4`,
- `${itemId}-5`,
- `${itemId}-6`,
- ],
- },
- features: [
- syncDataLoaderFeature,
- selectionFeature,
- hotkeysCoreFeature,
- dragAndDropFeature,
- keyboardDragAndDropFeature,
- ],
+ dataLoader: mockDataLoader,
+ features: STATIC_FEATURES,
});
+ const dragLineStyle = tree.getDragLineStyle();
+
return (
<>
+
{tree.getItems().map((item) => (
-
+
))}
-
-
-
- action("onDropExternally")(e.dataTransfer.getData("text/plain"))
- }
- onDragOver={(e) => e.preventDefault()}
- >
- Drop items here!
-
- {
- e.dataTransfer.setData("text/plain", "hello world");
- }}
- >
- Or drag me into the tree!
+
+
+
+
+
>
);
};
From 73f75396ace4662cf8710c263158682dd24c5e52 Mon Sep 17 00:00:00 2001
From: Sophya Ribeiro
Date: Tue, 25 Nov 2025 14:11:40 -0400
Subject: [PATCH 6/7] remove code smell
---
...checked-state-as-radio-buttons.stories.tsx | 63 ++++++++++---------
1 file changed, 35 insertions(+), 28 deletions(-)
diff --git a/packages/sb-react/src/checkboxes/checked-state-as-radio-buttons.stories.tsx b/packages/sb-react/src/checkboxes/checked-state-as-radio-buttons.stories.tsx
index d37b5b3..76cc3d1 100644
--- a/packages/sb-react/src/checkboxes/checked-state-as-radio-buttons.stories.tsx
+++ b/packages/sb-react/src/checkboxes/checked-state-as-radio-buttons.stories.tsx
@@ -1,5 +1,5 @@
import type { Meta } from "@storybook/react";
-import React from "react";
+import React, { JSX } from "react";
import {
CheckedState,
type FeatureImplementation,
@@ -54,6 +54,36 @@ const checkboxOverride: FeatureImplementation = {
},
};
+
+interface TreeViewProps {
+ tree: TreeInstance;
+}
+
+const TreeView: React.FC = ({ tree }) => (
+
+ {tree.getItems().map((item: TreeInstance
["getItems"][number]) => (
+
+
+
+
+ ))}
+
+);
+
export const CheckedStateAsRadioButtons = () => {
const tree = useTree({
rootItemId: "root",
@@ -61,8 +91,8 @@ export const CheckedStateAsRadioButtons = () => {
expandedItems: ["fruit", "berries", "red"],
checkedItems: ["fruit", "banana", "berries", "strawberry"],
},
- getItemName: (item) => item.getItemData().name,
- isItemFolder: (item) => !!item.getItemData().children,
+ getItemName: (item: TreeInstance["getItems"][number]) => item.getItemData().name,
+ isItemFolder: (item: TreeInstance["getItems"][number]) => !!item.getItemData().children,
dataLoader: syncDataLoader,
canCheckFolders: true,
propagateCheckedState: false,
@@ -82,31 +112,8 @@ export const CheckedStateAsRadioButtons = () => {
In this sample, a custom "toggleCheckedState" implementation is used to
enforce that for each folder, only one child can be checked.
-
-
- {tree.getItems().map((item) => (
-
-
-
-
- ))}
-
-
+
{JSON.stringify(tree.getState().checkedItems)}
>
);
-};
+}
From b112c29d3a3d1ec8ff944cc2e7434fe3706c985b Mon Sep 17 00:00:00 2001
From: Soraya Ferreira <113856615+SorayaFerreira@users.noreply.github.com>
Date: Tue, 25 Nov 2025 14:24:42 -0400
Subject: [PATCH 7/7] Delete .github/workflows directory
---
.github/workflows/docs.yml | 38 -------------------
.github/workflows/publish.yml | 54 ---------------------------
.github/workflows/snapshot.yml | 67 ----------------------------------
.github/workflows/verify.yml | 24 ------------
4 files changed, 183 deletions(-)
delete mode 100644 .github/workflows/docs.yml
delete mode 100644 .github/workflows/publish.yml
delete mode 100644 .github/workflows/snapshot.yml
delete mode 100644 .github/workflows/verify.yml
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
deleted file mode 100644
index 0464c39..0000000
--- a/.github/workflows/docs.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-name: Docs
-on:
- push:
- branches:
- - main
- workflow_dispatch:
-
-permissions:
- contents: read
- pages: write
- deployments: write
- id-token: write
-
-jobs:
- docs:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- - uses: actions/cache@v3
- with:
- path: |
- **/node_modules
- ./.yarn/cache
- key: ${{ runner.os }}-deps-${{ hashFiles('**/yarn.lock') }}
- - uses: volta-cli/action@v4.1.1
- - run: yarn
- - run: yarn lint:test
- - run: yarn build:core
- - run: yarn build:sb
- - run: yarn llmtxt
- - run: yarn build:web
- - run: |
- mkdir -p ./packages/docs/build/storybook
- cp -r ./packages/sb-react/storybook-static ./packages/docs/build/storybook/react
- - uses: actions/upload-pages-artifact@v3
- with:
- path: ./packages/docs/build
- - uses: actions/deploy-pages@v4
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
deleted file mode 100644
index 06e47ac..0000000
--- a/.github/workflows/publish.yml
+++ /dev/null
@@ -1,54 +0,0 @@
-name: Publish
-on:
- push:
- branches:
- - main
- workflow_dispatch:
-
-permissions:
- contents: write
- pull-requests: write
- id-token: write
-
-jobs:
- publish:
- runs-on: ubuntu-latest
- name: Publish
- steps:
- - uses: actions/checkout@v3
- with:
- persist-credentials: false
- fetch-depth: 0
-
- - uses: actions/cache@v3
- with:
- path: |
- **/node_modules
- ./.yarn/cache
- key: ${{ runner.os }}-deps-${{ hashFiles('**/yarn.lock') }}
- - uses: volta-cli/action@v4.1.1
- with:
- registry-url: "https://registry.npmjs.org"
-
- - run: yarn
- - run: yarn lint:test
- - run: yarn test
- - run: yarn build:core
- - run: yarn build:web
- - name: Copy readme.md to packages
- run: |
- for dir in $(find packages -type d -maxdepth 1); do
- cp readme.md $dir/readme.md
- done
-
- - name: Create Release Pull Request or Publish to npm
- id: changesets
- uses: changesets/action@v1
- with:
- version: npx zx ./scripts/version.mjs
- publish: yarn changeset publish
- commit: "chore: release [nosnapshot]"
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml
deleted file mode 100644
index 08d85e4..0000000
--- a/.github/workflows/snapshot.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-name: Snapshot Release
-on:
- push:
- branches:
- - main
- workflow_dispatch:
-
-permissions:
- contents: write
- pull-requests: write
- id-token: write
-
-jobs:
- snapshot:
- if: ${{ !contains(github.event.commits[0].message, 'nosnapshot') }}
- runs-on: ubuntu-latest
- name: Publish
- steps:
- - uses: actions/checkout@v3
- with:
- persist-credentials: false
- fetch-depth: 0
-
- - name: check skip tag
- run: |
- if git log -1 --pretty=%B | grep -qE 'chore: release|nosnapshot'; then
- echo "Skipping snapshot release due to commit message."
- exit 0
- fi
-
- - uses: actions/cache@v3
- with:
- path: |
- **/node_modules
- ./.yarn/cache
- key: ${{ runner.os }}-deps-${{ hashFiles('**/yarn.lock') }}
- - uses: volta-cli/action@v4.1.1
- with:
- registry-url: "https://registry.npmjs.org"
-
- - run: yarn
- - run: yarn lint:test
- - run: yarn test
- - run: yarn build:core
- - run: yarn build:web
-
- - name: Copy readme.md to packages
- run: |
- for dir in $(find packages -type d -maxdepth 1); do
- cp readme.md $dir/readme.md
- done
-
- - name: Snapshot Versioning
- run: yarn changeset version --snapshot
-
- - name: Snapshot Release
- run: |
- if git diff --quiet; then
- echo "No changes detected"
- exit 0
- else
- yarn changeset publish --no-git-tag --tag snapshot
- fi
- env:
- GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml
deleted file mode 100644
index 410b9df..0000000
--- a/.github/workflows/verify.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-name: Verify
-on:
- push:
- pull_request:
- workflow_dispatch:
-
-jobs:
- verify:
- runs-on: ubuntu-latest
- name: Verify
- steps:
- - uses: actions/checkout@v3
- - uses: actions/cache@v3
- with:
- path: |
- **/node_modules
- ./.yarn/cache
- key: ${{ runner.os }}-deps-${{ hashFiles('**/yarn.lock') }}
- - uses: volta-cli/action@v4.1.1
- - run: yarn
- - run: yarn lint:test
- - run: yarn test
- - run: yarn build:core
- - run: yarn build:web