create-gtkx 1.6.0 → 2.0.0-beta.1
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 +5 -5
- package/dist/scaffolder.d.ts.map +1 -1
- package/dist/scaffolder.js +31 -71
- package/dist/scaffolder.js.map +1 -1
- package/dist/templates/gtkx.config.ts.ejs +0 -9
- package/dist/templates/package.json.ejs +3 -0
- package/dist/templates.d.ts.map +1 -1
- package/dist/templates.js +5 -7
- package/dist/templates.js.map +1 -1
- package/package.json +8 -6
- package/src/scaffolder.ts +49 -102
- package/src/templates/gtkx.config.ts.ejs +0 -9
- package/src/templates/package.json.ejs +3 -0
- package/src/templates.ts +5 -7
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<p align="center">
|
|
14
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
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%
|
|
16
|
+
<img src="https://img.shields.io/badge/node-%E2%89%A526.7-339933?logo=node.js&logoColor=white" alt="Node >= 26.7" />
|
|
17
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
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
19
|
<img src="https://img.shields.io/badge/TypeScript-strict-3178c6?logo=typescript&logoColor=white" alt="TypeScript" />
|
|
@@ -116,7 +116,7 @@ At runtime, the native Rust core calls straight into the system GTK4, Adwaita, a
|
|
|
116
116
|
|
|
117
117
|
## Quick start
|
|
118
118
|
|
|
119
|
-
GTKX is Linux-only and needs Node.js
|
|
119
|
+
GTKX is Linux-only and needs Node.js 26.7 or later. See [Requirements](#requirements).
|
|
120
120
|
|
|
121
121
|
Scaffold a new app with the `create-gtkx` initializer:
|
|
122
122
|
|
|
@@ -145,8 +145,8 @@ The documentation at **[gtkx.dev](https://gtkx.dev)** includes a step-by-step tu
|
|
|
145
145
|
|
|
146
146
|
GTKX is Linux-only. You need:
|
|
147
147
|
|
|
148
|
-
- Linux with the GTK4 (4.20 or later)
|
|
149
|
-
- Node.js
|
|
148
|
+
- Linux with the GTK4 (4.20 or later), Adwaita (1.8 or later), and GLib development libraries
|
|
149
|
+
- Node.js 26.7 or later
|
|
150
150
|
|
|
151
151
|
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.
|
|
152
152
|
|
|
@@ -167,7 +167,7 @@ GTKX is stable and ready for production use.
|
|
|
167
167
|
|
|
168
168
|
## Contributing
|
|
169
169
|
|
|
170
|
-
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
|
|
170
|
+
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.
|
|
171
171
|
|
|
172
172
|
## License
|
|
173
173
|
|
package/dist/scaffolder.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffolder.d.ts","sourceRoot":"","sources":["../src/scaffolder.ts"],"names":[],"mappings":"AAsBA,KAAK,aAAa,GAAG;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,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;
|
|
1
|
+
{"version":3,"file":"scaffolder.d.ts","sourceRoot":"","sources":["../src/scaffolder.ts"],"names":[],"mappings":"AAsBA,KAAK,aAAa,GAAG;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,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;AAkjBF,QAAA,MAAM,QAAQ,GAAU,UAAS,aAAkB,KAAG,OAAO,CAAC,IAAI,CAcjE,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
package/dist/scaffolder.js
CHANGED
|
@@ -39,9 +39,6 @@ const APPLICATION_ID_PREFIX = "com.";
|
|
|
39
39
|
const APPLICATION_ID_SUFFIX = ".app";
|
|
40
40
|
const APPLICATION_ID_SEGMENT_LIMIT = APPLICATION_ID_MAX_LENGTH - APPLICATION_ID_PREFIX.length -
|
|
41
41
|
APPLICATION_ID_SUFFIX.length;
|
|
42
|
-
const pinGtkxDependency = (name, version) => name.startsWith("@gtkx/") ? `${name}@^${version}` : name;
|
|
43
|
-
const getDevCommand = (packageManager) => DEV_COMMAND[packageManager];
|
|
44
|
-
const getAddCommand = (packageManager) => ADD_COMMAND[packageManager];
|
|
45
42
|
const titleFromName = (name) => name.split("-").map((part) => upperFirst(part)).join(" ");
|
|
46
43
|
const gitConfigValue = (key) => {
|
|
47
44
|
const git = tryResolveExecutable("git");
|
|
@@ -116,14 +113,6 @@ const requestedPackageManager = (value) => {
|
|
|
116
113
|
}
|
|
117
114
|
return value;
|
|
118
115
|
};
|
|
119
|
-
const targetStats = (root) => {
|
|
120
|
-
try {
|
|
121
|
-
return statSync(root, { throwIfNoEntry: false });
|
|
122
|
-
}
|
|
123
|
-
catch {
|
|
124
|
-
return undefined;
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
116
|
const validateTargetDir = (target) => {
|
|
128
117
|
if (!target) {
|
|
129
118
|
return "Project directory is required";
|
|
@@ -145,29 +134,20 @@ const promptApplicationId = async (name) => {
|
|
|
145
134
|
validate: validateApplicationIdAnswer,
|
|
146
135
|
}));
|
|
147
136
|
};
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
if (!detected) {
|
|
151
|
-
return undefined;
|
|
152
|
-
}
|
|
153
|
-
return isKnownPackageManager(detected.name) ? detected.name : undefined;
|
|
154
|
-
};
|
|
155
|
-
const packageManagerHint = (manager, detected) => {
|
|
137
|
+
const packageManagerOption = (manager, detected) => {
|
|
138
|
+
let hint;
|
|
156
139
|
if (detected === manager.value) {
|
|
157
|
-
|
|
140
|
+
hint = "detected";
|
|
158
141
|
}
|
|
159
|
-
if (manager.isRecommended) {
|
|
160
|
-
|
|
142
|
+
else if (manager.isRecommended) {
|
|
143
|
+
hint = "recommended";
|
|
161
144
|
}
|
|
162
|
-
return undefined;
|
|
163
|
-
};
|
|
164
|
-
const packageManagerOption = (manager, detected) => {
|
|
165
|
-
const hint = packageManagerHint(manager, detected);
|
|
166
145
|
return { value: manager.value, label: manager.label, ...(hint !== undefined && { hint }) };
|
|
167
146
|
};
|
|
168
147
|
const detectedPackageManager = async () => {
|
|
169
148
|
try {
|
|
170
|
-
|
|
149
|
+
const detected = await nypmDetectPackageManager(process.cwd(), { includeParentDirs: true });
|
|
150
|
+
return detected && isKnownPackageManager(detected.name) ? detected.name : undefined;
|
|
171
151
|
}
|
|
172
152
|
catch {
|
|
173
153
|
return undefined;
|
|
@@ -182,14 +162,10 @@ const promptPackageManager = async () => {
|
|
|
182
162
|
initialValue: initial,
|
|
183
163
|
}));
|
|
184
164
|
};
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const shouldSetUpTesting = async () => guardCancellation(await p.confirm({
|
|
190
|
-
message: "Include testing setup (Vitest)?",
|
|
191
|
-
initialValue: true,
|
|
192
|
-
}));
|
|
165
|
+
const isOptionEnabled = async (value, isInteractive, message) => value ??
|
|
166
|
+
(isInteractive
|
|
167
|
+
? guardCancellation(await p.confirm({ message, initialValue: true }))
|
|
168
|
+
: true);
|
|
193
169
|
const emptyDir = (root) => {
|
|
194
170
|
for (const entry of readdirSync(root)) {
|
|
195
171
|
if (entry === ".git") {
|
|
@@ -198,12 +174,6 @@ const emptyDir = (root) => {
|
|
|
198
174
|
rmSync(join(root, entry), { recursive: true, force: true });
|
|
199
175
|
}
|
|
200
176
|
};
|
|
201
|
-
const prepareTargetDirectory = (root, shouldEmptyTarget) => {
|
|
202
|
-
mkdirSync(root, { recursive: true });
|
|
203
|
-
if (shouldEmptyTarget) {
|
|
204
|
-
emptyDir(root);
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
177
|
const shouldOverwriteDirectory = async (target, options) => {
|
|
208
178
|
if (!options.isInteractive) {
|
|
209
179
|
return options.shouldOverwrite === true;
|
|
@@ -214,7 +184,7 @@ const shouldOverwriteDirectory = async (target, options) => {
|
|
|
214
184
|
}));
|
|
215
185
|
};
|
|
216
186
|
const shouldEmptyTargetDirectory = async (root, target, options) => {
|
|
217
|
-
const stats =
|
|
187
|
+
const stats = statSync(root, { throwIfNoEntry: false });
|
|
218
188
|
if (stats === undefined) {
|
|
219
189
|
return false;
|
|
220
190
|
}
|
|
@@ -252,18 +222,6 @@ const resolvePackageManager = async (requested, options) => {
|
|
|
252
222
|
}
|
|
253
223
|
return (await detectedPackageManager()) ?? "pnpm";
|
|
254
224
|
};
|
|
255
|
-
const isTypescriptSelected = async (options) => {
|
|
256
|
-
if (options.isTypescript !== undefined) {
|
|
257
|
-
return options.isTypescript;
|
|
258
|
-
}
|
|
259
|
-
return options.isInteractive ? shouldUseTypeScript() : true;
|
|
260
|
-
};
|
|
261
|
-
const isTestingIncluded = async (options) => {
|
|
262
|
-
if (options.shouldIncludeTesting !== undefined) {
|
|
263
|
-
return options.shouldIncludeTesting;
|
|
264
|
-
}
|
|
265
|
-
return options.isInteractive ? shouldSetUpTesting() : true;
|
|
266
|
-
};
|
|
267
225
|
const resolveOptions = async (options) => {
|
|
268
226
|
const requested = requestedPackageManager(options.packageManager);
|
|
269
227
|
const target = await resolveTarget(options);
|
|
@@ -273,8 +231,8 @@ const resolveOptions = async (options) => {
|
|
|
273
231
|
const isCurrentDirectory = root === process.cwd();
|
|
274
232
|
const shouldEmptyTarget = await shouldEmptyTargetDirectory(root, target, options);
|
|
275
233
|
const packageManager = await resolvePackageManager(requested, options);
|
|
276
|
-
const isTypescript = await
|
|
277
|
-
const shouldIncludeTesting = await
|
|
234
|
+
const isTypescript = await isOptionEnabled(options.isTypescript, options.isInteractive, "Use TypeScript?");
|
|
235
|
+
const shouldIncludeTesting = await isOptionEnabled(options.shouldIncludeTesting, options.isInteractive, "Include testing setup (Vitest)?");
|
|
278
236
|
return {
|
|
279
237
|
target,
|
|
280
238
|
root,
|
|
@@ -296,13 +254,11 @@ const isTemplateIncluded = (templateRelativePath, resolved) => {
|
|
|
296
254
|
}
|
|
297
255
|
return true;
|
|
298
256
|
};
|
|
299
|
-
const
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
manifest.scripts.test = "vitest run";
|
|
305
|
-
});
|
|
257
|
+
const destinationPath = (template, resolved) => {
|
|
258
|
+
const scriptPath = resolved.isTypescript ? template : template.replace(/\.tsx$/, ".jsx").replace(/\.ts$/, ".js");
|
|
259
|
+
return scriptPath.endsWith(ICON_TEMPLATE_NAME)
|
|
260
|
+
? `${scriptPath.slice(0, -ICON_TEMPLATE_NAME.length)}${resolved.applicationId}.svg`
|
|
261
|
+
: scriptPath;
|
|
306
262
|
};
|
|
307
263
|
const templateContext = (resolved) => ({
|
|
308
264
|
name: resolved.name,
|
|
@@ -315,18 +271,19 @@ const templateContext = (resolved) => ({
|
|
|
315
271
|
developerEmail: gitConfigValue("user.email"),
|
|
316
272
|
});
|
|
317
273
|
const scaffoldProject = async (root, resolved) => {
|
|
318
|
-
const { applicationId, isTypescript, shouldIncludeTesting } = resolved;
|
|
319
274
|
const context = templateContext(resolved);
|
|
320
275
|
for (const template of listTemplates()) {
|
|
321
276
|
if (!isTemplateIncluded(template, resolved)) {
|
|
322
277
|
continue;
|
|
323
278
|
}
|
|
324
|
-
const destination = join(root,
|
|
279
|
+
const destination = join(root, destinationPath(template, resolved));
|
|
325
280
|
mkdirSync(dirname(destination), { recursive: true });
|
|
326
281
|
writeFileSync(destination, await renderFile(template, context));
|
|
327
282
|
}
|
|
328
|
-
if (shouldIncludeTesting) {
|
|
329
|
-
|
|
283
|
+
if (resolved.shouldIncludeTesting) {
|
|
284
|
+
updateManifest(root, (manifest) => {
|
|
285
|
+
manifest.scripts.test = "vitest run";
|
|
286
|
+
});
|
|
330
287
|
}
|
|
331
288
|
};
|
|
332
289
|
const withoutInheritedScriptPolicy = async (run) => {
|
|
@@ -351,9 +308,9 @@ const installDependencies = async (options) => {
|
|
|
351
308
|
await addDependency(dependencies, { cwd, packageManager, dev: isDev, silent: true });
|
|
352
309
|
});
|
|
353
310
|
};
|
|
354
|
-
const pin = (names) => names.map((dependency) =>
|
|
311
|
+
const pin = (names) => names.map((dependency) => dependency.startsWith("@gtkx/") ? `${dependency}@^${selfVersion}` : dependency);
|
|
355
312
|
const formatRecovery = ({ resolved, devDependencies }) => {
|
|
356
|
-
const add =
|
|
313
|
+
const add = ADD_COMMAND[resolved.packageManager];
|
|
357
314
|
const steps = [
|
|
358
315
|
...(resolved.isCurrentDirectory ? [] : [`cd ${resolved.target}`]),
|
|
359
316
|
`${add} ${pin(DEPENDENCIES).join(" ")}`,
|
|
@@ -419,7 +376,7 @@ const initializeGitRepo = async (root) => {
|
|
|
419
376
|
}
|
|
420
377
|
};
|
|
421
378
|
const printNextSteps = (resolved) => {
|
|
422
|
-
const devCmd =
|
|
379
|
+
const devCmd = DEV_COMMAND[resolved.packageManager];
|
|
423
380
|
const cdStep = resolved.isCurrentDirectory ? "" : `cd ${resolved.target}\n`;
|
|
424
381
|
const testingNote = resolved.shouldIncludeTesting ? HEADLESS_COMPOSITOR_NOTE : "";
|
|
425
382
|
p.note(`${cdStep}${devCmd}${testingNote}`, "Next steps");
|
|
@@ -430,7 +387,10 @@ const createProjectStructure = async (root, resolved) => {
|
|
|
430
387
|
done: "Project structure created",
|
|
431
388
|
failed: "Failed to create the project structure",
|
|
432
389
|
run: async () => {
|
|
433
|
-
|
|
390
|
+
mkdirSync(root, { recursive: true });
|
|
391
|
+
if (resolved.shouldEmptyTarget) {
|
|
392
|
+
emptyDir(root);
|
|
393
|
+
}
|
|
434
394
|
await scaffoldProject(root, resolved);
|
|
435
395
|
writeBuildAllowance(root, resolved.packageManager);
|
|
436
396
|
},
|
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 { APPLICATION_ID_MAX_LENGTH, isValidApplicationId } from \"@gtkx/config/internal\";\nimport { errorMessage, tryResolveExecutable, upperFirst } from \"@gtkx/utils\";\nimport { execFileSync } from \"node:child_process\";\nimport { mkdirSync, readdirSync, rmSync, type Stats, statSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { addDependency, detectPackageManager as nypmDetectPackageManager } from \"nypm\";\nimport { x } from \"tinyexec\";\nimport packageManifest from \"../package.json\" with { type: \"json\" };\nimport { writeBuildAllowance } from \"./build-allowance.js\";\nimport { OperationCanceledError, ScaffoldAbortedError } from \"./errors.js\";\nimport { getInstallHint } from \"./install-hints.js\";\nimport { updateManifest } from \"./manifest.js\";\nimport {\n isKnownPackageManager,\n PACKAGE_MANAGER_VALUES,\n PACKAGE_MANAGERS,\n type PackageManager,\n} 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?: string | 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 root: string;\n isCurrentDirectory: boolean;\n name: string;\n applicationId: string;\n packageManager: PackageManager;\n isTypescript: boolean;\n shouldIncludeTesting: boolean;\n shouldEmptyTarget: boolean;\n};\n\ntype InstallDependenciesOptions = {\n cwd: string;\n packageManager: PackageManager;\n dependencies: string[];\n isDev: boolean;\n};\n\ntype InstallAllOptions = {\n resolved: ResolvedOptions;\n devDependencies: string[];\n};\n\ntype InstallFailureOptions = {\n error: unknown;\n resolved: ResolvedOptions;\n devDependencies: string[];\n};\n\ntype SpinnerStep = {\n pending: string;\n done: string;\n failed: string;\n run: () => Promise<void>;\n explain?: ((error: unknown) => void) | undefined;\n};\n\nconst selfVersion = packageManifest.version;\nconst ICON_TEMPLATE_NAME = \"icon.svg\";\n\nconst GTKX_ENV_MODULE_HEADER = `/**\n * Generated by \\`gtkx codegen\\`, \\`gtkx dev\\`, and \\`gtkx build\\`; do not edit.\n */`;\n\nconst DEPENDENCIES = [\"@gtkx/cairo\", \"@gtkx/css\", \"@gtkx/runtime\", \"@gtkx/react\", \"react\"];\nconst DEV_DEPENDENCIES = [\"@gtkx/cli\", \"@gtkx/config\", \"@gtkx/mcp\", \"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 ADD_COMMAND: Record<PackageManager, string> = Object.fromEntries(\n PACKAGE_MANAGERS.map((manager) => [manager.value, manager.addCommand]),\n) as Record<PackageManager, string>;\n\nconst INHERITED_SCRIPT_POLICY_VARS = [\"npm_config_allow_scripts\", \"npm_config_allow-scripts\"];\nconst TESTING_TEMPLATES = new Set([\"vitest.config.ts\", \"tests/app.test.tsx\"]);\nconst TYPESCRIPT_TEMPLATES = new Set([\"tsconfig.json\", \"src/gtkx-env.d.ts\"]);\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 RECOVERY_HEADING = \"Finish the setup by adding the dependencies again, which is safe to repeat:\";\nconst APPLICATION_ID_FORMAT_ERROR = \"Application ID must be reverse domain notation (e.g., com.example.myapp)\";\nconst APPLICATION_ID_PREFIX = \"com.\";\nconst APPLICATION_ID_SUFFIX = \".app\";\n\nconst APPLICATION_ID_SEGMENT_LIMIT = APPLICATION_ID_MAX_LENGTH - APPLICATION_ID_PREFIX.length -\n APPLICATION_ID_SUFFIX.length;\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 getAddCommand = (packageManager: PackageManager): string => ADD_COMMAND[packageManager];\nconst titleFromName = (name: string): string => name.split(\"-\").map((part) => upperFirst(part)).join(\" \");\n\nconst gitConfigValue = (key: string): string | null => {\n const git = tryResolveExecutable(\"git\");\n\n if (git === undefined) {\n return null;\n }\n\n try {\n return execFileSync(git, [\"config\", \"--get\", key], { encoding: \"utf8\" }).trim() || null;\n } catch {\n return null;\n }\n};\n\nconst applicationIdSegment = (name: string): string => {\n const compact = name.replaceAll(\"-\", \"\");\n const segment = /^[A-Za-z_]/.test(compact) ? compact : `_${compact}`;\n\n return segment.slice(0, APPLICATION_ID_SEGMENT_LIMIT);\n};\n\nconst suggestApplicationId = (name: string): string =>\n `${APPLICATION_ID_PREFIX}${applicationIdSegment(name)}${APPLICATION_ID_SUFFIX}`;\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 validateApplicationIdFormat = (value: string): string | undefined =>\n isValidApplicationId(value) ? undefined : APPLICATION_ID_FORMAT_ERROR;\n\nconst validateApplicationIdInput = (value: string | undefined): string | undefined =>\n value ? validateApplicationIdFormat(value) : \"Application ID is required\";\n\nconst validateApplicationIdAnswer = (value: string | undefined): string | undefined =>\n value ? validateApplicationIdFormat(value) : undefined;\n\nconst fail = (message: string): never => {\n p.log.error(message);\n throw new ScaffoldAbortedError(message);\n};\n\nconst requestedPackageManager = (value: string | undefined): PackageManager | undefined => {\n if (value === undefined) {\n return undefined;\n }\n\n if (!isKnownPackageManager(value)) {\n return fail(`Unknown package manager \"${value}\". Expected one of: ${PACKAGE_MANAGER_VALUES.join(\", \")}`);\n }\n\n return value;\n};\n\nconst targetStats = (root: string): Stats | undefined => {\n try {\n return statSync(root, { throwIfNoEntry: false });\n } catch {\n return undefined;\n }\n};\n\nconst validateTargetDir = (target: string): string | undefined => {\n if (!target) {\n return \"Project directory is required\";\n }\n\n return validateProjectName(deriveProjectName(target));\n};\n\nconst validateTargetAnswer = (value: string | undefined): string | undefined =>\n validateTargetDir(formatTargetDir(value ?? \"\"));\n\nconst promptTarget = async (): Promise<string> =>\n formatTargetDir(\n guardCancellation(\n await p.text({\n message: \"Project directory\",\n placeholder: \"my-app\",\n validate: validateTargetAnswer,\n }),\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 defaultValue: defaultApplicationId,\n validate: validateApplicationIdAnswer,\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 shouldUseTypeScript = async (): Promise<boolean> =>\n guardCancellation(\n await p.confirm({\n message: \"Use TypeScript?\",\n initialValue: true,\n }),\n );\n\nconst shouldSetUpTesting = 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 prepareTargetDirectory = (root: string, shouldEmptyTarget: boolean): void => {\n mkdirSync(root, { recursive: true });\n\n if (shouldEmptyTarget) {\n emptyDir(root);\n }\n};\n\nconst shouldOverwriteDirectory = 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 shouldEmptyTargetDirectory = async (root: string, target: string, options: CreateOptions): Promise<boolean> => {\n const stats = targetStats(root);\n\n if (stats === undefined) {\n return false;\n }\n\n if (!stats.isDirectory()) {\n return fail(`Target \"${target}\" is not a directory`);\n }\n\n if (isDirEmpty(root)) {\n return false;\n }\n\n if (await shouldOverwriteDirectory(target, options)) {\n return true;\n }\n\n return fail(`Directory \"${target}\" is not empty`);\n};\n\nconst resolveTarget = async (options: CreateOptions): Promise<string> => {\n if (options.name === undefined && options.isInteractive) {\n return promptTarget();\n }\n\n const target = formatTargetDir(options.name ?? \"\");\n const error = validateTargetDir(target);\n\n return error === undefined ? target : fail(error);\n};\n\nconst resolveApplicationId = async (options: CreateOptions, name: string): Promise<string> => {\n const applicationId = options.applicationId ??\n (options.isInteractive ? await promptApplicationId(name) : suggestApplicationId(name));\n\n const error = validateApplicationIdInput(applicationId);\n\n return error === undefined ? applicationId : fail(error);\n};\n\nconst resolvePackageManager = async (\n requested: PackageManager | undefined,\n options: CreateOptions,\n): Promise<PackageManager> => {\n if (requested !== undefined) {\n return requested;\n }\n\n if (options.isInteractive) {\n return promptPackageManager();\n }\n\n return (await detectedPackageManager()) ?? \"pnpm\";\n};\n\nconst isTypescriptSelected = async (options: CreateOptions): Promise<boolean> => {\n if (options.isTypescript !== undefined) {\n return options.isTypescript;\n }\n\n return options.isInteractive ? shouldUseTypeScript() : true;\n};\n\nconst isTestingIncluded = async (options: CreateOptions): Promise<boolean> => {\n if (options.shouldIncludeTesting !== undefined) {\n return options.shouldIncludeTesting;\n }\n\n return options.isInteractive ? shouldSetUpTesting() : true;\n};\n\nconst resolveOptions = async (options: CreateOptions): Promise<ResolvedOptions> => {\n const requested = requestedPackageManager(options.packageManager);\n const target = await resolveTarget(options);\n const name = deriveProjectName(target);\n const applicationId = await resolveApplicationId(options, name);\n const root = resolve(process.cwd(), target);\n const isCurrentDirectory = root === process.cwd();\n const shouldEmptyTarget = await shouldEmptyTargetDirectory(root, target, options);\n const packageManager = await resolvePackageManager(requested, options);\n const isTypescript = await isTypescriptSelected(options);\n const shouldIncludeTesting = await isTestingIncluded(options);\n\n return {\n target,\n root,\n isCurrentDirectory,\n name,\n applicationId,\n packageManager,\n isTypescript,\n shouldIncludeTesting,\n shouldEmptyTarget,\n };\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 toScriptExtension = (templateRelativePath: string, isTypescript: boolean): string =>\n isTypescript ? templateRelativePath : templateRelativePath.replace(/\\.tsx$/, \".jsx\").replace(/\\.ts$/, \".js\");\n\nconst toIconPath = (path: string, applicationId: string): string =>\n path.endsWith(ICON_TEMPLATE_NAME) ? `${path.slice(0, -ICON_TEMPLATE_NAME.length)}${applicationId}.svg` : path;\n\nconst toDestinationPath = (templateRelativePath: string, isTypescript: boolean, applicationId: string): string =>\n toIconPath(toScriptExtension(templateRelativePath, isTypescript), applicationId);\n\nconst addTestScript = (root: string): void => {\n updateManifest(root, (manifest) => {\n (manifest.scripts as Record<string, string>).test = \"vitest run\";\n });\n};\n\nconst templateContext = (resolved: ResolvedOptions): TemplateContext => ({\n name: resolved.name,\n applicationId: resolved.applicationId,\n title: titleFromName(resolved.name),\n shouldIncludeTesting: resolved.shouldIncludeTesting,\n isTypescript: resolved.isTypescript,\n importExtension: resolved.isTypescript ? \".js\" : \".jsx\",\n developerName: gitConfigValue(\"user.name\") ?? titleFromName(resolved.name),\n developerEmail: gitConfigValue(\"user.email\"),\n});\n\nconst scaffoldProject = async (root: string, resolved: ResolvedOptions): Promise<void> => {\n const { applicationId, isTypescript, shouldIncludeTesting } = resolved;\n const context = templateContext(resolved);\n\n for (const template of listTemplates()) {\n if (!isTemplateIncluded(template, resolved)) {\n continue;\n }\n\n const destination = join(root, toDestinationPath(template, isTypescript, applicationId));\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 withoutInheritedScriptPolicy = async (run: () => Promise<void>): Promise<void> => {\n const saved = INHERITED_SCRIPT_POLICY_VARS.map((key) => [key, process.env[key]] as const);\n\n for (const [key] of saved) {\n Reflect.deleteProperty(process.env, key);\n }\n\n try {\n await run();\n } finally {\n for (const [key, value] of saved) {\n if (value !== undefined) {\n process.env[key] = value;\n }\n }\n }\n};\n\nconst installDependencies = async (options: InstallDependenciesOptions): Promise<void> => {\n const { cwd, packageManager, dependencies, isDev } = options;\n\n await withoutInheritedScriptPolicy(async () => {\n await addDependency(dependencies, { cwd, packageManager, dev: isDev, silent: true });\n });\n};\n\nconst pin = (names: string[]): string[] => names.map((dependency) => pinGtkxDependency(dependency, selfVersion));\n\nconst formatRecovery = ({ resolved, devDependencies }: InstallFailureOptions): string => {\n const add = getAddCommand(resolved.packageManager);\n\n const steps = [\n ...(resolved.isCurrentDirectory ? [] : [`cd ${resolved.target}`]),\n `${add} ${pin(DEPENDENCIES).join(\" \")}`,\n `${add} -D ${pin(devDependencies).join(\" \")}`,\n ];\n\n const indented = steps.map((step) => ` ${step}`).join(\"\\n\");\n\n return `${RECOVERY_HEADING}\\n${indented}`;\n};\n\nconst explainInstallFailure = (options: InstallFailureOptions): void => {\n const hint = getInstallHint(errorMessage(options.error));\n\n if (hint !== undefined) {\n p.log.warn(hint);\n }\n\n p.log.info(formatRecovery(options));\n};\n\nconst runWithSpinner = async (step: SpinnerStep): Promise<void> => {\n const spinner = p.spinner();\n spinner.start(step.pending);\n\n try {\n await step.run();\n spinner.stop(step.done);\n } catch (error) {\n spinner.error(step.failed);\n p.log.error(errorMessage(error));\n step.explain?.(error);\n throw new ScaffoldAbortedError(step.failed);\n }\n};\n\nconst installAllDependencies = async (options: InstallAllOptions): Promise<void> => {\n const { resolved, devDependencies } = options;\n const { root, packageManager } = resolved;\n\n await runWithSpinner({\n pending: \"Installing dependencies...\",\n done: \"Dependencies installed\",\n failed: \"Failed to install dependencies\",\n run: async () => {\n await installDependencies({ cwd: root, packageManager, dependencies: pin(DEPENDENCIES), isDev: false });\n await installDependencies({ cwd: root, packageManager, dependencies: pin(devDependencies), isDev: true });\n },\n explain: (error) => {\n explainInstallFailure({ error, resolved, devDependencies });\n },\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.error(\"Failed to initialize git repository\");\n }\n};\n\nconst printNextSteps = (resolved: ResolvedOptions): void => {\n const devCmd = getDevCommand(resolved.packageManager);\n const cdStep = resolved.isCurrentDirectory ? \"\" : `cd ${resolved.target}\\n`;\n const testingNote = resolved.shouldIncludeTesting ? HEADLESS_COMPOSITOR_NOTE : \"\";\n p.note(`${cdStep}${devCmd}${testingNote}`, \"Next steps\");\n};\n\nconst createProjectStructure = async (root: string, resolved: ResolvedOptions): Promise<void> => {\n await runWithSpinner({\n pending: \"Creating project structure...\",\n done: \"Project structure created\",\n failed: \"Failed to create the project structure\",\n run: async () => {\n prepareTargetDirectory(root, resolved.shouldEmptyTarget);\n await scaffoldProject(root, resolved);\n writeBuildAllowance(root, resolved.packageManager);\n },\n });\n};\n\nconst scaffold = async (options: CreateOptions = {}): Promise<void> => {\n p.intro(\"Create GTKX App\");\n const resolved = await resolveOptions(options);\n const { root } = resolved;\n const devDeps = getDevDependencies(resolved);\n await createProjectStructure(root, resolved);\n await installAllDependencies({ resolved, devDependencies: devDeps });\n\n if (resolved.isTypescript) {\n writeInitialEnvModule(root);\n }\n\n await initializeGitRepo(root);\n printNextSteps(resolved);\n};\n\nexport { scaffold };\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 { APPLICATION_ID_MAX_LENGTH, isValidApplicationId } from \"@gtkx/config/internal\";\nimport { errorMessage, tryResolveExecutable, upperFirst } from \"@gtkx/utils\";\nimport { execFileSync } from \"node:child_process\";\nimport { mkdirSync, readdirSync, rmSync, statSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { addDependency, detectPackageManager as nypmDetectPackageManager } from \"nypm\";\nimport { x } from \"tinyexec\";\nimport packageManifest from \"../package.json\" with { type: \"json\" };\nimport { writeBuildAllowance } from \"./build-allowance.js\";\nimport { OperationCanceledError, ScaffoldAbortedError } from \"./errors.js\";\nimport { getInstallHint } from \"./install-hints.js\";\nimport { updateManifest } from \"./manifest.js\";\nimport {\n isKnownPackageManager,\n PACKAGE_MANAGER_VALUES,\n PACKAGE_MANAGERS,\n type PackageManager,\n} 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?: string | 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 root: string;\n isCurrentDirectory: boolean;\n name: string;\n applicationId: string;\n packageManager: PackageManager;\n isTypescript: boolean;\n shouldIncludeTesting: boolean;\n shouldEmptyTarget: boolean;\n};\n\ntype InstallDependenciesOptions = {\n cwd: string;\n packageManager: PackageManager;\n dependencies: string[];\n isDev: boolean;\n};\n\ntype InstallAllOptions = {\n resolved: ResolvedOptions;\n devDependencies: string[];\n};\n\ntype InstallFailureOptions = {\n error: unknown;\n resolved: ResolvedOptions;\n devDependencies: string[];\n};\n\ntype SpinnerStep = {\n pending: string;\n done: string;\n failed: string;\n run: () => Promise<void>;\n explain?: ((error: unknown) => void) | undefined;\n};\n\nconst selfVersion = packageManifest.version;\nconst ICON_TEMPLATE_NAME = \"icon.svg\";\n\nconst GTKX_ENV_MODULE_HEADER = `/**\n * Generated by \\`gtkx codegen\\`, \\`gtkx dev\\`, and \\`gtkx build\\`; do not edit.\n */`;\n\nconst DEPENDENCIES = [\"@gtkx/cairo\", \"@gtkx/css\", \"@gtkx/runtime\", \"@gtkx/react\", \"react\"];\nconst DEV_DEPENDENCIES = [\"@gtkx/cli\", \"@gtkx/config\", \"@gtkx/mcp\", \"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 ADD_COMMAND: Record<PackageManager, string> = Object.fromEntries(\n PACKAGE_MANAGERS.map((manager) => [manager.value, manager.addCommand]),\n) as Record<PackageManager, string>;\n\nconst INHERITED_SCRIPT_POLICY_VARS = [\"npm_config_allow_scripts\", \"npm_config_allow-scripts\"];\nconst TESTING_TEMPLATES = new Set([\"vitest.config.ts\", \"tests/app.test.tsx\"]);\nconst TYPESCRIPT_TEMPLATES = new Set([\"tsconfig.json\", \"src/gtkx-env.d.ts\"]);\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 RECOVERY_HEADING = \"Finish the setup by adding the dependencies again, which is safe to repeat:\";\nconst APPLICATION_ID_FORMAT_ERROR = \"Application ID must be reverse domain notation (e.g., com.example.myapp)\";\nconst APPLICATION_ID_PREFIX = \"com.\";\nconst APPLICATION_ID_SUFFIX = \".app\";\n\nconst APPLICATION_ID_SEGMENT_LIMIT = APPLICATION_ID_MAX_LENGTH - APPLICATION_ID_PREFIX.length -\n APPLICATION_ID_SUFFIX.length;\n\nconst titleFromName = (name: string): string => name.split(\"-\").map((part) => upperFirst(part)).join(\" \");\n\nconst gitConfigValue = (key: string): string | null => {\n const git = tryResolveExecutable(\"git\");\n\n if (git === undefined) {\n return null;\n }\n\n try {\n return execFileSync(git, [\"config\", \"--get\", key], { encoding: \"utf8\" }).trim() || null;\n } catch {\n return null;\n }\n};\n\nconst applicationIdSegment = (name: string): string => {\n const compact = name.replaceAll(\"-\", \"\");\n const segment = /^[A-Za-z_]/.test(compact) ? compact : `_${compact}`;\n\n return segment.slice(0, APPLICATION_ID_SEGMENT_LIMIT);\n};\n\nconst suggestApplicationId = (name: string): string =>\n `${APPLICATION_ID_PREFIX}${applicationIdSegment(name)}${APPLICATION_ID_SUFFIX}`;\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 =>\n stripTrailingSlashes(target.trim().replaceAll(/[<>:\"\\\\|?*]/g, \"\"));\n\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 validateApplicationIdFormat = (value: string): string | undefined =>\n isValidApplicationId(value) ? undefined : APPLICATION_ID_FORMAT_ERROR;\n\nconst validateApplicationIdInput = (value: string | undefined): string | undefined =>\n value ? validateApplicationIdFormat(value) : \"Application ID is required\";\n\nconst validateApplicationIdAnswer = (value: string | undefined): string | undefined =>\n value ? validateApplicationIdFormat(value) : undefined;\n\nconst fail = (message: string): never => {\n p.log.error(message);\n throw new ScaffoldAbortedError(message);\n};\n\nconst requestedPackageManager = (value: string | undefined): PackageManager | undefined => {\n if (value === undefined) {\n return undefined;\n }\n\n if (!isKnownPackageManager(value)) {\n return fail(`Unknown package manager \"${value}\". Expected one of: ${PACKAGE_MANAGER_VALUES.join(\", \")}`);\n }\n\n return value;\n};\n\nconst validateTargetDir = (target: string): string | undefined => {\n if (!target) {\n return \"Project directory is required\";\n }\n\n return validateProjectName(deriveProjectName(target));\n};\n\nconst validateTargetAnswer = (value: string | undefined): string | undefined =>\n validateTargetDir(formatTargetDir(value ?? \"\"));\n\nconst promptTarget = async (): Promise<string> =>\n formatTargetDir(\n guardCancellation(\n await p.text({\n message: \"Project directory\",\n placeholder: \"my-app\",\n validate: validateTargetAnswer,\n }),\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 defaultValue: defaultApplicationId,\n validate: validateApplicationIdAnswer,\n }),\n );\n};\n\nconst packageManagerOption = (manager: (typeof PACKAGE_MANAGERS)[number], detected: PackageManager | undefined) => {\n let hint: string | undefined;\n\n if (detected === manager.value) {\n hint = \"detected\";\n } else if (manager.isRecommended) {\n hint = \"recommended\";\n }\n\n return { value: manager.value, label: manager.label, ...(hint !== undefined && { hint }) };\n};\n\nconst detectedPackageManager = async (): Promise<PackageManager | undefined> => {\n try {\n const detected = await nypmDetectPackageManager(process.cwd(), { includeParentDirs: true });\n\n return detected && isKnownPackageManager(detected.name) ? detected.name : undefined;\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 isOptionEnabled = async (\n value: boolean | undefined,\n isInteractive: boolean | undefined,\n message: string,\n): Promise<boolean> =>\n value ??\n (isInteractive\n ? guardCancellation(await p.confirm({ message, initialValue: true }))\n : true);\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 shouldOverwriteDirectory = 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 shouldEmptyTargetDirectory = async (root: string, target: string, options: CreateOptions): Promise<boolean> => {\n const stats = statSync(root, { throwIfNoEntry: false });\n\n if (stats === undefined) {\n return false;\n }\n\n if (!stats.isDirectory()) {\n return fail(`Target \"${target}\" is not a directory`);\n }\n\n if (isDirEmpty(root)) {\n return false;\n }\n\n if (await shouldOverwriteDirectory(target, options)) {\n return true;\n }\n\n return fail(`Directory \"${target}\" is not empty`);\n};\n\nconst resolveTarget = async (options: CreateOptions): Promise<string> => {\n if (options.name === undefined && options.isInteractive) {\n return promptTarget();\n }\n\n const target = formatTargetDir(options.name ?? \"\");\n const error = validateTargetDir(target);\n\n return error === undefined ? target : fail(error);\n};\n\nconst resolveApplicationId = async (options: CreateOptions, name: string): Promise<string> => {\n const applicationId = options.applicationId ??\n (options.isInteractive ? await promptApplicationId(name) : suggestApplicationId(name));\n\n const error = validateApplicationIdInput(applicationId);\n\n return error === undefined ? applicationId : fail(error);\n};\n\nconst resolvePackageManager = async (\n requested: PackageManager | undefined,\n options: CreateOptions,\n): Promise<PackageManager> => {\n if (requested !== undefined) {\n return requested;\n }\n\n if (options.isInteractive) {\n return promptPackageManager();\n }\n\n return (await detectedPackageManager()) ?? \"pnpm\";\n};\n\nconst resolveOptions = async (options: CreateOptions): Promise<ResolvedOptions> => {\n const requested = requestedPackageManager(options.packageManager);\n const target = await resolveTarget(options);\n const name = deriveProjectName(target);\n const applicationId = await resolveApplicationId(options, name);\n const root = resolve(process.cwd(), target);\n const isCurrentDirectory = root === process.cwd();\n const shouldEmptyTarget = await shouldEmptyTargetDirectory(root, target, options);\n const packageManager = await resolvePackageManager(requested, options);\n const isTypescript = await isOptionEnabled(options.isTypescript, options.isInteractive, \"Use TypeScript?\");\n\n const shouldIncludeTesting = await isOptionEnabled(\n options.shouldIncludeTesting,\n options.isInteractive,\n \"Include testing setup (Vitest)?\",\n );\n\n return {\n target,\n root,\n isCurrentDirectory,\n name,\n applicationId,\n packageManager,\n isTypescript,\n shouldIncludeTesting,\n shouldEmptyTarget,\n };\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 destinationPath = (template: string, resolved: ResolvedOptions): string => {\n const scriptPath = resolved.isTypescript ? template : template.replace(/\\.tsx$/, \".jsx\").replace(/\\.ts$/, \".js\");\n\n return scriptPath.endsWith(ICON_TEMPLATE_NAME)\n ? `${scriptPath.slice(0, -ICON_TEMPLATE_NAME.length)}${resolved.applicationId}.svg`\n : scriptPath;\n};\n\nconst templateContext = (resolved: ResolvedOptions): TemplateContext => ({\n name: resolved.name,\n applicationId: resolved.applicationId,\n title: titleFromName(resolved.name),\n shouldIncludeTesting: resolved.shouldIncludeTesting,\n isTypescript: resolved.isTypescript,\n importExtension: resolved.isTypescript ? \".js\" : \".jsx\",\n developerName: gitConfigValue(\"user.name\") ?? titleFromName(resolved.name),\n developerEmail: gitConfigValue(\"user.email\"),\n});\n\nconst scaffoldProject = async (root: string, resolved: ResolvedOptions): Promise<void> => {\n const context = templateContext(resolved);\n\n for (const template of listTemplates()) {\n if (!isTemplateIncluded(template, resolved)) {\n continue;\n }\n\n const destination = join(root, destinationPath(template, resolved));\n mkdirSync(dirname(destination), { recursive: true });\n writeFileSync(destination, await renderFile(template, context));\n }\n\n if (resolved.shouldIncludeTesting) {\n updateManifest(root, (manifest) => {\n (manifest.scripts as Record<string, string>).test = \"vitest run\";\n });\n }\n};\n\nconst withoutInheritedScriptPolicy = async (run: () => Promise<void>): Promise<void> => {\n const saved = INHERITED_SCRIPT_POLICY_VARS.map((key) => [key, process.env[key]] as const);\n\n for (const [key] of saved) {\n Reflect.deleteProperty(process.env, key);\n }\n\n try {\n await run();\n } finally {\n for (const [key, value] of saved) {\n if (value !== undefined) {\n process.env[key] = value;\n }\n }\n }\n};\n\nconst installDependencies = async (options: InstallDependenciesOptions): Promise<void> => {\n const { cwd, packageManager, dependencies, isDev } = options;\n\n await withoutInheritedScriptPolicy(async () => {\n await addDependency(dependencies, { cwd, packageManager, dev: isDev, silent: true });\n });\n};\n\nconst pin = (names: string[]): string[] =>\n names.map((dependency) => dependency.startsWith(\"@gtkx/\") ? `${dependency}@^${selfVersion}` : dependency);\n\nconst formatRecovery = ({ resolved, devDependencies }: InstallFailureOptions): string => {\n const add = ADD_COMMAND[resolved.packageManager];\n\n const steps = [\n ...(resolved.isCurrentDirectory ? [] : [`cd ${resolved.target}`]),\n `${add} ${pin(DEPENDENCIES).join(\" \")}`,\n `${add} -D ${pin(devDependencies).join(\" \")}`,\n ];\n\n const indented = steps.map((step) => ` ${step}`).join(\"\\n\");\n\n return `${RECOVERY_HEADING}\\n${indented}`;\n};\n\nconst explainInstallFailure = (options: InstallFailureOptions): void => {\n const hint = getInstallHint(errorMessage(options.error));\n\n if (hint !== undefined) {\n p.log.warn(hint);\n }\n\n p.log.info(formatRecovery(options));\n};\n\nconst runWithSpinner = async (step: SpinnerStep): Promise<void> => {\n const spinner = p.spinner();\n spinner.start(step.pending);\n\n try {\n await step.run();\n spinner.stop(step.done);\n } catch (error) {\n spinner.error(step.failed);\n p.log.error(errorMessage(error));\n step.explain?.(error);\n throw new ScaffoldAbortedError(step.failed);\n }\n};\n\nconst installAllDependencies = async (options: InstallAllOptions): Promise<void> => {\n const { resolved, devDependencies } = options;\n const { root, packageManager } = resolved;\n\n await runWithSpinner({\n pending: \"Installing dependencies...\",\n done: \"Dependencies installed\",\n failed: \"Failed to install dependencies\",\n run: async () => {\n await installDependencies({ cwd: root, packageManager, dependencies: pin(DEPENDENCIES), isDev: false });\n await installDependencies({ cwd: root, packageManager, dependencies: pin(devDependencies), isDev: true });\n },\n explain: (error) => {\n explainInstallFailure({ error, resolved, devDependencies });\n },\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.error(\"Failed to initialize git repository\");\n }\n};\n\nconst printNextSteps = (resolved: ResolvedOptions): void => {\n const devCmd = DEV_COMMAND[resolved.packageManager];\n const cdStep = resolved.isCurrentDirectory ? \"\" : `cd ${resolved.target}\\n`;\n const testingNote = resolved.shouldIncludeTesting ? HEADLESS_COMPOSITOR_NOTE : \"\";\n p.note(`${cdStep}${devCmd}${testingNote}`, \"Next steps\");\n};\n\nconst createProjectStructure = async (root: string, resolved: ResolvedOptions): Promise<void> => {\n await runWithSpinner({\n pending: \"Creating project structure...\",\n done: \"Project structure created\",\n failed: \"Failed to create the project structure\",\n run: async () => {\n mkdirSync(root, { recursive: true });\n\n if (resolved.shouldEmptyTarget) {\n emptyDir(root);\n }\n\n await scaffoldProject(root, resolved);\n writeBuildAllowance(root, resolved.packageManager);\n },\n });\n};\n\nconst scaffold = async (options: CreateOptions = {}): Promise<void> => {\n p.intro(\"Create GTKX App\");\n const resolved = await resolveOptions(options);\n const { root } = resolved;\n const devDeps = getDevDependencies(resolved);\n await createProjectStructure(root, resolved);\n await installAllDependencies({ resolved, devDependencies: devDeps });\n\n if (resolved.isTypescript) {\n writeInitialEnvModule(root);\n }\n\n await initializeGitRepo(root);\n printNextSteps(resolved);\n};\n\nexport { scaffold };\n"]}
|
|
@@ -3,15 +3,6 @@ import { defineConfig } from "@gtkx/config";
|
|
|
3
3
|
export default defineConfig({
|
|
4
4
|
applicationId: "<%= applicationId %>",
|
|
5
5
|
applicationIcon: "data/icons",
|
|
6
|
-
future: {
|
|
7
|
-
v2ByteArrays: true,
|
|
8
|
-
v2ValueReturns: true,
|
|
9
|
-
v2FinishResults: true,
|
|
10
|
-
v2InoutReturns: true,
|
|
11
|
-
v2ResourceImports: true,
|
|
12
|
-
v2DefaultLibraries: true,
|
|
13
|
-
v2TreeShaking: true,
|
|
14
|
-
},
|
|
15
6
|
deploy: {
|
|
16
7
|
name: "<%= title %>",
|
|
17
8
|
summary: "A GTK4 application built with GTKX",
|
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,oBAAoB,EAAE,OAAO,CAAC;IAC9B,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,CAAC;
|
|
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;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,CAAC;AAIF,QAAA,MAAM,aAAa,QAAO,MAAM,EAO3B,CAAC;AAEN,QAAA,MAAM,UAAU,GAAU,cAAc,MAAM,EAAE,SAAS,eAAe,KAAG,OAAO,CAAC,MAAM,CACU,CAAC;AAEpG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,CAAC"}
|
package/dist/templates.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import { sortStrings, sourceStringLiteral } from "@gtkx/utils";
|
|
1
|
+
import { sortStrings, sourceStringLiteral, toPosixPath } from "@gtkx/utils";
|
|
2
2
|
import ejs from "ejs";
|
|
3
3
|
import { readdirSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
};
|
|
8
|
-
const listTemplates = () => sortStrings(readdirSync(getTemplatesDir(), { recursive: true, withFileTypes: true })
|
|
5
|
+
const TEMPLATES_DIR = join(import.meta.dirname, "templates");
|
|
6
|
+
const listTemplates = () => sortStrings(readdirSync(TEMPLATES_DIR, { recursive: true, withFileTypes: true })
|
|
9
7
|
.filter((entry) => entry.isFile())
|
|
10
8
|
.map((entry) => join(entry.parentPath, entry.name))
|
|
11
|
-
.map((absolute) => absolute.slice(
|
|
9
|
+
.map((absolute) => toPosixPath(absolute.slice(TEMPLATES_DIR.length + 1)))
|
|
12
10
|
.map((relative) => relative.replace(/\.ejs$/, "")));
|
|
13
|
-
const renderFile = async (templateName, context) => ejs.renderFile(join(
|
|
11
|
+
const renderFile = async (templateName, context) => ejs.renderFile(join(TEMPLATES_DIR, `${templateName}.ejs`), { ...context, sourceStringLiteral });
|
|
14
12
|
export { listTemplates, renderFile };
|
|
15
13
|
//# sourceMappingURL=templates.js.map
|
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,mBAAmB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAajC,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AAE7D,MAAM,aAAa,GAAG,GAAa,EAAE,CACjC,WAAW,CACP,WAAW,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;KAC/D,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,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;KACxE,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,aAAa,EAAE,GAAG,YAAY,MAAM,CAAC,EAAE,EAAE,GAAG,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAAC;AAEpG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAwB,CAAC","sourcesContent":["import { sortStrings, sourceStringLiteral, toPosixPath } 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 developerName: string;\n developerEmail: string | null;\n};\n\nconst TEMPLATES_DIR = join(import.meta.dirname, \"templates\");\n\nconst listTemplates = (): string[] =>\n sortStrings(\n readdirSync(TEMPLATES_DIR, { recursive: true, withFileTypes: true })\n .filter((entry) => entry.isFile())\n .map((entry) => join(entry.parentPath, entry.name))\n .map((absolute) => toPosixPath(absolute.slice(TEMPLATES_DIR.length + 1)))\n .map((relative) => relative.replace(/\\.ejs$/, \"\")),\n );\n\nconst renderFile = async (templateName: string, context: TemplateContext): Promise<string> =>\n ejs.renderFile(join(TEMPLATES_DIR, `${templateName}.ejs`), { ...context, sourceStringLiteral });\n\nexport { listTemplates, renderFile, type TemplateContext };\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-gtkx",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta.1",
|
|
4
4
|
"description": "Create a native GTK4 + React desktop app. Real GTK widgets.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gtkx",
|
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
"./package.json": "./package.json",
|
|
31
31
|
".": {
|
|
32
32
|
"types": "./dist/index.d.ts",
|
|
33
|
+
"import": "./dist/index.js",
|
|
34
|
+
"require": null,
|
|
33
35
|
"default": "./dist/index.js"
|
|
34
36
|
}
|
|
35
37
|
},
|
|
@@ -43,20 +45,20 @@
|
|
|
43
45
|
"src"
|
|
44
46
|
],
|
|
45
47
|
"engines": {
|
|
46
|
-
"node": ">=
|
|
48
|
+
"node": ">=26.7.0"
|
|
47
49
|
},
|
|
48
50
|
"dependencies": {
|
|
49
51
|
"@clack/prompts": "^1.7.0",
|
|
52
|
+
"@gtkx/config": "2.0.0-beta.1",
|
|
53
|
+
"@gtkx/utils": "2.0.0-beta.1",
|
|
50
54
|
"ejs": "^6.0.1",
|
|
51
55
|
"citty": "^0.2.2",
|
|
52
56
|
"nypm": "^0.6.9",
|
|
53
|
-
"tinyexec": "^1.3.0"
|
|
54
|
-
"@gtkx/config": "1.6.0",
|
|
55
|
-
"@gtkx/utils": "1.6.0"
|
|
57
|
+
"tinyexec": "^1.3.0"
|
|
56
58
|
},
|
|
57
59
|
"devDependencies": {
|
|
58
60
|
"@types/ejs": "^3.1.5",
|
|
59
|
-
"@types/node": "^26.
|
|
61
|
+
"@types/node": "^26.4.0",
|
|
60
62
|
"typescript": "^6.0.3",
|
|
61
63
|
"vitest": "^4.1.11"
|
|
62
64
|
},
|
package/src/scaffolder.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as p from "@clack/prompts";
|
|
|
2
2
|
import { APPLICATION_ID_MAX_LENGTH, isValidApplicationId } from "@gtkx/config/internal";
|
|
3
3
|
import { errorMessage, tryResolveExecutable, upperFirst } from "@gtkx/utils";
|
|
4
4
|
import { execFileSync } from "node:child_process";
|
|
5
|
-
import { mkdirSync, readdirSync, rmSync,
|
|
5
|
+
import { mkdirSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { basename, dirname, join, resolve } from "node:path";
|
|
7
7
|
import { addDependency, detectPackageManager as nypmDetectPackageManager } from "nypm";
|
|
8
8
|
import { x } from "tinyexec";
|
|
@@ -106,11 +106,6 @@ const APPLICATION_ID_SUFFIX = ".app";
|
|
|
106
106
|
const APPLICATION_ID_SEGMENT_LIMIT = APPLICATION_ID_MAX_LENGTH - APPLICATION_ID_PREFIX.length -
|
|
107
107
|
APPLICATION_ID_SUFFIX.length;
|
|
108
108
|
|
|
109
|
-
const pinGtkxDependency = (name: string, version: string): string =>
|
|
110
|
-
name.startsWith("@gtkx/") ? `${name}@^${version}` : name;
|
|
111
|
-
|
|
112
|
-
const getDevCommand = (packageManager: PackageManager): string => DEV_COMMAND[packageManager];
|
|
113
|
-
const getAddCommand = (packageManager: PackageManager): string => ADD_COMMAND[packageManager];
|
|
114
109
|
const titleFromName = (name: string): string => name.split("-").map((part) => upperFirst(part)).join(" ");
|
|
115
110
|
|
|
116
111
|
const gitConfigValue = (key: string): string | null => {
|
|
@@ -147,7 +142,9 @@ const stripTrailingSlashes = (value: string): string => {
|
|
|
147
142
|
return value.slice(0, end);
|
|
148
143
|
};
|
|
149
144
|
|
|
150
|
-
const formatTargetDir = (target: string): string =>
|
|
145
|
+
const formatTargetDir = (target: string): string =>
|
|
146
|
+
stripTrailingSlashes(target.trim().replaceAll(/[<>:"\\|?*]/g, ""));
|
|
147
|
+
|
|
151
148
|
const deriveProjectName = (target: string): string => basename(resolve(process.cwd(), target));
|
|
152
149
|
|
|
153
150
|
const isDirEmpty = (dir: string): boolean => {
|
|
@@ -220,14 +217,6 @@ const requestedPackageManager = (value: string | undefined): PackageManager | un
|
|
|
220
217
|
return value;
|
|
221
218
|
};
|
|
222
219
|
|
|
223
|
-
const targetStats = (root: string): Stats | undefined => {
|
|
224
|
-
try {
|
|
225
|
-
return statSync(root, { throwIfNoEntry: false });
|
|
226
|
-
} catch {
|
|
227
|
-
return undefined;
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
|
|
231
220
|
const validateTargetDir = (target: string): string | undefined => {
|
|
232
221
|
if (!target) {
|
|
233
222
|
return "Project directory is required";
|
|
@@ -263,40 +252,23 @@ const promptApplicationId = async (name: string): Promise<string> => {
|
|
|
263
252
|
);
|
|
264
253
|
};
|
|
265
254
|
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
if (!detected) {
|
|
270
|
-
return undefined;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return isKnownPackageManager(detected.name) ? detected.name : undefined;
|
|
274
|
-
};
|
|
255
|
+
const packageManagerOption = (manager: (typeof PACKAGE_MANAGERS)[number], detected: PackageManager | undefined) => {
|
|
256
|
+
let hint: string | undefined;
|
|
275
257
|
|
|
276
|
-
const packageManagerHint = (
|
|
277
|
-
manager: (typeof PACKAGE_MANAGERS)[number],
|
|
278
|
-
detected: PackageManager | undefined,
|
|
279
|
-
): string | undefined => {
|
|
280
258
|
if (detected === manager.value) {
|
|
281
|
-
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
if (manager.isRecommended) {
|
|
285
|
-
return "recommended";
|
|
259
|
+
hint = "detected";
|
|
260
|
+
} else if (manager.isRecommended) {
|
|
261
|
+
hint = "recommended";
|
|
286
262
|
}
|
|
287
263
|
|
|
288
|
-
return undefined;
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
const packageManagerOption = (manager: (typeof PACKAGE_MANAGERS)[number], detected: PackageManager | undefined) => {
|
|
292
|
-
const hint = packageManagerHint(manager, detected);
|
|
293
|
-
|
|
294
264
|
return { value: manager.value, label: manager.label, ...(hint !== undefined && { hint }) };
|
|
295
265
|
};
|
|
296
266
|
|
|
297
267
|
const detectedPackageManager = async (): Promise<PackageManager | undefined> => {
|
|
298
268
|
try {
|
|
299
|
-
|
|
269
|
+
const detected = await nypmDetectPackageManager(process.cwd(), { includeParentDirs: true });
|
|
270
|
+
|
|
271
|
+
return detected && isKnownPackageManager(detected.name) ? detected.name : undefined;
|
|
300
272
|
} catch {
|
|
301
273
|
return undefined;
|
|
302
274
|
}
|
|
@@ -315,21 +287,15 @@ const promptPackageManager = async (): Promise<PackageManager> => {
|
|
|
315
287
|
);
|
|
316
288
|
};
|
|
317
289
|
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
guardCancellation(
|
|
328
|
-
await p.confirm({
|
|
329
|
-
message: "Include testing setup (Vitest)?",
|
|
330
|
-
initialValue: true,
|
|
331
|
-
}),
|
|
332
|
-
);
|
|
290
|
+
const isOptionEnabled = async (
|
|
291
|
+
value: boolean | undefined,
|
|
292
|
+
isInteractive: boolean | undefined,
|
|
293
|
+
message: string,
|
|
294
|
+
): Promise<boolean> =>
|
|
295
|
+
value ??
|
|
296
|
+
(isInteractive
|
|
297
|
+
? guardCancellation(await p.confirm({ message, initialValue: true }))
|
|
298
|
+
: true);
|
|
333
299
|
|
|
334
300
|
const emptyDir = (root: string): void => {
|
|
335
301
|
for (const entry of readdirSync(root)) {
|
|
@@ -341,14 +307,6 @@ const emptyDir = (root: string): void => {
|
|
|
341
307
|
}
|
|
342
308
|
};
|
|
343
309
|
|
|
344
|
-
const prepareTargetDirectory = (root: string, shouldEmptyTarget: boolean): void => {
|
|
345
|
-
mkdirSync(root, { recursive: true });
|
|
346
|
-
|
|
347
|
-
if (shouldEmptyTarget) {
|
|
348
|
-
emptyDir(root);
|
|
349
|
-
}
|
|
350
|
-
};
|
|
351
|
-
|
|
352
310
|
const shouldOverwriteDirectory = async (target: string, options: CreateOptions): Promise<boolean> => {
|
|
353
311
|
if (!options.isInteractive) {
|
|
354
312
|
return options.shouldOverwrite === true;
|
|
@@ -363,7 +321,7 @@ const shouldOverwriteDirectory = async (target: string, options: CreateOptions):
|
|
|
363
321
|
};
|
|
364
322
|
|
|
365
323
|
const shouldEmptyTargetDirectory = async (root: string, target: string, options: CreateOptions): Promise<boolean> => {
|
|
366
|
-
const stats =
|
|
324
|
+
const stats = statSync(root, { throwIfNoEntry: false });
|
|
367
325
|
|
|
368
326
|
if (stats === undefined) {
|
|
369
327
|
return false;
|
|
@@ -419,22 +377,6 @@ const resolvePackageManager = async (
|
|
|
419
377
|
return (await detectedPackageManager()) ?? "pnpm";
|
|
420
378
|
};
|
|
421
379
|
|
|
422
|
-
const isTypescriptSelected = async (options: CreateOptions): Promise<boolean> => {
|
|
423
|
-
if (options.isTypescript !== undefined) {
|
|
424
|
-
return options.isTypescript;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
return options.isInteractive ? shouldUseTypeScript() : true;
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
const isTestingIncluded = async (options: CreateOptions): Promise<boolean> => {
|
|
431
|
-
if (options.shouldIncludeTesting !== undefined) {
|
|
432
|
-
return options.shouldIncludeTesting;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
return options.isInteractive ? shouldSetUpTesting() : true;
|
|
436
|
-
};
|
|
437
|
-
|
|
438
380
|
const resolveOptions = async (options: CreateOptions): Promise<ResolvedOptions> => {
|
|
439
381
|
const requested = requestedPackageManager(options.packageManager);
|
|
440
382
|
const target = await resolveTarget(options);
|
|
@@ -444,8 +386,13 @@ const resolveOptions = async (options: CreateOptions): Promise<ResolvedOptions>
|
|
|
444
386
|
const isCurrentDirectory = root === process.cwd();
|
|
445
387
|
const shouldEmptyTarget = await shouldEmptyTargetDirectory(root, target, options);
|
|
446
388
|
const packageManager = await resolvePackageManager(requested, options);
|
|
447
|
-
const isTypescript = await
|
|
448
|
-
|
|
389
|
+
const isTypescript = await isOptionEnabled(options.isTypescript, options.isInteractive, "Use TypeScript?");
|
|
390
|
+
|
|
391
|
+
const shouldIncludeTesting = await isOptionEnabled(
|
|
392
|
+
options.shouldIncludeTesting,
|
|
393
|
+
options.isInteractive,
|
|
394
|
+
"Include testing setup (Vitest)?",
|
|
395
|
+
);
|
|
449
396
|
|
|
450
397
|
return {
|
|
451
398
|
target,
|
|
@@ -472,19 +419,12 @@ const isTemplateIncluded = (templateRelativePath: string, resolved: ResolvedOpti
|
|
|
472
419
|
return true;
|
|
473
420
|
};
|
|
474
421
|
|
|
475
|
-
const
|
|
476
|
-
isTypescript ?
|
|
477
|
-
|
|
478
|
-
const toIconPath = (path: string, applicationId: string): string =>
|
|
479
|
-
path.endsWith(ICON_TEMPLATE_NAME) ? `${path.slice(0, -ICON_TEMPLATE_NAME.length)}${applicationId}.svg` : path;
|
|
422
|
+
const destinationPath = (template: string, resolved: ResolvedOptions): string => {
|
|
423
|
+
const scriptPath = resolved.isTypescript ? template : template.replace(/\.tsx$/, ".jsx").replace(/\.ts$/, ".js");
|
|
480
424
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
const addTestScript = (root: string): void => {
|
|
485
|
-
updateManifest(root, (manifest) => {
|
|
486
|
-
(manifest.scripts as Record<string, string>).test = "vitest run";
|
|
487
|
-
});
|
|
425
|
+
return scriptPath.endsWith(ICON_TEMPLATE_NAME)
|
|
426
|
+
? `${scriptPath.slice(0, -ICON_TEMPLATE_NAME.length)}${resolved.applicationId}.svg`
|
|
427
|
+
: scriptPath;
|
|
488
428
|
};
|
|
489
429
|
|
|
490
430
|
const templateContext = (resolved: ResolvedOptions): TemplateContext => ({
|
|
@@ -499,7 +439,6 @@ const templateContext = (resolved: ResolvedOptions): TemplateContext => ({
|
|
|
499
439
|
});
|
|
500
440
|
|
|
501
441
|
const scaffoldProject = async (root: string, resolved: ResolvedOptions): Promise<void> => {
|
|
502
|
-
const { applicationId, isTypescript, shouldIncludeTesting } = resolved;
|
|
503
442
|
const context = templateContext(resolved);
|
|
504
443
|
|
|
505
444
|
for (const template of listTemplates()) {
|
|
@@ -507,13 +446,15 @@ const scaffoldProject = async (root: string, resolved: ResolvedOptions): Promise
|
|
|
507
446
|
continue;
|
|
508
447
|
}
|
|
509
448
|
|
|
510
|
-
const destination = join(root,
|
|
449
|
+
const destination = join(root, destinationPath(template, resolved));
|
|
511
450
|
mkdirSync(dirname(destination), { recursive: true });
|
|
512
451
|
writeFileSync(destination, await renderFile(template, context));
|
|
513
452
|
}
|
|
514
453
|
|
|
515
|
-
if (shouldIncludeTesting) {
|
|
516
|
-
|
|
454
|
+
if (resolved.shouldIncludeTesting) {
|
|
455
|
+
updateManifest(root, (manifest) => {
|
|
456
|
+
(manifest.scripts as Record<string, string>).test = "vitest run";
|
|
457
|
+
});
|
|
517
458
|
}
|
|
518
459
|
};
|
|
519
460
|
|
|
@@ -543,10 +484,11 @@ const installDependencies = async (options: InstallDependenciesOptions): Promise
|
|
|
543
484
|
});
|
|
544
485
|
};
|
|
545
486
|
|
|
546
|
-
const pin = (names: string[]): string[] =>
|
|
487
|
+
const pin = (names: string[]): string[] =>
|
|
488
|
+
names.map((dependency) => dependency.startsWith("@gtkx/") ? `${dependency}@^${selfVersion}` : dependency);
|
|
547
489
|
|
|
548
490
|
const formatRecovery = ({ resolved, devDependencies }: InstallFailureOptions): string => {
|
|
549
|
-
const add =
|
|
491
|
+
const add = ADD_COMMAND[resolved.packageManager];
|
|
550
492
|
|
|
551
493
|
const steps = [
|
|
552
494
|
...(resolved.isCurrentDirectory ? [] : [`cd ${resolved.target}`]),
|
|
@@ -624,7 +566,7 @@ const initializeGitRepo = async (root: string): Promise<void> => {
|
|
|
624
566
|
};
|
|
625
567
|
|
|
626
568
|
const printNextSteps = (resolved: ResolvedOptions): void => {
|
|
627
|
-
const devCmd =
|
|
569
|
+
const devCmd = DEV_COMMAND[resolved.packageManager];
|
|
628
570
|
const cdStep = resolved.isCurrentDirectory ? "" : `cd ${resolved.target}\n`;
|
|
629
571
|
const testingNote = resolved.shouldIncludeTesting ? HEADLESS_COMPOSITOR_NOTE : "";
|
|
630
572
|
p.note(`${cdStep}${devCmd}${testingNote}`, "Next steps");
|
|
@@ -636,7 +578,12 @@ const createProjectStructure = async (root: string, resolved: ResolvedOptions):
|
|
|
636
578
|
done: "Project structure created",
|
|
637
579
|
failed: "Failed to create the project structure",
|
|
638
580
|
run: async () => {
|
|
639
|
-
|
|
581
|
+
mkdirSync(root, { recursive: true });
|
|
582
|
+
|
|
583
|
+
if (resolved.shouldEmptyTarget) {
|
|
584
|
+
emptyDir(root);
|
|
585
|
+
}
|
|
586
|
+
|
|
640
587
|
await scaffoldProject(root, resolved);
|
|
641
588
|
writeBuildAllowance(root, resolved.packageManager);
|
|
642
589
|
},
|
|
@@ -3,15 +3,6 @@ import { defineConfig } from "@gtkx/config";
|
|
|
3
3
|
export default defineConfig({
|
|
4
4
|
applicationId: "<%= applicationId %>",
|
|
5
5
|
applicationIcon: "data/icons",
|
|
6
|
-
future: {
|
|
7
|
-
v2ByteArrays: true,
|
|
8
|
-
v2ValueReturns: true,
|
|
9
|
-
v2FinishResults: true,
|
|
10
|
-
v2InoutReturns: true,
|
|
11
|
-
v2ResourceImports: true,
|
|
12
|
-
v2DefaultLibraries: true,
|
|
13
|
-
v2TreeShaking: true,
|
|
14
|
-
},
|
|
15
6
|
deploy: {
|
|
16
7
|
name: "<%= title %>",
|
|
17
8
|
summary: "A GTK4 application built with GTKX",
|
package/src/templates.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { sortStrings, sourceStringLiteral } from "@gtkx/utils";
|
|
1
|
+
import { sortStrings, sourceStringLiteral, toPosixPath } from "@gtkx/utils";
|
|
2
2
|
import ejs from "ejs";
|
|
3
3
|
import { readdirSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -14,20 +14,18 @@ type TemplateContext = {
|
|
|
14
14
|
developerEmail: string | null;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
const
|
|
18
|
-
return join(import.meta.dirname, "templates");
|
|
19
|
-
};
|
|
17
|
+
const TEMPLATES_DIR = join(import.meta.dirname, "templates");
|
|
20
18
|
|
|
21
19
|
const listTemplates = (): string[] =>
|
|
22
20
|
sortStrings(
|
|
23
|
-
readdirSync(
|
|
21
|
+
readdirSync(TEMPLATES_DIR, { recursive: true, withFileTypes: true })
|
|
24
22
|
.filter((entry) => entry.isFile())
|
|
25
23
|
.map((entry) => join(entry.parentPath, entry.name))
|
|
26
|
-
.map((absolute) => absolute.slice(
|
|
24
|
+
.map((absolute) => toPosixPath(absolute.slice(TEMPLATES_DIR.length + 1)))
|
|
27
25
|
.map((relative) => relative.replace(/\.ejs$/, "")),
|
|
28
26
|
);
|
|
29
27
|
|
|
30
28
|
const renderFile = async (templateName: string, context: TemplateContext): Promise<string> =>
|
|
31
|
-
ejs.renderFile(join(
|
|
29
|
+
ejs.renderFile(join(TEMPLATES_DIR, `${templateName}.ejs`), { ...context, sourceStringLiteral });
|
|
32
30
|
|
|
33
31
|
export { listTemplates, renderFile, type TemplateContext };
|