179 lines
6.6 KiB
JavaScript
179 lines
6.6 KiB
JavaScript
/**
|
|
* 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;
|
|
}
|
|
|
|
/**
|
|
* Generate the instance-classes.ts file content
|
|
* @param {string[]} classNames List of creatable instance class names
|
|
* @returns {string} The content for the instance-classes.ts file
|
|
*/
|
|
function generateInstanceClassesFile(classNames) {
|
|
return `/**
|
|
* This file is auto-generated by the generate-instance-classes script.
|
|
* Do not modify manually.
|
|
*/
|
|
|
|
/**
|
|
* Array of all creatable Roblox instance class names
|
|
* Used by the transformer to identify constructor calls
|
|
*/
|
|
export const CREATABLE_INSTANCES = [
|
|
${classNames.map(name => `"${name}"`).join(",\n ")}
|
|
];`;
|
|
}
|
|
|
|
/**
|
|
* Main function
|
|
*/
|
|
function main() {
|
|
const classNames = getCreatableInstanceNames();
|
|
console.log(`Found ${classNames.length} creatable instance types`);
|
|
|
|
// Generate and write declarations file
|
|
const declarationsContent = generateDeclarations(classNames);
|
|
const declarationsPath = path.join(__dirname, '..', 'index.d.ts');
|
|
fs.writeFileSync(declarationsPath, declarationsContent, 'utf-8');
|
|
console.log(`Successfully generated declarations in ${declarationsPath}`);
|
|
|
|
// Generate and write instance-classes.ts
|
|
const instanceClassesContent = generateInstanceClassesFile(classNames);
|
|
const instanceClassesPath = path.join(__dirname, '..', 'src', 'instance-classes.ts');
|
|
fs.writeFileSync(instanceClassesPath, instanceClassesContent, 'utf-8');
|
|
console.log(`Successfully generated instance classes in ${instanceClassesPath}`);
|
|
|
|
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(); |