@antelopejs/dms-frontend 0.10.0 → 0.10.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 +34 -11
- package/dist/commands/build-action.d.ts +3 -0
- package/dist/commands/build-action.js +74 -6
- package/dist/commands/build.js +7 -0
- package/dist/commands/clean-action.js +1 -1
- package/dist/commands/clean.js +1 -1
- package/dist/commands/dev-action.js +2 -2
- package/dist/commands/dev.js +1 -1
- package/dist/config.js +1 -0
- package/dist/derived-outputs.d.ts +1 -0
- package/dist/derived-outputs.js +3 -1
- package/dist/help.js +1 -1
- package/dist/internal/prepared-workspace.d.ts +12 -0
- package/dist/internal/prepared-workspace.js +74 -0
- package/dist/layer-watch.js +1 -1
- package/dist/locale-files.d.ts +4 -2
- package/dist/locale-files.js +11 -9
- package/dist/manifest.js +2 -1
- package/dist/ports.d.ts +3 -1
- package/dist/ports.js +1 -1
- package/dist/project-modules.d.ts +5 -1
- package/dist/project-modules.js +10 -7
- package/dist/verify-source-runner.js +2 -44
- package/dist/verify-source-workspace.d.ts +2 -0
- package/dist/verify-source-workspace.js +111 -0
- package/dist/workspace-setup.d.ts +1 -0
- package/dist/workspace-setup.js +3 -2
- package/package.json +7 -5
- package/templates/vue/backend-boundary.mjs +132 -0
- package/templates/vue/client-chunking.mjs +2 -0
- package/templates/vue/entry-weight.mjs +9 -5
- package/templates/vue/frontend-build.ts +4 -3
- package/templates/vue/head-order.mjs +3 -2
- package/templates/vue/icon-api.mjs +2 -0
- package/templates/vue/server/auth/backend.mjs +4 -4
- package/templates/vue/server/auth/establish-endpoints.mjs +2 -2
- package/templates/vue/server/auth/session.mjs +5 -2
- package/templates/vue/server/auth-declarations.mjs +46 -0
- package/templates/vue/server/auth-hooks.mjs +41 -3
- package/templates/vue/server/backend-proxies.mjs +16 -12
- package/templates/vue/server/backend-response.mjs +3 -3
- package/templates/vue/server/cli-report.mjs +22 -1
- package/templates/vue/server/client-error.mjs +5 -0
- package/templates/vue/server/content.mjs +24 -11
- package/templates/vue/server/email-bundle-watch.mjs +9 -3
- package/templates/vue/server/email.mjs +5 -3
- package/templates/vue/server/generated-files.mjs +16 -6
- package/templates/vue/server/icons.mjs +15 -11
- package/templates/vue/server/in-place-render.mjs +3 -3
- package/templates/vue/server/inertia.mjs +17 -3
- package/templates/vue/server/module-event.mjs +28 -16
- package/templates/vue/server/module-route-types.mjs +2 -2
- package/templates/vue/server/module-routes.mjs +24 -76
- package/templates/vue/server/module-server.mjs +27 -17
- package/templates/vue/server/module-testing.mjs +23 -8
- package/templates/vue/server/page-props.mjs +6 -5
- package/templates/vue/server/page-redirects.mjs +1 -1
- package/templates/vue/server/path-patterns.mjs +22 -11
- package/templates/vue/server/proxy-headers.mjs +1 -1
- package/templates/vue/server/proxy-redirects.mjs +1 -0
- package/templates/vue/server/proxy-request.mjs +2 -1
- package/templates/vue/server/proxy-transfers.mjs +17 -11
- package/templates/vue/server/public-endpoints.mjs +12 -16
- package/templates/vue/server/request-failure.mjs +1 -1
- package/templates/vue/server/request-routing.mjs +6 -1
- package/templates/vue/server/request-target.mjs +22 -9
- package/templates/vue/server/route-rules.mjs +12 -6
- package/templates/vue/server/static-files.mjs +12 -7
- package/templates/vue/server/vite-errors.mjs +13 -2
- package/templates/vue/server/web-body.mjs +2 -1
- package/templates/vue/server-module.ts +2 -1
- package/templates/vue/server.mjs +41 -20
- package/templates/vue/ui-inertia-page.mjs +1 -1
- package/templates/vue/vite.config.ts +9 -0
package/templates/vue/server.mjs
CHANGED
|
@@ -17,6 +17,7 @@ import { handleClientError } from "./server/client-error.mjs";
|
|
|
17
17
|
import {
|
|
18
18
|
reportListenError,
|
|
19
19
|
reportReady,
|
|
20
|
+
reportRouting,
|
|
20
21
|
reportStartError,
|
|
21
22
|
} from "./server/cli-report.mjs";
|
|
22
23
|
import { publicBuildFile } from "./server/built-files.mjs";
|
|
@@ -64,7 +65,10 @@ import * as icons from "./server/icons.mjs";
|
|
|
64
65
|
import { ssrRenderer } from "./server/ssr-module.mjs";
|
|
65
66
|
import * as requestFailure from "./server/request-failure.mjs";
|
|
66
67
|
import { proxy } from "./server/proxy-request.mjs";
|
|
67
|
-
import {
|
|
68
|
+
import {
|
|
69
|
+
hasOriginFormTarget,
|
|
70
|
+
isServerRequest,
|
|
71
|
+
} from "./server/request-target.mjs";
|
|
68
72
|
import { SERVER_OPTIONS } from "./server/proxy-transfers.mjs";
|
|
69
73
|
import {
|
|
70
74
|
createInertiaPage,
|
|
@@ -74,10 +78,12 @@ import {
|
|
|
74
78
|
isFrontendVisit,
|
|
75
79
|
redirectFrontendVisit,
|
|
76
80
|
handleAssetVersionMismatch,
|
|
81
|
+
isSsrPage,
|
|
77
82
|
} from "./server/inertia.mjs";
|
|
78
83
|
export * from "./server/inertia.mjs";
|
|
79
84
|
|
|
80
85
|
/** @typedef {import("node:http").IncomingMessage} IncomingMessage */
|
|
86
|
+
/** @typedef {import("./server/request-target.mjs").ServerRequest} ServerRequest */
|
|
81
87
|
/** @typedef {import("node:http").ServerResponse} ServerResponse */
|
|
82
88
|
/** @typedef {import("vite").ViteDevServer} ViteDevServer */
|
|
83
89
|
/** @typedef {import("./server/inertia.mjs").InertiaPage} InertiaPage */
|
|
@@ -86,6 +92,12 @@ export * from "./server/inertia.mjs";
|
|
|
86
92
|
const INERTIA_HEADER = "x-inertia";
|
|
87
93
|
const JSON_TYPE = "application/json";
|
|
88
94
|
const PROJECT_ROOT = fileURLToPath(new URL(".", import.meta.url));
|
|
95
|
+
/**
|
|
96
|
+
* @type {[
|
|
97
|
+
* (pathname: string) => boolean,
|
|
98
|
+
* (request: ServerRequest, response: ServerResponse) => Promise<void>
|
|
99
|
+
* ][]}
|
|
100
|
+
*/
|
|
89
101
|
const LOCAL_ROUTES = [[icons.isIconRequest, icons.handleIcons]];
|
|
90
102
|
const CLIENT_ROOT = join(PROJECT_ROOT, "dist/client");
|
|
91
103
|
const SOURCE_TEMPLATE_PATH = join(PROJECT_ROOT, "index.html");
|
|
@@ -97,7 +109,9 @@ const SOURCE_TEMPLATE_PATH = join(PROJECT_ROOT, "index.html");
|
|
|
97
109
|
* NODE_ENV=production throws a ReferenceError on the first render.
|
|
98
110
|
*/
|
|
99
111
|
function defineVueCompileFlags() {
|
|
100
|
-
globalThis
|
|
112
|
+
/** @type {typeof globalThis & { __VUE_PROD_DEVTOOLS__?: boolean }} */
|
|
113
|
+
const vueGlobals = globalThis;
|
|
114
|
+
vueGlobals.__VUE_PROD_DEVTOOLS__ ??= false;
|
|
101
115
|
}
|
|
102
116
|
|
|
103
117
|
defineVueCompileFlags();
|
|
@@ -145,7 +159,7 @@ async function currentAuth() {
|
|
|
145
159
|
}
|
|
146
160
|
|
|
147
161
|
/**
|
|
148
|
-
* @param {
|
|
162
|
+
* @param {ServerRequest} request
|
|
149
163
|
* @returns {import("./server/page-props.mjs").PageBackend}
|
|
150
164
|
*/
|
|
151
165
|
function pageBackend(request) {
|
|
@@ -159,7 +173,7 @@ function pageBackend(request) {
|
|
|
159
173
|
}
|
|
160
174
|
|
|
161
175
|
/**
|
|
162
|
-
* @param {
|
|
176
|
+
* @param {ServerRequest} request
|
|
163
177
|
* @param {import("./server/page-props.mjs").PageAuth} auth
|
|
164
178
|
*/
|
|
165
179
|
function pageProps(request, auth) {
|
|
@@ -207,6 +221,8 @@ function clientRenderedShell(page) {
|
|
|
207
221
|
async function serverRendered(page, serverFetch, requestCookies, devServer) {
|
|
208
222
|
try {
|
|
209
223
|
const renderer = await ssrRenderer(devServer);
|
|
224
|
+
if (!isSsrPage(page))
|
|
225
|
+
throw new TypeError("The page has no path and no page props to render");
|
|
210
226
|
return await renderer.renderDmsPage(page, serverFetch, requestCookies);
|
|
211
227
|
} catch (error) {
|
|
212
228
|
console.error(
|
|
@@ -222,7 +238,7 @@ async function serverRendered(page, serverFetch, requestCookies, devServer) {
|
|
|
222
238
|
* renders the page from the shell instead.
|
|
223
239
|
*
|
|
224
240
|
* @param {InertiaPage} page
|
|
225
|
-
* @param {string
|
|
241
|
+
* @param {string} requestUrl
|
|
226
242
|
* @param {ServerReads} serverFetch
|
|
227
243
|
* @param {string | undefined} requestCookies
|
|
228
244
|
* @param {{ ssr?: false }} [options]
|
|
@@ -271,7 +287,7 @@ export async function renderHtml(
|
|
|
271
287
|
|
|
272
288
|
/**
|
|
273
289
|
* @param {InertiaPage} page
|
|
274
|
-
* @param {
|
|
290
|
+
* @param {ServerRequest} request
|
|
275
291
|
* @param {Pick<import("./server/route-rules.mjs").RouteRule, "ssr">} [rule]
|
|
276
292
|
* @param {ServerReads} [reads]
|
|
277
293
|
*/
|
|
@@ -287,7 +303,7 @@ function renderRequestHtml(page, request, rule = {}, reads) {
|
|
|
287
303
|
* see `renderInPlace`.
|
|
288
304
|
*
|
|
289
305
|
* @param {InertiaPage} page
|
|
290
|
-
* @param {
|
|
306
|
+
* @param {ServerRequest} request
|
|
291
307
|
* @param {import("./server/route-rules.mjs").MergedRouteRule} rule
|
|
292
308
|
* @param {import("./server/page-props.mjs").PageAuth} auth
|
|
293
309
|
*/
|
|
@@ -304,7 +320,7 @@ function renderDocument(page, request, rule, auth) {
|
|
|
304
320
|
|
|
305
321
|
/**
|
|
306
322
|
* @param {unknown} error
|
|
307
|
-
* @param {
|
|
323
|
+
* @param {ServerRequest} request
|
|
308
324
|
* @param {ServerResponse} response
|
|
309
325
|
*/
|
|
310
326
|
async function writeBackendError(error, request, response) {
|
|
@@ -422,7 +438,7 @@ function writeNotFound(response) {
|
|
|
422
438
|
}
|
|
423
439
|
|
|
424
440
|
/**
|
|
425
|
-
* @param {
|
|
441
|
+
* @param {ServerRequest} request
|
|
426
442
|
* @param {ServerResponse} response
|
|
427
443
|
*/
|
|
428
444
|
export async function handleRequest(request, response) {
|
|
@@ -488,6 +504,8 @@ export async function handleRequest(request, response) {
|
|
|
488
504
|
*/
|
|
489
505
|
async function writeRequestFailure(error, request, response) {
|
|
490
506
|
if (requestFailure.isResponseGone(error, response)) return;
|
|
507
|
+
if (!isServerRequest(request))
|
|
508
|
+
return requestFailure.abandonResponse(error, response);
|
|
491
509
|
if (
|
|
492
510
|
error instanceof BackendResponseError &&
|
|
493
511
|
error.status === 401 &&
|
|
@@ -513,7 +531,10 @@ async function writeRequestFailure(error, request, response) {
|
|
|
513
531
|
*/
|
|
514
532
|
export async function handleRequestSafely(request, response) {
|
|
515
533
|
try {
|
|
516
|
-
if (
|
|
534
|
+
if (!hasOriginFormTarget(request)) {
|
|
535
|
+
requestFailure.writeBadRequest(response);
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
517
538
|
await handleRequest(request, response);
|
|
518
539
|
} catch (error) {
|
|
519
540
|
await writeRequestFailure(error, request, response).catch(
|
|
@@ -528,26 +549,26 @@ if (
|
|
|
528
549
|
import.meta.url === new URL(`file://${process.argv[1]}`).href
|
|
529
550
|
) {
|
|
530
551
|
frontendHttpServer = createServer(SERVER_OPTIONS, handleRequestSafely);
|
|
531
|
-
|
|
552
|
+
const server = frontendHttpServer;
|
|
553
|
+
server.on("clientError", (error, socket) =>
|
|
532
554
|
handleClientError(error, socket, maxHeaderSize),
|
|
533
555
|
);
|
|
534
556
|
const port = Number(process.env.PORT ?? 3001);
|
|
535
557
|
const host = listenHost();
|
|
536
558
|
/** @param {NodeJS.ErrnoException} error */
|
|
537
559
|
const onListenError = (error) => void reportListenError(error, host, port);
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
560
|
+
server.once("error", onListenError);
|
|
561
|
+
server.listen(port, host, () => {
|
|
562
|
+
server.off("error", onListenError);
|
|
541
563
|
void announceReady();
|
|
542
564
|
});
|
|
543
565
|
}
|
|
544
566
|
|
|
545
567
|
/** Prints who owns which paths, once the server is up. */
|
|
546
|
-
async function
|
|
568
|
+
async function reportServerModules() {
|
|
547
569
|
try {
|
|
548
570
|
const modules = await loadServerModules(await developmentServer());
|
|
549
|
-
|
|
550
|
-
console.log(line);
|
|
571
|
+
reportRouting(routingReport(modules.proxies, modules.routes.length));
|
|
551
572
|
} catch (error) {
|
|
552
573
|
console.error("DMS server modules failed to load", error);
|
|
553
574
|
}
|
|
@@ -568,11 +589,11 @@ async function announceReady() {
|
|
|
568
589
|
await reportStartError(error);
|
|
569
590
|
return;
|
|
570
591
|
}
|
|
571
|
-
const listening = frontendHttpServer
|
|
572
|
-
if (listening
|
|
592
|
+
const listening = frontendHttpServer?.address();
|
|
593
|
+
if (!listening || isString(listening))
|
|
573
594
|
throw new TypeError("The DMS server is not listening on a port");
|
|
574
595
|
const { address, port } = listening;
|
|
575
596
|
await reportReady(address, port);
|
|
576
|
-
await
|
|
597
|
+
await reportServerModules();
|
|
577
598
|
if (process.env.DMS_DEV === "true") watchEmailBundle();
|
|
578
599
|
}
|
|
@@ -13,7 +13,7 @@ const ANY_INERTIA_PAGE_IMPORT =
|
|
|
13
13
|
* name: string,
|
|
14
14
|
* enforce: "pre",
|
|
15
15
|
* transform: (
|
|
16
|
-
* this: import("vite").Rollup.TransformPluginContext,
|
|
16
|
+
* this: Pick<import("vite").Rollup.TransformPluginContext, "error">,
|
|
17
17
|
* code: string,
|
|
18
18
|
* id: string,
|
|
19
19
|
* ) => { code: string, map: null } | null,
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from "vite";
|
|
12
12
|
import { clientCodeSplitting, onBuildLog } from "./client-chunking.mjs";
|
|
13
13
|
import { recordEntryWeight } from "./entry-weight.mjs";
|
|
14
|
+
import { rejectBackendSources } from "./backend-boundary.mjs";
|
|
14
15
|
import { rejectServerSourcesInClient } from "./client-server-guard.mjs";
|
|
15
16
|
import { uiInertiaPage } from "./ui-inertia-page.mjs";
|
|
16
17
|
import { uiKbd } from "./ui-kbd.mjs";
|
|
@@ -29,6 +30,7 @@ interface FrontendModuleRegistryEntry {
|
|
|
29
30
|
id: string;
|
|
30
31
|
name?: string;
|
|
31
32
|
packageName?: string;
|
|
33
|
+
backendPackage?: string;
|
|
32
34
|
root: string;
|
|
33
35
|
priority: number;
|
|
34
36
|
}
|
|
@@ -45,6 +47,9 @@ const registry = JSON.parse(
|
|
|
45
47
|
readFileSync(registryPath, "utf8"),
|
|
46
48
|
) as FrontendModuleRegistry;
|
|
47
49
|
const moduleRoots = registry.modules.map((module) => module.root);
|
|
50
|
+
const backendPackages = registry.modules.flatMap((module) =>
|
|
51
|
+
module.backendPackage === undefined ? [] : [module.backendPackage],
|
|
52
|
+
);
|
|
48
53
|
const frontendSourceRoots = moduleRoots.flatMap((root) => {
|
|
49
54
|
const layersRoot = resolve(root, "layers");
|
|
50
55
|
if (!existsSync(layersRoot)) return [root];
|
|
@@ -175,6 +180,9 @@ export default defineConfig({
|
|
|
175
180
|
// Fails a client build that imports a dms.server.ts or a file under a
|
|
176
181
|
// module's server/ directory, however it is imported.
|
|
177
182
|
rejectServerSourcesInClient(moduleRoots),
|
|
183
|
+
// Fails a build, a worker build or a dev request that resolves a file
|
|
184
|
+
// under the src of the package that ships a module.
|
|
185
|
+
rejectBackendSources(backendPackages),
|
|
178
186
|
// What each module adds to the client entry, which `ajs dms build` reports.
|
|
179
187
|
recordEntryWeight(registry.modules),
|
|
180
188
|
{
|
|
@@ -267,6 +275,7 @@ export default defineConfig({
|
|
|
267
275
|
paintBeforeHydrate(),
|
|
268
276
|
...vitePlugins(registry.modules, frontendBuilds),
|
|
269
277
|
],
|
|
278
|
+
worker: { plugins: () => vitePlugins(registry.modules, frontendBuilds) },
|
|
270
279
|
resolve: {
|
|
271
280
|
// `@iconify/vue` keeps its API providers in module state: `main.ts` and
|
|
272
281
|
// Nuxt UI's `Icon` must share one copy for the same-origin provider to apply.
|