@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
|
@@ -11,13 +11,21 @@ import { ssrRenderPage } from './ssr-render.js';
|
|
|
11
11
|
import { readProjectConfig, getLumenJSNodeModules, getLumenJSDirs } from './config.js';
|
|
12
12
|
import { getNuralyUIAliases, resolveNuralyUIPaths } from './nuralyui-aliases.js';
|
|
13
13
|
import { litDedupPlugin } from './plugins/vite-plugin-lit-dedup.js';
|
|
14
|
+
import { autoDefinePlugin } from './plugins/vite-plugin-auto-define.js';
|
|
14
15
|
import { autoImportPlugin } from './plugins/vite-plugin-auto-import.js';
|
|
15
16
|
import { litHmrPlugin } from './plugins/vite-plugin-lit-hmr.js';
|
|
16
17
|
import { sourceAnnotatorPlugin } from './plugins/vite-plugin-source-annotator.js';
|
|
18
|
+
import { editorApiPlugin } from './plugins/vite-plugin-editor-api.js';
|
|
17
19
|
import { virtualModulesPlugin } from './plugins/vite-plugin-virtual-modules.js';
|
|
18
20
|
import { i18nPlugin, loadTranslationsFromDisk } from './plugins/vite-plugin-i18n.js';
|
|
21
|
+
import { authPlugin } from './plugins/vite-plugin-auth.js';
|
|
22
|
+
import { communicationPlugin } from './plugins/vite-plugin-communication.js';
|
|
23
|
+
import { lumenStoragePlugin } from './plugins/vite-plugin-storage.js';
|
|
24
|
+
import { lumenSocketIOPlugin } from './plugins/vite-plugin-socketio.js';
|
|
19
25
|
import { resolveLocale } from './middleware/locale.js';
|
|
20
26
|
import { setProjectDir } from '../db/context.js';
|
|
27
|
+
import { scanMiddleware, getMiddlewareDirsForPathname } from '../build/scan.js';
|
|
28
|
+
import { runMiddlewareChain, extractMiddleware } from '../shared/middleware-runner.js';
|
|
21
29
|
// Re-export for backwards compatibility
|
|
22
30
|
export { readProjectConfig, readProjectTitle, getLumenJSNodeModules, getLumenJSDirs } from './config.js';
|
|
23
31
|
export { getNuralyUIAliases, resolveNuralyUIPaths } from './nuralyui-aliases.js';
|
|
@@ -30,24 +38,37 @@ export function getSharedViteConfig(projectDir, options) {
|
|
|
30
38
|
const isDev = mode === 'development';
|
|
31
39
|
const pagesDir = path.join(projectDir, 'pages');
|
|
32
40
|
const lumenNodeModules = getLumenJSNodeModules();
|
|
33
|
-
const { runtimeDir, editorDir } = getLumenJSDirs();
|
|
41
|
+
const { distDir, runtimeDir, editorDir } = getLumenJSDirs();
|
|
34
42
|
// Resolve NuralyUI paths for aliases (only when nuralyui integration is enabled)
|
|
35
43
|
const aliases = {};
|
|
36
44
|
if (options?.integrations?.includes('nuralyui')) {
|
|
37
45
|
const nuralyUIPaths = resolveNuralyUIPaths(projectDir);
|
|
38
46
|
if (nuralyUIPaths) {
|
|
39
47
|
Object.assign(aliases, getNuralyUIAliases(nuralyUIPaths.componentsPath, nuralyUIPaths.commonPath));
|
|
48
|
+
// Add root aliases for theme CSS imports
|
|
49
|
+
const nuralyUIRoot = path.resolve(nuralyUIPaths.componentsPath, '..');
|
|
50
|
+
aliases['@nuralyui-theme'] = path.join(nuralyUIRoot, 'shared/themes');
|
|
51
|
+
aliases['@nuralyui-common'] = nuralyUIPaths.commonPath;
|
|
40
52
|
}
|
|
41
53
|
}
|
|
42
54
|
const resolve = {
|
|
43
55
|
alias: {
|
|
44
56
|
...aliases,
|
|
45
|
-
// Map @lumenjs/i18n to the physical dist file so Vite resolves it
|
|
46
|
-
// without going through node_modules (it's not an npm package).
|
|
47
57
|
'@lumenjs/i18n': path.join(runtimeDir, 'i18n.js'),
|
|
58
|
+
'@lumenjs/auth': path.join(runtimeDir, 'auth.js'),
|
|
59
|
+
'@nuraly/lumenjs-auth': path.join(runtimeDir, 'auth.js'),
|
|
60
|
+
'@lumenjs/communication': path.join(runtimeDir, 'communication.js'),
|
|
61
|
+
'@lumenjs/webrtc': path.join(runtimeDir, 'webrtc.js'),
|
|
62
|
+
'@lumenjs/db': path.join(distDir, 'db', 'client.js'),
|
|
63
|
+
'@lumenjs/permissions': path.join(distDir, 'permissions', 'index.js'),
|
|
64
|
+
'@lumenjs/storage': path.join(distDir, 'storage', 'index.js'),
|
|
65
|
+
'@nuraly/lumenjs': path.resolve(distDir, '..'),
|
|
48
66
|
},
|
|
49
67
|
conditions: isDev ? ['development', 'browser'] : ['browser'],
|
|
50
|
-
|
|
68
|
+
// Note: resolve.dedupe is NOT used — it resolves via Node's algorithm
|
|
69
|
+
// which ignores Vite's resolve.conditions, picking the `default` export
|
|
70
|
+
// (prod proxy) instead of `development`. The litDedupPlugin handles
|
|
71
|
+
// single-copy resolution with correct conditions instead.
|
|
51
72
|
};
|
|
52
73
|
const esbuild = {
|
|
53
74
|
tsconfigRaw: {
|
|
@@ -60,6 +81,7 @@ export function getSharedViteConfig(projectDir, options) {
|
|
|
60
81
|
const plugins = [
|
|
61
82
|
lumenRoutesPlugin(pagesDir),
|
|
62
83
|
lumenLoadersPlugin(pagesDir),
|
|
84
|
+
autoDefinePlugin(pagesDir),
|
|
63
85
|
litDedupPlugin(lumenNodeModules, isDev),
|
|
64
86
|
virtualModulesPlugin(runtimeDir, editorDir),
|
|
65
87
|
];
|
|
@@ -83,15 +105,41 @@ export function getSharedViteConfig(projectDir, options) {
|
|
|
83
105
|
}
|
|
84
106
|
export async function createDevServer(options) {
|
|
85
107
|
const { projectDir, port, editorMode = false, base = '/' } = options;
|
|
86
|
-
setProjectDir(projectDir);
|
|
87
108
|
const pagesDir = path.join(projectDir, 'pages');
|
|
88
109
|
const apiDir = path.join(projectDir, 'api');
|
|
89
110
|
const publicDir = path.join(projectDir, 'public');
|
|
90
111
|
const config = readProjectConfig(projectDir);
|
|
91
|
-
const { title, integrations, i18n: i18nConfig } = config;
|
|
112
|
+
const { title, integrations, i18n: i18nConfig, prefetch: prefetchStrategy } = config;
|
|
113
|
+
// Read optional head.html for blocking scripts (e.g. theme initialization)
|
|
114
|
+
const headHtmlPath = path.join(projectDir, 'head.html');
|
|
115
|
+
const headContent = fs.existsSync(headHtmlPath) ? fs.readFileSync(headHtmlPath, 'utf-8') : undefined;
|
|
116
|
+
// Set project dir for DB context (used by loaders, API routes, plugins)
|
|
117
|
+
setProjectDir(projectDir);
|
|
118
|
+
process.env.LUMENJS_PROJECT_DIR = projectDir;
|
|
92
119
|
const shared = getSharedViteConfig(projectDir, { integrations });
|
|
120
|
+
// Load user-defined Vite plugins from lumenjs.plugins.js (if present).
|
|
121
|
+
// This allows apps to add custom Vite plugins (e.g. proxy middleware)
|
|
122
|
+
// that run at the raw Connect level, before LumenJS's own middleware.
|
|
123
|
+
let userPlugins = [];
|
|
124
|
+
const pluginsPath = path.join(projectDir, 'lumenjs.plugins.js');
|
|
125
|
+
if (fs.existsSync(pluginsPath)) {
|
|
126
|
+
try {
|
|
127
|
+
// Use a temporary Vite server to load the TS file via ssrLoadModule
|
|
128
|
+
// would be circular, so we import it directly via dynamic import
|
|
129
|
+
// after Vite transforms it. Instead, read and eval the JS-compatible parts.
|
|
130
|
+
// Simplest: the file exports an array of plugin objects.
|
|
131
|
+
const pluginsMod = await import(pathToFileURL(pluginsPath).href);
|
|
132
|
+
const exported = pluginsMod.default || pluginsMod.plugins || pluginsMod;
|
|
133
|
+
if (Array.isArray(exported))
|
|
134
|
+
userPlugins = exported;
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
console.warn(`[LumenJS] Failed to load lumenjs.plugins.js:`, err?.message);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
93
140
|
const server = await createViteServer({
|
|
94
141
|
root: projectDir,
|
|
142
|
+
base,
|
|
95
143
|
publicDir: fs.existsSync(publicDir) ? publicDir : undefined,
|
|
96
144
|
server: {
|
|
97
145
|
port,
|
|
@@ -99,93 +147,217 @@ export async function createDevServer(options) {
|
|
|
99
147
|
strictPort: false,
|
|
100
148
|
allowedHosts: true,
|
|
101
149
|
cors: true,
|
|
102
|
-
hmr:
|
|
150
|
+
hmr: process.env.HMR_CLIENT_PORT ? {
|
|
151
|
+
clientPort: parseInt(process.env.HMR_CLIENT_PORT),
|
|
152
|
+
port: parseInt(process.env.HMR_CLIENT_PORT),
|
|
153
|
+
...(process.env.HMR_PROTOCOL ? { protocol: process.env.HMR_PROTOCOL } : {}),
|
|
154
|
+
...(process.env.HMR_HOST ? { host: process.env.HMR_HOST } : {}),
|
|
155
|
+
} : true,
|
|
156
|
+
fs: {
|
|
157
|
+
allow: [projectDir, getLumenJSNodeModules(), path.resolve(getLumenJSNodeModules(), '..')],
|
|
158
|
+
},
|
|
103
159
|
},
|
|
104
160
|
resolve: shared.resolve,
|
|
161
|
+
// 'custom' prevents Vite from adding SPA fallback and indexHtml middleware,
|
|
162
|
+
// which would interfere with LumenJS's own HTML handler (especially when base != '/')
|
|
163
|
+
appType: 'custom',
|
|
105
164
|
plugins: [
|
|
165
|
+
...userPlugins,
|
|
166
|
+
...(integrations.includes('auth') ? [authPlugin(projectDir)] : []),
|
|
106
167
|
...shared.plugins,
|
|
168
|
+
...(integrations.includes('communication') ? [communicationPlugin(projectDir)] : []),
|
|
169
|
+
lumenStoragePlugin(projectDir),
|
|
107
170
|
lumenApiRoutesPlugin(apiDir, projectDir),
|
|
108
171
|
litHmrPlugin(projectDir),
|
|
109
172
|
...(i18nConfig ? [i18nPlugin(projectDir, i18nConfig)] : []),
|
|
110
|
-
...(editorMode ? [sourceAnnotatorPlugin(projectDir)] : []),
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
173
|
+
...(editorMode ? [sourceAnnotatorPlugin(projectDir), editorApiPlugin(projectDir)] : []),
|
|
174
|
+
lumenSocketIOPlugin(pagesDir),
|
|
175
|
+
...(base !== '/' ? [{
|
|
176
|
+
// Fix HMR fetch URLs when Vite runs behind a base path.
|
|
177
|
+
// Vite's import analysis injects createHotContext() with the full filesystem
|
|
178
|
+
// path (e.g. /data/user-apps/.../bb2/pages/index.ts) instead of root-relative.
|
|
179
|
+
// When @vite/client fetches the updated module it builds the URL as
|
|
180
|
+
// base + filesystemPath.slice(1) → /__app_dev/{id}/data/.../pages/index.ts
|
|
181
|
+
// which 404s because transformMiddleware resolves relative to root, doubling
|
|
182
|
+
// the path. This pre-hook middleware strips the projectDir prefix so
|
|
183
|
+
// baseMiddleware sees the correct root-relative path.
|
|
184
|
+
name: 'lumenjs-hmr-path-fix',
|
|
185
|
+
configureServer(server) {
|
|
186
|
+
const projSlash = projectDir.replace(/\\/g, '/');
|
|
187
|
+
server.middlewares.use((req, _res, next) => {
|
|
188
|
+
if (req.url) {
|
|
189
|
+
const prefix = base + projSlash.slice(1) + '/';
|
|
190
|
+
if (req.url.startsWith(prefix)) {
|
|
191
|
+
req.url = base + req.url.slice(prefix.length);
|
|
192
|
+
}
|
|
119
193
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
194
|
+
next();
|
|
195
|
+
});
|
|
196
|
+
},
|
|
197
|
+
}] : []),
|
|
198
|
+
{
|
|
199
|
+
// Clear SSR module cache on file changes so the next SSR request uses fresh code.
|
|
200
|
+
// Without this, HMR updates the client but SSR keeps serving stale modules.
|
|
201
|
+
name: 'lumenjs-ssr-invalidate-on-change',
|
|
202
|
+
handleHotUpdate({ file, server }) {
|
|
203
|
+
const mods = server.moduleGraph.getModulesByFile(file);
|
|
204
|
+
if (mods) {
|
|
205
|
+
for (const m of mods) {
|
|
206
|
+
m.ssrModule = null;
|
|
207
|
+
m.ssrTransformResult = null;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
name: 'lumenjs-user-middleware',
|
|
214
|
+
config(config) {
|
|
215
|
+
const entries = scanMiddleware(pagesDir);
|
|
216
|
+
if (entries.length === 0)
|
|
217
|
+
return;
|
|
218
|
+
const npmDeps = new Set();
|
|
219
|
+
for (const entry of entries) {
|
|
220
|
+
try {
|
|
221
|
+
const content = fs.readFileSync(entry.filePath, 'utf-8');
|
|
222
|
+
const importMatches = content.matchAll(/(?:import|require)\s*(?:\(?\s*['"]([^./][^'"]*)['"]\s*\)?|.*from\s*['"]([^./][^'"]*)['"]\s*)/g);
|
|
223
|
+
for (const m of importMatches) {
|
|
224
|
+
const pkg = m[1] || m[2];
|
|
225
|
+
if (pkg) {
|
|
226
|
+
const pkgName = pkg.startsWith('@') ? pkg.split('/').slice(0, 2).join('/') : pkg.split('/')[0];
|
|
227
|
+
npmDeps.add(pkgName);
|
|
228
|
+
}
|
|
124
229
|
}
|
|
125
230
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
231
|
+
catch { }
|
|
232
|
+
}
|
|
233
|
+
if (npmDeps.size > 0) {
|
|
234
|
+
const existing = config.ssr?.external || [];
|
|
235
|
+
return { ssr: { external: [...existing, ...npmDeps] } };
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
configureServer(server) {
|
|
239
|
+
return () => {
|
|
240
|
+
server.middlewares.use(async (req, res, next) => {
|
|
241
|
+
const pathname = (req.url || '/').split('?')[0];
|
|
242
|
+
if (pathname.startsWith('/@') || pathname.startsWith('/node_modules') || pathname.includes('.')) {
|
|
243
|
+
return next();
|
|
139
244
|
}
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
245
|
+
const middlewareEntries = scanMiddleware(pagesDir);
|
|
246
|
+
if (middlewareEntries.length === 0)
|
|
247
|
+
return next();
|
|
248
|
+
const matchingDirs = getMiddlewareDirsForPathname(pathname, middlewareEntries);
|
|
249
|
+
if (matchingDirs.length === 0)
|
|
250
|
+
return next();
|
|
251
|
+
const allMw = [];
|
|
252
|
+
for (const entry of matchingDirs) {
|
|
253
|
+
try {
|
|
254
|
+
const mod = await server.ssrLoadModule(entry.filePath);
|
|
255
|
+
allMw.push(...extractMiddleware(mod));
|
|
256
|
+
}
|
|
257
|
+
catch (err) {
|
|
258
|
+
console.error(`[LumenJS] Failed to load _middleware.ts (${entry.dir || 'root'}):`, err);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (allMw.length === 0)
|
|
262
|
+
return next();
|
|
263
|
+
runMiddlewareChain(allMw, req, res, next);
|
|
264
|
+
});
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
name: 'lumenjs-index-html',
|
|
270
|
+
configureServer(server) {
|
|
271
|
+
return () => {
|
|
272
|
+
server.middlewares.use((req, res, next) => {
|
|
273
|
+
// Guard against malformed percent-encoded URLs that crash Vite's transformIndexHtml
|
|
274
|
+
if (req.url) {
|
|
275
|
+
try {
|
|
276
|
+
decodeURIComponent(req.url);
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
res.statusCode = 400;
|
|
280
|
+
res.end('Bad Request');
|
|
145
281
|
return;
|
|
146
282
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
283
|
+
}
|
|
284
|
+
if (req.url && !req.url.startsWith('/@') && !req.url.startsWith('/node_modules') &&
|
|
285
|
+
!req.url.startsWith('/api/') && !req.url.startsWith('/__nk_loader/') &&
|
|
286
|
+
!req.url.startsWith('/__nk_i18n/') &&
|
|
287
|
+
!req.url.includes('.') && req.method === 'GET') {
|
|
288
|
+
let pathname = req.url.split('?')[0];
|
|
289
|
+
// Resolve locale from URL/cookie/header
|
|
290
|
+
let locale;
|
|
291
|
+
let translations;
|
|
292
|
+
if (i18nConfig) {
|
|
293
|
+
const localeResult = resolveLocale(pathname, i18nConfig, req.headers);
|
|
294
|
+
locale = localeResult.locale;
|
|
295
|
+
pathname = localeResult.pathname;
|
|
296
|
+
translations = loadTranslationsFromDisk(projectDir, locale);
|
|
297
|
+
}
|
|
298
|
+
const SSR_PLACEHOLDER = '<!--__NK_SSR_CONTENT__-->';
|
|
299
|
+
ssrRenderPage(server, pagesDir, pathname, req.headers, locale, req.nkAuth?.user ?? undefined).then(async (ssrResult) => {
|
|
300
|
+
if (ssrResult?.redirect) {
|
|
301
|
+
res.writeHead(ssrResult.redirect.status, { Location: ssrResult.redirect.location });
|
|
302
|
+
res.end();
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const shellHtml = generateIndexHtml({
|
|
306
|
+
title,
|
|
307
|
+
editorMode,
|
|
308
|
+
ssrContent: ssrResult ? SSR_PLACEHOLDER : undefined,
|
|
309
|
+
loaderData: ssrResult?.loaderData,
|
|
310
|
+
layoutsData: ssrResult?.layoutsData,
|
|
311
|
+
integrations,
|
|
312
|
+
locale,
|
|
313
|
+
i18nConfig: i18nConfig || undefined,
|
|
314
|
+
translations,
|
|
315
|
+
prefetch: prefetchStrategy,
|
|
316
|
+
authUser: ssrResult?.authUser ?? req.nkAuth?.user ?? undefined,
|
|
317
|
+
headContent,
|
|
318
|
+
base,
|
|
319
|
+
});
|
|
320
|
+
const transformed = await server.transformIndexHtml(req.url, shellHtml);
|
|
321
|
+
const finalHtml = ssrResult
|
|
322
|
+
? transformed.replace(SSR_PLACEHOLDER, ssrResult.html)
|
|
323
|
+
: transformed;
|
|
169
324
|
res.setHeader('Content-Type', 'text/html');
|
|
170
325
|
res.setHeader('Cache-Control', 'no-store');
|
|
171
|
-
res.end(
|
|
172
|
-
}).catch(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
326
|
+
res.end(finalHtml);
|
|
327
|
+
}).catch(err => {
|
|
328
|
+
console.error('[LumenJS] SSR/HTML generation error:', err);
|
|
329
|
+
const html = generateIndexHtml({ title, editorMode, integrations, locale, i18nConfig: i18nConfig || undefined, translations, prefetch: prefetchStrategy, headContent, base });
|
|
330
|
+
server.transformIndexHtml(req.url, html).then(transformed => {
|
|
331
|
+
res.setHeader('Content-Type', 'text/html');
|
|
332
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
333
|
+
res.end(transformed);
|
|
334
|
+
}).catch(next);
|
|
335
|
+
});
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
next();
|
|
339
|
+
});
|
|
340
|
+
};
|
|
178
341
|
}
|
|
179
342
|
}
|
|
180
343
|
],
|
|
181
344
|
esbuild: shared.esbuild,
|
|
182
345
|
optimizeDeps: {
|
|
183
|
-
|
|
184
|
-
|
|
346
|
+
exclude: [
|
|
347
|
+
'@lumenjs/i18n',
|
|
348
|
+
'@nuraly/lumenjs-auth',
|
|
349
|
+
// Lit packages must NOT be pre-bundled — pre-bundling creates separate
|
|
350
|
+
// module entries (/.vite/deps/) alongside raw /@fs/ files, causing
|
|
351
|
+
// multiple lit-html instances. Instead, resolve.dedupe forces all lit
|
|
352
|
+
// imports to a single copy. The project's lit version MUST match
|
|
353
|
+
// lumenjs's lit version for dedupe to work.
|
|
354
|
+
'lit', 'lit-html', 'lit-element', '@lit/reactive-element',
|
|
355
|
+
'@lit-labs/ssr-client',
|
|
356
|
+
],
|
|
185
357
|
},
|
|
186
358
|
ssr: {
|
|
187
359
|
noExternal: true,
|
|
188
|
-
external: ['node-domexception'],
|
|
360
|
+
external: ['node-domexception', 'socket.io-client', 'xmlhttprequest-ssl', 'engine.io-client', 'better-sqlite3', '@lumenjs/db', '@lumenjs/permissions', 'amqplib'],
|
|
189
361
|
resolve: {
|
|
190
362
|
conditions: ['node', 'import'],
|
|
191
363
|
},
|
|
@@ -9,7 +9,7 @@ export interface LayoutSSRData {
|
|
|
9
9
|
*
|
|
10
10
|
* Returns pre-rendered HTML and loader data, or null on failure (falls back to CSR).
|
|
11
11
|
*/
|
|
12
|
-
export declare function ssrRenderPage(server: ViteDevServer, pagesDir: string, pathname: string, headers?: Record<string, string | string[] | undefined>, locale?: string): Promise<{
|
|
12
|
+
export declare function ssrRenderPage(server: ViteDevServer, pagesDir: string, pathname: string, headers?: Record<string, string | string[] | undefined>, locale?: string, user?: any): Promise<{
|
|
13
13
|
html: string;
|
|
14
14
|
loaderData: any;
|
|
15
15
|
layoutsData?: LayoutSSRData[];
|
|
@@ -17,4 +17,5 @@ export declare function ssrRenderPage(server: ViteDevServer, pagesDir: string, p
|
|
|
17
17
|
location: string;
|
|
18
18
|
status: number;
|
|
19
19
|
};
|
|
20
|
+
authUser?: any;
|
|
20
21
|
} | null>;
|