diff --git a/package-lock.json b/package-lock.json index f532ff1c..bbeda28a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -188,7 +188,6 @@ "integrity": "sha512-Jc360x4yqb3eEg4OY4KEIdGePBxZogivKI+OGIU8aLXgAYPTECvzeOBc90312yHA1hr3AeRlAFl0rIc8lQaIrQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.50.0", "@algolia/requester-browser-xhr": "5.50.0", @@ -787,6 +786,25 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/@clack/core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.1.0.tgz", + "integrity": "sha512-SVcm4Dqm2ukn64/8Gub2wnlA5nS2iWJyCkdNHcvNHPIeBTGojpdJ+9cZKwLfmqy7irD4N5qLteSilJlE0WLAtA==", + "license": "MIT", + "dependencies": { + "sisteransi": "^1.0.5" + } + }, + "node_modules/@clack/prompts": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.1.0.tgz", + "integrity": "sha512-pkqbPGtohJAvm4Dphs2M8xE29ggupihHdy1x84HNojZuMtFsHiUlRvqD24tM2+XmI+61LlfNceM3Wr7U5QES5g==", + "license": "MIT", + "dependencies": { + "@clack/core": "1.1.0", + "sisteransi": "^1.0.5" + } + }, "node_modules/@codemirror/autocomplete": { "version": "6.20.1", "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.1.tgz", @@ -967,7 +985,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=20.19.0" }, @@ -1016,7 +1033,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=20.19.0" } @@ -1110,7 +1126,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1127,7 +1142,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1144,7 +1158,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1161,7 +1174,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1178,7 +1190,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1195,7 +1206,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1212,7 +1222,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1229,7 +1238,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1246,7 +1254,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1263,7 +1270,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1280,7 +1286,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1297,7 +1302,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1314,7 +1318,6 @@ "cpu": [ "mips64el" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1331,7 +1334,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1348,7 +1350,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1365,7 +1366,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1382,7 +1382,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1399,7 +1398,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1416,7 +1414,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1433,7 +1430,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1450,7 +1446,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1467,7 +1462,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1484,7 +1478,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1501,7 +1494,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1518,7 +1510,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1535,7 +1526,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2054,6 +2044,7 @@ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.120.0.tgz", "integrity": "sha512-k1YNu55DuvAip/MGE1FTsIuU3FUCn6v/ujG9V7Nq5Df/kX2CWb13hhwD0lmJGMGqE+bE1MXvv9SZVnMzEXlWcg==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/Boshen" } @@ -2116,6 +2107,7 @@ "os": [ "android" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2132,6 +2124,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2148,6 +2141,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2164,6 +2158,7 @@ "os": [ "freebsd" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2180,6 +2175,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2196,6 +2192,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2212,6 +2209,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2228,6 +2226,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2244,6 +2243,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2260,6 +2260,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2276,6 +2277,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2292,6 +2294,7 @@ "os": [ "openharmony" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2305,6 +2308,7 @@ ], "license": "MIT", "optional": true, + "peer": true, "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, @@ -2324,6 +2328,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2340,6 +2345,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2348,7 +2354,8 @@ "version": "1.0.0-rc.10", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.10.tgz", "integrity": "sha512-UkVDEFk1w3mveXeKgaTuYfKWtPbvgck1dT8TUG3bnccrH0XtLTuAyfCoks4Q/M5ZGToSVJTIQYCzy2g/atAOeg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@rollup/plugin-commonjs": { "version": "29.0.2", @@ -2401,7 +2408,6 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -2841,6 +2847,12 @@ "win32" ] }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "license": "MIT" + }, "node_modules/@shikijs/core": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-2.5.0.tgz", @@ -2928,6 +2940,18 @@ "dev": true, "license": "MIT" }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@swc/helpers": { "version": "0.5.19", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.19.tgz", @@ -3110,7 +3134,6 @@ "integrity": "sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.57.1", "@typescript-eslint/types": "8.57.1", @@ -4125,7 +4148,6 @@ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4166,7 +4188,6 @@ "integrity": "sha512-yE5I83Q2s8euVou8Y3feXK08wyZInJWLYXgWO6Xti9jBUEZAGUahyeQ7wSZWkifLWVnQVKEz5RAmBlXG5nqxog==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@algolia/abtesting": "1.16.0", "@algolia/client-abtesting": "5.50.0", @@ -4508,7 +4529,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -4862,7 +4882,6 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -5164,7 +5183,6 @@ "devOptional": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -5229,7 +5247,6 @@ "integrity": "sha512-COV33RzXZkqhG9P2rZCFl9ZmJ7WL+gQSCRzE7RhkbclbQPtLAWReL7ysA0Sh4c8Im2U9ynybdR56PV0XcKvqaQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", @@ -5495,6 +5512,32 @@ "dev": true, "license": "MIT" }, + "node_modules/execa": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", + "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, "node_modules/extendable-error": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz", @@ -5570,6 +5613,21 @@ "reusify": "^1.0.4" } }, + "node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -5649,7 +5707,6 @@ "integrity": "sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "tabbable": "^6.4.0" } @@ -5724,6 +5781,10 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gea-cli": { + "resolved": "packages/gea-cli", + "link": true + }, "node_modules/gea-tools": { "resolved": "packages/gea-tools", "link": true @@ -5738,6 +5799,22 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-tsconfig": { "version": "4.13.6", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz", @@ -5820,7 +5897,6 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, "license": "ISC" }, "node_modules/has-flag": { @@ -5932,6 +6008,15 @@ "human-id": "dist/cli.js" } }, + "node_modules/human-signals": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, "node_modules/iconv-lite": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", @@ -6061,6 +6146,18 @@ "node": ">=0.12.0" } }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -6078,6 +6175,18 @@ "@types/estree": "*" } }, + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-subdir": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz", @@ -6091,6 +6200,18 @@ "node": ">=4" } }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-what": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/is-what/-/is-what-5.5.0.tgz", @@ -6118,7 +6239,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, "license": "ISC" }, "node_modules/istanbul-lib-coverage": { @@ -6293,6 +6413,12 @@ "json-buffer": "3.0.1" } }, + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "license": "MIT" + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -6987,6 +7113,34 @@ "node": ">=0.10.0" } }, + "node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -7134,6 +7288,18 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse5": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", @@ -7161,7 +7327,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -7332,7 +7497,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -7513,6 +7677,21 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/pretty-ms": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz", + "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==", + "license": "MIT", + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/prismjs": { "version": "1.30.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", @@ -7962,7 +8141,6 @@ "integrity": "sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -8090,7 +8268,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -8103,7 +8280,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -8130,7 +8306,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "license": "ISC", "engines": { "node": ">=14" @@ -8139,6 +8314,12 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -8260,6 +8441,18 @@ "node": ">=4" } }, + "node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/style-mod": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.3.tgz", @@ -8538,7 +8731,6 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -9156,7 +9348,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -9244,6 +9435,18 @@ "devOptional": true, "license": "MIT" }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/unist-util-is": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", @@ -9788,6 +9991,7 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.1.tgz", "integrity": "sha512-wt+Z2qIhfFt85uiyRt5LPU4oVEJBXj8hZNWKeqFG4gRG/0RaRGJ7njQCwzFVjO+v4+Ipmf5CY7VdmZRAYYBPHw==", "license": "MIT", + "peer": true, "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.3", @@ -9865,6 +10069,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -10364,7 +10569,6 @@ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -10509,7 +10713,6 @@ "integrity": "sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.30", "@vue/compiler-sfc": "3.5.30", @@ -10585,7 +10788,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -10694,6 +10896,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", @@ -10708,13 +10922,17 @@ "packages/create-gea": { "version": "1.0.1", "license": "MIT", + "dependencies": { + "@clack/prompts": "^1.1.0", + "kolorist": "^1.8.0" + }, "bin": { "create-gea": "bin/create-gea.js" } }, "packages/gea": { "name": "@geajs/core", - "version": "1.0.4", + "version": "1.0.5", "license": "MIT", "devDependencies": { "@types/node": "^25.5.0", @@ -10726,6 +10944,65 @@ "typescript": "~5.8.0" } }, + "packages/gea-cli": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@clack/prompts": "^1.1.0", + "commander": "^13.1.0", + "execa": "^9.0.2", + "fs-extra": "^11.3.0", + "kolorist": "^1.8.0", + "picocolors": "^1.1.1" + }, + "bin": { + "gea": "bin/gea.js" + } + }, + "packages/gea-cli/node_modules/commander": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "packages/gea-cli/node_modules/fs-extra": { + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "packages/gea-cli/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "packages/gea-cli/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "packages/gea-mobile": { "name": "@geajs/mobile", "version": "1.0.0", @@ -10854,7 +11131,7 @@ }, "packages/vite-plugin-gea": { "name": "@geajs/vite-plugin", - "version": "1.0.4", + "version": "1.0.5", "license": "MIT", "dependencies": { "@acemir/cssom": "^0.9.31", diff --git a/package.json b/package.json index 441912e0..3bd28440 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,8 @@ "example:router-v2": "vite dev examples/router-v2", "example:tic-tac-toe": "vite dev --config examples/tic-tac-toe/vite.config.ts", "example:todo": "vite dev examples/todo", - "test:e2e": "npx playwright test --config=tests/e2e/playwright.config.ts" + "test:e2e": "npx playwright test --config=tests/e2e/playwright.config.ts", + "gea": "node packages/gea-cli/bin/gea.js" }, "devDependencies": { "@changesets/changelog-github": "^0.6.0", diff --git a/packages/create-gea/bin/create-gea.js b/packages/create-gea/bin/create-gea.js index 22d8da5e..3a3c2b4d 100755 --- a/packages/create-gea/bin/create-gea.js +++ b/packages/create-gea/bin/create-gea.js @@ -1,25 +1,17 @@ -#!/usr/bin/env node - -import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs' +import { cpSync, existsSync, readdirSync, readFileSync, renameSync, writeFileSync, mkdirSync } from 'node:fs' import { basename, dirname, resolve } from 'node:path' import { fileURLToPath } from 'node:url' -import { stdin as input, stdout as output } from 'node:process' -import { createInterface } from 'node:readline/promises' +import { intro, outro, text, select, confirm, isCancel, cancel, spinner } from '@clack/prompts' +import { cyan, gray, green, reset } from 'kolorist' const __dirname = dirname(fileURLToPath(import.meta.url)) -const templateDir = resolve(__dirname, '../template') - -function printHelp() { - console.log(`create-gea +const templatesDir = resolve(__dirname, '../templates') -Usage: - npm create gea@latest [project-name] - -Examples: - npm create gea@latest my-gea-app - npm create gea@latest . -`) -} +const TEMPLATES = [ + { value: 'default', label: 'Standard', hint: 'Simple Gea app with Vite' }, + { value: 'mobile', label: 'Mobile', hint: 'Gea mobile app with touch-friendly UI' }, + { value: 'dashboard', label: 'Dashboard', hint: 'Gea dashboard starter with layout' }, +] function isValidPackageName(value) { return /^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(value) @@ -37,7 +29,6 @@ function toValidPackageName(value) { function getPackageManager() { const userAgent = process.env.npm_config_user_agent ?? '' - if (userAgent.startsWith('pnpm/')) return 'pnpm' if (userAgent.startsWith('yarn/')) return 'yarn' if (userAgent.startsWith('bun/')) return 'bun' @@ -45,11 +36,12 @@ function getPackageManager() { } function isEmptyDir(dir) { - return readdirSync(dir).length === 0 + return !existsSync(dir) || readdirSync(dir).length === 0 } function writeTemplateFile(projectRoot, fileName, replacements) { const filePath = resolve(projectRoot, fileName) + if (!existsSync(filePath)) return const source = readFileSync(filePath, 'utf8') let next = source @@ -60,47 +52,66 @@ function writeTemplateFile(projectRoot, fileName, replacements) { writeFileSync(filePath, next) } -async function getTargetDir(args) { - const firstArg = args.find((arg) => !arg.startsWith('-')) - if (firstArg) return firstArg - - const rl = createInterface({ input, output }) - try { - const answer = await rl.question('Project name: ') - return answer.trim() || 'gea-app' - } finally { - rl.close() - } -} - async function main() { + intro(cyan('create-gea')) + const args = process.argv.slice(2) + let targetDir = args[0] + + if (!targetDir) { + targetDir = await text({ + message: 'Project name:', + placeholder: 'my-gea-app', + defaultValue: 'my-gea-app', + }) + if (isCancel(targetDir)) { + cancel('Operation cancelled') + process.exit(0) + } + } - if (args.includes('--help') || args.includes('-h')) { - printHelp() - process.exit(0) + if (!targetDir || targetDir.trim() === '') { + cancel('Project name cannot be empty') + process.exit(1) } - const targetDir = await getTargetDir(args) const projectRoot = resolve(process.cwd(), targetDir) if (existsSync(projectRoot) && !isEmptyDir(projectRoot)) { - console.error(`Target directory is not empty: ${projectRoot}`) + cancel('Target directory is not empty') process.exit(1) } - mkdirSync(projectRoot, { recursive: true }) + const template = await select({ + message: 'Select a template:', + options: TEMPLATES, + }) - const rawName = targetDir === '.' ? basename(process.cwd()) : basename(projectRoot) - const packageName = isValidPackageName(rawName) ? rawName : toValidPackageName(rawName) + if (isCancel(template)) { + cancel('Operation cancelled') + process.exit(0) + } + + const s = spinner() + s.start(`Scaffolding project in ${gray(projectRoot)}...`) + + if (!existsSync(projectRoot)) { + mkdirSync(projectRoot, { recursive: true }) + } - cpSync(templateDir, projectRoot, { recursive: true }) + const selectedTemplateDir = resolve(templatesDir, template) + + const templateToUse = existsSync(selectedTemplateDir) ? template : 'default' + cpSync(resolve(templatesDir, templateToUse), projectRoot, { recursive: true }) const gitignoreSource = resolve(projectRoot, '_gitignore') if (existsSync(gitignoreSource)) { renameSync(gitignoreSource, resolve(projectRoot, '.gitignore')) } + const rawName = targetDir === '.' ? basename(process.cwd()) : basename(projectRoot) + const packageName = isValidPackageName(rawName) ? rawName : toValidPackageName(rawName) + writeTemplateFile(projectRoot, 'package.json', { __PACKAGE_NAME__: packageName, }) @@ -108,20 +119,18 @@ async function main() { __PROJECT_TITLE__: packageName, }) + s.stop(green(`Success! Project scaffolded in ${targetDir}`)) + const packageManager = getPackageManager() const installCommand = packageManager === 'yarn' ? 'yarn' : `${packageManager} install` const devCommand = packageManager === 'yarn' ? 'yarn dev' : `${packageManager} run dev` - console.log(`\nScaffolded an Gea app in ${projectRoot}\n`) - console.log('Next steps:') - if (targetDir !== '.') { - console.log(` cd ${targetDir}`) - } - console.log(` ${installCommand}`) - console.log(` ${devCommand}`) + outro(`Next steps: + ${targetDir !== '.' ? `cd "${targetDir}"\n ` : ''}${installCommand}\n ${devCommand} + `) } main().catch((error) => { - console.error(error instanceof Error ? error.message : error) + cancel(error instanceof Error ? error.message : String(error)) process.exit(1) }) diff --git a/packages/create-gea/package.json b/packages/create-gea/package.json index a2f36fec..ef480ee9 100644 --- a/packages/create-gea/package.json +++ b/packages/create-gea/package.json @@ -1,7 +1,6 @@ { "name": "create-gea", "version": "1.0.1", - "description": "Scaffold a new Gea app with Vite in seconds", "type": "module", "bin": { "create-gea": "bin/create-gea.js" @@ -11,17 +10,10 @@ }, "files": [ "bin", - "template" + "templates" ], - "keywords": [ - "gea", - "create-gea", - "vite", - "scaffold", - "starter", - "boilerplate" - ], - "author": "Armagan Amcalar ", + "keywords": [], + "author": "Hacı Mert Gökhan ", "license": "MIT", "repository": { "type": "git", @@ -30,5 +22,9 @@ "bugs": { "url": "https://github.com/dashersw/gea/issues" }, - "homepage": "https://github.com/dashersw/gea#readme" -} + "homepage": "https://github.com/dashersw/gea#readme", + "dependencies": { + "@clack/prompts": "^1.1.0", + "kolorist": "^1.8.0" + } +} \ No newline at end of file diff --git a/packages/create-gea/template/_gitignore b/packages/create-gea/templates/dashboard/_gitignore similarity index 100% rename from packages/create-gea/template/_gitignore rename to packages/create-gea/templates/dashboard/_gitignore diff --git a/packages/create-gea/templates/dashboard/index.html b/packages/create-gea/templates/dashboard/index.html new file mode 100644 index 00000000..1fbba87e --- /dev/null +++ b/packages/create-gea/templates/dashboard/index.html @@ -0,0 +1,13 @@ + + + + + Dashboard — gea-ui Example + + + + +
+ + + diff --git a/packages/create-gea/templates/dashboard/package.json b/packages/create-gea/templates/dashboard/package.json new file mode 100644 index 00000000..34bb13f5 --- /dev/null +++ b/packages/create-gea/templates/dashboard/package.json @@ -0,0 +1,20 @@ +{ + "name": "__PACKAGE_NAME__", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "@geajs/core": "^1.0.0", + "@geajs/ui": "^0.1.0" + }, + "devDependencies": { + "typescript": "^5.9.3", + "vite": "^8.0.0", + "@geajs/vite-plugin": "^1.0.0" + } +} diff --git a/packages/create-gea/template/public/favicon.ico b/packages/create-gea/templates/dashboard/public/favicon.ico similarity index 100% rename from packages/create-gea/template/public/favicon.ico rename to packages/create-gea/templates/dashboard/public/favicon.ico diff --git a/packages/create-gea/template/public/logo.png b/packages/create-gea/templates/dashboard/public/logo.png similarity index 100% rename from packages/create-gea/template/public/logo.png rename to packages/create-gea/templates/dashboard/public/logo.png diff --git a/packages/create-gea/templates/dashboard/src/app.tsx b/packages/create-gea/templates/dashboard/src/app.tsx new file mode 100644 index 00000000..9130cf46 --- /dev/null +++ b/packages/create-gea/templates/dashboard/src/app.tsx @@ -0,0 +1,172 @@ +import { Component } from '@geajs/core' +import { + Button, + Card, + CardHeader, + CardTitle, + CardDescription, + CardContent, + CardFooter, + Badge, + Progress, + Avatar, + Tabs, + Separator, + Skeleton, +} from '@geajs/ui' + +const stats = [ + { label: 'Total Revenue', value: '$45,231.89', change: '+20.1% from last month', positive: true }, + { label: 'Subscriptions', value: '+2,350', change: '+180.1% from last month', positive: true }, + { label: 'Sales', value: '+12,234', change: '+19% from last month', positive: true }, + { label: 'Active Now', value: '+573', change: '+201 since last hour', positive: true }, +] + +const activities = [ + { name: 'Olivia Martin', action: 'purchased Pro plan', time: '2 min ago', src: '' }, + { name: 'Jackson Lee', action: 'uploaded 3 files', time: '15 min ago', src: '' }, + { name: 'Isabella Nguyen', action: 'commented on a task', time: '1 hour ago', src: '' }, + { name: 'William Kim', action: 'completed onboarding', time: '3 hours ago', src: '' }, + { name: 'Sofia Davis', action: 'updated profile settings', time: '5 hours ago', src: '' }, +] + +const team = [ + { name: 'Sofia Davis', role: 'Engineering Lead', initials: 'SD' }, + { name: 'Jackson Lee', role: 'Product Design', initials: 'JL' }, + { name: 'Isabella Nguyen', role: 'Frontend Dev', initials: 'IN' }, + { name: 'William Kim', role: 'Backend Dev', initials: 'WK' }, +] + +export default class App extends Component { + template() { + return ( +
+
+
+

Dashboard

+

Welcome back, here's your overview.

+
+
+ Live + + +
+
+ +
+ {stats.map((stat) => ( + + + {stat.label} + {stat.value} + {stat.change} + + + ))} +
+ +
+ + + Overview + Revenue breakdown by category. + + + +
+ Revenue chart would render here +
+ +
+
+

Monthly Target

+

72% of $50,000 goal

+
+ On Track +
+ +
+
+ +
+ + + Recent Activity + Latest actions from your team. + + + {activities.map((a) => ( +
+ +
+ {a.name} {a.action} +
+ {a.time} +
+ ))} +
+
+ + + + Team + Your core team members. + + +
+ {team.map((m) => ( +
+ +
+
{m.name}
+
{m.role}
+
+ {m.role.split(' ')[0]} +
+ ))} +
+
+
+ + + + Loading State + Skeleton placeholders. + + +
+
+ +
+ + +
+
+ + + +
+
+
+
+
+ + + gea-ui Dashboard Example — All components are accessible and fully keyboard-navigable. + +
+ ) + } +} diff --git a/packages/create-gea/template/src/counter-note.tsx b/packages/create-gea/templates/dashboard/src/counter-note.tsx similarity index 100% rename from packages/create-gea/template/src/counter-note.tsx rename to packages/create-gea/templates/dashboard/src/counter-note.tsx diff --git a/packages/create-gea/template/src/counter-panel.tsx b/packages/create-gea/templates/dashboard/src/counter-panel.tsx similarity index 100% rename from packages/create-gea/template/src/counter-panel.tsx rename to packages/create-gea/templates/dashboard/src/counter-panel.tsx diff --git a/packages/create-gea/template/src/counter-store.ts b/packages/create-gea/templates/dashboard/src/counter-store.ts similarity index 100% rename from packages/create-gea/template/src/counter-store.ts rename to packages/create-gea/templates/dashboard/src/counter-store.ts diff --git a/packages/create-gea/templates/dashboard/src/main.ts b/packages/create-gea/templates/dashboard/src/main.ts new file mode 100644 index 00000000..05a55600 --- /dev/null +++ b/packages/create-gea/templates/dashboard/src/main.ts @@ -0,0 +1,9 @@ +import App from './app' +import '@geajs/ui/styles/theme.css' +import './styles.css' + +const root = document.getElementById('app') +if (!root) throw new Error('App root element not found') + +const app = new App() +app.render(root) diff --git a/packages/create-gea/templates/dashboard/src/styles.css b/packages/create-gea/templates/dashboard/src/styles.css new file mode 100644 index 00000000..a4cb8bc6 --- /dev/null +++ b/packages/create-gea/templates/dashboard/src/styles.css @@ -0,0 +1,139 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: Inter, system-ui, sans-serif; + background-color: hsl(var(--background)); + color: hsl(var(--foreground)); + line-height: 1.6; +} + +.dashboard { + max-width: 1200px; + margin: 0 auto; + padding: 2rem; +} + +.dashboard-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 2rem; +} + +.stat-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + gap: 1rem; + margin-bottom: 2rem; +} + +.stat-card { + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +.stat-value { + font-size: 1.75rem; + font-weight: 700; + letter-spacing: -0.025em; +} + +.stat-label { + font-size: 0.875rem; + color: hsl(var(--muted-foreground)); +} + +.stat-change { + font-size: 0.75rem; + margin-top: 0.25rem; +} + +.stat-change.positive { + color: #16a34a; +} +.stat-change.negative { + color: #dc2626; +} + +.main-grid { + display: grid; + grid-template-columns: 2fr 1fr; + gap: 1.5rem; +} + +@media (max-width: 768px) { + .main-grid { + grid-template-columns: 1fr; + } +} + +.chart-placeholder { + height: 200px; + background: linear-gradient(135deg, hsl(var(--primary) / 0.05), hsl(var(--primary) / 0.1)); + border-radius: var(--radius); + display: flex; + align-items: center; + justify-content: center; + color: hsl(var(--muted-foreground)); + font-size: 0.875rem; +} + +.activity-item { + display: flex; + align-items: center; + gap: 0.75rem; + padding: 0.75rem 0; +} + +.activity-item + .activity-item { + border-top: 1px solid hsl(var(--border)); +} + +.activity-text { + flex: 1; + font-size: 0.875rem; +} + +.activity-text strong { + font-weight: 600; +} +.activity-time { + font-size: 0.75rem; + color: hsl(var(--muted-foreground)); + white-space: nowrap; +} + +.team-list { + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.team-member { + display: flex; + align-items: center; + gap: 0.75rem; +} + +.team-info { + flex: 1; +} +.team-name { + font-size: 0.875rem; + font-weight: 500; +} +.team-role { + font-size: 0.75rem; + color: hsl(var(--muted-foreground)); +} + +.skeleton-group { + display: flex; + flex-direction: column; + gap: 0.5rem; +} diff --git a/packages/create-gea/template/tsconfig.json b/packages/create-gea/templates/dashboard/tsconfig.json similarity index 100% rename from packages/create-gea/template/tsconfig.json rename to packages/create-gea/templates/dashboard/tsconfig.json diff --git a/packages/create-gea/templates/dashboard/vite.config.ts b/packages/create-gea/templates/dashboard/vite.config.ts new file mode 100644 index 00000000..69763e09 --- /dev/null +++ b/packages/create-gea/templates/dashboard/vite.config.ts @@ -0,0 +1,3 @@ +import { createConfig } from '../shared/vite-config-base' + +export default createConfig(import.meta.url, 5190) diff --git a/packages/create-gea/templates/default/_gitignore b/packages/create-gea/templates/default/_gitignore new file mode 100644 index 00000000..f06235c4 --- /dev/null +++ b/packages/create-gea/templates/default/_gitignore @@ -0,0 +1,2 @@ +node_modules +dist diff --git a/packages/create-gea/template/index.html b/packages/create-gea/templates/default/index.html similarity index 100% rename from packages/create-gea/template/index.html rename to packages/create-gea/templates/default/index.html diff --git a/packages/create-gea/template/package.json b/packages/create-gea/templates/default/package.json similarity index 100% rename from packages/create-gea/template/package.json rename to packages/create-gea/templates/default/package.json diff --git a/packages/create-gea/templates/default/public/favicon.ico b/packages/create-gea/templates/default/public/favicon.ico new file mode 100644 index 00000000..8cc45d3b Binary files /dev/null and b/packages/create-gea/templates/default/public/favicon.ico differ diff --git a/packages/create-gea/templates/default/public/logo.png b/packages/create-gea/templates/default/public/logo.png new file mode 100644 index 00000000..fdcff7b5 Binary files /dev/null and b/packages/create-gea/templates/default/public/logo.png differ diff --git a/packages/create-gea/template/src/app.tsx b/packages/create-gea/templates/default/src/app.tsx similarity index 100% rename from packages/create-gea/template/src/app.tsx rename to packages/create-gea/templates/default/src/app.tsx diff --git a/packages/create-gea/templates/default/src/counter-note.tsx b/packages/create-gea/templates/default/src/counter-note.tsx new file mode 100644 index 00000000..cd8b401f --- /dev/null +++ b/packages/create-gea/templates/default/src/counter-note.tsx @@ -0,0 +1,14 @@ +interface CounterNoteProps { + count: number +} + +export default function CounterNote({ count }: CounterNoteProps) { + return ( +
+

Function component

+

+ This component receives the count as a prop. Count is {count}. +

+
+ ) +} diff --git a/packages/create-gea/templates/default/src/counter-panel.tsx b/packages/create-gea/templates/default/src/counter-panel.tsx new file mode 100644 index 00000000..fdf2b2f4 --- /dev/null +++ b/packages/create-gea/templates/default/src/counter-panel.tsx @@ -0,0 +1,21 @@ +import { Component } from '@geajs/core' +import counterStore from './counter-store' + +export default class CounterPanel extends Component { + template() { + return ( +
+

Class component

+

{counterStore.count}

+
+ + +
+
+ ) + } +} diff --git a/packages/create-gea/templates/default/src/counter-store.ts b/packages/create-gea/templates/default/src/counter-store.ts new file mode 100644 index 00000000..805d6d86 --- /dev/null +++ b/packages/create-gea/templates/default/src/counter-store.ts @@ -0,0 +1,15 @@ +import { Store } from '@geajs/core' + +class CounterStore extends Store { + count = 0 + + increment() { + this.count++ + } + + decrement() { + this.count-- + } +} + +export default new CounterStore() diff --git a/packages/create-gea/template/src/main.ts b/packages/create-gea/templates/default/src/main.ts similarity index 100% rename from packages/create-gea/template/src/main.ts rename to packages/create-gea/templates/default/src/main.ts diff --git a/packages/create-gea/template/src/styles.css b/packages/create-gea/templates/default/src/styles.css similarity index 100% rename from packages/create-gea/template/src/styles.css rename to packages/create-gea/templates/default/src/styles.css diff --git a/packages/create-gea/templates/default/tsconfig.json b/packages/create-gea/templates/default/tsconfig.json new file mode 100644 index 00000000..e4ce5665 --- /dev/null +++ b/packages/create-gea/templates/default/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "Bundler", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "declaration": false, + "noEmit": true, + "strict": false, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "skipLibCheck": true, + "jsx": "preserve" + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts", "vite.config.ts"], + "exclude": ["dist", "node_modules"] +} diff --git a/packages/create-gea/template/vite.config.ts b/packages/create-gea/templates/default/vite.config.ts similarity index 100% rename from packages/create-gea/template/vite.config.ts rename to packages/create-gea/templates/default/vite.config.ts diff --git a/packages/create-gea/templates/mobile/_gitignore b/packages/create-gea/templates/mobile/_gitignore new file mode 100644 index 00000000..f06235c4 --- /dev/null +++ b/packages/create-gea/templates/mobile/_gitignore @@ -0,0 +1,2 @@ +node_modules +dist diff --git a/packages/create-gea/templates/mobile/index.html b/packages/create-gea/templates/mobile/index.html new file mode 100644 index 00000000..96c1d00d --- /dev/null +++ b/packages/create-gea/templates/mobile/index.html @@ -0,0 +1,13 @@ + + + + + + + __PROJECT_TITLE__ + + +
+ + + diff --git a/packages/create-gea/templates/mobile/package.json b/packages/create-gea/templates/mobile/package.json new file mode 100644 index 00000000..138d6ee0 --- /dev/null +++ b/packages/create-gea/templates/mobile/package.json @@ -0,0 +1,20 @@ +{ + "name": "__PACKAGE_NAME__", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "@geajs/core": "^1.0.0", + "@geajs/mobile": "^1.0.0" + }, + "devDependencies": { + "typescript": "^5.9.3", + "vite": "^8.0.0", + "@geajs/vite-plugin": "^1.0.0" + } +} diff --git a/packages/create-gea/templates/mobile/public/favicon.ico b/packages/create-gea/templates/mobile/public/favicon.ico new file mode 100644 index 00000000..8cc45d3b Binary files /dev/null and b/packages/create-gea/templates/mobile/public/favicon.ico differ diff --git a/packages/create-gea/templates/mobile/public/logo.png b/packages/create-gea/templates/mobile/public/logo.png new file mode 100644 index 00000000..fdcff7b5 Binary files /dev/null and b/packages/create-gea/templates/mobile/public/logo.png differ diff --git a/packages/create-gea/templates/mobile/src/app.tsx b/packages/create-gea/templates/mobile/src/app.tsx new file mode 100644 index 00000000..6ea54cbf --- /dev/null +++ b/packages/create-gea/templates/mobile/src/app.tsx @@ -0,0 +1,18 @@ +import { Component } from '@geajs/core' +import CounterNote from './counter-note' +import CounterPanel from './counter-panel' +import counterStore from './counter-store' + +export default class App extends Component { + template() { + return ( +
+ +

Hello from Gea.

+

A tiny starter with a shared store, one class component, and one function component.

+ + +
+ ) + } +} diff --git a/packages/create-gea/templates/mobile/src/counter-note.tsx b/packages/create-gea/templates/mobile/src/counter-note.tsx new file mode 100644 index 00000000..cd8b401f --- /dev/null +++ b/packages/create-gea/templates/mobile/src/counter-note.tsx @@ -0,0 +1,14 @@ +interface CounterNoteProps { + count: number +} + +export default function CounterNote({ count }: CounterNoteProps) { + return ( +
+

Function component

+

+ This component receives the count as a prop. Count is {count}. +

+
+ ) +} diff --git a/packages/create-gea/templates/mobile/src/counter-panel.tsx b/packages/create-gea/templates/mobile/src/counter-panel.tsx new file mode 100644 index 00000000..fdf2b2f4 --- /dev/null +++ b/packages/create-gea/templates/mobile/src/counter-panel.tsx @@ -0,0 +1,21 @@ +import { Component } from '@geajs/core' +import counterStore from './counter-store' + +export default class CounterPanel extends Component { + template() { + return ( +
+

Class component

+

{counterStore.count}

+
+ + +
+
+ ) + } +} diff --git a/packages/create-gea/templates/mobile/src/counter-store.ts b/packages/create-gea/templates/mobile/src/counter-store.ts new file mode 100644 index 00000000..805d6d86 --- /dev/null +++ b/packages/create-gea/templates/mobile/src/counter-store.ts @@ -0,0 +1,15 @@ +import { Store } from '@geajs/core' + +class CounterStore extends Store { + count = 0 + + increment() { + this.count++ + } + + decrement() { + this.count-- + } +} + +export default new CounterStore() diff --git a/packages/create-gea/templates/mobile/src/main.ts b/packages/create-gea/templates/mobile/src/main.ts new file mode 100644 index 00000000..2fe3ff70 --- /dev/null +++ b/packages/create-gea/templates/mobile/src/main.ts @@ -0,0 +1,11 @@ +import App from './app' +import './styles.css' + +const root = document.getElementById('app') + +if (!root) { + throw new Error('App root element not found') +} + +const app = new App() +app.render(root) diff --git a/packages/create-gea/templates/mobile/src/styles.css b/packages/create-gea/templates/mobile/src/styles.css new file mode 100644 index 00000000..7949b461 --- /dev/null +++ b/packages/create-gea/templates/mobile/src/styles.css @@ -0,0 +1,136 @@ +:root { + color: #e5eef6; + background: #0b1220; + font-family: Inter, system-ui, sans-serif; + line-height: 1.5; + font-weight: 400; +} + +* { + box-sizing: border-box; +} + +html, +body { + margin: 0; + min-height: 100%; +} + +body { + min-height: 100vh; + background: + radial-gradient(circle at top, rgba(56, 189, 248, 0.18), transparent 32%), + linear-gradient(180deg, #0f172a 0%, #020617 100%); +} + +#app { + min-height: 100vh; + display: grid; + place-items: center; + padding: 24px; +} + +.app { + width: min(100%, 420px); + padding: 32px; + border: 1px solid rgba(148, 163, 184, 0.2); + border-radius: 20px; + background: rgba(15, 23, 42, 0.82); + box-shadow: 0 20px 80px rgba(15, 23, 42, 0.45); + display: grid; + gap: 16px; +} + +.logo { + width: 100%; + height: auto; + margin-bottom: 8px; +} + +h1 { + margin: 0; + font-size: clamp(2rem, 5vw, 2.6rem); + line-height: 1.05; +} + +.copy { + margin: 14px 0 0; + color: #94a3b8; +} + +code { + color: #f8fafc; + font-family: SFMono-Regular, ui-monospace, monospace; +} + +.panel { + padding: 18px; + border: 1px solid rgba(148, 163, 184, 0.18); + border-radius: 16px; + background: rgba(30, 41, 59, 0.45); +} + +.panel-subtle { + background: rgba(15, 23, 42, 0.45); +} + +.label { + margin: 0 0 10px; + color: #67e8f9; + font-size: 0.78rem; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.count { + margin: 0; + font-size: 3rem; + font-weight: 800; + line-height: 1; +} + +.actions { + display: flex; + gap: 10px; + margin-top: 18px; +} + +.button { + border: 0; + border-radius: 999px; + padding: 12px 18px; + font: inherit; + font-weight: 700; + color: #082f49; + background: #67e8f9; + cursor: pointer; + transition: + transform 0.15s ease, + box-shadow 0.15s ease; + box-shadow: 0 10px 30px rgba(103, 232, 249, 0.28); +} + +.button:hover { + transform: translateY(-1px); +} + +.button:active { + transform: translateY(0); +} + +.button-muted { + color: #e2e8f0; + background: rgba(148, 163, 184, 0.16); + box-shadow: none; +} + +.link-button { + padding: 0; + border: 0; + background: transparent; + color: #67e8f9; + font: inherit; + font-weight: 700; + cursor: pointer; +} diff --git a/packages/create-gea/templates/mobile/tsconfig.json b/packages/create-gea/templates/mobile/tsconfig.json new file mode 100644 index 00000000..e4ce5665 --- /dev/null +++ b/packages/create-gea/templates/mobile/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "Bundler", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "declaration": false, + "noEmit": true, + "strict": false, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "skipLibCheck": true, + "jsx": "preserve" + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts", "vite.config.ts"], + "exclude": ["dist", "node_modules"] +} diff --git a/packages/create-gea/templates/mobile/vite.config.ts b/packages/create-gea/templates/mobile/vite.config.ts new file mode 100644 index 00000000..b8271f1e --- /dev/null +++ b/packages/create-gea/templates/mobile/vite.config.ts @@ -0,0 +1,6 @@ +import { defineConfig } from 'vite' +import { geaPlugin } from '@geajs/vite-plugin' + +export default defineConfig({ + plugins: [geaPlugin()], +}) diff --git a/packages/gea-cli/bin/gea.js b/packages/gea-cli/bin/gea.js new file mode 100755 index 00000000..66c339f0 --- /dev/null +++ b/packages/gea-cli/bin/gea.js @@ -0,0 +1,141 @@ +#!/usr/bin/env node + +import { Command } from 'commander' +import { intro, outro, select, text, spinner, confirm, isCancel, cancel } from '@clack/prompts' +import { cyan, green, yellow, gray } from 'kolorist' +import { execa } from 'execa' +import fs from 'fs-extra' +import { resolve, dirname, basename } from 'node:path' +import { fileURLToPath } from 'node:url' + +const __dirname = dirname(fileURLToPath(import.meta.url)) +const program = new Command() + +async function getProjectRoot() { + let current = process.cwd() + while (true) { + if (await fs.pathExists(resolve(current, 'package.json'))) { + const pkg = await fs.readJson(resolve(current, 'package.json')) + if (pkg.dependencies?.['@geajs/core'] || pkg.devDependencies?.['@geajs/core']) { + return current + } + } + const parent = dirname(current) + if (parent === current) break + current = parent + } + return null +} + +program + .name('gea') + .description('The command line interface for the Gea framework') + .version('1.0.0') + +program + .command('init') + .description('Scaffold a new Gea project') + .argument('[project-name]', 'Name of the project') + .action(async (name) => { + intro(cyan('gea init')) + + try { + if (!name) { + name = await text({ + message: 'Project name:', + placeholder: 'my-gea-app', + }) + if (isCancel(name)) { + cancel('Operation cancelled') + process.exit(0) + } + } + + const s = spinner() + s.start('Initalizing project...') + + await execa('npm', ['create', 'gea@latest', name], { stdio: 'inherit' }) + + s.stop(green('Project initialized!')) + outro(`Happy coding with ${cyan('Gea')}!`) + } catch (e) { + cancel(`Error: ${e.message}`) + process.exit(1) + } + }) + +program + .command('dev') + .description('Launch the development server') + .action(async () => { + const root = await getProjectRoot() + if (!root) { + console.error(yellow('Not in a Gea project!')) + process.exit(1) + } + + await execa('npm', ['run', 'dev'], { stdio: 'inherit', cwd: root }) + }) + +program + .command('add') + .description('Add a new component or store to your project') + .argument('', 'Type of element: component|store') + .argument('', 'Name of the element') + .action(async (type, name) => { + const root = await getProjectRoot() + if (!root) { + console.error(yellow('Not in a Gea project!')) + process.exit(1) + } + + if (name.includes('/') || name.includes('\\') || name.includes('..')) { + console.error(yellow('Invalid name: path segments are not allowed')) + process.exit(1) + } + + const s = spinner() + s.start(`Adding ${type} ${name}...`) + + const srcDir = resolve(root, 'src') + if (!await fs.pathExists(srcDir)) { + await fs.mkdirp(srcDir) + } + + if (type === 'component') { + const fileName = name.endsWith('.tsx') ? name : `${name}.tsx` + const filePath = resolve(srcDir, fileName) + + const content = `import { Component } from '@geajs/core'; + +export default class ${name} extends Component { + template() { + return ( +
+

Hello from ${name}

+
+ ); + } +} +` + await fs.writeFile(filePath, content) + s.stop(green(`Added component: ${gray(filePath)}`)) + } else if (type === 'store') { + const fileName = name.endsWith('.ts') ? name : `${name}.ts` + const filePath = resolve(srcDir, fileName) + + const content = `import { Store } from '@geajs/core'; + +export const ${name} = new Store({ + count: 0, +}); +` + await fs.writeFile(filePath, content) + s.stop(green(`Added store: ${gray(filePath)}`)) + } else { + s.stop(yellow(`Unknown type: ${type}`)) + process.exit(1) + } + }) + +program.parse() diff --git a/packages/gea-cli/package.json b/packages/gea-cli/package.json new file mode 100644 index 00000000..8979503d --- /dev/null +++ b/packages/gea-cli/package.json @@ -0,0 +1,22 @@ +{ + "name": "gea-cli", + "version": "1.0.0", + "description": "The command line interface for the Gea framework", + "type": "module", + "bin": { + "gea": "bin/gea.js" + }, + "scripts": { + "test": "node --test ./test/*.test.js" + }, + "author": "Hacı Mert Gökhan ", + "license": "MIT", + "dependencies": { + "commander": "^13.1.0", + "@clack/prompts": "^1.1.0", + "kolorist": "^1.8.0", + "picocolors": "^1.1.1", + "execa": "^9.0.2", + "fs-extra": "^11.3.0" + } +} \ No newline at end of file