Basic transformer functionality
This commit is contained in:
@@ -1,15 +1,21 @@
|
|||||||
ISC License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2020, Fireboltofdeath
|
Copyright (c) 2025 evilbocchi
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
copyright notice and this permission notice appear in all copies.
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
The above copyright notice and this permission notice shall be included in all
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
copies or substantial portions of the Software.
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -1,38 +1,99 @@
|
|||||||
# rbxts-transformer-services
|
# rbxts-transformer-instances
|
||||||
This is a [demo transformer](#template) that converts @rbxts/services imports into plain GetService calls for increased legibility.
|
|
||||||
|
|
||||||
## Example
|
Enable the use of instance constructors in roblox-ts, reducing boilerplate by letting you use familiar class-like syntax.
|
||||||
```ts
|
|
||||||
// input.ts
|
|
||||||
import { Players, ServerScriptService } from "@rbxts/services";
|
|
||||||
|
|
||||||
print(Players.LocalPlayer);
|
## Overview
|
||||||
print(ServerScriptService.GetChildren().size());
|
|
||||||
|
This transformer automatically converts constructor-style instance creation (`new Frame()`) into the standard Roblox `Instance.new("Frame")` pattern at compile time.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- ✨ Cleaner syntax for creating instances
|
||||||
|
- 🔍 Full TypeScript type safety
|
||||||
|
- ⚡ Zero runtime overhead (transforms at compile-time)
|
||||||
|
- 🔄 Supports all creatable Roblox instance types
|
||||||
|
- 📦 Easy to install and use
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install rbxts-transformer-instances
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Configure in your tsconfig.json
|
||||||
|
|
||||||
|
Add the transformer to your `tsconfig.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
...
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"transform": "rbxts-transformer-instances",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [..., "node_modules/rbxts-transformer-instances"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Basic Usage
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// Instead of this:
|
||||||
|
const part = new Instance("Part");
|
||||||
|
part.Material = Enum.Material.Neon;
|
||||||
|
part.Position = new Vector3(0, 10, 0);
|
||||||
|
|
||||||
|
// You can write this:
|
||||||
|
const part = new Part();
|
||||||
|
part.Material = Enum.Material.Neon;
|
||||||
|
part.Position = new Vector3(0, 10, 0);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Input (TypeScript):
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// Creating a basic UI
|
||||||
|
const screenGui = new ScreenGui();
|
||||||
|
screenGui.Parent = game.GetService("Players").LocalPlayer!.WaitForChild("PlayerGui");
|
||||||
|
|
||||||
|
const frame = new Frame();
|
||||||
|
frame.Size = new UDim2(0, 200, 0, 200);
|
||||||
|
frame.Position = new UDim2(0.5, -100, 0.5, -100);
|
||||||
|
frame.BackgroundColor3 = Color3.fromRGB(45, 45, 45);
|
||||||
|
frame.Parent = screenGui;
|
||||||
|
|
||||||
|
const textLabel = new TextLabel();
|
||||||
|
textLabel.Size = new UDim2(1, 0, 0, 50);
|
||||||
|
textLabel.Text = "Hello, World!";
|
||||||
|
textLabel.Parent = frame;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Output (Lua):
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
-- output.lua
|
-- Creates standard Instance.new calls
|
||||||
local Players = game:GetService("Players")
|
local screenGui = Instance.new("ScreenGui")
|
||||||
local ServerScriptService = game:GetService("ServerScriptService")
|
screenGui.Parent = game:GetService("Players").LocalPlayer:WaitForChild("PlayerGui")
|
||||||
print(Players.LocalPlayer)
|
|
||||||
print(#ServerScriptService:GetChildren())
|
local frame = Instance.new("Frame")
|
||||||
|
frame.Size = UDim2.new(0, 200, 0, 200)
|
||||||
|
frame.Position = UDim2.new(0.5, -100, 0.5, -100)
|
||||||
|
frame.BackgroundColor3 = Color3.fromRGB(45, 45, 45)
|
||||||
|
frame.Parent = screenGui
|
||||||
|
|
||||||
|
local textLabel = Instance.new("TextLabel")
|
||||||
|
textLabel.Size = UDim2.new(1, 0, 0, 50)
|
||||||
|
textLabel.Text = "Hello, World!"
|
||||||
|
textLabel.Parent = frame
|
||||||
```
|
```
|
||||||
|
|
||||||
# Template
|
## License
|
||||||
This transformer is intended to be used as a template for those who are interested in creating their own transformers in roblox-ts.
|
|
||||||
|
|
||||||
A necessary resource for those starting out with transformers is [ts-ast-viewer](https://ts-ast-viewer.com/). It shows you the result of AST, relevant properties, symbol information, type information and it automatically generates factory code for nodes. For example, you can see the code this transformer generates [here](https://ts-ast-viewer.com/#code/MYewdgzgLgBACgGwIYE8CmAnCMC8MDmSAtmgHQDiaUAypgG4CWwaAFAESKqYRsCUANACgYImAHUQGANYQADkma4CxMpRr0mrNhIxQZ85nwDcQA).
|
MIT
|
||||||
|
|
||||||
I'd also recommend downloading the [TypeScript repo](https://github.com/microsoft/TypeScript) locally as it's extremely helpful when you're using undocumented (the majority of the compiler API), internal or uncommon APIs.
|
|
||||||
|
|
||||||
Transformers mutate the TypeScript [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) by replacing parts of the AST with new nodes. Transformers are also able to utilize symbol and type information giving you access to TypeScript's advanced control flow analysis.
|
|
||||||
|
|
||||||
## Other Transformers
|
|
||||||
|
|
||||||
Here's a list of transformers if you want to see how they handle working with parts of the TypeScript compiler api not shown here (e.g symbols or types).
|
|
||||||
|
|
||||||
- [rbxts-transform-debug](https://github.com/roblox-aurora/rbxts-transform-debug) by [@roblox-aurora](https://github.com/roblox-aurora)
|
|
||||||
- [rbxts-transform-env](https://github.com/roblox-aurora/rbxts-transform-env) by [@roblox-aurora](https://github.com/roblox-aurora)
|
|
||||||
- [Flamework](https://github.com/rbxts-flamework/transformer) by [@rbxts-flamework](https://github.com/rbxts-flamework)
|
|
||||||
|
|
||||||
One other source you may goto for learning about transformers is actually [roblox-ts](https://github.com/roblox-ts/roblox-ts/tree/master/src/TSTransformer) itself. This generates a Luau AST instead of a TS AST but it may still be a useful resource for learning about the compiler api.
|
|
||||||
Vendored
+308
@@ -0,0 +1,308 @@
|
|||||||
|
/// <reference no-default-lib="true"/>
|
||||||
|
/// <reference types="@rbxts/types" />
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add constructors to all Roblox CreatableInstances
|
||||||
|
* This adds `new ClassName()` constructors for all Roblox instance types
|
||||||
|
* that can be created with Instance.new()
|
||||||
|
*
|
||||||
|
* The transformer will convert these to `new Instance("ClassName")`
|
||||||
|
*/
|
||||||
|
type CreatableInstancesWithConstructors = {
|
||||||
|
[K in keyof CreatableInstances]: {
|
||||||
|
new (...args: any[]): CreatableInstances[K];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare const CreatableInstancesWithConstructors: CreatableInstancesWithConstructors;
|
||||||
|
|
||||||
|
declare const Accessory: CreatableInstancesWithConstructors["Accessory"];
|
||||||
|
declare const AccessoryDescription: CreatableInstancesWithConstructors["AccessoryDescription"];
|
||||||
|
declare const Accoutrement: CreatableInstancesWithConstructors["Accoutrement"];
|
||||||
|
declare const Actor: CreatableInstancesWithConstructors["Actor"];
|
||||||
|
declare const AdGui: CreatableInstancesWithConstructors["AdGui"];
|
||||||
|
declare const AdPortal: CreatableInstancesWithConstructors["AdPortal"];
|
||||||
|
declare const AirController: CreatableInstancesWithConstructors["AirController"];
|
||||||
|
declare const AlignOrientation: CreatableInstancesWithConstructors["AlignOrientation"];
|
||||||
|
declare const AlignPosition: CreatableInstancesWithConstructors["AlignPosition"];
|
||||||
|
declare const AngularVelocity: CreatableInstancesWithConstructors["AngularVelocity"];
|
||||||
|
declare const Animation: CreatableInstancesWithConstructors["Animation"];
|
||||||
|
declare const AnimationConstraint: CreatableInstancesWithConstructors["AnimationConstraint"];
|
||||||
|
declare const AnimationController: CreatableInstancesWithConstructors["AnimationController"];
|
||||||
|
declare const AnimationRigData: CreatableInstancesWithConstructors["AnimationRigData"];
|
||||||
|
declare const Animator: CreatableInstancesWithConstructors["Animator"];
|
||||||
|
declare const Annotation: CreatableInstancesWithConstructors["Annotation"];
|
||||||
|
declare const ArcHandles: CreatableInstancesWithConstructors["ArcHandles"];
|
||||||
|
declare const Atmosphere: CreatableInstancesWithConstructors["Atmosphere"];
|
||||||
|
declare const AtmosphereSensor: CreatableInstancesWithConstructors["AtmosphereSensor"];
|
||||||
|
declare const Attachment: CreatableInstancesWithConstructors["Attachment"];
|
||||||
|
declare const AudioAnalyzer: CreatableInstancesWithConstructors["AudioAnalyzer"];
|
||||||
|
declare const AudioChannelMixer: CreatableInstancesWithConstructors["AudioChannelMixer"];
|
||||||
|
declare const AudioChannelSplitter: CreatableInstancesWithConstructors["AudioChannelSplitter"];
|
||||||
|
declare const AudioChorus: CreatableInstancesWithConstructors["AudioChorus"];
|
||||||
|
declare const AudioCompressor: CreatableInstancesWithConstructors["AudioCompressor"];
|
||||||
|
declare const AudioDeviceInput: CreatableInstancesWithConstructors["AudioDeviceInput"];
|
||||||
|
declare const AudioDeviceOutput: CreatableInstancesWithConstructors["AudioDeviceOutput"];
|
||||||
|
declare const AudioDistortion: CreatableInstancesWithConstructors["AudioDistortion"];
|
||||||
|
declare const AudioEcho: CreatableInstancesWithConstructors["AudioEcho"];
|
||||||
|
declare const AudioEmitter: CreatableInstancesWithConstructors["AudioEmitter"];
|
||||||
|
declare const AudioEqualizer: CreatableInstancesWithConstructors["AudioEqualizer"];
|
||||||
|
declare const AudioFader: CreatableInstancesWithConstructors["AudioFader"];
|
||||||
|
declare const AudioFilter: CreatableInstancesWithConstructors["AudioFilter"];
|
||||||
|
declare const AudioFlanger: CreatableInstancesWithConstructors["AudioFlanger"];
|
||||||
|
declare const AudioLimiter: CreatableInstancesWithConstructors["AudioLimiter"];
|
||||||
|
declare const AudioListener: CreatableInstancesWithConstructors["AudioListener"];
|
||||||
|
declare const AudioPitchShifter: CreatableInstancesWithConstructors["AudioPitchShifter"];
|
||||||
|
declare const AudioPlayer: CreatableInstancesWithConstructors["AudioPlayer"];
|
||||||
|
declare const AudioReverb: CreatableInstancesWithConstructors["AudioReverb"];
|
||||||
|
declare const AudioSearchParams: CreatableInstancesWithConstructors["AudioSearchParams"];
|
||||||
|
declare const AudioTextToSpeech: CreatableInstancesWithConstructors["AudioTextToSpeech"];
|
||||||
|
declare const AuroraScript: CreatableInstancesWithConstructors["AuroraScript"];
|
||||||
|
declare const Backpack: CreatableInstancesWithConstructors["Backpack"];
|
||||||
|
declare const BallSocketConstraint: CreatableInstancesWithConstructors["BallSocketConstraint"];
|
||||||
|
declare const Beam: CreatableInstancesWithConstructors["Beam"];
|
||||||
|
declare const BillboardGui: CreatableInstancesWithConstructors["BillboardGui"];
|
||||||
|
declare const BindableEvent: CreatableInstancesWithConstructors["BindableEvent"];
|
||||||
|
declare const BindableFunction: CreatableInstancesWithConstructors["BindableFunction"];
|
||||||
|
declare const BlockMesh: CreatableInstancesWithConstructors["BlockMesh"];
|
||||||
|
declare const BloomEffect: CreatableInstancesWithConstructors["BloomEffect"];
|
||||||
|
declare const BlurEffect: CreatableInstancesWithConstructors["BlurEffect"];
|
||||||
|
declare const BodyAngularVelocity: CreatableInstancesWithConstructors["BodyAngularVelocity"];
|
||||||
|
declare const BodyColors: CreatableInstancesWithConstructors["BodyColors"];
|
||||||
|
declare const BodyForce: CreatableInstancesWithConstructors["BodyForce"];
|
||||||
|
declare const BodyGyro: CreatableInstancesWithConstructors["BodyGyro"];
|
||||||
|
declare const BodyPartDescription: CreatableInstancesWithConstructors["BodyPartDescription"];
|
||||||
|
declare const BodyPosition: CreatableInstancesWithConstructors["BodyPosition"];
|
||||||
|
declare const BodyThrust: CreatableInstancesWithConstructors["BodyThrust"];
|
||||||
|
declare const BodyVelocity: CreatableInstancesWithConstructors["BodyVelocity"];
|
||||||
|
declare const Bone: CreatableInstancesWithConstructors["Bone"];
|
||||||
|
declare const BoolValue: CreatableInstancesWithConstructors["BoolValue"];
|
||||||
|
declare const BoxHandleAdornment: CreatableInstancesWithConstructors["BoxHandleAdornment"];
|
||||||
|
declare const Breakpoint: CreatableInstancesWithConstructors["Breakpoint"];
|
||||||
|
declare const BrickColorValue: CreatableInstancesWithConstructors["BrickColorValue"];
|
||||||
|
declare const BubbleChatMessageProperties: CreatableInstancesWithConstructors["BubbleChatMessageProperties"];
|
||||||
|
declare const BuoyancySensor: CreatableInstancesWithConstructors["BuoyancySensor"];
|
||||||
|
declare const CFrameValue: CreatableInstancesWithConstructors["CFrameValue"];
|
||||||
|
declare const Camera: CreatableInstancesWithConstructors["Camera"];
|
||||||
|
declare const CanvasGroup: CreatableInstancesWithConstructors["CanvasGroup"];
|
||||||
|
declare const CharacterMesh: CreatableInstancesWithConstructors["CharacterMesh"];
|
||||||
|
declare const ChorusSoundEffect: CreatableInstancesWithConstructors["ChorusSoundEffect"];
|
||||||
|
declare const ClickDetector: CreatableInstancesWithConstructors["ClickDetector"];
|
||||||
|
declare const ClimbController: CreatableInstancesWithConstructors["ClimbController"];
|
||||||
|
declare const Clouds: CreatableInstancesWithConstructors["Clouds"];
|
||||||
|
declare const Color3Value: CreatableInstancesWithConstructors["Color3Value"];
|
||||||
|
declare const ColorCorrectionEffect: CreatableInstancesWithConstructors["ColorCorrectionEffect"];
|
||||||
|
declare const ColorGradingEffect: CreatableInstancesWithConstructors["ColorGradingEffect"];
|
||||||
|
declare const CompressorSoundEffect: CreatableInstancesWithConstructors["CompressorSoundEffect"];
|
||||||
|
declare const ConeHandleAdornment: CreatableInstancesWithConstructors["ConeHandleAdornment"];
|
||||||
|
declare const Configuration: CreatableInstancesWithConstructors["Configuration"];
|
||||||
|
declare const ControllerManager: CreatableInstancesWithConstructors["ControllerManager"];
|
||||||
|
declare const ControllerPartSensor: CreatableInstancesWithConstructors["ControllerPartSensor"];
|
||||||
|
declare const CornerWedgePart: CreatableInstancesWithConstructors["CornerWedgePart"];
|
||||||
|
declare const CurveAnimation: CreatableInstancesWithConstructors["CurveAnimation"];
|
||||||
|
declare const CustomLog: CreatableInstancesWithConstructors["CustomLog"];
|
||||||
|
declare const CylinderHandleAdornment: CreatableInstancesWithConstructors["CylinderHandleAdornment"];
|
||||||
|
declare const CylinderMesh: CreatableInstancesWithConstructors["CylinderMesh"];
|
||||||
|
declare const CylindricalConstraint: CreatableInstancesWithConstructors["CylindricalConstraint"];
|
||||||
|
declare const DataStoreGetOptions: CreatableInstancesWithConstructors["DataStoreGetOptions"];
|
||||||
|
declare const DataStoreIncrementOptions: CreatableInstancesWithConstructors["DataStoreIncrementOptions"];
|
||||||
|
declare const DataStoreOptions: CreatableInstancesWithConstructors["DataStoreOptions"];
|
||||||
|
declare const DataStoreSetOptions: CreatableInstancesWithConstructors["DataStoreSetOptions"];
|
||||||
|
declare const Decal: CreatableInstancesWithConstructors["Decal"];
|
||||||
|
declare const DepthOfFieldEffect: CreatableInstancesWithConstructors["DepthOfFieldEffect"];
|
||||||
|
declare const Dialog: CreatableInstancesWithConstructors["Dialog"];
|
||||||
|
declare const DialogChoice: CreatableInstancesWithConstructors["DialogChoice"];
|
||||||
|
declare const DistortionSoundEffect: CreatableInstancesWithConstructors["DistortionSoundEffect"];
|
||||||
|
declare const DoubleConstrainedValue: CreatableInstancesWithConstructors["DoubleConstrainedValue"];
|
||||||
|
declare const DragDetector: CreatableInstancesWithConstructors["DragDetector"];
|
||||||
|
declare const Dragger: CreatableInstancesWithConstructors["Dragger"];
|
||||||
|
declare const EchoSoundEffect: CreatableInstancesWithConstructors["EchoSoundEffect"];
|
||||||
|
declare const EqualizerSoundEffect: CreatableInstancesWithConstructors["EqualizerSoundEffect"];
|
||||||
|
declare const EulerRotationCurve: CreatableInstancesWithConstructors["EulerRotationCurve"];
|
||||||
|
declare const ExperienceInviteOptions: CreatableInstancesWithConstructors["ExperienceInviteOptions"];
|
||||||
|
declare const ExplorerFilter: CreatableInstancesWithConstructors["ExplorerFilter"];
|
||||||
|
declare const Explosion: CreatableInstancesWithConstructors["Explosion"];
|
||||||
|
declare const FaceControls: CreatableInstancesWithConstructors["FaceControls"];
|
||||||
|
declare const FileMesh: CreatableInstancesWithConstructors["FileMesh"];
|
||||||
|
declare const Fire: CreatableInstancesWithConstructors["Fire"];
|
||||||
|
declare const FlangeSoundEffect: CreatableInstancesWithConstructors["FlangeSoundEffect"];
|
||||||
|
declare const FloatCurve: CreatableInstancesWithConstructors["FloatCurve"];
|
||||||
|
declare const FloorWire: CreatableInstancesWithConstructors["FloorWire"];
|
||||||
|
declare const FluidForceSensor: CreatableInstancesWithConstructors["FluidForceSensor"];
|
||||||
|
declare const Folder: CreatableInstancesWithConstructors["Folder"];
|
||||||
|
declare const ForceField: CreatableInstancesWithConstructors["ForceField"];
|
||||||
|
declare const Frame: CreatableInstancesWithConstructors["Frame"];
|
||||||
|
declare const GetTextBoundsParams: CreatableInstancesWithConstructors["GetTextBoundsParams"];
|
||||||
|
declare const Glue: CreatableInstancesWithConstructors["Glue"];
|
||||||
|
declare const GroundController: CreatableInstancesWithConstructors["GroundController"];
|
||||||
|
declare const Handles: CreatableInstancesWithConstructors["Handles"];
|
||||||
|
declare const HapticEffect: CreatableInstancesWithConstructors["HapticEffect"];
|
||||||
|
declare const Hat: CreatableInstancesWithConstructors["Hat"];
|
||||||
|
declare const HiddenSurfaceRemovalAsset: CreatableInstancesWithConstructors["HiddenSurfaceRemovalAsset"];
|
||||||
|
declare const Highlight: CreatableInstancesWithConstructors["Highlight"];
|
||||||
|
declare const HingeConstraint: CreatableInstancesWithConstructors["HingeConstraint"];
|
||||||
|
declare const Hole: CreatableInstancesWithConstructors["Hole"];
|
||||||
|
declare const Humanoid: CreatableInstancesWithConstructors["Humanoid"];
|
||||||
|
declare const HumanoidController: CreatableInstancesWithConstructors["HumanoidController"];
|
||||||
|
declare const HumanoidDescription: CreatableInstancesWithConstructors["HumanoidDescription"];
|
||||||
|
declare const HumanoidRigDescription: CreatableInstancesWithConstructors["HumanoidRigDescription"];
|
||||||
|
declare const IKControl: CreatableInstancesWithConstructors["IKControl"];
|
||||||
|
declare const ImageButton: CreatableInstancesWithConstructors["ImageButton"];
|
||||||
|
declare const ImageHandleAdornment: CreatableInstancesWithConstructors["ImageHandleAdornment"];
|
||||||
|
declare const ImageLabel: CreatableInstancesWithConstructors["ImageLabel"];
|
||||||
|
declare const InputAction: CreatableInstancesWithConstructors["InputAction"];
|
||||||
|
declare const InputBinding: CreatableInstancesWithConstructors["InputBinding"];
|
||||||
|
declare const InputContext: CreatableInstancesWithConstructors["InputContext"];
|
||||||
|
declare const IntConstrainedValue: CreatableInstancesWithConstructors["IntConstrainedValue"];
|
||||||
|
declare const IntValue: CreatableInstancesWithConstructors["IntValue"];
|
||||||
|
declare const InternalSyncItem: CreatableInstancesWithConstructors["InternalSyncItem"];
|
||||||
|
declare const IntersectOperation: CreatableInstancesWithConstructors["IntersectOperation"];
|
||||||
|
declare const Keyframe: CreatableInstancesWithConstructors["Keyframe"];
|
||||||
|
declare const KeyframeMarker: CreatableInstancesWithConstructors["KeyframeMarker"];
|
||||||
|
declare const KeyframeSequence: CreatableInstancesWithConstructors["KeyframeSequence"];
|
||||||
|
declare const LineForce: CreatableInstancesWithConstructors["LineForce"];
|
||||||
|
declare const LineHandleAdornment: CreatableInstancesWithConstructors["LineHandleAdornment"];
|
||||||
|
declare const LinearVelocity: CreatableInstancesWithConstructors["LinearVelocity"];
|
||||||
|
declare const LocalScript: CreatableInstancesWithConstructors["LocalScript"];
|
||||||
|
declare const LocalizationTable: CreatableInstancesWithConstructors["LocalizationTable"];
|
||||||
|
declare const ManualGlue: CreatableInstancesWithConstructors["ManualGlue"];
|
||||||
|
declare const ManualWeld: CreatableInstancesWithConstructors["ManualWeld"];
|
||||||
|
declare const MarkerCurve: CreatableInstancesWithConstructors["MarkerCurve"];
|
||||||
|
declare const MaterialVariant: CreatableInstancesWithConstructors["MaterialVariant"];
|
||||||
|
declare const MeshPart: CreatableInstancesWithConstructors["MeshPart"];
|
||||||
|
declare const Model: CreatableInstancesWithConstructors["Model"];
|
||||||
|
declare const ModuleScript: CreatableInstancesWithConstructors["ModuleScript"];
|
||||||
|
declare const Motor: CreatableInstancesWithConstructors["Motor"];
|
||||||
|
declare const Motor6D: CreatableInstancesWithConstructors["Motor6D"];
|
||||||
|
declare const MotorFeature: CreatableInstancesWithConstructors["MotorFeature"];
|
||||||
|
declare const NegateOperation: CreatableInstancesWithConstructors["NegateOperation"];
|
||||||
|
declare const NoCollisionConstraint: CreatableInstancesWithConstructors["NoCollisionConstraint"];
|
||||||
|
declare const Noise: CreatableInstancesWithConstructors["Noise"];
|
||||||
|
declare const NumberPose: CreatableInstancesWithConstructors["NumberPose"];
|
||||||
|
declare const NumberValue: CreatableInstancesWithConstructors["NumberValue"];
|
||||||
|
declare const ObjectValue: CreatableInstancesWithConstructors["ObjectValue"];
|
||||||
|
declare const OperationGraph: CreatableInstancesWithConstructors["OperationGraph"];
|
||||||
|
declare const Pants: CreatableInstancesWithConstructors["Pants"];
|
||||||
|
declare const Part: CreatableInstancesWithConstructors["Part"];
|
||||||
|
declare const PartOperation: CreatableInstancesWithConstructors["PartOperation"];
|
||||||
|
declare const ParticleEmitter: CreatableInstancesWithConstructors["ParticleEmitter"];
|
||||||
|
declare const Path2D: CreatableInstancesWithConstructors["Path2D"];
|
||||||
|
declare const PathfindingLink: CreatableInstancesWithConstructors["PathfindingLink"];
|
||||||
|
declare const PathfindingModifier: CreatableInstancesWithConstructors["PathfindingModifier"];
|
||||||
|
declare const PitchShiftSoundEffect: CreatableInstancesWithConstructors["PitchShiftSoundEffect"];
|
||||||
|
declare const Plane: CreatableInstancesWithConstructors["Plane"];
|
||||||
|
declare const PlaneConstraint: CreatableInstancesWithConstructors["PlaneConstraint"];
|
||||||
|
declare const PluginCapabilities: CreatableInstancesWithConstructors["PluginCapabilities"];
|
||||||
|
declare const PointLight: CreatableInstancesWithConstructors["PointLight"];
|
||||||
|
declare const Pose: CreatableInstancesWithConstructors["Pose"];
|
||||||
|
declare const PrismaticConstraint: CreatableInstancesWithConstructors["PrismaticConstraint"];
|
||||||
|
declare const ProximityPrompt: CreatableInstancesWithConstructors["ProximityPrompt"];
|
||||||
|
declare const RTAnimationTracker: CreatableInstancesWithConstructors["RTAnimationTracker"];
|
||||||
|
declare const RayValue: CreatableInstancesWithConstructors["RayValue"];
|
||||||
|
declare const RelativeGui: CreatableInstancesWithConstructors["RelativeGui"];
|
||||||
|
declare const RemoteEvent: CreatableInstancesWithConstructors["RemoteEvent"];
|
||||||
|
declare const RemoteFunction: CreatableInstancesWithConstructors["RemoteFunction"];
|
||||||
|
declare const ReverbSoundEffect: CreatableInstancesWithConstructors["ReverbSoundEffect"];
|
||||||
|
declare const RigidConstraint: CreatableInstancesWithConstructors["RigidConstraint"];
|
||||||
|
declare const RocketPropulsion: CreatableInstancesWithConstructors["RocketPropulsion"];
|
||||||
|
declare const RodConstraint: CreatableInstancesWithConstructors["RodConstraint"];
|
||||||
|
declare const RopeConstraint: CreatableInstancesWithConstructors["RopeConstraint"];
|
||||||
|
declare const Rotate: CreatableInstancesWithConstructors["Rotate"];
|
||||||
|
declare const RotateP: CreatableInstancesWithConstructors["RotateP"];
|
||||||
|
declare const RotateV: CreatableInstancesWithConstructors["RotateV"];
|
||||||
|
declare const RotationCurve: CreatableInstancesWithConstructors["RotationCurve"];
|
||||||
|
declare const ScreenGui: CreatableInstancesWithConstructors["ScreenGui"];
|
||||||
|
declare const Script: CreatableInstancesWithConstructors["Script"];
|
||||||
|
declare const ScrollingFrame: CreatableInstancesWithConstructors["ScrollingFrame"];
|
||||||
|
declare const Seat: CreatableInstancesWithConstructors["Seat"];
|
||||||
|
declare const SelectionBox: CreatableInstancesWithConstructors["SelectionBox"];
|
||||||
|
declare const SelectionPartLasso: CreatableInstancesWithConstructors["SelectionPartLasso"];
|
||||||
|
declare const SelectionPointLasso: CreatableInstancesWithConstructors["SelectionPointLasso"];
|
||||||
|
declare const SelectionSphere: CreatableInstancesWithConstructors["SelectionSphere"];
|
||||||
|
declare const Shirt: CreatableInstancesWithConstructors["Shirt"];
|
||||||
|
declare const ShirtGraphic: CreatableInstancesWithConstructors["ShirtGraphic"];
|
||||||
|
declare const SkateboardController: CreatableInstancesWithConstructors["SkateboardController"];
|
||||||
|
declare const SkateboardPlatform: CreatableInstancesWithConstructors["SkateboardPlatform"];
|
||||||
|
declare const Sky: CreatableInstancesWithConstructors["Sky"];
|
||||||
|
declare const Smoke: CreatableInstancesWithConstructors["Smoke"];
|
||||||
|
declare const Snap: CreatableInstancesWithConstructors["Snap"];
|
||||||
|
declare const Sound: CreatableInstancesWithConstructors["Sound"];
|
||||||
|
declare const SoundGroup: CreatableInstancesWithConstructors["SoundGroup"];
|
||||||
|
declare const Sparkles: CreatableInstancesWithConstructors["Sparkles"];
|
||||||
|
declare const SpawnLocation: CreatableInstancesWithConstructors["SpawnLocation"];
|
||||||
|
declare const SpecialMesh: CreatableInstancesWithConstructors["SpecialMesh"];
|
||||||
|
declare const SphereHandleAdornment: CreatableInstancesWithConstructors["SphereHandleAdornment"];
|
||||||
|
declare const SpotLight: CreatableInstancesWithConstructors["SpotLight"];
|
||||||
|
declare const SpringConstraint: CreatableInstancesWithConstructors["SpringConstraint"];
|
||||||
|
declare const StarterGear: CreatableInstancesWithConstructors["StarterGear"];
|
||||||
|
declare const StringValue: CreatableInstancesWithConstructors["StringValue"];
|
||||||
|
declare const StudioAttachment: CreatableInstancesWithConstructors["StudioAttachment"];
|
||||||
|
declare const StudioCallout: CreatableInstancesWithConstructors["StudioCallout"];
|
||||||
|
declare const StyleDerive: CreatableInstancesWithConstructors["StyleDerive"];
|
||||||
|
declare const StyleLink: CreatableInstancesWithConstructors["StyleLink"];
|
||||||
|
declare const StyleRule: CreatableInstancesWithConstructors["StyleRule"];
|
||||||
|
declare const StyleSheet: CreatableInstancesWithConstructors["StyleSheet"];
|
||||||
|
declare const SunRaysEffect: CreatableInstancesWithConstructors["SunRaysEffect"];
|
||||||
|
declare const SurfaceAppearance: CreatableInstancesWithConstructors["SurfaceAppearance"];
|
||||||
|
declare const SurfaceGui: CreatableInstancesWithConstructors["SurfaceGui"];
|
||||||
|
declare const SurfaceLight: CreatableInstancesWithConstructors["SurfaceLight"];
|
||||||
|
declare const SurfaceSelection: CreatableInstancesWithConstructors["SurfaceSelection"];
|
||||||
|
declare const SwimController: CreatableInstancesWithConstructors["SwimController"];
|
||||||
|
declare const Team: CreatableInstancesWithConstructors["Team"];
|
||||||
|
declare const TeleportOptions: CreatableInstancesWithConstructors["TeleportOptions"];
|
||||||
|
declare const TerrainDetail: CreatableInstancesWithConstructors["TerrainDetail"];
|
||||||
|
declare const TerrainRegion: CreatableInstancesWithConstructors["TerrainRegion"];
|
||||||
|
declare const TextBox: CreatableInstancesWithConstructors["TextBox"];
|
||||||
|
declare const TextButton: CreatableInstancesWithConstructors["TextButton"];
|
||||||
|
declare const TextChannel: CreatableInstancesWithConstructors["TextChannel"];
|
||||||
|
declare const TextChatCommand: CreatableInstancesWithConstructors["TextChatCommand"];
|
||||||
|
declare const TextChatMessageProperties: CreatableInstancesWithConstructors["TextChatMessageProperties"];
|
||||||
|
declare const TextLabel: CreatableInstancesWithConstructors["TextLabel"];
|
||||||
|
declare const Texture: CreatableInstancesWithConstructors["Texture"];
|
||||||
|
declare const Tool: CreatableInstancesWithConstructors["Tool"];
|
||||||
|
declare const Torque: CreatableInstancesWithConstructors["Torque"];
|
||||||
|
declare const TorsionSpringConstraint: CreatableInstancesWithConstructors["TorsionSpringConstraint"];
|
||||||
|
declare const TrackerStreamAnimation: CreatableInstancesWithConstructors["TrackerStreamAnimation"];
|
||||||
|
declare const Trail: CreatableInstancesWithConstructors["Trail"];
|
||||||
|
declare const TremoloSoundEffect: CreatableInstancesWithConstructors["TremoloSoundEffect"];
|
||||||
|
declare const TrussPart: CreatableInstancesWithConstructors["TrussPart"];
|
||||||
|
declare const UIAspectRatioConstraint: CreatableInstancesWithConstructors["UIAspectRatioConstraint"];
|
||||||
|
declare const UICorner: CreatableInstancesWithConstructors["UICorner"];
|
||||||
|
declare const UIDragDetector: CreatableInstancesWithConstructors["UIDragDetector"];
|
||||||
|
declare const UIFlexItem: CreatableInstancesWithConstructors["UIFlexItem"];
|
||||||
|
declare const UIGradient: CreatableInstancesWithConstructors["UIGradient"];
|
||||||
|
declare const UIGridLayout: CreatableInstancesWithConstructors["UIGridLayout"];
|
||||||
|
declare const UIListLayout: CreatableInstancesWithConstructors["UIListLayout"];
|
||||||
|
declare const UIPadding: CreatableInstancesWithConstructors["UIPadding"];
|
||||||
|
declare const UIPageLayout: CreatableInstancesWithConstructors["UIPageLayout"];
|
||||||
|
declare const UIScale: CreatableInstancesWithConstructors["UIScale"];
|
||||||
|
declare const UISizeConstraint: CreatableInstancesWithConstructors["UISizeConstraint"];
|
||||||
|
declare const UIStroke: CreatableInstancesWithConstructors["UIStroke"];
|
||||||
|
declare const UITableLayout: CreatableInstancesWithConstructors["UITableLayout"];
|
||||||
|
declare const UITextSizeConstraint: CreatableInstancesWithConstructors["UITextSizeConstraint"];
|
||||||
|
declare const UnionOperation: CreatableInstancesWithConstructors["UnionOperation"];
|
||||||
|
declare const UniversalConstraint: CreatableInstancesWithConstructors["UniversalConstraint"];
|
||||||
|
declare const UnreliableRemoteEvent: CreatableInstancesWithConstructors["UnreliableRemoteEvent"];
|
||||||
|
declare const Vector3Curve: CreatableInstancesWithConstructors["Vector3Curve"];
|
||||||
|
declare const Vector3Value: CreatableInstancesWithConstructors["Vector3Value"];
|
||||||
|
declare const VectorForce: CreatableInstancesWithConstructors["VectorForce"];
|
||||||
|
declare const VehicleController: CreatableInstancesWithConstructors["VehicleController"];
|
||||||
|
declare const VehicleSeat: CreatableInstancesWithConstructors["VehicleSeat"];
|
||||||
|
declare const VelocityMotor: CreatableInstancesWithConstructors["VelocityMotor"];
|
||||||
|
declare const VideoDeviceInput: CreatableInstancesWithConstructors["VideoDeviceInput"];
|
||||||
|
declare const VideoDisplay: CreatableInstancesWithConstructors["VideoDisplay"];
|
||||||
|
declare const VideoFrame: CreatableInstancesWithConstructors["VideoFrame"];
|
||||||
|
declare const VideoPlayer: CreatableInstancesWithConstructors["VideoPlayer"];
|
||||||
|
declare const ViewportFrame: CreatableInstancesWithConstructors["ViewportFrame"];
|
||||||
|
declare const VisualizationMode: CreatableInstancesWithConstructors["VisualizationMode"];
|
||||||
|
declare const VisualizationModeCategory: CreatableInstancesWithConstructors["VisualizationModeCategory"];
|
||||||
|
declare const WedgePart: CreatableInstancesWithConstructors["WedgePart"];
|
||||||
|
declare const Weld: CreatableInstancesWithConstructors["Weld"];
|
||||||
|
declare const WeldConstraint: CreatableInstancesWithConstructors["WeldConstraint"];
|
||||||
|
declare const Wire: CreatableInstancesWithConstructors["Wire"];
|
||||||
|
declare const WireframeHandleAdornment: CreatableInstancesWithConstructors["WireframeHandleAdornment"];
|
||||||
|
declare const WorkspaceAnnotation: CreatableInstancesWithConstructors["WorkspaceAnnotation"];
|
||||||
|
declare const WorldModel: CreatableInstancesWithConstructors["WorldModel"];
|
||||||
|
declare const WrapDeformer: CreatableInstancesWithConstructors["WrapDeformer"];
|
||||||
|
declare const WrapLayer: CreatableInstancesWithConstructors["WrapLayer"];
|
||||||
|
declare const WrapTarget: CreatableInstancesWithConstructors["WrapTarget"];
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
preset: 'ts-jest',
|
||||||
|
testEnvironment: 'node',
|
||||||
|
testMatch: ['**/test/**/*.test.ts'],
|
||||||
|
moduleFileExtensions: ['ts', 'js'],
|
||||||
|
};
|
||||||
Generated
+7110
-1272
File diff suppressed because it is too large
Load Diff
+26
-19
@@ -1,33 +1,40 @@
|
|||||||
{
|
{
|
||||||
"name": "rbxts-transformer-services",
|
"name": "rbxts-transformer-instances",
|
||||||
"version": "1.1.1",
|
"version": "1.0.0",
|
||||||
"description": "A transformer that converts @rbxts/services imports into plain GetService calls.",
|
"description": "Enable the use of instance constructors, reducing boilerplate.",
|
||||||
"main": "out/index.js",
|
"main": "out/index.js",
|
||||||
"author": "Fireboltofdeath <fireboltofpublic@gmail.com> (https://github.com/Fireboltofdeath)",
|
"author": "evilbocchi",
|
||||||
"license": "ISC",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/FireTS/rbxts-transformer-services.git"
|
"url": "https://github.com/evilbocchi/rbxts-transformer-instances.git"
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"typescript": "^5.2.2"
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepare": "npm run build",
|
"prepare": "npm run generate-declarations && npm run build",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"watch": "tsc -w"
|
"watch": "tsc -w",
|
||||||
|
"test": "jest",
|
||||||
|
"generate-declarations": "node scripts/generate-declarations.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"typescript": "^5.5.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@rbxts/types": "^1.0.845",
|
||||||
|
"@types/jest": "^29.5.14",
|
||||||
"@types/node": "^18.18.6",
|
"@types/node": "^18.18.6",
|
||||||
"@types/ts-expose-internals": "npm:ts-expose-internals@5.2.2",
|
"@types/ts-expose-internals": "npm:ts-expose-internals@5.2.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.9.1",
|
"@typescript-eslint/eslint-plugin": "^8.5.0",
|
||||||
"@typescript-eslint/parser": "^4.9.1",
|
"@typescript-eslint/parser": "^8.5.0",
|
||||||
"eslint": "^7.15.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-config-prettier": "^7.0.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-plugin-prettier": "^3.2.0",
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
"prettier": "^2.2.1"
|
"jest": "^29.7.0",
|
||||||
|
"ts-jest": "^29.3.1"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"out"
|
"out",
|
||||||
]
|
"index.d.ts"
|
||||||
|
],
|
||||||
|
"types": "index.d.ts"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,154 @@
|
|||||||
|
/**
|
||||||
|
* Script to generate declaration statements for all creatable Roblox instances
|
||||||
|
* This will produce declarations in the format:
|
||||||
|
* declare const INSTANCENAME: CreatableInstancesWithConstructors["INSTANCENAME"]
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const { execSync } = require('child_process');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all creatable instance class names by examining the @rbxts/types package
|
||||||
|
*/
|
||||||
|
function getCreatableInstanceNames() {
|
||||||
|
try {
|
||||||
|
// Find the location of @rbxts/types in node_modules
|
||||||
|
let typesPath;
|
||||||
|
try {
|
||||||
|
// Try to find the path to @rbxts/types
|
||||||
|
typesPath = path.dirname(require.resolve('@rbxts/types/package.json'));
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Could not find @rbxts/types. Make sure it is installed.');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the CreatableInstances interface definition file
|
||||||
|
// This could be in a few different locations depending on the package structure
|
||||||
|
let instancesFile;
|
||||||
|
const possiblePaths = [
|
||||||
|
path.join(typesPath, 'include', 'generated', 'None.d.ts'),
|
||||||
|
path.join(typesPath, 'types', 'generated', 'None.d.ts'),
|
||||||
|
path.join(typesPath, 'generated', 'None.d.ts')
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const filePath of possiblePaths) {
|
||||||
|
if (fs.existsSync(filePath)) {
|
||||||
|
instancesFile = filePath;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!instancesFile) {
|
||||||
|
throw new Error('Could not find None.d.ts file in @rbxts/types');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the file content
|
||||||
|
const content = fs.readFileSync(instancesFile, 'utf-8');
|
||||||
|
|
||||||
|
// Extract interface names that appear in CreatableInstances
|
||||||
|
// This regex might need adjustment depending on the exact format
|
||||||
|
const creatableInstancesRegex = /interface CreatableInstances \{([\s\S]*?)\}/;
|
||||||
|
const creatablesMatch = content.match(creatableInstancesRegex);
|
||||||
|
|
||||||
|
if (!creatablesMatch || !creatablesMatch[1]) {
|
||||||
|
throw new Error('Could not find CreatableInstances interface in the types file');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract class names by looking for patterns like "ClassName: ClassName;"
|
||||||
|
const classNameRegex = /([A-Za-z0-9_]+)\s*:\s*([A-Za-z0-9_]+);/g;
|
||||||
|
const classNames = [];
|
||||||
|
let match;
|
||||||
|
|
||||||
|
while ((match = classNameRegex.exec(creatablesMatch[1])) !== null) {
|
||||||
|
classNames.push(match[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return classNames.sort();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error extracting instance names:', error);
|
||||||
|
|
||||||
|
// Fallback to a predefined list of common instances
|
||||||
|
console.log('Falling back to predefined list of common instances...');
|
||||||
|
return [
|
||||||
|
"Accessory", "Accoutrement", "Animation", "Attachment", "BillboardGui",
|
||||||
|
"BindableEvent", "BindableFunction", "BlockMesh", "BodyAngularVelocity",
|
||||||
|
"BodyForce", "BodyGyro", "BodyPosition", "BodyThrust", "BodyVelocity",
|
||||||
|
"BoolValue", "BrickColorValue", "Camera", "CFrameValue", "ClickDetector",
|
||||||
|
"Clothing", "Color3Value", "ColorCorrectionEffect", "Configuration",
|
||||||
|
"CornerWedgePart", "Decal", "Dialog", "DialogChoice", "DoubleConstrainedValue",
|
||||||
|
"Explosion", "Folder", "ForceField", "Frame", "GuiButton", "GuiObject",
|
||||||
|
"Highlight", "Humanoid", "HumanoidDescription", "ImageButton", "ImageLabel",
|
||||||
|
"IntConstrainedValue", "IntValue", "LocalScript", "MeshPart", "Model",
|
||||||
|
"ModuleScript", "Motor", "Motor6D", "NumberValue", "ObjectValue", "Part",
|
||||||
|
"ParticleEmitter", "ProximityPrompt", "RayValue", "RemoteEvent", "RemoteFunction",
|
||||||
|
"ScreenGui", "Script", "ScrollingFrame", "Seat", "Sky", "Sound", "SpecialMesh",
|
||||||
|
"SpotLight", "StringValue", "SurfaceGui", "TextBox", "TextButton",
|
||||||
|
"TextLabel", "Texture", "Tool", "TouchTransmitter", "Trail", "TrussPart",
|
||||||
|
"UIAspectRatioConstraint", "UICorner", "UIGradient", "UIGridLayout",
|
||||||
|
"UIListLayout", "UIPadding", "UIPageLayout", "UIScale", "UIStroke",
|
||||||
|
"UITableLayout", "UITextSizeConstraint", "UnionOperation", "Vector3Value",
|
||||||
|
"VectorForce", "VideoFrame", "WedgePart", "Weld"
|
||||||
|
].sort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the declarations file content
|
||||||
|
* @param {string[]} classNames List of creatable instance class names
|
||||||
|
* @returns {string} The content for the declarations file
|
||||||
|
*/
|
||||||
|
function generateDeclarations(classNames) {
|
||||||
|
// Header part
|
||||||
|
let content = `/// <reference no-default-lib="true"/>
|
||||||
|
/// <reference types="@rbxts/types" />
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add constructors to all Roblox CreatableInstances
|
||||||
|
* This adds \`new ClassName()\` constructors for all Roblox instance types
|
||||||
|
* that can be created with Instance.new()
|
||||||
|
*
|
||||||
|
* The transformer will convert these to \`new Instance("ClassName")\`
|
||||||
|
*/
|
||||||
|
type CreatableInstancesWithConstructors = {
|
||||||
|
[K in keyof CreatableInstances]: {
|
||||||
|
new (...args: any[]): CreatableInstances[K];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare const CreatableInstancesWithConstructors: CreatableInstancesWithConstructors;
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Add declarations for each class
|
||||||
|
for (const className of classNames) {
|
||||||
|
content += `declare const ${className}: CreatableInstancesWithConstructors["${className}"];\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main function
|
||||||
|
*/
|
||||||
|
function main() {
|
||||||
|
const classNames = getCreatableInstanceNames();
|
||||||
|
console.log(`Found ${classNames.length} creatable instance types`);
|
||||||
|
|
||||||
|
const declarationsContent = generateDeclarations(classNames);
|
||||||
|
const outputPath = path.join(__dirname, '..', 'index.d.ts');
|
||||||
|
|
||||||
|
// Write to file
|
||||||
|
fs.writeFileSync(outputPath, declarationsContent, 'utf-8');
|
||||||
|
console.log(`Successfully generated declarations in ${outputPath}`);
|
||||||
|
|
||||||
|
console.log('Example declarations:');
|
||||||
|
const examples = classNames.slice(0, 5);
|
||||||
|
for (const className of examples) {
|
||||||
|
console.log(`declare const ${className}: CreatableInstancesWithConstructors["${className}"];`);
|
||||||
|
}
|
||||||
|
console.log(`...and ${classNames.length - 5} more`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the script
|
||||||
|
main();
|
||||||
+1
-1
@@ -10,4 +10,4 @@ export default function (program: ts.Program, config: TransformerConfig) {
|
|||||||
const context = new TransformContext(program, transformationContext, config);
|
const context = new TransformContext(program, transformationContext, config);
|
||||||
return (file) => context.transform(file);
|
return (file) => context.transform(file);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
+62
-92
@@ -4,7 +4,7 @@ import ts from "typescript";
|
|||||||
* This is the transformer's configuration, the values are passed from the tsconfig.
|
* This is the transformer's configuration, the values are passed from the tsconfig.
|
||||||
*/
|
*/
|
||||||
export interface TransformerConfig {
|
export interface TransformerConfig {
|
||||||
_: void;
|
_: void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -13,105 +13,75 @@ export interface TransformerConfig {
|
|||||||
* You can also use this object to store state, e.g prereqs.
|
* You can also use this object to store state, e.g prereqs.
|
||||||
*/
|
*/
|
||||||
export class TransformContext {
|
export class TransformContext {
|
||||||
public factory: ts.NodeFactory;
|
public factory: ts.NodeFactory;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public program: ts.Program,
|
public program: ts.Program,
|
||||||
public context: ts.TransformationContext,
|
public context: ts.TransformationContext,
|
||||||
public config: TransformerConfig,
|
public config: TransformerConfig,
|
||||||
) {
|
) {
|
||||||
this.factory = context.factory;
|
this.factory = context.factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms the children of the specified node.
|
* Transforms the children of the specified node.
|
||||||
*/
|
*/
|
||||||
transform<T extends ts.Node>(node: T): T {
|
transform<T extends ts.Node>(node: T): T {
|
||||||
return ts.visitEachChild(node, (node) => visitNode(this, node), this.context);
|
return ts.visitEachChild(node, (node) => visitNode(this, node), this.context);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function visitImportDeclaration(context: TransformContext, node: ts.ImportDeclaration) {
|
|
||||||
const { factory } = context;
|
|
||||||
|
|
||||||
const path = node.moduleSpecifier;
|
|
||||||
const clause = node.importClause;
|
|
||||||
if (!clause) return node;
|
|
||||||
if (!ts.isStringLiteral(path)) return node;
|
|
||||||
if (path.text !== "@rbxts/services") return node;
|
|
||||||
|
|
||||||
const namedBindings = clause.namedBindings;
|
|
||||||
if (!namedBindings) return node;
|
|
||||||
if (!ts.isNamedImports(namedBindings)) return node;
|
|
||||||
|
|
||||||
return [
|
|
||||||
// We replace the import declaration instead of stripping it to prevent
|
|
||||||
// issues with isolated modules.
|
|
||||||
factory.updateImportDeclaration(
|
|
||||||
node,
|
|
||||||
undefined,
|
|
||||||
factory.createImportClause(false, undefined, factory.createNamedImports([])),
|
|
||||||
node.moduleSpecifier,
|
|
||||||
undefined,
|
|
||||||
),
|
|
||||||
|
|
||||||
// Creates a multi-variable statement as shown below.
|
|
||||||
//
|
|
||||||
// const Players = game.GetService("Players"),
|
|
||||||
// Workspace = game.GetService("Workspace");
|
|
||||||
factory.createVariableStatement(
|
|
||||||
undefined,
|
|
||||||
factory.createVariableDeclarationList(
|
|
||||||
namedBindings.elements.map((specifier) => {
|
|
||||||
const serviceName = specifier.propertyName ? specifier.propertyName.text : specifier.name.text;
|
|
||||||
const variableName = specifier.name;
|
|
||||||
|
|
||||||
return factory.createVariableDeclaration(
|
|
||||||
variableName,
|
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
factory.createCallExpression(
|
|
||||||
factory.createPropertyAccessExpression(factory.createIdentifier("game"), "GetService"),
|
|
||||||
undefined,
|
|
||||||
[factory.createStringLiteral(serviceName)],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
ts.NodeFlags.Const,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
function visitStatement(context: TransformContext, node: ts.Statement): ts.Statement | ts.Statement[] {
|
|
||||||
// This is used to transform statements.
|
|
||||||
// TypeScript allows you to return multiple statements here.
|
|
||||||
|
|
||||||
if (ts.isImportDeclaration(node)) {
|
|
||||||
// We have encountered an import declaration,
|
|
||||||
// so we should transform it using a separate function.
|
|
||||||
|
|
||||||
return visitImportDeclaration(context, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
return context.transform(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function visitExpression(context: TransformContext, node: ts.Expression): ts.Expression {
|
function visitExpression(context: TransformContext, node: ts.Expression): ts.Expression {
|
||||||
// This can be used to transform expressions
|
// Check for new expressions (new Part())
|
||||||
// For example, a call expression for macros.
|
if (ts.isNewExpression(node)) {
|
||||||
|
const { expression, arguments: args } = node;
|
||||||
|
|
||||||
|
// Check if it's a simple identifier (e.g., Part, not Something.Part)
|
||||||
|
if (ts.isIdentifier(expression)) {
|
||||||
|
const className = expression.text;
|
||||||
|
|
||||||
|
// Check if it's an Instance-derived class (assuming basic Roblox classes for now)
|
||||||
|
const instanceClasses = [
|
||||||
|
"Part", "Model", "Folder", "Script", "LocalScript", "ModuleScript",
|
||||||
|
"Frame", "TextLabel", "TextButton", "ImageLabel", "ImageButton",
|
||||||
|
"Sound", "Animation", "BoolValue", "StringValue", "NumberValue",
|
||||||
|
// Add more Roblox classes as needed
|
||||||
|
];
|
||||||
|
|
||||||
|
if (instanceClasses.includes(className)) {
|
||||||
|
const { factory } = context;
|
||||||
|
|
||||||
|
// Create new Instance("ClassName") expression
|
||||||
|
return factory.createNewExpression(
|
||||||
|
factory.createIdentifier("Instance"),
|
||||||
|
undefined,
|
||||||
|
[
|
||||||
|
factory.createStringLiteral(className),
|
||||||
|
...(args || [])
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return context.transform(node);
|
// For other expressions, continue traversing
|
||||||
|
return context.transform(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
function visitNode(context: TransformContext, node: ts.Node): ts.Node | ts.Node[] {
|
function visitNode(context: TransformContext, node: ts.Node): ts.Node | ts.Node[] {
|
||||||
if (ts.isStatement(node)) {
|
if (ts.isExpression(node)) {
|
||||||
return visitStatement(context, node);
|
return visitExpression(context, node);
|
||||||
} else if (ts.isExpression(node)) {
|
}
|
||||||
return visitExpression(context, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We encountered a node that we don't handle above,
|
// Continue traversing the AST
|
||||||
// but we should keep iterating the AST in case we find something we want to transform.
|
return context.transform(node);
|
||||||
return context.transform(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default function(program: ts.Program, config: TransformerConfig = { _: undefined }) {
|
||||||
|
return (context: ts.TransformationContext) => {
|
||||||
|
const transformContext = new TransformContext(program, context, config);
|
||||||
|
return (file: ts.SourceFile) => {
|
||||||
|
return ts.visitNode(file, (node) => visitNode(transformContext, node));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/// <reference path="index.d.ts" />
|
||||||
|
|
||||||
|
type hi = CreatableInstancesWithConstructors;
|
||||||
|
new Frame()
|
||||||
|
|
||||||
|
new Part().Name = "hi";
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import * as ts from 'typescript';
|
||||||
|
import transformer from '../src/transformer';
|
||||||
|
|
||||||
|
function transpile(source: string): string {
|
||||||
|
const program = ts.createProgram([], {});
|
||||||
|
const result = ts.transpileModule(source, {
|
||||||
|
compilerOptions: {
|
||||||
|
target: ts.ScriptTarget.ESNext,
|
||||||
|
module: ts.ModuleKind.CommonJS,
|
||||||
|
},
|
||||||
|
transformers: {
|
||||||
|
before: [transformer(program) as ts.TransformerFactory<ts.SourceFile>]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result.outputText;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('rbxts-transformer-instances', () => {
|
||||||
|
test('transforms new Part() to new Instance("Part")', () => {
|
||||||
|
const source = `const part = new Part();`;
|
||||||
|
const result = transpile(source);
|
||||||
|
|
||||||
|
expect(result).toContain('const part = new Instance("Part")');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('transforms new instances with arguments', () => {
|
||||||
|
const source = `const model = new Model("MyModel");`;
|
||||||
|
const result = transpile(source);
|
||||||
|
|
||||||
|
expect(result).toContain('const model = new Instance("Model", "MyModel")');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('preserves non-instance constructors', () => {
|
||||||
|
const source = `const obj = new CustomClass();`;
|
||||||
|
const result = transpile(source);
|
||||||
|
|
||||||
|
expect(result).toContain('const obj = new CustomClass()');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handles multiple constructors in the same file', () => {
|
||||||
|
const source = `
|
||||||
|
const part = new Part();
|
||||||
|
const obj = new CustomClass();
|
||||||
|
const folder = new Folder("MyFolder");
|
||||||
|
`;
|
||||||
|
const result = transpile(source);
|
||||||
|
|
||||||
|
expect(result).toContain('const part = new Instance("Part")');
|
||||||
|
expect(result).toContain('const obj = new CustomClass()');
|
||||||
|
expect(result).toContain('const folder = new Instance("Folder", "MyFolder")');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('transforms instances in complex expressions', () => {
|
||||||
|
const source = `
|
||||||
|
function createParts() {
|
||||||
|
return [new Part(), new Part(), new Model("MyModel")];
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const result = transpile(source);
|
||||||
|
|
||||||
|
expect(result).toContain('return [new Instance("Part"), new Instance("Part"), new Instance("Model", "MyModel")]');
|
||||||
|
});
|
||||||
|
});
|
||||||
+18
-7
@@ -1,16 +1,27 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"allowSyntheticDefaultImports": true,
|
||||||
"module": "commonjs",
|
"downlevelIteration": true,
|
||||||
"outDir": "out",
|
"module": "commonjs",
|
||||||
"rootDir": "src",
|
"moduleResolution": "node",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
"target": "ES5",
|
||||||
"lib": [
|
"lib": [
|
||||||
"ES2015",
|
"ES2015",
|
||||||
"DOM"
|
"DOM"
|
||||||
],
|
],
|
||||||
|
"skipLibCheck": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"skipLibCheck": true,
|
|
||||||
"forceConsistentCasingInFileNames": true
|
"rootDir": "src",
|
||||||
}
|
"outDir": "out",
|
||||||
|
"baseUrl": "src",
|
||||||
|
"tsBuildInfoFile": "out/tsconfig.tsbuildinfo",
|
||||||
|
"declaration": true
|
||||||
|
},
|
||||||
|
"include": ["src/**/*", "index.d.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user