@gxp-dev/tools 2.0.61 → 2.0.63

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gxp-dev/tools",
3
- "version": "2.0.61",
3
+ "version": "2.0.63",
4
4
  "description": "Dev tools to create platform plugins",
5
5
  "type": "commonjs",
6
6
  "publishConfig": {
@@ -140,17 +140,40 @@ export default defineConfig(({ mode }) => {
140
140
  name: "runtime-files",
141
141
  configureServer(server) {
142
142
  server.middlewares.use((req, res, next) => {
143
- // Serve runtime index.html for root requests (unless local index.html is opted in)
143
+ // Serve runtime index.html for root requests and SPA navigation requests
144
+ // (unless local index.html is opted in). SPA fallback is required so
145
+ // client-side routers (e.g. vue-router createWebHistory) can handle
146
+ // deep links when no physical index.html exists at the project root.
147
+ const rawUrl = req.url || "";
148
+ const urlPath = rawUrl.split("?")[0];
149
+ const accept = req.headers.accept || "";
150
+ const isGetOrHead = req.method === "GET" || req.method === "HEAD";
151
+ const isInternalPath =
152
+ urlPath.startsWith("/@") ||
153
+ urlPath.startsWith("/__") ||
154
+ urlPath.startsWith("/node_modules/") ||
155
+ urlPath.startsWith("/src/") ||
156
+ urlPath.startsWith("/dev-assets/") ||
157
+ urlPath.startsWith("/api-proxy/");
158
+ const hasExtension = path.extname(urlPath) !== "";
159
+ const isSpaNavigation =
160
+ isGetOrHead &&
161
+ !isInternalPath &&
162
+ !hasExtension &&
163
+ accept.includes("text/html");
164
+
144
165
  if (
145
166
  !useLocalIndex &&
146
- (req.url === "/" || req.url === "/index.html")
167
+ (urlPath === "/" ||
168
+ urlPath === "/index.html" ||
169
+ isSpaNavigation)
147
170
  ) {
148
171
  const runtimeIndexPath = path.join(runtimeDir, "index.html");
149
172
  if (fs.existsSync(runtimeIndexPath)) {
150
173
  // Read and transform the runtime index.html
151
174
  server
152
175
  .transformIndexHtml(
153
- req.url,
176
+ rawUrl,
154
177
  fs.readFileSync(runtimeIndexPath, "utf-8")
155
178
  )
156
179
  .then((html) => {
@@ -208,44 +208,44 @@ export default defineConfig(({ mode }) => {
208
208
  name: "spa-fallback",
209
209
  configureServer(server) {
210
210
  return () => {
211
- server.middlewares.use((req, res, next) => {
212
- // Only handle GET requests for non-file routes
213
- if (req.method !== "GET") {
214
- next();
215
- return;
216
- }
211
+ server.middlewares.use((req, res, next) => {
212
+ // Only handle GET requests for non-file routes
213
+ if (req.method !== "GET") {
214
+ next();
215
+ return;
216
+ }
217
217
 
218
- // Skip API routes, health checks, and known file extensions
219
- if (
220
- req.url.startsWith("/@") ||
221
- req.url.startsWith("/api") ||
222
- req.url === "/__health" ||
223
- /\.[a-z0-9]+$/i.test(req.url) // Has file extension
224
- ) {
225
- next();
226
- return;
227
- }
218
+ // Skip API routes, health checks, known file extensions, and vite internals
219
+ if (
220
+ req.url.startsWith("/@") ||
221
+ req.url.startsWith("/api") ||
222
+ req.url === "/__health" ||
223
+ /\.[a-z0-9]+$/i.test(req.url) // Has file extension
224
+ ) {
225
+ next();
226
+ return;
227
+ }
228
228
 
229
- // Serve index.html for all other routes (SPA fallback)
230
- const indexPath = path.join(process.cwd(), "index.html");
231
- if (fs.existsSync(indexPath)) {
232
- server
233
- .transformIndexHtml(
234
- req.url,
235
- fs.readFileSync(indexPath, "utf-8")
236
- )
237
- .then((html) => {
238
- res.setHeader("Content-Type", "text/html");
239
- res.end(html);
240
- })
241
- .catch((err) => {
242
- console.error("Error serving SPA fallback:", err);
243
- next(err);
244
- });
245
- } else {
246
- next();
247
- }
248
- });
229
+ // Check if local index.html exists, otherwise use toolkit version
230
+ const localIndexPath = path.join(process.cwd(), "index.html");
231
+ const toolkitIndexPath = path.join(runtimeDir, "index.html");
232
+ const indexPath = fs.existsSync(localIndexPath) ? localIndexPath : toolkitIndexPath;
233
+
234
+ if (fs.existsSync(indexPath)) {
235
+ server
236
+ .transformIndexHtml(req.url, fs.readFileSync(indexPath, "utf-8"))
237
+ .then((html) => {
238
+ res.setHeader("Content-Type", "text/html");
239
+ res.end(html);
240
+ })
241
+ .catch((err) => {
242
+ console.error("Error serving SPA fallback:", err);
243
+ next(err);
244
+ });
245
+ } else {
246
+ next();
247
+ }
248
+ });
249
249
  };
250
250
  },
251
251
  },