@ossy/platform 1.38.3 → 1.38.5

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.
Files changed (2) hide show
  1. package/package.json +9 -9
  2. package/src/server.js +19 -33
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ossy/platform",
3
- "version": "1.38.3",
3
+ "version": "1.38.5",
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.7.3",
42
- "@ossy/observability": "^1.7.3",
43
- "@ossy/policies": "^1.12.3",
44
- "@ossy/router": "^1.39.3",
45
- "@ossy/sdk": "^1.39.3",
46
- "@ossy/tokens": "^1.12.3",
47
- "@ossy/users": "^1.12.3",
41
+ "@ossy/event-store": "^1.7.5",
42
+ "@ossy/observability": "^1.7.5",
43
+ "@ossy/policies": "^1.12.5",
44
+ "@ossy/router": "^1.39.5",
45
+ "@ossy/sdk": "^1.39.5",
46
+ "@ossy/tokens": "^1.12.5",
47
+ "@ossy/users": "^1.12.5",
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": "501d2273560cb04d668afd32edf448019f3312aa"
65
+ "gitHead": "97d02b0762f2c0461abb1e6753fc3aaad30ee93f"
66
66
  }
package/src/server.js CHANGED
@@ -17,8 +17,6 @@ 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'
21
-
22
20
  const log = createLogger('@ossy/platform')
23
21
 
24
22
  const DEFAULT_PORT = 3000
@@ -111,6 +109,8 @@ export async function startServer (options = {}) {
111
109
 
112
110
  const manifest = loadManifest(buildDir)
113
111
  const config = manifest.config
112
+ const supportedLanguages = Array.isArray(config.supportedLanguages) ? config.supportedLanguages : []
113
+ const defaultLanguage = config.defaultLanguage
114
114
  for (const task of manifest.tasks ?? []) {
115
115
  try {
116
116
  const mod = await import(resolveEntryUrl(task.entry, buildDir))
@@ -179,15 +179,22 @@ export async function startServer (options = {}) {
179
179
  }
180
180
  }
181
181
 
182
- // Layout loading — import each bundled layout module and store the default-
183
- // exported React component in a map keyed by the layout's id. At render
184
- // time we pick the first layout whose `applies` glob matches the page path.
185
- const layoutModuleMap = new Map()
186
- for (const layoutEntry of manifest.layouts ?? []) {
182
+ // Layout loading — one `*.layout.jsx` per app wraps every page render. The
183
+ // layout component decides route-specific chrome (auth, public flows, etc.).
184
+ /** @type {{ component: import('react').ComponentType, entry: string } | null} */
185
+ let appLayout = null
186
+ const layoutManifest = manifest.layouts ?? []
187
+ if (layoutManifest.length > 1) {
188
+ log.warn(
189
+ `Multiple layouts in manifest (${layoutManifest.length}); only the first is used. Use one *.layout.jsx per app.`,
190
+ )
191
+ }
192
+ const layoutEntry = layoutManifest[0]
193
+ if (layoutEntry) {
187
194
  try {
188
195
  const mod = await import(resolveEntryUrl(layoutEntry.entry, buildDir))
189
196
  if (typeof mod.default === 'function') {
190
- layoutModuleMap.set(layoutEntry.id, { component: mod.default, applies: layoutEntry.applies ?? '*' })
197
+ appLayout = { component: mod.default, entry: layoutEntry.entry }
191
198
  }
192
199
  } catch (err) {
193
200
  log.warn(`Failed to load layout "${layoutEntry.id}"`, undefined, err)
@@ -214,26 +221,6 @@ export async function startServer (options = {}) {
214
221
  }
215
222
  }
216
223
 
217
- function findLayoutForPage (pagePathOrPaths) {
218
- if (!layoutModuleMap.size) return null
219
- const paths = typeof pagePathOrPaths === 'string'
220
- ? [pagePathOrPaths]
221
- : Object.values(pagePathOrPaths || {})
222
- // Check specific (non-wildcard) layouts first, then fall back to catch-all '*'.
223
- // This lets e.g. `applies: '/'` override a global `applies: '*'` layout.
224
- let catchAll = null
225
- for (const [, layout] of layoutModuleMap) {
226
- if (layout.applies === '*') {
227
- if (!catchAll) catchAll = layout.component
228
- continue
229
- }
230
- for (const p of paths) {
231
- if (matchesGlob(layout.applies, p)) return layout.component
232
- }
233
- }
234
- return catchAll
235
- }
236
-
237
224
  // Register the SDK so all tasks receive it as `sdk`.
238
225
  // Priority: explicit options.sdk → SDK.of() from env vars → null (direct-DB fallback in tasks).
239
226
  const botSdk = (process.env.API_URL && process.env.OSSY_API_KEY)
@@ -247,9 +234,6 @@ export async function startServer (options = {}) {
247
234
  ChangeStream.start(process.env.DB_URL)
248
235
  }
249
236
 
250
- const supportedLanguages = Array.isArray(config.supportedLanguages) ? config.supportedLanguages : []
251
- const defaultLanguage = config.defaultLanguage
252
-
253
237
  const pageRouter = OssyRouter.of({
254
238
  pages: manifest.pages,
255
239
  supportedLanguages,
@@ -346,7 +330,8 @@ export async function startServer (options = {}) {
346
330
  res.status(503).type('text').send('SSR runtime unavailable')
347
331
  return
348
332
  }
349
- const Layout = findLayoutForPage(pageEntry.path)
333
+ const Layout = appLayout?.component ?? null
334
+ const layoutEntry = appLayout?.entry ?? null
350
335
  const props = {
351
336
  ...config,
352
337
  ...(req.userAppSettings || {}),
@@ -360,7 +345,8 @@ export async function startServer (options = {}) {
360
345
  // Slot component entries are prepended so that layout-level
361
346
  // ComponentSlotsProviders (which merge on top) can override them.
362
347
  componentEntries: [...slotComponentEntries, ...manifest.components],
363
- Layout: Layout ?? null,
348
+ Layout,
349
+ layoutEntry,
364
350
  }
365
351
  const html = await mod.render(props)
366
352
  res.status(200).type('html').send(html)