- ✨ Better interface style Use classes and decorators to define extensions, more concise and elegant
- ⚡ Convenient caching functionality Provides caching functionality to optimize performance (customizable in the interface)
- 🔨 Better development environment Auto-completion of Turbowarp types
- 📦 webpack compression Reduces the size of packaged JS files, improves loading speed and performance
- 🎃 Registration Exception Detection Check for exceptions and intercept reports when registering extensions
- 🎉 Typescript support provides better type checking and auto-completion
- 🍎 ESLint Fix Automatically formats code to maintain a consistent style and specification
- 🎉 Action Auto Build Use action to implement auto-package and add to release, easy to get online
- ⚡ CLI Auto Translation i18n translation via cli without configuration
entrypoint /src/index.ts (javascript same)
- Initial installation of dependencies (yarn pnpm same, pnpm recommended)
npm install
- dev
npm run dev
- eslint fix
npm run lint
- translate
npm run i18n
- build
The js file generated by webpack packaging is located in dist/extension.js
npm run build
TurboWarp Extension Interface Specification More go to TurboWarp Extension Documentation
id
is a string that indicates the unique id used by this extension should contain only characters a-z and 0-9 (the same extension should always use the same id, as changing it will break existing items)name
is a string that tells Scratch what name to display in the sidebarcolor1
is a hex format color that will be set to the extension's square colorblocks
is a list of objects that define which blocks the extension containsopcode
is the internal name of the block, which also corresponds to the method that will be called by default when the block is run *(optionallyfunc
overrides the called method name, deprecated)- opcode should not be changed
blockType
defines the type of the blockreporter
A round block that reports a string or numberBoolean
A block with pointy edges that reports a boolean (true or false)command
A block that doesn't report a valuehat
A block that starts in response to events
- ✨
bind
accepts a function, allowing asynchronous execution to return a Promise - ✨
cache
Cacheenable
whether to turn on cachingexpiration
cache time, in seconds, if 0 then never expires
- ✨
text
is a string that defines the name of the block in the editor in the format [parameter:type]parameters
defines the objects that the building block accepts as parameters, possibly referenced in thedefault
andmenu
fieldsTYPE
defines the input shape to be created (case-insensitive)STRING
string typeNUMBER
for numeric inputBOOLEAN
for boolean input (default values will be ignored)ANGLE
for angleCOLOR
for color type (hex format, e.g. #fff)MATRIX
5x5 matrix (passed in 111101010101... string format)NOTE
is used for music
default
is the initial value of the parameter, accepts a dictionary, the key corresponds to theparameter
, the value corresponds to thedefault
value of the parametermenu
can be added to this parameter if there are parameters to select more than one given value, accepts a dictionary, key corresponds toparameter
, value corresponds to the list type of more than one given value, will generate a drop-down menudisableMonitor
if or not the block forces to remove the checkbox to create a monitor, applicable type is REPORTER (block with return value), if true, then remove the checkbox to the left of the variable
docsURI
corresponds to document link- ✨
debug
whether to open the console debugging (default is false, that is, the plugin itself will not have any output) - ✨
uptime
periodic cache cleaning interval, in seconds, default is 60 seconds - ✨
i18n
i18n translationsource
source language, default is Simplified Chineseaccept
list of target languages, defaults to English and Simplified Chinese
Don't quite get it? Here's an example
import Extension from './include/plugin'
new Extension({
id: "ExampleExtension",
name: "example",
color1: "#0800ff",
blocks: [
{
opcode: 'output',
blockType: 'command',
text: 'command [block:string] [type:string]',
default: { block : "param2", type: "type" },
menu: { block : [ "param1", "param2" ] },
bind: function({ block, type }) {
return `content ${block} type ${type}`;
},
}, {
opcode: 'list',
blockType: 'reporter',
text: 'Get an empty array',
bind: () => [],
disableMonitor: true,
},
]
}).register();
The above creates and registers an extension ExampleExtension, which is displayed in Scratch as example, square color #0800ff, and creates two squares:
The first square output is of type key block and has two parameters:
- The
block
parameter is a drop-down menu of type String, default value is"param2"
, optional values are param1 and param2 - The
type
parameter is an input box, String type, default value is"type"
Bind a method that returncontent {{block}} type {{type}}
Force the checkbox to be removed by settingdisableMonitor
to true
The second square list is of type Blocks with return value, the method returns an empty list
A very simple example:
native turbowarp
class Extension {
public getInfo() {
return {
id: 'FetchExtension',
name: 'fetch',
color1: '#00c4ff',
blocks: [
{
opcode: 'fetchReq',
// @ts-ignore
blockType: Scratch.BlockType.REPORTER,
text: 'fetch [uri] method[method]',
arguments: {
uri: {
// @ts-ignore
type: Scratch.ArgumentType.STRING,
defaultValue: 'https://example.com/',
},
method: {
// @ts-ignore
type: Scratch.ArgumentType.STRING,
defaultValue: 'GET',
},
}
},
],
menus: {
method: [
"GET",
"POST",
"PUT",
"DELETE",
],
},
};
}
fetchReq({ uri, method }): Promise<any> {
return fetch(uri, {
method: method,
});
}
}
// @ts-ignore
Scratch.extensions.register(new Extension());
turbowarp-clipx
import Extension from "./plugin";
new Extension({
id: 'FetchExtension',
name: 'fetch',
color1: '#00c4ff',
blocks: [
{
opcode: 'fetch',
blockType: 'reporter',
text: 'fetch [uri:string] method[method:string]',
default: { uri: "https://example.com/" , method: "GET" },
menu: { method: ["GET", "POST", "PUT", "DELETE" ] },
bind: ({ uri, method }): Promise<any> => fetch(uri, { method, }),
},
]
}).register();
In fact, for documentation size reasons, only a single cube extension example is excerpted here, but what about a cloud database extension? A much larger amount of code, iterating through interfaces and methods...
So with that in mind, this plugin takes a page from Django's routing and passes it through a better interface style, which is only about 30~45% of the native interface code.
Configure TOKEN
as your GitHub Token for the repository key, which will automatically trigger an event package to be sent when the Release is released