@m2c2kit/cli 0.1.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/dist/cli.js ADDED
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env node
2
+ // https://github.com/yargs/yargs/issues/1854#issuecomment-792354121
3
+ import yargs from "yargs";
4
+ import { hideBin } from "yargs/helpers";
5
+ import fs from "fs";
6
+ import path from "path";
7
+ import handlebars from "handlebars";
8
+ import { dirname } from "path";
9
+ import { fileURLToPath } from "url";
10
+ import { spawn } from "child_process";
11
+ const packageHomeFolderPath = dirname(fileURLToPath(import.meta.url));
12
+ const yarg = yargs(hideBin(process.argv));
13
+ const argv = yarg
14
+ .command("new <name>", "create a new m2c2kit app", (yarg) => {
15
+ yarg.positional("name", {
16
+ describe: "name of new app",
17
+ type: "string",
18
+ });
19
+ }, (argv) => {
20
+ const appName = argv["name"];
21
+ const newFolderPath = path.join(path.resolve(), appName);
22
+ if (fs.existsSync(newFolderPath)) {
23
+ console.log(`error: folder ${newFolderPath} already exists. please remove this folder and try again.`);
24
+ yarg.exit(1, new Error("path exists"));
25
+ }
26
+ fs.mkdirSync(newFolderPath);
27
+ fs.mkdirSync(path.join(newFolderPath, "src"));
28
+ fs.mkdirSync(path.join(newFolderPath, ".vscode"));
29
+ function applyValuesToTemplate(templateFilePath, contents) {
30
+ const templateContents = fs.readFileSync(templateFilePath).toString();
31
+ const template = handlebars.compile(templateContents);
32
+ return template(contents);
33
+ }
34
+ const templateFolderPath = path.join(packageHomeFolderPath, "templates");
35
+ const templates = [
36
+ {
37
+ templateFilePath: path.join(templateFolderPath, "package.json.handlebars"),
38
+ destinationFilePath: path.join(newFolderPath, "package.json"),
39
+ },
40
+ {
41
+ templateFilePath: path.join(templateFolderPath, "rollup.config.js.handlebars"),
42
+ destinationFilePath: path.join(newFolderPath, "rollup.config.js"),
43
+ },
44
+ {
45
+ templateFilePath: path.join(templateFolderPath, "tsconfig.json.handlebars"),
46
+ destinationFilePath: path.join(newFolderPath, "tsconfig.json"),
47
+ },
48
+ {
49
+ templateFilePath: path.join(templateFolderPath, "README.md.handlebars"),
50
+ destinationFilePath: path.join(newFolderPath, "README.md"),
51
+ },
52
+ {
53
+ templateFilePath: path.join(templateFolderPath, "starter.ts.handlebars"),
54
+ destinationFilePath: path.join(newFolderPath, "src", `${appName}.ts`),
55
+ },
56
+ {
57
+ templateFilePath: path.join(templateFolderPath, "index.html.handlebars"),
58
+ destinationFilePath: path.join(newFolderPath, "src", "index.html"),
59
+ },
60
+ {
61
+ templateFilePath: path.join(templateFolderPath, "launch.json.handlebars"),
62
+ destinationFilePath: path.join(newFolderPath, ".vscode", "launch.json"),
63
+ },
64
+ ];
65
+ templates.forEach((t) => {
66
+ const contents = applyValuesToTemplate(t.templateFilePath, {
67
+ appName: appName,
68
+ });
69
+ fs.writeFileSync(t.destinationFilePath, contents);
70
+ console.log(`CREATE ${t.destinationFilePath} (${contents.length} bytes)`);
71
+ });
72
+ let npm;
73
+ if (process.platform === "win32") {
74
+ npm = spawn(`npm`, ["install"], { shell: true, cwd: newFolderPath });
75
+ }
76
+ else {
77
+ npm = spawn(`npm`, ["install"], { cwd: newFolderPath });
78
+ }
79
+ npm.stdout.on("data", (data) => {
80
+ console.log(data.toString());
81
+ });
82
+ npm.stderr.on("data", (data) => {
83
+ console.error(data.toString());
84
+ });
85
+ npm.on("exit", (code) => {
86
+ if (code !== 0) {
87
+ console.log(`error: npm install exited with code ${code}`);
88
+ }
89
+ });
90
+ })
91
+ //.command("build", "compiles to output directory named dist/")
92
+ //.command("serve", "builds and serves app, rebuilding on files changes")
93
+ .demandCommand()
94
+ .showHelpOnFail(true).argv;
@@ -0,0 +1,15 @@
1
+ # {{appName}}
2
+
3
+ This project was generated with the m2c2kit CLI.
4
+
5
+ ## Development server
6
+
7
+ Run `npm run serve` from the command line for a development server. Browse to `http://localhost:3000/`. The app will automatically compile and reload when you change source files.
8
+
9
+ ## Debugging
10
+
11
+ With the file `.vscode/launch.json`, the project has been configured for debugging with Visual Studio Code and Chrome. If the development server is running, debugging in Visual Studio Code is available by pressing `F5` or selecting Run --> Start Debugging
12
+
13
+ ## Build
14
+
15
+ Run `npm run build` from the command line to build the project. Build artifacts will be stored in the `dist/` directory.
@@ -0,0 +1,41 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>{{appName}}</title>
5
+ <style type="text/css">
6
+ body {
7
+ margin: 0;
8
+ }
9
+ </style>
10
+ <meta charset="UTF-8" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ </head>
13
+
14
+ <body style="background: white">
15
+ <div
16
+ style="
17
+ display: flex;
18
+ justify-content: center;
19
+ align-items: center;
20
+ height: 100vh;
21
+ width: 100vw;
22
+ "
23
+ >
24
+ <canvas style="height: 100vh; width: 100vw"></canvas>
25
+ <!-- If you don't want the game to start immediately, remove game.start()
26
+ from the code and call game.start() somehow else, such as with
27
+ the button shown below or a programmatic call -->
28
+ <!-- <button
29
+ style="position: absolute; bottom: 8px; left: 8px"
30
+ id="startButton"
31
+ onclick="{
32
+ document.getElementById('startButton').disabled = true;
33
+ window.game.start();
34
+ }"
35
+ >
36
+ Start
37
+ </button> -->
38
+ </div>
39
+ <script type="module" src="./{{appName}}.bundle.js"></script>
40
+ </body>
41
+ </html>
@@ -0,0 +1,15 @@
1
+ {
2
+ // Use IntelliSense to learn about possible attributes.
3
+ // Hover to view descriptions of existing attributes.
4
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+ {
8
+ "type": "pwa-chrome",
9
+ "request": "launch",
10
+ "name": "Launch Chrome against localhost",
11
+ "url": "http://localhost:3000",
12
+ "webRoot": "${workspaceFolder}/build"
13
+ }
14
+ ]
15
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "{{appName}}",
3
+ "version": "1.0.0",
4
+ "scripts": {
5
+ "serve": "rollup -c --watch --configServe",
6
+ "build": "rollup -c --configProd"
7
+ },
8
+ "private": true,
9
+ "dependencies": {
10
+ "@m2c2kit/core": "^0.1.0",
11
+ "typescript": "^4.5.2",
12
+ "rollup": "^2.60.2",
13
+ "@rollup/plugin-typescript": "^8.3.0",
14
+ "rollup-plugin-shim": "^1.0.0",
15
+ "@rollup/plugin-node-resolve": "^13.0.6",
16
+ "@rollup/plugin-commonjs": "^21.0.1",
17
+ "rollup-plugin-copy": "^3.4.0",
18
+ "rollup-plugin-serve": "^1.1.0",
19
+ "rollup-plugin-livereload": "^2.0.5"
20
+ }
21
+ }
@@ -0,0 +1,81 @@
1
+ import typescript from "@rollup/plugin-typescript";
2
+ import shim from "rollup-plugin-shim";
3
+ import nodeResolve from "@rollup/plugin-node-resolve";
4
+ import commonjs from "@rollup/plugin-commonjs";
5
+ import copy from "rollup-plugin-copy";
6
+ import serve from "rollup-plugin-serve";
7
+ import livereload from "rollup-plugin-livereload";
8
+
9
+ let sharedPlugins = [
10
+ // canvaskit-wasm references these node.js functions
11
+ // shim them to empty functions for browser usage
12
+ shim({
13
+ fs: `export function fs_empty_shim() { }`,
14
+ path: `export function path_empty_shim() { }`,
15
+ }),
16
+ nodeResolve(),
17
+ commonjs({
18
+ include: "node_modules/canvaskit-wasm/**",
19
+ }),
20
+ ];
21
+
22
+ export default (commandLineArgs) => {
23
+
24
+ let outputFolder = "build";
25
+ if (commandLineArgs.configProd) {
26
+ outputFolder = "dist"
27
+ }
28
+
29
+ const finalConfig = [
30
+ {
31
+ input: "./src/{{appName}}.ts",
32
+ output: [
33
+ {
34
+ file: `./${outputFolder}/{{appName}}.bundle.js`,
35
+ format: "esm",
36
+ sourcemap: commandLineArgs.configServe && true,
37
+ },
38
+ ],
39
+ plugins: [
40
+ ...sharedPlugins,
41
+ typescript({
42
+ inlineSourceMap: commandLineArgs.configServe && true,
43
+ inlineSources: commandLineArgs.configServe && true,
44
+ }),
45
+ copy({
46
+ targets: [
47
+ // copy the wasm bundle out of node_modules so it can be served
48
+ {
49
+ src: "node_modules/canvaskit-wasm/bin/canvaskit.wasm",
50
+ dest: outputFolder,
51
+ },
52
+ ],
53
+ copyOnce: true,
54
+ hook: "writeBundle",
55
+ }),
56
+ copy({
57
+ targets: [
58
+ {
59
+ src: "src/index.html",
60
+ dest: outputFolder,
61
+ },
62
+ ],
63
+ copyOnce: false,
64
+ hook: "writeBundle",
65
+ }),
66
+ commandLineArgs.configServe &&
67
+ serve({
68
+ open: false,
69
+ verbose: true,
70
+ contentBase: [`./${outputFolder}`],
71
+ historyApiFallback: true,
72
+ host: "localhost",
73
+ port: 3000,
74
+ }),
75
+ commandLineArgs.configServe &&
76
+ livereload(),
77
+ ],
78
+ },
79
+ ];
80
+ return finalConfig;
81
+ };
@@ -0,0 +1,99 @@
1
+ import {
2
+ WebColors,
3
+ Action,
4
+ Game,
5
+ Scene,
6
+ Rect,
7
+ Shape,
8
+ Sprite,
9
+ Point,
10
+ Label,
11
+ } from "@m2c2kit/core";
12
+
13
+ const game = new Game();
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ (window as unknown as any).game = game;
16
+
17
+ game
18
+ .init({
19
+ showFps: true,
20
+ // set this color so we can see the boundaries of the game
21
+ bodyBackgroundColor: WebColors.Wheat,
22
+ // note: using 2:1 aspect ratio, because that is closer to modern phones
23
+ width: 400,
24
+ height: 800,
25
+ // set stretch to true if you want to fill the screen
26
+ stretch: false,
27
+ fontUrls: [
28
+ "https://storage.googleapis.com/skia-cdn/google-web-fonts/Roboto-Regular.ttf",
29
+ ],
30
+ // each svgImage below, you specify either a tag of an svg in the property "svgString" (as I do below)
31
+ // or you specify a URL to an svg in the property "url", such as url: 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/android.svg'
32
+ svgImages: [
33
+ {
34
+ name: "star",
35
+ height: 60,
36
+ width: 60,
37
+ svgString:
38
+ '<svg xmlns="http://www.w3.org/2000/svg" width="304" height="290"> <path d="M2,111 h300 l-242.7,176.3 92.7,-285.3 92.7,285.3 z" style="fill:#00FF00;stroke:#0000FF;stroke-width:15;stroke-linejoin:round"/></svg>',
39
+ },
40
+ ],
41
+ })
42
+ .then(() => {
43
+ const s = new Scene({
44
+ backgroundColor: WebColors.SlateBlue,
45
+ name: "first-scene",
46
+ });
47
+ game.addScene(s);
48
+
49
+ const greeting = new Label({
50
+ text: "Hello, {{appName}}",
51
+ fontColor: WebColors.WhiteSmoke,
52
+ position: new Point(200, 200),
53
+ });
54
+ s.addChild(greeting);
55
+
56
+ const starImage = new Sprite({
57
+ imageName: "star",
58
+ position: new Point(200, 400),
59
+ });
60
+ s.addChild(starImage);
61
+
62
+ const rectangle = new Shape({
63
+ rect: new Rect({ width: 300, height: 50, x: 200, y: 700 }),
64
+ cornerRadius: 9,
65
+ fillColor: WebColors.RebeccaPurple,
66
+ });
67
+
68
+ const messageLabel = new Label({
69
+ text: "you tapped the bar!",
70
+ fontColor: WebColors.Yellow,
71
+ position: new Point(200, 600),
72
+ });
73
+ s.addChild(messageLabel);
74
+ messageLabel.hidden = true;
75
+
76
+ rectangle.isUserInteractionEnabled = true;
77
+ rectangle.onTap(() => {
78
+ console.log("you tapped it!");
79
+ rectangle.run(
80
+ Action.Sequence([
81
+ Action.Custom({
82
+ callback: () => {
83
+ messageLabel.hidden = false;
84
+ },
85
+ }),
86
+ Action.Wait({ duration: 500 }),
87
+ Action.Custom({
88
+ callback: () => {
89
+ messageLabel.hidden = true;
90
+ },
91
+ }),
92
+ ])
93
+ );
94
+ });
95
+
96
+ s.addChild(rectangle);
97
+
98
+ game.start("first-scene");
99
+ });
@@ -0,0 +1,24 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es6",
4
+ "lib": [
5
+ "es6",
6
+ "dom",
7
+ "dom.iterable"
8
+ ],
9
+ "module": "es6",
10
+ "moduleResolution": "node",
11
+ "allowJs": true,
12
+ "esModuleInterop": true,
13
+ "forceConsistentCasingInFileNames": true,
14
+ "strict": true,
15
+ "skipLibCheck": true
16
+ },
17
+ "exclude": [
18
+ "node_modules",
19
+ "build",
20
+ "dist",
21
+ "**/{{appName}}.bundle.js",
22
+ "rollup.config.js"
23
+ ]
24
+ }
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@m2c2kit/cli",
3
+ "version": "0.1.0",
4
+ "description": "m2c2kit command line interface",
5
+ "module": "dist/cli.js",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "type": "module",
10
+ "bin": {
11
+ "m2": "./dist/cli.js"
12
+ },
13
+ "scripts": {
14
+ "build": "npm run clean && npm run compile && npm run copy-files",
15
+ "compile": "tsc",
16
+ "clean": "rimraf dist/ && rimraf build/",
17
+ "copy-files": "copyfiles -f build/src/cli.js dist && copyfiles templates/* dist/"
18
+ },
19
+ "author": "",
20
+ "license": "MIT",
21
+ "dependencies": {
22
+ "yargs": "^17.3.0",
23
+ "handlebars": "^4.7.7"
24
+ },
25
+ "devDependencies": {
26
+ "rimraf": "^3.0.2",
27
+ "typescript": "^4.5.2",
28
+ "copyfiles": "^2.4.1",
29
+ "yargs": "^17.3.0",
30
+ "@types/node": "^16.11.12",
31
+ "@types/yargs": "^17.0.7"
32
+ }
33
+ }