@ts-for-gir/cli 4.0.0-rc.9 → 4.0.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 +43 -3
- package/bin/ts-for-gir +454 -129
- package/bin/ts-for-gir-gjs +1213 -0
- package/dist-templates/types-gjsify/README.md +32 -0
- package/dist-templates/types-gjsify/biome.json +38 -0
- package/dist-templates/types-gjsify/main.ts +19 -0
- package/dist-templates/types-gjsify/package.json +26 -0
- package/dist-templates/types-gjsify/tsconfig.json +15 -0
- package/dist-templates/types-locally/package.json +1 -1
- package/dist-templates/types-npm/package.json +5 -5
- package/dist-templates/types-workspace/package.json +1 -1
- package/package.json +194 -83
- package/src/commands/create.ts +84 -12
- package/src/commands/index.ts +1 -0
- package/src/commands/self-update.ts +142 -0
- package/src/config/config-loader.ts +6 -2
- package/src/config/defaults.ts +14 -0
- package/src/config/options.ts +2 -2
- package/src/start.ts +20 -6
- package/src/types/command-args.ts +8 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# __PROJECT_NAME__
|
|
2
|
+
|
|
3
|
+
GJS + TypeScript starter, fully Node-free at runtime. Uses pre-generated [`@girs/*`](https://www.npmjs.com/org/girs) types and the [`gjsify` CLI](https://gjsify.github.io/gjsify/) for install, build, run, format and lint — no `npm`, no `node`, no `esbuild` ceremony.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
gjsify install
|
|
9
|
+
gjsify run build && gjsify run start
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
That's it. `gjsify build` produces a single GJS bundle with the right `firefox*` target + `gi://*` externals; `gjsify run` launches it with `LD_LIBRARY_PATH` / `GI_TYPELIB_PATH` pre-wired for any native typelib deps.
|
|
13
|
+
|
|
14
|
+
## Scripts
|
|
15
|
+
|
|
16
|
+
| Script | What it does |
|
|
17
|
+
|---|---|
|
|
18
|
+
| `gjsify install` | Install deps (Node-free; reads `gjsify-lock.json`) |
|
|
19
|
+
| `gjsify run check` | TypeScript `tsc --noEmit` |
|
|
20
|
+
| `gjsify run build` | Bundle `main.ts` → `dist/main.js` |
|
|
21
|
+
| `gjsify run start` | Launch the bundle under `gjs -m` |
|
|
22
|
+
| `gjsify run format` | Format via Biome |
|
|
23
|
+
| `gjsify run fix` | Format + safe-fix lint + organize imports |
|
|
24
|
+
| `gjsify run clear` | Remove `dist/` |
|
|
25
|
+
|
|
26
|
+
## Adding GIR modules
|
|
27
|
+
|
|
28
|
+
Install the matching `@girs/<name>-<version>` package and add it to `tsconfig.json`'s `types` array. Example for GStreamer:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
gjsify install @girs/gst-1.0
|
|
32
|
+
```
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.4.13/schema.json",
|
|
3
|
+
"formatter": {
|
|
4
|
+
"enabled": true,
|
|
5
|
+
"indentStyle": "tab",
|
|
6
|
+
"lineWidth": 120,
|
|
7
|
+
"lineEnding": "lf"
|
|
8
|
+
},
|
|
9
|
+
"linter": {
|
|
10
|
+
"enabled": true,
|
|
11
|
+
"rules": {
|
|
12
|
+
"recommended": true,
|
|
13
|
+
"style": {
|
|
14
|
+
"useImportType": "warn",
|
|
15
|
+
"useNodejsImportProtocol": "error",
|
|
16
|
+
"noNonNullAssertion": "off"
|
|
17
|
+
},
|
|
18
|
+
"suspicious": {
|
|
19
|
+
"noExplicitAny": "warn",
|
|
20
|
+
"noConsole": "off"
|
|
21
|
+
},
|
|
22
|
+
"correctness": {
|
|
23
|
+
"noUnusedImports": "warn"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"javascript": {
|
|
28
|
+
"formatter": {
|
|
29
|
+
"quoteStyle": "double",
|
|
30
|
+
"semicolons": "always",
|
|
31
|
+
"trailingCommas": "all",
|
|
32
|
+
"arrowParentheses": "always"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"files": {
|
|
36
|
+
"includes": ["**", "!**/node_modules", "!**/dist", "!**/.cache"]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Adw from "gi://Adw?version=1";
|
|
2
|
+
import Gio from "gi://Gio?version=2.0";
|
|
3
|
+
import Gtk from "gi://Gtk?version=4.0";
|
|
4
|
+
|
|
5
|
+
const app = new Adw.Application({
|
|
6
|
+
applicationId: "com.example.__PROJECT_NAME__",
|
|
7
|
+
flags: Gio.ApplicationFlags.FLAGS_NONE,
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
app.connect("activate", (app: Adw.Application) => {
|
|
11
|
+
const label = new Gtk.Label({ label: "Hello from __PROJECT_NAME__" });
|
|
12
|
+
const window = new Gtk.ApplicationWindow({ application: app });
|
|
13
|
+
window.set_title("__PROJECT_NAME__");
|
|
14
|
+
window.set_default_size(320, 120);
|
|
15
|
+
window.set_child(label);
|
|
16
|
+
window.present();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
app.run([imports.system.programInvocationName].concat(ARGV));
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__PROJECT_NAME__",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"private": true,
|
|
6
|
+
"scripts": {
|
|
7
|
+
"check": "tsc --noEmit",
|
|
8
|
+
"build": "gjsify build main.ts --app gjs --outfile dist/main.js",
|
|
9
|
+
"start": "gjsify run dist/main.js",
|
|
10
|
+
"format": "gjsify format",
|
|
11
|
+
"fix": "gjsify fix",
|
|
12
|
+
"clear": "rm -rf dist"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@biomejs/biome": "^2.4.13",
|
|
16
|
+
"@gjsify/cli": "^0.4.14",
|
|
17
|
+
"typescript": "^6.0.2"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@girs/adw-1": "^1.10.0-4.0.0-rc.17",
|
|
21
|
+
"@girs/gio-2.0": "^2.88.0-4.0.0-rc.17",
|
|
22
|
+
"@girs/gjs": "^4.0.0-rc.17",
|
|
23
|
+
"@girs/glib-2.0": "^2.88.0-4.0.0-rc.17",
|
|
24
|
+
"@girs/gtk-4.0": "^4.23.0-4.0.0-rc.17"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"lib": ["ESNext"],
|
|
4
|
+
"types": ["@girs/gjs", "@girs/adw-1"],
|
|
5
|
+
"target": "ESNext",
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"moduleResolution": "bundler",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"noImplicitAny": true,
|
|
10
|
+
"strictNullChecks": true,
|
|
11
|
+
"noImplicitThis": true,
|
|
12
|
+
"alwaysStrict": true
|
|
13
|
+
},
|
|
14
|
+
"files": ["main.ts"]
|
|
15
|
+
}
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
"typescript": "^6.0.2"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@girs/adw-1": "^1.10.0-4.0.0-rc.
|
|
18
|
-
"@girs/gio-2.0": "^2.88.0-4.0.0-rc.
|
|
19
|
-
"@girs/gjs": "^4.0.0-rc.
|
|
20
|
-
"@girs/glib-2.0": "^2.88.0-4.0.0-rc.
|
|
21
|
-
"@girs/gtk-4.0": "^4.23.0-4.0.0-rc.
|
|
17
|
+
"@girs/adw-1": "^1.10.0-4.0.0-rc.17",
|
|
18
|
+
"@girs/gio-2.0": "^2.88.0-4.0.0-rc.17",
|
|
19
|
+
"@girs/gjs": "^4.0.0-rc.17",
|
|
20
|
+
"@girs/glib-2.0": "^2.88.0-4.0.0-rc.17",
|
|
21
|
+
"@girs/gtk-4.0": "^4.23.0-4.0.0-rc.17"
|
|
22
22
|
}
|
|
23
23
|
}
|
package/package.json
CHANGED
|
@@ -1,84 +1,195 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
2
|
+
"name": "@ts-for-gir/cli",
|
|
3
|
+
"version": "4.0.1",
|
|
4
|
+
"description": "TypeScript type definition generator for GObject introspection GIR files",
|
|
5
|
+
"main": "src/index.ts",
|
|
6
|
+
"module": "src/index.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"bin": {
|
|
9
|
+
"cli": "bin/ts-for-gir",
|
|
10
|
+
"ts-for-gir": "bin/ts-for-gir",
|
|
11
|
+
"ts-for-gir-dev": "bin/ts-for-gir-dev",
|
|
12
|
+
"ts-for-gir-gjs": "bin/ts-for-gir-gjs"
|
|
13
|
+
},
|
|
14
|
+
"gjsify": {
|
|
15
|
+
"bin": {
|
|
16
|
+
"ts-for-gir": "bin/ts-for-gir-gjs"
|
|
17
|
+
},
|
|
18
|
+
"shebang": true,
|
|
19
|
+
"bundler": {
|
|
20
|
+
"input": "src/start.ts",
|
|
21
|
+
"output": {
|
|
22
|
+
"file": "bin/ts-for-gir-gjs"
|
|
23
|
+
},
|
|
24
|
+
"transform": {
|
|
25
|
+
"define": {
|
|
26
|
+
"__GJS_BUNDLE__": "true"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"defineFromPackageJson": {
|
|
31
|
+
"__TS_FOR_GIR_VERSION__": {
|
|
32
|
+
"field": "version"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"excludeGlobals": [
|
|
36
|
+
"XMLHttpRequest",
|
|
37
|
+
"XMLHttpRequestUpload"
|
|
38
|
+
],
|
|
39
|
+
"flatpak": {
|
|
40
|
+
"appId": "io.github.gjsify.ts_for_gir",
|
|
41
|
+
"kind": "cli",
|
|
42
|
+
"name": "ts-for-gir",
|
|
43
|
+
"runtime": "gnome",
|
|
44
|
+
"runtimeVersion": "50",
|
|
45
|
+
"command": "ts-for-gir",
|
|
46
|
+
"finishArgs": [
|
|
47
|
+
"--share=network",
|
|
48
|
+
"--filesystem=host"
|
|
49
|
+
],
|
|
50
|
+
"developer": {
|
|
51
|
+
"id": "io.github.gjsify",
|
|
52
|
+
"name": "gjsify contributors",
|
|
53
|
+
"email": "pascal@artandcode.studio"
|
|
54
|
+
},
|
|
55
|
+
"summary": "TypeScript type definitions for GObject Introspection (GJS)",
|
|
56
|
+
"description": [
|
|
57
|
+
{
|
|
58
|
+
"p": "ts-for-gir reads GObject Introspection (GIR) XML files and emits strongly-typed TypeScript definitions for use in GJS (GNOME JavaScript) projects. Type-check your GTK / Adwaita / GLib / Gio / GStreamer / WebKit / etc. code, get full IDE completion, and catch missing properties / wrong-arity signal handlers at build time instead of runtime."
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"p": "This Flatpak ships ts-for-gir as a self-contained CLI runnable on any modern Linux distro — no Node.js installation required. It reads from the system's installed GIR catalog (read-only mounts of /usr/share/gir-1.0 and /usr/share/gobject-introspection-1.0) and writes generated types under your project directory."
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"ul": [
|
|
65
|
+
{
|
|
66
|
+
"item": "`ts-for-gir generate Gtk-4.0` — generate types for one or more GI namespaces"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"item": "`ts-for-gir generate --reporter` — write a JSON report alongside types for downstream analysis"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"item": "`ts-for-gir analyze report.json` — inspect type-resolution issues by severity / category / namespace"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"item": "`ts-for-gir create my-app` — scaffold a new GJS app from a template"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"item": "`ts-for-gir list` — list all GIR namespaces available on this system"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"item": "`ts-for-gir self-update` — refresh the global install in place"
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
"license": {
|
|
87
|
+
"metadata": "CC0-1.0",
|
|
88
|
+
"project": "Apache-2.0"
|
|
89
|
+
},
|
|
90
|
+
"categories": [
|
|
91
|
+
"Development"
|
|
92
|
+
],
|
|
93
|
+
"homepageUrl": "https://gjsify.github.io/gjsify/projects/ts-for-gir/",
|
|
94
|
+
"vcsBrowserUrl": "https://github.com/gjsify/ts-for-gir",
|
|
95
|
+
"issueTrackerUrl": "https://github.com/gjsify/ts-for-gir/issues",
|
|
96
|
+
"modules": [
|
|
97
|
+
{
|
|
98
|
+
"name": "ts-for-gir-cli",
|
|
99
|
+
"buildsystem": "simple",
|
|
100
|
+
"build-commands": [
|
|
101
|
+
"install -Dm755 package/bin/ts-for-gir-gjs /app/share/ts-for-gir/ts-for-gir.gjs.mjs",
|
|
102
|
+
"install -Dm755 launcher.sh /app/bin/ts-for-gir"
|
|
103
|
+
],
|
|
104
|
+
"sources": [
|
|
105
|
+
{
|
|
106
|
+
"type": "archive",
|
|
107
|
+
"url": "https://registry.npmjs.org/@ts-for-gir/cli/-/cli-4.0.0-rc.17.tgz",
|
|
108
|
+
"sha256": "6ca2c7c73bbc37259ebec621f1b24f8e9ca896426783114e80faa59cb4983afe",
|
|
109
|
+
"strip-components": 0,
|
|
110
|
+
"dest-filename": "tarball.tgz"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"type": "file",
|
|
114
|
+
"path": "launcher.sh"
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
"engines": {
|
|
122
|
+
"node": ">=18"
|
|
123
|
+
},
|
|
124
|
+
"scripts": {
|
|
125
|
+
"start": "node bin/ts-for-gir-dev",
|
|
126
|
+
"start:prod": "node bin/ts-for-gir",
|
|
127
|
+
"build": "node --experimental-specifier-resolution=node --experimental-strip-types --experimental-transform-types --no-warnings esbuild.ts && chmod +x bin/ts-for-gir-dev && chmod +x bin/ts-for-gir && node scripts/process-templates.mjs",
|
|
128
|
+
"build:gjs": "gjsify build",
|
|
129
|
+
"build:templates": "node scripts/process-templates.mjs",
|
|
130
|
+
"prepack": "node scripts/process-templates.mjs",
|
|
131
|
+
"check:types": "tsc --noEmit",
|
|
132
|
+
"check": "gjsify run check:types"
|
|
133
|
+
},
|
|
134
|
+
"repository": {
|
|
135
|
+
"type": "git",
|
|
136
|
+
"url": "git+https://github.com/gjsify/ts-for-gir.git"
|
|
137
|
+
},
|
|
138
|
+
"author": "Pascal Garber <pascal@mailfreun.de>",
|
|
139
|
+
"files": [
|
|
140
|
+
"src",
|
|
141
|
+
"bin",
|
|
142
|
+
"dist-templates"
|
|
143
|
+
],
|
|
144
|
+
"license": "Apache-2.0",
|
|
145
|
+
"bugs": {
|
|
146
|
+
"url": "https://github.com/gjsify/ts-for-gir/issues"
|
|
147
|
+
},
|
|
148
|
+
"homepage": "https://github.com/gjsify/ts-for-gir#readme",
|
|
149
|
+
"keywords": [
|
|
150
|
+
"gjs",
|
|
151
|
+
"typescript",
|
|
152
|
+
"generate",
|
|
153
|
+
"gir",
|
|
154
|
+
"gobject-introspection",
|
|
155
|
+
"gnome",
|
|
156
|
+
"gtk",
|
|
157
|
+
"glib",
|
|
158
|
+
"gobject",
|
|
159
|
+
"dts",
|
|
160
|
+
"type definitions",
|
|
161
|
+
"cli"
|
|
162
|
+
],
|
|
163
|
+
"exports": {
|
|
164
|
+
".": "./src/index.ts"
|
|
165
|
+
},
|
|
166
|
+
"devDependencies": {
|
|
167
|
+
"@gi.ts/parser": "^4.0.1",
|
|
168
|
+
"@gjsify/cli": "^0.4.19",
|
|
169
|
+
"@ts-for-gir/generator-base": "^4.0.1",
|
|
170
|
+
"@ts-for-gir/generator-html-doc": "^4.0.1",
|
|
171
|
+
"@ts-for-gir/generator-json": "^4.0.1",
|
|
172
|
+
"@ts-for-gir/generator-typescript": "^4.0.1",
|
|
173
|
+
"@ts-for-gir/lib": "^4.0.1",
|
|
174
|
+
"@ts-for-gir/reporter": "^4.0.1",
|
|
175
|
+
"@ts-for-gir/tsconfig": "^4.0.1",
|
|
176
|
+
"@types/ejs": "^3.1.5",
|
|
177
|
+
"@types/inquirer": "^9.0.9",
|
|
178
|
+
"@types/node": "^25.6.2",
|
|
179
|
+
"@types/yargs": "^17.0.35",
|
|
180
|
+
"esbuild": "^0.28.0",
|
|
181
|
+
"source-map-support": "^0.5.21",
|
|
182
|
+
"typescript": "^6.0.3"
|
|
183
|
+
},
|
|
184
|
+
"dependencies": {
|
|
185
|
+
"@inquirer/prompts": "^8.4.2",
|
|
186
|
+
"@ts-for-gir/templates": "^4.0.1",
|
|
187
|
+
"colorette": "^2.0.20",
|
|
188
|
+
"cosmiconfig": "^9.0.1",
|
|
189
|
+
"ejs": "^5.0.2",
|
|
190
|
+
"glob": "^13.0.6",
|
|
191
|
+
"inquirer": "^13.4.2",
|
|
192
|
+
"typedoc": "^0.28.19",
|
|
193
|
+
"yargs": "^18.0.0"
|
|
194
|
+
}
|
|
195
|
+
}
|
package/src/commands/create.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { spawnSync } from "node:child_process";
|
|
6
|
-
import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { dirname, join, resolve } from "node:path";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
9
|
|
|
@@ -19,7 +19,8 @@ const command = "create [name]";
|
|
|
19
19
|
const description = "Scaffold a new GJS TypeScript project from a template";
|
|
20
20
|
|
|
21
21
|
const examples: ReadonlyArray<[string, string?]> = [
|
|
22
|
-
[`${APP_NAME} create my-app --template types-
|
|
22
|
+
[`${APP_NAME} create my-app --template types-gjsify`, "Scaffold a Node-free GJS app via gjsify (recommended)"],
|
|
23
|
+
[`${APP_NAME} create my-app --template types-npm`, "Scaffold using the @girs/* NPM types + node/esbuild"],
|
|
23
24
|
[`${APP_NAME} create my-app --template types-locally`, "Scaffold and generate types into ./@types/ locally"],
|
|
24
25
|
[
|
|
25
26
|
`${APP_NAME} create my-app --template types-workspace`,
|
|
@@ -30,15 +31,20 @@ const examples: ReadonlyArray<[string, string?]> = [
|
|
|
30
31
|
|
|
31
32
|
const TEMPLATE_CHOICES: ReadonlyArray<{ value: CreateTemplateId; name: string; description: string }> = [
|
|
32
33
|
{
|
|
33
|
-
value: "types-
|
|
34
|
-
name: "types-
|
|
35
|
-
description: "
|
|
34
|
+
value: "types-gjsify",
|
|
35
|
+
name: "types-gjsify",
|
|
36
|
+
description: "Node-free: @girs/* from NPM, all dev scripts (install/build/run/format) routed through gjsify",
|
|
36
37
|
},
|
|
37
38
|
{
|
|
38
39
|
value: "types-npm",
|
|
39
40
|
name: "types-npm",
|
|
40
41
|
description: "Use pre-generated types from the @girs/* NPM packages",
|
|
41
42
|
},
|
|
43
|
+
{
|
|
44
|
+
value: "types-locally",
|
|
45
|
+
name: "types-locally",
|
|
46
|
+
description: "Generate GIR types directly into ./@types/ (no package format, no @girs/* deps)",
|
|
47
|
+
},
|
|
42
48
|
{
|
|
43
49
|
value: "types-workspace",
|
|
44
50
|
name: "types-workspace",
|
|
@@ -55,18 +61,44 @@ const builder = createBuilder<CreateCommandArgs>(createOptions, examples);
|
|
|
55
61
|
function findTemplatesRoot(): string {
|
|
56
62
|
const __filename = fileURLToPath(import.meta.url);
|
|
57
63
|
const __dirname = dirname(__filename);
|
|
64
|
+
// Resolve symlinks too. When the CLI is installed via `npm i -g`,
|
|
65
|
+
// `gjsify install -g`, or any tool that lands a symlink in the user's PATH
|
|
66
|
+
// (Yarn Berry's bin links, asdf shims, ...), `import.meta.url` resolves to
|
|
67
|
+
// the symlink path — `<dir>/../dist-templates` would then look for the
|
|
68
|
+
// templates next to the symlink (e.g. `~/.local/bin/../dist-templates`)
|
|
69
|
+
// instead of next to the real package. Resolving via realpath first lets
|
|
70
|
+
// the same `<dir>/../dist-templates` candidate hit the actual install dir.
|
|
71
|
+
let realDirname = __dirname;
|
|
72
|
+
try {
|
|
73
|
+
realDirname = dirname(realpathSync(__filename));
|
|
74
|
+
} catch {
|
|
75
|
+
// `realpathSync` can throw on bundled paths that don't exist on disk
|
|
76
|
+
// (e.g. virtual entries in a single-file binary). Fall through to the
|
|
77
|
+
// direct __dirname — the candidate list below is a superset and will
|
|
78
|
+
// still find templates when they live alongside the bundle.
|
|
79
|
+
}
|
|
58
80
|
const candidates = [
|
|
59
|
-
//
|
|
81
|
+
// Symlink-resolved binary (`npm i -g` / `gjsify install -g`): the
|
|
82
|
+
// realpath-aware candidate is required when the CLI is launched via a
|
|
83
|
+
// `~/.local/bin/<name>` symlink that points at the real package's
|
|
84
|
+
// `bin/<name>`. Try it first so the success path is symmetric across
|
|
85
|
+
// install modes.
|
|
86
|
+
resolve(realDirname, "..", "dist-templates"),
|
|
87
|
+
// Bundled production binary invoked at its real path (no symlink),
|
|
88
|
+
// or a tarball extracted into a flat `bin/` + `dist-templates/` layout.
|
|
60
89
|
resolve(__dirname, "..", "dist-templates"),
|
|
61
90
|
// Source layout (src/commands/create.ts): ../../dist-templates then ../../templates
|
|
62
91
|
resolve(__dirname, "..", "..", "dist-templates"),
|
|
63
92
|
resolve(__dirname, "..", "..", "templates"),
|
|
64
93
|
];
|
|
94
|
+
const seen = new Set<string>();
|
|
65
95
|
for (const path of candidates) {
|
|
96
|
+
if (seen.has(path)) continue;
|
|
97
|
+
seen.add(path);
|
|
66
98
|
if (existsSync(path)) return path;
|
|
67
99
|
}
|
|
68
100
|
throw new Error(
|
|
69
|
-
`Could not locate templates directory. Looked in:\n ${
|
|
101
|
+
`Could not locate templates directory. Looked in:\n ${[...seen].join("\n ")}\n` +
|
|
70
102
|
"If you are running from source, make sure packages/cli/templates/ exists. " +
|
|
71
103
|
"If you are running the published CLI, make sure dist-templates/ was packed.",
|
|
72
104
|
);
|
|
@@ -119,11 +151,36 @@ function walkAndSubstitute(rootDir: string, projectName: string): void {
|
|
|
119
151
|
}
|
|
120
152
|
}
|
|
121
153
|
|
|
154
|
+
declare const __GJS_BUNDLE__: boolean | undefined;
|
|
155
|
+
|
|
122
156
|
const handler = async (args: ConfigFlags) => {
|
|
123
157
|
const opts = args as unknown as CreateCommandArgs;
|
|
124
158
|
const log = new Logger(opts.verbose ?? false, "CreateCommand");
|
|
125
159
|
|
|
126
|
-
|
|
160
|
+
let templatesRoot: string;
|
|
161
|
+
try {
|
|
162
|
+
templatesRoot = findTemplatesRoot();
|
|
163
|
+
} catch (err) {
|
|
164
|
+
// `dist-templates/` not next to the running file. Two known scenarios:
|
|
165
|
+
// 1. `install.js` (or any flow) deployed only the single-file GJS
|
|
166
|
+
// binary without the package tree. We can't scaffold without
|
|
167
|
+
// templates — point the user at the working install path.
|
|
168
|
+
// 2. Source-mode mis-checkout (no `packages/cli/templates/`). Surface
|
|
169
|
+
// the original error so the developer can fix their layout.
|
|
170
|
+
// The `__GJS_BUNDLE__` define lets us discriminate at build time.
|
|
171
|
+
if (typeof __GJS_BUNDLE__ !== "undefined") {
|
|
172
|
+
process.stderr.write(
|
|
173
|
+
"The 'create' command needs templates that aren't shipped alongside this binary.\n" +
|
|
174
|
+
"Install the full package instead so `dist-templates/` lives next to the bin:\n" +
|
|
175
|
+
" gjsify install -g @ts-for-gir/cli\n" +
|
|
176
|
+
" npm install -g @ts-for-gir/cli\n" +
|
|
177
|
+
" npx @ts-for-gir/cli create ... # one-shot, no install\n",
|
|
178
|
+
);
|
|
179
|
+
process.exitCode = 1;
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
throw err;
|
|
183
|
+
}
|
|
127
184
|
const available = listTemplates(templatesRoot);
|
|
128
185
|
if (available.length === 0) {
|
|
129
186
|
throw new Error(`No templates found in ${templatesRoot}`);
|
|
@@ -175,19 +232,30 @@ const handler = async (args: ConfigFlags) => {
|
|
|
175
232
|
log.success(`Scaffolded ${template} into ${targetDir}`);
|
|
176
233
|
|
|
177
234
|
if (opts.install) {
|
|
178
|
-
|
|
179
|
-
|
|
235
|
+
// types-gjsify is Node-free at runtime — bootstrap deps via `gjsify install`
|
|
236
|
+
// so the user's first impression matches the rest of the template's scripts.
|
|
237
|
+
// Other templates remain on npm (matches the prior behavior + their README).
|
|
238
|
+
const installer = template === "types-gjsify" ? "gjsify" : "npm";
|
|
239
|
+
const installerArgs = template === "types-gjsify" ? ["install"] : ["install", "--no-audit", "--no-fund"];
|
|
240
|
+
log.info(`Running ${installer} install...`);
|
|
241
|
+
const result = spawnSync(installer, installerArgs, {
|
|
180
242
|
cwd: targetDir,
|
|
181
243
|
stdio: "inherit",
|
|
182
244
|
});
|
|
183
245
|
if (result.status !== 0) {
|
|
184
|
-
log.warn(
|
|
246
|
+
log.warn(`${installer} install failed; you can re-run it manually in the project directory.`);
|
|
185
247
|
}
|
|
186
248
|
}
|
|
187
249
|
|
|
188
250
|
log.info("\nNext steps:");
|
|
189
251
|
log.white(` cd ${projectName}`);
|
|
190
|
-
if (!opts.install)
|
|
252
|
+
if (!opts.install) {
|
|
253
|
+
if (template === "types-gjsify") {
|
|
254
|
+
log.white(" gjsify install");
|
|
255
|
+
} else {
|
|
256
|
+
log.white(" npm install");
|
|
257
|
+
}
|
|
258
|
+
}
|
|
191
259
|
switch (template) {
|
|
192
260
|
case "types-locally":
|
|
193
261
|
log.white(" npm run generate");
|
|
@@ -202,6 +270,10 @@ const handler = async (args: ConfigFlags) => {
|
|
|
202
270
|
log.white(" npm run build:types && npm install");
|
|
203
271
|
log.white(" npm run build:app && npm start");
|
|
204
272
|
break;
|
|
273
|
+
case "types-gjsify":
|
|
274
|
+
log.white(" gjsify run check");
|
|
275
|
+
log.white(" gjsify run build && gjsify run start");
|
|
276
|
+
break;
|
|
205
277
|
}
|
|
206
278
|
};
|
|
207
279
|
|
package/src/commands/index.ts
CHANGED