windowpp 0.1.2 → 0.1.3
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/lib/create.js +3 -0
- package/package.json +4 -2
- package/scripts/publish.js +4 -0
- package/scripts/sync-templates.js +238 -0
- package/templates/example/CMakeLists.txt +59 -0
- package/templates/example/frontend/index.html +20 -0
- package/templates/example/frontend/src/API.ts +56 -0
- package/templates/example/frontend/src/App.tsx +781 -0
- package/templates/example/frontend/src/Layout.tsx +5 -0
- package/templates/example/frontend/src/components/ClipboardToast.tsx +23 -0
- package/templates/example/frontend/src/components/FileSearch.tsx +936 -0
- package/templates/example/frontend/src/components/InfiniteScrollList.tsx +267 -0
- package/templates/example/frontend/src/components/index.ts +13 -0
- package/templates/example/frontend/src/filedrop.css +421 -0
- package/templates/example/frontend/src/index.css +1 -0
- package/templates/example/frontend/src/index.tsx +24 -0
- package/templates/example/frontend/src/pages/About.tsx +47 -0
- package/templates/example/frontend/src/pages/Settings.tsx +37 -0
- package/templates/example/frontend/tsconfig.json +20 -0
- package/templates/example/frontend/vite.config.ts +27 -0
- package/templates/example/main.cpp +224 -0
- package/templates/example/package.json +12 -0
- package/templates/solid/CMakeLists.txt +4 -1
- package/templates/solid/frontend/vite.config.ts +3 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* @refresh reload */
|
|
2
|
+
import './index.css';
|
|
3
|
+
import { render } from 'solid-js/web';
|
|
4
|
+
import { HashRouter, Route } from '@solidjs/router';
|
|
5
|
+
import 'solid-devtools';
|
|
6
|
+
|
|
7
|
+
import Layout from './Layout';
|
|
8
|
+
import App from './App';
|
|
9
|
+
import Settings from './pages/Settings';
|
|
10
|
+
|
|
11
|
+
const root = document.getElementById('root');
|
|
12
|
+
|
|
13
|
+
if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
|
|
14
|
+
throw new Error(
|
|
15
|
+
'Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got misspelled?',
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
render(() => (
|
|
20
|
+
<HashRouter root={Layout}>
|
|
21
|
+
<Route path="/" component={App} />
|
|
22
|
+
<Route path="/settings" component={Settings} />
|
|
23
|
+
</HashRouter>
|
|
24
|
+
), root!);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useLocation } from '@solidjs/router';
|
|
2
|
+
import { createSignal, onMount } from 'solid-js';
|
|
3
|
+
|
|
4
|
+
export default function About() {
|
|
5
|
+
const location = useLocation();
|
|
6
|
+
const [href, setHref] = createSignal('');
|
|
7
|
+
|
|
8
|
+
onMount(() => {
|
|
9
|
+
setHref(window.location.href);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div class="p-10 max-w-2xl mx-auto text-zinc-100">
|
|
14
|
+
<h1 class="text-3xl font-bold mb-3">About — Routing Test</h1>
|
|
15
|
+
<p class="mb-4 text-zinc-400">
|
|
16
|
+
This page demonstrates <strong class="text-white">hash-based client-side routing</strong> with{' '}
|
|
17
|
+
<code class="bg-zinc-800 px-1 rounded text-blue-300">@solidjs/router</code>.
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
<div class="rounded-lg bg-zinc-900 border border-zinc-700 p-4 font-mono text-sm space-y-1">
|
|
21
|
+
<div>
|
|
22
|
+
<span class="text-zinc-500">pathname: </span>
|
|
23
|
+
<span class="text-green-400">{location.pathname}</span>
|
|
24
|
+
</div>
|
|
25
|
+
<div>
|
|
26
|
+
<span class="text-zinc-500">search: </span>
|
|
27
|
+
<span class="text-yellow-400">{location.search || '(none)'}</span>
|
|
28
|
+
</div>
|
|
29
|
+
<div>
|
|
30
|
+
<span class="text-zinc-500">hash: </span>
|
|
31
|
+
<span class="text-blue-400">{location.hash || '(none)'}</span>
|
|
32
|
+
</div>
|
|
33
|
+
<div>
|
|
34
|
+
<span class="text-zinc-500">href: </span>
|
|
35
|
+
<span class="text-zinc-300 break-all">{href()}</span>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<p class="mt-5 text-sm text-zinc-500">
|
|
40
|
+
Hash routing works out-of-the-box with embedded binary assets — the
|
|
41
|
+
scheme handler returns <code class="bg-zinc-800 px-1 rounded">index.html</code> for
|
|
42
|
+
any path, and the <code class="bg-zinc-800 px-1 rounded">#fragment</code> is
|
|
43
|
+
resolved entirely in the browser, never sent to the server.
|
|
44
|
+
</p>
|
|
45
|
+
</div>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useNavigate } from '@solidjs/router';
|
|
2
|
+
|
|
3
|
+
export default function Settings() {
|
|
4
|
+
const navigate = useNavigate();
|
|
5
|
+
|
|
6
|
+
return (
|
|
7
|
+
<div class="min-h-screen bg-[radial-gradient(circle_at_top,#f8fafc,#e2e8f0_40%,#cbd5e1)] px-6 py-8 text-slate-900">
|
|
8
|
+
<div class="mx-auto max-w-6xl">
|
|
9
|
+
|
|
10
|
+
{/* Header Card */}
|
|
11
|
+
<div class="mb-8 rounded-4xl border border-white/70 bg-white/80 p-8 shadow-2xl shadow-slate-400/20 backdrop-blur">
|
|
12
|
+
<div class="flex items-center justify-between">
|
|
13
|
+
<div>
|
|
14
|
+
<p class="mb-2 text-sm font-semibold uppercase tracking-[0.3em] text-slate-500">WindowPP Playground</p>
|
|
15
|
+
<h1 class="text-4xl font-bold tracking-tight text-slate-900">Settings</h1>
|
|
16
|
+
</div>
|
|
17
|
+
<button
|
|
18
|
+
class="flex items-center gap-1.5 rounded-2xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-600 hover:bg-slate-100 transition-colors select-none"
|
|
19
|
+
onClick={() => navigate('/')}
|
|
20
|
+
>
|
|
21
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 text-slate-500" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
22
|
+
<path d="M19 12H5M12 5l-7 7 7 7"/>
|
|
23
|
+
</svg>
|
|
24
|
+
<span class="font-semibold text-slate-800">Back to App</span>
|
|
25
|
+
</button>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
{/* Placeholder content */}
|
|
30
|
+
<div class="rounded-4xl border border-white/70 bg-white/80 p-8 shadow-2xl shadow-slate-400/20 backdrop-blur text-slate-500 text-sm">
|
|
31
|
+
Settings content goes here.
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
// General
|
|
4
|
+
"jsx": "preserve",
|
|
5
|
+
"jsxImportSource": "solid-js",
|
|
6
|
+
"target": "ESNext",
|
|
7
|
+
|
|
8
|
+
// Modules
|
|
9
|
+
"allowSyntheticDefaultImports": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"isolatedModules": true,
|
|
12
|
+
"module": "ESNext",
|
|
13
|
+
"moduleResolution": "bundler",
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
|
|
16
|
+
// Type Checking & Safety
|
|
17
|
+
"strict": true,
|
|
18
|
+
"types": ["vite/client"]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
3
|
+
import { defineConfig } from 'vite';
|
|
4
|
+
import solidPlugin from 'vite-plugin-solid';
|
|
5
|
+
|
|
6
|
+
const REPO_ROOT = '{{REPO_ROOT}}';
|
|
7
|
+
|
|
8
|
+
export default defineConfig({
|
|
9
|
+
plugins: [solidPlugin(), tailwindcss()],
|
|
10
|
+
base: './',
|
|
11
|
+
resolve: {
|
|
12
|
+
alias: {
|
|
13
|
+
// '@wpp/Foo/bar' resolves to <framework>/src/Foo/bar
|
|
14
|
+
// Used by templates that import bridge APIs: @wpp/AppData/API/AppData, etc.
|
|
15
|
+
'@wpp': resolve(REPO_ROOT, 'src'),
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
server: {
|
|
19
|
+
port: 3000,
|
|
20
|
+
fs: {
|
|
21
|
+
allow: [REPO_ROOT],
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
build: {
|
|
25
|
+
target: 'esnext',
|
|
26
|
+
},
|
|
27
|
+
});
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// main.cpp — WindowPP WebView Example
|
|
3
|
+
//
|
|
4
|
+
// Build modes
|
|
5
|
+
// ───────────
|
|
6
|
+
// Release (cmake --build build --config Release):
|
|
7
|
+
// Frontend is compiled into the binary via embedded_assets.cpp.
|
|
8
|
+
// The app serves assets from the "app" custom URI scheme — no server needed.
|
|
9
|
+
//
|
|
10
|
+
// Dev (set env var WPP_DEV_URL before launching):
|
|
11
|
+
// WPP_DEV_URL=http://localhost:3000 ./{{CMAKE_TARGET}}
|
|
12
|
+
// The app loads from the Vite dev server instead; hot-reload works normally.
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
#include <windowpp/windowpp.h>
|
|
16
|
+
#include "AppData/appdata_bridge.h"
|
|
17
|
+
#include "AppData/appdata_manager.h"
|
|
18
|
+
#include "FileSystem/filesystem_bridge.h"
|
|
19
|
+
#include "Input/input_bridge.h"
|
|
20
|
+
#include "platform/platform_bridge.h"
|
|
21
|
+
#include <cstdlib> // std::getenv
|
|
22
|
+
#include <memory>
|
|
23
|
+
#include <vector>
|
|
24
|
+
|
|
25
|
+
#ifdef WPP_EMBEDDED_ASSETS
|
|
26
|
+
#include "embedded_assets.h"
|
|
27
|
+
#endif
|
|
28
|
+
|
|
29
|
+
int main() {
|
|
30
|
+
wpp::AppConfig app_config;
|
|
31
|
+
app_config.name = "WindowPP Dev";
|
|
32
|
+
app_config.quit_on_last_close = true;
|
|
33
|
+
app_config.tray_enabled = true;
|
|
34
|
+
|
|
35
|
+
wpp::AppDataManager app_data(app_config.name);
|
|
36
|
+
|
|
37
|
+
auto app = wpp::create_app(app_config);
|
|
38
|
+
|
|
39
|
+
wpp::WindowConfig main_win;
|
|
40
|
+
main_win.id = "main";
|
|
41
|
+
main_win.title = "WindowPP - Dev View";
|
|
42
|
+
main_win.width = 1280;
|
|
43
|
+
main_win.height = 800;
|
|
44
|
+
main_win.center = true;
|
|
45
|
+
main_win.frameless = true;
|
|
46
|
+
main_win.transparent = true;
|
|
47
|
+
main_win.background = {0, 0, 0, 0};
|
|
48
|
+
|
|
49
|
+
main_win.webview.enabled = true;
|
|
50
|
+
main_win.file_drop = true;
|
|
51
|
+
main_win.scrollbars = false;
|
|
52
|
+
|
|
53
|
+
// Keep all WebView profile data (cookies, cache, localStorage) in the
|
|
54
|
+
// OS-standard app data directory rather than next to the exe.
|
|
55
|
+
main_win.webview.user_data_dir = app_data.path("WebView");
|
|
56
|
+
|
|
57
|
+
wpp::Window* win = nullptr;
|
|
58
|
+
auto app_data_bridge = std::make_shared<wpp::appdata::AppDataBridge>(
|
|
59
|
+
[&win](const std::string& js) {
|
|
60
|
+
if (win && win->webview()) {
|
|
61
|
+
win->webview()->execute_script(js);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
app_config.name);
|
|
65
|
+
auto filesystem_bridge = std::make_shared<wpp::fs::FsBridge>(
|
|
66
|
+
[&win](const std::string& js) {
|
|
67
|
+
if (win && win->webview()) {
|
|
68
|
+
win->webview()->execute_script(js);
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
[app_ptr = app.get()](std::function<void()> fn) {
|
|
72
|
+
app_ptr->dispatch(std::move(fn));
|
|
73
|
+
},
|
|
74
|
+
app_data.path("FileIndex"));
|
|
75
|
+
auto input_bridge = std::make_shared<wpp::input::InputBridge>(
|
|
76
|
+
[&win](const std::string& js) {
|
|
77
|
+
if (win && win->webview()) {
|
|
78
|
+
win->webview()->execute_script(js);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
[app_ptr = app.get()](std::function<void()> fn) {
|
|
82
|
+
app_ptr->dispatch(std::move(fn));
|
|
83
|
+
},
|
|
84
|
+
main_win.id);
|
|
85
|
+
auto platform_bridge = std::make_shared<wpp::platform_api::PlatformBridge>(
|
|
86
|
+
[&win](const std::string& js) {
|
|
87
|
+
if (win && win->webview()) {
|
|
88
|
+
win->webview()->execute_script(js);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
[app_ptr = app.get()](std::function<void()> fn) {
|
|
92
|
+
app_ptr->dispatch(std::move(fn));
|
|
93
|
+
},
|
|
94
|
+
*app,
|
|
95
|
+
app_config,
|
|
96
|
+
main_win.id);
|
|
97
|
+
|
|
98
|
+
main_win.on_created = [platform_bridge, window_id = main_win.id]() {
|
|
99
|
+
platform_bridge->emit_window_event("created", window_id);
|
|
100
|
+
};
|
|
101
|
+
main_win.on_shown = [platform_bridge, window_id = main_win.id]() {
|
|
102
|
+
platform_bridge->emit_window_event("shown", window_id);
|
|
103
|
+
};
|
|
104
|
+
main_win.on_hidden = [platform_bridge, window_id = main_win.id]() {
|
|
105
|
+
platform_bridge->emit_window_event("hidden", window_id);
|
|
106
|
+
};
|
|
107
|
+
main_win.on_resize = [platform_bridge, window_id = main_win.id](wpp::ResizeEvent event) {
|
|
108
|
+
platform_bridge->emit_resize_event(window_id, event);
|
|
109
|
+
};
|
|
110
|
+
main_win.on_move = [platform_bridge, window_id = main_win.id](wpp::MoveEvent event) {
|
|
111
|
+
platform_bridge->emit_move_event(window_id, event);
|
|
112
|
+
};
|
|
113
|
+
main_win.on_closed = [platform_bridge, window_id = main_win.id]() {
|
|
114
|
+
platform_bridge->emit_window_event("closed", window_id);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
main_win.webview.on_message = [app_data_bridge, filesystem_bridge, input_bridge, platform_bridge](const std::string& raw) {
|
|
118
|
+
app_data_bridge->dispatch(raw);
|
|
119
|
+
filesystem_bridge->dispatch(raw);
|
|
120
|
+
input_bridge->dispatch(raw);
|
|
121
|
+
platform_bridge->dispatch(raw);
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// Decide where to load the UI from.
|
|
125
|
+
const char* dev_url = std::getenv("WPP_DEV_URL");
|
|
126
|
+
if (dev_url && *dev_url) {
|
|
127
|
+
// Developer override — point at a running Vite server (or any URL).
|
|
128
|
+
main_win.webview.initial_url = dev_url;
|
|
129
|
+
} else {
|
|
130
|
+
#ifdef WPP_EMBEDDED_ASSETS
|
|
131
|
+
// Production: serve embedded Vite build from the "app://" custom scheme.
|
|
132
|
+
main_win.webview.custom_scheme = "app";
|
|
133
|
+
main_win.webview.scheme_handler =
|
|
134
|
+
[](const std::string& path) -> wpp::SchemeResponse {
|
|
135
|
+
const EmbeddedAsset* asset = find_asset(path);
|
|
136
|
+
if (!asset) {
|
|
137
|
+
// SPA fallback: unknown paths get index.html so that
|
|
138
|
+
// client-side routers (Solid Router, TanStack Router, etc.)
|
|
139
|
+
// can handle the route in JavaScript.
|
|
140
|
+
asset = find_asset("/index.html");
|
|
141
|
+
}
|
|
142
|
+
if (asset) {
|
|
143
|
+
return wpp::SchemeResponse{
|
|
144
|
+
std::vector<uint8_t>(asset->data, asset->data + asset->size),
|
|
145
|
+
asset->content_type,
|
|
146
|
+
200
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
std::string body = "404 Not Found";
|
|
150
|
+
return wpp::SchemeResponse{
|
|
151
|
+
std::vector<uint8_t>(body.begin(), body.end()),
|
|
152
|
+
"text/plain",
|
|
153
|
+
404
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
main_win.webview.initial_url = "app://localhost/index.html";
|
|
157
|
+
#else
|
|
158
|
+
// Fallback when no embedded assets were compiled in.
|
|
159
|
+
main_win.webview.initial_url = "http://localhost:3000";
|
|
160
|
+
#endif
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
win = app->create_window(main_win);
|
|
164
|
+
|
|
165
|
+
if (win && win->webview()) {
|
|
166
|
+
win->webview()->execute_script("window.__wpp_appdata_ready = true;");
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Allow the frontend to open additional windows at specific hash routes.
|
|
170
|
+
// The URL is computed on the JS side:
|
|
171
|
+
// dev: http://localhost:3000/#/route
|
|
172
|
+
// prod: app://localhost/index.html#/route
|
|
173
|
+
static int child_counter = 0;
|
|
174
|
+
platform_bridge->set_create_window_fn(
|
|
175
|
+
[&app, webview_dir = app_data.path("WebView")](
|
|
176
|
+
const std::string& url,
|
|
177
|
+
const std::string& title,
|
|
178
|
+
int width, int height)
|
|
179
|
+
{
|
|
180
|
+
wpp::WindowConfig child;
|
|
181
|
+
child.id = "child_" + std::to_string(++child_counter);
|
|
182
|
+
child.title = title;
|
|
183
|
+
child.width = width;
|
|
184
|
+
child.height = height;
|
|
185
|
+
child.center = true;
|
|
186
|
+
child.frameless = true;
|
|
187
|
+
child.transparent = true;
|
|
188
|
+
child.background = {0, 0, 0, 0};
|
|
189
|
+
child.webview.enabled = true;
|
|
190
|
+
child.webview.user_data_dir = webview_dir;
|
|
191
|
+
child.webview.initial_url = url;
|
|
192
|
+
|
|
193
|
+
// In embedded-assets mode, the child window must also register the
|
|
194
|
+
// custom "app://" scheme so it can serve the same SPA assets.
|
|
195
|
+
#ifdef WPP_EMBEDDED_ASSETS
|
|
196
|
+
const char* dev_env = std::getenv("WPP_DEV_URL");
|
|
197
|
+
if (!dev_env || !*dev_env) {
|
|
198
|
+
child.webview.custom_scheme = "app";
|
|
199
|
+
child.webview.scheme_handler =
|
|
200
|
+
[](const std::string& path) -> wpp::SchemeResponse {
|
|
201
|
+
const EmbeddedAsset* asset = find_asset(path);
|
|
202
|
+
if (!asset) asset = find_asset("/index.html");
|
|
203
|
+
if (asset) {
|
|
204
|
+
return wpp::SchemeResponse{
|
|
205
|
+
std::vector<uint8_t>(asset->data, asset->data + asset->size),
|
|
206
|
+
asset->content_type,
|
|
207
|
+
200
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
std::string body = "404 Not Found";
|
|
211
|
+
return wpp::SchemeResponse{
|
|
212
|
+
std::vector<uint8_t>(body.begin(), body.end()),
|
|
213
|
+
"text/plain", 404
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
#endif
|
|
218
|
+
app->create_window(child);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
app->run();
|
|
222
|
+
|
|
223
|
+
return 0;
|
|
224
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{APP_NAME}}",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "{{APP_TITLE}} — a WindowPP app",
|
|
5
|
+
"cmakeTarget": "{{CMAKE_TARGET}}",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "windowpp dev",
|
|
8
|
+
"dev:clean": "windowpp dev --clean",
|
|
9
|
+
"build": "windowpp build",
|
|
10
|
+
"build:clean": "windowpp build --clean"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -50,7 +50,10 @@ add_custom_target({{CMAKE_TARGET}}_frontend_assets ALL
|
|
|
50
50
|
)
|
|
51
51
|
|
|
52
52
|
add_executable({{CMAKE_TARGET}} main.cpp ${EMBEDDED_ASSETS_CPP})
|
|
53
|
-
target_include_directories({{CMAKE_TARGET}} PRIVATE
|
|
53
|
+
target_include_directories({{CMAKE_TARGET}} PRIVATE
|
|
54
|
+
${GENERATED_DIR}
|
|
55
|
+
"${WPP_FRAMEWORK_DIR}/src" # bridge headers: AppData/, FileSystem/, Input/, platform/
|
|
56
|
+
)
|
|
54
57
|
target_compile_definitions({{CMAKE_TARGET}} PRIVATE WPP_EMBEDDED_ASSETS)
|
|
55
58
|
target_link_libraries({{CMAKE_TARGET}} PRIVATE windowpp windowpp_deps nlohmann_json::nlohmann_json)
|
|
56
59
|
add_dependencies({{CMAKE_TARGET}} {{CMAKE_TARGET}}_frontend_assets)
|
|
@@ -10,7 +10,9 @@ export default defineConfig({
|
|
|
10
10
|
base: './',
|
|
11
11
|
resolve: {
|
|
12
12
|
alias: {
|
|
13
|
-
'@wpp'
|
|
13
|
+
// '@wpp/Foo/bar' resolves to <framework>/src/Foo/bar
|
|
14
|
+
// Used by templates that import bridge APIs: @wpp/AppData/API/AppData, etc.
|
|
15
|
+
'@wpp': resolve(REPO_ROOT, 'src'),
|
|
14
16
|
},
|
|
15
17
|
},
|
|
16
18
|
server: {
|