diff --git a/.darklua-dev.json b/.darklua-dev.json new file mode 100644 index 00000000..f3e217a3 --- /dev/null +++ b/.darklua-dev.json @@ -0,0 +1,29 @@ +{ + "process": [ + { + "rule": "inject_global_value", + "identifier": "__DEV__", + "value": true + }, + { + "rule": "convert_require", + "current": { + "name": "path", + "sources": { + "@pkg": "node_modules/.luau-aliases" + } + }, + "target": { + "name": "roblox", + "rojo_sourcemap": "./sourcemap.json", + "indexing_style": "wait_for_child" + } + }, + "compute_expression", + "remove_unused_if_branch", + "remove_unused_while", + "filter_after_early_return", + "remove_nil_declaration", + "remove_empty_do" + ] +} diff --git a/.darklua-wally.json b/.darklua-wally.json new file mode 100644 index 00000000..b6101b9e --- /dev/null +++ b/.darklua-wally.json @@ -0,0 +1,24 @@ +{ + "process": [ + { + "rule": "convert_require", + "current": { + "name": "path", + "sources": { + "@pkg": "." + } + }, + "target": { + "name": "roblox", + "indexing_style": "wait_for_child", + "rojo_sourcemap": "./sourcemap.json" + } + }, + "compute_expression", + "remove_unused_if_branch", + "remove_unused_while", + "filter_after_early_return", + "remove_nil_declaration", + "remove_empty_do" + ] +} diff --git a/.darklua.json b/.darklua.json new file mode 100644 index 00000000..6d599d65 --- /dev/null +++ b/.darklua.json @@ -0,0 +1,29 @@ +{ + "process": [ + { + "rule": "inject_global_value", + "identifier": "__DEV__", + "value": false + }, + { + "rule": "convert_require", + "current": { + "name": "path", + "sources": { + "@pkg": "node_modules/.luau-aliases" + } + }, + "target": { + "name": "roblox", + "rojo_sourcemap": "./sourcemap.json", + "indexing_style": "wait_for_child" + } + }, + "compute_expression", + "remove_unused_if_branch", + "remove_unused_while", + "filter_after_early_return", + "remove_nil_declaration", + "remove_empty_do" + ] +} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..b109ce77 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,212 @@ +name: Release + +on: + workflow_dispatch: + inputs: + release_tag: + description: "The version to release starting with `v`" + required: true + type: string + + release_ref: + description: "The branch, tag or SHA to checkout (default to latest)" + default: "" + type: string + +permissions: + contents: write + +jobs: + publish-package: + name: Publish package + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v3 + with: + node-version: "latest" + cache: "yarn" + cache-dependency-path: "yarn.lock" + + - name: Update yarn + run: yarn set version stable + + - name: Install packages + run: yarn install --immutable + + - name: Run npmluau + run: yarn run prepare + + - name: Authenticate yarn + run: | + yarn config set npmAlwaysAuth true + yarn config set npmScopes.jsdotlua.npmAuthToken $NPM_AUTH_TOKEN + env: + NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - run: yarn workspaces foreach --all --no-private npm publish --access public + + publish-wally-package: + needs: publish-package + + name: Publish wally package + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: Roblox/setup-foreman@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/setup-node@v3 + with: + node-version: "latest" + cache: "yarn" + cache-dependency-path: "yarn.lock" + + - name: Update yarn + run: yarn set version stable + + - name: Install packages + run: yarn install --immutable + + - name: Run npmluau + run: yarn run prepare + + - name: Build assets + run: yarn run build-assets + + - name: Login to wally + run: wally login --project-path build/wally/shared --token ${{ secrets.WALLY_ACCESS_TOKEN }} + + - name: Publish shared to wally + run: wally publish --project-path build/wally/shared + + - name: Publish scheduler to wally + run: wally publish --project-path build/wally/scheduler + + - name: Publish react-is to wally + run: wally publish --project-path build/wally/react-is + + - name: Publish react to wally + run: wally publish --project-path build/wally/react + + - name: Publish react-cache to wally + run: wally publish --project-path build/wally/react-cache + + - name: Publish react-reconciler to wally + run: wally publish --project-path build/wally/react-reconciler + + - name: Publish react-roblox to wally + run: wally publish --project-path build/wally/react-roblox + + - name: Publish react-test-renderer to wally + run: wally publish --project-path build/wally/react-test-renderer + + - name: Publish react-shallow-renderer to wally + run: wally publish --project-path build/wally/react-shallow-renderer + + - name: Publish roact-compat to wally + run: wally publish --project-path build/wally/roact-compat + + - name: Publish react-devtools-shared to wally + run: wally publish --project-path build/wally/react-devtools-shared + + - name: Publish react-debug-tools to wally + run: wally publish --project-path build/wally/react-debug-tools + + - name: Publish react-devtools-extensions to wally + run: wally publish --project-path build/wally/react-devtools-extensions + + + create-release: + needs: publish-package + + name: Create release + runs-on: ubuntu-latest + + outputs: + upload_url: ${{ steps.create_release.outputs.upload_url }} + + steps: + - uses: actions/checkout@v4 + + - name: Create tag + run: | + git fetch --tags --no-recurse-submodules + if [ ! $(git tag -l ${{ inputs.release_tag }}) ]; then + git tag ${{ inputs.release_tag }} + git push origin ${{ inputs.release_tag }} + fi + + - name: Create release + id: create_release + uses: softprops/action-gh-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ inputs.release_tag }} + name: ${{ inputs.release_tag }} + draft: false + + build-assets: + needs: create-release + + name: Add assets + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + include: + - artifact-name: react-lua.rbxm + path: build/react-lua.rbxm + asset-type: application/octet-stream + + - artifact-name: react-lua-dev.rbxm + path: build/debug/react-lua.rbxm + asset-type: application/octet-stream + + steps: + - uses: actions/checkout@v4 + + - uses: Roblox/setup-foreman@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/setup-node@v3 + with: + node-version: "latest" + cache: "yarn" + cache-dependency-path: "yarn.lock" + + - name: Update yarn + run: yarn set version stable + + - name: Install packages + run: yarn install --immutable + + - name: Run npmluau + run: yarn run prepare + + - name: Build assets + run: yarn run build-assets + + - name: Upload asset + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.artifact-name }} + path: ${{ matrix.path }} + + - name: Add asset to Release + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create-release.outputs.upload_url }} + asset_path: ${{ matrix.path }} + asset_name: ${{ matrix.artifact-name }} + asset_content_type: ${{ matrix.asset-type }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..63a02c95 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,45 @@ +name: Tests + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + test: + name: Run tests + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: Roblox/setup-foreman@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/setup-node@v3 + with: + node-version: "latest" + cache: "yarn" + cache-dependency-path: "yarn.lock" + + - name: Update yarn + run: yarn set version stable + + - name: Install packages + run: yarn install --immutable + + - name: Run npmluau + run: yarn run prepare + + - name: Run linter + run: yarn run lint + + - name: Verify code style + run: yarn run style-check + + - name: Build assets + run: yarn run build-assets diff --git a/.gitignore b/.gitignore index 1e923871..2d96e898 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,11 @@ site/ default_modules modules_* + +.yarn +/*.tgz + +**/sourcemap.json +**/node_modules +/build +/roblox diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..3d28e3e0 --- /dev/null +++ b/.npmignore @@ -0,0 +1,33 @@ +/.* +/bin +/Packages +**/.robloxrc +rotriever.toml + +/.github/ +/.vscode/ + +/roblox +/build + +/*.json +/*.toml +/*.yml +/*.md +/*.tgz + +/globalTypes.d.lua +**/sourcemap.json +**/*.project.json + +**/__tests__ +**/*.test.lua +**/*.spec.lua +**/jest.config.lua + +**/*.rbxl +**/*.rbxlx +**/*.rbxl.lock +**/*.rbxlx.lock +**/*.rbxm +**/*.rbxmx diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 00000000..3186f3f0 --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1 @@ +nodeLinker: node-modules diff --git a/default.project.json b/default.project.json new file mode 100644 index 00000000..7ec90a40 --- /dev/null +++ b/default.project.json @@ -0,0 +1,9 @@ +{ + "name": "ReactLua", + "tree": { + "$path": "roblox-model", + "node_modules": { + "$path": "node_modules" + } + } +} \ No newline at end of file diff --git a/foreman.toml b/foreman.toml index fcb5d36a..9ce7b7bd 100644 --- a/foreman.toml +++ b/foreman.toml @@ -1,4 +1,8 @@ [tools] rojo = { source = "rojo-rbx/rojo", version = "7.3.0" } selene = { source = "Kampfkarren/selene", version = "0.26.1" } -stylua = { source = "JohnnyMorganz/StyLua", version = "0.19.1" } +stylua = { source = "JohnnyMorganz/StyLua", version = "=0.15.1" } +wally = { github = "UpliftGames/wally", version = "=0.3.2" } +luau-lsp = { github = "johnnymorganz/luau-lsp", version = "=1.23.0"} +darklua = { github = "seaofvoices/darklua", version = "=0.12.1" } +lune = { github = "filiptibell/lune", version = "0.7.11" } diff --git a/package.json b/package.json new file mode 100644 index 00000000..82f8344e --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "workspace", + "private": true, + "workspaces": [ + "modules/*" + ], + "scripts": { + "prepare": "npmluau", + "build-assets": "sh ./scripts/build-assets.sh", + "lint": "selene modules", + "format": "stylua modules", + "style-check": "stylua modules --check", + "clean": "rm -rf roblox build node_modules" + }, + "devDependencies": { + "commander": "^11.1.0", + "npmluau": "^0.1.1" + } +} diff --git a/roblox-model/React.lua b/roblox-model/React.lua new file mode 100644 index 00000000..80e3c436 --- /dev/null +++ b/roblox-model/React.lua @@ -0,0 +1 @@ +return require("@pkg/@jsdotlua/react") diff --git a/roblox-model/ReactCache.lua b/roblox-model/ReactCache.lua new file mode 100644 index 00000000..961739a4 --- /dev/null +++ b/roblox-model/ReactCache.lua @@ -0,0 +1 @@ +return require("@pkg/@jsdotlua/react-cache") diff --git a/roblox-model/ReactDebugTools.lua b/roblox-model/ReactDebugTools.lua new file mode 100644 index 00000000..3d9297e6 --- /dev/null +++ b/roblox-model/ReactDebugTools.lua @@ -0,0 +1 @@ +return require("@pkg/@jsdotlua/react-debug-tools") diff --git a/roblox-model/ReactDevtoolsExtensions.lua b/roblox-model/ReactDevtoolsExtensions.lua new file mode 100644 index 00000000..a2b99442 --- /dev/null +++ b/roblox-model/ReactDevtoolsExtensions.lua @@ -0,0 +1 @@ +return require("@pkg/@jsdotlua/react-devtools-extensions") diff --git a/roblox-model/ReactDevtoolsShared.lua b/roblox-model/ReactDevtoolsShared.lua new file mode 100644 index 00000000..c4c274d7 --- /dev/null +++ b/roblox-model/ReactDevtoolsShared.lua @@ -0,0 +1 @@ +return require("@pkg/@jsdotlua/react-devtools-shared") diff --git a/roblox-model/ReactIs.lua b/roblox-model/ReactIs.lua new file mode 100644 index 00000000..686fc2f1 --- /dev/null +++ b/roblox-model/ReactIs.lua @@ -0,0 +1 @@ +return require("@pkg/@jsdotlua/react-is") diff --git a/roblox-model/ReactReconciler.lua b/roblox-model/ReactReconciler.lua new file mode 100644 index 00000000..58629da5 --- /dev/null +++ b/roblox-model/ReactReconciler.lua @@ -0,0 +1 @@ +return require("@pkg/@jsdotlua/react-reconciler") diff --git a/roblox-model/ReactRoblox.lua b/roblox-model/ReactRoblox.lua new file mode 100644 index 00000000..2621a262 --- /dev/null +++ b/roblox-model/ReactRoblox.lua @@ -0,0 +1 @@ +return require("@pkg/@jsdotlua/react-roblox") diff --git a/roblox-model/ReactShallowRenderer.lua b/roblox-model/ReactShallowRenderer.lua new file mode 100644 index 00000000..d94f2540 --- /dev/null +++ b/roblox-model/ReactShallowRenderer.lua @@ -0,0 +1 @@ +return require("@pkg/@jsdotlua/react-shallow-renderer") diff --git a/roblox-model/ReactTestRenderer.lua b/roblox-model/ReactTestRenderer.lua new file mode 100644 index 00000000..aa72a10a --- /dev/null +++ b/roblox-model/ReactTestRenderer.lua @@ -0,0 +1 @@ +return require("@pkg/@jsdotlua/react-test-renderer") diff --git a/roblox-model/RoactCompat.lua b/roblox-model/RoactCompat.lua new file mode 100644 index 00000000..b7c33d65 --- /dev/null +++ b/roblox-model/RoactCompat.lua @@ -0,0 +1 @@ +return require("@pkg/@jsdotlua/roact-compat") diff --git a/roblox-model/Scheduler.lua b/roblox-model/Scheduler.lua new file mode 100644 index 00000000..7d0f9d74 --- /dev/null +++ b/roblox-model/Scheduler.lua @@ -0,0 +1 @@ +return require("@pkg/@jsdotlua/scheduler") diff --git a/roblox-model/Shared.lua b/roblox-model/Shared.lua new file mode 100644 index 00000000..0fd60e91 --- /dev/null +++ b/roblox-model/Shared.lua @@ -0,0 +1 @@ +return require("@pkg/@jsdotlua/shared") diff --git a/scripts/build-assets.sh b/scripts/build-assets.sh new file mode 100755 index 00000000..1df8d023 --- /dev/null +++ b/scripts/build-assets.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +set -e + +./scripts/build-roblox-model.sh +./scripts/build-wally-package.sh diff --git a/scripts/build-roblox-model.sh b/scripts/build-roblox-model.sh new file mode 100755 index 00000000..8645f0b2 --- /dev/null +++ b/scripts/build-roblox-model.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +set -e + +build_with_darklua_config () { + DARKLUA_CONFIG=$1 + OUTPUT=build/$2 + + rm -rf roblox + rm -f $OUTPUT + + mkdir -p roblox + + cp -rL node_modules/ roblox/ + cp -r roblox-model/ roblox/ + + for module_path in roblox/roblox-model/*; do + module_name=$(basename $module_path) + + react_module=$(cat $module_path | sed 's/return require(\"\@pkg\/\@jsdotlua\/\(.*\)\")/\1/') + alias_path=roblox/node_modules/.luau-aliases/@jsdotlua/$react_module.luau + + echo "local module = require('@pkg/@jsdotlua/${react_module}')" > $module_path + + tail -n +2 $alias_path >> $module_path + done + + ./scripts/remove-tests.sh roblox + + cp default.project.json roblox + + rojo sourcemap roblox/default.project.json -o roblox/sourcemap.json + + cp $DARKLUA_CONFIG roblox + + darklua process --config roblox/$DARKLUA_CONFIG roblox/node_modules roblox/node_modules + darklua process --config roblox/$DARKLUA_CONFIG roblox/roblox-model roblox/roblox-model + + mkdir -p $(dirname $OUTPUT) + + rojo build roblox/default.project.json -o $OUTPUT +} + +build_with_darklua_config .darklua.json react-lua.rbxm +build_with_darklua_config .darklua-dev.json debug/react-lua.rbxm diff --git a/scripts/build-wally-package.sh b/scripts/build-wally-package.sh new file mode 100755 index 00000000..dd4936d8 --- /dev/null +++ b/scripts/build-wally-package.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +set -e + +rm -rf roblox/node_modules + +mkdir -p roblox + +cp -rL node_modules/ roblox/ + +./scripts/remove-tests.sh roblox/node_modules + +rm -rf build/wally + +for module_path in modules/*; do + module_name=$(basename $module_path) + + original_package=node_modules/@jsdotlua/$module_name + + if [ -f $original_package/package.json ]; then + echo Process package $module_name + + wally_package=build/wally/$module_name + roblox_package=roblox/node_modules/@jsdotlua/$module_name + + mkdir -p $wally_package + mkdir -p $wally_package/src + cp LICENSE $wally_package/LICENSE + cp $original_package/default.project.json $wally_package + node ./scripts/npm-to-wally.js $roblox_package/package.json $wally_package/wally.toml $roblox_package/wally-package.project.json --workspace-path modules + + cp .darklua-wally.json $roblox_package + cp -r roblox/node_modules/.luau-aliases/* $roblox_package + + rojo sourcemap $roblox_package/wally-package.project.json --output $roblox_package/sourcemap.json + + darklua process --config $roblox_package/.darklua-wally.json $roblox_package/src $wally_package/src + + wally package --project-path $wally_package --list + + echo "" + fi +done + diff --git a/scripts/npm-to-wally.js b/scripts/npm-to-wally.js new file mode 100644 index 00000000..232e7429 --- /dev/null +++ b/scripts/npm-to-wally.js @@ -0,0 +1,144 @@ +#!/usr/bin/env node + +const { Command } = require("commander"); + +const fs = require("fs").promises; +const path = require("path"); +const process = require("process"); + +const readPackageConfig = async (packagePath) => { + const packageContent = await fs.readFile(packagePath).catch((err) => { + console.error(`unable to read package.json at '${packagePath}': ${err}`); + return null; + }); + + if (packageContent !== null) { + try { + const packageData = JSON.parse(packageContent); + return packageData; + } catch (error) { + console.error(`unable to parse package.json at '${packagePath}': ${err}`); + } + } + + return null; +}; + +const main = async ( + packageJsonPath, + wallyOutputPath, + rojoConfigPath, + { workspacePath } +) => { + const packageData = await readPackageConfig(packageJsonPath); + + const { name: scopedName, version, license, dependencies = [] } = packageData; + + const tomlLines = [ + "[package]", + `name = "${scopedName.substring(1)}"`, + `version = "${version}"`, + 'registry = "https://github.com/UpliftGames/wally-index"', + 'realm = "shared"', + `license = "${license}"`, + "", + "[dependencies]", + ]; + + const rojoConfig = { + name: "WallyPackage", + tree: { + $className: "Folder", + Package: { + $path: "src", + }, + }, + }; + + for (const [dependencyName, specifiedVersion] of Object.entries( + dependencies + )) { + const name = dependencyName.startsWith("@") + ? dependencyName.substring(dependencyName.indexOf("/") + 1) + : dependencyName; + + rojoConfig.tree[name] = { + $path: dependencyName + ".luau", + }; + + const wallyPackageName = name.indexOf("-") !== -1 ? `"${name}"` : name; + + if (specifiedVersion == "workspace:^") { + const dependentPackage = + workspacePath && + (await readPackageConfig( + path.join(workspacePath, name, "package.json") + )); + + if (dependentPackage) { + tomlLines.push( + `${wallyPackageName} = "jsdotlua/${name}@${dependentPackage.version}"` + ); + } else { + console.error(`unable to find version for package '${name}'`); + } + } else { + tomlLines.push( + `${wallyPackageName} = "jsdotlua/${name}@${specifiedVersion}"` + ); + } + } + + tomlLines.push(""); + + await Promise.all([ + fs.writeFile(wallyOutputPath, tomlLines.join("\n")).catch((err) => { + console.error( + `unable to write wally config at '${wallyOutputPath}': ${err}` + ); + }), + fs + .writeFile(rojoConfigPath, JSON.stringify(rojoConfig, null, 2)) + .catch((err) => { + console.error( + `unable to write rojo config at '${rojoConfigPath}': ${err}` + ); + }), + ]); +}; + +const createCLI = () => { + const program = new Command(); + + program + .name("npm-to-wally") + .description("a utility to convert npm packages to wally packages") + .argument("") + .argument("") + .argument("") + .option( + "--workspace-path ", + "the path containing all workspace members" + ) + .action( + async (packageJson, wallyToml, rojoConfig, { workspacePath = null }) => { + const cwd = process.cwd(); + main( + path.join(cwd, packageJson), + path.join(cwd, wallyToml), + path.join(cwd, rojoConfig), + { + workspacePath: workspacePath && path.join(cwd, workspacePath), + } + ); + } + ); + + return (args) => { + program.parse(args); + }; +}; + +const run = createCLI(); + +run(process.argv); diff --git a/scripts/remove-tests.sh b/scripts/remove-tests.sh new file mode 100755 index 00000000..7d3af7e1 --- /dev/null +++ b/scripts/remove-tests.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +set -e + +FOLDER=$1 + +find $FOLDER -name '__tests__' -type d -exec rm -r {} + +find $FOLDER -name '.robloxrc' -type f -exec rm -r {} + +find $FOLDER -name '*.spec.lua' -type f -exec rm -r {} + +find $FOLDER -name 'jest.config.lua' -type f -exec rm -r {} + diff --git a/selene.toml b/selene.toml index cd8f80ee..e06be2ee 100644 --- a/selene.toml +++ b/selene.toml @@ -1,4 +1,4 @@ -std = "roblox" +std = "selene_definitions" [config] empty_if = { comments_count = true } @@ -8,6 +8,7 @@ shadowing = { ignore_pattern = "result|ok|^_" } global_usage = { ignore_pattern = "^__" } [rules] +global_usage = "allow" unused_variable = "allow" # remove when the Luau type narrowing issues (and the workarounds) are resolved shadowing = "allow" diff --git a/selene_definitions.yml b/selene_definitions.yml new file mode 100644 index 00000000..95cabdf1 --- /dev/null +++ b/selene_definitions.yml @@ -0,0 +1,7 @@ +base: roblox +name: selene_defs +globals: + # override Roblox require style with string requires + require: + args: + - type: string diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..459549d5 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,300 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10c0 + +"@jsdotlua/boolean@npm:^1.2.6": + version: 1.2.6 + resolution: "@jsdotlua/boolean@npm:1.2.6" + dependencies: + "@jsdotlua/number": "npm:^1.2.6" + checksum: 5f567e556bb7c56102327a97468571522ce939be6cdc1b51591afc3dfc1dff4b2c9ec5462e7809bd9a515b3bdfc1c3eaabb4f631892cb5f471b4fc8da188cb84 + languageName: node + linkType: hard + +"@jsdotlua/collections@npm:^1.2.6": + version: 1.2.6 + resolution: "@jsdotlua/collections@npm:1.2.6" + dependencies: + "@jsdotlua/es7-types": "npm:^1.2.6" + "@jsdotlua/instance-of": "npm:^1.2.6" + checksum: a4b3fe826358484528f10e8ca61a80d841a6515a22277a003117449da66ea1fb891c7b4103b952b01bd7d75666f26cb41c8efb852672aa8aaaaebbcd656dca79 + languageName: node + linkType: hard + +"@jsdotlua/console@npm:^1.2.6": + version: 1.2.6 + resolution: "@jsdotlua/console@npm:1.2.6" + dependencies: + "@jsdotlua/collections": "npm:^1.2.6" + checksum: eff658d9e8d23f932893facf18400a29ada54d1a24748b751aac1e4df48e92ff70b3b2ccd1ab6a4f2490dd709f826fe39427fb80f01a7574265fdd4e8af9187a + languageName: node + linkType: hard + +"@jsdotlua/es7-types@npm:^1.2.6": + version: 1.2.6 + resolution: "@jsdotlua/es7-types@npm:1.2.6" + checksum: e5710f5f6de0608aec22744845e3a24acc47e2bda6cfc0b1fe4040935039b73e8467da90c3a6c9d75b08c9f39d2b98e9d72d54f3f630012538a7d53ad828a0d6 + languageName: node + linkType: hard + +"@jsdotlua/instance-of@npm:^1.2.6": + version: 1.2.6 + resolution: "@jsdotlua/instance-of@npm:1.2.6" + checksum: 0958caf214bb0556c1dcf94096410c367f413af4b02ef3adbd733e47435d8734b583217804bed5aec8308d56ccfb39032bb12fd4337e01ec5ae2db690b2ca9ce + languageName: node + linkType: hard + +"@jsdotlua/luau-polyfill@npm:^1.2.6": + version: 1.2.6 + resolution: "@jsdotlua/luau-polyfill@npm:1.2.6" + dependencies: + "@jsdotlua/boolean": "npm:^1.2.6" + "@jsdotlua/collections": "npm:^1.2.6" + "@jsdotlua/console": "npm:^1.2.6" + "@jsdotlua/es7-types": "npm:^1.2.6" + "@jsdotlua/instance-of": "npm:^1.2.6" + "@jsdotlua/math": "npm:^1.2.6" + "@jsdotlua/number": "npm:^1.2.6" + "@jsdotlua/string": "npm:^1.2.6" + "@jsdotlua/timers": "npm:^1.2.6" + symbol-luau: "npm:^1.0.0" + checksum: 63265f9fde3b895400d12802929ddab5daed79efc4e2aa90325b2eea0e2b7addcf351d35ad8bb19955956e913c212408944d73b6f3126223893d17cecd24de61 + languageName: node + linkType: hard + +"@jsdotlua/math@npm:^1.2.6": + version: 1.2.6 + resolution: "@jsdotlua/math@npm:1.2.6" + checksum: 06137df2a6352d4f5c730a7cf9e2902509d36de08415a3c70d470a05669dfeaf48e4aff2d5b6885a92b8f4d19fd0294a40f147a3f39c8558e887a09eb3ccd9e0 + languageName: node + linkType: hard + +"@jsdotlua/number@npm:^1.2.6": + version: 1.2.6 + resolution: "@jsdotlua/number@npm:1.2.6" + checksum: 74541fce86f80c52f05e5d4ca774d94f08ed21619af7b575c2bb7284e24fc2b178626c9888e286459a344d662cafab74d839ec8b95dcdab551fd14754911a292 + languageName: node + linkType: hard + +"@jsdotlua/promise@npm:^3.5.0": + version: 3.5.0 + resolution: "@jsdotlua/promise@npm:3.5.0" + checksum: 8771dac525b8d608ad319040b742cdde8f4cbbd4a075ae02dad4d510c8ab739dabf7de40ae1b15211e3890331cf3e7d9454fdcb3ec9a08471663436c0e9ec977 + languageName: node + linkType: hard + +"@jsdotlua/react-cache@workspace:modules/react-cache": + version: 0.0.0-use.local + resolution: "@jsdotlua/react-cache@workspace:modules/react-cache" + dependencies: + "@jsdotlua/luau-polyfill": "npm:^1.2.6" + "@jsdotlua/react": "workspace:^" + "@jsdotlua/scheduler": "workspace:^" + "@jsdotlua/shared": "workspace:^" + npmluau: "npm:^0.1.0" + languageName: unknown + linkType: soft + +"@jsdotlua/react-debug-tools@workspace:^, @jsdotlua/react-debug-tools@workspace:modules/react-debug-tools": + version: 0.0.0-use.local + resolution: "@jsdotlua/react-debug-tools@workspace:modules/react-debug-tools" + dependencies: + "@jsdotlua/luau-polyfill": "npm:^1.2.6" + "@jsdotlua/react-reconciler": "workspace:^" + "@jsdotlua/shared": "workspace:^" + npmluau: "npm:^0.1.0" + languageName: unknown + linkType: soft + +"@jsdotlua/react-devtools-extensions@workspace:modules/react-devtools-extensions": + version: 0.0.0-use.local + resolution: "@jsdotlua/react-devtools-extensions@workspace:modules/react-devtools-extensions" + dependencies: + "@jsdotlua/luau-polyfill": "npm:^1.2.6" + "@jsdotlua/react": "workspace:^" + "@jsdotlua/react-devtools-shared": "workspace:^" + "@jsdotlua/react-roblox": "workspace:^" + "@jsdotlua/shared": "workspace:^" + npmluau: "npm:^0.1.0" + languageName: unknown + linkType: soft + +"@jsdotlua/react-devtools-shared@workspace:^, @jsdotlua/react-devtools-shared@workspace:modules/react-devtools-shared": + version: 0.0.0-use.local + resolution: "@jsdotlua/react-devtools-shared@workspace:modules/react-devtools-shared" + dependencies: + "@jsdotlua/luau-polyfill": "npm:^1.2.6" + "@jsdotlua/react": "workspace:^" + "@jsdotlua/react-debug-tools": "workspace:^" + "@jsdotlua/react-is": "workspace:^" + "@jsdotlua/react-reconciler": "workspace:^" + "@jsdotlua/react-roblox": "workspace:^" + "@jsdotlua/shared": "workspace:^" + npmluau: "npm:^0.1.0" + languageName: unknown + linkType: soft + +"@jsdotlua/react-is@workspace:^, @jsdotlua/react-is@workspace:modules/react-is": + version: 0.0.0-use.local + resolution: "@jsdotlua/react-is@workspace:modules/react-is" + dependencies: + "@jsdotlua/shared": "workspace:^" + npmluau: "npm:^0.1.0" + languageName: unknown + linkType: soft + +"@jsdotlua/react-reconciler@workspace:^, @jsdotlua/react-reconciler@workspace:modules/react-reconciler": + version: 0.0.0-use.local + resolution: "@jsdotlua/react-reconciler@workspace:modules/react-reconciler" + dependencies: + "@jsdotlua/luau-polyfill": "npm:^1.2.6" + "@jsdotlua/promise": "npm:^3.5.0" + "@jsdotlua/react": "workspace:^" + "@jsdotlua/scheduler": "workspace:^" + "@jsdotlua/shared": "workspace:^" + npmluau: "npm:^0.1.0" + languageName: unknown + linkType: soft + +"@jsdotlua/react-roblox@workspace:^, @jsdotlua/react-roblox@workspace:modules/react-roblox": + version: 0.0.0-use.local + resolution: "@jsdotlua/react-roblox@workspace:modules/react-roblox" + dependencies: + "@jsdotlua/luau-polyfill": "npm:^1.2.6" + "@jsdotlua/react": "workspace:^" + "@jsdotlua/react-reconciler": "workspace:^" + "@jsdotlua/scheduler": "workspace:^" + "@jsdotlua/shared": "workspace:^" + npmluau: "npm:^0.1.0" + languageName: unknown + linkType: soft + +"@jsdotlua/react-shallow-renderer@workspace:modules/react-shallow-renderer": + version: 0.0.0-use.local + resolution: "@jsdotlua/react-shallow-renderer@workspace:modules/react-shallow-renderer" + dependencies: + "@jsdotlua/luau-polyfill": "npm:^1.2.6" + "@jsdotlua/react": "workspace:^" + "@jsdotlua/react-is": "workspace:^" + "@jsdotlua/shared": "workspace:^" + npmluau: "npm:^0.1.0" + languageName: unknown + linkType: soft + +"@jsdotlua/react-test-renderer@workspace:modules/react-test-renderer": + version: 0.0.0-use.local + resolution: "@jsdotlua/react-test-renderer@workspace:modules/react-test-renderer" + dependencies: + "@jsdotlua/luau-polyfill": "npm:^1.2.6" + "@jsdotlua/react": "workspace:^" + "@jsdotlua/react-reconciler": "workspace:^" + "@jsdotlua/scheduler": "workspace:^" + "@jsdotlua/shared": "workspace:^" + npmluau: "npm:^0.1.0" + languageName: unknown + linkType: soft + +"@jsdotlua/react@workspace:^, @jsdotlua/react@workspace:modules/react": + version: 0.0.0-use.local + resolution: "@jsdotlua/react@workspace:modules/react" + dependencies: + "@jsdotlua/luau-polyfill": "npm:^1.2.6" + "@jsdotlua/shared": "workspace:^" + npmluau: "npm:^0.1.0" + languageName: unknown + linkType: soft + +"@jsdotlua/roact-compat@workspace:modules/roact-compat": + version: 0.0.0-use.local + resolution: "@jsdotlua/roact-compat@workspace:modules/roact-compat" + dependencies: + "@jsdotlua/luau-polyfill": "npm:^1.2.6" + "@jsdotlua/react": "workspace:^" + "@jsdotlua/react-roblox": "workspace:^" + "@jsdotlua/shared": "workspace:^" + npmluau: "npm:^0.1.0" + languageName: unknown + linkType: soft + +"@jsdotlua/scheduler@workspace:^, @jsdotlua/scheduler@workspace:modules/scheduler": + version: 0.0.0-use.local + resolution: "@jsdotlua/scheduler@workspace:modules/scheduler" + dependencies: + "@jsdotlua/luau-polyfill": "npm:^1.2.6" + "@jsdotlua/shared": "workspace:^" + npmluau: "npm:^0.1.0" + languageName: unknown + linkType: soft + +"@jsdotlua/shared@workspace:^, @jsdotlua/shared@workspace:modules/shared": + version: 0.0.0-use.local + resolution: "@jsdotlua/shared@workspace:modules/shared" + dependencies: + "@jsdotlua/luau-polyfill": "npm:^1.2.6" + npmluau: "npm:^0.1.0" + languageName: unknown + linkType: soft + +"@jsdotlua/string@npm:^1.2.6": + version: 1.2.6 + resolution: "@jsdotlua/string@npm:1.2.6" + dependencies: + "@jsdotlua/es7-types": "npm:^1.2.6" + "@jsdotlua/number": "npm:^1.2.6" + checksum: de51c662439110642b699e4196240aa45ec4b8814f99bc606acb84dbb3f1c6889099bb722b3370f5873e06bd65c76779b5d94694309c9bdc63d324f40add2b0f + languageName: node + linkType: hard + +"@jsdotlua/timers@npm:^1.2.6": + version: 1.2.6 + resolution: "@jsdotlua/timers@npm:1.2.6" + dependencies: + "@jsdotlua/collections": "npm:^1.2.6" + checksum: f3ec2753894e4939f7dfdf0072517f1e769e4009b4bd882c9c6878526372753ac4b08b531e1a32c96b7bccb5bf10bb8e2f5730cbc70534da7eddc620fbccaaca + languageName: node + linkType: hard + +"commander@npm:^11.0.0, commander@npm:^11.1.0": + version: 11.1.0 + resolution: "commander@npm:11.1.0" + checksum: 13cc6ac875e48780250f723fb81c1c1178d35c5decb1abb1b628b3177af08a8554e76b2c0f29de72d69eef7c864d12613272a71fabef8047922bc622ab75a179 + languageName: node + linkType: hard + +"npmluau@npm:^0.1.0, npmluau@npm:^0.1.1": + version: 0.1.1 + resolution: "npmluau@npm:0.1.1" + dependencies: + commander: "npm:^11.0.0" + walkdir: "npm:^0.4.1" + bin: + npmluau: main.js + checksum: 9ae22c0dcff9e85c90b4da4e8c17bc51e9b567b4a417c9767d355ff68faca4f99a2934b581743ebc8729f6851d1ba5b64597312151747252e040517d1794fbca + languageName: node + linkType: hard + +"symbol-luau@npm:^1.0.0": + version: 1.0.1 + resolution: "symbol-luau@npm:1.0.1" + checksum: ab51a77331b2d5e4666528bada17e67b26aea355257bba9e97351016cd1836bd19f372355a14cf5bef2f4d5bc6b32fe91aeb09698d7bdc079d2c61330bedf251 + languageName: node + linkType: hard + +"walkdir@npm:^0.4.1": + version: 0.4.1 + resolution: "walkdir@npm:0.4.1" + checksum: 88e635aa9303e9196e4dc15013d2bd4afca4c8c8b4bb27722ca042bad213bb882d3b9141b3b0cca6bfb274f7889b30cf58d6374844094abec0016f335c5414dc + languageName: node + linkType: hard + +"workspace@workspace:.": + version: 0.0.0-use.local + resolution: "workspace@workspace:." + dependencies: + commander: "npm:^11.1.0" + npmluau: "npm:^0.1.1" + languageName: unknown + linkType: soft