From d5f7dd3191f99fbc34ced394691127b4d5ac68fd Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Thu, 12 Feb 2026 15:16:54 +0800 Subject: [PATCH 1/7] Migrate from lodash to es-toolkit --- .github/actions/package.json | 2 +- .github/actions/src/__tests__/commons.test.ts | 9 ++- .../actions/src/__tests__/lockfiles.test.ts | 4 +- .github/actions/src/__tests__/sample_why.txt | 16 ++--- .github/actions/src/commons.ts | 2 +- .../actions/src/info/__tests__/index.test.ts | 2 +- .github/actions/src/lockfiles.ts | 2 +- .yarnrc.yml | 1 + docs/src/lib/lintplugin/2-rules.md | 1 + docs/src/modules/2-bundle/3-editing.md | 2 +- docs/src/modules/3-tabs/3-editing.md | 2 +- eslint.config.js | 1 - lib/buildtools/package.json | 3 +- lib/buildtools/src/commands/commandUtils.ts | 2 +- lib/buildtools/src/commands/list.ts | 6 +- lib/buildtools/src/templates/tab.ts | 2 +- .../rules/__tests__/noBarrelImports.test.ts | 68 ++++++++++--------- lib/markdown-tree/package.json | 3 +- lib/markdown-tree/src/tree.ts | 11 ++- .../src/tabs/MultiItemDisplay/index.tsx | 6 +- lib/modules-lib/src/tabs/NumberSelector.tsx | 2 +- lib/modules-lib/vitest.config.ts | 2 +- lib/repotools/package.json | 5 +- lib/repotools/src/manifest.ts | 2 +- lib/repotools/src/testing/index.ts | 9 ++- package.json | 2 +- src/bundles/curve/src/functions.ts | 2 +- .../src/controllers/program/evaluate.ts | 4 +- .../src/controllers/utils/mergeConfig.ts | 6 +- src/bundles/rune/src/functions.ts | 4 +- src/bundles/unittest/package.json | 5 +- src/bundles/unittest/src/asserts.ts | 2 +- src/tabs/Curve/vitest.config.ts | 1 - src/tabs/Rune/vitest.config.ts | 1 - src/tabs/Unittest/index.tsx | 2 +- yarn.lock | 39 ++++------- 36 files changed, 109 insertions(+), 124 deletions(-) diff --git a/.github/actions/package.json b/.github/actions/package.json index a95b403f17..14f8172a31 100644 --- a/.github/actions/package.json +++ b/.github/actions/package.json @@ -13,7 +13,7 @@ "@actions/artifact": "^6.0.0", "@actions/core": "^1.11.1", "@actions/exec": "^3.0.0", - "lodash": "^4.17.23", + "es-toolkit": "^1.44.0", "snyk-nodejs-lockfile-parser": "^2.4.2" }, "scripts": { diff --git a/.github/actions/src/__tests__/commons.test.ts b/.github/actions/src/__tests__/commons.test.ts index 82447d6487..9393ae9bf8 100644 --- a/.github/actions/src/__tests__/commons.test.ts +++ b/.github/actions/src/__tests__/commons.test.ts @@ -2,9 +2,12 @@ import * as exec from '@actions/exec'; import { describe, expect, it, test, vi } from 'vitest'; import * as commons from '../commons.js'; -vi.mock(import('lodash/memoize.js'), () => ({ - default: (x: any) => x -}) as any); +vi.mock(import("es-toolkit"), async (importOriginal) => { + const actual = await importOriginal() + return { + ...actual + } +}) const mockedExecOutput = vi.spyOn(exec, 'getExecOutput'); diff --git a/.github/actions/src/__tests__/lockfiles.test.ts b/.github/actions/src/__tests__/lockfiles.test.ts index 973f4674d8..279fefa5f4 100644 --- a/.github/actions/src/__tests__/lockfiles.test.ts +++ b/.github/actions/src/__tests__/lockfiles.test.ts @@ -12,8 +12,8 @@ describe(utils.extractPackageName, () => { }); it('works with regular package names', () => { - expect(utils.extractPackageName('lodash@npm:^4.17.20')) - .toEqual('lodash'); + expect(utils.extractPackageName('es-toolkit@npm:^1.44.0')) + .toEqual('es-toolkit'); }); it('throws an error on an invalid package name', () => { diff --git a/.github/actions/src/__tests__/sample_why.txt b/.github/actions/src/__tests__/sample_why.txt index 240cec0056..a64d322d11 100644 --- a/.github/actions/src/__tests__/sample_why.txt +++ b/.github/actions/src/__tests__/sample_why.txt @@ -1,6 +1,6 @@ {"value":"@sourceacademy/bundle-ar@workspace:src/bundles/ar","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}}}} {"value":"@sourceacademy/bundle-arcade_2d@workspace:src/bundles/arcade_2d","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-lib@workspace:lib/modules-lib":{"value":{"locator":"@sourceacademy/modules-lib@workspace:lib/modules-lib","descriptor":"@sourceacademy/modules-lib@workspace:^"},"children":{}}}} -{"value":"@sourceacademy/bundle-binary_tree@workspace:src/bundles/binary_tree","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{"lodash@npm:4.17.21":{"value":{"locator":"lodash@npm:4.17.21","descriptor":"lodash@npm:^4.17.21"},"children":{}}}}}} +{"value":"@sourceacademy/bundle-binary_tree@workspace:src/bundles/binary_tree","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}}}}}} {"value":"@sourceacademy/bundle-communication@workspace:src/bundles/communication","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}}}} {"value":"@sourceacademy/bundle-copy_gc@workspace:src/bundles/copy_gc","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}}}} {"value":"@sourceacademy/bundle-csg@workspace:src/bundles/csg","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-lib@workspace:lib/modules-lib":{"value":{"locator":"@sourceacademy/modules-lib@workspace:lib/modules-lib","descriptor":"@sourceacademy/modules-lib@workspace:^"},"children":{}}}} @@ -23,18 +23,18 @@ {"value":"@sourceacademy/bundle-sound@workspace:src/bundles/sound","children":{"@sourceacademy/bundle-midi@workspace:src/bundles/midi":{"value":{"locator":"@sourceacademy/bundle-midi@workspace:src/bundles/midi","descriptor":"@sourceacademy/bundle-midi@workspace:^"},"children":{}},"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-lib@workspace:lib/modules-lib":{"value":{"locator":"@sourceacademy/modules-lib@workspace:lib/modules-lib","descriptor":"@sourceacademy/modules-lib@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{}}}} {"value":"@sourceacademy/bundle-sound_matrix@workspace:src/bundles/sound_matrix","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{}}}} {"value":"@sourceacademy/bundle-stereo_sound@workspace:src/bundles/stereo_sound","children":{"@sourceacademy/bundle-midi@workspace:src/bundles/midi":{"value":{"locator":"@sourceacademy/bundle-midi@workspace:src/bundles/midi","descriptor":"@sourceacademy/bundle-midi@workspace:^"},"children":{}},"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{}}}} -{"value":"@sourceacademy/bundle-unittest@workspace:src/bundles/unittest","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{}},"lodash@npm:4.17.21":{"value":{"locator":"lodash@npm:4.17.21","descriptor":"lodash@npm:^4.17.21"},"children":{}}}} +{"value":"@sourceacademy/bundle-unittest@workspace:src/bundles/unittest","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{}},"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}}}} {"value":"@sourceacademy/bundle-unity_academy@workspace:src/bundles/unity_academy","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}}}} -{"value":"@sourceacademy/bundle-wasm@workspace:src/bundles/wasm","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"source-academy-wabt@npm:1.1.3":{"value":{"locator":"source-academy-wabt@npm:1.1.3","descriptor":"source-academy-wabt@npm:^1.0.4"},"children":{"lodash@npm:4.17.21":{"value":{"locator":"lodash@npm:4.17.21","descriptor":"lodash@npm:^4.17.21"},"children":{}}}}}} +{"value":"@sourceacademy/bundle-wasm@workspace:src/bundles/wasm","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"source-academy-wabt@npm:1.1.3":{"value":{"locator":"source-academy-wabt@npm:1.1.3","descriptor":"source-academy-wabt@npm:^1.0.4"},"children":{"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}}}}}} {"value":"@sourceacademy/lint-plugin@workspace:lib/lintplugin","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:^"},"children":{}}}} -{"value":"@sourceacademy/markdown-plugin-directory-tree@workspace:lib/markdown-tree","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"lodash@npm:4.17.21":{"value":{"locator":"lodash@npm:4.17.21","descriptor":"lodash@npm:^4.17.21"},"children":{}},"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:^"},"children":{}}}} -{"value":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","children":{"lodash@npm:4.17.21":{"value":{"locator":"lodash@npm:4.17.21","descriptor":"lodash@npm:^4.17.21"},"children":{}},"@sourceacademy/modules-repotools@virtual:1448f4d06c0cf02cc986bce0139b31c0f3c95af1573e69673bc11ad2928a2fc505818a40d3f1caf168c35ce00c20238d52dfdba1940c59c81fd5df1b08ba49d6#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:1448f4d06c0cf02cc986bce0139b31c0f3c95af1573e69673bc11ad2928a2fc505818a40d3f1caf168c35ce00c20238d52dfdba1940c59c81fd5df1b08ba49d6#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:1448f4d06c0cf02cc986bce0139b31c0f3c95af1573e69673bc11ad2928a2fc505818a40d3f1caf168c35ce00c20238d52dfdba1940c59c81fd5df1b08ba49d6#workspace:^"},"children":{}}}} +{"value":"@sourceacademy/markdown-plugin-directory-tree@workspace:lib/markdown-tree","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}},"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:^"},"children":{}}}} +{"value":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","children":{"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}},"@sourceacademy/modules-repotools@virtual:1448f4d06c0cf02cc986bce0139b31c0f3c95af1573e69673bc11ad2928a2fc505818a40d3f1caf168c35ce00c20238d52dfdba1940c59c81fd5df1b08ba49d6#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:1448f4d06c0cf02cc986bce0139b31c0f3c95af1573e69673bc11ad2928a2fc505818a40d3f1caf168c35ce00c20238d52dfdba1940c59c81fd5df1b08ba49d6#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:1448f4d06c0cf02cc986bce0139b31c0f3c95af1573e69673bc11ad2928a2fc505818a40d3f1caf168c35ce00c20238d52dfdba1940c59c81fd5df1b08ba49d6#workspace:^"},"children":{}}}} {"value":"@sourceacademy/modules-devserver@workspace:devserver","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-lib@workspace:lib/modules-lib":{"value":{"locator":"@sourceacademy/modules-lib@workspace:lib/modules-lib","descriptor":"@sourceacademy/modules-lib@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{}}}} {"value":"@sourceacademy/modules-docserver@workspace:docs","children":{"@sourceacademy/modules-lib@workspace:lib/modules-lib":{"value":{"locator":"@sourceacademy/modules-lib@workspace:lib/modules-lib","descriptor":"@sourceacademy/modules-lib@workspace:^"},"children":{}},"@sourceacademy/lint-plugin@virtual:f0562030a653a107496800a80ececfadfd737a6a260bbd2572ca4e42de1d6b97749197bb1c41d0d71c9f18ab009789560666041994678fe1aba63902e9fb15bd#workspace:lib/lintplugin":{"value":{"locator":"@sourceacademy/lint-plugin@virtual:f0562030a653a107496800a80ececfadfd737a6a260bbd2572ca4e42de1d6b97749197bb1c41d0d71c9f18ab009789560666041994678fe1aba63902e9fb15bd#workspace:lib/lintplugin","descriptor":"@sourceacademy/lint-plugin@virtual:f0562030a653a107496800a80ececfadfd737a6a260bbd2572ca4e42de1d6b97749197bb1c41d0d71c9f18ab009789560666041994678fe1aba63902e9fb15bd#workspace:^"},"children":{}},"@sourceacademy/markdown-plugin-directory-tree@virtual:f0562030a653a107496800a80ececfadfd737a6a260bbd2572ca4e42de1d6b97749197bb1c41d0d71c9f18ab009789560666041994678fe1aba63902e9fb15bd#workspace:lib/markdown-tree":{"value":{"locator":"@sourceacademy/markdown-plugin-directory-tree@virtual:f0562030a653a107496800a80ececfadfd737a6a260bbd2572ca4e42de1d6b97749197bb1c41d0d71c9f18ab009789560666041994678fe1aba63902e9fb15bd#workspace:lib/markdown-tree","descriptor":"@sourceacademy/markdown-plugin-directory-tree@virtual:f0562030a653a107496800a80ececfadfd737a6a260bbd2572ca4e42de1d6b97749197bb1c41d0d71c9f18ab009789560666041994678fe1aba63902e9fb15bd#workspace:^"},"children":{}}}} -{"value":"@sourceacademy/modules-github-actions@workspace:.github/actions","children":{"@actions/artifact@npm:2.3.2":{"value":{"locator":"@actions/artifact@npm:2.3.2","descriptor":"@actions/artifact@npm:^2.3.2"},"children":{"archiver@npm:7.0.1":{"value":{"locator":"archiver@npm:7.0.1","descriptor":"archiver@npm:^7.0.1"},"children":{"archiver-utils@npm:5.0.2":{"value":{"locator":"archiver-utils@npm:5.0.2","descriptor":"archiver-utils@npm:^5.0.2"},"children":{"lodash@npm:4.17.21":{"value":{"locator":"lodash@npm:4.17.21","descriptor":"lodash@npm:^4.17.15"},"children":{}}}},"zip-stream@npm:6.0.1":{"value":{"locator":"zip-stream@npm:6.0.1","descriptor":"zip-stream@npm:^6.0.1"},"children":{"archiver-utils@npm:5.0.2":{"value":{"locator":"archiver-utils@npm:5.0.2","descriptor":"archiver-utils@npm:^5.0.0"},"children":{}}}}}}}},"lodash@npm:4.17.21":{"value":{"locator":"lodash@npm:4.17.21","descriptor":"lodash@npm:^4.17.21"},"children":{}},"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:^"},"children":{}}}} +{"value":"@sourceacademy/modules-github-actions@workspace:.github/actions","children":{"@actions/artifact@npm:2.3.2":{"value":{"locator":"@actions/artifact@npm:2.3.2","descriptor":"@actions/artifact@npm:^2.3.2"},"children":{"archiver@npm:7.0.1":{"value":{"locator":"archiver@npm:7.0.1","descriptor":"archiver@npm:^7.0.1"},"children":{"archiver-utils@npm:5.0.2":{"value":{"locator":"archiver-utils@npm:5.0.2","descriptor":"archiver-utils@npm:^5.0.2"},"children":{"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-tookit@npm:^1.44.0"},"children":{}}}},"zip-stream@npm:6.0.1":{"value":{"locator":"zip-stream@npm:6.0.1","descriptor":"zip-stream@npm:^6.0.1"},"children":{"archiver-utils@npm:5.0.2":{"value":{"locator":"archiver-utils@npm:5.0.2","descriptor":"archiver-utils@npm:^5.0.0"},"children":{}}}}}}}},"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}},"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:^"},"children":{}}}} {"value":"@sourceacademy/modules-lib@workspace:lib/modules-lib","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{}}}} -{"value":"@sourceacademy/modules-repotools@workspace:lib/repotools","children":{"lodash@npm:4.17.21":{"value":{"locator":"lodash@npm:4.17.21","descriptor":"lodash@npm:^4.17.21"},"children":{}}}} -{"value":"@sourceacademy/modules@workspace:.","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{}},"lodash@npm:4.17.21":{"value":{"locator":"lodash@npm:4.17.21","descriptor":"lodash@npm:^4.17.21"},"children":{}},"@sourceacademy/lint-plugin@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/lintplugin":{"value":{"locator":"@sourceacademy/lint-plugin@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/lintplugin","descriptor":"@sourceacademy/lint-plugin@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:^"},"children":{}},"@sourceacademy/modules-repotools@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:^"},"children":{}}}} +{"value":"@sourceacademy/modules-repotools@workspace:lib/repotools","children":{"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}}}} +{"value":"@sourceacademy/modules@workspace:.","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{}},"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}},"@sourceacademy/lint-plugin@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/lintplugin":{"value":{"locator":"@sourceacademy/lint-plugin@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/lintplugin","descriptor":"@sourceacademy/lint-plugin@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:^"},"children":{}},"@sourceacademy/modules-repotools@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:^"},"children":{}}}} {"value":"@sourceacademy/tab-ArcadeTwod@workspace:src/tabs/ArcadeTwod","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-lib@workspace:lib/modules-lib":{"value":{"locator":"@sourceacademy/modules-lib@workspace:lib/modules-lib","descriptor":"@sourceacademy/modules-lib@workspace:^"},"children":{}}}} {"value":"@sourceacademy/tab-AugmentedReality@workspace:src/tabs/AugmentedReality","children":{"@sourceacademy/bundle-ar@workspace:src/bundles/ar":{"value":{"locator":"@sourceacademy/bundle-ar@workspace:src/bundles/ar","descriptor":"@sourceacademy/bundle-ar@workspace:^"},"children":{}},"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-lib@workspace:lib/modules-lib":{"value":{"locator":"@sourceacademy/modules-lib@workspace:lib/modules-lib","descriptor":"@sourceacademy/modules-lib@workspace:^"},"children":{}}}} {"value":"@sourceacademy/tab-CopyGc@workspace:src/tabs/CopyGc","children":{"@sourceacademy/bundle-copy_gc@workspace:src/bundles/copy_gc":{"value":{"locator":"@sourceacademy/bundle-copy_gc@workspace:src/bundles/copy_gc","descriptor":"@sourceacademy/bundle-copy_gc@workspace:^"},"children":{}},"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-lib@workspace:lib/modules-lib":{"value":{"locator":"@sourceacademy/modules-lib@workspace:lib/modules-lib","descriptor":"@sourceacademy/modules-lib@workspace:^"},"children":{}}}} diff --git a/.github/actions/src/commons.ts b/.github/actions/src/commons.ts index 4d02975ea7..bd3185a2a4 100644 --- a/.github/actions/src/commons.ts +++ b/.github/actions/src/commons.ts @@ -1,5 +1,5 @@ import { getExecOutput } from '@actions/exec'; -import memoize from 'lodash/memoize.js'; +import { memoize } from 'es-toolkit'; export interface RawPackageRecord { directory: string; diff --git a/.github/actions/src/info/__tests__/index.test.ts b/.github/actions/src/info/__tests__/index.test.ts index 0effab3c01..6fcefaf68b 100644 --- a/.github/actions/src/info/__tests__/index.test.ts +++ b/.github/actions/src/info/__tests__/index.test.ts @@ -55,7 +55,7 @@ const mockDirectory: Record> = { 'package.json': JSON.stringify({ name: '@sourceacademy/tab-Tab0', dependencies: { - lodash: '^4.1.1', + 'es-toolkit': '^1.44.0', '@sourceacademy/bundle-bundle0': 'workspace:^', }, devDependencies: { diff --git a/.github/actions/src/lockfiles.ts b/.github/actions/src/lockfiles.ts index 59656f3c5b..d8c47e7760 100644 --- a/.github/actions/src/lockfiles.ts +++ b/.github/actions/src/lockfiles.ts @@ -2,7 +2,7 @@ import fs from 'fs/promises'; import pathlib from 'path'; import * as core from '@actions/core'; import { getExecOutput } from '@actions/exec'; -import memoize from 'lodash/memoize.js'; +import { memoize } from 'es-toolkit'; import { extractPkgsFromYarnLockV2 } from 'snyk-nodejs-lockfile-parser'; import { gitRoot } from './gitRoot.js'; diff --git a/.yarnrc.yml b/.yarnrc.yml index 3186f3f079..09d6a8236b 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -1 +1,2 @@ nodeLinker: node-modules +checksumBehavior: update diff --git a/docs/src/lib/lintplugin/2-rules.md b/docs/src/lib/lintplugin/2-rules.md index 9dbf81e572..9401e8178e 100644 --- a/docs/src/lib/lintplugin/2-rules.md +++ b/docs/src/lib/lintplugin/2-rules.md @@ -62,6 +62,7 @@ import path from 'pathlib'; ## `no-barrel-imports` +_Note: Due to the migration to es-toolkit, this rule is no longer used_ Enforces that imports from a certain source uses individual imports instead of the main barrel import. This rule was primarily motivated by packages like `lodash` and `@mui`, which re-export all their functionalities diff --git a/docs/src/modules/2-bundle/3-editing.md b/docs/src/modules/2-bundle/3-editing.md index 7ae919975c..925215bef8 100644 --- a/docs/src/modules/2-bundle/3-editing.md +++ b/docs/src/modules/2-bundle/3-editing.md @@ -62,7 +62,7 @@ You can also add the dependency directly by modifying your `package.json`: { "name": "@sourceacademy/bundle-bundle0", "dependencies": { - "lodash": "^4.0.0" + "es-toolkit": "^1.44.0" } } ``` diff --git a/docs/src/modules/3-tabs/3-editing.md b/docs/src/modules/3-tabs/3-editing.md index 465f410b41..c04f95ac93 100644 --- a/docs/src/modules/3-tabs/3-editing.md +++ b/docs/src/modules/3-tabs/3-editing.md @@ -62,7 +62,7 @@ You can also add the dependency directly by modifying your `package.json`: { "name": "@sourceacademy/tab-Tab0", "dependencies": { - "lodash": "^4.0.0" + "es-toolkit": "^1.44.0" } } ``` diff --git a/eslint.config.js b/eslint.config.js index 788d9a165b..457912d275 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -271,7 +271,6 @@ export default defineConfig( 'prefer-const': ['warn', { destructuring: 'all' }], '@sourceacademy/default-import-name': ['warn', { path: 'pathlib' }], - '@sourceacademy/no-barrel-imports': ['error', ['lodash']], '@sourceacademy/region-comment': 'error', } }, diff --git a/lib/buildtools/package.json b/lib/buildtools/package.json index 1989cedb9c..95877d7f6e 100644 --- a/lib/buildtools/package.json +++ b/lib/buildtools/package.json @@ -7,7 +7,6 @@ "@commander-js/extra-typings": "^14.0.0", "@types/estree": "^1.0.0", "@types/http-server": "^0.12.4", - "@types/lodash": "^4.14.198", "@types/node": "^22.15.30", "typescript": "^5.8.2" }, @@ -25,11 +24,11 @@ "astring": "^1.8.6", "chalk": "^5.0.1", "commander": "^14.0.0", + "es-toolkit": "^1.44.0", "esbuild": "^0.27.0", "eslint": "^9.35.0", "http-server": "^14.1.1", "jsdom": "^26.1.0", - "lodash": "^4.17.23", "typedoc": "^0.28.9", "vite": "^7.1.11", "vitest": "^4.0.4" diff --git a/lib/buildtools/src/commands/commandUtils.ts b/lib/buildtools/src/commands/commandUtils.ts index 1820aa2602..1aa92f21b1 100644 --- a/lib/buildtools/src/commands/commandUtils.ts +++ b/lib/buildtools/src/commands/commandUtils.ts @@ -2,7 +2,7 @@ import { InvalidArgumentError, Option } from '@commander-js/extra-typings'; import type { ErrorResult, Severity } from '@sourceacademy/modules-repotools/types'; import { isSeverity, objectKeys, objectValues } from '@sourceacademy/modules-repotools/utils'; import chalk from 'chalk'; -import capitalize from 'lodash/capitalize.js'; +import { capitalize } from 'es-toolkit'; import { LogLevel } from 'typedoc'; export const lintOption = new Option('--lint', 'Run ESLint when building') diff --git a/lib/buildtools/src/commands/list.ts b/lib/buildtools/src/commands/list.ts index 77058ff756..0e288b8954 100644 --- a/lib/buildtools/src/commands/list.ts +++ b/lib/buildtools/src/commands/list.ts @@ -2,7 +2,7 @@ import { Command } from '@commander-js/extra-typings'; import { bundlesDir, tabsDir } from '@sourceacademy/modules-repotools/getGitRoot'; import { resolveAllBundles, resolveAllTabs, resolveSingleBundle, resolveSingleTab } from '@sourceacademy/modules-repotools/manifest'; import chalk from 'chalk'; -import omit from 'lodash/omit.js'; +import { omit } from 'es-toolkit'; import { logCommandErrorAndExit } from './commandUtils.js'; export const getListBundlesCommand = () => new Command('bundle') @@ -23,7 +23,7 @@ export const getListBundlesCommand = () => new Command('bundle') return; } - const bundlesStr = bundleNames.map((each, i) => `${i+1}. ${each}`).join('\n'); + const bundlesStr = bundleNames.map((each, i) => `${i + 1}. ${each}`).join('\n'); console.log(`${chalk.magentaBright(`Detected ${bundleNames.length} bundles in ${bundlesDir}:`)}\n${bundlesStr}`); } else { logCommandErrorAndExit(`No bundles in ${bundlesDir}!`); @@ -49,7 +49,7 @@ export const getListTabsCommand = () => new Command('tabs') return; } - const tabsStr = tabNames.map((each, i) => `${i+1}. ${each}`).join('\n'); + const tabsStr = tabNames.map((each, i) => `${i + 1}. ${each}`).join('\n'); console.log(`${chalk.magentaBright(`Detected ${tabNames.length} tabs in ${tabsDir}:`)}\n${tabsStr}`); } else { logCommandErrorAndExit(`No tabs in ${tabsDir}`); diff --git a/lib/buildtools/src/templates/tab.ts b/lib/buildtools/src/templates/tab.ts index a9e8b54d3c..892d92507c 100644 --- a/lib/buildtools/src/templates/tab.ts +++ b/lib/buildtools/src/templates/tab.ts @@ -3,7 +3,7 @@ import pathlib from 'path'; import type { Interface } from 'readline/promises'; import { getBundleManifests } from '@sourceacademy/modules-repotools/manifest'; import type { BundleManifest, ModulesManifest } from '@sourceacademy/modules-repotools/types'; -import omit from 'lodash/omit.js'; +import { omit } from 'es-toolkit/object'; import _package from '../../../../package.json' with { type: 'json' }; import { formatResult } from '../build/formatter.js'; import { askQuestion, error, success, warn } from './print.js'; diff --git a/lib/lintplugin/src/rules/__tests__/noBarrelImports.test.ts b/lib/lintplugin/src/rules/__tests__/noBarrelImports.test.ts index 4eaa1f905b..c099f74c38 100644 --- a/lib/lintplugin/src/rules/__tests__/noBarrelImports.test.ts +++ b/lib/lintplugin/src/rules/__tests__/noBarrelImports.test.ts @@ -1,6 +1,7 @@ import { RuleTester } from '@typescript-eslint/rule-tester'; import noBarrelImports from '../noBarrelImports'; +/* describe('Test noBarrelImports', () => { const tester = new RuleTester(); tester.run( @@ -9,68 +10,69 @@ describe('Test noBarrelImports', () => { { valid: [ { - code: "import memoize from 'lodash/memoize';", - options: [['lodash']] + code: "import { memoize } from 'es-toolkit';", + options: [['es-toolkit']] }, { - code: "import type { memoize } from 'lodash';", - options: [['lodash']] + code: "import type { memoize } from 'es-toolkit';", + options: [['es-toolkit']] }, { - code: "import type * as _ from 'lodash';", - options: [['lodash']] + code: "import type * as _ from 'es-toolkit';", + options: [['es-toolkit']] }, { - code: "import memoize from 'lodash/memoize'\nimport cloneDeep from 'lodash/cloneDeep'", - options: [['lodash']] + code: "import { memoize } from 'es-toolkit'\nimport { cloneDeep } from 'es-toolkit';", + options: [['es-toolkit']] }, { - code: "import something from 'lodash/memoize'", - options: [['lodash']] + code: "import something from 'es-toolkit'", + options: [['es-toolkit']] }, { - code: "import * as _ from 'lodash'", - options: [['lodash']] + code: "import * as _ from 'es-toolkit'", + options: [['es-toolkit']] }, { - code: "import _ from 'lodash'", - options: [['lodash']] + code: "import _ from 'es-toolkit'", + options: [['es-toolkit']] } ], invalid: [{ - code: "import { memoize } from 'lodash';", + code: "import { memoize } from 'es-toolkit';", errors: [{ messageId: 'main' }], - output: "import memoize from 'lodash/memoize'", - options: [['lodash']] + output: "import { memoize } from 'es-toolkit'", + options: [['es-toolkit']] }, { - code: "import { memoize, cloneDeep } from 'lodash';", + code: "import { memoize, cloneDeep } from 'es-toolkit';", errors: [{ messageId: 'main' }], - output: "import memoize from 'lodash/memoize'\nimport cloneDeep from 'lodash/cloneDeep'", - options: [['lodash']] + output: "import { memoize } from 'es-toolkit'\nimport { cloneDeep } from 'es-toolkit';", + options: [['es-toolkit']] }, { - code: "import { memoize as memoize2, cloneDeep } from 'lodash';", + code: "import { memoize as memoize2, cloneDeep } from 'es-toolkit';", errors: [{ messageId: 'main' }], - output: "import memoize2 from 'lodash/memoize'\nimport cloneDeep from 'lodash/cloneDeep'", - options: [['lodash']] + output: "import { memoize2 } from 'es-toolkit'\nimport { cloneDeep } from 'es-toolkit';", + options: [['es-toolkit']] }, { - code: "import _, { memoize as memoize2, cloneDeep } from 'lodash'", + code: "import _, { memoize as memoize2, cloneDeep } from 'es-toolkit';", errors: [{ messageId: 'main' }], output: [ - "import _ from 'lodash'", - "import memoize2 from 'lodash/memoize'", - "import cloneDeep from 'lodash/cloneDeep'", + "import _ from 'es-toolkit'", + "import { memoize2 } from 'es-toolkit'", + "import { cloneDeep } from 'es-toolkit';", ].join('\n'), - options: [['lodash']] + options: [['es-toolkit']] }, { - code: "import _, { type memoize as memoize2, cloneDeep } from 'lodash'", + code: "import _, { type memoize as memoize2, cloneDeep } from 'es-toolkit';", errors: [{ messageId: 'main' }], output: [ - "import _ from 'lodash'", - "import type memoize2 from 'lodash/memoize'", - "import cloneDeep from 'lodash/cloneDeep'", + "import _ from 'es-toolkit'", + "import type { memoize2 } from 'es-toolkit'", + "import { cloneDeep } from 'es-toolkit';", ].join('\n'), - options: [['lodash']] + options: [['es-toolkit']] }] } ); }); +*/ diff --git a/lib/markdown-tree/package.json b/lib/markdown-tree/package.json index 96623017b9..cef7edba6f 100644 --- a/lib/markdown-tree/package.json +++ b/lib/markdown-tree/package.json @@ -8,7 +8,6 @@ "@shikijs/types": "^3.15.0", "@sourceacademy/modules-buildtools": "workspace:^", "@sourceacademy/modules-repotools": "workspace:^", - "@types/lodash": "^4.14.198", "@types/markdown-it": "^14.1.2", "typescript": "^5.8.2" }, @@ -23,7 +22,7 @@ "shiki": ">=2" }, "dependencies": { - "lodash": "^4.17.23", + "es-toolkit": "^1.44.0", "tm-themes": "^1.10.12", "yaml": "^2.8.0" }, diff --git a/lib/markdown-tree/src/tree.ts b/lib/markdown-tree/src/tree.ts index 7c6a728609..c6826117e0 100644 --- a/lib/markdown-tree/src/tree.ts +++ b/lib/markdown-tree/src/tree.ts @@ -1,9 +1,6 @@ // Adapted from: https://gitlab.com/nfriend/tree-online/-/tree/master?ref_type=heads -import type { RecursiveArray } from 'lodash'; -import defaultsDeep from 'lodash/defaultsDeep'; -import flattenDeep from 'lodash/flattenDeep'; -import last from 'lodash/last'; +import { flattenDeep, last } from 'es-toolkit'; import type { FileStructure } from './types'; /** @@ -73,11 +70,11 @@ export function generateTree( commentLoc: number, options?: GenerateTreeOptions ): string { - const combinedOptions = defaultsDeep({}, options, defaultOptions); + const combinedOptions = { ...defaultOptions, ...options }; return flattenDeep([ getAsciiLine(structure, commentLoc, combinedOptions), - structure.children.map(c => generateTree(c, commentLoc, options)) as RecursiveArray, + structure.children.map(c => generateTree(c, commentLoc, options)), ]) // Remove null entries. Should only occur for the very first node // when `options.rootDot === false` @@ -161,7 +158,7 @@ const getName = ( nameChunks.unshift( getName( structure.parent, - defaultsDeep({}, { trailingDirSlash: true }, options), + { ...{ trailingDirSlash: true }, ...options }, ), ); } diff --git a/lib/modules-lib/src/tabs/MultiItemDisplay/index.tsx b/lib/modules-lib/src/tabs/MultiItemDisplay/index.tsx index 375d6658d8..00924348f2 100644 --- a/lib/modules-lib/src/tabs/MultiItemDisplay/index.tsx +++ b/lib/modules-lib/src/tabs/MultiItemDisplay/index.tsx @@ -1,6 +1,6 @@ import { Button, EditableText } from '@blueprintjs/core'; import { IconNames } from '@blueprintjs/icons'; -import clamp from 'lodash/clamp'; +import { clamp } from 'es-toolkit'; import { useState } from 'react'; export interface MultiItemDisplayProps { @@ -31,7 +31,7 @@ export default function MultiItemDisplay(props: MultiItemDisplayProps) { const elementsDigitCount = Math.floor(Math.log10(Math.max(1, props.elements.length))) + 1; return ( -
{props.elements[currentStep]}
- + ) ); } diff --git a/lib/modules-lib/src/tabs/NumberSelector.tsx b/lib/modules-lib/src/tabs/NumberSelector.tsx index f3e3f91cae..d2d87ff18b 100644 --- a/lib/modules-lib/src/tabs/NumberSelector.tsx +++ b/lib/modules-lib/src/tabs/NumberSelector.tsx @@ -1,5 +1,5 @@ import { EditableText, type EditableTextProps } from '@blueprintjs/core'; -import clamp from 'lodash/clamp'; +import { clamp } from 'es-toolkit'; import { useState } from 'react'; export type NumberSelectorProps = { diff --git a/lib/modules-lib/vitest.config.ts b/lib/modules-lib/vitest.config.ts index 1fb0389d8a..bfed783156 100644 --- a/lib/modules-lib/vitest.config.ts +++ b/lib/modules-lib/vitest.config.ts @@ -12,7 +12,7 @@ export default mergeConfig( include: [ '@blueprintjs/core', '@blueprintjs/icons', - 'lodash', + 'es-toolkit', 'vitest-browser-react', ] }, diff --git a/lib/repotools/package.json b/lib/repotools/package.json index 7c60439683..38e721bf99 100644 --- a/lib/repotools/package.json +++ b/lib/repotools/package.json @@ -6,7 +6,6 @@ "description": "Common library for tooling used by the modules repository", "devDependencies": { "@commander-js/extra-typings": "^14.0.0", - "@types/lodash": "^4.14.198", "@types/node": "^22.15.30", "@vitejs/plugin-react": "^5.1.0", "@vitest/coverage-v8": "^4.0.4", @@ -18,9 +17,9 @@ "@vitest/browser-playwright": "^4.0.4", "chalk": "^5.0.1", "commander": "^14.0.0", + "es-toolkit": "^1.44.0", "esbuild": "^0.27.0", - "jsonschema": "^1.5.0", - "lodash": "^4.17.23" + "jsonschema": "^1.5.0" }, "peerDependencies": { "@vitejs/plugin-react": "*", diff --git a/lib/repotools/src/manifest.ts b/lib/repotools/src/manifest.ts index fc84d0b231..22ef7aaaaf 100644 --- a/lib/repotools/src/manifest.ts +++ b/lib/repotools/src/manifest.ts @@ -2,7 +2,7 @@ import type { Dirent } from 'fs'; import fs from 'fs/promises'; import pathlib from 'path'; import { validate } from 'jsonschema'; -import uniq from 'lodash/uniq.js'; +import { uniq } from 'es-toolkit'; import { tabsDir } from './getGitRoot.js'; import manifestSchema from './manifest.schema.json' with { type: 'json' }; import type { BundleManifest, InputAsset, ResolvedBundle, ResolvedTab, ResultType } from './types.js'; diff --git a/lib/repotools/src/testing/index.ts b/lib/repotools/src/testing/index.ts index 11d21ed853..f58349b2ac 100644 --- a/lib/repotools/src/testing/index.ts +++ b/lib/repotools/src/testing/index.ts @@ -2,8 +2,7 @@ import fs from 'fs/promises'; import pathlib from 'path'; import react from '@vitejs/plugin-react'; import { playwright } from '@vitest/browser-playwright'; -import cloneDeep from 'lodash/cloneDeep.js'; -import partition from 'lodash/partition.js'; +import { cloneDeep, partition } from 'es-toolkit'; import { loadConfigFromFile } from 'vite'; import type { LabelColor } from 'vitest'; import { defineProject, mergeConfig, type TestProjectInlineConfiguration, type ViteUserConfig } from 'vitest/config'; @@ -82,7 +81,7 @@ export const sharedTabsConfig = mergeConfig( '@blueprintjs/icons', 'gl-matrix', 'js-slang', - 'lodash', + 'es-toolkit', 'vitest-browser-react' ] }, @@ -226,7 +225,7 @@ export async function getTestConfiguration(directory: string, watch: boolean): P } if (config === null) { - if (!await isTestDirectory(jsonDir)) { + if (!(await isTestDirectory(jsonDir))) { return { severity: 'success', config: null @@ -254,7 +253,7 @@ export async function getTestConfiguration(directory: string, watch: boolean): P const { bundle } = bundleResult; if (config === null) { - if (!await isTestDirectory(jsonDir)) { + if (!(await isTestDirectory(jsonDir))) { return { severity: 'success', config: null diff --git a/package.json b/package.json index 3c88f75f62..0566977355 100644 --- a/package.json +++ b/package.json @@ -79,8 +79,8 @@ "vitest-browser-react": "^2.0.2" }, "dependencies": { + "es-toolkit": "^1.44.0", "js-slang": "^1.0.81", - "lodash": "^4.17.23", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/src/bundles/curve/src/functions.ts b/src/bundles/curve/src/functions.ts index 4faf29a8a4..c4e6ec8412 100644 --- a/src/bundles/curve/src/functions.ts +++ b/src/bundles/curve/src/functions.ts @@ -1,4 +1,4 @@ -import clamp from 'lodash/clamp'; +import { clamp } from 'es-toolkit'; import { Point, type Curve } from './curves_webgl'; import type { CurveTransformer } from './types'; diff --git a/src/bundles/robot_simulation/src/controllers/program/evaluate.ts b/src/bundles/robot_simulation/src/controllers/program/evaluate.ts index 4107595edb..f72ebd93f9 100644 --- a/src/bundles/robot_simulation/src/controllers/program/evaluate.ts +++ b/src/bundles/robot_simulation/src/controllers/program/evaluate.ts @@ -5,7 +5,7 @@ import { } from 'js-slang/dist/cse-machine/interpreter'; import { parse } from 'js-slang/dist/parser/parser'; import { Variant, type Context } from 'js-slang/dist/types'; -import * as _ from 'lodash'; +import { merge } from 'es-toolkit'; export const DEFAULT_SOURCE_OPTIONS = { scheduler: 'async', @@ -30,7 +30,7 @@ export function* runECEvaluator( context: Context, options: any ): Generator<{ steps: number }, void, undefined> { - const theOptions = _.merge({ ...DEFAULT_SOURCE_OPTIONS }, options); + const theOptions = merge({ ...DEFAULT_SOURCE_OPTIONS }, options); const program = parse(code, context); if (!program) { diff --git a/src/bundles/robot_simulation/src/controllers/utils/mergeConfig.ts b/src/bundles/robot_simulation/src/controllers/utils/mergeConfig.ts index ce7c9c824f..5123c33973 100644 --- a/src/bundles/robot_simulation/src/controllers/utils/mergeConfig.ts +++ b/src/bundles/robot_simulation/src/controllers/utils/mergeConfig.ts @@ -1,9 +1,9 @@ import type { DeepPartial } from '@sourceacademy/modules-lib/types'; -import * as _ from 'lodash'; +import { merge } from 'es-toolkit'; -export const mergeConfig = (defaultConfig: T, userConfig?: DeepPartial): T => { +export const mergeConfig = >(defaultConfig: T, userConfig?: DeepPartial): T => { if (userConfig === undefined) { return defaultConfig; } - return _.merge({ ...defaultConfig }, userConfig); + return merge({ ...defaultConfig }, userConfig); }; diff --git a/src/bundles/rune/src/functions.ts b/src/bundles/rune/src/functions.ts index 7a34c5f925..71fe82d4fc 100644 --- a/src/bundles/rune/src/functions.ts +++ b/src/bundles/rune/src/functions.ts @@ -1,5 +1,5 @@ import { mat4, vec3 } from 'gl-matrix'; -import clamp from 'lodash/clamp'; +import { clamp } from 'es-toolkit'; import { DrawnRune, Rune, @@ -633,7 +633,7 @@ export class HollusionRune extends DrawnRune { lastTime = timeInMs; const framePos - = Math.floor(timeInMs / (period / frameCount)) % frameCount; + = Math.floor(timeInMs / (period / frameCount)) % frameCount; const fbObject = frameBuffer[framePos]; gl.clearColor(1.0, 1.0, 1.0, 1.0); // Set clear color to white, fully opaque gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Clear the viewport diff --git a/src/bundles/unittest/package.json b/src/bundles/unittest/package.json index e2ab7c4e4a..7ab7ef1022 100644 --- a/src/bundles/unittest/package.json +++ b/src/bundles/unittest/package.json @@ -3,12 +3,11 @@ "version": "1.0.0", "private": true, "dependencies": { - "js-slang": "^1.0.81", - "lodash": "^4.17.23" + "es-toolkit": "^1.44.0", + "js-slang": "^1.0.81" }, "devDependencies": { "@sourceacademy/modules-buildtools": "workspace:^", - "@types/lodash": "^4.14.198", "typescript": "^5.8.2" }, "type": "module", diff --git a/src/bundles/unittest/src/asserts.ts b/src/bundles/unittest/src/asserts.ts index abba0c02ed..6f0e8d883d 100644 --- a/src/bundles/unittest/src/asserts.ts +++ b/src/bundles/unittest/src/asserts.ts @@ -1,6 +1,6 @@ import * as list from 'js-slang/dist/stdlib/list'; import { stringify } from 'js-slang/dist/utils/stringify'; -import isEqualWith from 'lodash/isEqualWith'; +import { isEqualWith } from 'es-toolkit'; /** * Asserts that a predicate returns true. diff --git a/src/tabs/Curve/vitest.config.ts b/src/tabs/Curve/vitest.config.ts index baecefa1d1..abfd2ed98a 100644 --- a/src/tabs/Curve/vitest.config.ts +++ b/src/tabs/Curve/vitest.config.ts @@ -5,7 +5,6 @@ export default defineProject({ optimizeDeps: { include: [ 'js-slang/dist/utils/stringify', - 'lodash/clamp', ] }, test: { diff --git a/src/tabs/Rune/vitest.config.ts b/src/tabs/Rune/vitest.config.ts index 2bff4313b7..b52f142c40 100644 --- a/src/tabs/Rune/vitest.config.ts +++ b/src/tabs/Rune/vitest.config.ts @@ -4,7 +4,6 @@ import { defineProject } from 'vitest/config'; export default defineProject({ optimizeDeps: { include: [ - 'lodash/clamp', 'js-slang/dist/utils/stringify' ] }, diff --git a/src/tabs/Unittest/index.tsx b/src/tabs/Unittest/index.tsx index 4b6776b8fd..9d852782f0 100644 --- a/src/tabs/Unittest/index.tsx +++ b/src/tabs/Unittest/index.tsx @@ -5,7 +5,7 @@ import type { SuiteResult, UnittestModuleState } from '@sourceacademy/bundle-unittest/types'; import { defineTab, getModuleState } from '@sourceacademy/modules-lib/tabs/utils'; -import partition from 'lodash/partition'; +import { partition } from 'es-toolkit'; const colfixed = { border: '1px solid gray', diff --git a/yarn.lock b/yarn.lock index da73c9be22..7cd1888167 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4415,9 +4415,8 @@ __metadata: resolution: "@sourceacademy/bundle-unittest@workspace:src/bundles/unittest" dependencies: "@sourceacademy/modules-buildtools": "workspace:^" - "@types/lodash": "npm:^4.14.198" + es-toolkit: "npm:^1.44.0" js-slang: "npm:^1.0.81" - lodash: "npm:^4.17.23" typescript: "npm:^5.8.2" languageName: unknown linkType: soft @@ -4488,9 +4487,8 @@ __metadata: "@shikijs/types": "npm:^3.15.0" "@sourceacademy/modules-buildtools": "workspace:^" "@sourceacademy/modules-repotools": "workspace:^" - "@types/lodash": "npm:^4.14.198" "@types/markdown-it": "npm:^14.1.2" - lodash: "npm:^4.17.23" + es-toolkit: "npm:^1.44.0" tm-themes: "npm:^1.10.12" typescript: "npm:^5.8.2" yaml: "npm:^2.8.0" @@ -4508,7 +4506,6 @@ __metadata: "@sourceacademy/modules-repotools": "workspace:^" "@types/estree": "npm:^1.0.0" "@types/http-server": "npm:^0.12.4" - "@types/lodash": "npm:^4.14.198" "@types/node": "npm:^22.15.30" "@vitejs/plugin-react": "npm:^5.1.0" "@vitest/browser-playwright": "npm:^4.0.4" @@ -4517,11 +4514,11 @@ __metadata: astring: "npm:^1.8.6" chalk: "npm:^5.0.1" commander: "npm:^14.0.0" + es-toolkit: "npm:^1.44.0" esbuild: "npm:^0.27.0" eslint: "npm:^9.35.0" http-server: "npm:^14.1.1" jsdom: "npm:^26.1.0" - lodash: "npm:^4.17.23" typedoc: "npm:^0.28.9" typescript: "npm:^5.8.2" vite: "npm:^7.1.11" @@ -4590,7 +4587,7 @@ __metadata: "@actions/exec": "npm:^3.0.0" "@sourceacademy/modules-repotools": "workspace:^" "@types/node": "npm:^22.15.30" - lodash: "npm:^4.17.23" + es-toolkit: "npm:^1.44.0" snyk-nodejs-lockfile-parser: "npm:^2.4.2" typescript: "npm:^5.8.2" vitest: "npm:^4.0.4" @@ -4628,16 +4625,15 @@ __metadata: resolution: "@sourceacademy/modules-repotools@workspace:lib/repotools" dependencies: "@commander-js/extra-typings": "npm:^14.0.0" - "@types/lodash": "npm:^4.14.198" "@types/node": "npm:^22.15.30" "@vitejs/plugin-react": "npm:^5.1.0" "@vitest/browser-playwright": "npm:^4.0.4" "@vitest/coverage-v8": "npm:^4.0.4" chalk: "npm:^5.0.1" commander: "npm:^14.0.0" + es-toolkit: "npm:^1.44.0" esbuild: "npm:^0.27.0" jsonschema: "npm:^1.5.0" - lodash: "npm:^4.17.23" typescript: "npm:^5.8.2" vitest: "npm:^4.0.4" vitest-browser-react: "npm:^2.0.2" @@ -4663,6 +4659,7 @@ __metadata: "@vitest/coverage-v8": "npm:^4.0.4" "@vitest/eslint-plugin": "npm:^1.3.4" "@yarnpkg/types": "npm:^4.0.1" + es-toolkit: "npm:^1.44.0" esbuild: "npm:^0.27.0" eslint: "npm:^9.35.0" eslint-plugin-import: "npm:^2.32.0" @@ -4675,7 +4672,6 @@ __metadata: js-slang: "npm:^1.0.81" jsdom: "npm:^26.1.0" jsonc-eslint-parser: "npm:^2.4.0" - lodash: "npm:^4.17.23" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" typescript: "npm:^5.8.2" @@ -5567,13 +5563,6 @@ __metadata: languageName: node linkType: hard -"@types/lodash@npm:^4.14.198": - version: 4.17.23 - resolution: "@types/lodash@npm:4.17.23" - checksum: 10c0/9d9cbfb684e064a2b78aab9e220d398c9c2a7d36bc51a07b184ff382fa043a99b3d00c16c7f109b4eb8614118f4869678dbae7d5c6700ed16fb9340e26cc0bf6 - languageName: node - linkType: hard - "@types/markdown-it@npm:^14.1.2": version: 14.1.2 resolution: "@types/markdown-it@npm:14.1.2" @@ -9504,6 +9493,13 @@ __metadata: languageName: node linkType: hard +"es-toolkit@npm:^1.44.0, lodash@npm:^4.17.15": + version: 4.17.21 + resolution: "es-toolkit@npm:1.44.0" + checksum: 10c0/b80ff52ddc85ba26914cda57c9d4e46379ccc38c60dc097ef0d065cc0b20f95a16cf8d537969eea600b51c6687b5900a6cce67489db16d5ccc14d47597a29c34 + languageName: node + linkType: hard + "esbuild@npm:^0.21.3": version: 0.21.5 resolution: "esbuild@npm:0.21.5" @@ -12660,14 +12656,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.15, lodash@npm:^4.17.21": - version: 4.17.21 - resolution: "lodash@npm:4.17.21" - checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c - languageName: node - linkType: hard - -"lodash@npm:^4.17.23": +"lodash@npm:^4.17.21": version: 4.17.23 resolution: "lodash@npm:4.17.23" checksum: 10c0/1264a90469f5bb95d4739c43eb6277d15b6d9e186df4ac68c3620443160fc669e2f14c11e7d8b2ccf078b81d06147c01a8ccced9aab9f9f63d50dcf8cace6bf6 From 7108867a90de9e5063883c14af4d65627898b856 Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Fri, 13 Feb 2026 02:05:19 +0800 Subject: [PATCH 2/7] Revert noBarrelImports tests + mock memoize function --- .github/actions/src/__tests__/commons.test.ts | 3 +- .../rules/__tests__/noBarrelImports.test.ts | 68 +++++++++---------- 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/.github/actions/src/__tests__/commons.test.ts b/.github/actions/src/__tests__/commons.test.ts index 9393ae9bf8..5c610dfd71 100644 --- a/.github/actions/src/__tests__/commons.test.ts +++ b/.github/actions/src/__tests__/commons.test.ts @@ -5,7 +5,8 @@ import * as commons from '../commons.js'; vi.mock(import("es-toolkit"), async (importOriginal) => { const actual = await importOriginal() return { - ...actual + ...actual, + memoize: (x : any) => x } }) diff --git a/lib/lintplugin/src/rules/__tests__/noBarrelImports.test.ts b/lib/lintplugin/src/rules/__tests__/noBarrelImports.test.ts index c099f74c38..4eaa1f905b 100644 --- a/lib/lintplugin/src/rules/__tests__/noBarrelImports.test.ts +++ b/lib/lintplugin/src/rules/__tests__/noBarrelImports.test.ts @@ -1,7 +1,6 @@ import { RuleTester } from '@typescript-eslint/rule-tester'; import noBarrelImports from '../noBarrelImports'; -/* describe('Test noBarrelImports', () => { const tester = new RuleTester(); tester.run( @@ -10,69 +9,68 @@ describe('Test noBarrelImports', () => { { valid: [ { - code: "import { memoize } from 'es-toolkit';", - options: [['es-toolkit']] + code: "import memoize from 'lodash/memoize';", + options: [['lodash']] }, { - code: "import type { memoize } from 'es-toolkit';", - options: [['es-toolkit']] + code: "import type { memoize } from 'lodash';", + options: [['lodash']] }, { - code: "import type * as _ from 'es-toolkit';", - options: [['es-toolkit']] + code: "import type * as _ from 'lodash';", + options: [['lodash']] }, { - code: "import { memoize } from 'es-toolkit'\nimport { cloneDeep } from 'es-toolkit';", - options: [['es-toolkit']] + code: "import memoize from 'lodash/memoize'\nimport cloneDeep from 'lodash/cloneDeep'", + options: [['lodash']] }, { - code: "import something from 'es-toolkit'", - options: [['es-toolkit']] + code: "import something from 'lodash/memoize'", + options: [['lodash']] }, { - code: "import * as _ from 'es-toolkit'", - options: [['es-toolkit']] + code: "import * as _ from 'lodash'", + options: [['lodash']] }, { - code: "import _ from 'es-toolkit'", - options: [['es-toolkit']] + code: "import _ from 'lodash'", + options: [['lodash']] } ], invalid: [{ - code: "import { memoize } from 'es-toolkit';", + code: "import { memoize } from 'lodash';", errors: [{ messageId: 'main' }], - output: "import { memoize } from 'es-toolkit'", - options: [['es-toolkit']] + output: "import memoize from 'lodash/memoize'", + options: [['lodash']] }, { - code: "import { memoize, cloneDeep } from 'es-toolkit';", + code: "import { memoize, cloneDeep } from 'lodash';", errors: [{ messageId: 'main' }], - output: "import { memoize } from 'es-toolkit'\nimport { cloneDeep } from 'es-toolkit';", - options: [['es-toolkit']] + output: "import memoize from 'lodash/memoize'\nimport cloneDeep from 'lodash/cloneDeep'", + options: [['lodash']] }, { - code: "import { memoize as memoize2, cloneDeep } from 'es-toolkit';", + code: "import { memoize as memoize2, cloneDeep } from 'lodash';", errors: [{ messageId: 'main' }], - output: "import { memoize2 } from 'es-toolkit'\nimport { cloneDeep } from 'es-toolkit';", - options: [['es-toolkit']] + output: "import memoize2 from 'lodash/memoize'\nimport cloneDeep from 'lodash/cloneDeep'", + options: [['lodash']] }, { - code: "import _, { memoize as memoize2, cloneDeep } from 'es-toolkit';", + code: "import _, { memoize as memoize2, cloneDeep } from 'lodash'", errors: [{ messageId: 'main' }], output: [ - "import _ from 'es-toolkit'", - "import { memoize2 } from 'es-toolkit'", - "import { cloneDeep } from 'es-toolkit';", + "import _ from 'lodash'", + "import memoize2 from 'lodash/memoize'", + "import cloneDeep from 'lodash/cloneDeep'", ].join('\n'), - options: [['es-toolkit']] + options: [['lodash']] }, { - code: "import _, { type memoize as memoize2, cloneDeep } from 'es-toolkit';", + code: "import _, { type memoize as memoize2, cloneDeep } from 'lodash'", errors: [{ messageId: 'main' }], output: [ - "import _ from 'es-toolkit'", - "import type { memoize2 } from 'es-toolkit'", - "import { cloneDeep } from 'es-toolkit';", + "import _ from 'lodash'", + "import type memoize2 from 'lodash/memoize'", + "import cloneDeep from 'lodash/cloneDeep'", ].join('\n'), - options: [['es-toolkit']] + options: [['lodash']] }] } ); }); -*/ From 9540a780cde869d407c25809d9d5ad11310e7058 Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Wed, 18 Feb 2026 16:30:41 +0800 Subject: [PATCH 3/7] Fix weird dependency aliasing --- .github/actions/src/__tests__/sample_why.txt | 12 ++++++------ yarn.lock | 11 ++++++++--- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/.github/actions/src/__tests__/sample_why.txt b/.github/actions/src/__tests__/sample_why.txt index a64d322d11..7c697a6046 100644 --- a/.github/actions/src/__tests__/sample_why.txt +++ b/.github/actions/src/__tests__/sample_why.txt @@ -1,6 +1,6 @@ {"value":"@sourceacademy/bundle-ar@workspace:src/bundles/ar","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}}}} {"value":"@sourceacademy/bundle-arcade_2d@workspace:src/bundles/arcade_2d","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-lib@workspace:lib/modules-lib":{"value":{"locator":"@sourceacademy/modules-lib@workspace:lib/modules-lib","descriptor":"@sourceacademy/modules-lib@workspace:^"},"children":{}}}} -{"value":"@sourceacademy/bundle-binary_tree@workspace:src/bundles/binary_tree","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}}}}}} +{"value":"@sourceacademy/bundle-binary_tree@workspace:src/bundles/binary_tree","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{"lodash@npm:4.17.21":{"value":{"locator":"lodash@npm:4.17.21","descriptor":"lodash@npm:^4.17.21"},"children":{}}}}}} {"value":"@sourceacademy/bundle-communication@workspace:src/bundles/communication","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}}}} {"value":"@sourceacademy/bundle-copy_gc@workspace:src/bundles/copy_gc","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}}}} {"value":"@sourceacademy/bundle-csg@workspace:src/bundles/csg","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-lib@workspace:lib/modules-lib":{"value":{"locator":"@sourceacademy/modules-lib@workspace:lib/modules-lib","descriptor":"@sourceacademy/modules-lib@workspace:^"},"children":{}}}} @@ -25,16 +25,16 @@ {"value":"@sourceacademy/bundle-stereo_sound@workspace:src/bundles/stereo_sound","children":{"@sourceacademy/bundle-midi@workspace:src/bundles/midi":{"value":{"locator":"@sourceacademy/bundle-midi@workspace:src/bundles/midi","descriptor":"@sourceacademy/bundle-midi@workspace:^"},"children":{}},"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{}}}} {"value":"@sourceacademy/bundle-unittest@workspace:src/bundles/unittest","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{}},"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}}}} {"value":"@sourceacademy/bundle-unity_academy@workspace:src/bundles/unity_academy","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}}}} -{"value":"@sourceacademy/bundle-wasm@workspace:src/bundles/wasm","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"source-academy-wabt@npm:1.1.3":{"value":{"locator":"source-academy-wabt@npm:1.1.3","descriptor":"source-academy-wabt@npm:^1.0.4"},"children":{"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}}}}}} +{"value":"@sourceacademy/bundle-wasm@workspace:src/bundles/wasm","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"source-academy-wabt@npm:1.1.3":{"value":{"locator":"source-academy-wabt@npm:1.1.3","descriptor":"source-academy-wabt@npm:^1.0.4"},"children":{"lodash@npm:4.17.21":{"value":{"locator":"lodash@npm:4.17.21","descriptor":"lodash@npm:^4.17.21"},"children":{}}}}}} {"value":"@sourceacademy/lint-plugin@workspace:lib/lintplugin","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:^"},"children":{}}}} -{"value":"@sourceacademy/markdown-plugin-directory-tree@workspace:lib/markdown-tree","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}},"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:^"},"children":{}}}} -{"value":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","children":{"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}},"@sourceacademy/modules-repotools@virtual:1448f4d06c0cf02cc986bce0139b31c0f3c95af1573e69673bc11ad2928a2fc505818a40d3f1caf168c35ce00c20238d52dfdba1940c59c81fd5df1b08ba49d6#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:1448f4d06c0cf02cc986bce0139b31c0f3c95af1573e69673bc11ad2928a2fc505818a40d3f1caf168c35ce00c20238d52dfdba1940c59c81fd5df1b08ba49d6#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:1448f4d06c0cf02cc986bce0139b31c0f3c95af1573e69673bc11ad2928a2fc505818a40d3f1caf168c35ce00c20238d52dfdba1940c59c81fd5df1b08ba49d6#workspace:^"},"children":{}}}} +{"value":"@sourceacademy/markdown-plugin-directory-tree@workspace:lib/markdown-tree","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:^"},"children":{}},"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}}}} +{"value":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","children":{"@sourceacademy/modules-repotools@virtual:1448f4d06c0cf02cc986bce0139b31c0f3c95af1573e69673bc11ad2928a2fc505818a40d3f1caf168c35ce00c20238d52dfdba1940c59c81fd5df1b08ba49d6#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:1448f4d06c0cf02cc986bce0139b31c0f3c95af1573e69673bc11ad2928a2fc505818a40d3f1caf168c35ce00c20238d52dfdba1940c59c81fd5df1b08ba49d6#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:1448f4d06c0cf02cc986bce0139b31c0f3c95af1573e69673bc11ad2928a2fc505818a40d3f1caf168c35ce00c20238d52dfdba1940c59c81fd5df1b08ba49d6#workspace:^"},"children":{}},"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}}}} {"value":"@sourceacademy/modules-devserver@workspace:devserver","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-lib@workspace:lib/modules-lib":{"value":{"locator":"@sourceacademy/modules-lib@workspace:lib/modules-lib","descriptor":"@sourceacademy/modules-lib@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{}}}} {"value":"@sourceacademy/modules-docserver@workspace:docs","children":{"@sourceacademy/modules-lib@workspace:lib/modules-lib":{"value":{"locator":"@sourceacademy/modules-lib@workspace:lib/modules-lib","descriptor":"@sourceacademy/modules-lib@workspace:^"},"children":{}},"@sourceacademy/lint-plugin@virtual:f0562030a653a107496800a80ececfadfd737a6a260bbd2572ca4e42de1d6b97749197bb1c41d0d71c9f18ab009789560666041994678fe1aba63902e9fb15bd#workspace:lib/lintplugin":{"value":{"locator":"@sourceacademy/lint-plugin@virtual:f0562030a653a107496800a80ececfadfd737a6a260bbd2572ca4e42de1d6b97749197bb1c41d0d71c9f18ab009789560666041994678fe1aba63902e9fb15bd#workspace:lib/lintplugin","descriptor":"@sourceacademy/lint-plugin@virtual:f0562030a653a107496800a80ececfadfd737a6a260bbd2572ca4e42de1d6b97749197bb1c41d0d71c9f18ab009789560666041994678fe1aba63902e9fb15bd#workspace:^"},"children":{}},"@sourceacademy/markdown-plugin-directory-tree@virtual:f0562030a653a107496800a80ececfadfd737a6a260bbd2572ca4e42de1d6b97749197bb1c41d0d71c9f18ab009789560666041994678fe1aba63902e9fb15bd#workspace:lib/markdown-tree":{"value":{"locator":"@sourceacademy/markdown-plugin-directory-tree@virtual:f0562030a653a107496800a80ececfadfd737a6a260bbd2572ca4e42de1d6b97749197bb1c41d0d71c9f18ab009789560666041994678fe1aba63902e9fb15bd#workspace:lib/markdown-tree","descriptor":"@sourceacademy/markdown-plugin-directory-tree@virtual:f0562030a653a107496800a80ececfadfd737a6a260bbd2572ca4e42de1d6b97749197bb1c41d0d71c9f18ab009789560666041994678fe1aba63902e9fb15bd#workspace:^"},"children":{}}}} -{"value":"@sourceacademy/modules-github-actions@workspace:.github/actions","children":{"@actions/artifact@npm:2.3.2":{"value":{"locator":"@actions/artifact@npm:2.3.2","descriptor":"@actions/artifact@npm:^2.3.2"},"children":{"archiver@npm:7.0.1":{"value":{"locator":"archiver@npm:7.0.1","descriptor":"archiver@npm:^7.0.1"},"children":{"archiver-utils@npm:5.0.2":{"value":{"locator":"archiver-utils@npm:5.0.2","descriptor":"archiver-utils@npm:^5.0.2"},"children":{"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-tookit@npm:^1.44.0"},"children":{}}}},"zip-stream@npm:6.0.1":{"value":{"locator":"zip-stream@npm:6.0.1","descriptor":"zip-stream@npm:^6.0.1"},"children":{"archiver-utils@npm:5.0.2":{"value":{"locator":"archiver-utils@npm:5.0.2","descriptor":"archiver-utils@npm:^5.0.0"},"children":{}}}}}}}},"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}},"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:^"},"children":{}}}} +{"value":"@sourceacademy/modules-github-actions@workspace:.github/actions","children":{"@actions/artifact@npm:2.3.2":{"value":{"locator":"@actions/artifact@npm:2.3.2","descriptor":"@actions/artifact@npm:^2.3.2"},"children":{"archiver@npm:7.0.1":{"value":{"locator":"archiver@npm:7.0.1","descriptor":"archiver@npm:^7.0.1"},"children":{"archiver-utils@npm:5.0.2":{"value":{"locator":"archiver-utils@npm:5.0.2","descriptor":"archiver-utils@npm:^5.0.2"},"children":{"lodash@npm:4.17.21":{"value":{"locator":"lodash@npm:4.17.21","descriptor":"lodash@npm:^4.17.15"},"children":{}}}},"zip-stream@npm:6.0.1":{"value":{"locator":"zip-stream@npm:6.0.1","descriptor":"zip-stream@npm:^6.0.1"},"children":{"archiver-utils@npm:5.0.2":{"value":{"locator":"archiver-utils@npm:5.0.2","descriptor":"archiver-utils@npm:^5.0.0"},"children":{}}}}}}}},"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:420fa510eaf06edbb20ddb72fbcd454e937e7e266b8c6b7a55ab314e0562f2688175809f2b44c78563a0467da21b6d34688fe0020ecef5e669997fe518ee56e1#workspace:^"},"children":{}},"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}}}} {"value":"@sourceacademy/modules-lib@workspace:lib/modules-lib","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{}}}} {"value":"@sourceacademy/modules-repotools@workspace:lib/repotools","children":{"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}}}} -{"value":"@sourceacademy/modules@workspace:.","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{}},"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}},"@sourceacademy/lint-plugin@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/lintplugin":{"value":{"locator":"@sourceacademy/lint-plugin@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/lintplugin","descriptor":"@sourceacademy/lint-plugin@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:^"},"children":{}},"@sourceacademy/modules-repotools@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:^"},"children":{}}}} +{"value":"@sourceacademy/modules@workspace:.","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"js-slang@npm:1.0.85":{"value":{"locator":"js-slang@npm:1.0.85","descriptor":"js-slang@npm:^1.0.81"},"children":{}},"@sourceacademy/lint-plugin@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/lintplugin":{"value":{"locator":"@sourceacademy/lint-plugin@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/lintplugin","descriptor":"@sourceacademy/lint-plugin@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:^"},"children":{}},"@sourceacademy/modules-repotools@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/repotools":{"value":{"locator":"@sourceacademy/modules-repotools@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:lib/repotools","descriptor":"@sourceacademy/modules-repotools@virtual:72a684de9912e8b42da7a581a5478d78ad73e0a505830e61e9b2fbc990fcc10719f71ef5373c26313c28b9295f1381b0d95a4d0ab2ae6e33671c2ba25a5c1dc2#workspace:^"},"children":{}},"es-toolkit@npm:1.44.0":{"value":{"locator":"es-toolkit@npm:1.44.0","descriptor":"es-toolkit@npm:^1.44.0"},"children":{}}}} {"value":"@sourceacademy/tab-ArcadeTwod@workspace:src/tabs/ArcadeTwod","children":{"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-lib@workspace:lib/modules-lib":{"value":{"locator":"@sourceacademy/modules-lib@workspace:lib/modules-lib","descriptor":"@sourceacademy/modules-lib@workspace:^"},"children":{}}}} {"value":"@sourceacademy/tab-AugmentedReality@workspace:src/tabs/AugmentedReality","children":{"@sourceacademy/bundle-ar@workspace:src/bundles/ar":{"value":{"locator":"@sourceacademy/bundle-ar@workspace:src/bundles/ar","descriptor":"@sourceacademy/bundle-ar@workspace:^"},"children":{}},"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-lib@workspace:lib/modules-lib":{"value":{"locator":"@sourceacademy/modules-lib@workspace:lib/modules-lib","descriptor":"@sourceacademy/modules-lib@workspace:^"},"children":{}}}} {"value":"@sourceacademy/tab-CopyGc@workspace:src/tabs/CopyGc","children":{"@sourceacademy/bundle-copy_gc@workspace:src/bundles/copy_gc":{"value":{"locator":"@sourceacademy/bundle-copy_gc@workspace:src/bundles/copy_gc","descriptor":"@sourceacademy/bundle-copy_gc@workspace:^"},"children":{}},"@sourceacademy/modules-buildtools@workspace:lib/buildtools":{"value":{"locator":"@sourceacademy/modules-buildtools@workspace:lib/buildtools","descriptor":"@sourceacademy/modules-buildtools@workspace:^"},"children":{}},"@sourceacademy/modules-lib@workspace:lib/modules-lib":{"value":{"locator":"@sourceacademy/modules-lib@workspace:lib/modules-lib","descriptor":"@sourceacademy/modules-lib@workspace:^"},"children":{}}}} diff --git a/yarn.lock b/yarn.lock index 7cd1888167..c72cddf161 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9493,9 +9493,14 @@ __metadata: languageName: node linkType: hard -"es-toolkit@npm:^1.44.0, lodash@npm:^4.17.15": - version: 4.17.21 +"es-toolkit@npm:^1.44.0": + version: 1.44.0 resolution: "es-toolkit@npm:1.44.0" + dependenciesMeta: + "@trivago/prettier-plugin-sort-imports@4.3.0": + unplugged: true + prettier-plugin-sort-re-exports@0.0.1: + unplugged: true checksum: 10c0/b80ff52ddc85ba26914cda57c9d4e46379ccc38c60dc097ef0d065cc0b20f95a16cf8d537969eea600b51c6687b5900a6cce67489db16d5ccc14d47597a29c34 languageName: node linkType: hard @@ -12656,7 +12661,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.21": +"lodash@npm:^4.17.15, lodash@npm:^4.17.21": version: 4.17.23 resolution: "lodash@npm:4.17.23" checksum: 10c0/1264a90469f5bb95d4739c43eb6277d15b6d9e186df4ac68c3620443160fc669e2f14c11e7d8b2ccf078b81d06147c01a8ccced9aab9f9f63d50dcf8cace6bf6 From 870b6ba2f468707071f16d0ae9bbb460c3f6af3d Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Wed, 18 Feb 2026 17:22:10 +0800 Subject: [PATCH 4/7] Lint files --- .github/actions/src/__tests__/commons.test.ts | 10 ++++----- lib/repotools/src/manifest.ts | 2 +- lib/repotools/src/testing/index.ts | 4 ++-- lib/vitest-reporter/src/coverage-reporter.cts | 22 +++++++++---------- src/bundles/arcade_2d/src/functions.ts | 18 +++++++-------- src/bundles/midi/src/types.ts | 2 +- src/bundles/repl/src/programmable_repl.ts | 2 +- .../src/controllers/program/evaluate.ts | 2 +- src/bundles/rune/src/functions.ts | 2 +- src/bundles/unittest/src/asserts.ts | 2 +- 10 files changed, 33 insertions(+), 33 deletions(-) diff --git a/.github/actions/src/__tests__/commons.test.ts b/.github/actions/src/__tests__/commons.test.ts index 5c610dfd71..3b7598c623 100644 --- a/.github/actions/src/__tests__/commons.test.ts +++ b/.github/actions/src/__tests__/commons.test.ts @@ -2,13 +2,13 @@ import * as exec from '@actions/exec'; import { describe, expect, it, test, vi } from 'vitest'; import * as commons from '../commons.js'; -vi.mock(import("es-toolkit"), async (importOriginal) => { - const actual = await importOriginal() +vi.mock(import('es-toolkit'), async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, - memoize: (x : any) => x - } -}) + memoize: (x: any) => x + }; +}); const mockedExecOutput = vi.spyOn(exec, 'getExecOutput'); diff --git a/lib/repotools/src/manifest.ts b/lib/repotools/src/manifest.ts index 22ef7aaaaf..fa7ee78a37 100644 --- a/lib/repotools/src/manifest.ts +++ b/lib/repotools/src/manifest.ts @@ -1,8 +1,8 @@ import type { Dirent } from 'fs'; import fs from 'fs/promises'; import pathlib from 'path'; -import { validate } from 'jsonschema'; import { uniq } from 'es-toolkit'; +import { validate } from 'jsonschema'; import { tabsDir } from './getGitRoot.js'; import manifestSchema from './manifest.schema.json' with { type: 'json' }; import type { BundleManifest, InputAsset, ResolvedBundle, ResolvedTab, ResultType } from './types.js'; diff --git a/lib/repotools/src/testing/index.ts b/lib/repotools/src/testing/index.ts index f58349b2ac..6af79ee703 100644 --- a/lib/repotools/src/testing/index.ts +++ b/lib/repotools/src/testing/index.ts @@ -225,7 +225,7 @@ export async function getTestConfiguration(directory: string, watch: boolean): P } if (config === null) { - if (!(await isTestDirectory(jsonDir))) { + if (!await isTestDirectory(jsonDir)) { return { severity: 'success', config: null @@ -253,7 +253,7 @@ export async function getTestConfiguration(directory: string, watch: boolean): P const { bundle } = bundleResult; if (config === null) { - if (!(await isTestDirectory(jsonDir))) { + if (!await isTestDirectory(jsonDir)) { return { severity: 'success', config: null diff --git a/lib/vitest-reporter/src/coverage-reporter.cts b/lib/vitest-reporter/src/coverage-reporter.cts index d9b8748a1e..2829865241 100644 --- a/lib/vitest-reporter/src/coverage-reporter.cts +++ b/lib/vitest-reporter/src/coverage-reporter.cts @@ -49,20 +49,20 @@ function getUncoveredLines(node: report.ReportNode) { let newRange = true; const ranges = coveredLines .reduce<([number] | [number, number])[]>((acum, [line, hit]) => { - if (hit) { - newRange = true; - } else { - const linenum = parseInt(line); - if (newRange) { - acum.push([linenum]); - newRange = false; + if (hit) { + newRange = true; } else { - acum[acum.length - 1][1] = linenum; + const linenum = parseInt(line); + if (newRange) { + acum.push([linenum]); + newRange = false; + } else { + acum[acum.length - 1][1] = linenum; + } } - } - return acum; - }, []); + return acum; + }, []); return ranges; } diff --git a/src/bundles/arcade_2d/src/functions.ts b/src/bundles/arcade_2d/src/functions.ts index 6b16b0cf8c..ad384a5883 100644 --- a/src/bundles/arcade_2d/src/functions.ts +++ b/src/bundles/arcade_2d/src/functions.ts @@ -519,15 +519,15 @@ export function query_pointer_position(): PositionXY { * @hidden */ const withinRange: (num: number, min: number, max: number) => number -= (num: number, min: number, max: number) => { - if (num > max) { - return max; - } - if (num < min) { - return min; - } - return num; -}; + = (num: number, min: number, max: number) => { + if (num > max) { + return max; + } + if (num < min) { + return min; + } + return num; + }; /** * Sets the frames per second of the canvas, which should be between the MIN_FPS and MAX_FPS. diff --git a/src/bundles/midi/src/types.ts b/src/bundles/midi/src/types.ts index 6291c6790a..df28275a29 100644 --- a/src/bundles/midi/src/types.ts +++ b/src/bundles/midi/src/types.ts @@ -11,7 +11,7 @@ type NotesWithFlats = 'A' | 'B' | 'D' | 'E' | 'G'; // & {} is a weird trick with typescript that causes intellisense to evaluate every single option // so you see all the valid notes instead of just the type definition below export type Note = {} & (NoteName | `${NoteName}${Accidental.NATURAL}` | `${NotesWithFlats}${Accidental.FLAT}` | `${NotesWithSharps}${Accidental.SHARP}`); -export type NoteWithOctave = (Note | `${Note}${number}`); +export type NoteWithOctave = Note | `${Note}${number}`; /** * An integer representing a MIDI note value. Refer to {@link https://i.imgur.com/qGQgmYr.png|this} mapping from diff --git a/src/bundles/repl/src/programmable_repl.ts b/src/bundles/repl/src/programmable_repl.ts index 7bb7678417..1d9bfc9720 100644 --- a/src/bundles/repl/src/programmable_repl.ts +++ b/src/bundles/repl/src/programmable_repl.ts @@ -10,7 +10,7 @@ import { COLOR_ERROR_MESSAGE, COLOR_RUN_CODE_RESULT, DEFAULT_EDITOR_HEIGHT } fro import { evaluatorSymbol } from './functions'; export class ProgrammableRepl { - public evalFunction: ((code: string) => any); + public evalFunction: (code: string) => any; public userCodeInEditor: string; public outputStrings: any[]; private _editorInstance; diff --git a/src/bundles/robot_simulation/src/controllers/program/evaluate.ts b/src/bundles/robot_simulation/src/controllers/program/evaluate.ts index f72ebd93f9..940d030875 100644 --- a/src/bundles/robot_simulation/src/controllers/program/evaluate.ts +++ b/src/bundles/robot_simulation/src/controllers/program/evaluate.ts @@ -1,3 +1,4 @@ +import { merge } from 'es-toolkit'; import { Control, Stash, @@ -5,7 +6,6 @@ import { } from 'js-slang/dist/cse-machine/interpreter'; import { parse } from 'js-slang/dist/parser/parser'; import { Variant, type Context } from 'js-slang/dist/types'; -import { merge } from 'es-toolkit'; export const DEFAULT_SOURCE_OPTIONS = { scheduler: 'async', diff --git a/src/bundles/rune/src/functions.ts b/src/bundles/rune/src/functions.ts index 71fe82d4fc..bb5c0c5e7e 100644 --- a/src/bundles/rune/src/functions.ts +++ b/src/bundles/rune/src/functions.ts @@ -1,5 +1,5 @@ -import { mat4, vec3 } from 'gl-matrix'; import { clamp } from 'es-toolkit'; +import { mat4, vec3 } from 'gl-matrix'; import { DrawnRune, Rune, diff --git a/src/bundles/unittest/src/asserts.ts b/src/bundles/unittest/src/asserts.ts index 6f0e8d883d..a1d337271e 100644 --- a/src/bundles/unittest/src/asserts.ts +++ b/src/bundles/unittest/src/asserts.ts @@ -1,6 +1,6 @@ +import { isEqualWith } from 'es-toolkit'; import * as list from 'js-slang/dist/stdlib/list'; import { stringify } from 'js-slang/dist/utils/stringify'; -import { isEqualWith } from 'es-toolkit'; /** * Asserts that a predicate returns true. From 40e4e057afd413856b04bdee1442526dc0b52c33 Mon Sep 17 00:00:00 2001 From: Richard Dominick <34370238+RichDom2185@users.noreply.github.com> Date: Thu, 19 Feb 2026 01:11:15 +0800 Subject: [PATCH 5/7] Fix lockfile post-merge --- yarn.lock | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index 89ad24b16e..5cf5618785 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4809,7 +4809,6 @@ __metadata: "@vitest/coverage-v8": "npm:^4.0.18" "@vitest/eslint-plugin": "npm:^1.6.6" "@yarnpkg/types": "npm:^4.0.1" - es-toolkit: "npm:^1.44.0" esbuild: "npm:^0.27.0" eslint: "npm:^9.35.0" eslint-import-resolver-typescript: "npm:^4.4.4" @@ -4829,8 +4828,8 @@ __metadata: peerDependencies: "@blueprintjs/core": ^6.0.0 "@blueprintjs/icons": ^6.0.0 + es-toolkit: ^1.44.0 js-slang: ^1.0.85 - lodash: ^4.17.23 react: ^18.3.1 react-dom: ^18.3.1 languageName: unknown @@ -5740,6 +5739,13 @@ __metadata: languageName: node linkType: hard +"@types/lodash@npm:^4.14.198": + version: 4.17.23 + resolution: "@types/lodash@npm:4.17.23" + checksum: 10c0/9d9cbfb684e064a2b78aab9e220d398c9c2a7d36bc51a07b184ff382fa043a99b3d00c16c7f109b4eb8614118f4869678dbae7d5c6700ed16fb9340e26cc0bf6 + languageName: node + linkType: hard + "@types/markdown-it@npm:^14.1.2": version: 14.1.2 resolution: "@types/markdown-it@npm:14.1.2" @@ -13020,6 +13026,13 @@ __metadata: linkType: hard "lodash@npm:^4.17.15, lodash@npm:^4.17.21": + version: 4.17.21 + resolution: "lodash@npm:4.17.21" + checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c + languageName: node + linkType: hard + +"lodash@npm:^4.17.23": version: 4.17.23 resolution: "lodash@npm:4.17.23" checksum: 10c0/1264a90469f5bb95d4739c43eb6277d15b6d9e186df4ac68c3620443160fc669e2f14c11e7d8b2ccf078b81d06147c01a8ccced9aab9f9f63d50dcf8cace6bf6 From 0dfdaf6a8e572922bf7be3c02cc3ff0e98d18ab4 Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Thu, 19 Feb 2026 20:37:03 +0800 Subject: [PATCH 6/7] Fix missing packages --- .github/actions/package.json | 1 - lib/modules-lib/package.json | 3 +-- src/bundles/curve/package.json | 1 + src/bundles/robot_simulation/package.json | 1 + src/bundles/rune/package.json | 5 ++--- src/tabs/Rune/package.json | 2 +- yarn.lock | 25 +++++------------------ 7 files changed, 11 insertions(+), 27 deletions(-) diff --git a/.github/actions/package.json b/.github/actions/package.json index 58ebbb4265..8530bf124b 100644 --- a/.github/actions/package.json +++ b/.github/actions/package.json @@ -5,7 +5,6 @@ "type": "module", "devDependencies": { "@sourceacademy/modules-repotools": "workspace:^", - "@types/lodash": "^4.14.198", "@types/node": "^22.15.30", "typescript": "^5.8.2", "vitest": "^4.0.18" diff --git a/lib/modules-lib/package.json b/lib/modules-lib/package.json index 0227e90625..e328b8ea5c 100644 --- a/lib/modules-lib/package.json +++ b/lib/modules-lib/package.json @@ -5,7 +5,6 @@ "type": "module", "devDependencies": { "@sourceacademy/modules-buildtools": "workspace:^", - "@types/lodash": "^4.14.198", "@types/react": "^18.3.1", "@types/react-dom": "^18.3.1", "@vitejs/plugin-react": "^5.1.0", @@ -34,8 +33,8 @@ "dependencies": { "@blueprintjs/core": "^6.0.0", "@blueprintjs/icons": "^6.0.0", + "es-toolkit": "^1.44.0", "js-slang": "^1.0.85", - "lodash": "^4.17.23", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/src/bundles/curve/package.json b/src/bundles/curve/package.json index 805f8c10d6..5a047f83c8 100644 --- a/src/bundles/curve/package.json +++ b/src/bundles/curve/package.json @@ -4,6 +4,7 @@ "private": true, "dependencies": { "@sourceacademy/modules-lib": "workspace:^", + "es-toolkit": "^1.44.0", "gl-matrix": "^3.3.0", "js-slang": "^1.0.85" }, diff --git a/src/bundles/robot_simulation/package.json b/src/bundles/robot_simulation/package.json index c8d974932b..22b0d99d57 100644 --- a/src/bundles/robot_simulation/package.json +++ b/src/bundles/robot_simulation/package.json @@ -4,6 +4,7 @@ "private": true, "dependencies": { "@sourceacademy/modules-lib": "workspace:^", + "es-toolkit": "^1.44.0", "js-slang": "^1.0.85", "three": "^0.181.0" }, diff --git a/src/bundles/rune/package.json b/src/bundles/rune/package.json index 212ea20643..badc8ccb84 100644 --- a/src/bundles/rune/package.json +++ b/src/bundles/rune/package.json @@ -4,12 +4,11 @@ "private": true, "dependencies": { "@sourceacademy/modules-lib": "workspace:^", - "gl-matrix": "^3.3.0", - "lodash": "^4.17.23" + "es-toolkit": "^1.44.0", + "gl-matrix": "^3.3.0" }, "devDependencies": { "@sourceacademy/modules-buildtools": "workspace:^", - "@types/lodash": "^4.14.198", "js-slang": "^1.0.85", "typescript": "^5.8.2" }, diff --git a/src/tabs/Rune/package.json b/src/tabs/Rune/package.json index cc8b731107..ad254efc28 100644 --- a/src/tabs/Rune/package.json +++ b/src/tabs/Rune/package.json @@ -5,7 +5,7 @@ "dependencies": { "@sourceacademy/bundle-rune": "workspace:^", "@sourceacademy/modules-lib": "workspace:^", - "lodash": "^4.17.23", + "es-toolkit": "^1.44.0", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/yarn.lock b/yarn.lock index 5cf5618785..f9df2a486b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4345,6 +4345,7 @@ __metadata: dependencies: "@sourceacademy/modules-buildtools": "workspace:^" "@sourceacademy/modules-lib": "workspace:^" + es-toolkit: "npm:^1.44.0" gl-matrix: "npm:^3.3.0" js-slang: "npm:^1.0.85" typescript: "npm:^5.8.2" @@ -4485,6 +4486,7 @@ __metadata: "@sourceacademy/modules-buildtools": "workspace:^" "@sourceacademy/modules-lib": "workspace:^" "@types/three": "npm:^0.181.0" + es-toolkit: "npm:^1.44.0" js-slang: "npm:^1.0.85" three: "npm:^0.181.0" typescript: "npm:^5.8.2" @@ -4497,10 +4499,9 @@ __metadata: dependencies: "@sourceacademy/modules-buildtools": "workspace:^" "@sourceacademy/modules-lib": "workspace:^" - "@types/lodash": "npm:^4.14.198" + es-toolkit: "npm:^1.44.0" gl-matrix: "npm:^3.3.0" js-slang: "npm:^1.0.85" - lodash: "npm:^4.17.23" typescript: "npm:^5.8.2" languageName: unknown linkType: soft @@ -4733,7 +4734,6 @@ __metadata: "@actions/core": "npm:^1.11.1" "@actions/exec": "npm:^3.0.0" "@sourceacademy/modules-repotools": "workspace:^" - "@types/lodash": "npm:^4.14.198" "@types/node": "npm:^22.15.30" es-toolkit: "npm:^1.44.0" snyk-nodejs-lockfile-parser: "npm:^2.4.2" @@ -4749,14 +4749,13 @@ __metadata: "@blueprintjs/core": "npm:^6.0.0" "@blueprintjs/icons": "npm:^6.0.0" "@sourceacademy/modules-buildtools": "workspace:^" - "@types/lodash": "npm:^4.14.198" "@types/react": "npm:^18.3.1" "@types/react-dom": "npm:^18.3.1" "@vitejs/plugin-react": "npm:^5.1.0" "@vitest/browser-playwright": "npm:^4.0.18" + es-toolkit: "npm:^1.44.0" eslint: "npm:^9.35.0" js-slang: "npm:^1.0.85" - lodash: "npm:^4.17.23" playwright: "npm:^1.55.1" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" @@ -5075,7 +5074,7 @@ __metadata: "@sourceacademy/modules-lib": "workspace:^" "@types/react": "npm:^18.3.1" "@vitest/browser-playwright": "npm:^4.0.18" - lodash: "npm:^4.17.23" + es-toolkit: "npm:^1.44.0" playwright: "npm:^1.55.1" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" @@ -5739,13 +5738,6 @@ __metadata: languageName: node linkType: hard -"@types/lodash@npm:^4.14.198": - version: 4.17.23 - resolution: "@types/lodash@npm:4.17.23" - checksum: 10c0/9d9cbfb684e064a2b78aab9e220d398c9c2a7d36bc51a07b184ff382fa043a99b3d00c16c7f109b4eb8614118f4869678dbae7d5c6700ed16fb9340e26cc0bf6 - languageName: node - linkType: hard - "@types/markdown-it@npm:^14.1.2": version: 14.1.2 resolution: "@types/markdown-it@npm:14.1.2" @@ -13032,13 +13024,6 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.23": - version: 4.17.23 - resolution: "lodash@npm:4.17.23" - checksum: 10c0/1264a90469f5bb95d4739c43eb6277d15b6d9e186df4ac68c3620443160fc669e2f14c11e7d8b2ccf078b81d06147c01a8ccced9aab9f9f63d50dcf8cace6bf6 - languageName: node - linkType: hard - "longest-streak@npm:^3.0.0": version: 3.1.0 resolution: "longest-streak@npm:3.1.0" From 00bbd27d93f4c478e510195ea142327fa7ecae20 Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Thu, 19 Feb 2026 21:39:57 +0800 Subject: [PATCH 7/7] Fix omit change to es-toolkit + Add react to base module --- lib/buildtools/src/commands/list.ts | 2 +- lib/buildtools/src/templates/tab.ts | 2 +- package.json | 2 ++ src/tabs/Unittest/package.json | 1 + yarn.lock | 3 +++ 5 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/buildtools/src/commands/list.ts b/lib/buildtools/src/commands/list.ts index 0e288b8954..e21a1eab5d 100644 --- a/lib/buildtools/src/commands/list.ts +++ b/lib/buildtools/src/commands/list.ts @@ -73,7 +73,7 @@ export const getValidateCommand = () => new Command('validate') } else if (manifestResult.severity === 'error') { logCommandErrorAndExit(manifestResult); } else { - const bundle = omit(manifestResult.bundle, 'type'); + const bundle = omit(manifestResult.bundle, ['type']); const manifestStr = JSON.stringify(bundle, null, 2); console.log(`${chalk.magentaBright(`Bundle '${manifestResult.bundle.name}' found in ${directory}`)}:\n${manifestStr}`); } diff --git a/lib/buildtools/src/templates/tab.ts b/lib/buildtools/src/templates/tab.ts index 97cf39d316..a251715dcc 100644 --- a/lib/buildtools/src/templates/tab.ts +++ b/lib/buildtools/src/templates/tab.ts @@ -79,7 +79,7 @@ export async function addNew(bundlesDir: string, tabsDir: string, rl: Interface) }; // Version property gets stored in package.json, not manifest.json - const requiredProperties = omit(manifest[moduleName], 'version'); + const requiredProperties = omit(manifest[moduleName], ['version']); const newManifest: BundleManifest = { ...requiredProperties, diff --git a/package.json b/package.json index 0d468104f4..9e4a4d23ee 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,8 @@ "husky": "^9.1.7", "jsdom": "^26.1.0", "jsonc-eslint-parser": "^2.4.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", "typescript": "^5.8.2", "typescript-eslint": "^8.53.1", "vitest": "^4.0.18", diff --git a/src/tabs/Unittest/package.json b/src/tabs/Unittest/package.json index 3654f6abe4..0109117c7c 100644 --- a/src/tabs/Unittest/package.json +++ b/src/tabs/Unittest/package.json @@ -5,6 +5,7 @@ "dependencies": { "@sourceacademy/bundle-unittest": "workspace:^", "@sourceacademy/modules-lib": "workspace:^", + "es-toolkit": "^1.44.0", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/yarn.lock b/yarn.lock index f9df2a486b..d8fae7387d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4820,6 +4820,8 @@ __metadata: husky: "npm:^9.1.7" jsdom: "npm:^26.1.0" jsonc-eslint-parser: "npm:^2.4.0" + react: "npm:^18.3.1" + react-dom: "npm:^18.3.1" typescript: "npm:^5.8.2" typescript-eslint: "npm:^8.53.1" vitest: "npm:^4.0.18" @@ -5133,6 +5135,7 @@ __metadata: "@sourceacademy/modules-buildtools": "workspace:^" "@sourceacademy/modules-lib": "workspace:^" "@types/react": "npm:^18.3.1" + es-toolkit: "npm:^1.44.0" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" languageName: unknown