create-gtkx 1.0.0-rc.2 → 1.0.0-rc.4
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/README.md +4 -5
- package/dist/command.js +4 -4
- package/dist/command.js.map +1 -1
- package/dist/package-managers.d.ts +3 -3
- package/dist/package-managers.js +3 -3
- package/dist/package-managers.js.map +1 -1
- package/dist/scaffolder.d.ts +4 -4
- package/dist/scaffolder.d.ts.map +1 -1
- package/dist/scaffolder.js +31 -31
- package/dist/scaffolder.js.map +1 -1
- package/dist/templates/package.json.ejs +1 -1
- package/dist/templates/vitest.config.ts.ejs +1 -1
- package/dist/templates.d.ts +2 -2
- package/dist/templates.d.ts.map +1 -1
- package/dist/templates.js.map +1 -1
- package/package.json +3 -3
- package/src/command.ts +4 -4
- package/src/package-managers.ts +3 -3
- package/src/scaffolder.ts +40 -40
- package/src/templates/package.json.ejs +1 -1
- package/src/templates/vitest.config.ts.ejs +1 -1
- package/src/templates.ts +2 -2
package/README.md
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
The React framework for Linux.<br />
|
|
9
|
-
|
|
9
|
+
Write native Linux applications with React and TypeScript.
|
|
10
|
+
Built on the GNOME stack and standard web tooling.
|
|
10
11
|
</p>
|
|
11
12
|
|
|
12
13
|
<p align="center">
|
|
@@ -20,15 +21,13 @@
|
|
|
20
21
|
|
|
21
22
|
<p align="center">
|
|
22
23
|
<a href="https://gtkx.dev">Homepage</a> ·
|
|
23
|
-
<a href="https://gtkx.dev/guide/
|
|
24
|
+
<a href="https://gtkx.dev/guide/getting-started">Documentation</a> ·
|
|
24
25
|
<a href="https://github.com/gtkx-org/gtkx/tree/main/examples">Examples</a> ·
|
|
25
26
|
<a href="https://github.com/gtkx-org/gtkx/blob/main/CONTRIBUTING.md">Contributing</a>
|
|
26
27
|
</p>
|
|
27
28
|
|
|
28
29
|
---
|
|
29
30
|
|
|
30
|
-
GTKX generates fully typed bindings for the entire GTK4 and Adwaita surface directly from GObject-Introspection. On top of those bindings you get the React programming model: components and hooks driving GObject instances, with Fast Refresh while you develop.
|
|
31
|
-
|
|
32
31
|
<p align="center">
|
|
33
32
|
<img src="https://raw.githubusercontent.com/gtkx-org/gtkx/main/examples/tutorial/assets/screenshot.png" alt="The Tasks app: an Adwaita window with a sidebar of smart views and colored lists on the left, and a boxed task list on the right." />
|
|
34
33
|
</p>
|
|
@@ -109,7 +108,7 @@ React Native and similar frameworks hide the native toolkit so one API can run e
|
|
|
109
108
|
|
|
110
109
|
### Why Node.js, and why generated bindings
|
|
111
110
|
|
|
112
|
-
GTKX runs on Node.js, which puts native modules, the npm ecosystem, and the tooling built for Node.js APIs within reach. GJS is GNOME's own runtime, built on SpiderMonkey rather than V8; node-gtk runs on Node.js but is lightly maintained, on the older nan/V8 ABI rather than N-API, and still centered on GTK3. The [
|
|
111
|
+
GTKX runs on Node.js, which puts native modules, the npm ecosystem, and the tooling built for Node.js APIs within reach. GJS is GNOME's own runtime, built on SpiderMonkey rather than V8; node-gtk runs on Node.js but is lightly maintained, on the older nan/V8 ABI rather than N-API, and still centered on GTK3. The [Why GTKX guide](https://gtkx.dev/guide/why-gtkx) covers the comparison in full.
|
|
113
112
|
|
|
114
113
|
GTKX generates the TypeScript types and the native FFI calls from the same GObject-Introspection data, so the types cannot drift from the calls they back. Codegen covers the whole GTK4 and Adwaita surface.
|
|
115
114
|
|
package/dist/command.js
CHANGED
|
@@ -82,10 +82,10 @@ const runCreate = async (args) => {
|
|
|
82
82
|
name: args.name,
|
|
83
83
|
applicationId: args["application-id"],
|
|
84
84
|
packageManager,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
isTypescript: args.typescript,
|
|
86
|
+
shouldIncludeTesting: args.vitest,
|
|
87
|
+
isInteractive,
|
|
88
|
+
shouldOverwrite: args.overwrite,
|
|
89
89
|
});
|
|
90
90
|
}
|
|
91
91
|
catch (error) {
|
package/dist/command.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,gCAAgC,EAAuB,MAAM,uBAAuB,CAAC;AACrH,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAa3C;;;;;GAKG;AACH,MAAM,eAAe,GAAG,aAAa,CAAC;IAClC,IAAI,EAAE;QACF,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,+BAA+B;KAC/C;IACD,IAAI,EAAE;QACF,IAAI,EAAE;YACF,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,gEAAgE;YAC7E,QAAQ,EAAE,KAAK;SAClB;QACD,gBAAgB,EAAE;YACd,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,0CAA0C;SAC1D;QACD,iBAAiB,EAAE;YACf,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,IAAI;YACX,WAAW,EAAE,gCAAgC;SAChD;QACD,UAAU,EAAE;YACR,IAAI,EAAE,SAAS;YACf,mBAAmB,EAAE,8DAA8D;YACnF,WAAW,EAAE,wCAAwC;SACxD;QACD,MAAM,EAAE;YACJ,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,gCAAgC;SAChD;QACD,GAAG,EAAE;YACD,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,GAAG;YACV,WAAW,EAAE,0DAA0D;SAC1E;QACD,gBAAgB,EAAE;YACd,IAAI,EAAE,SAAS;YACf,WAAW,EACP,yFAAyF;gBACzF,iBAAiB;SACxB;QACD,SAAS,EAAE;YACP,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,OAAO;YACd,WAAW,EAAE,qFAAqF;SACrG;KACJ;IACD,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,CAAC,KAAyB,EAA8B,EAAE;IAClF,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,uBAAuB,gCAAgC,GAAG,CAAC,CAAC;IACjH,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,KAAc,EAAQ,EAAE;IACnD,IAAI,KAAK,YAAY,sBAAsB,EAAE,CAAC;QAC1C,OAAO;IACX,CAAC;IAED,IAAI,KAAK,YAAY,oBAAoB,EAAE,CAAC;QACxC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QAErB,OAAO;IACX,CAAC;IAED,MAAM,KAAK,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,KAAK,EAAE,IAAuB,EAAiB,EAAE;IAC/D,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;IACvF,MAAM,cAAc,GAAG,mBAAmB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAEpE,IAAI,CAAC;QACD,MAAM,QAAQ,CAAC;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,aAAa,EAAE,IAAI,CAAC,gBAAgB,CAAC;YACrC,cAAc;YACd,
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,gCAAgC,EAAuB,MAAM,uBAAuB,CAAC;AACrH,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAa3C;;;;;GAKG;AACH,MAAM,eAAe,GAAG,aAAa,CAAC;IAClC,IAAI,EAAE;QACF,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,+BAA+B;KAC/C;IACD,IAAI,EAAE;QACF,IAAI,EAAE;YACF,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,gEAAgE;YAC7E,QAAQ,EAAE,KAAK;SAClB;QACD,gBAAgB,EAAE;YACd,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,0CAA0C;SAC1D;QACD,iBAAiB,EAAE;YACf,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,IAAI;YACX,WAAW,EAAE,gCAAgC;SAChD;QACD,UAAU,EAAE;YACR,IAAI,EAAE,SAAS;YACf,mBAAmB,EAAE,8DAA8D;YACnF,WAAW,EAAE,wCAAwC;SACxD;QACD,MAAM,EAAE;YACJ,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,gCAAgC;SAChD;QACD,GAAG,EAAE;YACD,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,GAAG;YACV,WAAW,EAAE,0DAA0D;SAC1E;QACD,gBAAgB,EAAE;YACd,IAAI,EAAE,SAAS;YACf,WAAW,EACP,yFAAyF;gBACzF,iBAAiB;SACxB;QACD,SAAS,EAAE;YACP,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,OAAO;YACd,WAAW,EAAE,qFAAqF;SACrG;KACJ;IACD,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,CAAC,KAAyB,EAA8B,EAAE;IAClF,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,uBAAuB,gCAAgC,GAAG,CAAC,CAAC;IACjH,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,KAAc,EAAQ,EAAE;IACnD,IAAI,KAAK,YAAY,sBAAsB,EAAE,CAAC;QAC1C,OAAO;IACX,CAAC;IAED,IAAI,KAAK,YAAY,oBAAoB,EAAE,CAAC;QACxC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QAErB,OAAO;IACX,CAAC;IAED,MAAM,KAAK,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,KAAK,EAAE,IAAuB,EAAiB,EAAE;IAC/D,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;IACvF,MAAM,cAAc,GAAG,mBAAmB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAEpE,IAAI,CAAC;QACD,MAAM,QAAQ,CAAC;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,aAAa,EAAE,IAAI,CAAC,gBAAgB,CAAC;YACrC,cAAc;YACd,YAAY,EAAE,IAAI,CAAC,UAAU;YAC7B,oBAAoB,EAAE,IAAI,CAAC,MAAM;YACjC,aAAa;YACb,eAAe,EAAE,IAAI,CAAC,SAAS;SAClC,CAAC,CAAC;IACP,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,qBAAqB,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;AACL,CAAC,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,SAAS,EAA0B,CAAC","sourcesContent":["import { defineCommand } from \"citty\";\nimport { OperationCanceledError, ScaffoldAbortedError } from \"./errors.js\";\nimport { isKnownPackageManager, PACKAGE_MANAGER_FLAG_DESCRIPTION, type PackageManager } from \"./package-managers.js\";\nimport { scaffold } from \"./scaffolder.js\";\n\ntype CreateCommandArgs = {\n name?: string | undefined;\n \"application-id\"?: string | undefined;\n \"package-manager\"?: string | undefined;\n typescript?: boolean | undefined;\n vitest?: boolean | undefined;\n yes?: boolean | undefined;\n \"no-interactive\"?: boolean | undefined;\n overwrite?: boolean | undefined;\n};\n\n/**\n * Citty command definition for the CLI `create` subcommand. It declares the\n * scaffolder's arguments (target name, application ID, package manager,\n * TypeScript and Vitest toggles, prompt behavior, and overwrite) and runs the\n * scaffolder to generate a new GTKX application.\n */\nconst scaffoldCommand = defineCommand({\n meta: {\n name: \"create\",\n description: \"Create a new GTKX application\",\n },\n args: {\n name: {\n type: \"positional\",\n description: \"Target directory or project name (e.g. my-app, ., apps/my-app)\",\n required: false,\n },\n \"application-id\": {\n type: \"string\",\n description: \"Application ID (e.g., com.example.myapp)\",\n },\n \"package-manager\": {\n type: \"string\",\n alias: \"pm\",\n description: PACKAGE_MANAGER_FLAG_DESCRIPTION,\n },\n typescript: {\n type: \"boolean\",\n negativeDescription: \"Scaffold the application in JavaScript instead of TypeScript\",\n description: \"Scaffold the application in TypeScript\",\n },\n vitest: {\n type: \"boolean\",\n description: \"Include a Vitest testing setup\",\n },\n yes: {\n type: \"boolean\",\n alias: \"y\",\n description: \"Skip prompts and accept defaults for unspecified options\",\n },\n \"no-interactive\": {\n type: \"boolean\",\n description:\n \"Run without prompts, using the default for every option not passed on the command line \" +\n \"(same as --yes)\",\n },\n overwrite: {\n type: \"boolean\",\n alias: \"force\",\n description: \"Overwrite the contents of a non-empty target directory when running without prompts\",\n },\n },\n run: ({ args }) => runCreate(args),\n});\n\nconst parsePackageManager = (value: string | undefined): PackageManager | undefined => {\n if (value === undefined) {\n return undefined;\n }\n\n if (!isKnownPackageManager(value)) {\n throw new Error(`Unknown package manager \"${value}\". Expected one of: ${PACKAGE_MANAGER_FLAG_DESCRIPTION}.`);\n }\n\n return value;\n};\n\nconst settleScaffoldFailure = (error: unknown): void => {\n if (error instanceof OperationCanceledError) {\n return;\n }\n\n if (error instanceof ScaffoldAbortedError) {\n process.exitCode = 1;\n\n return;\n }\n\n throw error;\n};\n\nconst runCreate = async (args: CreateCommandArgs): Promise<void> => {\n const isInteractive = args[\"no-interactive\"] || args.yes ? false : process.stdin.isTTY;\n const packageManager = parsePackageManager(args[\"package-manager\"]);\n\n try {\n await scaffold({\n name: args.name,\n applicationId: args[\"application-id\"],\n packageManager,\n isTypescript: args.typescript,\n shouldIncludeTesting: args.vitest,\n isInteractive,\n shouldOverwrite: args.overwrite,\n });\n } catch (error) {\n settleScaffoldFailure(error);\n }\n};\n\nexport { scaffoldCommand, runCreate, type CreateCommandArgs };\n"]}
|
|
@@ -4,19 +4,19 @@ declare const PACKAGE_MANAGERS: readonly [{
|
|
|
4
4
|
readonly label: "pnpm";
|
|
5
5
|
readonly devCommand: "pnpm dev";
|
|
6
6
|
readonly installCommand: "pnpm install";
|
|
7
|
-
readonly
|
|
7
|
+
readonly isRecommended: true;
|
|
8
8
|
}, {
|
|
9
9
|
readonly value: "npm";
|
|
10
10
|
readonly label: "npm";
|
|
11
11
|
readonly devCommand: "npm run dev";
|
|
12
12
|
readonly installCommand: "npm install";
|
|
13
|
-
readonly
|
|
13
|
+
readonly isRecommended: false;
|
|
14
14
|
}, {
|
|
15
15
|
readonly value: "yarn";
|
|
16
16
|
readonly label: "yarn";
|
|
17
17
|
readonly devCommand: "yarn dev";
|
|
18
18
|
readonly installCommand: "yarn install";
|
|
19
|
-
readonly
|
|
19
|
+
readonly isRecommended: false;
|
|
20
20
|
}];
|
|
21
21
|
declare const PACKAGE_MANAGER_FLAG_DESCRIPTION: string;
|
|
22
22
|
declare const isKnownPackageManager: (name: string) => name is PackageManager;
|
package/dist/package-managers.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const PACKAGE_MANAGERS = [
|
|
2
|
-
{ value: "pnpm", label: "pnpm", devCommand: "pnpm dev", installCommand: "pnpm install",
|
|
3
|
-
{ value: "npm", label: "npm", devCommand: "npm run dev", installCommand: "npm install",
|
|
4
|
-
{ value: "yarn", label: "yarn", devCommand: "yarn dev", installCommand: "yarn install",
|
|
2
|
+
{ value: "pnpm", label: "pnpm", devCommand: "pnpm dev", installCommand: "pnpm install", isRecommended: true },
|
|
3
|
+
{ value: "npm", label: "npm", devCommand: "npm run dev", installCommand: "npm install", isRecommended: false },
|
|
4
|
+
{ value: "yarn", label: "yarn", devCommand: "yarn dev", installCommand: "yarn install", isRecommended: false },
|
|
5
5
|
];
|
|
6
6
|
const PACKAGE_MANAGER_VALUES = PACKAGE_MANAGERS.map((manager) => manager.value);
|
|
7
7
|
const PACKAGE_MANAGER_FLAG_DESCRIPTION = `Package manager (${PACKAGE_MANAGER_VALUES.join(", ")})`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-managers.js","sourceRoot":"","sources":["../src/package-managers.ts"],"names":[],"mappings":"AAEA,MAAM,gBAAgB,GAAG;IACrB,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"package-managers.js","sourceRoot":"","sources":["../src/package-managers.ts"],"names":[],"mappings":"AAEA,MAAM,gBAAgB,GAAG;IACrB,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,IAAI,EAAE;IAC7G,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,EAAE;IAC9G,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,EAAE;CACxG,CAAC;AAEX,MAAM,sBAAsB,GAAqB,gBAAgB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAClG,MAAM,gCAAgC,GAAG,oBAAoB,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AAElG,MAAM,qBAAqB,GAAG,CAAC,IAAY,EAA0B,EAAE,CAClE,sBAAmC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAExD,OAAO,EAAE,gBAAgB,EAAE,gCAAgC,EAAE,qBAAqB,EAAuB,CAAC","sourcesContent":["type PackageManager = (typeof PACKAGE_MANAGERS)[number][\"value\"];\n\nconst PACKAGE_MANAGERS = [\n { value: \"pnpm\", label: \"pnpm\", devCommand: \"pnpm dev\", installCommand: \"pnpm install\", isRecommended: true },\n { value: \"npm\", label: \"npm\", devCommand: \"npm run dev\", installCommand: \"npm install\", isRecommended: false },\n { value: \"yarn\", label: \"yarn\", devCommand: \"yarn dev\", installCommand: \"yarn install\", isRecommended: false },\n] as const;\n\nconst PACKAGE_MANAGER_VALUES: PackageManager[] = PACKAGE_MANAGERS.map((manager) => manager.value);\nconst PACKAGE_MANAGER_FLAG_DESCRIPTION = `Package manager (${PACKAGE_MANAGER_VALUES.join(\", \")})`;\n\nconst isKnownPackageManager = (name: string): name is PackageManager =>\n (PACKAGE_MANAGER_VALUES as string[]).includes(name);\n\nexport { PACKAGE_MANAGERS, PACKAGE_MANAGER_FLAG_DESCRIPTION, isKnownPackageManager, type PackageManager };\n"]}
|
package/dist/scaffolder.d.ts
CHANGED
|
@@ -3,10 +3,10 @@ type CreateOptions = {
|
|
|
3
3
|
name?: string | undefined;
|
|
4
4
|
applicationId?: string | undefined;
|
|
5
5
|
packageManager?: PackageManager | undefined;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
isTypescript?: boolean | undefined;
|
|
7
|
+
shouldIncludeTesting?: boolean | undefined;
|
|
8
|
+
isInteractive?: boolean | undefined;
|
|
9
|
+
shouldOverwrite?: boolean | undefined;
|
|
10
10
|
};
|
|
11
11
|
declare const scaffold: (options?: CreateOptions) => Promise<void>;
|
|
12
12
|
export { scaffold, type CreateOptions };
|
package/dist/scaffolder.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffolder.d.ts","sourceRoot":"","sources":["../src/scaffolder.ts"],"names":[],"mappings":"AAQA,OAAO,EAA2C,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAIrG,KAAK,aAAa,GAAG;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,cAAc,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IAC5C,
|
|
1
|
+
{"version":3,"file":"scaffolder.d.ts","sourceRoot":"","sources":["../src/scaffolder.ts"],"names":[],"mappings":"AAQA,OAAO,EAA2C,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAIrG,KAAK,aAAa,GAAG;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,cAAc,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IAC5C,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACnC,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3C,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACzC,CAAC;AAscF,QAAA,MAAM,QAAQ,GAAU,UAAS,aAAkB,KAAG,OAAO,CAAC,IAAI,CAuBjE,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,CAAC"}
|
package/dist/scaffolder.js
CHANGED
|
@@ -45,12 +45,12 @@ const isDirEmpty = (dir) => {
|
|
|
45
45
|
const entries = readdirSync(dir);
|
|
46
46
|
return entries.length === 0 || (entries.length === 1 && entries[0] === ".git");
|
|
47
47
|
};
|
|
48
|
-
const getDevDependencies = ({
|
|
48
|
+
const getDevDependencies = ({ isTypescript, shouldIncludeTesting, }) => {
|
|
49
49
|
const devDeps = [...DEV_DEPENDENCIES];
|
|
50
|
-
if (
|
|
50
|
+
if (isTypescript) {
|
|
51
51
|
devDeps.push(...TYPESCRIPT_DEV_DEPENDENCIES);
|
|
52
52
|
}
|
|
53
|
-
if (
|
|
53
|
+
if (shouldIncludeTesting) {
|
|
54
54
|
devDeps.push(...TESTING_DEV_DEPENDENCIES);
|
|
55
55
|
}
|
|
56
56
|
return devDeps;
|
|
@@ -115,7 +115,7 @@ const packageManagerHint = (manager, detected) => {
|
|
|
115
115
|
if (detected === manager.value) {
|
|
116
116
|
return "detected";
|
|
117
117
|
}
|
|
118
|
-
if (manager.
|
|
118
|
+
if (manager.isRecommended) {
|
|
119
119
|
return "recommended";
|
|
120
120
|
}
|
|
121
121
|
return undefined;
|
|
@@ -168,8 +168,8 @@ const validateResolvedOptions = (name, applicationId) => {
|
|
|
168
168
|
}
|
|
169
169
|
};
|
|
170
170
|
const confirmOverwrite = async (target, options) => {
|
|
171
|
-
if (!options.
|
|
172
|
-
return options.
|
|
171
|
+
if (!options.isInteractive) {
|
|
172
|
+
return options.shouldOverwrite === true;
|
|
173
173
|
}
|
|
174
174
|
return guardCancellation(await p.confirm({
|
|
175
175
|
message: `Directory "${target}" is not empty. Overwrite its contents?`,
|
|
@@ -190,7 +190,7 @@ const resolveTarget = async (options) => {
|
|
|
190
190
|
if (options.name !== undefined) {
|
|
191
191
|
return formatTargetDir(options.name);
|
|
192
192
|
}
|
|
193
|
-
if (!options.
|
|
193
|
+
if (!options.isInteractive) {
|
|
194
194
|
return fail("Project directory is required");
|
|
195
195
|
}
|
|
196
196
|
return formatTargetDir(await promptTarget());
|
|
@@ -199,28 +199,28 @@ const resolveApplicationId = async (options, name) => {
|
|
|
199
199
|
if (options.applicationId !== undefined) {
|
|
200
200
|
return options.applicationId;
|
|
201
201
|
}
|
|
202
|
-
return options.
|
|
202
|
+
return options.isInteractive ? promptApplicationId(name) : suggestApplicationId(name);
|
|
203
203
|
};
|
|
204
204
|
const resolvePackageManager = async (options) => {
|
|
205
205
|
if (options.packageManager !== undefined) {
|
|
206
206
|
return options.packageManager;
|
|
207
207
|
}
|
|
208
|
-
if (options.
|
|
208
|
+
if (options.isInteractive) {
|
|
209
209
|
return promptPackageManager();
|
|
210
210
|
}
|
|
211
211
|
return (await detectedPackageManager()) ?? "pnpm";
|
|
212
212
|
};
|
|
213
213
|
const resolveTypeScript = async (options) => {
|
|
214
|
-
if (options.
|
|
215
|
-
return options.
|
|
214
|
+
if (options.isTypescript !== undefined) {
|
|
215
|
+
return options.isTypescript;
|
|
216
216
|
}
|
|
217
|
-
return options.
|
|
217
|
+
return options.isInteractive ? promptTypeScript() : true;
|
|
218
218
|
};
|
|
219
219
|
const resolveIncludeTesting = async (options) => {
|
|
220
|
-
if (options.
|
|
221
|
-
return options.
|
|
220
|
+
if (options.shouldIncludeTesting !== undefined) {
|
|
221
|
+
return options.shouldIncludeTesting;
|
|
222
222
|
}
|
|
223
|
-
return options.
|
|
223
|
+
return options.isInteractive ? promptTesting() : true;
|
|
224
224
|
};
|
|
225
225
|
const resolveOptions = async (options) => {
|
|
226
226
|
const target = await resolveTarget(options);
|
|
@@ -231,15 +231,15 @@ const resolveOptions = async (options) => {
|
|
|
231
231
|
await handleTargetDirectory(root, target, options);
|
|
232
232
|
const packageManager = await resolvePackageManager(options);
|
|
233
233
|
const isTypescript = await resolveTypeScript(options);
|
|
234
|
-
const
|
|
235
|
-
return { target, name, applicationId, packageManager,
|
|
234
|
+
const shouldIncludeTesting = await resolveIncludeTesting(options);
|
|
235
|
+
return { target, name, applicationId, packageManager, isTypescript, shouldIncludeTesting };
|
|
236
236
|
};
|
|
237
237
|
const isTemplateIncluded = (templateRelativePath, resolved) => {
|
|
238
238
|
if (TESTING_TEMPLATES.has(templateRelativePath)) {
|
|
239
|
-
return resolved.
|
|
239
|
+
return resolved.shouldIncludeTesting;
|
|
240
240
|
}
|
|
241
241
|
if (TYPESCRIPT_TEMPLATES.has(templateRelativePath)) {
|
|
242
|
-
return resolved.
|
|
242
|
+
return resolved.isTypescript;
|
|
243
243
|
}
|
|
244
244
|
return true;
|
|
245
245
|
};
|
|
@@ -251,31 +251,31 @@ const addTestScript = (root) => {
|
|
|
251
251
|
writeFileSync(packageJsonPath, `${JSON.stringify(manifest, null, 4)}\n`);
|
|
252
252
|
};
|
|
253
253
|
const scaffoldProject = async (root, resolved) => {
|
|
254
|
-
const { name, applicationId,
|
|
254
|
+
const { name, applicationId, isTypescript, shouldIncludeTesting } = resolved;
|
|
255
255
|
const context = {
|
|
256
256
|
name,
|
|
257
257
|
applicationId,
|
|
258
258
|
title: titleFromName(name),
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
importExtension:
|
|
259
|
+
shouldIncludeTesting,
|
|
260
|
+
isTypescript,
|
|
261
|
+
importExtension: isTypescript ? ".js" : ".jsx",
|
|
262
262
|
};
|
|
263
263
|
mkdirSync(root, { recursive: true });
|
|
264
264
|
for (const template of listTemplates()) {
|
|
265
265
|
if (!isTemplateIncluded(template, resolved)) {
|
|
266
266
|
continue;
|
|
267
267
|
}
|
|
268
|
-
const destination = join(root, toDestinationPath(template,
|
|
268
|
+
const destination = join(root, toDestinationPath(template, isTypescript));
|
|
269
269
|
mkdirSync(dirname(destination), { recursive: true });
|
|
270
270
|
writeFileSync(destination, await renderFile(template, context));
|
|
271
271
|
}
|
|
272
|
-
if (
|
|
272
|
+
if (shouldIncludeTesting) {
|
|
273
273
|
addTestScript(root);
|
|
274
274
|
}
|
|
275
275
|
};
|
|
276
276
|
const installDependencies = async (options) => {
|
|
277
|
-
const { cwd, packageManager, dependencies,
|
|
278
|
-
await addDependency(dependencies, { cwd, packageManager, dev, silent: true });
|
|
277
|
+
const { cwd, packageManager, dependencies, isDev } = options;
|
|
278
|
+
await addDependency(dependencies, { cwd, packageManager, dev: isDev, silent: true });
|
|
279
279
|
};
|
|
280
280
|
const pin = (names) => names.map((dependency) => pinGtkxDependency(dependency, selfVersion));
|
|
281
281
|
const installAllDependencies = async (options) => {
|
|
@@ -283,8 +283,8 @@ const installAllDependencies = async (options) => {
|
|
|
283
283
|
const spinner = p.spinner();
|
|
284
284
|
spinner.start("Installing dependencies...");
|
|
285
285
|
try {
|
|
286
|
-
await installDependencies({ cwd: root, packageManager, dependencies: pin(DEPENDENCIES),
|
|
287
|
-
await installDependencies({ cwd: root, packageManager, dependencies: pin(devDependencies),
|
|
286
|
+
await installDependencies({ cwd: root, packageManager, dependencies: pin(DEPENDENCIES), isDev: false });
|
|
287
|
+
await installDependencies({ cwd: root, packageManager, dependencies: pin(devDependencies), isDev: true });
|
|
288
288
|
spinner.stop("Dependencies installed");
|
|
289
289
|
}
|
|
290
290
|
catch (error) {
|
|
@@ -316,7 +316,7 @@ const initializeGitRepo = async (root) => {
|
|
|
316
316
|
const printNextSteps = (resolved) => {
|
|
317
317
|
const devCmd = getDevCommand(resolved.packageManager);
|
|
318
318
|
const cdStep = resolved.target === "." ? "" : `cd ${resolved.target}\n`;
|
|
319
|
-
const testingNote = resolved.
|
|
319
|
+
const testingNote = resolved.shouldIncludeTesting ? HEADLESS_COMPOSITOR_NOTE : "";
|
|
320
320
|
p.note(`${cdStep}${devCmd}${testingNote}`, "Next steps");
|
|
321
321
|
};
|
|
322
322
|
const scaffold = async (options = {}) => {
|
|
@@ -334,7 +334,7 @@ const scaffold = async (options = {}) => {
|
|
|
334
334
|
packageManager: resolved.packageManager,
|
|
335
335
|
devDependencies: devDeps,
|
|
336
336
|
});
|
|
337
|
-
if (resolved.
|
|
337
|
+
if (resolved.isTypescript) {
|
|
338
338
|
writeInitialEnvModule(root);
|
|
339
339
|
}
|
|
340
340
|
await initializeGitRepo(root);
|
package/dist/scaffolder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffolder.js","sourceRoot":"","sources":["../src/scaffolder.ts"],"names":[],"mappings":"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","sourcesContent":["import * as p from \"@clack/prompts\";\nimport { isValidApplicationId } from \"@gtkx/config/internal\";\nimport { errorMessage, packageVersion, upperFirst } from \"@gtkx/utils\";\nimport { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { addDependency, detectPackageManager as nypmDetectPackageManager } from \"nypm\";\nimport { x } from \"tinyexec\";\nimport { OperationCanceledError, ScaffoldAbortedError } from \"./errors.js\";\nimport { isKnownPackageManager, PACKAGE_MANAGERS, type PackageManager } from \"./package-managers.js\";\nimport { isValidProjectName } from \"./project-name.js\";\nimport { listTemplates, renderFile, type TemplateContext } from \"./templates.js\";\n\ntype CreateOptions = {\n name?: string | undefined;\n applicationId?: string | undefined;\n packageManager?: PackageManager | undefined;\n typescript?: boolean | undefined;\n includeTesting?: boolean | undefined;\n interactive?: boolean | undefined;\n overwrite?: boolean | undefined;\n};\n\ntype ResolvedOptions = {\n target: string;\n name: string;\n applicationId: string;\n packageManager: PackageManager;\n typescript: boolean;\n includeTesting: boolean;\n};\n\ntype InstallDependenciesOptions = {\n cwd: string;\n packageManager: PackageManager;\n dependencies: string[];\n dev: boolean;\n};\n\ntype InstallAllOptions = {\n root: string;\n target: string;\n packageManager: PackageManager;\n devDependencies: string[];\n};\n\nconst selfVersion = packageVersion(import.meta.url);\n\nconst GTKX_ENV_MODULE_HEADER = `/**\n * Generated by \\`gtkx codegen\\`, \\`gtkx dev\\`, and \\`gtkx build\\`; do not edit.\n */`;\n\nconst DEPENDENCIES = [\"@gtkx/css\", \"@gtkx/runtime\", \"@gtkx/react\", \"react\"];\nconst DEV_DEPENDENCIES = [\"@gtkx/cli\", \"@gtkx/config\", \"vite\"];\nconst TYPESCRIPT_DEV_DEPENDENCIES = [\"@types/node\", \"@types/react\", \"typescript\"];\nconst TESTING_DEV_DEPENDENCIES = [\"@gtkx/testing\", \"vitest\"];\n\nconst DEV_COMMAND: Record<PackageManager, string> = Object.fromEntries(\n PACKAGE_MANAGERS.map((manager) => [manager.value, manager.devCommand]),\n) as Record<PackageManager, string>;\n\nconst INSTALL_COMMAND: Record<PackageManager, string> = Object.fromEntries(\n PACKAGE_MANAGERS.map((manager) => [manager.value, manager.installCommand]),\n) as Record<PackageManager, string>;\n\nconst TESTING_TEMPLATES = new Set([\"vitest.config.ts\", \"tests/app.test.tsx\"]);\nconst TYPESCRIPT_TEMPLATES = new Set([\"tsconfig.json\", \"src/gtkx-env.d.ts\"]);\nconst PACKAGE_JSON_TEMPLATE = \"package.json\";\n\nconst HEADLESS_COMPOSITOR_NOTE = `\n\nTo run tests, you need a headless Wayland compositor installed:\n Fedora: sudo dnf install sway\n Ubuntu: sudo apt install sway`;\n\nconst pinGtkxDependency = (name: string, version: string): string =>\n name.startsWith(\"@gtkx/\") ? `${name}@^${version}` : name;\n\nconst getDevCommand = (packageManager: PackageManager): string => DEV_COMMAND[packageManager];\nconst getInstallCommand = (packageManager: PackageManager): string => INSTALL_COMMAND[packageManager];\nconst titleFromName = (name: string): string => name.split(\"-\").map((part) => upperFirst(part)).join(\" \");\nconst suggestApplicationId = (name: string): string => `com.${name.replaceAll(\"-\", \"\")}.app`;\n\nconst stripTrailingSlashes = (value: string): string => {\n let end = value.length;\n\n while (end > 0 && value[end - 1] === \"/\") {\n end--;\n }\n\n return value.slice(0, end);\n};\n\nconst formatTargetDir = (target: string): string => stripTrailingSlashes(target.trim().replaceAll(/[<>:\"\\\\|?*]/g, \"\"));\nconst deriveProjectName = (target: string): string => basename(resolve(process.cwd(), target));\n\nconst isDirEmpty = (dir: string): boolean => {\n const entries = readdirSync(dir);\n\n return entries.length === 0 || (entries.length === 1 && entries[0] === \".git\");\n};\n\nconst getDevDependencies = ({\n typescript,\n includeTesting,\n}: Pick<ResolvedOptions, \"typescript\" | \"includeTesting\">): string[] => {\n const devDeps = [...DEV_DEPENDENCIES];\n\n if (typescript) {\n devDeps.push(...TYPESCRIPT_DEV_DEPENDENCIES);\n }\n\n if (includeTesting) {\n devDeps.push(...TESTING_DEV_DEPENDENCIES);\n }\n\n return devDeps;\n};\n\nconst guardCancellation = <T>(value: T | symbol): T => {\n if (p.isCancel(value)) {\n p.cancel(\"Operation canceled\");\n throw new OperationCanceledError();\n }\n\n return value;\n};\n\nconst validateProjectName = (value: string | undefined): string | undefined => {\n if (!value) {\n return \"Project name is required\";\n }\n\n if (!isValidProjectName(value)) {\n return \"Project name must be lowercase letters, numbers, and hyphens only\";\n }\n\n return undefined;\n};\n\nconst validateApplicationIdInput = (value: string | undefined): string | undefined => {\n if (!value) {\n return \"Application ID is required\";\n }\n\n if (!isValidApplicationId(value)) {\n return \"Application ID must be reverse domain notation (e.g., com.example.myapp)\";\n }\n\n return undefined;\n};\n\nconst fail = (message: string): never => {\n p.log.error(message);\n throw new ScaffoldAbortedError(message);\n};\n\nconst validateTarget = (value: string | undefined): string | undefined => {\n if (!value) {\n return \"Project directory is required\";\n }\n\n return validateProjectName(deriveProjectName(formatTargetDir(value)));\n};\n\nconst promptTarget = async (): Promise<string> =>\n guardCancellation(\n await p.text({\n message: \"Project directory\",\n placeholder: \"my-app\",\n validate: validateTarget,\n }),\n );\n\nconst promptApplicationId = async (name: string): Promise<string> => {\n const defaultApplicationId = suggestApplicationId(name);\n\n return guardCancellation(\n await p.text({\n message: \"Application ID\",\n placeholder: defaultApplicationId,\n initialValue: defaultApplicationId,\n validate: validateApplicationIdInput,\n }),\n );\n};\n\nconst detectPackageManager = async (cwd: string): Promise<PackageManager | undefined> => {\n const detected = await nypmDetectPackageManager(cwd, { includeParentDirs: true });\n\n if (!detected) {\n return undefined;\n }\n\n return isKnownPackageManager(detected.name) ? detected.name : undefined;\n};\n\nconst packageManagerHint = (\n manager: (typeof PACKAGE_MANAGERS)[number],\n detected: PackageManager | undefined,\n): string | undefined => {\n if (detected === manager.value) {\n return \"detected\";\n }\n\n if (manager.recommended) {\n return \"recommended\";\n }\n\n return undefined;\n};\n\nconst packageManagerOption = (manager: (typeof PACKAGE_MANAGERS)[number], detected: PackageManager | undefined) => {\n const hint = packageManagerHint(manager, detected);\n\n return { value: manager.value, label: manager.label, ...(hint !== undefined && { hint }) };\n};\n\nconst detectedPackageManager = async (): Promise<PackageManager | undefined> => {\n try {\n return await detectPackageManager(process.cwd());\n } catch {\n return undefined;\n }\n};\n\nconst promptPackageManager = async (): Promise<PackageManager> => {\n const detected = await detectedPackageManager();\n const initial: PackageManager = detected ?? \"pnpm\";\n\n return guardCancellation(\n await p.select<PackageManager>({\n message: \"Package manager\",\n options: PACKAGE_MANAGERS.map((manager) => packageManagerOption(manager, detected)),\n initialValue: initial,\n }),\n );\n};\n\nconst promptTypeScript = async (): Promise<boolean> =>\n guardCancellation(\n await p.confirm({\n message: \"Use TypeScript?\",\n initialValue: true,\n }),\n );\n\nconst promptTesting = async (): Promise<boolean> =>\n guardCancellation(\n await p.confirm({\n message: \"Include testing setup (Vitest)?\",\n initialValue: true,\n }),\n );\n\nconst emptyDir = (root: string): void => {\n for (const entry of readdirSync(root)) {\n if (entry === \".git\") {\n continue;\n }\n\n rmSync(join(root, entry), { recursive: true, force: true });\n }\n};\n\nconst validateResolvedOptions = (name: string, applicationId: string): void => {\n const nameError = validateProjectName(name);\n\n if (nameError) {\n fail(nameError);\n }\n\n const applicationIdError = validateApplicationIdInput(applicationId);\n\n if (applicationIdError) {\n fail(applicationIdError);\n }\n};\n\nconst confirmOverwrite = async (target: string, options: CreateOptions): Promise<boolean> => {\n if (!options.interactive) {\n return options.overwrite === true;\n }\n\n return guardCancellation(\n await p.confirm({\n message: `Directory \"${target}\" is not empty. Overwrite its contents?`,\n initialValue: false,\n }),\n );\n};\n\nconst handleTargetDirectory = async (root: string, target: string, options: CreateOptions): Promise<void> => {\n if (!existsSync(root) || isDirEmpty(root)) {\n return;\n }\n\n if (await confirmOverwrite(target, options)) {\n emptyDir(root);\n\n return;\n }\n\n fail(`Directory \"${target}\" is not empty`);\n};\n\nconst resolveTarget = async (options: CreateOptions): Promise<string> => {\n if (options.name !== undefined) {\n return formatTargetDir(options.name);\n }\n\n if (!options.interactive) {\n return fail(\"Project directory is required\");\n }\n\n return formatTargetDir(await promptTarget());\n};\n\nconst resolveApplicationId = async (options: CreateOptions, name: string): Promise<string> => {\n if (options.applicationId !== undefined) {\n return options.applicationId;\n }\n\n return options.interactive ? promptApplicationId(name) : suggestApplicationId(name);\n};\n\nconst resolvePackageManager = async (options: CreateOptions): Promise<PackageManager> => {\n if (options.packageManager !== undefined) {\n return options.packageManager;\n }\n\n if (options.interactive) {\n return promptPackageManager();\n }\n\n return (await detectedPackageManager()) ?? \"pnpm\";\n};\n\nconst resolveTypeScript = async (options: CreateOptions): Promise<boolean> => {\n if (options.typescript !== undefined) {\n return options.typescript;\n }\n\n return options.interactive ? promptTypeScript() : true;\n};\n\nconst resolveIncludeTesting = async (options: CreateOptions): Promise<boolean> => {\n if (options.includeTesting !== undefined) {\n return options.includeTesting;\n }\n\n return options.interactive ? promptTesting() : true;\n};\n\nconst resolveOptions = async (options: CreateOptions): Promise<ResolvedOptions> => {\n const target = await resolveTarget(options);\n const name = deriveProjectName(target);\n const applicationId = await resolveApplicationId(options, name);\n validateResolvedOptions(name, applicationId);\n const root = resolve(process.cwd(), target);\n await handleTargetDirectory(root, target, options);\n const packageManager = await resolvePackageManager(options);\n const isTypescript = await resolveTypeScript(options);\n const isIncludeTesting = await resolveIncludeTesting(options);\n\n return { target, name, applicationId, packageManager, typescript: isTypescript, includeTesting: isIncludeTesting };\n};\n\nconst isTemplateIncluded = (templateRelativePath: string, resolved: ResolvedOptions): boolean => {\n if (TESTING_TEMPLATES.has(templateRelativePath)) {\n return resolved.includeTesting;\n }\n\n if (TYPESCRIPT_TEMPLATES.has(templateRelativePath)) {\n return resolved.typescript;\n }\n\n return true;\n};\n\nconst toDestinationPath = (templateRelativePath: string, isTypescript: boolean): string =>\n isTypescript ? templateRelativePath : templateRelativePath.replace(/\\.tsx$/, \".jsx\").replace(/\\.ts$/, \".js\");\n\nconst addTestScript = (root: string): void => {\n const packageJsonPath = join(root, PACKAGE_JSON_TEMPLATE);\n\n const manifest = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as {\n scripts: Record<string, string>;\n };\n\n manifest.scripts.test = \"vitest\";\n writeFileSync(packageJsonPath, `${JSON.stringify(manifest, null, 4)}\\n`);\n};\n\nconst scaffoldProject = async (root: string, resolved: ResolvedOptions): Promise<void> => {\n const { name, applicationId, typescript, includeTesting } = resolved;\n\n const context: TemplateContext = {\n name,\n applicationId,\n title: titleFromName(name),\n includeTesting,\n typescript,\n importExtension: typescript ? \".js\" : \".jsx\",\n };\n\n mkdirSync(root, { recursive: true });\n\n for (const template of listTemplates()) {\n if (!isTemplateIncluded(template, resolved)) {\n continue;\n }\n\n const destination = join(root, toDestinationPath(template, typescript));\n mkdirSync(dirname(destination), { recursive: true });\n writeFileSync(destination, await renderFile(template, context));\n }\n\n if (includeTesting) {\n addTestScript(root);\n }\n};\n\nconst installDependencies = async (options: InstallDependenciesOptions): Promise<void> => {\n const { cwd, packageManager, dependencies, dev } = options;\n await addDependency(dependencies, { cwd, packageManager, dev, silent: true });\n};\n\nconst pin = (names: string[]): string[] => names.map((dependency) => pinGtkxDependency(dependency, selfVersion));\n\nconst installAllDependencies = async (options: InstallAllOptions): Promise<void> => {\n const { root, target, packageManager, devDependencies } = options;\n const spinner = p.spinner();\n spinner.start(\"Installing dependencies...\");\n\n try {\n await installDependencies({ cwd: root, packageManager, dependencies: pin(DEPENDENCIES), dev: false });\n await installDependencies({ cwd: root, packageManager, dependencies: pin(devDependencies), dev: true });\n spinner.stop(\"Dependencies installed\");\n } catch (error) {\n spinner.stop(\"Failed to install dependencies\");\n p.log.error(`Failed to install dependencies: ${errorMessage(error)}`);\n p.log.info(`Install them manually by running:\\n cd ${target}\\n ${getInstallCommand(packageManager)}`);\n throw new ScaffoldAbortedError(\"Failed to install dependencies\");\n }\n};\n\nconst writeInitialEnvModule = (root: string): void => {\n const storeDir = join(root, \"node_modules\", \".gtkx\");\n mkdirSync(storeDir, { recursive: true });\n writeFileSync(join(storeDir, \"env.d.ts\"), `${GTKX_ENV_MODULE_HEADER}\\n`);\n};\n\nconst initializeGitRepo = async (root: string): Promise<void> => {\n const spinner = p.spinner();\n spinner.start(\"Initializing git repository...\");\n\n try {\n const opts = { nodeOptions: { cwd: root }, throwOnError: true } as const;\n await x(\"git\", [\"init\"], opts);\n await x(\"git\", [\"add\", \"-A\"], opts);\n await x(\"git\", [\"commit\", \"-m\", \"Initial commit\"], opts);\n spinner.stop(\"Git repository initialized\");\n } catch {\n spinner.stop(\"Failed to initialize git repository\");\n }\n};\n\nconst printNextSteps = (resolved: ResolvedOptions): void => {\n const devCmd = getDevCommand(resolved.packageManager);\n const cdStep = resolved.target === \".\" ? \"\" : `cd ${resolved.target}\\n`;\n const testingNote = resolved.includeTesting ? HEADLESS_COMPOSITOR_NOTE : \"\";\n p.note(`${cdStep}${devCmd}${testingNote}`, \"Next steps\");\n};\n\nconst scaffold = async (options: CreateOptions = {}): Promise<void> => {\n p.intro(\"Create GTKX App\");\n const resolved = await resolveOptions(options);\n const root = resolve(process.cwd(), resolved.target);\n const devDeps = getDevDependencies(resolved);\n const projectSpinner = p.spinner();\n projectSpinner.start(\"Creating project structure...\");\n await scaffoldProject(root, resolved);\n projectSpinner.stop(\"Project structure created\");\n\n await installAllDependencies({\n root,\n target: resolved.target,\n packageManager: resolved.packageManager,\n devDependencies: devDeps,\n });\n\n if (resolved.typescript) {\n writeInitialEnvModule(root);\n }\n\n await initializeGitRepo(root);\n printNextSteps(resolved);\n};\n\nexport { scaffold, type CreateOptions };\n"]}
|
|
1
|
+
{"version":3,"file":"scaffolder.js","sourceRoot":"","sources":["../src/scaffolder.ts"],"names":[],"mappings":"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","sourcesContent":["import * as p from \"@clack/prompts\";\nimport { isValidApplicationId } from \"@gtkx/config/internal\";\nimport { errorMessage, packageVersion, upperFirst } from \"@gtkx/utils\";\nimport { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { addDependency, detectPackageManager as nypmDetectPackageManager } from \"nypm\";\nimport { x } from \"tinyexec\";\nimport { OperationCanceledError, ScaffoldAbortedError } from \"./errors.js\";\nimport { isKnownPackageManager, PACKAGE_MANAGERS, type PackageManager } from \"./package-managers.js\";\nimport { isValidProjectName } from \"./project-name.js\";\nimport { listTemplates, renderFile, type TemplateContext } from \"./templates.js\";\n\ntype CreateOptions = {\n name?: string | undefined;\n applicationId?: string | undefined;\n packageManager?: PackageManager | undefined;\n isTypescript?: boolean | undefined;\n shouldIncludeTesting?: boolean | undefined;\n isInteractive?: boolean | undefined;\n shouldOverwrite?: boolean | undefined;\n};\n\ntype ResolvedOptions = {\n target: string;\n name: string;\n applicationId: string;\n packageManager: PackageManager;\n isTypescript: boolean;\n shouldIncludeTesting: boolean;\n};\n\ntype InstallDependenciesOptions = {\n cwd: string;\n packageManager: PackageManager;\n dependencies: string[];\n isDev: boolean;\n};\n\ntype InstallAllOptions = {\n root: string;\n target: string;\n packageManager: PackageManager;\n devDependencies: string[];\n};\n\nconst selfVersion = packageVersion(import.meta.url);\n\nconst GTKX_ENV_MODULE_HEADER = `/**\n * Generated by \\`gtkx codegen\\`, \\`gtkx dev\\`, and \\`gtkx build\\`; do not edit.\n */`;\n\nconst DEPENDENCIES = [\"@gtkx/css\", \"@gtkx/runtime\", \"@gtkx/react\", \"react\"];\nconst DEV_DEPENDENCIES = [\"@gtkx/cli\", \"@gtkx/config\", \"vite\"];\nconst TYPESCRIPT_DEV_DEPENDENCIES = [\"@types/node\", \"@types/react\", \"typescript\"];\nconst TESTING_DEV_DEPENDENCIES = [\"@gtkx/testing\", \"vitest\"];\n\nconst DEV_COMMAND: Record<PackageManager, string> = Object.fromEntries(\n PACKAGE_MANAGERS.map((manager) => [manager.value, manager.devCommand]),\n) as Record<PackageManager, string>;\n\nconst INSTALL_COMMAND: Record<PackageManager, string> = Object.fromEntries(\n PACKAGE_MANAGERS.map((manager) => [manager.value, manager.installCommand]),\n) as Record<PackageManager, string>;\n\nconst TESTING_TEMPLATES = new Set([\"vitest.config.ts\", \"tests/app.test.tsx\"]);\nconst TYPESCRIPT_TEMPLATES = new Set([\"tsconfig.json\", \"src/gtkx-env.d.ts\"]);\nconst PACKAGE_JSON_TEMPLATE = \"package.json\";\n\nconst HEADLESS_COMPOSITOR_NOTE = `\n\nTo run tests, you need a headless Wayland compositor installed:\n Fedora: sudo dnf install sway\n Ubuntu: sudo apt install sway`;\n\nconst pinGtkxDependency = (name: string, version: string): string =>\n name.startsWith(\"@gtkx/\") ? `${name}@^${version}` : name;\n\nconst getDevCommand = (packageManager: PackageManager): string => DEV_COMMAND[packageManager];\nconst getInstallCommand = (packageManager: PackageManager): string => INSTALL_COMMAND[packageManager];\nconst titleFromName = (name: string): string => name.split(\"-\").map((part) => upperFirst(part)).join(\" \");\nconst suggestApplicationId = (name: string): string => `com.${name.replaceAll(\"-\", \"\")}.app`;\n\nconst stripTrailingSlashes = (value: string): string => {\n let end = value.length;\n\n while (end > 0 && value[end - 1] === \"/\") {\n end--;\n }\n\n return value.slice(0, end);\n};\n\nconst formatTargetDir = (target: string): string => stripTrailingSlashes(target.trim().replaceAll(/[<>:\"\\\\|?*]/g, \"\"));\nconst deriveProjectName = (target: string): string => basename(resolve(process.cwd(), target));\n\nconst isDirEmpty = (dir: string): boolean => {\n const entries = readdirSync(dir);\n\n return entries.length === 0 || (entries.length === 1 && entries[0] === \".git\");\n};\n\nconst getDevDependencies = ({\n isTypescript,\n shouldIncludeTesting,\n}: Pick<ResolvedOptions, \"isTypescript\" | \"shouldIncludeTesting\">): string[] => {\n const devDeps = [...DEV_DEPENDENCIES];\n\n if (isTypescript) {\n devDeps.push(...TYPESCRIPT_DEV_DEPENDENCIES);\n }\n\n if (shouldIncludeTesting) {\n devDeps.push(...TESTING_DEV_DEPENDENCIES);\n }\n\n return devDeps;\n};\n\nconst guardCancellation = <T>(value: T | symbol): T => {\n if (p.isCancel(value)) {\n p.cancel(\"Operation canceled\");\n throw new OperationCanceledError();\n }\n\n return value;\n};\n\nconst validateProjectName = (value: string | undefined): string | undefined => {\n if (!value) {\n return \"Project name is required\";\n }\n\n if (!isValidProjectName(value)) {\n return \"Project name must be lowercase letters, numbers, and hyphens only\";\n }\n\n return undefined;\n};\n\nconst validateApplicationIdInput = (value: string | undefined): string | undefined => {\n if (!value) {\n return \"Application ID is required\";\n }\n\n if (!isValidApplicationId(value)) {\n return \"Application ID must be reverse domain notation (e.g., com.example.myapp)\";\n }\n\n return undefined;\n};\n\nconst fail = (message: string): never => {\n p.log.error(message);\n throw new ScaffoldAbortedError(message);\n};\n\nconst validateTarget = (value: string | undefined): string | undefined => {\n if (!value) {\n return \"Project directory is required\";\n }\n\n return validateProjectName(deriveProjectName(formatTargetDir(value)));\n};\n\nconst promptTarget = async (): Promise<string> =>\n guardCancellation(\n await p.text({\n message: \"Project directory\",\n placeholder: \"my-app\",\n validate: validateTarget,\n }),\n );\n\nconst promptApplicationId = async (name: string): Promise<string> => {\n const defaultApplicationId = suggestApplicationId(name);\n\n return guardCancellation(\n await p.text({\n message: \"Application ID\",\n placeholder: defaultApplicationId,\n initialValue: defaultApplicationId,\n validate: validateApplicationIdInput,\n }),\n );\n};\n\nconst detectPackageManager = async (cwd: string): Promise<PackageManager | undefined> => {\n const detected = await nypmDetectPackageManager(cwd, { includeParentDirs: true });\n\n if (!detected) {\n return undefined;\n }\n\n return isKnownPackageManager(detected.name) ? detected.name : undefined;\n};\n\nconst packageManagerHint = (\n manager: (typeof PACKAGE_MANAGERS)[number],\n detected: PackageManager | undefined,\n): string | undefined => {\n if (detected === manager.value) {\n return \"detected\";\n }\n\n if (manager.isRecommended) {\n return \"recommended\";\n }\n\n return undefined;\n};\n\nconst packageManagerOption = (manager: (typeof PACKAGE_MANAGERS)[number], detected: PackageManager | undefined) => {\n const hint = packageManagerHint(manager, detected);\n\n return { value: manager.value, label: manager.label, ...(hint !== undefined && { hint }) };\n};\n\nconst detectedPackageManager = async (): Promise<PackageManager | undefined> => {\n try {\n return await detectPackageManager(process.cwd());\n } catch {\n return undefined;\n }\n};\n\nconst promptPackageManager = async (): Promise<PackageManager> => {\n const detected = await detectedPackageManager();\n const initial: PackageManager = detected ?? \"pnpm\";\n\n return guardCancellation(\n await p.select<PackageManager>({\n message: \"Package manager\",\n options: PACKAGE_MANAGERS.map((manager) => packageManagerOption(manager, detected)),\n initialValue: initial,\n }),\n );\n};\n\nconst promptTypeScript = async (): Promise<boolean> =>\n guardCancellation(\n await p.confirm({\n message: \"Use TypeScript?\",\n initialValue: true,\n }),\n );\n\nconst promptTesting = async (): Promise<boolean> =>\n guardCancellation(\n await p.confirm({\n message: \"Include testing setup (Vitest)?\",\n initialValue: true,\n }),\n );\n\nconst emptyDir = (root: string): void => {\n for (const entry of readdirSync(root)) {\n if (entry === \".git\") {\n continue;\n }\n\n rmSync(join(root, entry), { recursive: true, force: true });\n }\n};\n\nconst validateResolvedOptions = (name: string, applicationId: string): void => {\n const nameError = validateProjectName(name);\n\n if (nameError) {\n fail(nameError);\n }\n\n const applicationIdError = validateApplicationIdInput(applicationId);\n\n if (applicationIdError) {\n fail(applicationIdError);\n }\n};\n\nconst confirmOverwrite = async (target: string, options: CreateOptions): Promise<boolean> => {\n if (!options.isInteractive) {\n return options.shouldOverwrite === true;\n }\n\n return guardCancellation(\n await p.confirm({\n message: `Directory \"${target}\" is not empty. Overwrite its contents?`,\n initialValue: false,\n }),\n );\n};\n\nconst handleTargetDirectory = async (root: string, target: string, options: CreateOptions): Promise<void> => {\n if (!existsSync(root) || isDirEmpty(root)) {\n return;\n }\n\n if (await confirmOverwrite(target, options)) {\n emptyDir(root);\n\n return;\n }\n\n fail(`Directory \"${target}\" is not empty`);\n};\n\nconst resolveTarget = async (options: CreateOptions): Promise<string> => {\n if (options.name !== undefined) {\n return formatTargetDir(options.name);\n }\n\n if (!options.isInteractive) {\n return fail(\"Project directory is required\");\n }\n\n return formatTargetDir(await promptTarget());\n};\n\nconst resolveApplicationId = async (options: CreateOptions, name: string): Promise<string> => {\n if (options.applicationId !== undefined) {\n return options.applicationId;\n }\n\n return options.isInteractive ? promptApplicationId(name) : suggestApplicationId(name);\n};\n\nconst resolvePackageManager = async (options: CreateOptions): Promise<PackageManager> => {\n if (options.packageManager !== undefined) {\n return options.packageManager;\n }\n\n if (options.isInteractive) {\n return promptPackageManager();\n }\n\n return (await detectedPackageManager()) ?? \"pnpm\";\n};\n\nconst resolveTypeScript = async (options: CreateOptions): Promise<boolean> => {\n if (options.isTypescript !== undefined) {\n return options.isTypescript;\n }\n\n return options.isInteractive ? promptTypeScript() : true;\n};\n\nconst resolveIncludeTesting = async (options: CreateOptions): Promise<boolean> => {\n if (options.shouldIncludeTesting !== undefined) {\n return options.shouldIncludeTesting;\n }\n\n return options.isInteractive ? promptTesting() : true;\n};\n\nconst resolveOptions = async (options: CreateOptions): Promise<ResolvedOptions> => {\n const target = await resolveTarget(options);\n const name = deriveProjectName(target);\n const applicationId = await resolveApplicationId(options, name);\n validateResolvedOptions(name, applicationId);\n const root = resolve(process.cwd(), target);\n await handleTargetDirectory(root, target, options);\n const packageManager = await resolvePackageManager(options);\n const isTypescript = await resolveTypeScript(options);\n const shouldIncludeTesting = await resolveIncludeTesting(options);\n\n return { target, name, applicationId, packageManager, isTypescript, shouldIncludeTesting };\n};\n\nconst isTemplateIncluded = (templateRelativePath: string, resolved: ResolvedOptions): boolean => {\n if (TESTING_TEMPLATES.has(templateRelativePath)) {\n return resolved.shouldIncludeTesting;\n }\n\n if (TYPESCRIPT_TEMPLATES.has(templateRelativePath)) {\n return resolved.isTypescript;\n }\n\n return true;\n};\n\nconst toDestinationPath = (templateRelativePath: string, isTypescript: boolean): string =>\n isTypescript ? templateRelativePath : templateRelativePath.replace(/\\.tsx$/, \".jsx\").replace(/\\.ts$/, \".js\");\n\nconst addTestScript = (root: string): void => {\n const packageJsonPath = join(root, PACKAGE_JSON_TEMPLATE);\n\n const manifest = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as {\n scripts: Record<string, string>;\n };\n\n manifest.scripts.test = \"vitest\";\n writeFileSync(packageJsonPath, `${JSON.stringify(manifest, null, 4)}\\n`);\n};\n\nconst scaffoldProject = async (root: string, resolved: ResolvedOptions): Promise<void> => {\n const { name, applicationId, isTypescript, shouldIncludeTesting } = resolved;\n\n const context: TemplateContext = {\n name,\n applicationId,\n title: titleFromName(name),\n shouldIncludeTesting,\n isTypescript,\n importExtension: isTypescript ? \".js\" : \".jsx\",\n };\n\n mkdirSync(root, { recursive: true });\n\n for (const template of listTemplates()) {\n if (!isTemplateIncluded(template, resolved)) {\n continue;\n }\n\n const destination = join(root, toDestinationPath(template, isTypescript));\n mkdirSync(dirname(destination), { recursive: true });\n writeFileSync(destination, await renderFile(template, context));\n }\n\n if (shouldIncludeTesting) {\n addTestScript(root);\n }\n};\n\nconst installDependencies = async (options: InstallDependenciesOptions): Promise<void> => {\n const { cwd, packageManager, dependencies, isDev } = options;\n await addDependency(dependencies, { cwd, packageManager, dev: isDev, silent: true });\n};\n\nconst pin = (names: string[]): string[] => names.map((dependency) => pinGtkxDependency(dependency, selfVersion));\n\nconst installAllDependencies = async (options: InstallAllOptions): Promise<void> => {\n const { root, target, packageManager, devDependencies } = options;\n const spinner = p.spinner();\n spinner.start(\"Installing dependencies...\");\n\n try {\n await installDependencies({ cwd: root, packageManager, dependencies: pin(DEPENDENCIES), isDev: false });\n await installDependencies({ cwd: root, packageManager, dependencies: pin(devDependencies), isDev: true });\n spinner.stop(\"Dependencies installed\");\n } catch (error) {\n spinner.stop(\"Failed to install dependencies\");\n p.log.error(`Failed to install dependencies: ${errorMessage(error)}`);\n p.log.info(`Install them manually by running:\\n cd ${target}\\n ${getInstallCommand(packageManager)}`);\n throw new ScaffoldAbortedError(\"Failed to install dependencies\");\n }\n};\n\nconst writeInitialEnvModule = (root: string): void => {\n const storeDir = join(root, \"node_modules\", \".gtkx\");\n mkdirSync(storeDir, { recursive: true });\n writeFileSync(join(storeDir, \"env.d.ts\"), `${GTKX_ENV_MODULE_HEADER}\\n`);\n};\n\nconst initializeGitRepo = async (root: string): Promise<void> => {\n const spinner = p.spinner();\n spinner.start(\"Initializing git repository...\");\n\n try {\n const opts = { nodeOptions: { cwd: root }, throwOnError: true } as const;\n await x(\"git\", [\"init\"], opts);\n await x(\"git\", [\"add\", \"-A\"], opts);\n await x(\"git\", [\"commit\", \"-m\", \"Initial commit\"], opts);\n spinner.stop(\"Git repository initialized\");\n } catch {\n spinner.stop(\"Failed to initialize git repository\");\n }\n};\n\nconst printNextSteps = (resolved: ResolvedOptions): void => {\n const devCmd = getDevCommand(resolved.packageManager);\n const cdStep = resolved.target === \".\" ? \"\" : `cd ${resolved.target}\\n`;\n const testingNote = resolved.shouldIncludeTesting ? HEADLESS_COMPOSITOR_NOTE : \"\";\n p.note(`${cdStep}${devCmd}${testingNote}`, \"Next steps\");\n};\n\nconst scaffold = async (options: CreateOptions = {}): Promise<void> => {\n p.intro(\"Create GTKX App\");\n const resolved = await resolveOptions(options);\n const root = resolve(process.cwd(), resolved.target);\n const devDeps = getDevDependencies(resolved);\n const projectSpinner = p.spinner();\n projectSpinner.start(\"Creating project structure...\");\n await scaffoldProject(root, resolved);\n projectSpinner.stop(\"Project structure created\");\n\n await installAllDependencies({\n root,\n target: resolved.target,\n packageManager: resolved.packageManager,\n devDependencies: devDeps,\n });\n\n if (resolved.isTypescript) {\n writeInitialEnvModule(root);\n }\n\n await initializeGitRepo(root);\n printNextSteps(resolved);\n};\n\nexport { scaffold, type CreateOptions };\n"]}
|
|
@@ -4,7 +4,7 @@ import { defineConfig } from "vitest/config";
|
|
|
4
4
|
export default defineConfig({
|
|
5
5
|
plugins: [gtkx()],
|
|
6
6
|
test: {
|
|
7
|
-
include: ["tests/**/*.test.{<%=
|
|
7
|
+
include: ["tests/**/*.test.{<%= isTypescript ? "ts,tsx" : "js,jsx" %>}"],
|
|
8
8
|
bail: 1,
|
|
9
9
|
},
|
|
10
10
|
});
|
package/dist/templates.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ type TemplateContext = {
|
|
|
2
2
|
name: string;
|
|
3
3
|
applicationId: string;
|
|
4
4
|
title: string;
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
shouldIncludeTesting: boolean;
|
|
6
|
+
isTypescript: boolean;
|
|
7
7
|
importExtension: string;
|
|
8
8
|
};
|
|
9
9
|
declare const listTemplates: () => string[];
|
package/dist/templates.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAKA,KAAK,eAAe,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAKA,KAAK,eAAe,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB,EAAE,OAAO,CAAC;IAC9B,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CAC3B,CAAC;AAMF,QAAA,MAAM,aAAa,QAAO,MAAM,EAO3B,CAAC;AAEN,QAAA,MAAM,UAAU,GAAU,cAAc,MAAM,EAAE,SAAS,eAAe,KAAG,OAAO,CAAC,MAAM,CACd,CAAC;AAE5E,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,CAAC"}
|
package/dist/templates.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAWjC,MAAM,eAAe,GAAG,GAAW,EAAE;IACjC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AAClD,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,GAAa,EAAE,CACjC,WAAW,CACP,WAAW,CAAC,eAAe,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;KACnE,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;KACjC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;KAClD,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;KACzF,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CACzD,CAAC;AAEN,MAAM,UAAU,GAAG,KAAK,EAAE,YAAoB,EAAE,OAAwB,EAAmB,EAAE,CACzF,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,GAAG,YAAY,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;AAE5E,OAAO,EAAE,aAAa,EAAE,UAAU,EAAwB,CAAC","sourcesContent":["import { sortStrings } from \"@gtkx/utils\";\nimport ejs from \"ejs\";\nimport { readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\ntype TemplateContext = {\n name: string;\n applicationId: string;\n title: string;\n
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAWjC,MAAM,eAAe,GAAG,GAAW,EAAE;IACjC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AAClD,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,GAAa,EAAE,CACjC,WAAW,CACP,WAAW,CAAC,eAAe,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;KACnE,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;KACjC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;KAClD,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;KACzF,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CACzD,CAAC;AAEN,MAAM,UAAU,GAAG,KAAK,EAAE,YAAoB,EAAE,OAAwB,EAAmB,EAAE,CACzF,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,GAAG,YAAY,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;AAE5E,OAAO,EAAE,aAAa,EAAE,UAAU,EAAwB,CAAC","sourcesContent":["import { sortStrings } from \"@gtkx/utils\";\nimport ejs from \"ejs\";\nimport { readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\ntype TemplateContext = {\n name: string;\n applicationId: string;\n title: string;\n shouldIncludeTesting: boolean;\n isTypescript: boolean;\n importExtension: string;\n};\n\nconst getTemplatesDir = (): string => {\n return join(import.meta.dirname, \"templates\");\n};\n\nconst listTemplates = (): string[] =>\n sortStrings(\n readdirSync(getTemplatesDir(), { recursive: true, withFileTypes: true })\n .filter((entry) => entry.isFile())\n .map((entry) => join(entry.parentPath, entry.name))\n .map((absolute) => absolute.slice(getTemplatesDir().length + 1).replaceAll(/[/\\\\]/g, \"/\"))\n .map((relative) => relative.replace(/\\.ejs$/, \"\")),\n );\n\nconst renderFile = async (templateName: string, context: TemplateContext): Promise<string> =>\n ejs.renderFile(join(getTemplatesDir(), `${templateName}.ejs`), context);\n\nexport { listTemplates, renderFile, type TemplateContext };\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-gtkx",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.4",
|
|
4
4
|
"description": "Scaffold a new native GTK4 + React desktop application with GTKX",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gtkx",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"citty": "^0.2.2",
|
|
52
52
|
"nypm": "^0.6.9",
|
|
53
53
|
"tinyexec": "^1.2.4",
|
|
54
|
-
"@gtkx/
|
|
55
|
-
"@gtkx/
|
|
54
|
+
"@gtkx/config": "1.0.0-rc.4",
|
|
55
|
+
"@gtkx/utils": "1.0.0-rc.4"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@types/ejs": "^3.1.5",
|
package/src/command.ts
CHANGED
|
@@ -104,10 +104,10 @@ const runCreate = async (args: CreateCommandArgs): Promise<void> => {
|
|
|
104
104
|
name: args.name,
|
|
105
105
|
applicationId: args["application-id"],
|
|
106
106
|
packageManager,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
isTypescript: args.typescript,
|
|
108
|
+
shouldIncludeTesting: args.vitest,
|
|
109
|
+
isInteractive,
|
|
110
|
+
shouldOverwrite: args.overwrite,
|
|
111
111
|
});
|
|
112
112
|
} catch (error) {
|
|
113
113
|
settleScaffoldFailure(error);
|
package/src/package-managers.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
type PackageManager = (typeof PACKAGE_MANAGERS)[number]["value"];
|
|
2
2
|
|
|
3
3
|
const PACKAGE_MANAGERS = [
|
|
4
|
-
{ value: "pnpm", label: "pnpm", devCommand: "pnpm dev", installCommand: "pnpm install",
|
|
5
|
-
{ value: "npm", label: "npm", devCommand: "npm run dev", installCommand: "npm install",
|
|
6
|
-
{ value: "yarn", label: "yarn", devCommand: "yarn dev", installCommand: "yarn install",
|
|
4
|
+
{ value: "pnpm", label: "pnpm", devCommand: "pnpm dev", installCommand: "pnpm install", isRecommended: true },
|
|
5
|
+
{ value: "npm", label: "npm", devCommand: "npm run dev", installCommand: "npm install", isRecommended: false },
|
|
6
|
+
{ value: "yarn", label: "yarn", devCommand: "yarn dev", installCommand: "yarn install", isRecommended: false },
|
|
7
7
|
] as const;
|
|
8
8
|
|
|
9
9
|
const PACKAGE_MANAGER_VALUES: PackageManager[] = PACKAGE_MANAGERS.map((manager) => manager.value);
|
package/src/scaffolder.ts
CHANGED
|
@@ -14,10 +14,10 @@ type CreateOptions = {
|
|
|
14
14
|
name?: string | undefined;
|
|
15
15
|
applicationId?: string | undefined;
|
|
16
16
|
packageManager?: PackageManager | undefined;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
isTypescript?: boolean | undefined;
|
|
18
|
+
shouldIncludeTesting?: boolean | undefined;
|
|
19
|
+
isInteractive?: boolean | undefined;
|
|
20
|
+
shouldOverwrite?: boolean | undefined;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
type ResolvedOptions = {
|
|
@@ -25,15 +25,15 @@ type ResolvedOptions = {
|
|
|
25
25
|
name: string;
|
|
26
26
|
applicationId: string;
|
|
27
27
|
packageManager: PackageManager;
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
isTypescript: boolean;
|
|
29
|
+
shouldIncludeTesting: boolean;
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
type InstallDependenciesOptions = {
|
|
33
33
|
cwd: string;
|
|
34
34
|
packageManager: PackageManager;
|
|
35
35
|
dependencies: string[];
|
|
36
|
-
|
|
36
|
+
isDev: boolean;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
type InstallAllOptions = {
|
|
@@ -100,16 +100,16 @@ const isDirEmpty = (dir: string): boolean => {
|
|
|
100
100
|
};
|
|
101
101
|
|
|
102
102
|
const getDevDependencies = ({
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}: Pick<ResolvedOptions, "
|
|
103
|
+
isTypescript,
|
|
104
|
+
shouldIncludeTesting,
|
|
105
|
+
}: Pick<ResolvedOptions, "isTypescript" | "shouldIncludeTesting">): string[] => {
|
|
106
106
|
const devDeps = [...DEV_DEPENDENCIES];
|
|
107
107
|
|
|
108
|
-
if (
|
|
108
|
+
if (isTypescript) {
|
|
109
109
|
devDeps.push(...TYPESCRIPT_DEV_DEPENDENCIES);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
if (
|
|
112
|
+
if (shouldIncludeTesting) {
|
|
113
113
|
devDeps.push(...TESTING_DEV_DEPENDENCIES);
|
|
114
114
|
}
|
|
115
115
|
|
|
@@ -202,7 +202,7 @@ const packageManagerHint = (
|
|
|
202
202
|
return "detected";
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
-
if (manager.
|
|
205
|
+
if (manager.isRecommended) {
|
|
206
206
|
return "recommended";
|
|
207
207
|
}
|
|
208
208
|
|
|
@@ -277,8 +277,8 @@ const validateResolvedOptions = (name: string, applicationId: string): void => {
|
|
|
277
277
|
};
|
|
278
278
|
|
|
279
279
|
const confirmOverwrite = async (target: string, options: CreateOptions): Promise<boolean> => {
|
|
280
|
-
if (!options.
|
|
281
|
-
return options.
|
|
280
|
+
if (!options.isInteractive) {
|
|
281
|
+
return options.shouldOverwrite === true;
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
return guardCancellation(
|
|
@@ -308,7 +308,7 @@ const resolveTarget = async (options: CreateOptions): Promise<string> => {
|
|
|
308
308
|
return formatTargetDir(options.name);
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
-
if (!options.
|
|
311
|
+
if (!options.isInteractive) {
|
|
312
312
|
return fail("Project directory is required");
|
|
313
313
|
}
|
|
314
314
|
|
|
@@ -320,7 +320,7 @@ const resolveApplicationId = async (options: CreateOptions, name: string): Promi
|
|
|
320
320
|
return options.applicationId;
|
|
321
321
|
}
|
|
322
322
|
|
|
323
|
-
return options.
|
|
323
|
+
return options.isInteractive ? promptApplicationId(name) : suggestApplicationId(name);
|
|
324
324
|
};
|
|
325
325
|
|
|
326
326
|
const resolvePackageManager = async (options: CreateOptions): Promise<PackageManager> => {
|
|
@@ -328,7 +328,7 @@ const resolvePackageManager = async (options: CreateOptions): Promise<PackageMan
|
|
|
328
328
|
return options.packageManager;
|
|
329
329
|
}
|
|
330
330
|
|
|
331
|
-
if (options.
|
|
331
|
+
if (options.isInteractive) {
|
|
332
332
|
return promptPackageManager();
|
|
333
333
|
}
|
|
334
334
|
|
|
@@ -336,19 +336,19 @@ const resolvePackageManager = async (options: CreateOptions): Promise<PackageMan
|
|
|
336
336
|
};
|
|
337
337
|
|
|
338
338
|
const resolveTypeScript = async (options: CreateOptions): Promise<boolean> => {
|
|
339
|
-
if (options.
|
|
340
|
-
return options.
|
|
339
|
+
if (options.isTypescript !== undefined) {
|
|
340
|
+
return options.isTypescript;
|
|
341
341
|
}
|
|
342
342
|
|
|
343
|
-
return options.
|
|
343
|
+
return options.isInteractive ? promptTypeScript() : true;
|
|
344
344
|
};
|
|
345
345
|
|
|
346
346
|
const resolveIncludeTesting = async (options: CreateOptions): Promise<boolean> => {
|
|
347
|
-
if (options.
|
|
348
|
-
return options.
|
|
347
|
+
if (options.shouldIncludeTesting !== undefined) {
|
|
348
|
+
return options.shouldIncludeTesting;
|
|
349
349
|
}
|
|
350
350
|
|
|
351
|
-
return options.
|
|
351
|
+
return options.isInteractive ? promptTesting() : true;
|
|
352
352
|
};
|
|
353
353
|
|
|
354
354
|
const resolveOptions = async (options: CreateOptions): Promise<ResolvedOptions> => {
|
|
@@ -360,18 +360,18 @@ const resolveOptions = async (options: CreateOptions): Promise<ResolvedOptions>
|
|
|
360
360
|
await handleTargetDirectory(root, target, options);
|
|
361
361
|
const packageManager = await resolvePackageManager(options);
|
|
362
362
|
const isTypescript = await resolveTypeScript(options);
|
|
363
|
-
const
|
|
363
|
+
const shouldIncludeTesting = await resolveIncludeTesting(options);
|
|
364
364
|
|
|
365
|
-
return { target, name, applicationId, packageManager,
|
|
365
|
+
return { target, name, applicationId, packageManager, isTypescript, shouldIncludeTesting };
|
|
366
366
|
};
|
|
367
367
|
|
|
368
368
|
const isTemplateIncluded = (templateRelativePath: string, resolved: ResolvedOptions): boolean => {
|
|
369
369
|
if (TESTING_TEMPLATES.has(templateRelativePath)) {
|
|
370
|
-
return resolved.
|
|
370
|
+
return resolved.shouldIncludeTesting;
|
|
371
371
|
}
|
|
372
372
|
|
|
373
373
|
if (TYPESCRIPT_TEMPLATES.has(templateRelativePath)) {
|
|
374
|
-
return resolved.
|
|
374
|
+
return resolved.isTypescript;
|
|
375
375
|
}
|
|
376
376
|
|
|
377
377
|
return true;
|
|
@@ -392,15 +392,15 @@ const addTestScript = (root: string): void => {
|
|
|
392
392
|
};
|
|
393
393
|
|
|
394
394
|
const scaffoldProject = async (root: string, resolved: ResolvedOptions): Promise<void> => {
|
|
395
|
-
const { name, applicationId,
|
|
395
|
+
const { name, applicationId, isTypescript, shouldIncludeTesting } = resolved;
|
|
396
396
|
|
|
397
397
|
const context: TemplateContext = {
|
|
398
398
|
name,
|
|
399
399
|
applicationId,
|
|
400
400
|
title: titleFromName(name),
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
importExtension:
|
|
401
|
+
shouldIncludeTesting,
|
|
402
|
+
isTypescript,
|
|
403
|
+
importExtension: isTypescript ? ".js" : ".jsx",
|
|
404
404
|
};
|
|
405
405
|
|
|
406
406
|
mkdirSync(root, { recursive: true });
|
|
@@ -410,19 +410,19 @@ const scaffoldProject = async (root: string, resolved: ResolvedOptions): Promise
|
|
|
410
410
|
continue;
|
|
411
411
|
}
|
|
412
412
|
|
|
413
|
-
const destination = join(root, toDestinationPath(template,
|
|
413
|
+
const destination = join(root, toDestinationPath(template, isTypescript));
|
|
414
414
|
mkdirSync(dirname(destination), { recursive: true });
|
|
415
415
|
writeFileSync(destination, await renderFile(template, context));
|
|
416
416
|
}
|
|
417
417
|
|
|
418
|
-
if (
|
|
418
|
+
if (shouldIncludeTesting) {
|
|
419
419
|
addTestScript(root);
|
|
420
420
|
}
|
|
421
421
|
};
|
|
422
422
|
|
|
423
423
|
const installDependencies = async (options: InstallDependenciesOptions): Promise<void> => {
|
|
424
|
-
const { cwd, packageManager, dependencies,
|
|
425
|
-
await addDependency(dependencies, { cwd, packageManager, dev, silent: true });
|
|
424
|
+
const { cwd, packageManager, dependencies, isDev } = options;
|
|
425
|
+
await addDependency(dependencies, { cwd, packageManager, dev: isDev, silent: true });
|
|
426
426
|
};
|
|
427
427
|
|
|
428
428
|
const pin = (names: string[]): string[] => names.map((dependency) => pinGtkxDependency(dependency, selfVersion));
|
|
@@ -433,8 +433,8 @@ const installAllDependencies = async (options: InstallAllOptions): Promise<void>
|
|
|
433
433
|
spinner.start("Installing dependencies...");
|
|
434
434
|
|
|
435
435
|
try {
|
|
436
|
-
await installDependencies({ cwd: root, packageManager, dependencies: pin(DEPENDENCIES),
|
|
437
|
-
await installDependencies({ cwd: root, packageManager, dependencies: pin(devDependencies),
|
|
436
|
+
await installDependencies({ cwd: root, packageManager, dependencies: pin(DEPENDENCIES), isDev: false });
|
|
437
|
+
await installDependencies({ cwd: root, packageManager, dependencies: pin(devDependencies), isDev: true });
|
|
438
438
|
spinner.stop("Dependencies installed");
|
|
439
439
|
} catch (error) {
|
|
440
440
|
spinner.stop("Failed to install dependencies");
|
|
@@ -468,7 +468,7 @@ const initializeGitRepo = async (root: string): Promise<void> => {
|
|
|
468
468
|
const printNextSteps = (resolved: ResolvedOptions): void => {
|
|
469
469
|
const devCmd = getDevCommand(resolved.packageManager);
|
|
470
470
|
const cdStep = resolved.target === "." ? "" : `cd ${resolved.target}\n`;
|
|
471
|
-
const testingNote = resolved.
|
|
471
|
+
const testingNote = resolved.shouldIncludeTesting ? HEADLESS_COMPOSITOR_NOTE : "";
|
|
472
472
|
p.note(`${cdStep}${devCmd}${testingNote}`, "Next steps");
|
|
473
473
|
};
|
|
474
474
|
|
|
@@ -489,7 +489,7 @@ const scaffold = async (options: CreateOptions = {}): Promise<void> => {
|
|
|
489
489
|
devDependencies: devDeps,
|
|
490
490
|
});
|
|
491
491
|
|
|
492
|
-
if (resolved.
|
|
492
|
+
if (resolved.isTypescript) {
|
|
493
493
|
writeInitialEnvModule(root);
|
|
494
494
|
}
|
|
495
495
|
|
|
@@ -4,7 +4,7 @@ import { defineConfig } from "vitest/config";
|
|
|
4
4
|
export default defineConfig({
|
|
5
5
|
plugins: [gtkx()],
|
|
6
6
|
test: {
|
|
7
|
-
include: ["tests/**/*.test.{<%=
|
|
7
|
+
include: ["tests/**/*.test.{<%= isTypescript ? "ts,tsx" : "js,jsx" %>}"],
|
|
8
8
|
bail: 1,
|
|
9
9
|
},
|
|
10
10
|
});
|
package/src/templates.ts
CHANGED