@ossy/platform 1.36.1 → 1.36.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -9
- package/src/server.js +41 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ossy/platform",
|
|
3
|
-
"version": "1.36.
|
|
3
|
+
"version": "1.36.2",
|
|
4
4
|
"description": "Ossy application server runtime",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -38,13 +38,13 @@
|
|
|
38
38
|
"@aws-sdk/s3-request-presigner": "^3.1057.0",
|
|
39
39
|
"@aws-sdk/util-create-request": "^3.972.26",
|
|
40
40
|
"@aws-sdk/util-format-url": "^3.972.17",
|
|
41
|
-
"@ossy/event-store": "^1.5.
|
|
42
|
-
"@ossy/observability": "^1.5.
|
|
43
|
-
"@ossy/policies": "^1.10.
|
|
44
|
-
"@ossy/router": "^1.37.
|
|
45
|
-
"@ossy/sdk": "^1.37.
|
|
46
|
-
"@ossy/tokens": "^1.10.
|
|
47
|
-
"@ossy/users": "^1.10.
|
|
41
|
+
"@ossy/event-store": "^1.5.2",
|
|
42
|
+
"@ossy/observability": "^1.5.2",
|
|
43
|
+
"@ossy/policies": "^1.10.2",
|
|
44
|
+
"@ossy/router": "^1.37.2",
|
|
45
|
+
"@ossy/sdk": "^1.37.2",
|
|
46
|
+
"@ossy/tokens": "^1.10.2",
|
|
47
|
+
"@ossy/users": "^1.10.2",
|
|
48
48
|
"cookie-parser": "^1.4.7",
|
|
49
49
|
"dotenv": ">=16.0.0 <18.0.0",
|
|
50
50
|
"express": ">=5.0.0 <6.0.0",
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"src",
|
|
63
63
|
"Dockerfile"
|
|
64
64
|
],
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "723d9d35aba3cd43700ecd6e72a7e7de96acff65"
|
|
66
66
|
}
|
package/src/server.js
CHANGED
|
@@ -17,6 +17,7 @@ import { createLogger } from '@ossy/observability'
|
|
|
17
17
|
import { ConfigService } from './config.service.js'
|
|
18
18
|
import { UsersMiddleware } from './users.middleware.js'
|
|
19
19
|
import { WorkspacesMiddleware } from './workspaces.middleware.js'
|
|
20
|
+
import { matchesGlob } from './tasks/glob.js'
|
|
20
21
|
|
|
21
22
|
const log = createLogger('@ossy/platform')
|
|
22
23
|
|
|
@@ -61,8 +62,8 @@ export function loadManifest (buildDir) {
|
|
|
61
62
|
const integrations = Array.isArray(manifest.integrations) ? manifest.integrations : []
|
|
62
63
|
const startups = Array.isArray(manifest.startups) ? manifest.startups : []
|
|
63
64
|
const actions = Array.isArray(manifest.actions) ? manifest.actions : []
|
|
64
|
-
|
|
65
|
-
if ((e.type === 'page' || e.type === 'api') && !validRoutable(e)) {
|
|
65
|
+
const layouts = Array.isArray(manifest.layouts) ? manifest.layouts : []
|
|
66
|
+
for (const e of entries) { if ((e.type === 'page' || e.type === 'api') && !validRoutable(e)) {
|
|
66
67
|
log.warn(`Skipping ${e.type} "${e.id}" — manifest entry has no path.`)
|
|
67
68
|
}
|
|
68
69
|
}
|
|
@@ -77,6 +78,7 @@ export function loadManifest (buildDir) {
|
|
|
77
78
|
integrations,
|
|
78
79
|
startups,
|
|
79
80
|
actions,
|
|
81
|
+
layouts,
|
|
80
82
|
config: manifest.config || {},
|
|
81
83
|
}
|
|
82
84
|
}
|
|
@@ -107,7 +109,6 @@ export async function startServer (options = {}) {
|
|
|
107
109
|
|
|
108
110
|
const manifest = loadManifest(buildDir)
|
|
109
111
|
const config = manifest.config
|
|
110
|
-
|
|
111
112
|
for (const task of manifest.tasks ?? []) {
|
|
112
113
|
try {
|
|
113
114
|
const mod = await import(resolveEntryUrl(task.entry, buildDir))
|
|
@@ -176,6 +177,41 @@ export async function startServer (options = {}) {
|
|
|
176
177
|
}
|
|
177
178
|
}
|
|
178
179
|
|
|
180
|
+
// Layout loading — import each bundled layout module and store the default-
|
|
181
|
+
// exported React component in a map keyed by the layout's id. At render
|
|
182
|
+
// time we pick the first layout whose `applies` glob matches the page path.
|
|
183
|
+
const layoutModuleMap = new Map()
|
|
184
|
+
for (const layoutEntry of manifest.layouts ?? []) {
|
|
185
|
+
try {
|
|
186
|
+
const mod = await import(resolveEntryUrl(layoutEntry.entry, buildDir))
|
|
187
|
+
if (typeof mod.default === 'function') {
|
|
188
|
+
layoutModuleMap.set(layoutEntry.id, { component: mod.default, applies: layoutEntry.applies ?? '*' })
|
|
189
|
+
}
|
|
190
|
+
} catch (err) {
|
|
191
|
+
log.warn(`Failed to load layout "${layoutEntry.id}"`, undefined, err)
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function findLayoutForPage (pagePathOrPaths) {
|
|
196
|
+
if (!layoutModuleMap.size) return null
|
|
197
|
+
const paths = typeof pagePathOrPaths === 'string'
|
|
198
|
+
? [pagePathOrPaths]
|
|
199
|
+
: Object.values(pagePathOrPaths || {})
|
|
200
|
+
// Check specific (non-wildcard) layouts first, then fall back to catch-all '*'.
|
|
201
|
+
// This lets e.g. `applies: '/'` override a global `applies: '*'` layout.
|
|
202
|
+
let catchAll = null
|
|
203
|
+
for (const [, layout] of layoutModuleMap) {
|
|
204
|
+
if (layout.applies === '*') {
|
|
205
|
+
if (!catchAll) catchAll = layout.component
|
|
206
|
+
continue
|
|
207
|
+
}
|
|
208
|
+
for (const p of paths) {
|
|
209
|
+
if (matchesGlob(layout.applies, p)) return layout.component
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return catchAll
|
|
213
|
+
}
|
|
214
|
+
|
|
179
215
|
// Register the SDK so all tasks receive it as `sdk`.
|
|
180
216
|
// Priority: explicit options.sdk → SDK.of() from env vars → null (direct-DB fallback in tasks).
|
|
181
217
|
const botSdk = (process.env.API_URL && process.env.OSSY_API_KEY)
|
|
@@ -288,6 +324,7 @@ export async function startServer (options = {}) {
|
|
|
288
324
|
res.status(503).type('text').send('SSR runtime unavailable')
|
|
289
325
|
return
|
|
290
326
|
}
|
|
327
|
+
const Layout = findLayoutForPage(pageEntry.path)
|
|
291
328
|
const props = {
|
|
292
329
|
...config,
|
|
293
330
|
...(req.userAppSettings || {}),
|
|
@@ -299,6 +336,7 @@ export async function startServer (options = {}) {
|
|
|
299
336
|
pages: manifest.pages.map((page) => ({ id: page.id, path: page.path })),
|
|
300
337
|
pageId: pageRoute.id,
|
|
301
338
|
componentEntries: manifest.components,
|
|
339
|
+
Layout: Layout ?? null,
|
|
302
340
|
}
|
|
303
341
|
const html = await mod.render(props)
|
|
304
342
|
res.status(200).type('html').send(html)
|