@flare-desktop/cli 0.0.0-stage → 0.1.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.
@@ -0,0 +1,284 @@
1
+ import { SCHEMA_URL } from "../schema.js";
2
+
3
+ export function embeddedIdentifier(name) {
4
+ const segments = String(name).split("-").filter(Boolean);
5
+ return segments
6
+ .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
7
+ .join("");
8
+ }
9
+
10
+ export function configTemplate({ name, identifier, version }) {
11
+ return {
12
+ $schema: SCHEMA_URL,
13
+ package: { productName: name, version },
14
+ app: {
15
+ identifier,
16
+ productName: name,
17
+ mainBinaryName: name,
18
+ version
19
+ },
20
+ build: {
21
+ frontendDist: "frontend",
22
+ devUrl: "",
23
+ beforeDevCommand: "",
24
+ afterDevCommand: "",
25
+ beforeBuildCommand: "",
26
+ afterBuildCommand: ""
27
+ },
28
+ bundle: {
29
+ active: true,
30
+ identifier,
31
+ icon: "icons/icon.png",
32
+ category: "DeveloperTool",
33
+ shortDescription: `${name} built with flare`,
34
+ targets: []
35
+ },
36
+ security: {
37
+ csp: "default-src 'self'",
38
+ freezePrototype: true
39
+ },
40
+ windows: [
41
+ {
42
+ label: "main",
43
+ title: name,
44
+ width: 960,
45
+ height: 640,
46
+ resizable: true,
47
+ center: true,
48
+ theme: "automatic"
49
+ }
50
+ ]
51
+ };
52
+ }
53
+
54
+ export function packageJsonTemplate({ name, version, cliVersion }) {
55
+ return {
56
+ name,
57
+ version,
58
+ private: true,
59
+ type: "module",
60
+ scripts: {
61
+ dev: "flare dev",
62
+ build: "flare build",
63
+ bundle: "flare bundle",
64
+ icon: "flare icon icons/icon.png"
65
+ },
66
+ devDependencies: {
67
+ "@flare-desktop/cli": `^${cliVersion}`
68
+ }
69
+ };
70
+ }
71
+
72
+ export function cmakeTemplate({ name, version, coreVersion }) {
73
+ return `cmake_minimum_required(VERSION 3.24)
74
+
75
+ project(${name} VERSION ${version} LANGUAGES CXX)
76
+
77
+ set(CMAKE_CXX_STANDARD 20)
78
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
79
+
80
+ include(FetchContent)
81
+
82
+ FetchContent_Declare(
83
+ flare
84
+ GIT_REPOSITORY https://github.com/flare-desktop/flare.git
85
+ GIT_TAG v${coreVersion}
86
+ GIT_SHALLOW TRUE)
87
+ FetchContent_MakeAvailable(flare)
88
+
89
+ add_executable(${name} source/main.cpp)
90
+ target_link_libraries(${name} PRIVATE flare::core flare::assets)
91
+
92
+ set(FLARE_FRONTEND_DIR "frontend" CACHE PATH "Frontend directory")
93
+ file(TO_CMAKE_PATH "\${FLARE_FRONTEND_DIR}" FLARE_FRONTEND_DIR)
94
+ target_compile_definitions(${name} PRIVATE FLARE_FRONTEND_DIR="\${FLARE_FRONTEND_DIR}")
95
+ FlareEmbedFrontend(${name} "\${FLARE_FRONTEND_DIR}")
96
+ `;
97
+ }
98
+
99
+ export function sourceTemplate({ name, identifier, version }) {
100
+ const embedded = embeddedIdentifier(name);
101
+ return `#include <flare/config/config.h>
102
+ #include <flare/core/application.h>
103
+ #include <flare/log/log.h>
104
+
105
+ #include <${name}-frontend.h>
106
+
107
+ #include <cstdlib>
108
+ #include <string>
109
+
110
+ #ifndef FLARE_FRONTEND_DIR
111
+ #define FLARE_FRONTEND_DIR "frontend"
112
+ #endif
113
+
114
+ int main() {
115
+ const bool development = std::getenv("FLARE_DEV") != nullptr;
116
+
117
+ Flare::ApplicationOptions options;
118
+ options.config = Flare::Config::Defaults("${identifier}", "${version}");
119
+ options.config.app.productName = "${name}";
120
+ options.config.windows.front().title = "${name}";
121
+ options.development = development;
122
+
123
+ std::string error;
124
+ Flare::ConfigLoader loader(
125
+ Flare::ConfigMergeOptions{"flare.config.json", development ? "development" : "production", "", {}});
126
+ if (const auto loaded = loader.Load(error); loaded.has_value()) {
127
+ options.config = *loaded;
128
+ } else {
129
+ Flare::LogWarn("using the built-in configuration: {}", error);
130
+ }
131
+
132
+ const char* devUrl = std::getenv("FLARE_DEV_URL");
133
+ if (devUrl != nullptr) options.devUrl = devUrl;
134
+ if (development && options.devUrl.empty()) options.frontendDirectory = FLARE_FRONTEND_DIR;
135
+
136
+ Flare::Application application(options);
137
+ if (!development) Flare::Embedded::Insert${embedded}(application.Assets());
138
+
139
+ application.RegisterCommand("greet", [](const Flare::InvokeRequest& request) {
140
+ const std::string name =
141
+ request.payload.contains("name") ? request.payload["name"].get<std::string>() : "world";
142
+ return Flare::JSON("hello, " + name);
143
+ });
144
+
145
+ application.CreateWindow(application.Config().MainWindow());
146
+ Flare::LogInfo("${name} started");
147
+ application.Run();
148
+ return EXIT_SUCCESS;
149
+ }
150
+ `;
151
+ }
152
+
153
+ export function indexHtmlTemplate(name) {
154
+ return `<!doctype html>
155
+ <html lang="en">
156
+ <head>
157
+ <meta charset="utf-8">
158
+ <meta name="viewport" content="width=device-width, initial-scale=1">
159
+ <title>${name}</title>
160
+ <link rel="stylesheet" href="style.css">
161
+ </head>
162
+ <body>
163
+ <main>
164
+ <h1>${name}</h1>
165
+ <p>the frontend runs in the system webview, the backend in C++.</p>
166
+ <button id="greet">call the backend</button>
167
+ <pre id="output"></pre>
168
+ </main>
169
+ <script type="module" src="main.js"></script>
170
+ </body>
171
+ </html>
172
+ `;
173
+ }
174
+
175
+ export function styleTemplate() {
176
+ return `:root {
177
+ color-scheme: light dark;
178
+ --background: #f4f1ec;
179
+ --foreground: #2c2328;
180
+ --accent: #d8a7b1;
181
+ }
182
+
183
+ @media (prefers-color-scheme: dark) {
184
+ :root {
185
+ --background: #201918;
186
+ --foreground: #f4f1ec;
187
+ }
188
+ }
189
+
190
+ * {
191
+ box-sizing: border-box;
192
+ }
193
+
194
+ body {
195
+ margin: 0;
196
+ min-height: 100vh;
197
+ display: grid;
198
+ place-items: center;
199
+ background: var(--background);
200
+ color: var(--foreground);
201
+ font-family: system-ui, sans-serif;
202
+ }
203
+
204
+ main {
205
+ text-align: center;
206
+ padding: 2rem;
207
+ }
208
+
209
+ h1 {
210
+ margin: 0 0 0.5rem;
211
+ letter-spacing: -0.02em;
212
+ }
213
+
214
+ p {
215
+ margin: 0 0 1.5rem;
216
+ opacity: 0.7;
217
+ }
218
+
219
+ button {
220
+ padding: 0.65rem 1.3rem;
221
+ border: 0;
222
+ border-radius: 0.6rem;
223
+ background: var(--accent);
224
+ color: #201918;
225
+ font-weight: 600;
226
+ cursor: pointer;
227
+ }
228
+
229
+ pre {
230
+ margin-top: 1rem;
231
+ opacity: 0.8;
232
+ }
233
+ `;
234
+ }
235
+
236
+ export function scriptTemplate() {
237
+ return `import { app, invoke } from "/core.js";
238
+
239
+ const output = document.querySelector("#output");
240
+
241
+ document.querySelector("#greet").addEventListener("click", async () => {
242
+ const message = await invoke("greet", { name: "flare" });
243
+ const version = await app.version();
244
+ output.textContent = \`\${message} (\${version})\`;
245
+ });
246
+ `;
247
+ }
248
+
249
+ export function gitignoreTemplate() {
250
+ return "build/\ntarget/\nnode_modules/\n.DS_Store\n";
251
+ }
252
+
253
+ export function readmeTemplate(name) {
254
+ return `# ${name}
255
+
256
+ A desktop application built with [flare](https://github.com/flare-desktop/flare).
257
+
258
+ ## Development
259
+
260
+ \`\`\`bash
261
+ npm install
262
+ npm run dev
263
+ \`\`\`
264
+
265
+ ## Build
266
+
267
+ \`\`\`bash
268
+ npm run build
269
+ npm run bundle
270
+ \`\`\`
271
+
272
+ \`npm run dev\` builds the C++ core and serves \`frontend/\` in the system webview.
273
+ \`npm run build\` compiles the frontend into the executable and produces a release build.
274
+ \`npm run bundle\` assembles the configured bundle targets under \`target/bundle\`.
275
+
276
+ ## Icons
277
+
278
+ \`\`\`bash
279
+ npm run icon
280
+ \`\`\`
281
+
282
+ The command reads \`icons/icon.png\` and writes the png, ico and icns sets next to it.
283
+ `;
284
+ }
package/src/version.js ADDED
@@ -0,0 +1,6 @@
1
+ import { readFileSync } from "node:fs";
2
+
3
+ const manifest = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
4
+
5
+ export const VERSION = manifest.version;
6
+ export const PACKAGE_NAME = manifest.name;