@gjsify/create-app 0.64.14 → 0.64.15-next.287
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/dist-templates/adw-canvas2d/package.json +6 -6
- package/dist-templates/adw-game/package.json +9 -9
- package/dist-templates/adw-webgl/package.json +6 -6
- package/dist-templates/cli/package.json +4 -4
- package/dist-templates/gtk-minimal/LICENSE +21 -0
- package/dist-templates/gtk-minimal/README.md +31 -0
- package/dist-templates/gtk-minimal/data/icons/hicolor/scalable/apps/org.gjsify.example.svg +11 -0
- package/dist-templates/gtk-minimal/package.json +26 -5
- package/dist-templates/gtk-minimal/src/index.ts +17 -0
- package/dist-templates/gtk-minimal/src/main-window.blp +6 -0
- package/dist-templates/gtk-minimal/src/style.css +10 -0
- package/dist-templates/gtk-minimal/tsconfig.json +2 -1
- package/dist-templates/web-server-express/package.json +4 -4
- package/dist-templates/web-server-hono/package.json +4 -4
- package/lib/create.js +59 -6
- package/package.json +6 -5
|
@@ -22,16 +22,16 @@
|
|
|
22
22
|
"@girs/gjs": "5.4.0",
|
|
23
23
|
"@girs/gobject-2.0": "5.4.0",
|
|
24
24
|
"@girs/gtk-4.0": "5.4.0",
|
|
25
|
-
"@gjsify/cli": "^0.64.
|
|
26
|
-
"@gjsify/dom-elements": "^0.64.
|
|
27
|
-
"@gjsify/oxlint-plugin-gjsify": "^0.64.
|
|
28
|
-
"@gjsify/rolldown-native": "^0.64.
|
|
29
|
-
"@gjsify/vite-plugin-blueprint": "^0.64.
|
|
25
|
+
"@gjsify/cli": "^0.64.15-next.287",
|
|
26
|
+
"@gjsify/dom-elements": "^0.64.15-next.287",
|
|
27
|
+
"@gjsify/oxlint-plugin-gjsify": "^0.64.15-next.287",
|
|
28
|
+
"@gjsify/rolldown-native": "^0.64.15-next.287",
|
|
29
|
+
"@gjsify/vite-plugin-blueprint": "^0.64.15-next.287",
|
|
30
30
|
"@types/node": "^25.9.2",
|
|
31
31
|
"typescript": "^6.0.3"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@gjsify/canvas2d": "^0.64.
|
|
34
|
+
"@gjsify/canvas2d": "^0.64.15-next.287",
|
|
35
35
|
"@gjsify/node-gi": "^0.64.14"
|
|
36
36
|
},
|
|
37
37
|
"gjsify": {
|
|
@@ -22,20 +22,20 @@
|
|
|
22
22
|
"@girs/gjs": "5.4.0",
|
|
23
23
|
"@girs/gobject-2.0": "5.4.0",
|
|
24
24
|
"@girs/gtk-4.0": "5.4.0",
|
|
25
|
-
"@gjsify/canvas2d": "^0.64.
|
|
26
|
-
"@gjsify/cli": "^0.64.
|
|
27
|
-
"@gjsify/dom-elements": "^0.64.
|
|
28
|
-
"@gjsify/dom-events": "^0.64.
|
|
29
|
-
"@gjsify/fetch": "^0.64.
|
|
30
|
-
"@gjsify/oxlint-plugin-gjsify": "^0.64.
|
|
31
|
-
"@gjsify/rolldown-native": "^0.64.
|
|
32
|
-
"@gjsify/vite-plugin-blueprint": "^0.64.
|
|
25
|
+
"@gjsify/canvas2d": "^0.64.15-next.287",
|
|
26
|
+
"@gjsify/cli": "^0.64.15-next.287",
|
|
27
|
+
"@gjsify/dom-elements": "^0.64.15-next.287",
|
|
28
|
+
"@gjsify/dom-events": "^0.64.15-next.287",
|
|
29
|
+
"@gjsify/fetch": "^0.64.15-next.287",
|
|
30
|
+
"@gjsify/oxlint-plugin-gjsify": "^0.64.15-next.287",
|
|
31
|
+
"@gjsify/rolldown-native": "^0.64.15-next.287",
|
|
32
|
+
"@gjsify/vite-plugin-blueprint": "^0.64.15-next.287",
|
|
33
33
|
"@types/node": "^25.9.2",
|
|
34
34
|
"typescript": "^6.0.3"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@gjsify/node-gi": "^0.64.14",
|
|
38
|
-
"@gjsify/webgl": "^0.64.
|
|
38
|
+
"@gjsify/webgl": "^0.64.15-next.287",
|
|
39
39
|
"excalibur": "0.32.0"
|
|
40
40
|
},
|
|
41
41
|
"gjsify": {
|
|
@@ -22,18 +22,18 @@
|
|
|
22
22
|
"@girs/gjs": "5.4.0",
|
|
23
23
|
"@girs/gobject-2.0": "5.4.0",
|
|
24
24
|
"@girs/gtk-4.0": "5.4.0",
|
|
25
|
-
"@gjsify/cli": "^0.64.
|
|
26
|
-
"@gjsify/dom-elements": "^0.64.
|
|
27
|
-
"@gjsify/oxlint-plugin-gjsify": "^0.64.
|
|
28
|
-
"@gjsify/rolldown-native": "^0.64.
|
|
29
|
-
"@gjsify/vite-plugin-blueprint": "^0.64.
|
|
25
|
+
"@gjsify/cli": "^0.64.15-next.287",
|
|
26
|
+
"@gjsify/dom-elements": "^0.64.15-next.287",
|
|
27
|
+
"@gjsify/oxlint-plugin-gjsify": "^0.64.15-next.287",
|
|
28
|
+
"@gjsify/rolldown-native": "^0.64.15-next.287",
|
|
29
|
+
"@gjsify/vite-plugin-blueprint": "^0.64.15-next.287",
|
|
30
30
|
"@types/node": "^25.9.2",
|
|
31
31
|
"@types/three": "^0.185.0",
|
|
32
32
|
"typescript": "^6.0.3"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@gjsify/node-gi": "^0.64.14",
|
|
36
|
-
"@gjsify/webgl": "^0.64.
|
|
36
|
+
"@gjsify/webgl": "^0.64.15-next.287",
|
|
37
37
|
"three": "0.185.1"
|
|
38
38
|
},
|
|
39
39
|
"gjsify": {
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"dev": "gjsify dev --runtime gjs"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@gjsify/cli": "^0.64.
|
|
21
|
-
"@gjsify/node-globals": "^0.64.
|
|
22
|
-
"@gjsify/rolldown-native": "^0.64.
|
|
23
|
-
"@gjsify/runtime": "^0.64.
|
|
20
|
+
"@gjsify/cli": "^0.64.15-next.287",
|
|
21
|
+
"@gjsify/node-globals": "^0.64.15-next.287",
|
|
22
|
+
"@gjsify/rolldown-native": "^0.64.15-next.287",
|
|
23
|
+
"@gjsify/runtime": "^0.64.15-next.287",
|
|
24
24
|
"@types/node": "^25.9.2",
|
|
25
25
|
"@types/yargs": "^17.0.35",
|
|
26
26
|
"typescript": "^6.0.3"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 new-gjsify-app contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -16,6 +16,11 @@ app carries it too. The three `adw-*` templates work the same way.
|
|
|
16
16
|
The parser holds a subset of the language, and a construct outside it fails the build naming the
|
|
17
17
|
construct, the file and the line rather than emitting something plausible and wrong.
|
|
18
18
|
|
|
19
|
+
`src/style.css` is the app's stylesheet: it is imported as a **string** and handed to a
|
|
20
|
+
`Gtk.CssProvider` in the `activate` handler, the first point at which a display exists, while
|
|
21
|
+
`main-window.blp` names its class. `@gjsify/rolldown-plugin-gjsify/types` in `tsconfig.json` is
|
|
22
|
+
what types that import — no hand-written `css.d.ts` needed.
|
|
23
|
+
|
|
19
24
|
## Install
|
|
20
25
|
|
|
21
26
|
```bash
|
|
@@ -41,6 +46,7 @@ npm run start:bun # run on Bun
|
|
|
41
46
|
npm run start:deno # run on Deno
|
|
42
47
|
npm run check # type-check
|
|
43
48
|
npm run clear # remove build output
|
|
49
|
+
npm run ship -- <os> # package it (see Ship below)
|
|
44
50
|
```
|
|
45
51
|
|
|
46
52
|
## Runtimes
|
|
@@ -69,6 +75,31 @@ native on the other three. Templates that draw through a Canvas or WebGL request
|
|
|
69
75
|
that surface explicitly (`--globals auto,dom`); asking for it here would inject
|
|
70
76
|
registers nothing ever calls.
|
|
71
77
|
|
|
78
|
+
## Ship
|
|
79
|
+
|
|
80
|
+
`gjsify ship` wraps the built app into something a stranger can install — a
|
|
81
|
+
`.app` on macOS, an `.exe`/`.msi` on Windows, a `.deb`/`.rpm` on Linux:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npm run ship -- darwin # → ship/*.app, ship/*.zip
|
|
85
|
+
npm run ship -- windows # → ship/*/ (directory) + .zip
|
|
86
|
+
npm run ship -- windows --target msi
|
|
87
|
+
npm run ship -- linux # → .deb + .rpm (needs gjs on the target)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`gjsify.ship` in `package.json` is the whole configuration: the application id,
|
|
91
|
+
the icon in `data/icons`, and — for macOS and Windows, which have no system GJS —
|
|
92
|
+
the `--app node` bundle plus the `@gjsify/node-runtime-*` package for that
|
|
93
|
+
platform. Those three packages sit in `optionalDependencies`, so `npm install`
|
|
94
|
+
takes the one matching your machine and skips the others instead of refusing the
|
|
95
|
+
install; a project shipping for a platform therefore builds it on that platform's
|
|
96
|
+
runner, or hands `gjsify` the interpreter through `GJSIFY_NODE_RUNTIME`. The
|
|
97
|
+
cross target itself wants GTK for its own architecture, which `gjsify` fetches
|
|
98
|
+
into its cache on first use.
|
|
99
|
+
|
|
100
|
+
Replace the placeholder icon and put your own name and email in `author` before
|
|
101
|
+
publishing anything.
|
|
102
|
+
|
|
72
103
|
## Operating systems
|
|
73
104
|
|
|
74
105
|
gjsify targets Linux, macOS and Windows. What this project can actually do on
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128">
|
|
3
|
+
<rect width="128" height="128" rx="24" fill="#241f31"/>
|
|
4
|
+
<rect x="24" y="34" width="80" height="60" rx="8" fill="#ffffff"/>
|
|
5
|
+
<rect x="24" y="34" width="80" height="16" rx="8" fill="#c0bfbc"/>
|
|
6
|
+
<circle cx="34" cy="42" r="3" fill="#e01b24"/>
|
|
7
|
+
<circle cx="44" cy="42" r="3" fill="#f5c211"/>
|
|
8
|
+
<circle cx="54" cy="42" r="3" fill="#33d17a"/>
|
|
9
|
+
<rect x="36" y="62" width="56" height="6" rx="3" fill="#9a9996"/>
|
|
10
|
+
<rect x="36" y="74" width="40" height="6" rx="3" fill="#9a9996"/>
|
|
11
|
+
</svg>
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
"version": "0.1.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": true,
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"author": "new-gjsify-app contributors",
|
|
7
9
|
"scripts": {
|
|
8
10
|
"clear": "gjsify clear dist tsconfig.tsbuildinfo",
|
|
9
11
|
"check": "gjsify tsc --noEmit",
|
|
@@ -14,13 +16,15 @@
|
|
|
14
16
|
"start:node": "gjsify run dist/index.node.mjs --runtime node",
|
|
15
17
|
"start:bun": "gjsify run dist/index.node.mjs --runtime bun",
|
|
16
18
|
"start:deno": "gjsify run dist/index.node.mjs --runtime deno",
|
|
17
|
-
"dev": "gjsify dev --runtime gjs"
|
|
19
|
+
"dev": "gjsify dev --runtime gjs",
|
|
20
|
+
"ship": "gjsify ship"
|
|
18
21
|
},
|
|
19
22
|
"devDependencies": {
|
|
20
|
-
"@gjsify/cli": "^0.64.
|
|
21
|
-
"@gjsify/oxlint-plugin-gjsify": "^0.64.
|
|
22
|
-
"@gjsify/rolldown-native": "^0.64.
|
|
23
|
-
"@gjsify/
|
|
23
|
+
"@gjsify/cli": "^0.64.15-next.287",
|
|
24
|
+
"@gjsify/oxlint-plugin-gjsify": "^0.64.15-next.287",
|
|
25
|
+
"@gjsify/rolldown-native": "^0.64.15-next.287",
|
|
26
|
+
"@gjsify/rolldown-plugin-gjsify": "^0.64.15-next.287",
|
|
27
|
+
"@gjsify/vite-plugin-blueprint": "^0.64.15-next.287",
|
|
24
28
|
"@types/node": "^25.9.2",
|
|
25
29
|
"typescript": "^6.0.3"
|
|
26
30
|
},
|
|
@@ -31,6 +35,11 @@
|
|
|
31
35
|
"@girs/gtk-4.0": "5.4.0",
|
|
32
36
|
"@gjsify/node-gi": "^0.64.14"
|
|
33
37
|
},
|
|
38
|
+
"optionalDependencies": {
|
|
39
|
+
"@gjsify/node-runtime-darwin-arm64": "^0.64.14",
|
|
40
|
+
"@gjsify/node-runtime-darwin-x64": "^0.64.14",
|
|
41
|
+
"@gjsify/node-runtime-win32-x64": "^0.64.14"
|
|
42
|
+
},
|
|
34
43
|
"gjsify": {
|
|
35
44
|
"main": "dist/index.gjs.js",
|
|
36
45
|
"example": {
|
|
@@ -41,6 +50,18 @@
|
|
|
41
50
|
"deno"
|
|
42
51
|
],
|
|
43
52
|
"node": "dist/index.node.mjs"
|
|
53
|
+
},
|
|
54
|
+
"ship": {
|
|
55
|
+
"appId": "org.gjsify.example",
|
|
56
|
+
"app": {
|
|
57
|
+
"darwin": "node",
|
|
58
|
+
"win32": "node"
|
|
59
|
+
},
|
|
60
|
+
"bundle": {
|
|
61
|
+
"darwin": "dist/index.node.mjs",
|
|
62
|
+
"win32": "dist/index.node.mjs"
|
|
63
|
+
},
|
|
64
|
+
"icon": "data/icons"
|
|
44
65
|
}
|
|
45
66
|
}
|
|
46
67
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import Gtk from 'gi://Gtk?version=4.0';
|
|
2
2
|
import Gio from 'gi://Gio?version=2.0';
|
|
3
|
+
import Gdk from 'gi://Gdk?version=4.0';
|
|
4
|
+
import css from './style.css';
|
|
3
5
|
import { MainWindow } from './main-window.js';
|
|
4
6
|
|
|
5
7
|
const app = new Gtk.Application({
|
|
@@ -7,7 +9,22 @@ const app = new Gtk.Application({
|
|
|
7
9
|
flags: Gio.ApplicationFlags.FLAGS_NONE,
|
|
8
10
|
});
|
|
9
11
|
|
|
12
|
+
// Only on `activate`: while this module is evaluated there is no display yet, so
|
|
13
|
+
// `Gdk.Display.get_default()` is null and GTK aborts the call with "Argument display may not be
|
|
14
|
+
// null". `css` is the stylesheet as a string — a bare `import './style.css'` would be a module
|
|
15
|
+
// whose only effect is that default export, and the bundler would tree-shake it away.
|
|
16
|
+
function applyStylesheet(): void {
|
|
17
|
+
const provider = new Gtk.CssProvider();
|
|
18
|
+
provider.load_from_string(css);
|
|
19
|
+
Gtk.StyleContext.add_provider_for_display(
|
|
20
|
+
Gdk.Display.get_default()!,
|
|
21
|
+
provider,
|
|
22
|
+
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
10
26
|
app.connect('activate', () => {
|
|
27
|
+
applyStylesheet();
|
|
11
28
|
new MainWindow(app).present();
|
|
12
29
|
});
|
|
13
30
|
|
|
@@ -26,8 +26,14 @@ template $MainWindow: Gtk.ApplicationWindow {
|
|
|
26
26
|
|
|
27
27
|
// Named, and left empty: the platform and PID are runtime FACTS, so TypeScript fills
|
|
28
28
|
// them in. Declaring the container here and populating it there is the intended split.
|
|
29
|
+
// `demo-status` comes from `src/style.css`, registered on `activate` — the class name is
|
|
30
|
+
// the whole contract between the two files.
|
|
29
31
|
Gtk.Label hint {
|
|
30
32
|
xalign: 0.5;
|
|
33
|
+
|
|
34
|
+
styles [
|
|
35
|
+
"demo-status",
|
|
36
|
+
]
|
|
31
37
|
}
|
|
32
38
|
};
|
|
33
39
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/* Imported as a STRING (`.css` → `export default "<css>"`, see the build), because GTK has no
|
|
2
|
+
* stylesheet module. `main-window.blp` puts this class on the hint label.
|
|
3
|
+
*
|
|
4
|
+
* Block comments only: CSS has no `//`, and lightningcss drops a rule that follows one, so a
|
|
5
|
+
* JS-style header would ship an app with an empty stylesheet and no error.
|
|
6
|
+
*/
|
|
7
|
+
.demo-status {
|
|
8
|
+
color: #9141ac;
|
|
9
|
+
font-weight: bold;
|
|
10
|
+
}
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"dev": "gjsify dev --runtime gjs"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@gjsify/cli": "^0.64.
|
|
21
|
-
"@gjsify/node-globals": "^0.64.
|
|
22
|
-
"@gjsify/rolldown-native": "^0.64.
|
|
23
|
-
"@gjsify/runtime": "^0.64.
|
|
20
|
+
"@gjsify/cli": "^0.64.15-next.287",
|
|
21
|
+
"@gjsify/node-globals": "^0.64.15-next.287",
|
|
22
|
+
"@gjsify/rolldown-native": "^0.64.15-next.287",
|
|
23
|
+
"@gjsify/runtime": "^0.64.15-next.287",
|
|
24
24
|
"@types/express": "^5.0.6",
|
|
25
25
|
"@types/node": "^25.9.2",
|
|
26
26
|
"typescript": "^6.0.3"
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"dev": "gjsify dev --runtime gjs"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@gjsify/cli": "^0.64.
|
|
21
|
-
"@gjsify/node-globals": "^0.64.
|
|
22
|
-
"@gjsify/rolldown-native": "^0.64.
|
|
23
|
-
"@gjsify/runtime": "^0.64.
|
|
20
|
+
"@gjsify/cli": "^0.64.15-next.287",
|
|
21
|
+
"@gjsify/node-globals": "^0.64.15-next.287",
|
|
22
|
+
"@gjsify/rolldown-native": "^0.64.15-next.287",
|
|
23
|
+
"@gjsify/runtime": "^0.64.15-next.287",
|
|
24
24
|
"@types/node": "^25.9.2",
|
|
25
25
|
"typescript": "^6.0.3"
|
|
26
26
|
},
|
package/lib/create.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync, readdirSync, cpSync } from 'node:fs';
|
|
2
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, readdirSync, cpSync, renameSync } from 'node:fs';
|
|
3
3
|
import { resolve, join } from 'node:path';
|
|
4
4
|
import { discoverTemplates, findTemplate } from './discover-templates.js';
|
|
5
5
|
import { defaultRuntimeFor, installCommandLine, hostRuntime, packageManagersForRuntime, runScriptCommand, startScriptFor, } from './runtimes.js';
|
|
@@ -48,7 +48,20 @@ const TEXT_FILE_EXT = new Set([
|
|
|
48
48
|
'.xml',
|
|
49
49
|
'.ui',
|
|
50
50
|
'.txt',
|
|
51
|
+
// An icon is an XML document like `.ui` is, and the application-id sentinel
|
|
52
|
+
// is its FILENAME as well as its `inkscape:label` — so the bytes need the
|
|
53
|
+
// same substitution the name gets.
|
|
54
|
+
'.svg',
|
|
51
55
|
]);
|
|
56
|
+
/**
|
|
57
|
+
* Extensionless files that are still text, by exact basename.
|
|
58
|
+
*
|
|
59
|
+
* `LICENSE` is the case that forced this: it is the file every package format
|
|
60
|
+
* and every forge looks for, it carries the project name in its copyright line,
|
|
61
|
+
* and it has no extension to recognise it by. A suffix test cannot see it, so
|
|
62
|
+
* the walk skipped exactly the one file `gjsify ship` requires.
|
|
63
|
+
*/
|
|
64
|
+
const TEXT_BASENAMES = new Set(['LICENSE', 'LICENCE', 'COPYING', 'NOTICE']);
|
|
52
65
|
/** npm package names: lowercase, digits, -, _, .; no leading . or _. */
|
|
53
66
|
export function sanitizeProjectName(raw) {
|
|
54
67
|
const trimmed = raw.trim();
|
|
@@ -145,18 +158,50 @@ export async function createProject(options) {
|
|
|
145
158
|
/**
|
|
146
159
|
* Walk the scaffolded tree and replace every template sentinel in every text file.
|
|
147
160
|
* Skips node_modules / dist / lib and non-text files by extension.
|
|
161
|
+
*
|
|
162
|
+
* NAMES as well as contents: `data/icons/…/org.gjsify.example.svg` is a path a
|
|
163
|
+
* scaffolded project has to be able to keep, and leaving the sentinel in the
|
|
164
|
+
* filename put an icon named after the template in a project that `gjsify ship`
|
|
165
|
+
* then packages under its own id.
|
|
148
166
|
*/
|
|
149
167
|
function substituteTemplateSentinels(rootDir, projectName) {
|
|
150
168
|
const sentinels = [
|
|
151
169
|
[PROJECT_NAME_SENTINEL, projectName],
|
|
152
170
|
[APPLICATION_ID_SENTINEL, applicationIdFor(projectName)],
|
|
153
171
|
];
|
|
172
|
+
// Paths first: the content pass below reads `full` from the same walk, so a
|
|
173
|
+
// file renamed afterwards would be read under a name that no longer exists.
|
|
174
|
+
renameSentinelPaths(rootDir, sentinels);
|
|
175
|
+
substituteSentinelContents(rootDir, sentinels);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Rename every file and directory whose NAME holds a sentinel.
|
|
179
|
+
*
|
|
180
|
+
* A directory is renamed before it is walked, so its children are visited at
|
|
181
|
+
* their new location; the recursion therefore carries the renamed path rather
|
|
182
|
+
* than the one the entry was read under.
|
|
183
|
+
*/
|
|
184
|
+
function renameSentinelPaths(dir, sentinels) {
|
|
185
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
186
|
+
let name = entry.name;
|
|
187
|
+
for (const [sentinel, value] of sentinels)
|
|
188
|
+
name = name.replaceAll(sentinel, value);
|
|
189
|
+
const before = join(dir, entry.name);
|
|
190
|
+
const after = join(dir, name);
|
|
191
|
+
if (after !== before)
|
|
192
|
+
renameSync(before, after);
|
|
193
|
+
if (entry.isDirectory())
|
|
194
|
+
renameSentinelPaths(after, sentinels);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/** The content half of {@link substituteTemplateSentinels}. */
|
|
198
|
+
function substituteSentinelContents(dir, sentinels) {
|
|
154
199
|
const skipDirs = new Set(['node_modules', 'dist', 'lib']);
|
|
155
|
-
const stack = [
|
|
200
|
+
const stack = [dir];
|
|
156
201
|
while (stack.length > 0) {
|
|
157
|
-
const
|
|
158
|
-
for (const entry of readdirSync(
|
|
159
|
-
const full = join(
|
|
202
|
+
const current = stack.pop();
|
|
203
|
+
for (const entry of readdirSync(current, { withFileTypes: true })) {
|
|
204
|
+
const full = join(current, entry.name);
|
|
160
205
|
if (entry.isDirectory()) {
|
|
161
206
|
if (!skipDirs.has(entry.name))
|
|
162
207
|
stack.push(full);
|
|
@@ -166,7 +211,7 @@ function substituteTemplateSentinels(rootDir, projectName) {
|
|
|
166
211
|
continue;
|
|
167
212
|
const dot = entry.name.lastIndexOf('.');
|
|
168
213
|
const ext = dot >= 0 ? entry.name.slice(dot) : '';
|
|
169
|
-
if (!TEXT_FILE_EXT.has(ext))
|
|
214
|
+
if (!TEXT_FILE_EXT.has(ext) && !TEXT_BASENAMES.has(entry.name))
|
|
170
215
|
continue;
|
|
171
216
|
const content = readFileSync(full, 'utf-8');
|
|
172
217
|
let replaced = content;
|
|
@@ -211,6 +256,14 @@ function printNextSteps(projectName, template, installed, packageManager, runtim
|
|
|
211
256
|
console.log(` ${run} ${startScriptFor(rt)}`);
|
|
212
257
|
console.log('');
|
|
213
258
|
}
|
|
259
|
+
// Only for a template that actually ships a `ship` script: printing the
|
|
260
|
+
// command for one that does not sends the reader to a script that is not
|
|
261
|
+
// there, which is worse than not mentioning packaging at all.
|
|
262
|
+
if (scripts['ship']) {
|
|
263
|
+
console.log('Package it for a machine without gjsify:');
|
|
264
|
+
console.log(` ${run} ship -- darwin`);
|
|
265
|
+
console.log('');
|
|
266
|
+
}
|
|
214
267
|
}
|
|
215
268
|
/** The template manifest, or `{}` when it cannot be read. */
|
|
216
269
|
function templateManifest(template) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/create-app",
|
|
3
|
-
"version": "0.64.
|
|
3
|
+
"version": "0.64.15-next.287",
|
|
4
4
|
"description": "Create a new Gjsify project",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/create.js",
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
"yargs": "^18.0.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@gjsify/cli": "
|
|
50
|
-
"@gjsify/rolldown-plugin-gjsify": "
|
|
51
|
-
"@gjsify/unit": "
|
|
49
|
+
"@gjsify/cli": "0.64.15-next.287",
|
|
50
|
+
"@gjsify/rolldown-plugin-gjsify": "0.64.15-next.287",
|
|
51
|
+
"@gjsify/unit": "0.64.15-next.287",
|
|
52
52
|
"@types/node": "^25.9.2",
|
|
53
53
|
"@types/yargs": "^17.0.35",
|
|
54
54
|
"typescript": "^6.0.3"
|
|
@@ -65,5 +65,6 @@
|
|
|
65
65
|
"homepage": "https://github.com/gjsify/gjsify/tree/main/packages/infra/create-gjsify#readme",
|
|
66
66
|
"gjsify": {
|
|
67
67
|
"tier": 1
|
|
68
|
-
}
|
|
68
|
+
},
|
|
69
|
+
"gitHead": "5742b282a8a2bc8633dd8384ef436768447f6a83"
|
|
69
70
|
}
|