xcratch-create 1.0.1 → 1.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/bin/create.js +67 -58
- package/package.json +5 -4
- package/template/jest.config.js +11 -0
- package/template/package.json +20 -20
- package/template/scripts/rollup.config.mjs +4 -9
- package/template/src/gui/.eslintrc.js +18 -2
- package/template/src/gui/lib/libraries/extensions/entry/index.jsx +1 -0
- package/template/src/vm/extensions/block/index.js +1 -2
- package/template/test/.eslintrc.js +3 -3
- package/template/test/mocks/fileMock.js +1 -0
- package/template/test/setup-test.js +2 -4
- package/template/test/unit/block.test.js +5 -6
- package/template/.mocharc.js +0 -4
package/bin/create.js
CHANGED
|
@@ -1,28 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict'
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { replaceInFile } from 'replace-in-file';
|
|
5
|
+
import fs from 'fs-extra';
|
|
6
|
+
import AdmZip from 'adm-zip';
|
|
7
|
+
import projectJson from '../package.json' assert { type: 'json' };
|
|
8
|
+
|
|
9
|
+
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
9
10
|
|
|
10
11
|
function getArgs() {
|
|
11
12
|
const args = {};
|
|
12
13
|
process.argv
|
|
13
|
-
.slice(2
|
|
14
|
+
.slice(2) // Start from the third argument (ignoring Node and script path)
|
|
14
15
|
.forEach(arg => {
|
|
15
|
-
if (arg.
|
|
16
|
-
//
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
args
|
|
21
|
-
|
|
22
|
-
else if (arg[0] === '-') {
|
|
23
|
-
// flags
|
|
24
|
-
const flags = arg.slice(1, arg.length).split('');
|
|
25
|
-
flags.forEach(flag => {
|
|
16
|
+
if (arg.startsWith('--')) {
|
|
17
|
+
// Long argument (e.g., --account=my-account)
|
|
18
|
+
const [longArgFlag, ...rest] = arg.slice(2).split('=');
|
|
19
|
+
args[longArgFlag] = rest.join('=') || true; // Handle arguments with and without values
|
|
20
|
+
} else if (arg.startsWith('-')) {
|
|
21
|
+
// Flags (e.g., -abc becomes args.a = args.b = args.c = true)
|
|
22
|
+
arg.slice(1).split('').forEach(flag => {
|
|
26
23
|
args[flag] = true;
|
|
27
24
|
});
|
|
28
25
|
}
|
|
@@ -32,85 +29,97 @@ function getArgs() {
|
|
|
32
29
|
|
|
33
30
|
const args = getArgs();
|
|
34
31
|
|
|
35
|
-
|
|
32
|
+
// Check for version request
|
|
33
|
+
if (args.version || args.V) {
|
|
36
34
|
process.stdout.write(`v${projectJson.version}\n`);
|
|
37
|
-
process.exit(0);
|
|
35
|
+
process.exit(0); // Exit successfully after displaying version
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
|
|
38
|
+
// Validate required arguments
|
|
39
|
+
if (!args.account) {
|
|
41
40
|
process.stderr.write('"--account=<github account>" is not set\n');
|
|
42
|
-
process.exit(1);
|
|
41
|
+
process.exit(1); // Exit with an error code
|
|
43
42
|
}
|
|
44
|
-
const account = args
|
|
43
|
+
const account = args.account;
|
|
45
44
|
|
|
46
|
-
if (!args
|
|
45
|
+
if (!args.repo) {
|
|
47
46
|
process.stderr.write('"--repo=<github repository>" is not set\n');
|
|
48
47
|
process.exit(1);
|
|
49
48
|
}
|
|
50
|
-
const repo = args
|
|
49
|
+
const repo = args.repo;
|
|
51
50
|
|
|
52
|
-
if (!args
|
|
51
|
+
if (!args.extensionID) {
|
|
53
52
|
process.stderr.write('"--extensionID=<extension ID>" is not set\n');
|
|
54
53
|
process.exit(1);
|
|
55
54
|
}
|
|
56
|
-
const extensionID = args
|
|
55
|
+
const extensionID = args.extensionID;
|
|
57
56
|
|
|
58
|
-
if (!args
|
|
57
|
+
if (!args.extensionName) {
|
|
59
58
|
process.stderr.write('"--extensionName=<extension name>" is not set\n');
|
|
60
59
|
process.exit(1);
|
|
61
60
|
}
|
|
62
|
-
const extensionName = args
|
|
61
|
+
const extensionName = args.extensionName;
|
|
63
62
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
path.resolve(process.cwd(),
|
|
63
|
+
// Determine output directory
|
|
64
|
+
const outputDir = args.out
|
|
65
|
+
? path.resolve(process.cwd(), args.out)
|
|
66
|
+
: path.resolve(process.cwd(), repo);
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
* Fetch template files
|
|
70
|
-
*
|
|
71
|
-
*/
|
|
68
|
+
// Fetch the project template
|
|
72
69
|
async function fetchTemplate() {
|
|
73
|
-
|
|
70
|
+
try {
|
|
71
|
+
await fs.copy(path.resolve(__dirname, '../template'), outputDir);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error('Error fetching template:', error);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
74
76
|
}
|
|
75
77
|
|
|
78
|
+
// Replacement options for template files
|
|
76
79
|
const options = {
|
|
77
|
-
files: [
|
|
78
|
-
'./**/*',
|
|
79
|
-
],
|
|
80
|
+
files: ['./**/*'], // Target all files in the output directory
|
|
80
81
|
from: [
|
|
81
82
|
/<<account>>/g,
|
|
82
83
|
/<<repo>>/g,
|
|
83
84
|
/<<extensionID>>/g,
|
|
84
85
|
/<<extensionName>>/g,
|
|
85
86
|
],
|
|
86
|
-
to: [
|
|
87
|
-
account,
|
|
88
|
-
repo,
|
|
89
|
-
extensionID,
|
|
90
|
-
extensionName,
|
|
91
|
-
],
|
|
87
|
+
to: [account, repo, extensionID, extensionName],
|
|
92
88
|
};
|
|
93
89
|
|
|
90
|
+
// Customize the template with provided arguments
|
|
94
91
|
async function resetRepo() {
|
|
95
|
-
process.chdir(outputDir);
|
|
96
|
-
fs.renameSync('dot_gitignore', '.gitignore');
|
|
97
92
|
try {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
93
|
+
process.chdir(outputDir); // Change working directory to the output directory
|
|
94
|
+
|
|
95
|
+
// Rename .gitignore file
|
|
96
|
+
await fs.rename('dot_gitignore', '.gitignore');
|
|
97
|
+
|
|
98
|
+
// Replace placeholders in template files
|
|
99
|
+
await replaceInFile(options);
|
|
100
|
+
|
|
101
|
+
// Zip the example project directory
|
|
102
|
+
const zip = new AdmZip();
|
|
106
103
|
const examplePath = path.resolve(outputDir, 'projects/example');
|
|
107
104
|
zip.addLocalFolder(examplePath);
|
|
108
105
|
zip.writeZip(path.resolve(outputDir, 'projects/example.sb3'));
|
|
109
|
-
|
|
106
|
+
|
|
107
|
+
// Remove the original example directory
|
|
108
|
+
await fs.rm(examplePath, { recursive: true, force: true });
|
|
109
|
+
|
|
110
|
+
console.log(`Scaffolding project created at: ${outputDir}`);
|
|
111
|
+
|
|
110
112
|
} catch (error) {
|
|
111
113
|
console.error('Error occurred:', error);
|
|
114
|
+
process.exit(1);
|
|
112
115
|
}
|
|
113
116
|
}
|
|
114
117
|
|
|
118
|
+
// Execute the setup process
|
|
115
119
|
fetchTemplate()
|
|
116
|
-
.then(
|
|
120
|
+
.then(resetRepo)
|
|
121
|
+
.catch(error => {
|
|
122
|
+
console.error('Error during setup:', error);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
});
|
|
125
|
+
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xcratch-create",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Support tool to create new extension for Xcratch",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"bin": {
|
|
6
7
|
"xcratch-create": "./bin/create.js"
|
|
7
8
|
},
|
|
@@ -27,8 +28,8 @@
|
|
|
27
28
|
},
|
|
28
29
|
"homepage": "https://github.com/xcratch/xcratch-create#readme",
|
|
29
30
|
"dependencies": {
|
|
30
|
-
"adm-zip": "^0.5.
|
|
31
|
-
"fs-extra": "^11.
|
|
32
|
-
"replace-in-file": "^
|
|
31
|
+
"adm-zip": "^0.5.16",
|
|
32
|
+
"fs-extra": "^11.3.0",
|
|
33
|
+
"replace-in-file": "^8.3.0"
|
|
33
34
|
}
|
|
34
35
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
testEnvironment: 'node',
|
|
3
|
+
transform: {
|
|
4
|
+
'^.+\\.jsx?$': 'babel-jest'
|
|
5
|
+
},
|
|
6
|
+
setupFilesAfterEnv: ['./test/setup-test.js'],
|
|
7
|
+
moduleNameMapper: {
|
|
8
|
+
'\\.(png|jpg|jpeg|gif|svg)$': '<rootDir>/test/mocks/fileMock.js'
|
|
9
|
+
},
|
|
10
|
+
testMatch: ['**/test/unit/**/*.test.js'],
|
|
11
|
+
};
|
package/template/package.json
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "<<repo>>",
|
|
3
3
|
"version": "0.0.0",
|
|
4
|
+
"description": "extension for Xcratch",
|
|
4
5
|
"scripts": {
|
|
5
6
|
"setup-dev": "node ./scripts/setup-dev.mjs",
|
|
6
7
|
"build": "rollup -c ./scripts/rollup.config.mjs",
|
|
7
8
|
"watch": "rollup -c ./scripts/rollup.config.mjs --watch",
|
|
8
|
-
"test": "
|
|
9
|
+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
|
|
9
10
|
},
|
|
10
11
|
"devDependencies": {
|
|
11
|
-
"@babel/core": "^7.
|
|
12
|
-
"@babel/eslint-parser": "^7.
|
|
13
|
-
"@babel/plugin-transform-react-jsx": "^7.
|
|
14
|
-
"@babel/plugin-transform-runtime": "^7.
|
|
15
|
-
"@babel/preset-env": "^7.
|
|
16
|
-
"@babel/preset-react": "^7.
|
|
17
|
-
"@babel/register": "^7.
|
|
12
|
+
"@babel/core": "^7.26.9",
|
|
13
|
+
"@babel/eslint-parser": "^7.26.8",
|
|
14
|
+
"@babel/plugin-transform-react-jsx": "^7.25.9",
|
|
15
|
+
"@babel/plugin-transform-runtime": "^7.26.9",
|
|
16
|
+
"@babel/preset-env": "^7.26.9",
|
|
17
|
+
"@babel/preset-react": "^7.26.3",
|
|
18
|
+
"@babel/register": "^7.25.9",
|
|
18
19
|
"@rollup/plugin-babel": "^6.0.4",
|
|
19
|
-
"@rollup/plugin-commonjs": "^
|
|
20
|
+
"@rollup/plugin-commonjs": "^28.0.2",
|
|
20
21
|
"@rollup/plugin-image": "^3.0.3",
|
|
21
22
|
"@rollup/plugin-json": "^6.1.0",
|
|
22
23
|
"@rollup/plugin-multi-entry": "^6.0.1",
|
|
23
|
-
"@rollup/plugin-node-resolve": "^
|
|
24
|
-
"
|
|
25
|
-
"core-js": "^3.36.0",
|
|
24
|
+
"@rollup/plugin-node-resolve": "^16.0.0",
|
|
25
|
+
"core-js": "^3.40.0",
|
|
26
26
|
"eslint": "^8.57.0",
|
|
27
|
-
"eslint-config-scratch": "^9.0.
|
|
28
|
-
"eslint-plugin-import": "^2.
|
|
29
|
-
"eslint-plugin-
|
|
30
|
-
"fs-extra": "^11.
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"rollup
|
|
27
|
+
"eslint-config-scratch": "^9.0.9",
|
|
28
|
+
"eslint-plugin-import": "^2.31.0",
|
|
29
|
+
"eslint-plugin-jest": "^27.6.3",
|
|
30
|
+
"fs-extra": "^11.3.0",
|
|
31
|
+
"jest": "^29.7.0",
|
|
32
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
33
|
+
"rollup": "^4.34.7",
|
|
34
34
|
"rollup-plugin-polyfill-node": "^0.13.0"
|
|
35
35
|
}
|
|
36
|
-
}
|
|
36
|
+
}
|
|
@@ -4,7 +4,6 @@ import fs from 'fs-extra';
|
|
|
4
4
|
import babel from '@rollup/plugin-babel';
|
|
5
5
|
import commonjs from '@rollup/plugin-commonjs';
|
|
6
6
|
import nodeResolve from '@rollup/plugin-node-resolve';
|
|
7
|
-
import nodeGlobals from 'rollup-plugin-node-globals';
|
|
8
7
|
import nodePolifills from 'rollup-plugin-polyfill-node';
|
|
9
8
|
import importImage from '@rollup/plugin-image';
|
|
10
9
|
import multi from '@rollup/plugin-multi-entry';
|
|
@@ -28,11 +27,10 @@ const rollupOptions = {
|
|
|
28
27
|
multi(),
|
|
29
28
|
importImage(),
|
|
30
29
|
commonjs(),
|
|
31
|
-
nodeGlobals(),
|
|
32
30
|
nodePolifills(),
|
|
33
31
|
nodeResolve({
|
|
34
32
|
browser: true,
|
|
35
|
-
preferBuiltins:
|
|
33
|
+
preferBuiltins: false,
|
|
36
34
|
modulePaths: [
|
|
37
35
|
path.resolve(process.cwd(), './node_modules'),
|
|
38
36
|
],
|
|
@@ -57,10 +55,8 @@ const rollupOptions = {
|
|
|
57
55
|
babelHelpers: 'runtime',
|
|
58
56
|
plugins: [
|
|
59
57
|
'@babel/plugin-transform-react-jsx',
|
|
60
|
-
[
|
|
61
|
-
"
|
|
62
|
-
{ "regenerator": true }
|
|
63
|
-
]
|
|
58
|
+
["@babel/plugin-transform-runtime",
|
|
59
|
+
{ "regenerator": true }]
|
|
64
60
|
],
|
|
65
61
|
}),
|
|
66
62
|
],
|
|
@@ -76,8 +72,7 @@ const rollupOptions = {
|
|
|
76
72
|
},
|
|
77
73
|
buildDelay: 500,
|
|
78
74
|
},
|
|
79
|
-
external: [
|
|
80
|
-
],
|
|
75
|
+
external: [],
|
|
81
76
|
}
|
|
82
77
|
|
|
83
78
|
export default rollupOptions;
|
|
@@ -8,8 +8,13 @@ module.exports = {
|
|
|
8
8
|
process: true
|
|
9
9
|
},
|
|
10
10
|
rules: {
|
|
11
|
+
// BEGIN: these caused trouble after upgrading eslint-plugin-react from 7.24.0 to 7.33.2
|
|
12
|
+
'react/forbid-prop-types': 'off',
|
|
13
|
+
'react/no-unknown-property': 'off',
|
|
14
|
+
// END: these caused trouble after upgrading eslint-plugin-react from 7.24.0 to 7.33.2
|
|
15
|
+
'no-warning-comments': 'off',
|
|
11
16
|
'import/no-mutable-exports': 'error',
|
|
12
|
-
|
|
17
|
+
'import/no-commonjs': 'error',
|
|
13
18
|
'import/no-amd': 'error',
|
|
14
19
|
'import/no-nodejs-modules': 'error',
|
|
15
20
|
'react/jsx-no-literals': 'error',
|
|
@@ -17,8 +22,19 @@ module.exports = {
|
|
|
17
22
|
allowParens: true
|
|
18
23
|
}]
|
|
19
24
|
},
|
|
25
|
+
overrides: [
|
|
26
|
+
{
|
|
27
|
+
files: ['**/.eslintrc.js'],
|
|
28
|
+
env: {
|
|
29
|
+
node: true
|
|
30
|
+
},
|
|
31
|
+
rules: {
|
|
32
|
+
'import/no-commonjs': 'off'
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
],
|
|
20
36
|
settings: {
|
|
21
|
-
react: {
|
|
37
|
+
'react': {
|
|
22
38
|
version: '16.2' // Prevent 16.3 lifecycle method errors
|
|
23
39
|
}
|
|
24
40
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import BlockType from '../../extension-support/block-type';
|
|
2
2
|
import ArgumentType from '../../extension-support/argument-type';
|
|
3
3
|
import Cast from '../../util/cast';
|
|
4
|
-
import log from '../../util/log';
|
|
5
4
|
import translations from './translations.json';
|
|
6
5
|
import blockIcon from './block-icon.png';
|
|
7
6
|
|
|
@@ -138,7 +137,7 @@ class ExtensionBlocks {
|
|
|
138
137
|
doIt (args) {
|
|
139
138
|
const statement = Cast.toString(args.SCRIPT);
|
|
140
139
|
const func = new Function(`return (${statement})`);
|
|
141
|
-
|
|
140
|
+
console.log(`doIt: ${statement}`);
|
|
142
141
|
return func.call(this);
|
|
143
142
|
}
|
|
144
143
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
root: true,
|
|
3
|
-
plugins: ["
|
|
4
|
-
extends: ["plugin:
|
|
3
|
+
plugins: ["jest"],
|
|
4
|
+
extends: ["plugin:jest/recommended"],
|
|
5
5
|
env: {
|
|
6
6
|
browser: true,
|
|
7
7
|
es6: true,
|
|
8
|
-
|
|
8
|
+
"jest/globals": true,
|
|
9
9
|
},
|
|
10
10
|
parserOptions: {
|
|
11
11
|
sourceType: "module",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = 'test-file-stub';
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { describe, it } from "mocha";
|
|
2
|
-
import { expect } from "chai";
|
|
3
1
|
import { blockClass } from "../../src/vm/extensions/block/index.js";
|
|
4
2
|
|
|
5
3
|
describe("blockClass", () => {
|
|
@@ -8,14 +6,15 @@ describe("blockClass", () => {
|
|
|
8
6
|
return msg.default;
|
|
9
7
|
}
|
|
10
8
|
};
|
|
11
|
-
|
|
9
|
+
|
|
10
|
+
test("should create an instance of blockClass", () => {
|
|
12
11
|
const block = new blockClass(runtime);
|
|
13
|
-
expect(block).
|
|
12
|
+
expect(block).toBeInstanceOf(blockClass);
|
|
14
13
|
});
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
test("doIt('3 + 4') should return 7", () => {
|
|
17
16
|
const block = new blockClass(runtime);
|
|
18
17
|
const result = block.doIt({SCRIPT: "3 + 4"});
|
|
19
|
-
expect(result).
|
|
18
|
+
expect(result).toBe(7);
|
|
20
19
|
});
|
|
21
20
|
});
|
package/template/.mocharc.js
DELETED