create-gtkx 2.0.0-beta.10 → 2.0.0-beta.11

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 CHANGED
@@ -1,177 +1,19 @@
1
- <p align="center">
2
- <img src="https://raw.githubusercontent.com/gtkx-org/gtkx/main/logo.svg" alt="GTKX" width="100" />
3
- </p>
1
+ # create-gtkx
4
2
 
5
- <h1 align="center">GTKX</h1>
3
+ Create a GTKX application.
6
4
 
7
- <p align="center">
8
- The React framework for Linux.<br />
9
- Write native GNOME applications with React and TypeScript.
10
- Real Adwaita and GTK4 widgets with standard web tooling.
11
- </p>
12
-
13
- <p align="center">
14
- <a href="https://www.npmjs.com/package/create-gtkx"><img src="https://img.shields.io/npm/v/create-gtkx?color=cb3837&logo=npm&label=create-gtkx" alt="npm version" /></a>
15
- <a href="https://www.npmjs.com/package/create-gtkx"><img src="https://img.shields.io/npm/dm/create-gtkx?color=cb3837&logo=npm&label=downloads" alt="npm downloads" /></a>
16
- <img src="https://img.shields.io/badge/node-%E2%89%A526.7-339933?logo=node.js&logoColor=white" alt="Node >= 26.7" />
17
- <a href="https://github.com/gtkx-org/gtkx/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MPL--2.0-blue.svg" alt="License: MPL-2.0" /></a>
18
- <a href="https://github.com/gtkx-org/gtkx/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/gtkx-org/gtkx/ci.yml?branch=main&logo=github&label=CI" alt="CI status" /></a>
19
- <img src="https://img.shields.io/badge/TypeScript-strict-3178c6?logo=typescript&logoColor=white" alt="TypeScript" />
20
- </p>
21
-
22
- <p align="center">
23
- <a href="https://gtkx.dev">Homepage</a> &middot;
24
- <a href="https://gtkx.dev/guide/getting-started">Documentation</a> &middot;
25
- <a href="https://github.com/gtkx-org/gtkx/tree/main/examples">Examples</a> &middot;
26
- <a href="https://github.com/gtkx-org/gtkx/blob/main/CONTRIBUTING.md">Contributing</a>
27
- </p>
28
-
29
- ---
30
-
31
- <p align="center">
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." />
33
- </p>
34
-
35
- <p align="center">
36
- <em>The Tasks app you build in the <a href="https://gtkx.dev/tutorial/">tutorial</a>.</em>
37
- </p>
38
-
39
- ## Demo
40
-
41
- This app starts with an Adwaita application shell, renders native GTK4 widgets inside it, and uses ordinary React hooks and events:
42
-
43
- ```tsx
44
- import * as Gtk from "@gtkx/gi/gtk";
45
- import { AdwApplication, AdwApplicationWindow, AdwHeaderBar, AdwToolbarView } from "@gtkx/jsx/adw";
46
- import { GtkBox, GtkButton, GtkLabel } from "@gtkx/jsx/gtk";
47
- import { createRoot, quit } from "@gtkx/react";
48
- import { useState } from "react";
49
-
50
- const Counter = () => {
51
- const [count, setCount] = useState(0);
52
-
53
- return (
54
- <AdwApplicationWindow
55
- title="Hello GTKX"
56
- defaultWidth={400}
57
- defaultHeight={300}
58
- onCloseRequest={quit}
59
- >
60
- <AdwToolbarView topBar={<AdwHeaderBar />}>
61
- <GtkBox
62
- orientation={Gtk.Orientation.VERTICAL}
63
- spacing={20}
64
- marginTop={40}
65
- marginBottom={40}
66
- marginStart={40}
67
- marginEnd={40}
68
- valign={Gtk.Align.CENTER}
69
- halign={Gtk.Align.CENTER}
70
- >
71
- <GtkLabel cssClasses={["title-1"]}>Welcome to GTKX!</GtkLabel>
72
- <GtkLabel cssClasses={["title-2"]}>{`Count: ${String(count)}`}</GtkLabel>
73
- <GtkButton
74
- label="Increment"
75
- onClicked={() => setCount((c) => c + 1)}
76
- cssClasses={["suggested-action", "pill"]}
77
- />
78
- </GtkBox>
79
- </AdwToolbarView>
80
- </AdwApplicationWindow>
81
- );
82
- };
83
-
84
- const App = () => (
85
- <AdwApplication>
86
- <Counter />
87
- </AdwApplication>
88
- );
89
-
90
- createRoot().render(<App />);
91
- ```
92
-
93
- This is the [`hello-world`](https://github.com/gtkx-org/gtkx/tree/main/examples/hello-world) example, with `app.tsx` and `index.tsx` combined into a single snippet. `@gtkx/gi` and `@gtkx/jsx` are per-project bindings generated by the CLI, not packages you install from npm.
94
-
95
- ## Why GTKX
96
-
97
- ### Adwaita-first application development
98
-
99
- GTKX uses Adwaita as the foundation for applications, windows, navigation, dialogs, and adaptive layouts, with the complete GTK4 toolkit underneath. It adds a declarative React layer and an integrated TypeScript toolchain to the GNOME platform:
100
-
101
- - a React reconciler that exposes every GObject as a JSX element,
102
- - a CLI for scaffolding, development, and production builds,
103
- - a dev server with Fast Refresh that patches your running UI in place,
104
- - CSS-in-JS styling, React Hook Form-powered Adwaita controls, gettext-backed react-i18next localization, React Spring animations, React Navigation stack, tab, drawer, and split view navigators, and high-level list, grid, and dialog components,
105
- - a Testing Library-style API for querying and driving your widgets in tests,
106
- - and a Model Context Protocol (MCP) server that exposes your live app to AI agents.
107
-
108
- ### Native GNOME widgets, without a compatibility layer
109
-
110
- React Native and similar frameworks hide the native toolkit so one API can run everywhere. GTKX renders real Adwaita and GTK4 widgets and exposes any other GObject-Introspection library on your system. It is GNOME-native and Linux-only by design.
111
-
112
- ### Why Node.js, and why generated bindings
113
-
114
- 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 what running on Node.js means day to day.
115
-
116
- GTKX generates the TypeScript types and native FFI calls from the same GObject-Introspection data, so the types cannot drift from the calls they back. `Adw-1` is the sole default GIR root; its GIR include pulls in `Gtk-4.0`, so codegen covers both complete API surfaces. Neither belongs in a GTKX 2 `libraries` list.
117
-
118
- At runtime, the native Rust core calls straight into the system Adwaita, GTK4, and GLib libraries through libffi, without loading libgirepository at all.
119
-
120
- ## Quick start
121
-
122
- GTKX is Linux-only and needs Node.js 26.7 or later. See [Requirements](#requirements).
123
-
124
- Scaffold a new app with the `create-gtkx` initializer:
125
-
126
- ```sh
127
- npm create gtkx@beta
128
- ```
129
-
130
- The same command works with other package managers: `pnpm create gtkx@beta` or `yarn create gtkx@beta`.
131
-
132
- Then run your new app:
5
+ Scaffold a Linux app with React, TypeScript or JavaScript, an Adwaita window, and optional testing support.
133
6
 
134
7
  ```sh
8
+ npm create gtkx@beta my-app
135
9
  cd my-app
136
10
  npm run dev
137
11
  ```
138
12
 
139
- To go further, follow the [tutorial](https://gtkx.dev/tutorial/).
140
-
141
- ## Documentation
142
-
143
- The documentation at **[gtkx.dev](https://gtkx.dev)** includes a step-by-step tutorial that builds a complete GNOME app, from scaffolding to packaging and shipping, plus guides and a full API reference.
144
-
145
- **[Read the docs &rarr;](https://gtkx.dev/guide/why-gtkx)**
146
-
147
- ## Requirements
148
-
149
- GTKX is Linux-only. You need:
150
-
151
- - Linux with the Adwaita (1.8 or later), GTK4 (4.20 or later), and GLib development libraries
152
- - Node.js 26.7 or later
153
-
154
- The `@gtkx/native` addon ships prebuilt for x64 and arm64 glibc Linux; other targets need to build it from the GTKX repository, which requires a Rust toolchain.
155
-
156
- ## Examples
157
-
158
- Explore the [example apps](https://github.com/gtkx-org/gtkx/tree/main/examples):
159
-
160
- - [`hello-world`](https://github.com/gtkx-org/gtkx/tree/main/examples/hello-world): the Adwaita counter above.
161
- - [`gtk-demo`](https://github.com/gtkx-org/gtkx/tree/main/examples/gtk-demo): the official GTK4 widget showcase in an Adwaita application shell, covering lists, dialogs, gestures, CSS, and OpenGL.
162
- - [`browser`](https://github.com/gtkx-org/gtkx/tree/main/examples/browser): an Adwaita browser built around `WebKitWebView`.
163
- - [`animations`](https://github.com/gtkx-org/gtkx/tree/main/examples/animations): an Adwaita showcase for `@gtkx/animated`, with React Spring animations driven by the GTK frame clock.
164
- - [`navigation`](https://github.com/gtkx-org/gtkx/tree/main/examples/navigation): a tour of `@gtkx/navigation`, React Navigation's stack, tab, and drawer navigators rendered with libadwaita.
165
- - [`tutorial`](https://github.com/gtkx-org/gtkx/tree/main/examples/tutorial): the Tasks app the documentation builds.
166
-
167
- ## Status
168
-
169
- GTKX is stable and ready for production use.
170
-
171
- ## Contributing
13
+ Install the [native prerequisites](https://gtkx.dev/v2/guide/getting-started) first. For language, test, package-manager, and overwrite options, see [Scaffold Options](https://gtkx.dev/v2/guide/scaffold-options).
172
14
 
173
- Contributions are welcome. See [CONTRIBUTING.md](https://github.com/gtkx-org/gtkx/blob/main/CONTRIBUTING.md), the [Code of Conduct](https://github.com/gtkx-org/gtkx/blob/main/CODE_OF_CONDUCT.md), and the [security policy](https://github.com/gtkx-org/gtkx/blob/main/SECURITY.md). Building the repo needs Node.js 26.7 or later, pnpm, and a Rust toolchain.
15
+ [Guide](https://gtkx.dev/v2/guide/getting-started) · [GTKX](https://gtkx.dev)
174
16
 
175
- ## License
17
+ GTKX runs on Linux with Node.js and system native libraries. See [Getting Started](https://gtkx.dev/v2/guide/getting-started) for supported versions and installation. This README describes the 2.0 beta.
176
18
 
177
- GTKX is licensed under [MPL-2.0](https://github.com/gtkx-org/gtkx/blob/main/LICENSE).
19
+ [MPL-2.0](https://github.com/gtkx-org/gtkx/blob/main/LICENSE).
@@ -1 +1 @@
1
- {"version":3,"file":"build-allowance.d.ts","sourceRoot":"","sources":["../src/build-allowance.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AA2B5D,QAAA,MAAM,mBAAmB,GAAI,MAAM,MAAM,EAAE,gBAAgB,cAAc,KAAG,IAc3E,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
1
+ {"version":3,"file":"build-allowance.d.ts","sourceRoot":"","sources":["../src/build-allowance.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAyB5D,QAAA,MAAM,mBAAmB,GAAI,MAAM,MAAM,EAAE,gBAAgB,cAAc,KAAG,IAc3E,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -1,14 +1,15 @@
1
1
  import { writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ import { stringify } from "yaml";
3
4
  import { updateManifest } from "./manifest.js";
4
5
  const BUILT_DEPENDENCIES = ["@swc/core", "esbuild"];
5
6
  const PNPM_WORKSPACE_FILE = "pnpm-workspace.yaml";
6
- const SAFE_YAML_KEY = /^[A-Za-z][A-Za-z0-9-]*$/;
7
- const PNPM_PACKAGES_BLOCK = "packages:\n - '.'\n";
8
- const quoteYamlKey = (name) => (SAFE_YAML_KEY.test(name) ? name : `'${name}'`);
9
7
  const writePnpmAllowance = (root) => {
10
- const entries = BUILT_DEPENDENCIES.map((name) => ` ${quoteYamlKey(name)}: true`).join("\n");
11
- writeFileSync(join(root, PNPM_WORKSPACE_FILE), `${PNPM_PACKAGES_BLOCK}allowBuilds:\n${entries}\n`);
8
+ const workspace = {
9
+ packages: ["."],
10
+ allowBuilds: Object.fromEntries(BUILT_DEPENDENCIES.map((name) => [name, true])),
11
+ };
12
+ writeFileSync(join(root, PNPM_WORKSPACE_FILE), stringify(workspace));
12
13
  };
13
14
  const writeNpmAllowance = (root) => {
14
15
  updateManifest(root, (manifest) => {
@@ -1 +1 @@
1
- {"version":3,"file":"build-allowance.js","sourceRoot":"","sources":["../src/build-allowance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,MAAM,kBAAkB,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AACpD,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAClD,MAAM,aAAa,GAAG,yBAAyB,CAAC;AAChD,MAAM,mBAAmB,GAAG,sBAAsB,CAAC;AAEnD,MAAM,YAAY,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;AAE/F,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAQ,EAAE;IAC9C,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7F,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,mBAAmB,CAAC,EAAE,GAAG,mBAAmB,iBAAiB,OAAO,IAAI,CAAC,CAAC;AACvG,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAQ,EAAE;IAC7C,cAAc,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;QAC9B,QAAQ,CAAC,YAAY,GAAG,MAAM,CAAC,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAQ,EAAE;IAC9C,cAAc,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;QAC9B,QAAQ,CAAC,gBAAgB,GAAG,MAAM,CAAC,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9G,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAE,cAA8B,EAAQ,EAAE;IAC/E,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;QAC5B,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAEzB,OAAO;IACX,CAAC;IAED,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;QAC5B,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAEzB,OAAO;IACX,CAAC;IAED,iBAAiB,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,CAAC","sourcesContent":["import { writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { PackageManager } from \"./package-managers.js\";\nimport { updateManifest } from \"./manifest.js\";\n\nconst BUILT_DEPENDENCIES = [\"@swc/core\", \"esbuild\"];\nconst PNPM_WORKSPACE_FILE = \"pnpm-workspace.yaml\";\nconst SAFE_YAML_KEY = /^[A-Za-z][A-Za-z0-9-]*$/;\nconst PNPM_PACKAGES_BLOCK = \"packages:\\n - '.'\\n\";\n\nconst quoteYamlKey = (name: string): string => (SAFE_YAML_KEY.test(name) ? name : `'${name}'`);\n\nconst writePnpmAllowance = (root: string): void => {\n const entries = BUILT_DEPENDENCIES.map((name) => ` ${quoteYamlKey(name)}: true`).join(\"\\n\");\n writeFileSync(join(root, PNPM_WORKSPACE_FILE), `${PNPM_PACKAGES_BLOCK}allowBuilds:\\n${entries}\\n`);\n};\n\nconst writeNpmAllowance = (root: string): void => {\n updateManifest(root, (manifest) => {\n manifest.allowScripts = Object.fromEntries(BUILT_DEPENDENCIES.map((name) => [name, true]));\n });\n};\n\nconst writeYarnAllowance = (root: string): void => {\n updateManifest(root, (manifest) => {\n manifest.dependenciesMeta = Object.fromEntries(BUILT_DEPENDENCIES.map((name) => [name, { built: true }]));\n });\n};\n\nconst writeBuildAllowance = (root: string, packageManager: PackageManager): void => {\n if (packageManager === \"pnpm\") {\n writePnpmAllowance(root);\n\n return;\n }\n\n if (packageManager === \"yarn\") {\n writeYarnAllowance(root);\n\n return;\n }\n\n writeNpmAllowance(root);\n};\n\nexport { writeBuildAllowance };\n"]}
1
+ {"version":3,"file":"build-allowance.js","sourceRoot":"","sources":["../src/build-allowance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,MAAM,kBAAkB,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AACpD,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAClD,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAQ,EAAE;IAC9C,MAAM,SAAS,GAAG;QACd,QAAQ,EAAE,CAAC,GAAG,CAAC;QACf,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;KAClF,CAAC;IACF,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,mBAAmB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;AACzE,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAQ,EAAE;IAC7C,cAAc,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;QAC9B,QAAQ,CAAC,YAAY,GAAG,MAAM,CAAC,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAQ,EAAE;IAC9C,cAAc,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;QAC9B,QAAQ,CAAC,gBAAgB,GAAG,MAAM,CAAC,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9G,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAE,cAA8B,EAAQ,EAAE;IAC/E,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;QAC5B,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAEzB,OAAO;IACX,CAAC;IAED,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;QAC5B,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAEzB,OAAO;IACX,CAAC;IAED,iBAAiB,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,CAAC","sourcesContent":["import { writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { stringify } from \"yaml\";\nimport type { PackageManager } from \"./package-managers.js\";\nimport { updateManifest } from \"./manifest.js\";\n\nconst BUILT_DEPENDENCIES = [\"@swc/core\", \"esbuild\"];\nconst PNPM_WORKSPACE_FILE = \"pnpm-workspace.yaml\";\nconst writePnpmAllowance = (root: string): void => {\n const workspace = {\n packages: [\".\"],\n allowBuilds: Object.fromEntries(BUILT_DEPENDENCIES.map((name) => [name, true])),\n };\n writeFileSync(join(root, PNPM_WORKSPACE_FILE), stringify(workspace));\n};\n\nconst writeNpmAllowance = (root: string): void => {\n updateManifest(root, (manifest) => {\n manifest.allowScripts = Object.fromEntries(BUILT_DEPENDENCIES.map((name) => [name, true]));\n });\n};\n\nconst writeYarnAllowance = (root: string): void => {\n updateManifest(root, (manifest) => {\n manifest.dependenciesMeta = Object.fromEntries(BUILT_DEPENDENCIES.map((name) => [name, { built: true }]));\n });\n};\n\nconst writeBuildAllowance = (root: string, packageManager: PackageManager): void => {\n if (packageManager === \"pnpm\") {\n writePnpmAllowance(root);\n\n return;\n }\n\n if (packageManager === \"yarn\") {\n writeYarnAllowance(root);\n\n return;\n }\n\n writeNpmAllowance(root);\n};\n\nexport { writeBuildAllowance };\n"]}
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@ const main = defineCommand({
7
7
  meta: {
8
8
  name: "create-gtkx",
9
9
  version,
10
- description: "Scaffold a new Adwaita-first GNOME application with GTKX",
10
+ description: "Scaffold a Linux application with GTKX",
11
11
  },
12
12
  });
13
13
  void runMain(main);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,eAAe,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC;AAExC,MAAM,IAAI,GAAG,aAAa,CAAC;IACvB,GAAG,eAAe;IAClB,IAAI,EAAE;QACF,IAAI,EAAE,aAAa;QACnB,OAAO;QACP,WAAW,EAAE,0DAA0D;KAC1E;CACJ,CAAC,CAAC;AAEH,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC","sourcesContent":["import { defineCommand, runMain } from \"citty\";\nimport packageManifest from \"../package.json\" with { type: \"json\" };\nimport { scaffoldCommand } from \"./command.js\";\n\nconst version = packageManifest.version;\n\nconst main = defineCommand({\n ...scaffoldCommand,\n meta: {\n name: \"create-gtkx\",\n version,\n description: \"Scaffold a new Adwaita-first GNOME application with GTKX\",\n },\n});\n\nvoid runMain(main);\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,eAAe,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC;AAExC,MAAM,IAAI,GAAG,aAAa,CAAC;IACvB,GAAG,eAAe;IAClB,IAAI,EAAE;QACF,IAAI,EAAE,aAAa;QACnB,OAAO;QACP,WAAW,EAAE,wCAAwC;KACxD;CACJ,CAAC,CAAC;AAEH,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC","sourcesContent":["import { defineCommand, runMain } from \"citty\";\nimport packageManifest from \"../package.json\" with { type: \"json\" };\nimport { scaffoldCommand } from \"./command.js\";\n\nconst version = packageManifest.version;\n\nconst main = defineCommand({\n ...scaffoldCommand,\n meta: {\n name: \"create-gtkx\",\n version,\n description: \"Scaffold a Linux application with GTKX\",\n },\n});\n\nvoid runMain(main);\n"]}
package/dist/command.d.ts CHANGED
@@ -31,9 +31,10 @@ declare const scaffoldCommand: import("citty").CommandDef<{
31
31
  readonly alias: "y";
32
32
  readonly description: "Skip prompts and accept defaults for unspecified options";
33
33
  };
34
- readonly "no-interactive": {
34
+ readonly interactive: {
35
35
  readonly type: "boolean";
36
- readonly description: string;
36
+ readonly description: "Prompt for unspecified options when running in a terminal";
37
+ readonly negativeDescription: string;
37
38
  };
38
39
  readonly overwrite: {
39
40
  readonly type: "boolean";
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AA0FA,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuDnB,CAAC;AAoCH,OAAO,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AA0IA,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOnB,CAAC;AAmCH,OAAO,EAAE,eAAe,EAAE,CAAC"}
package/dist/command.js CHANGED
@@ -1,35 +1,79 @@
1
1
  import * as p from "@clack/prompts";
2
2
  import { assertSupportedNodeVersion } from "@gtkx/config/internal";
3
- import { errorMessage } from "@gtkx/utils";
3
+ import { camelCase, errorMessage, kebabCase } from "@gtkx/utils";
4
4
  import { defineCommand } from "citty";
5
5
  import { parseArgs } from "node:util";
6
6
  import { OperationCanceledError, ScaffoldAbortedError } from "./errors.js";
7
7
  import { PACKAGE_MANAGER_FLAG_DESCRIPTION } from "./package-managers.js";
8
8
  import { scaffold } from "./scaffolder.js";
9
- const STRICT_OPTIONS = {
10
- "application-id": { type: "string" },
11
- applicationId: { type: "string" },
12
- "display-name": { type: "string" },
13
- displayName: { type: "string" },
14
- "package-manager": { type: "string", short: "p" },
15
- packageManager: { type: "string" },
16
- typescript: { type: "boolean" },
17
- vitest: { type: "boolean" },
18
- yes: { type: "boolean", short: "y" },
19
- "no-interactive": { type: "boolean" },
20
- noInteractive: { type: "boolean" },
21
- overwrite: { type: "boolean", short: "f" },
22
- "skip-install": { type: "boolean" },
23
- skipInstall: { type: "boolean" },
9
+ const CREATE_ARGS = {
10
+ name: {
11
+ type: "positional",
12
+ description: "Target directory or project name (e.g. my-app, ., apps/my-app)",
13
+ required: false,
14
+ },
15
+ "application-id": {
16
+ type: "string",
17
+ description: "Application ID (e.g., com.example.myapp)",
18
+ },
19
+ "display-name": {
20
+ type: "string",
21
+ description: "Application display name (e.g., My App)",
22
+ },
23
+ "package-manager": {
24
+ type: "string",
25
+ alias: "p",
26
+ description: PACKAGE_MANAGER_FLAG_DESCRIPTION,
27
+ },
28
+ typescript: {
29
+ type: "boolean",
30
+ negativeDescription: "Scaffold the application in JavaScript instead of TypeScript",
31
+ description: "Scaffold the application in TypeScript",
32
+ },
33
+ vitest: {
34
+ type: "boolean",
35
+ description: "Include a Vitest testing setup",
36
+ },
37
+ yes: {
38
+ type: "boolean",
39
+ alias: "y",
40
+ description: "Skip prompts and accept defaults for unspecified options",
41
+ },
42
+ interactive: {
43
+ type: "boolean",
44
+ description: "Prompt for unspecified options when running in a terminal",
45
+ negativeDescription: "Run without prompts, using the default for every option not passed on the command line " +
46
+ "(same as --yes)",
47
+ },
48
+ overwrite: {
49
+ type: "boolean",
50
+ alias: "f",
51
+ description: "Replace scaffold files in a non-empty target directory when running without prompts",
52
+ },
53
+ "skip-install": {
54
+ type: "boolean",
55
+ description: "Create the project without installing dependencies",
56
+ },
24
57
  };
25
- const BOOLEAN_OPTIONS = new Set([
26
- "--typescript",
27
- "--vitest",
28
- "--yes",
29
- "--overwrite",
30
- "--skip-install",
31
- "--skipInstall",
32
- ]);
58
+ const strictOption = (definition) => ({
59
+ type: definition.type,
60
+ ...("alias" in definition && { short: definition.alias }),
61
+ });
62
+ const createStrictOptions = () => {
63
+ const options = {};
64
+ for (const [name, definition] of Object.entries(CREATE_ARGS)) {
65
+ if (definition.type === "positional") {
66
+ continue;
67
+ }
68
+ options[name] = strictOption(definition);
69
+ if (camelCase(name) !== name) {
70
+ options[camelCase(name)] = { type: definition.type };
71
+ }
72
+ }
73
+ return options;
74
+ };
75
+ const STRICT_OPTIONS = createStrictOptions();
76
+ const BOOLEAN_OPTIONS = new Set(Object.entries(STRICT_OPTIONS).filter(([, option]) => option.type === "boolean").map(([name]) => `--${name}`));
33
77
  const normalizeBooleanArgument = (argument) => {
34
78
  const [option, value, ...rest] = argument.split("=");
35
79
  if (option === undefined || rest.length > 0 || !BOOLEAN_OPTIONS.has(option)) {
@@ -40,80 +84,34 @@ const normalizeBooleanArgument = (argument) => {
40
84
  }
41
85
  return value === "false" ? `--no-${option.slice(2)}` : argument;
42
86
  };
43
- const isKnownOption = (name, rawName) => Object.hasOwn(STRICT_OPTIONS, name) || Object.hasOwn(STRICT_OPTIONS, rawName.replace(/^--/, ""));
44
- const unknownOptions = (args) => {
45
- const { tokens } = parseArgs({
46
- args,
87
+ const canonicalOption = (token) => [kebabCase(token.name), token.value ?? !token.rawName.startsWith("--no-")];
88
+ /* TODO: Keep ordered token parsing until Citty respects the order of positive and negated flags.
89
+ * https://github.com/gtkx-org/gtkx/issues/732
90
+ */
91
+ const parseCreateArguments = (rawArgs) => {
92
+ const { tokens, positionals } = parseArgs({
93
+ args: rawArgs.map((argument) => normalizeBooleanArgument(argument === "--noInteractive" ? "--no-interactive" : argument)),
47
94
  options: STRICT_OPTIONS,
48
95
  allowPositionals: true,
49
96
  allowNegative: true,
50
- strict: false,
97
+ strict: true,
51
98
  tokens: true,
52
99
  });
53
- return tokens.flatMap((token) => token.kind === "option" && !isKnownOption(token.name, token.rawName) ? [token.rawName] : []);
54
- };
55
- const assertKnownArguments = (rawArgs) => {
56
- const args = rawArgs.map((argument) => normalizeBooleanArgument(argument));
57
- const [unknown] = unknownOptions(args);
58
- if (unknown !== undefined) {
59
- throw new Error(`Unknown option "${unknown}". Pass --help to list the supported options`);
100
+ if (positionals.length > 1) {
101
+ throw new TypeError("Expected one project directory");
60
102
  }
61
- parseArgs({ args, options: STRICT_OPTIONS, allowPositionals: true, allowNegative: true, strict: true });
103
+ return {
104
+ ...Object.fromEntries(tokens.filter((token) => token.kind === "option").map((token) => canonicalOption(token))),
105
+ name: positionals[0],
106
+ };
62
107
  };
63
108
  const scaffoldCommand = defineCommand({
64
109
  meta: {
65
110
  name: "create",
66
- description: "Create a new Adwaita-first GNOME application with GTKX",
67
- },
68
- args: {
69
- name: {
70
- type: "positional",
71
- description: "Target directory or project name (e.g. my-app, ., apps/my-app)",
72
- required: false,
73
- },
74
- "application-id": {
75
- type: "string",
76
- description: "Application ID (e.g., com.example.myapp)",
77
- },
78
- "display-name": {
79
- type: "string",
80
- description: "Application display name (e.g., My App)",
81
- },
82
- "package-manager": {
83
- type: "string",
84
- alias: "p",
85
- description: PACKAGE_MANAGER_FLAG_DESCRIPTION,
86
- },
87
- typescript: {
88
- type: "boolean",
89
- negativeDescription: "Scaffold the application in JavaScript instead of TypeScript",
90
- description: "Scaffold the application in TypeScript",
91
- },
92
- vitest: {
93
- type: "boolean",
94
- description: "Include a Vitest testing setup",
95
- },
96
- yes: {
97
- type: "boolean",
98
- alias: "y",
99
- description: "Skip prompts and accept defaults for unspecified options",
100
- },
101
- "no-interactive": {
102
- type: "boolean",
103
- description: "Run without prompts, using the default for every option not passed on the command line " +
104
- "(same as --yes)",
105
- },
106
- overwrite: {
107
- type: "boolean",
108
- alias: "f",
109
- description: "Replace scaffold files in a non-empty target directory when running without prompts",
110
- },
111
- "skip-install": {
112
- type: "boolean",
113
- description: "Create the project without installing dependencies",
114
- },
111
+ description: "Create a Linux application with GTKX",
115
112
  },
116
- run: ({ args, rawArgs }) => runCreate(args, rawArgs),
113
+ args: CREATE_ARGS,
114
+ run: ({ rawArgs }) => runCreate(rawArgs),
117
115
  });
118
116
  const settleScaffoldFailure = (error) => {
119
117
  if (error instanceof OperationCanceledError) {
@@ -124,10 +122,10 @@ const settleScaffoldFailure = (error) => {
124
122
  }
125
123
  process.exitCode = 1;
126
124
  };
127
- const runCreate = async (args, rawArgs) => {
128
- const isInteractive = args["no-interactive"] || args.yes ? false : process.stdin.isTTY;
125
+ const runCreate = async (rawArgs) => {
129
126
  try {
130
- assertKnownArguments(rawArgs);
127
+ const args = parseCreateArguments(rawArgs);
128
+ const isInteractive = args.interactive !== false && !args.yes && process.stdin.isTTY;
131
129
  assertSupportedNodeVersion();
132
130
  await scaffold({
133
131
  name: args.name,
@@ -1 +1 @@
1
- {"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"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","sourcesContent":["import * as p from \"@clack/prompts\";\nimport { assertSupportedNodeVersion } from \"@gtkx/config/internal\";\nimport { errorMessage } from \"@gtkx/utils\";\nimport { defineCommand } from \"citty\";\nimport { parseArgs, type ParseArgsOptionsConfig } from \"node:util\";\nimport { OperationCanceledError, ScaffoldAbortedError } from \"./errors.js\";\nimport { PACKAGE_MANAGER_FLAG_DESCRIPTION } from \"./package-managers.js\";\nimport { scaffold } from \"./scaffolder.js\";\n\ntype CreateCommandArgs = {\n name?: string | undefined;\n \"application-id\"?: string | undefined;\n \"display-name\"?: 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 \"skip-install\"?: boolean | undefined;\n};\n\nconst STRICT_OPTIONS: ParseArgsOptionsConfig = {\n \"application-id\": { type: \"string\" },\n applicationId: { type: \"string\" },\n \"display-name\": { type: \"string\" },\n displayName: { type: \"string\" },\n \"package-manager\": { type: \"string\", short: \"p\" },\n packageManager: { type: \"string\" },\n typescript: { type: \"boolean\" },\n vitest: { type: \"boolean\" },\n yes: { type: \"boolean\", short: \"y\" },\n \"no-interactive\": { type: \"boolean\" },\n noInteractive: { type: \"boolean\" },\n overwrite: { type: \"boolean\", short: \"f\" },\n \"skip-install\": { type: \"boolean\" },\n skipInstall: { type: \"boolean\" },\n};\n\nconst BOOLEAN_OPTIONS: ReadonlySet<string> = new Set([\n \"--typescript\",\n \"--vitest\",\n \"--yes\",\n \"--overwrite\",\n \"--skip-install\",\n \"--skipInstall\",\n]);\n\nconst normalizeBooleanArgument = (argument: string): string => {\n const [option, value, ...rest] = argument.split(\"=\");\n\n if (option === undefined || rest.length > 0 || !BOOLEAN_OPTIONS.has(option)) {\n return argument;\n }\n\n if (value === \"true\") {\n return option;\n }\n\n return value === \"false\" ? `--no-${option.slice(2)}` : argument;\n};\n\nconst isKnownOption = (name: string, rawName: string): boolean =>\n Object.hasOwn(STRICT_OPTIONS, name) || Object.hasOwn(STRICT_OPTIONS, rawName.replace(/^--/, \"\"));\n\nconst unknownOptions = (args: string[]): string[] => {\n const { tokens } = parseArgs({\n args,\n options: STRICT_OPTIONS,\n allowPositionals: true,\n allowNegative: true,\n strict: false,\n tokens: true,\n });\n\n return tokens.flatMap((token) =>\n token.kind === \"option\" && !isKnownOption(token.name, token.rawName) ? [token.rawName] : []);\n};\n\nconst assertKnownArguments = (rawArgs: string[]): void => {\n const args = rawArgs.map((argument) => normalizeBooleanArgument(argument));\n const [unknown] = unknownOptions(args);\n\n if (unknown !== undefined) {\n throw new Error(`Unknown option \"${unknown}\". Pass --help to list the supported options`);\n }\n\n parseArgs({ args, options: STRICT_OPTIONS, allowPositionals: true, allowNegative: true, strict: true });\n};\n\nconst scaffoldCommand = defineCommand({\n meta: {\n name: \"create\",\n description: \"Create a new Adwaita-first GNOME application with GTKX\",\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 \"display-name\": {\n type: \"string\",\n description: \"Application display name (e.g., My App)\",\n },\n \"package-manager\": {\n type: \"string\",\n alias: \"p\",\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: \"f\",\n description: \"Replace scaffold files in a non-empty target directory when running without prompts\",\n },\n \"skip-install\": {\n type: \"boolean\",\n description: \"Create the project without installing dependencies\",\n },\n },\n run: ({ args, rawArgs }) => runCreate(args, rawArgs),\n});\n\nconst settleScaffoldFailure = (error: unknown): void => {\n if (error instanceof OperationCanceledError) {\n return;\n }\n\n if (!(error instanceof ScaffoldAbortedError)) {\n p.log.error(errorMessage(error));\n }\n\n process.exitCode = 1;\n};\n\nconst runCreate = async (args: CreateCommandArgs, rawArgs: string[]): Promise<void> => {\n const isInteractive = args[\"no-interactive\"] || args.yes ? false : process.stdin.isTTY;\n\n try {\n assertKnownArguments(rawArgs);\n assertSupportedNodeVersion();\n await scaffold({\n name: args.name,\n applicationId: args[\"application-id\"],\n displayName: args[\"display-name\"],\n packageManager: args[\"package-manager\"],\n isTypescript: args.typescript,\n shouldIncludeTesting: args.vitest,\n isInteractive,\n shouldOverwrite: args.overwrite,\n shouldInstallDependencies: args[\"skip-install\"] !== true,\n });\n } catch (error) {\n settleScaffoldFailure(error);\n }\n};\n\nexport { scaffoldCommand };\n"]}
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"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","sourcesContent":["import * as p from \"@clack/prompts\";\nimport { assertSupportedNodeVersion } from \"@gtkx/config/internal\";\nimport { camelCase, errorMessage, kebabCase } from \"@gtkx/utils\";\nimport { type ArgsDef, defineCommand, type ParsedArgs } from \"citty\";\nimport { parseArgs, type ParseArgsOptionsConfig } from \"node:util\";\nimport { OperationCanceledError, ScaffoldAbortedError } from \"./errors.js\";\nimport { PACKAGE_MANAGER_FLAG_DESCRIPTION } from \"./package-managers.js\";\nimport { scaffold } from \"./scaffolder.js\";\n\nconst CREATE_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 \"display-name\": {\n type: \"string\",\n description: \"Application display name (e.g., My App)\",\n },\n \"package-manager\": {\n type: \"string\",\n alias: \"p\",\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 interactive: {\n type: \"boolean\",\n description: \"Prompt for unspecified options when running in a terminal\",\n negativeDescription:\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: \"f\",\n description: \"Replace scaffold files in a non-empty target directory when running without prompts\",\n },\n \"skip-install\": {\n type: \"boolean\",\n description: \"Create the project without installing dependencies\",\n },\n} as const satisfies ArgsDef;\n\ntype OptionToken = Extract<\n ReturnType<typeof parseArgs<{ tokens: true; strict: false }>>[\"tokens\"][number],\n { kind: \"option\" }\n>;\n\ntype CreateCommandArgs = Pick<ParsedArgs<typeof CREATE_ARGS>, keyof typeof CREATE_ARGS>;\ntype CreateOption = Exclude<(typeof CREATE_ARGS)[keyof typeof CREATE_ARGS], { type: \"positional\" }>;\n\nconst strictOption = (definition: CreateOption): ParseArgsOptionsConfig[string] => ({\n type: definition.type,\n ...(\"alias\" in definition && { short: definition.alias }),\n});\n\nconst createStrictOptions = (): ParseArgsOptionsConfig => {\n const options: ParseArgsOptionsConfig = {};\n\n for (const [name, definition] of Object.entries(CREATE_ARGS)) {\n if (definition.type === \"positional\") {\n continue;\n }\n\n options[name] = strictOption(definition);\n\n if (camelCase(name) !== name) {\n options[camelCase(name)] = { type: definition.type };\n }\n }\n\n return options;\n};\n\nconst STRICT_OPTIONS = createStrictOptions();\n\nconst BOOLEAN_OPTIONS = new Set(\n Object.entries(STRICT_OPTIONS).filter(([, option]) => option.type === \"boolean\").map(([name]) => `--${name}`),\n);\n\nconst normalizeBooleanArgument = (argument: string): string => {\n const [option, value, ...rest] = argument.split(\"=\");\n\n if (option === undefined || rest.length > 0 || !BOOLEAN_OPTIONS.has(option)) {\n return argument;\n }\n\n if (value === \"true\") {\n return option;\n }\n\n return value === \"false\" ? `--no-${option.slice(2)}` : argument;\n};\n\nconst canonicalOption = (token: OptionToken): [string, string | boolean] =>\n [kebabCase(token.name), token.value ?? !token.rawName.startsWith(\"--no-\")];\n\n/* TODO: Keep ordered token parsing until Citty respects the order of positive and negated flags.\n * https://github.com/gtkx-org/gtkx/issues/732\n */\nconst parseCreateArguments = (rawArgs: string[]): CreateCommandArgs => {\n const { tokens, positionals } = parseArgs({\n args: rawArgs.map((argument) =>\n normalizeBooleanArgument(argument === \"--noInteractive\" ? \"--no-interactive\" : argument)),\n options: STRICT_OPTIONS,\n allowPositionals: true,\n allowNegative: true,\n strict: true,\n tokens: true,\n });\n\n if (positionals.length > 1) {\n throw new TypeError(\"Expected one project directory\");\n }\n\n return {\n ...Object.fromEntries(tokens.filter((token) => token.kind === \"option\").map((token) => canonicalOption(token))),\n name: positionals[0],\n } as CreateCommandArgs;\n};\n\nconst scaffoldCommand = defineCommand({\n meta: {\n name: \"create\",\n description: \"Create a Linux application with GTKX\",\n },\n args: CREATE_ARGS,\n run: ({ rawArgs }) => runCreate(rawArgs),\n});\n\nconst settleScaffoldFailure = (error: unknown): void => {\n if (error instanceof OperationCanceledError) {\n return;\n }\n\n if (!(error instanceof ScaffoldAbortedError)) {\n p.log.error(errorMessage(error));\n }\n\n process.exitCode = 1;\n};\n\nconst runCreate = async (rawArgs: string[]): Promise<void> => {\n try {\n const args = parseCreateArguments(rawArgs);\n const isInteractive = args.interactive !== false && !args.yes && process.stdin.isTTY;\n assertSupportedNodeVersion();\n await scaffold({\n name: args.name,\n applicationId: args[\"application-id\"],\n displayName: args[\"display-name\"],\n packageManager: args[\"package-manager\"],\n isTypescript: args.typescript,\n shouldIncludeTesting: args.vitest,\n isInteractive,\n shouldOverwrite: args.overwrite,\n shouldInstallDependencies: args[\"skip-install\"] !== true,\n });\n } catch (error) {\n settleScaffoldFailure(error);\n }\n};\n\nexport { scaffoldCommand };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAMA,QAAA,MAAM,cAAc,GAAI,MAAM,MAAM,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,KAAG,IAY3F,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,cAAc,GAAI,MAAM,MAAM,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,KAAG,IAK3F,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC"}
package/dist/manifest.js CHANGED
@@ -1,19 +1,11 @@
1
- import { randomUUID } from "node:crypto";
2
- import { readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
1
+ import { readFileSync, writeFileSync } from "node:fs";
3
2
  import { join } from "node:path";
4
3
  const PACKAGE_JSON_FILE = "package.json";
5
4
  const updateManifest = (root, mutate) => {
6
5
  const manifestPath = join(root, PACKAGE_JSON_FILE);
7
6
  const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
8
7
  mutate(manifest);
9
- const pendingPath = join(root, `.package-${randomUUID()}.json`);
10
- try {
11
- writeFileSync(pendingPath, `${JSON.stringify(manifest, null, 4)}\n`, { flag: "wx", mode: 0o600 });
12
- renameSync(pendingPath, manifestPath);
13
- }
14
- finally {
15
- rmSync(pendingPath, { force: true });
16
- }
8
+ writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 4)}\n`);
17
9
  };
18
10
  export { updateManifest };
19
11
  //# sourceMappingURL=manifest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAEzC,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,MAAmD,EAAQ,EAAE;IAC/F,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAA4B,CAAC;IAC3F,MAAM,CAAC,QAAQ,CAAC,CAAC;IACjB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,YAAY,UAAU,EAAE,OAAO,CAAC,CAAC;IAEhE,IAAI,CAAC;QACD,aAAa,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAClG,UAAU,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAC1C,CAAC;YAAS,CAAC;QACP,MAAM,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;AACL,CAAC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst PACKAGE_JSON_FILE = \"package.json\";\n\nconst updateManifest = (root: string, mutate: (manifest: Record<string, unknown>) => void): void => {\n const manifestPath = join(root, PACKAGE_JSON_FILE);\n const manifest = JSON.parse(readFileSync(manifestPath, \"utf8\")) as Record<string, unknown>;\n mutate(manifest);\n const pendingPath = join(root, `.package-${randomUUID()}.json`);\n\n try {\n writeFileSync(pendingPath, `${JSON.stringify(manifest, null, 4)}\\n`, { flag: \"wx\", mode: 0o600 });\n renameSync(pendingPath, manifestPath);\n } finally {\n rmSync(pendingPath, { force: true });\n }\n};\n\nexport { updateManifest };\n"]}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAEzC,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,MAAmD,EAAQ,EAAE;IAC/F,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAA4B,CAAC;IAC3F,MAAM,CAAC,QAAQ,CAAC,CAAC;IACjB,aAAa,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AAC1E,CAAC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC","sourcesContent":["import { readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst PACKAGE_JSON_FILE = \"package.json\";\n\nconst updateManifest = (root: string, mutate: (manifest: Record<string, unknown>) => void): void => {\n const manifestPath = join(root, PACKAGE_JSON_FILE);\n const manifest = JSON.parse(readFileSync(manifestPath, \"utf8\")) as Record<string, unknown>;\n mutate(manifest);\n writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 4)}\\n`);\n};\n\nexport { updateManifest };\n"]}
@@ -3,21 +3,18 @@ declare const PACKAGE_MANAGERS: readonly [{
3
3
  readonly value: "pnpm";
4
4
  readonly label: "pnpm";
5
5
  readonly devCommand: "pnpm dev";
6
- readonly addCommand: "pnpm add";
7
6
  readonly installCommand: "pnpm install";
8
7
  readonly isRecommended: true;
9
8
  }, {
10
9
  readonly value: "npm";
11
10
  readonly label: "npm";
12
11
  readonly devCommand: "npm run dev";
13
- readonly addCommand: "npm install";
14
12
  readonly installCommand: "npm install";
15
13
  readonly isRecommended: false;
16
14
  }, {
17
15
  readonly value: "yarn";
18
16
  readonly label: "yarn";
19
17
  readonly devCommand: "yarn dev";
20
- readonly addCommand: "yarn add";
21
18
  readonly installCommand: "yarn install";
22
19
  readonly isRecommended: false;
23
20
  }];
@@ -1 +1 @@
1
- {"version":3,"file":"package-managers.d.ts","sourceRoot":"","sources":["../src/package-managers.ts"],"names":[],"mappings":"AAAA,KAAK,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;AAEjE,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;EAyBZ,CAAC;AAEX,QAAA,MAAM,sBAAsB,EAAE,cAAc,EAAqD,CAAC;AAClG,QAAA,MAAM,gCAAgC,QAA2D,CAAC;AAElG,QAAA,MAAM,qBAAqB,GAAI,MAAM,MAAM,KAAG,IAAI,IAAI,cACC,CAAC;AAExD,OAAO,EACH,gBAAgB,EAChB,gCAAgC,EAChC,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,cAAc,GACtB,CAAC"}
1
+ {"version":3,"file":"package-managers.d.ts","sourceRoot":"","sources":["../src/package-managers.ts"],"names":[],"mappings":"AAAA,KAAK,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;AAEjE,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;EAsBZ,CAAC;AAEX,QAAA,MAAM,sBAAsB,EAAE,cAAc,EAAqD,CAAC;AAClG,QAAA,MAAM,gCAAgC,QAA2D,CAAC;AAElG,QAAA,MAAM,qBAAqB,GAAI,MAAM,MAAM,KAAG,IAAI,IAAI,cACC,CAAC;AAExD,OAAO,EACH,gBAAgB,EAChB,gCAAgC,EAChC,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,cAAc,GACtB,CAAC"}
@@ -3,7 +3,6 @@ const PACKAGE_MANAGERS = [
3
3
  value: "pnpm",
4
4
  label: "pnpm",
5
5
  devCommand: "pnpm dev",
6
- addCommand: "pnpm add",
7
6
  installCommand: "pnpm install",
8
7
  isRecommended: true,
9
8
  },
@@ -11,7 +10,6 @@ const PACKAGE_MANAGERS = [
11
10
  value: "npm",
12
11
  label: "npm",
13
12
  devCommand: "npm run dev",
14
- addCommand: "npm install",
15
13
  installCommand: "npm install",
16
14
  isRecommended: false,
17
15
  },
@@ -19,7 +17,6 @@ const PACKAGE_MANAGERS = [
19
17
  value: "yarn",
20
18
  label: "yarn",
21
19
  devCommand: "yarn dev",
22
- addCommand: "yarn add",
23
20
  installCommand: "yarn install",
24
21
  isRecommended: false,
25
22
  },