@scaffscript/core 0.1.5 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +34 -304
- package/dist/index.cjs +84 -78
- package/dist/index.d.ts +95 -0
- package/package.json +41 -40
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Undervolta
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,329 +1,59 @@
|
|
|
1
1
|
# ScaffScript
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+

|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
> This project is still in early development. The syntax and features are subject to change. Use at your own risk.
|
|
7
|
-
|
|
8
|
-
## Key Features
|
|
9
|
-
|
|
10
|
-
- Unify multiple source files into a single source file.
|
|
11
|
-
- TypeScript-like syntax and module system.
|
|
12
|
-
- Flexible configuration options.
|
|
13
|
-
- Dev-friendly CLI interface.
|
|
14
|
-
- Togglable integration (auto/manual) to your GameMaker project.
|
|
15
|
-
- And more... (WIP)
|
|
16
|
-
|
|
17
|
-
## Installation
|
|
18
|
-
|
|
19
|
-
1. Install [Bun](https://bun.sh) (if not already installed).
|
|
20
|
-
2. Clone this repository.
|
|
21
|
-
3. Install dependencies:
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
bun install
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
4. CLI usage:
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
scaff <command> [args]
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Usage
|
|
34
|
-
|
|
35
|
-
Use `*.ss` files to mark a file as a Scaff file. Normal `*.gml` files are still supported, but they are not processed by Scaff.
|
|
36
|
-
|
|
37
|
-
### Export Module
|
|
38
|
-
|
|
39
|
-
1. Use `export` statement to export types (a variable, function, class, interface, type, enum, or arrow function) from a Scaff file.
|
|
40
|
-
|
|
41
|
-
```js
|
|
42
|
-
// my_file.ss
|
|
43
|
-
|
|
44
|
-
export var my_var = 1;
|
|
45
|
-
export let my_let = 2; // `let` will be removed, so it'll become an instance variable
|
|
46
|
-
export const MY_CONST = "Hello, World!"; // `const` will be converted to `#macro`
|
|
47
|
-
|
|
48
|
-
export function my_func() {
|
|
49
|
-
show_debug_message("Hello, World!");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// arrow functions will be converted to function expression or method
|
|
53
|
-
export const my_method = (name: string, age: number) => {
|
|
54
|
-
show_debug_message(`Hello, ${name}! You are ${age} years old.`);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export enum MY_ENUM {
|
|
58
|
-
A,
|
|
59
|
-
B,
|
|
60
|
-
C
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// classes will be converted to struct constructor
|
|
64
|
-
export class MyClass {
|
|
65
|
-
constructor(name: string, age: number)
|
|
66
|
-
|
|
67
|
-
name: string = "";
|
|
68
|
-
age: number = 0;
|
|
69
|
-
|
|
70
|
-
show_name() {
|
|
71
|
-
show_debug_message(this.name);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// interfaces and types will be converted to struct
|
|
76
|
-
export interface MyInterface {
|
|
77
|
-
name: string;
|
|
78
|
-
age: number = 0; // default value is allowed, which not allowed in TypeScript
|
|
79
|
-
isActive?: boolean; // optional property is allowed
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// interfaces can be extended
|
|
83
|
-
export interface MyExtInterface extends MyInterface {
|
|
84
|
-
address: string;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export type MyType = {
|
|
88
|
-
name: string = ""; // default value is allowed, which not allowed in TypeScript
|
|
89
|
-
age: number;
|
|
90
|
-
isActive?: boolean; // optional property is allowed
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// types intersection is allowed
|
|
94
|
-
export type MyIntersectedType = MyType & {
|
|
95
|
-
address: string;
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
You can do a barrel export (`export * from "<path>"`) as well, so that you can import modules from the parent directory:
|
|
100
|
-
|
|
101
|
-
```js
|
|
102
|
-
// index.ss
|
|
103
|
-
|
|
104
|
-
export * from "my_file"; // export all types from "my_file"
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
2. Use `impl` statement to add implementation to a class.
|
|
108
|
-
|
|
109
|
-
```js
|
|
110
|
-
// my_file.ss
|
|
111
|
-
|
|
112
|
-
export class MyClass {
|
|
113
|
-
constructor(name: string, age?: number)
|
|
5
|
+
A minimal superset language of **GameMaker Language** (GML) for creating module-based GameMaker source codes. This minimal language is mainly used for developing GML libraries, but can also be used for other purposes.
|
|
114
6
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
impl MyClass {
|
|
120
|
-
show_age() {
|
|
121
|
-
show_debug_message(age);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
You can split the implementation into multiple files as well:
|
|
127
|
-
|
|
128
|
-
```js
|
|
129
|
-
// set.ss
|
|
130
|
-
|
|
131
|
-
impl MyClass {
|
|
132
|
-
set_age(age: number) {
|
|
133
|
-
age = age;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// static method
|
|
137
|
-
static static_method = (name: string) => {
|
|
138
|
-
show_debug_message($"Hello, {name}!");
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### Import Module
|
|
144
|
-
|
|
145
|
-
1. Use `include` statement to import a module from another Scaff file, and replace the import statement with the actual content of the exported types.
|
|
146
|
-
|
|
147
|
-
```js
|
|
148
|
-
// my_other_file.ss
|
|
149
|
-
|
|
150
|
-
include { my_var, my_func, MyClass } from "my_file"
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* The generated source code will replace the include statement with the actual content of the exported types.
|
|
154
|
-
*
|
|
155
|
-
* For example, the above include statement will be replaced with:
|
|
156
|
-
|
|
157
|
-
var my_var = 1;
|
|
158
|
-
function my_func() {
|
|
159
|
-
show_debug_message("Hello, World!");
|
|
160
|
-
}
|
|
161
|
-
function MyClass(name, age) constructor {
|
|
162
|
-
// ...
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
*/
|
|
166
|
-
|
|
167
|
-
// non-included lines will be left as is
|
|
168
|
-
show_debug_message("This line will be left as is.");
|
|
169
|
-
|
|
170
|
-
// you can include multiple modules in a single file
|
|
171
|
-
include my_enum from "my_file"
|
|
172
|
-
/**
|
|
173
|
-
enum MY_ENUM {
|
|
174
|
-
A,
|
|
175
|
-
B,
|
|
176
|
-
C
|
|
177
|
-
}
|
|
178
|
-
*/
|
|
179
|
-
|
|
180
|
-
// you can include normal GML files as well
|
|
181
|
-
include { "some_script.gml", "another_gml" } from "./scripts"
|
|
182
|
-
// must be in curly braces and double quotes, the order of the files will be preserved, the `.gml` extension is optional
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
2. Use `import` statement to import a module from another Scaff file, and then use `@<keyword>` statements to load and replace the content of a Scaff file to certain places in the code.
|
|
186
|
-
|
|
187
|
-
| Keyword | Description | Example |
|
|
188
|
-
| --- | --- | --- |
|
|
189
|
-
| `@content` | Replace the statement with the actual content of the exported type. | `@content my_var` -> `var my_var = 1;` |
|
|
190
|
-
| `@nameof` | Replace the statement with the **name** of the exported type. | `@nameof my_var` -> `"my_var"` |
|
|
191
|
-
| `@valueof` or `@:` | Replace the statement with the **value** of the exported type. | `@valueof my_var` -> `1`, `@:my_var` -> `1` |
|
|
192
|
-
| `@typeof` | Replace the statement with the **type** of the exported type. | `@typeof my_var` -> `"number"` |
|
|
193
|
-
| `@use` | Replace the statement with the object shape of the exported type. Only works with `interface` or `type`. | `var obj = @use MyInterface { name: "John" }` -> `var obj = { name: "John", age: 0, isActive: false };` |
|
|
194
|
-
|
|
195
|
-
```js
|
|
196
|
-
// my_import.ss
|
|
197
|
-
|
|
198
|
-
import { my_var } from "my_file"
|
|
199
|
-
|
|
200
|
-
show_debug_message(@valueof my_var); // 1
|
|
201
|
-
show_debug_message(@:my_var); // 1
|
|
202
|
-
show_debug_message(@typeof my_var); // "number"
|
|
203
|
-
show_debug_message(@nameof my_var); // "my_var"
|
|
204
|
-
show_debug_message(@content my_var); // var my_var = 1;
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
```js
|
|
208
|
-
// my_other_file.ss
|
|
209
|
-
|
|
210
|
-
import * from "my_file"
|
|
211
|
-
|
|
212
|
-
my_method = function() {
|
|
213
|
-
@content my_var; // replace with `var my_var = 1;`
|
|
214
|
-
var hello = @valueof MY_CONST; // replace with `var hello = "Hello, World!";`
|
|
215
|
-
var obj = @use MyInterface { // replace with `var obj = { name: "John", age: 0, isActive: false };`
|
|
216
|
-
name: "John"
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
show_debug_message(my_var); // 1
|
|
220
|
-
show_debug_message(obj.name); // John
|
|
221
|
-
|
|
222
|
-
var inst = new MyClass("John", 20);
|
|
223
|
-
inst.show_age(); // 20
|
|
224
|
-
}
|
|
225
|
-
```
|
|
7
|
+
> [!CAUTION]
|
|
8
|
+
> ScaffScript is **not** affiliated with or endorsed by YoYo Games Ltd. GameMaker and GML are trademarks of YoYo Games Ltd.
|
|
226
9
|
|
|
227
10
|
> [!WARNING]
|
|
228
|
-
>
|
|
229
|
-
|
|
230
|
-
| Keyword | Description | Example |
|
|
231
|
-
| --- | --- | --- |
|
|
232
|
-
| `@now` | Replace the statement with the current timestamp in ISO 8601 format. | `var now = "@now";` -> `var now = "2021-01-01T00:00:00.000Z";` |
|
|
233
|
-
| `@today` | Replace the statement with the current date in ISO 8601 format. | `var today = "@today";` -> `var today = "2021-01-01";` |
|
|
234
|
-
| `@version` | Replace the statement with the current version of Scaff. | `var version = "@version";` -> `var version = "0.1.0";` |
|
|
235
|
-
| `@file` | Replace the statement with the current file name. | `var file = "@file";` -> `var file = "my_file";` |
|
|
236
|
-
| `@line` | Replace the statement with the current line number. | `var line = @line;` -> `var line = 1;` |
|
|
237
|
-
| `@counter` | Replace the statement with an increasing number. | `var counter = @counter;` -> `var counter = 1;`, `var counter = @counter;` -> `var counter = 2;`, etc. |
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
### GameMaker Integration
|
|
241
|
-
|
|
242
|
-
Use `intg` statement to mark this file as an integration target, and `#[<name_or_event>]` statement to mark a block of code as a write target. The content of the file will be written to the actual GameMaker project.
|
|
243
|
-
|
|
244
|
-
```js
|
|
245
|
-
// my_file.ss
|
|
246
|
-
|
|
247
|
-
intg { main, some_mod } to "./scripts/my_script" // integrate to `scripts/my_script/my_script.gml`
|
|
11
|
+
> This project is still in early development. The syntax and features are subject to change. Use at your own risk.
|
|
248
12
|
|
|
249
|
-
|
|
250
|
-
show_debug_message("Hello, from my_script!");
|
|
13
|
+
---
|
|
251
14
|
|
|
252
|
-
|
|
253
|
-
show_debug_message("Hello, from my_script (some_mod)!");
|
|
15
|
+
## Key Features
|
|
254
16
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
17
|
+
- **TypeScript-like Module System**. Use `export`, `import`, and `include` to organize code across `.ss` files, fully resolved at compile-time.
|
|
18
|
+
- **Class Syntax**. Define classes with constructors, properties, and methods that compile to GML struct constructors. Extend classes across files with `impl`.
|
|
19
|
+
- **Content Directives**. Inline compiled GML content (`@content`, `@valueof`, `@:`, etc.) directives for dynamic code insertion.
|
|
20
|
+
- **Special Values**. Access compile-time tokens like `@now`, `@today`, `@version`, `@file`, and `@line` for metadata and debugging.
|
|
21
|
+
- **Code Generation Blocks**. Use `#[blockName]` to define named content sections and `intg` to map them to GameMaker asset paths.
|
|
22
|
+
- **GameMaker Integration**. Automatically writes `.gml` files, generates `.yy` metadata, and updates your `.yyp` project file for scripts and objects.
|
|
23
|
+
- **File Scanning & Processing**. Recursive scanning of `.ss` and `.gml` files with dependency-aware processing order.
|
|
258
24
|
|
|
259
|
-
|
|
260
|
-
// my_other_file.ss
|
|
25
|
+
---
|
|
261
26
|
|
|
262
|
-
|
|
263
|
-
intg { Step, keydown:keyboard_d } to "objects/my_other_object"
|
|
27
|
+
## Installation & Documentation
|
|
264
28
|
|
|
265
|
-
|
|
266
|
-
#[main as create] // integrate to `objects/my_object/Create_0.gml`
|
|
267
|
-
show_debug_message("Hello, from my_object create event!");
|
|
29
|
+
For more information, please refer to the official [documentation](https://scaffscript.lefinitas.com).
|
|
268
30
|
|
|
269
|
-
|
|
270
|
-
#[StepEvent] // <event_name>Event is also supported
|
|
271
|
-
show_debug_message("Hello, from my_object step event!");
|
|
31
|
+
---
|
|
272
32
|
|
|
273
|
-
|
|
274
|
-
#[key as KeyPress:KEYBOARD_ENTER] // use `:` to specify the event number KEYBOARD_ENTER in this case)
|
|
275
|
-
show_debug_message("Hello, from my_object keypress - enter event!");
|
|
33
|
+
## Questions & Feature Requests
|
|
276
34
|
|
|
277
|
-
|
|
278
|
-
#[keydown:keyboard_d event] // the `event`, event type, and event number are case insensitive, add `event` suffix to mark as event (like in method 2 example)
|
|
279
|
-
show_debug_message("Hello, from my_object keydown - d event!");
|
|
280
|
-
```
|
|
35
|
+
Feel free to start a [discussion](https://github.com/undervolta/scaffscript/discussions) or open an [issue](https://github.com/undervolta/scaffscript/issues) for any questions or feature requests.
|
|
281
36
|
|
|
282
|
-
|
|
283
|
-
> If you're using method 2 or 4, the `event` keyword is required to mark the block as an event.
|
|
284
|
-
> The `event` keyword will be omitted in the block name, so `#[StepEvent]` will become `Step` in the integration block (example: `intg { Step } to "objects/my_object"`, notice no `Event` suffix).
|
|
285
|
-
> If you're creating (not modifying) a new **collision** event, you need to specify the name of the other object (case sensitive, exact name of the object in the IDE, such as `obj_player`). And you need to reopen the IDE if you're creating a new collision event using Scaff integration.
|
|
37
|
+
---
|
|
286
38
|
|
|
287
|
-
|
|
39
|
+
## Contributing
|
|
288
40
|
|
|
289
|
-
|
|
41
|
+
Contributions are welcome! Please open an issue or submit a pull request.
|
|
290
42
|
|
|
291
|
-
|
|
292
|
-
|
|
43
|
+
1. Fork the [repository](https://github.com/undervolta/scaffscript).
|
|
44
|
+
2. Clone the forked repository to your local machine.
|
|
45
|
+
3. Make and test your changes.
|
|
46
|
+
4. Commit your changes and push it to your forked repository.
|
|
47
|
+
5. Open a pull request to the main repository.
|
|
293
48
|
|
|
294
|
-
|
|
295
|
-
// ...
|
|
296
|
-
};
|
|
297
|
-
```
|
|
49
|
+
---
|
|
298
50
|
|
|
299
|
-
|
|
300
|
-
// scaff.config.mjs
|
|
51
|
+
## Support
|
|
301
52
|
|
|
302
|
-
|
|
303
|
-
// ...
|
|
304
|
-
};
|
|
305
|
-
```
|
|
53
|
+
If you like this project, or this project helped you in any way, please consider supporting me on [Ko-fi](https://ko-fi.com/undervolta) or [Trakteer](https://trakteer.id/undervolta). Don't forget to leave a star! Your support is greatly appreciated!
|
|
306
54
|
|
|
307
|
-
|
|
308
|
-
// scaff.config.cjs
|
|
55
|
+
---
|
|
309
56
|
|
|
310
|
-
|
|
311
|
-
// ...
|
|
312
|
-
};
|
|
313
|
-
```
|
|
57
|
+
## License
|
|
314
58
|
|
|
315
|
-
|
|
316
|
-
| --- | --- | --- | --- |
|
|
317
|
-
| `acceptAllIntegrations` | `boolean` | `false` | Accept all generated files to be integrated without manual confirmation. |
|
|
318
|
-
| `clearOutputDir` | `boolean` | `false` | Clear the output directory before generating source code. |
|
|
319
|
-
| `counterStart` | `number` | `1` | Starting value for the counter special value. |
|
|
320
|
-
| `debugLevel` | `0 \| 1 \| 2` | `0` | Debug level. `0` = no debug, `1` = basic debug, `2` = verbose debug. |
|
|
321
|
-
| `integrationOption` | `ScaffIntegrationOptions` | `{}` | Integration options. |
|
|
322
|
-
| `noBackup` | `boolean` | `false` | Don't backup the original files before integration. |
|
|
323
|
-
| `noIntegration` | `boolean` | `false` | Don't integrate the files to GM project. |
|
|
324
|
-
| `onNotFound` | `"error" \| "ignore"` | `"error"` | What to do when something is not found. |
|
|
325
|
-
| `path` | `Record<string, string>` | `{}` | Path aliases. |
|
|
326
|
-
| `production` | `boolean` | `false` | Whether the script is running in production mode. |
|
|
327
|
-
| `tabType` | `"1t" \| "2s" \| "4s"` | `"1t"` | Tab type to use when generating source code. |
|
|
328
|
-
| `targetPlatform` | `ScaffIntegrationTargetPlatform` | `"all"` | Target platform for the generated code. |
|
|
329
|
-
| `useGmAssetPath` | `boolean` | `false` | Whether to use GM asset path when integrating files. |
|
|
59
|
+
ScaffScript is **free** and **open-source**. It's licensed under the [MIT License](./LICENSE).
|
package/dist/index.cjs
CHANGED
|
@@ -110,17 +110,7 @@ async function parseArgs(...args) {
|
|
|
110
110
|
switch (cmd) {
|
|
111
111
|
case "gen":
|
|
112
112
|
case "generate":
|
|
113
|
-
const
|
|
114
|
-
if (!path3) {
|
|
115
|
-
log.error("No source path specified. Please specify a valid source path. Aborting...");
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
const target = args[2];
|
|
119
|
-
if (target !== "to") {
|
|
120
|
-
log.error(`Invalid target: \x1B[33m${target}\x1B[0m. Please replace it with \x1B[32mto\x1B[0m after the source path argument. Aborting...`);
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
const yypPath = args[3];
|
|
113
|
+
const yypPath = args[1];
|
|
124
114
|
if (!yypPath) {
|
|
125
115
|
log.error("No project path specified. Please specify a valid project path. Aborting...");
|
|
126
116
|
return null;
|
|
@@ -128,6 +118,15 @@ async function parseArgs(...args) {
|
|
|
128
118
|
log.error(`Invalid project path: \x1B[33m${yypPath}\x1B[0m. Please specify a valid \x1B[32m.yyp\x1B[0m file. Aborting...`);
|
|
129
119
|
return null;
|
|
130
120
|
}
|
|
121
|
+
const optionList = [...args].slice(2);
|
|
122
|
+
const options = {
|
|
123
|
+
integrate: optionList.includes("-i") || optionList.includes("--integrate"),
|
|
124
|
+
noIntegration: optionList.includes("-!i") || optionList.includes("--no-integration")
|
|
125
|
+
};
|
|
126
|
+
if (options.integrate && options.noIntegration) {
|
|
127
|
+
log.error("Cannot specify both \x1B[33m--integrate\x1B[0m and \x1B[33m--no-integrate\x1B[0m. Aborting...");
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
131
130
|
const exists = await fileExists(normalizePath(resolvePath(yypPath)));
|
|
132
131
|
if (!exists) {
|
|
133
132
|
log.error(`Project path \x1B[33m${yypPath}\x1B[0m not found. Aborting...`);
|
|
@@ -135,7 +134,7 @@ async function parseArgs(...args) {
|
|
|
135
134
|
}
|
|
136
135
|
return {
|
|
137
136
|
cmd: "generate",
|
|
138
|
-
|
|
137
|
+
options,
|
|
139
138
|
projectPath: normalizePath(resolvePath(yypPath))
|
|
140
139
|
};
|
|
141
140
|
case "help":
|
|
@@ -146,39 +145,15 @@ async function parseArgs(...args) {
|
|
|
146
145
|
console.log(`\x1B[34m[args]\x1B[0m: Optional arguments.`);
|
|
147
146
|
console.log("");
|
|
148
147
|
console.log("Commands:");
|
|
149
|
-
console.log("
|
|
150
|
-
console.log("
|
|
151
|
-
console.log("
|
|
152
|
-
console.log("
|
|
153
|
-
console.log("
|
|
154
|
-
console.log(" --git Initialize a new Git repository");
|
|
155
|
-
console.log(" --new Create a new GameMaker project");
|
|
148
|
+
console.log(" generate <source_path> <project_path> Generate source code from the given path to the given project");
|
|
149
|
+
console.log(" aliases: gen");
|
|
150
|
+
console.log(" example: generate ./src ./my-game.yyp");
|
|
151
|
+
console.log(" help Show this help message");
|
|
152
|
+
console.log(" aliases: -h, --help");
|
|
156
153
|
console.log("");
|
|
157
154
|
return {
|
|
158
155
|
cmd: "help"
|
|
159
156
|
};
|
|
160
|
-
case "init":
|
|
161
|
-
const targetPath = args[1];
|
|
162
|
-
const options = [...args];
|
|
163
|
-
options.shift();
|
|
164
|
-
const template = options.find((opt) => opt.startsWith("--template") || opt.startsWith("-t"))?.split("=")[1] ?? "npm";
|
|
165
|
-
const initGit = options.includes("--git");
|
|
166
|
-
const isNew = options.includes("--new");
|
|
167
|
-
if (!targetPath) {
|
|
168
|
-
log.error("No path specified. Please specify a valid path. Aborting...");
|
|
169
|
-
return null;
|
|
170
|
-
}
|
|
171
|
-
if (!["bun", "pnpm", "npm"].includes(template)) {
|
|
172
|
-
log.error(`Invalid template: \x1B[33m${template}\x1B[0m. Please specify a valid template (\x1B[32mbun\x1B[0m or \x1B[32mnode\x1B[0m). Aborting...`);
|
|
173
|
-
return null;
|
|
174
|
-
}
|
|
175
|
-
return {
|
|
176
|
-
cmd: "init",
|
|
177
|
-
targetPath,
|
|
178
|
-
template,
|
|
179
|
-
initGit,
|
|
180
|
-
isNew
|
|
181
|
-
};
|
|
182
157
|
default:
|
|
183
158
|
log.error(`Invalid command: \x1B[33m${cmd}\x1B[0m. Aborting...`);
|
|
184
159
|
return null;
|
|
@@ -324,10 +299,11 @@ async function getScaffConfig() {
|
|
|
324
299
|
debugLevel: conf.debugLevel ?? 0,
|
|
325
300
|
integrationOption: conf.integrationOption ?? {},
|
|
326
301
|
noBackup: conf.noBackup ?? false,
|
|
327
|
-
noIntegration: conf.noIntegration ??
|
|
302
|
+
noIntegration: conf.noIntegration ?? true,
|
|
328
303
|
onNotFound: conf.onNotFound ?? "error",
|
|
329
304
|
path: conf.path ?? {},
|
|
330
305
|
production: conf.production ?? false,
|
|
306
|
+
source: conf.source ?? "./src",
|
|
331
307
|
tabType: conf.tabType ?? "1t",
|
|
332
308
|
targetPlatform: conf.targetPlatform ?? "all",
|
|
333
309
|
useGmAssetPath: conf.useGmAssetPath ?? false
|
|
@@ -363,30 +339,45 @@ function getTabLevels(str, tabType) {
|
|
|
363
339
|
}
|
|
364
340
|
// package.json
|
|
365
341
|
var package_default = {
|
|
366
|
-
name: "scaffscript",
|
|
367
|
-
version: "0.1.
|
|
368
|
-
|
|
342
|
+
name: "@scaffscript/core",
|
|
343
|
+
version: "0.1.6",
|
|
344
|
+
repository: {
|
|
345
|
+
type: "git",
|
|
346
|
+
url: "https://github.com/undervolta/scaffscript"
|
|
347
|
+
},
|
|
369
348
|
main: "dist/index.cjs",
|
|
349
|
+
devDependencies: {
|
|
350
|
+
"@types/bun": "latest"
|
|
351
|
+
},
|
|
352
|
+
peerDependencies: {
|
|
353
|
+
typescript: "^5"
|
|
354
|
+
},
|
|
370
355
|
bin: {
|
|
371
356
|
scaff: "./dist/index.cjs"
|
|
372
357
|
},
|
|
373
|
-
|
|
374
|
-
files: [
|
|
358
|
+
description: "A minimal superset language of GML with TypeScript-like module system",
|
|
359
|
+
files: [
|
|
360
|
+
"dist"
|
|
361
|
+
],
|
|
362
|
+
keywords: [
|
|
363
|
+
"gamemaker",
|
|
364
|
+
"gml",
|
|
365
|
+
"scaff",
|
|
366
|
+
"script",
|
|
367
|
+
"superset",
|
|
368
|
+
"module",
|
|
369
|
+
"cli"
|
|
370
|
+
],
|
|
371
|
+
license: "MIT",
|
|
375
372
|
scripts: {
|
|
376
|
-
build: "bun run build:
|
|
373
|
+
build: "bun run build:all",
|
|
377
374
|
"build:node": "bun build src/index-node.ts --outfile dist/index.cjs --target node --format cjs",
|
|
378
|
-
"build:bun": "bun build src/index-bun.ts --outfile
|
|
375
|
+
"build:bun": "bun build src/index-bun.ts --outfile build/index.mjs --target bun --format esm",
|
|
379
376
|
"build:all": "bun run build:node && bun run build:bun",
|
|
380
|
-
dev: "bun run src/index-node.ts"
|
|
381
|
-
|
|
382
|
-
keywords: ["gamemaker", "gml", "scaff", "script", "superset", "module", "cli"],
|
|
383
|
-
license: "MIT",
|
|
384
|
-
devDependencies: {
|
|
385
|
-
"@types/bun": "latest"
|
|
377
|
+
dev: "bun run src/index-node.ts",
|
|
378
|
+
prelink: "bun run build"
|
|
386
379
|
},
|
|
387
|
-
|
|
388
|
-
typescript: "^5"
|
|
389
|
-
}
|
|
380
|
+
type: "module"
|
|
390
381
|
};
|
|
391
382
|
|
|
392
383
|
// src/parser/special-value.ts
|
|
@@ -456,6 +447,7 @@ async function readAndSplitFiles(files, config) {
|
|
|
456
447
|
continue;
|
|
457
448
|
}
|
|
458
449
|
const matchExport = [...file.content.matchAll(modControlRegex)];
|
|
450
|
+
implRegex.lastIndex = 0;
|
|
459
451
|
if (matchExport.length)
|
|
460
452
|
exports2.push({ file, depth: file.path.split("/").filter(Boolean).length });
|
|
461
453
|
else if (implRegex.test(file.content))
|
|
@@ -470,6 +462,7 @@ async function readAndSplitFiles(files, config) {
|
|
|
470
462
|
exports2.sort((a, b) => b.depth - a.depth);
|
|
471
463
|
indexes.sort((a, b) => b.depth - a.depth);
|
|
472
464
|
for (const fileHandle of exports2) {
|
|
465
|
+
implRegex.lastIndex = 0;
|
|
473
466
|
if (implRegex.test(fileHandle.file.content))
|
|
474
467
|
implFiles.push(fileHandle.file);
|
|
475
468
|
else if (fileHandle.file.isScaff && fileHandle.file.toGenerate)
|
|
@@ -478,6 +471,7 @@ async function readAndSplitFiles(files, config) {
|
|
|
478
471
|
res.scaff.push(fileHandle.file);
|
|
479
472
|
}
|
|
480
473
|
for (const fileHandle of indexes) {
|
|
474
|
+
implRegex.lastIndex = 0;
|
|
481
475
|
if (implRegex.test(fileHandle.file.content))
|
|
482
476
|
implFiles.push(fileHandle.file);
|
|
483
477
|
else if (fileHandle.file.isScaff && fileHandle.file.toGenerate)
|
|
@@ -846,14 +840,14 @@ ${insertTabs(1, config.tabType)}${classBody}
|
|
|
846
840
|
const parsedStr = `${name} = function(${params.combined.join(", ")}) ${arrowBlock}`;
|
|
847
841
|
if (!module2[filePath])
|
|
848
842
|
module2[filePath] = {};
|
|
849
|
-
module2[filePath][name] = { name, value: arrowBlock.slice(1, -1), type: "
|
|
843
|
+
module2[filePath][name] = { name, value: arrowBlock.slice(1, -1), type: "arrow-fn", parsedStr };
|
|
850
844
|
} else {
|
|
851
845
|
const params = parseFnParams(valuePart);
|
|
852
846
|
const body = valuePart.split("=>")[1].trim();
|
|
853
847
|
const parsedStr = `${name} = function(${params.combined.join(", ")}) { return ${body}; }`;
|
|
854
848
|
if (!module2[filePath])
|
|
855
849
|
module2[filePath] = {};
|
|
856
|
-
module2[filePath][name] = { name, value: body, type: "
|
|
850
|
+
module2[filePath][name] = { name, value: body, type: "arrow-fn", parsedStr };
|
|
857
851
|
}
|
|
858
852
|
} else if (valuePart.startsWith("function")) {
|
|
859
853
|
if (valuePart.trim().endsWith("{")) {
|
|
@@ -894,7 +888,7 @@ ${insertTabs(1, config.tabType)}${classBody}
|
|
|
894
888
|
if (!module2[filePath])
|
|
895
889
|
module2[filePath] = {};
|
|
896
890
|
const parsedStr = varType !== "const" ? `${varType === "let" ? "" : "var "}${name} = ${valuePart};` : `#macro ${name} ${valuePart}`;
|
|
897
|
-
module2[filePath][name] = { name, value: valuePart, type:
|
|
891
|
+
module2[filePath][name] = { name, value: valuePart, type: varType === "const" ? "constant" : "variable", parsedStr };
|
|
898
892
|
}
|
|
899
893
|
}
|
|
900
894
|
}
|
|
@@ -991,7 +985,7 @@ function implementClass(module2, fileGroup, config) {
|
|
|
991
985
|
if (file.childs.length > 0)
|
|
992
986
|
file.childs.forEach((child) => toImpl.push({ parent: file, file: child }));
|
|
993
987
|
}
|
|
994
|
-
for (const fileImpl of toImpl) {
|
|
988
|
+
for (const [idx, fileImpl] of toImpl.entries()) {
|
|
995
989
|
const filePath = fileImpl.parent.isIndex ? fileImpl.parent.path : `${fileImpl.parent.path}/${fileImpl.parent.name}`;
|
|
996
990
|
const match = parseHeader(fileImpl.file.content);
|
|
997
991
|
for (const m of match) {
|
|
@@ -1002,9 +996,11 @@ function implementClass(module2, fileGroup, config) {
|
|
|
1002
996
|
if (!className || !body)
|
|
1003
997
|
continue;
|
|
1004
998
|
module2[filePath][className].parsedStr = module2[filePath][className].parsedStr.slice(0, -1) + `${body.replace(`
|
|
1005
|
-
`, "")}
|
|
999
|
+
`, "")}` + (idx < toImpl.length - 1 ? `
|
|
1000
|
+
|
|
1001
|
+
` : `
|
|
1006
1002
|
}
|
|
1007
|
-
|
|
1003
|
+
`);
|
|
1008
1004
|
}
|
|
1009
1005
|
}
|
|
1010
1006
|
return true;
|
|
@@ -1588,6 +1584,7 @@ function getEventFile(eventInput, numInput) {
|
|
|
1588
1584
|
dynNum = true;
|
|
1589
1585
|
break;
|
|
1590
1586
|
case "keydown":
|
|
1587
|
+
case "key_down":
|
|
1591
1588
|
case "keyboard":
|
|
1592
1589
|
event = 5 /* KEY_DOWN */;
|
|
1593
1590
|
break;
|
|
@@ -1595,18 +1592,22 @@ function getEventFile(eventInput, numInput) {
|
|
|
1595
1592
|
event = 6 /* MOUSE */;
|
|
1596
1593
|
break;
|
|
1597
1594
|
case "other":
|
|
1595
|
+
case "async":
|
|
1598
1596
|
event = 7 /* OTHER */;
|
|
1599
1597
|
break;
|
|
1600
1598
|
case "draw":
|
|
1601
1599
|
event = 8 /* DRAW */;
|
|
1602
1600
|
break;
|
|
1603
1601
|
case "keypress":
|
|
1602
|
+
case "key_press":
|
|
1604
1603
|
event = 9 /* KEY_PRESS */;
|
|
1605
1604
|
break;
|
|
1606
1605
|
case "keyrelease":
|
|
1606
|
+
case "key_release":
|
|
1607
1607
|
event = 10 /* KEY_RELEASE */;
|
|
1608
1608
|
break;
|
|
1609
1609
|
case "cleanup":
|
|
1610
|
+
case "clean_up":
|
|
1610
1611
|
event = 12 /* CLEAN_UP */;
|
|
1611
1612
|
break;
|
|
1612
1613
|
case "gesture":
|
|
@@ -1943,7 +1944,7 @@ function createYYScript(projectYyp, rescName, dir, options) {
|
|
|
1943
1944
|
"name":"${rescName}",
|
|
1944
1945
|
"parent":{
|
|
1945
1946
|
"name":"${dir !== "" ? dirSplit.pop() : projectYyp.replace(".yyp", "")}",
|
|
1946
|
-
"path":"${dir !== "" ? `folders/${dir}.yy` : projectYyp}",
|
|
1947
|
+
"path":"${dir !== "" ? `folders/${dir}.yy` : `${projectYyp}.yyp`}",
|
|
1947
1948
|
},
|
|
1948
1949
|
"resourceType":"GMScript",
|
|
1949
1950
|
"resourceVersion":"2.0",
|
|
@@ -1964,7 +1965,7 @@ function createYYObject(projectYyp, rescName, dir, eventList, options) {
|
|
|
1964
1965
|
"overriddenProperties":[],
|
|
1965
1966
|
"parent":{
|
|
1966
1967
|
"name":"${dir !== "" ? dirSplit.pop() : projectYyp.replace(".yyp", "")}",
|
|
1967
|
-
"path":"${dir !== "" ? `folders/${dir}.yy` : projectYyp}",
|
|
1968
|
+
"path":"${dir !== "" ? `folders/${dir}.yy` : `${projectYyp}.yyp`}",
|
|
1968
1969
|
},
|
|
1969
1970
|
"parentObjectId":null,
|
|
1970
1971
|
"persistent":false,
|
|
@@ -2105,9 +2106,9 @@ async function modifyYyProject(type, projectPath, resource = null, folder = null
|
|
|
2105
2106
|
if (type === "add") {
|
|
2106
2107
|
let addedFolderCnt = 0;
|
|
2107
2108
|
if (toAddFolders) {
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
const existsFolders = rawLines.slice(folderStartIdx + 1, folderEndIdx);
|
|
2109
|
+
let folderStartIdx = rawLines.findIndex((line) => line.includes("Folders"));
|
|
2110
|
+
let folderEndIdx = rawLines.findIndex((line, idx) => idx >= folderStartIdx && line.includes("]"));
|
|
2111
|
+
const existsFolders = folderEndIdx > folderStartIdx ? rawLines.slice(folderStartIdx + 1, folderEndIdx) : [];
|
|
2111
2112
|
for (const folderDir of toAddFolders) {
|
|
2112
2113
|
const folderSplit = folderDir.split("/");
|
|
2113
2114
|
for (let i = 0;i < folderSplit.length; i++) {
|
|
@@ -2118,6 +2119,11 @@ async function modifyYyProject(type, projectPath, resource = null, folder = null
|
|
|
2118
2119
|
name = name.slice(0, -1);
|
|
2119
2120
|
const dupe = existsFolders.find((line) => line.includes(`"%Name":"${name}"`));
|
|
2120
2121
|
if (!dupe) {
|
|
2122
|
+
if (!existsFolders.length) {
|
|
2123
|
+
rawLines[folderStartIdx] = ' "Folders":[';
|
|
2124
|
+
rawLines.splice(folderStartIdx + 1, 0, " ],");
|
|
2125
|
+
folderEndIdx = folderStartIdx + 1;
|
|
2126
|
+
}
|
|
2121
2127
|
rawLines.splice(folderEndIdx + addedFolderCnt, 0, createGMFolderStr(name));
|
|
2122
2128
|
addedFolderCnt++;
|
|
2123
2129
|
}
|
|
@@ -2191,7 +2197,8 @@ async function integrateSourceCodes(genFile, config, projectPath) {
|
|
|
2191
2197
|
log.debug(`File \x1B[32m${relPath}\x1B[0m not found. Creating new resource...`);
|
|
2192
2198
|
const { type, name } = await createGMResource(gmProject, path3, data, config.integrationOption);
|
|
2193
2199
|
if (type && name) {
|
|
2194
|
-
|
|
2200
|
+
if (data.dirPath !== "")
|
|
2201
|
+
newFolders.push(data.dirPath);
|
|
2195
2202
|
newResources.push(createGMResourceStr(type, name));
|
|
2196
2203
|
data.isNew = true;
|
|
2197
2204
|
}
|
|
@@ -2210,7 +2217,7 @@ async function integrateSourceCodes(genFile, config, projectPath) {
|
|
|
2210
2217
|
await modifyYyProject("add", projectPath, newResources, newFolders);
|
|
2211
2218
|
if (!config.acceptAllIntegrations) {
|
|
2212
2219
|
console.log("---");
|
|
2213
|
-
log.info(`\x1B[34macceptAllIntegrations\x1B[0m flag is set to \x1B[33mfalse\x1B[0m in the \x1B[32mscaff.config
|
|
2220
|
+
log.info(`\x1B[34macceptAllIntegrations\x1B[0m flag is set to \x1B[33mfalse\x1B[0m in the \x1B[32mscaff.config\x1B[0m. Please review the generated source codes before integrating.`);
|
|
2214
2221
|
const deleteResources = [];
|
|
2215
2222
|
for (const [path3, data] of integrations) {
|
|
2216
2223
|
const pathSlice = path3.split("/");
|
|
@@ -2258,7 +2265,7 @@ async function main() {
|
|
|
2258
2265
|
case "generate":
|
|
2259
2266
|
log.debug("Getting Scaff config...");
|
|
2260
2267
|
const config = await getScaffConfig();
|
|
2261
|
-
const files = await getScaffFiles(resolvePath(
|
|
2268
|
+
const files = await getScaffFiles(resolvePath(config.source));
|
|
2262
2269
|
log.debug("Processing files...");
|
|
2263
2270
|
const fileGroup = await readAndSplitFiles(files, config);
|
|
2264
2271
|
if (!fileGroup) {
|
|
@@ -2295,7 +2302,7 @@ async function main() {
|
|
|
2295
2302
|
}, []);
|
|
2296
2303
|
log.debug("Integration data extracted successfully.");
|
|
2297
2304
|
const genFiles = await generateSourceCode(intgData, config, input.projectPath);
|
|
2298
|
-
if (!config.noIntegration) {
|
|
2305
|
+
if (!config.noIntegration && !input.options.noIntegration) {
|
|
2299
2306
|
log.debug("Integrating source code...");
|
|
2300
2307
|
const modified = await integrateSourceCodes(genFiles, config, input.projectPath);
|
|
2301
2308
|
if (modified === null) {
|
|
@@ -2310,14 +2317,13 @@ async function main() {
|
|
|
2310
2317
|
log.info("Program executed successfully. Thanks for using ScaffScript!");
|
|
2311
2318
|
} else {
|
|
2312
2319
|
console.log("---");
|
|
2313
|
-
|
|
2320
|
+
if (input.options.noIntegration)
|
|
2321
|
+
log.info("\x1B[34m--no-integration\x1B[0m option is set. No source code will be integrated. Thanks for using ScaffScript!");
|
|
2322
|
+
else
|
|
2323
|
+
log.info("\x1B[34mnoIntegration\x1B[0m flag is set to \x1B[33mtrue\x1B[0m in the \x1B[32mscaff.config\x1B[0m. No source code will be integrated. Thanks for using ScaffScript!");
|
|
2314
2324
|
}
|
|
2315
2325
|
console.log("");
|
|
2316
2326
|
break;
|
|
2317
|
-
case "init":
|
|
2318
|
-
log.info("ScaffScript project initializer hasn't been implemented yet. Please use the installation guide in the documentation.");
|
|
2319
|
-
return;
|
|
2320
|
-
break;
|
|
2321
2327
|
}
|
|
2322
2328
|
console.log("");
|
|
2323
2329
|
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export type ScaffConfig = {
|
|
2
|
+
/**
|
|
3
|
+
* accept all generated files to be integrated without manual confirmation (default = false)
|
|
4
|
+
*/
|
|
5
|
+
acceptAllIntegrations: boolean;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* clear the output directory before generating source code (default = false)
|
|
9
|
+
*/
|
|
10
|
+
clearOutputDir: boolean;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* starting value for the counter special value (default = 1)
|
|
14
|
+
*/
|
|
15
|
+
counterStart: number;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* debug level (default = 0, 0 = no debug, 1 = basic debug, 2 = verbose debug)
|
|
19
|
+
*/
|
|
20
|
+
debugLevel: 0 | 1 | 2;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* integration options
|
|
24
|
+
*/
|
|
25
|
+
integrationOption: ScaffIntegrationOptions;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* don't backup the original files before integration (default = false)
|
|
29
|
+
*/
|
|
30
|
+
noBackup: boolean;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* don't integrate the files to GM project (default = false)
|
|
34
|
+
*/
|
|
35
|
+
noIntegration: boolean;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* what to do when something is not found (default = "error")
|
|
39
|
+
*/
|
|
40
|
+
onNotFound: "error" | "ignore";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* path aliases (default = {})
|
|
44
|
+
*/
|
|
45
|
+
path: Record<string, string>;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* whether the script is running in production mode (default = false)
|
|
49
|
+
*/
|
|
50
|
+
production: boolean;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* source directory (default = "./src")
|
|
54
|
+
*/
|
|
55
|
+
source: string;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* tab type to use when generating source code (default = "1t")
|
|
59
|
+
*/
|
|
60
|
+
tabType: "1t" | "2s" | "4s";
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* target platform for the generated code (default = "all"). only used for tree-shaking purpose
|
|
64
|
+
*/
|
|
65
|
+
targetPlatform: ScaffIntegrationTargetPlatform;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* whether to use GM asset path when integrating files (default = false). asset path: `scripts` and `objects`
|
|
69
|
+
*/
|
|
70
|
+
useGmAssetPath: boolean;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
type ScaffIntegrationOptions = Partial<{
|
|
74
|
+
isDnd: boolean;
|
|
75
|
+
}>;
|
|
76
|
+
|
|
77
|
+
type ScaffIntegrationTargetPlatform =
|
|
78
|
+
| "all"
|
|
79
|
+
| "android"
|
|
80
|
+
| "gxgames"
|
|
81
|
+
| "html5"
|
|
82
|
+
| "ios"
|
|
83
|
+
| "linux"
|
|
84
|
+
| "mac"
|
|
85
|
+
| "ps4"
|
|
86
|
+
| "ps5"
|
|
87
|
+
| "reddit"
|
|
88
|
+
| "switch"
|
|
89
|
+
| "switch2"
|
|
90
|
+
| "tvos"
|
|
91
|
+
| "ubuntu"
|
|
92
|
+
| "windows"
|
|
93
|
+
| "xboxone"
|
|
94
|
+
| "xboxseries"
|
|
95
|
+
;
|
package/package.json
CHANGED
|
@@ -1,40 +1,41 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@scaffscript/core",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
}
|
|
40
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@scaffscript/core",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/undervolta/scaffscript"
|
|
7
|
+
},
|
|
8
|
+
"main": "dist/index.cjs",
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"@types/bun": "latest"
|
|
11
|
+
},
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"typescript": "^5"
|
|
14
|
+
},
|
|
15
|
+
"bin": {
|
|
16
|
+
"scaff": "./dist/index.cjs"
|
|
17
|
+
},
|
|
18
|
+
"description": "A minimal superset language of GML with TypeScript-like module system",
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"keywords": [
|
|
23
|
+
"gamemaker",
|
|
24
|
+
"gml",
|
|
25
|
+
"scaff",
|
|
26
|
+
"script",
|
|
27
|
+
"superset",
|
|
28
|
+
"module",
|
|
29
|
+
"cli"
|
|
30
|
+
],
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "bun run build:all",
|
|
34
|
+
"build:node": "bun build src/index-node.ts --outfile dist/index.cjs --target node --format cjs",
|
|
35
|
+
"build:bun": "bun build src/index-bun.ts --outfile build/index.mjs --target bun --format esm",
|
|
36
|
+
"build:all": "bun run build:node && bun run build:bun",
|
|
37
|
+
"dev": "bun run src/index-node.ts",
|
|
38
|
+
"prelink": "bun run build"
|
|
39
|
+
},
|
|
40
|
+
"type": "module"
|
|
41
|
+
}
|