@nuraly/lumenjs 0.1.3 → 0.2.0
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 +62 -282
- package/dist/auth/config.d.ts +23 -0
- package/dist/auth/config.js +115 -0
- package/dist/auth/guard.d.ts +12 -0
- package/dist/auth/guard.js +28 -0
- package/dist/auth/index.d.ts +3 -0
- package/dist/auth/index.js +1 -0
- package/dist/auth/middleware.d.ts +23 -0
- package/dist/auth/middleware.js +89 -0
- package/dist/auth/native-auth.d.ts +82 -0
- package/dist/auth/native-auth.js +340 -0
- package/dist/auth/oidc-client.d.ts +17 -0
- package/dist/auth/oidc-client.js +123 -0
- package/dist/auth/providers/google.d.ts +23 -0
- package/dist/auth/providers/google.js +25 -0
- package/dist/auth/providers/index.d.ts +2 -0
- package/dist/auth/providers/index.js +1 -0
- package/dist/auth/routes/login.d.ts +8 -0
- package/dist/auth/routes/login.js +121 -0
- package/dist/auth/routes/logout.d.ts +4 -0
- package/dist/auth/routes/logout.js +79 -0
- package/dist/auth/routes/oidc-callback.d.ts +3 -0
- package/dist/auth/routes/oidc-callback.js +70 -0
- package/dist/auth/routes/password.d.ts +5 -0
- package/dist/auth/routes/password.js +149 -0
- package/dist/auth/routes/signup.d.ts +3 -0
- package/dist/auth/routes/signup.js +81 -0
- package/dist/auth/routes/token.d.ts +4 -0
- package/dist/auth/routes/token.js +70 -0
- package/dist/auth/routes/totp.d.ts +22 -0
- package/dist/auth/routes/totp.js +232 -0
- package/dist/auth/routes/utils.d.ts +7 -0
- package/dist/auth/routes/utils.js +35 -0
- package/dist/auth/routes/verify.d.ts +3 -0
- package/dist/auth/routes/verify.js +26 -0
- package/dist/auth/routes.d.ts +8 -0
- package/dist/auth/routes.js +124 -0
- package/dist/auth/session.d.ts +8 -0
- package/dist/auth/session.js +54 -0
- package/dist/auth/token.d.ts +33 -0
- package/dist/auth/token.js +90 -0
- package/dist/auth/types.d.ts +156 -0
- package/dist/auth/types.js +2 -0
- package/dist/build/build-client.d.ts +15 -0
- package/dist/build/build-client.js +45 -0
- package/dist/build/build-prerender.d.ts +11 -0
- package/dist/build/build-prerender.js +159 -0
- package/dist/build/build-server.d.ts +18 -0
- package/dist/build/build-server.js +107 -0
- package/dist/build/build.js +60 -123
- package/dist/build/scan.d.ts +18 -0
- package/dist/build/scan.js +77 -6
- package/dist/build/serve-api.js +8 -2
- package/dist/build/serve-loaders.d.ts +4 -4
- package/dist/build/serve-loaders.js +26 -18
- package/dist/build/serve-ssr.js +38 -11
- package/dist/build/serve-static.js +3 -3
- package/dist/build/serve.js +341 -18
- package/dist/cli.js +37 -6
- package/dist/communication/encryption.d.ts +35 -0
- package/dist/communication/encryption.js +90 -0
- package/dist/communication/handlers/context.d.ts +27 -0
- package/dist/communication/handlers/context.js +1 -0
- package/dist/communication/handlers/conversation.d.ts +24 -0
- package/dist/communication/handlers/conversation.js +113 -0
- package/dist/communication/handlers/file-upload.d.ts +17 -0
- package/dist/communication/handlers/file-upload.js +62 -0
- package/dist/communication/handlers/messaging.d.ts +30 -0
- package/dist/communication/handlers/messaging.js +237 -0
- package/dist/communication/handlers/presence.d.ts +15 -0
- package/dist/communication/handlers/presence.js +76 -0
- package/dist/communication/handlers.d.ts +5 -0
- package/dist/communication/handlers.js +5 -0
- package/dist/communication/index.d.ts +9 -0
- package/dist/communication/index.js +7 -0
- package/dist/communication/link-preview.d.ts +18 -0
- package/dist/communication/link-preview.js +115 -0
- package/dist/communication/schema.d.ts +10 -0
- package/dist/communication/schema.js +101 -0
- package/dist/communication/server.d.ts +86 -0
- package/dist/communication/server.js +212 -0
- package/dist/communication/signaling.d.ts +43 -0
- package/dist/communication/signaling.js +271 -0
- package/dist/communication/store.d.ts +71 -0
- package/dist/communication/store.js +289 -0
- package/dist/communication/types.d.ts +454 -0
- package/dist/communication/types.js +1 -0
- package/dist/create.d.ts +1 -0
- package/dist/create.js +55 -0
- package/dist/db/auto-migrate.d.ts +3 -0
- package/dist/db/auto-migrate.js +100 -0
- package/dist/db/client.d.ts +3 -0
- package/dist/db/client.js +18 -0
- package/dist/db/index.d.ts +17 -13
- package/dist/db/index.js +205 -26
- package/dist/db/seed.d.ts +12 -0
- package/dist/db/seed.js +88 -0
- package/dist/db/table.d.ts +10 -0
- package/dist/db/table.js +12 -0
- package/dist/dev-server/config.d.ts +11 -0
- package/dist/dev-server/config.js +40 -20
- package/dist/dev-server/index-html.d.ts +4 -0
- package/dist/dev-server/index-html.js +21 -6
- package/dist/dev-server/nuralyui-aliases.d.ts +0 -4
- package/dist/dev-server/nuralyui-aliases.js +115 -94
- package/dist/dev-server/plugins/vite-plugin-api-routes.js +29 -5
- package/dist/dev-server/plugins/vite-plugin-auth.d.ts +6 -0
- package/dist/dev-server/plugins/vite-plugin-auth.js +223 -0
- package/dist/dev-server/plugins/vite-plugin-auto-define.d.ts +16 -0
- package/dist/dev-server/plugins/vite-plugin-auto-define.js +111 -0
- package/dist/dev-server/plugins/vite-plugin-communication.d.ts +6 -0
- package/dist/dev-server/plugins/vite-plugin-communication.js +205 -0
- package/dist/dev-server/plugins/vite-plugin-editor-api.d.ts +6 -0
- package/dist/dev-server/plugins/vite-plugin-editor-api.js +318 -0
- package/dist/dev-server/plugins/vite-plugin-i18n.js +69 -2
- package/dist/dev-server/plugins/vite-plugin-lit-dedup.d.ts +6 -0
- package/dist/dev-server/plugins/vite-plugin-lit-dedup.js +78 -34
- package/dist/dev-server/plugins/vite-plugin-lit-hmr.js +44 -2
- package/dist/dev-server/plugins/vite-plugin-llms.d.ts +2 -0
- package/dist/dev-server/plugins/vite-plugin-llms.js +92 -0
- package/dist/dev-server/plugins/vite-plugin-loaders.js +146 -13
- package/dist/dev-server/plugins/vite-plugin-routes.js +16 -5
- package/dist/dev-server/plugins/vite-plugin-socketio.d.ts +2 -0
- package/dist/dev-server/plugins/vite-plugin-socketio.js +51 -0
- package/dist/dev-server/plugins/vite-plugin-source-annotator.d.ts +2 -0
- package/dist/dev-server/plugins/vite-plugin-source-annotator.js +26 -3
- package/dist/dev-server/plugins/vite-plugin-storage.d.ts +10 -0
- package/dist/dev-server/plugins/vite-plugin-storage.js +126 -0
- package/dist/dev-server/plugins/vite-plugin-virtual-modules.js +140 -3
- package/dist/dev-server/server.js +242 -70
- package/dist/dev-server/ssr-render.d.ts +2 -1
- package/dist/dev-server/ssr-render.js +117 -50
- package/dist/editor/ai/backend.d.ts +20 -0
- package/dist/editor/ai/backend.js +113 -0
- package/dist/editor/ai/claude-code-client.d.ts +20 -0
- package/dist/editor/ai/claude-code-client.js +145 -0
- package/dist/editor/ai/deepseek-client.d.ts +7 -0
- package/dist/editor/ai/deepseek-client.js +113 -0
- package/dist/editor/ai/opencode-client.d.ts +14 -0
- package/dist/editor/ai/opencode-client.js +99 -0
- package/dist/editor/ai/snapshot-store.d.ts +22 -0
- package/dist/editor/ai/snapshot-store.js +35 -0
- package/dist/editor/ai/types.d.ts +30 -0
- package/dist/editor/ai/types.js +136 -0
- package/dist/editor/ai-chat-panel.d.ts +13 -0
- package/dist/editor/ai-chat-panel.js +613 -0
- package/dist/editor/ai-markdown.d.ts +10 -0
- package/dist/editor/ai-markdown.js +70 -0
- package/dist/editor/ai-project-panel.d.ts +11 -0
- package/dist/editor/ai-project-panel.js +332 -0
- package/dist/editor/ast-modification.d.ts +11 -0
- package/dist/editor/ast-modification.js +1 -0
- package/dist/editor/ast-service.d.ts +30 -0
- package/dist/editor/ast-service.js +180 -0
- package/dist/editor/css-rules.d.ts +54 -0
- package/dist/editor/css-rules.js +423 -0
- package/dist/editor/editor-api-client.d.ts +51 -0
- package/dist/editor/editor-api-client.js +162 -0
- package/dist/editor/editor-bridge.d.ts +1 -0
- package/dist/editor/editor-bridge.js +18 -8
- package/dist/editor/editor-toolbar.d.ts +14 -0
- package/dist/editor/editor-toolbar.js +115 -0
- package/dist/editor/file-editor.d.ts +9 -0
- package/dist/editor/file-editor.js +236 -0
- package/dist/editor/file-service.d.ts +16 -0
- package/dist/editor/file-service.js +52 -0
- package/dist/editor/i18n-key-gen.d.ts +1 -0
- package/dist/editor/i18n-key-gen.js +7 -0
- package/dist/editor/inline-text-edit.d.ts +5 -0
- package/dist/editor/inline-text-edit.js +173 -92
- package/dist/editor/overlay-events.d.ts +5 -0
- package/dist/editor/overlay-events.js +364 -0
- package/dist/editor/overlay-hmr.d.ts +2 -0
- package/dist/editor/overlay-hmr.js +76 -0
- package/dist/editor/overlay-selection.d.ts +29 -0
- package/dist/editor/overlay-selection.js +148 -0
- package/dist/editor/overlay-utils.d.ts +12 -0
- package/dist/editor/overlay-utils.js +59 -0
- package/dist/editor/properties-panel-persist.d.ts +14 -0
- package/dist/editor/properties-panel-persist.js +70 -0
- package/dist/editor/properties-panel-rows.d.ts +10 -0
- package/dist/editor/properties-panel-rows.js +349 -0
- package/dist/editor/properties-panel-styles.d.ts +4 -0
- package/dist/editor/properties-panel-styles.js +174 -0
- package/dist/editor/properties-panel.d.ts +4 -0
- package/dist/editor/properties-panel.js +148 -0
- package/dist/editor/property-registry.d.ts +16 -0
- package/dist/editor/property-registry.js +303 -0
- package/dist/editor/standalone-file-panel.d.ts +0 -0
- package/dist/editor/standalone-file-panel.js +1 -0
- package/dist/editor/standalone-overlay-dom.d.ts +0 -0
- package/dist/editor/standalone-overlay-dom.js +1 -0
- package/dist/editor/standalone-overlay-styles.d.ts +0 -0
- package/dist/editor/standalone-overlay-styles.js +1 -0
- package/dist/editor/standalone-overlay.d.ts +1 -0
- package/dist/editor/standalone-overlay.js +76 -0
- package/dist/editor/syntax-highlighter.d.ts +4 -0
- package/dist/editor/syntax-highlighter.js +81 -0
- package/dist/editor/text-toolbar.d.ts +11 -0
- package/dist/editor/text-toolbar.js +327 -0
- package/dist/editor/toolbar-styles.d.ts +4 -0
- package/dist/editor/toolbar-styles.js +198 -0
- package/dist/email/index.d.ts +32 -0
- package/dist/email/index.js +154 -0
- package/dist/email/providers/resend.d.ts +2 -0
- package/dist/email/providers/resend.js +24 -0
- package/dist/email/providers/sendgrid.d.ts +2 -0
- package/dist/email/providers/sendgrid.js +31 -0
- package/dist/email/providers/smtp.d.ts +13 -0
- package/dist/email/providers/smtp.js +125 -0
- package/dist/email/template-engine.d.ts +18 -0
- package/dist/email/template-engine.js +116 -0
- package/dist/email/templates/base.d.ts +9 -0
- package/dist/email/templates/base.js +65 -0
- package/dist/email/templates/password-reset.d.ts +5 -0
- package/dist/email/templates/password-reset.js +15 -0
- package/dist/email/templates/verify-email.d.ts +5 -0
- package/dist/email/templates/verify-email.js +15 -0
- package/dist/email/templates/welcome.d.ts +5 -0
- package/dist/email/templates/welcome.js +13 -0
- package/dist/email/types.d.ts +49 -0
- package/dist/email/types.js +1 -0
- package/dist/llms/generate.d.ts +46 -0
- package/dist/llms/generate.js +185 -0
- package/dist/permissions/guard.d.ts +28 -0
- package/dist/permissions/guard.js +30 -0
- package/dist/permissions/index.d.ts +6 -0
- package/dist/permissions/index.js +3 -0
- package/dist/permissions/service.d.ts +80 -0
- package/dist/permissions/service.js +210 -0
- package/dist/permissions/tables.d.ts +5 -0
- package/dist/permissions/tables.js +68 -0
- package/dist/permissions/types.d.ts +33 -0
- package/dist/permissions/types.js +1 -0
- package/dist/runtime/app-shell.d.ts +1 -1
- package/dist/runtime/app-shell.js +164 -0
- package/dist/runtime/auth.d.ts +10 -0
- package/dist/runtime/auth.js +30 -0
- package/dist/runtime/communication.d.ts +137 -0
- package/dist/runtime/communication.js +228 -0
- package/dist/runtime/error-boundary.d.ts +23 -0
- package/dist/runtime/error-boundary.js +120 -0
- package/dist/runtime/i18n.d.ts +6 -1
- package/dist/runtime/i18n.js +42 -21
- package/dist/runtime/island.d.ts +16 -0
- package/dist/runtime/island.js +80 -0
- package/dist/runtime/router-data.d.ts +3 -0
- package/dist/runtime/router-data.js +102 -17
- package/dist/runtime/router-hydration.js +34 -2
- package/dist/runtime/router.d.ts +19 -2
- package/dist/runtime/router.js +237 -43
- package/dist/runtime/socket-client.d.ts +2 -0
- package/dist/runtime/socket-client.js +30 -0
- package/dist/runtime/webrtc.d.ts +91 -0
- package/dist/runtime/webrtc.js +428 -0
- package/dist/shared/dom-shims.js +4 -2
- package/dist/shared/graceful-shutdown.d.ts +8 -0
- package/dist/shared/graceful-shutdown.js +36 -0
- package/dist/shared/health.d.ts +8 -0
- package/dist/shared/health.js +25 -0
- package/dist/shared/llms-txt.d.ts +31 -0
- package/dist/shared/llms-txt.js +85 -0
- package/dist/shared/logger.d.ts +32 -0
- package/dist/shared/logger.js +93 -0
- package/dist/shared/meta.d.ts +27 -0
- package/dist/shared/meta.js +71 -0
- package/dist/shared/middleware-runner.d.ts +9 -0
- package/dist/shared/middleware-runner.js +29 -0
- package/dist/shared/rate-limit.d.ts +18 -0
- package/dist/shared/rate-limit.js +71 -0
- package/dist/shared/request-id.d.ts +5 -0
- package/dist/shared/request-id.js +18 -0
- package/dist/shared/route-matching.js +16 -1
- package/dist/shared/security-headers.d.ts +18 -0
- package/dist/shared/security-headers.js +38 -0
- package/dist/shared/socket-io-setup.d.ts +11 -0
- package/dist/shared/socket-io-setup.js +51 -0
- package/dist/shared/types.d.ts +15 -0
- package/dist/shared/utils.d.ts +33 -7
- package/dist/shared/utils.js +164 -27
- package/dist/storage/adapters/local.d.ts +44 -0
- package/dist/storage/adapters/local.js +85 -0
- package/dist/storage/adapters/s3.d.ts +32 -0
- package/dist/storage/adapters/s3.js +119 -0
- package/dist/storage/adapters/types.d.ts +53 -0
- package/dist/storage/adapters/types.js +1 -0
- package/dist/storage/index.d.ts +76 -0
- package/dist/storage/index.js +83 -0
- package/package.json +45 -7
- package/templates/blog/api/posts.ts +4 -18
- package/templates/blog/data/migrations/001_init.sql +6 -5
- package/templates/blog/lumenjs.config.ts +3 -0
- package/templates/blog/package.json +14 -0
- package/templates/blog/pages/_layout.ts +25 -0
- package/templates/blog/pages/index.ts +48 -22
- package/templates/blog/pages/posts/[slug].ts +45 -20
- package/templates/blog/pages/tag/[tag].ts +44 -0
- package/templates/dashboard/api/stats.ts +8 -5
- package/templates/dashboard/lumenjs.config.ts +3 -0
- package/templates/dashboard/package.json +14 -0
- package/templates/dashboard/pages/_layout.ts +25 -0
- package/templates/dashboard/pages/index.ts +54 -23
- package/templates/dashboard/pages/settings/index.ts +29 -0
- package/templates/default/lumenjs.config.ts +3 -0
- package/templates/default/package.json +14 -0
- package/templates/default/pages/index.ts +24 -0
package/dist/build/build.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { build as viteBuild } from 'vite';
|
|
2
1
|
import path from 'path';
|
|
3
2
|
import fs from 'fs';
|
|
4
3
|
import { getSharedViteConfig } from '../dev-server/server.js';
|
|
5
4
|
import { readProjectConfig } from '../dev-server/config.js';
|
|
6
|
-
import { generateIndexHtml } from '../dev-server/index-html.js';
|
|
7
5
|
import { filePathToTagName } from '../shared/utils.js';
|
|
8
|
-
import { scanPages, scanLayouts, scanApiRoutes, getLayoutDirsForPage } from './scan.js';
|
|
6
|
+
import { scanPages, scanLayouts, scanApiRoutes, scanMiddleware, getLayoutDirsForPage } from './scan.js';
|
|
7
|
+
import { buildClient } from './build-client.js';
|
|
8
|
+
import { buildServer } from './build-server.js';
|
|
9
|
+
import { prerenderPages } from './build-prerender.js';
|
|
9
10
|
export async function buildProject(options) {
|
|
10
11
|
const { projectDir } = options;
|
|
11
12
|
const outDir = options.outDir || path.join(projectDir, '.lumenjs');
|
|
@@ -19,130 +20,44 @@ export async function buildProject(options) {
|
|
|
19
20
|
fs.rmSync(outDir, { recursive: true });
|
|
20
21
|
}
|
|
21
22
|
fs.mkdirSync(outDir, { recursive: true });
|
|
22
|
-
const { title, integrations, i18n: i18nConfig } = readProjectConfig(projectDir);
|
|
23
|
+
const { title, integrations, i18n: i18nConfig, prefetch: prefetchStrategy, prerender: globalPrerender } = readProjectConfig(projectDir);
|
|
23
24
|
const shared = getSharedViteConfig(projectDir, { mode: 'production', integrations });
|
|
24
|
-
// Scan pages, layouts,
|
|
25
|
+
// Scan pages, layouts, API routes, and middleware for the manifest
|
|
25
26
|
const pageEntries = scanPages(pagesDir);
|
|
26
27
|
const layoutEntries = scanLayouts(pagesDir);
|
|
27
28
|
const apiEntries = scanApiRoutes(apiDir);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
root: projectDir,
|
|
37
|
-
publicDir: fs.existsSync(publicDir) ? publicDir : undefined,
|
|
38
|
-
resolve: shared.resolve,
|
|
39
|
-
plugins: shared.plugins,
|
|
40
|
-
esbuild: shared.esbuild,
|
|
41
|
-
build: {
|
|
42
|
-
outDir: clientDir,
|
|
43
|
-
emptyOutDir: true,
|
|
44
|
-
rollupOptions: {
|
|
45
|
-
input: tempIndexPath,
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
logLevel: 'warn',
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
finally {
|
|
52
|
-
// Clean up temp file
|
|
53
|
-
if (fs.existsSync(tempIndexPath)) {
|
|
54
|
-
fs.unlinkSync(tempIndexPath);
|
|
29
|
+
const middlewareEntries = scanMiddleware(pagesDir);
|
|
30
|
+
// Check for auth config
|
|
31
|
+
const authConfigPath = path.join(projectDir, 'lumenjs.auth.ts');
|
|
32
|
+
const hasAuthConfig = fs.existsSync(authConfigPath);
|
|
33
|
+
// Apply global prerender flag from config
|
|
34
|
+
if (globalPrerender) {
|
|
35
|
+
for (const entry of pageEntries) {
|
|
36
|
+
entry.prerender = true;
|
|
55
37
|
}
|
|
56
38
|
}
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
39
|
+
// --- Client build ---
|
|
40
|
+
await buildClient({
|
|
41
|
+
projectDir,
|
|
42
|
+
clientDir,
|
|
43
|
+
title,
|
|
44
|
+
integrations,
|
|
45
|
+
prefetchStrategy,
|
|
46
|
+
publicDir,
|
|
47
|
+
shared,
|
|
48
|
+
});
|
|
63
49
|
// --- Server build ---
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
serverEntries[entryName] = entry.filePath;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
for (const entry of apiEntries) {
|
|
79
|
-
serverEntries[`api/${entry.name}`] = entry.filePath;
|
|
80
|
-
}
|
|
81
|
-
// Create SSR runtime entry — bundles @lit-labs/ssr alongside Lit so all
|
|
82
|
-
// server modules share one Lit instance (avoids _$EM mismatches).
|
|
83
|
-
const ssrEntryPath = path.join(projectDir, '__nk_ssr_entry.js');
|
|
84
|
-
const hasPageLoaders = pageEntries.some(e => e.hasLoader);
|
|
85
|
-
const hasLayoutLoaders = layoutEntries.some(e => e.hasLoader);
|
|
86
|
-
if (hasPageLoaders || hasLayoutLoaders) {
|
|
87
|
-
fs.writeFileSync(ssrEntryPath, [
|
|
88
|
-
"import '@lit-labs/ssr/lib/install-global-dom-shim.js';",
|
|
89
|
-
"export { render } from '@lit-labs/ssr';",
|
|
90
|
-
"export { html, unsafeStatic } from 'lit/static-html.js';",
|
|
91
|
-
].join('\n'));
|
|
92
|
-
serverEntries['ssr-runtime'] = ssrEntryPath;
|
|
93
|
-
}
|
|
94
|
-
try {
|
|
95
|
-
if (Object.keys(serverEntries).length > 0) {
|
|
96
|
-
await viteBuild({
|
|
97
|
-
root: projectDir,
|
|
98
|
-
resolve: shared.resolve,
|
|
99
|
-
plugins: shared.plugins,
|
|
100
|
-
esbuild: shared.esbuild,
|
|
101
|
-
build: {
|
|
102
|
-
outDir: serverDir,
|
|
103
|
-
emptyOutDir: true,
|
|
104
|
-
ssr: true,
|
|
105
|
-
rollupOptions: {
|
|
106
|
-
input: serverEntries,
|
|
107
|
-
output: {
|
|
108
|
-
format: 'esm',
|
|
109
|
-
entryFileNames: '[name].js',
|
|
110
|
-
chunkFileNames: 'assets/[name]-[hash].js',
|
|
111
|
-
manualChunks(id) {
|
|
112
|
-
// Force all Lit packages into a single shared chunk so SSR runtime
|
|
113
|
-
// and page modules use the exact same Lit class instances.
|
|
114
|
-
if (id.includes('/node_modules/lit/') ||
|
|
115
|
-
id.includes('/node_modules/lit-html/') ||
|
|
116
|
-
id.includes('/node_modules/lit-element/') ||
|
|
117
|
-
id.includes('/node_modules/@lit/reactive-element/')) {
|
|
118
|
-
return 'lit-shared';
|
|
119
|
-
}
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
external: [
|
|
123
|
-
/^node:/,
|
|
124
|
-
'os', 'fs', 'path', 'url', 'util', 'crypto', 'http', 'https', 'net',
|
|
125
|
-
'stream', 'zlib', 'events', 'buffer', 'querystring', 'child_process',
|
|
126
|
-
'worker_threads', 'cluster', 'dns', 'tls', 'assert', 'constants',
|
|
127
|
-
'better-sqlite3',
|
|
128
|
-
],
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
logLevel: 'warn',
|
|
132
|
-
ssr: {
|
|
133
|
-
noExternal: true,
|
|
134
|
-
},
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
fs.mkdirSync(serverDir, { recursive: true });
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
finally {
|
|
142
|
-
if (fs.existsSync(ssrEntryPath)) {
|
|
143
|
-
fs.unlinkSync(ssrEntryPath);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
50
|
+
await buildServer({
|
|
51
|
+
projectDir,
|
|
52
|
+
serverDir,
|
|
53
|
+
pageEntries,
|
|
54
|
+
layoutEntries,
|
|
55
|
+
apiEntries,
|
|
56
|
+
middlewareEntries,
|
|
57
|
+
hasAuthConfig,
|
|
58
|
+
authConfigPath,
|
|
59
|
+
shared,
|
|
60
|
+
});
|
|
146
61
|
// --- Copy locales ---
|
|
147
62
|
if (i18nConfig) {
|
|
148
63
|
const localesDir = path.join(projectDir, 'locales');
|
|
@@ -160,20 +75,25 @@ export async function buildProject(options) {
|
|
|
160
75
|
// --- Write manifest ---
|
|
161
76
|
const manifest = {
|
|
162
77
|
routes: pageEntries.map(e => {
|
|
163
|
-
const routeLayouts = getLayoutDirsForPage(e.filePath, pagesDir, layoutEntries);
|
|
78
|
+
const routeLayouts = e.hasStandalone ? [] : getLayoutDirsForPage(e.filePath, pagesDir, layoutEntries);
|
|
164
79
|
const relPath = path.relative(pagesDir, e.filePath).replace(/\\/g, '/');
|
|
165
80
|
return {
|
|
166
81
|
path: e.routePath,
|
|
167
|
-
module: (e.hasLoader || e.hasSubscribe) ? `pages/${e.name}.js` : '',
|
|
82
|
+
module: (e.hasLoader || e.hasSubscribe || e.hasSocket || e.prerender) ? `pages/${e.name.replace(/\[(\w+)\]/g, '_$1_')}.js` : '',
|
|
168
83
|
hasLoader: e.hasLoader,
|
|
169
84
|
hasSubscribe: e.hasSubscribe,
|
|
170
85
|
tagName: filePathToTagName(relPath),
|
|
171
86
|
...(routeLayouts.length > 0 ? { layouts: routeLayouts } : {}),
|
|
87
|
+
...(e.hasSocket ? { hasSocket: true } : {}),
|
|
88
|
+
...(e.hasAuth ? { hasAuth: true } : {}),
|
|
89
|
+
...(e.hasMeta ? { hasMeta: true } : {}),
|
|
90
|
+
...(e.hasStandalone ? { hasStandalone: true } : {}),
|
|
91
|
+
...(e.prerender ? { prerender: true } : {}),
|
|
172
92
|
};
|
|
173
93
|
}),
|
|
174
94
|
apiRoutes: apiEntries.map(e => ({
|
|
175
95
|
path: `/api/${e.routePath}`,
|
|
176
|
-
module: `api/${e.name}.js`,
|
|
96
|
+
module: `api/${e.name.replace(/\[(\w+)\]/g, '_$1_')}.js`,
|
|
177
97
|
hasLoader: false,
|
|
178
98
|
hasSubscribe: false,
|
|
179
99
|
})),
|
|
@@ -183,9 +103,26 @@ export async function buildProject(options) {
|
|
|
183
103
|
hasLoader: e.hasLoader,
|
|
184
104
|
hasSubscribe: e.hasSubscribe,
|
|
185
105
|
})),
|
|
106
|
+
...(middlewareEntries.length > 0 ? {
|
|
107
|
+
middlewares: middlewareEntries.map(e => ({
|
|
108
|
+
dir: e.dir,
|
|
109
|
+
module: e.dir ? `middleware/${e.dir}/_middleware.js` : 'middleware/_middleware.js',
|
|
110
|
+
})),
|
|
111
|
+
} : {}),
|
|
186
112
|
...(i18nConfig ? { i18n: i18nConfig } : {}),
|
|
113
|
+
...(hasAuthConfig ? { auth: { configModule: 'auth-config.js' } } : {}),
|
|
114
|
+
prefetch: prefetchStrategy,
|
|
187
115
|
};
|
|
188
116
|
fs.writeFileSync(path.join(outDir, 'manifest.json'), JSON.stringify(manifest, null, 2));
|
|
117
|
+
// --- Pre-render phase ---
|
|
118
|
+
await prerenderPages({
|
|
119
|
+
serverDir,
|
|
120
|
+
clientDir,
|
|
121
|
+
pagesDir,
|
|
122
|
+
pageEntries,
|
|
123
|
+
layoutEntries,
|
|
124
|
+
manifest,
|
|
125
|
+
});
|
|
189
126
|
console.log('[LumenJS] Build complete.');
|
|
190
127
|
console.log(` Output: ${outDir}`);
|
|
191
128
|
console.log(` Client assets: ${clientDir}`);
|
package/dist/build/scan.d.ts
CHANGED
|
@@ -4,6 +4,11 @@ export interface PageEntry {
|
|
|
4
4
|
routePath: string;
|
|
5
5
|
hasLoader: boolean;
|
|
6
6
|
hasSubscribe: boolean;
|
|
7
|
+
hasSocket: boolean;
|
|
8
|
+
hasAuth: boolean;
|
|
9
|
+
hasMeta: boolean;
|
|
10
|
+
hasStandalone: boolean;
|
|
11
|
+
prerender: boolean;
|
|
7
12
|
}
|
|
8
13
|
export interface LayoutEntry {
|
|
9
14
|
dir: string;
|
|
@@ -21,3 +26,16 @@ export declare function scanLayouts(pagesDir: string): LayoutEntry[];
|
|
|
21
26
|
export declare function scanApiRoutes(apiDir: string): ApiEntry[];
|
|
22
27
|
/** Get the layout directory chain for a given page file */
|
|
23
28
|
export declare function getLayoutDirsForPage(pageFilePath: string, pagesDir: string, layouts: LayoutEntry[]): string[];
|
|
29
|
+
export interface MiddlewareEntry {
|
|
30
|
+
dir: string;
|
|
31
|
+
filePath: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Scan for _middleware.ts files in the pages directory tree.
|
|
35
|
+
*/
|
|
36
|
+
export declare function scanMiddleware(pagesDir: string): MiddlewareEntry[];
|
|
37
|
+
/**
|
|
38
|
+
* Get middleware directories that match a given URL pathname.
|
|
39
|
+
* Returns matching middleware entries from root → deepest.
|
|
40
|
+
*/
|
|
41
|
+
export declare function getMiddlewareDirsForPathname(pathname: string, entries: MiddlewareEntry[]): MiddlewareEntry[];
|
package/dist/build/scan.js
CHANGED
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { fileHasLoader, fileHasSubscribe
|
|
3
|
+
import { filePathToRoute, fileHasLoader, fileHasSubscribe } from '../shared/utils.js';
|
|
4
|
+
/** Read a page file once and check all flags from the same content. */
|
|
5
|
+
function analyzePageFile(filePath) {
|
|
6
|
+
try {
|
|
7
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
8
|
+
const classStart = content.search(/export\s+class\s+\w+/);
|
|
9
|
+
const hasExportBefore = (regex) => {
|
|
10
|
+
const match = regex.exec(content);
|
|
11
|
+
if (!match)
|
|
12
|
+
return false;
|
|
13
|
+
if (classStart >= 0 && match.index > classStart)
|
|
14
|
+
return false;
|
|
15
|
+
return true;
|
|
16
|
+
};
|
|
17
|
+
return {
|
|
18
|
+
hasLoader: hasExportBefore(/export\s+(async\s+)?function\s+loader\s*\(/),
|
|
19
|
+
hasSubscribe: hasExportBefore(/export\s+(async\s+)?function\s+subscribe\s*\(/),
|
|
20
|
+
hasSocket: /export\s+(function|const)\s+socket[\s(=]/.test(content),
|
|
21
|
+
hasAuth: hasExportBefore(/export\s+const\s+auth\s*=/),
|
|
22
|
+
hasMeta: hasExportBefore(/export\s+(const\s+meta\s*=|(async\s+)?function\s+meta\s*\()/),
|
|
23
|
+
hasStandalone: hasExportBefore(/export\s+const\s+standalone\s*=/),
|
|
24
|
+
prerender: /export\s+const\s+prerender\s*=\s*true/.test(content),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return { hasLoader: false, hasSubscribe: false, hasSocket: false, hasAuth: false, hasMeta: false, hasStandalone: false, prerender: false };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
4
31
|
export function scanPages(pagesDir) {
|
|
5
32
|
if (!fs.existsSync(pagesDir))
|
|
6
33
|
return [];
|
|
@@ -44,18 +71,23 @@ export function getLayoutDirsForPage(pageFilePath, pagesDir, layouts) {
|
|
|
44
71
|
function walkDir(baseDir, relativePath, entries, pagesDir) {
|
|
45
72
|
const fullDir = path.join(baseDir, relativePath);
|
|
46
73
|
const dirEntries = fs.readdirSync(fullDir, { withFileTypes: true });
|
|
74
|
+
// Check if this subdirectory contains an index file (folder route)
|
|
75
|
+
// Only applies to subdirectories, not the root pages directory
|
|
76
|
+
const hasIndex = relativePath !== '' && dirEntries.some(e => e.isFile() && /^index\.(ts|js)$/.test(e.name));
|
|
47
77
|
for (const entry of dirEntries) {
|
|
48
78
|
const entryRelative = path.join(relativePath, entry.name);
|
|
49
|
-
if (entry.isDirectory()) {
|
|
79
|
+
if (entry.isDirectory() && !entry.name.startsWith('_')) {
|
|
50
80
|
walkDir(baseDir, entryRelative, entries, pagesDir);
|
|
51
81
|
}
|
|
52
82
|
else if (entry.isFile() && /\.(ts|js)$/.test(entry.name) && !entry.name.startsWith('_')) {
|
|
83
|
+
// In a folder route (has index file), only register the index file and dynamic param files
|
|
84
|
+
if (hasIndex && !/^index\.(ts|js)$/.test(entry.name) && !entry.name.startsWith('['))
|
|
85
|
+
continue;
|
|
53
86
|
const filePath = path.join(pagesDir, entryRelative);
|
|
54
87
|
const name = entryRelative.replace(/\.(ts|js)$/, '').replace(/\\/g, '/');
|
|
55
88
|
const routePath = filePathToRoute(entryRelative);
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
entries.push({ name, filePath, routePath, hasLoader, hasSubscribe });
|
|
89
|
+
const flags = analyzePageFile(filePath);
|
|
90
|
+
entries.push({ name, filePath, routePath, ...flags });
|
|
59
91
|
}
|
|
60
92
|
}
|
|
61
93
|
}
|
|
@@ -68,11 +100,50 @@ function walkForLayouts(baseDir, relativePath, entries) {
|
|
|
68
100
|
const dir = relativePath.replace(/\\/g, '/');
|
|
69
101
|
entries.push({ dir, filePath, hasLoader: fileHasLoader(filePath), hasSubscribe: fileHasSubscribe(filePath) });
|
|
70
102
|
}
|
|
71
|
-
if (entry.isDirectory()) {
|
|
103
|
+
if (entry.isDirectory() && !entry.name.startsWith('_')) {
|
|
72
104
|
walkForLayouts(baseDir, path.join(relativePath, entry.name), entries);
|
|
73
105
|
}
|
|
74
106
|
}
|
|
75
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Scan for _middleware.ts files in the pages directory tree.
|
|
110
|
+
*/
|
|
111
|
+
export function scanMiddleware(pagesDir) {
|
|
112
|
+
if (!fs.existsSync(pagesDir))
|
|
113
|
+
return [];
|
|
114
|
+
const entries = [];
|
|
115
|
+
walkForMiddleware(pagesDir, '', entries);
|
|
116
|
+
return entries;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get middleware directories that match a given URL pathname.
|
|
120
|
+
* Returns matching middleware entries from root → deepest.
|
|
121
|
+
*/
|
|
122
|
+
export function getMiddlewareDirsForPathname(pathname, entries) {
|
|
123
|
+
const urlSegments = pathname.replace(/^\//, '').split('/').filter(Boolean);
|
|
124
|
+
return entries.filter(entry => {
|
|
125
|
+
if (entry.dir === '')
|
|
126
|
+
return true; // Root middleware applies to all routes
|
|
127
|
+
const dirSegments = entry.dir.split('/').filter(Boolean);
|
|
128
|
+
if (dirSegments.length > urlSegments.length)
|
|
129
|
+
return false;
|
|
130
|
+
return dirSegments.every((seg, i) => seg === urlSegments[i]);
|
|
131
|
+
}).sort((a, b) => a.dir.split('/').length - b.dir.split('/').length);
|
|
132
|
+
}
|
|
133
|
+
function walkForMiddleware(baseDir, relativePath, entries) {
|
|
134
|
+
const fullDir = path.join(baseDir, relativePath);
|
|
135
|
+
const dirEntries = fs.readdirSync(fullDir, { withFileTypes: true });
|
|
136
|
+
for (const entry of dirEntries) {
|
|
137
|
+
if (entry.isFile() && /^_middleware\.(ts|js)$/.test(entry.name)) {
|
|
138
|
+
const filePath = path.join(fullDir, entry.name);
|
|
139
|
+
const dir = relativePath.replace(/\\/g, '/');
|
|
140
|
+
entries.push({ dir, filePath });
|
|
141
|
+
}
|
|
142
|
+
if (entry.isDirectory() && !entry.name.startsWith('_')) {
|
|
143
|
+
walkForMiddleware(baseDir, path.join(relativePath, entry.name), entries);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
76
147
|
function walkApiDir(baseDir, relativePath, entries, apiDir) {
|
|
77
148
|
const fullDir = path.join(baseDir, relativePath);
|
|
78
149
|
const dirEntries = fs.readdirSync(fullDir, { withFileTypes: true });
|
package/dist/build/serve-api.js
CHANGED
|
@@ -2,6 +2,7 @@ import fs from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { readBody } from '../shared/utils.js';
|
|
4
4
|
import { matchRoute } from '../shared/route-matching.js';
|
|
5
|
+
import { useStorage } from '../storage/index.js';
|
|
5
6
|
export async function handleApiRoute(manifest, serverDir, pathname, queryString, method, req, res) {
|
|
6
7
|
const matched = matchRoute(manifest.apiRoutes, pathname);
|
|
7
8
|
if (!matched) {
|
|
@@ -9,7 +10,9 @@ export async function handleApiRoute(manifest, serverDir, pathname, queryString,
|
|
|
9
10
|
res.end(JSON.stringify({ error: 'API route not found' }));
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
12
|
-
|
|
13
|
+
// Vite replaces [param] with _param_ in output filenames
|
|
14
|
+
const resolvedModule = matched.route.module.replace(/\[([^\]]+)\]/g, '_$1_');
|
|
15
|
+
const modulePath = path.join(serverDir, resolvedModule);
|
|
13
16
|
if (!fs.existsSync(modulePath)) {
|
|
14
17
|
res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
15
18
|
res.end(JSON.stringify({ error: 'API route module not found' }));
|
|
@@ -43,13 +46,16 @@ export async function handleApiRoute(manifest, serverDir, pathname, queryString,
|
|
|
43
46
|
params: matched.params,
|
|
44
47
|
body,
|
|
45
48
|
headers: req.headers,
|
|
49
|
+
storage: useStorage(),
|
|
50
|
+
nkAuth: req.nkAuth,
|
|
46
51
|
});
|
|
47
52
|
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
48
53
|
res.end(JSON.stringify(result));
|
|
49
54
|
}
|
|
50
55
|
catch (err) {
|
|
51
56
|
const status = err?.status || 500;
|
|
52
|
-
|
|
57
|
+
// Only expose error messages for client errors (4xx); hide internals for 5xx
|
|
58
|
+
const message = status < 500 ? (err?.message || 'Request error') : 'Internal server error';
|
|
53
59
|
res.writeHead(status, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
54
60
|
res.end(JSON.stringify({ error: message }));
|
|
55
61
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import http from 'http';
|
|
2
2
|
import type { BuildManifest } from '../shared/types.js';
|
|
3
|
-
export declare function handleLayoutLoaderRequest(manifest: BuildManifest, serverDir: string, queryString: string | undefined, headers: http.IncomingHttpHeaders, res: http.ServerResponse): Promise<void>;
|
|
4
|
-
export declare function handleLayoutSubscribeRequest(manifest: BuildManifest, serverDir: string, queryString: string | undefined, headers: http.IncomingHttpHeaders, res: http.ServerResponse): Promise<void>;
|
|
5
|
-
export declare function handleSubscribeRequest(manifest: BuildManifest, serverDir: string, pagesDir: string, pathname: string, queryString: string | undefined, headers: http.IncomingHttpHeaders, res: http.ServerResponse): Promise<void>;
|
|
6
|
-
export declare function handleLoaderRequest(manifest: BuildManifest, serverDir: string, pagesDir: string, pathname: string, queryString: string | undefined, headers: http.IncomingHttpHeaders, res: http.ServerResponse): Promise<void>;
|
|
3
|
+
export declare function handleLayoutLoaderRequest(manifest: BuildManifest, serverDir: string, queryString: string | undefined, headers: http.IncomingHttpHeaders, res: http.ServerResponse, user?: any): Promise<void>;
|
|
4
|
+
export declare function handleLayoutSubscribeRequest(manifest: BuildManifest, serverDir: string, queryString: string | undefined, headers: http.IncomingHttpHeaders, res: http.ServerResponse, user?: any): Promise<void>;
|
|
5
|
+
export declare function handleSubscribeRequest(manifest: BuildManifest, serverDir: string, pagesDir: string, pathname: string, queryString: string | undefined, headers: http.IncomingHttpHeaders, res: http.ServerResponse, user?: any): Promise<void>;
|
|
6
|
+
export declare function handleLoaderRequest(manifest: BuildManifest, serverDir: string, pagesDir: string, pathname: string, queryString: string | undefined, headers: http.IncomingHttpHeaders, res: http.ServerResponse, user?: any): Promise<void>;
|
|
@@ -2,7 +2,15 @@ import fs from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { isRedirectResponse } from '../shared/utils.js';
|
|
4
4
|
import { matchRoute } from '../shared/route-matching.js';
|
|
5
|
-
|
|
5
|
+
import { logger } from '../shared/logger.js';
|
|
6
|
+
/** Resolve a module path, falling back to bracket-sanitized filename (Rollup replaces [] with _) */
|
|
7
|
+
function resolveModulePath(serverDir, moduleName) {
|
|
8
|
+
const p = path.join(serverDir, moduleName);
|
|
9
|
+
if (fs.existsSync(p))
|
|
10
|
+
return p;
|
|
11
|
+
return path.join(serverDir, moduleName.replace(/\[/g, '_').replace(/\]/g, '_'));
|
|
12
|
+
}
|
|
13
|
+
export async function handleLayoutLoaderRequest(manifest, serverDir, queryString, headers, res, user) {
|
|
6
14
|
const query = {};
|
|
7
15
|
if (queryString) {
|
|
8
16
|
for (const pair of queryString.split('&')) {
|
|
@@ -18,7 +26,7 @@ export async function handleLayoutLoaderRequest(manifest, serverDir, queryString
|
|
|
18
26
|
res.end(JSON.stringify({ __nk_no_loader: true }));
|
|
19
27
|
return;
|
|
20
28
|
}
|
|
21
|
-
const modulePath =
|
|
29
|
+
const modulePath = resolveModulePath(serverDir, layout.module);
|
|
22
30
|
if (!fs.existsSync(modulePath)) {
|
|
23
31
|
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
24
32
|
res.end(JSON.stringify({ __nk_no_loader: true }));
|
|
@@ -34,7 +42,7 @@ export async function handleLayoutLoaderRequest(manifest, serverDir, queryString
|
|
|
34
42
|
// Parse locale from query for layout loader
|
|
35
43
|
const locale = query.__locale;
|
|
36
44
|
delete query.__locale;
|
|
37
|
-
const result = await mod.loader({ params: {}, query: {}, url: `/__layout/${dir}`, headers, locale });
|
|
45
|
+
const result = await mod.loader({ params: {}, query: {}, url: `/__layout/${dir}`, headers, locale, user: user ?? null });
|
|
38
46
|
if (isRedirectResponse(result)) {
|
|
39
47
|
res.writeHead(result.status || 302, { Location: result.location });
|
|
40
48
|
res.end();
|
|
@@ -49,14 +57,14 @@ export async function handleLayoutLoaderRequest(manifest, serverDir, queryString
|
|
|
49
57
|
res.end();
|
|
50
58
|
return;
|
|
51
59
|
}
|
|
52
|
-
|
|
60
|
+
logger.error(`Layout loader error`, { dir, error: err?.message });
|
|
53
61
|
const status = err?.status || 500;
|
|
54
|
-
const message = err?.message || 'Layout loader failed';
|
|
62
|
+
const message = status < 500 ? (err?.message || 'Layout loader failed') : 'Internal server error';
|
|
55
63
|
res.writeHead(status, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
56
64
|
res.end(JSON.stringify({ error: message }));
|
|
57
65
|
}
|
|
58
66
|
}
|
|
59
|
-
export async function handleLayoutSubscribeRequest(manifest, serverDir, queryString, headers, res) {
|
|
67
|
+
export async function handleLayoutSubscribeRequest(manifest, serverDir, queryString, headers, res, user) {
|
|
60
68
|
const query = {};
|
|
61
69
|
if (queryString) {
|
|
62
70
|
for (const pair of queryString.split('&')) {
|
|
@@ -71,7 +79,7 @@ export async function handleLayoutSubscribeRequest(manifest, serverDir, queryStr
|
|
|
71
79
|
res.end();
|
|
72
80
|
return;
|
|
73
81
|
}
|
|
74
|
-
const modulePath =
|
|
82
|
+
const modulePath = resolveModulePath(serverDir, layout.module);
|
|
75
83
|
if (!fs.existsSync(modulePath)) {
|
|
76
84
|
res.writeHead(204);
|
|
77
85
|
res.end();
|
|
@@ -93,21 +101,21 @@ export async function handleLayoutSubscribeRequest(manifest, serverDir, queryStr
|
|
|
93
101
|
const push = (data) => {
|
|
94
102
|
res.write(`data: ${JSON.stringify(data)}\n\n`);
|
|
95
103
|
};
|
|
96
|
-
const cleanup = mod.subscribe({ params: {}, push, headers, locale });
|
|
104
|
+
const cleanup = mod.subscribe({ params: {}, push, headers, locale, user: user ?? null });
|
|
97
105
|
res.on('close', () => {
|
|
98
106
|
if (typeof cleanup === 'function')
|
|
99
107
|
cleanup();
|
|
100
108
|
});
|
|
101
109
|
}
|
|
102
110
|
catch (err) {
|
|
103
|
-
|
|
111
|
+
logger.error(`Layout subscribe error`, { dir, error: err?.message });
|
|
104
112
|
if (!res.headersSent) {
|
|
105
113
|
res.writeHead(500);
|
|
106
114
|
res.end();
|
|
107
115
|
}
|
|
108
116
|
}
|
|
109
117
|
}
|
|
110
|
-
export async function handleSubscribeRequest(manifest, serverDir, pagesDir, pathname, queryString, headers, res) {
|
|
118
|
+
export async function handleSubscribeRequest(manifest, serverDir, pagesDir, pathname, queryString, headers, res, user) {
|
|
111
119
|
const pagePath = pathname.replace('/__nk_subscribe', '') || '/';
|
|
112
120
|
const query = {};
|
|
113
121
|
if (queryString) {
|
|
@@ -130,7 +138,7 @@ export async function handleSubscribeRequest(manifest, serverDir, pagesDir, path
|
|
|
130
138
|
res.end();
|
|
131
139
|
return;
|
|
132
140
|
}
|
|
133
|
-
const modulePath =
|
|
141
|
+
const modulePath = resolveModulePath(serverDir, matched.route.module);
|
|
134
142
|
if (!fs.existsSync(modulePath)) {
|
|
135
143
|
res.writeHead(204);
|
|
136
144
|
res.end();
|
|
@@ -152,21 +160,21 @@ export async function handleSubscribeRequest(manifest, serverDir, pagesDir, path
|
|
|
152
160
|
const push = (data) => {
|
|
153
161
|
res.write(`data: ${JSON.stringify(data)}\n\n`);
|
|
154
162
|
};
|
|
155
|
-
const cleanup = mod.subscribe({ params: matched.params, push, headers, locale });
|
|
163
|
+
const cleanup = mod.subscribe({ params: matched.params, push, headers, locale, user: user ?? null });
|
|
156
164
|
res.on('close', () => {
|
|
157
165
|
if (typeof cleanup === 'function')
|
|
158
166
|
cleanup();
|
|
159
167
|
});
|
|
160
168
|
}
|
|
161
169
|
catch (err) {
|
|
162
|
-
|
|
170
|
+
logger.error(`Subscribe error`, { pagePath, error: err?.message });
|
|
163
171
|
if (!res.headersSent) {
|
|
164
172
|
res.writeHead(500);
|
|
165
173
|
res.end();
|
|
166
174
|
}
|
|
167
175
|
}
|
|
168
176
|
}
|
|
169
|
-
export async function handleLoaderRequest(manifest, serverDir, pagesDir, pathname, queryString, headers, res) {
|
|
177
|
+
export async function handleLoaderRequest(manifest, serverDir, pagesDir, pathname, queryString, headers, res, user) {
|
|
170
178
|
const pagePath = pathname.replace('/__nk_loader', '') || '/';
|
|
171
179
|
// Parse query params
|
|
172
180
|
const query = {};
|
|
@@ -191,7 +199,7 @@ export async function handleLoaderRequest(manifest, serverDir, pagesDir, pathnam
|
|
|
191
199
|
res.end(JSON.stringify({ __nk_no_loader: true }));
|
|
192
200
|
return;
|
|
193
201
|
}
|
|
194
|
-
const modulePath =
|
|
202
|
+
const modulePath = resolveModulePath(serverDir, matched.route.module);
|
|
195
203
|
if (!fs.existsSync(modulePath)) {
|
|
196
204
|
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
197
205
|
res.end(JSON.stringify({ __nk_no_loader: true }));
|
|
@@ -206,7 +214,7 @@ export async function handleLoaderRequest(manifest, serverDir, pagesDir, pathnam
|
|
|
206
214
|
}
|
|
207
215
|
const locale = query.__locale;
|
|
208
216
|
delete query.__locale;
|
|
209
|
-
const result = await mod.loader({ params: matched.params, query, url: pagePath, headers, locale });
|
|
217
|
+
const result = await mod.loader({ params: matched.params, query, url: pagePath, headers, locale, user: user ?? null });
|
|
210
218
|
if (isRedirectResponse(result)) {
|
|
211
219
|
res.writeHead(result.status || 302, { Location: result.location });
|
|
212
220
|
res.end();
|
|
@@ -221,9 +229,9 @@ export async function handleLoaderRequest(manifest, serverDir, pagesDir, pathnam
|
|
|
221
229
|
res.end();
|
|
222
230
|
return;
|
|
223
231
|
}
|
|
224
|
-
|
|
232
|
+
logger.error(`Loader error`, { pagePath, error: err?.message });
|
|
225
233
|
const status = err?.status || 500;
|
|
226
|
-
const message = err?.message || 'Loader failed';
|
|
234
|
+
const message = status < 500 ? (err?.message || 'Loader failed') : 'Internal server error';
|
|
227
235
|
res.writeHead(status, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
228
236
|
res.end(JSON.stringify({ error: message }));
|
|
229
237
|
}
|