@platformatic/next 3.31.0 → 3.32.0-alpha.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/config.d.ts CHANGED
@@ -293,6 +293,18 @@ export interface PlatformaticNextJsConfig {
293
293
  maxSize?: number;
294
294
  maxEntrySize?: number;
295
295
  maxCount?: number;
296
+ /**
297
+ * Whitelist of origins to cache. Supports exact strings and regex patterns (e.g., "/https:\\/\\/.*\\.example\\.com/").
298
+ */
299
+ origins?: string[];
300
+ /**
301
+ * Default cache duration in seconds for responses without explicit expiration headers.
302
+ */
303
+ cacheByDefault?: number;
304
+ /**
305
+ * Cache type. "shared" caches may be shared between users, "private" caches are user-specific.
306
+ */
307
+ type?: "shared" | "private";
296
308
  [k: string]: unknown;
297
309
  };
298
310
  watch?: boolean | string;
package/lib/capability.js CHANGED
@@ -13,6 +13,7 @@ import { ChildProcess } from 'node:child_process'
13
13
  import { once } from 'node:events'
14
14
  import { existsSync } from 'node:fs'
15
15
  import { glob, readFile, writeFile } from 'node:fs/promises'
16
+ import { createRequire } from 'node:module'
16
17
  import { dirname, resolve as resolvePath, sep } from 'node:path'
17
18
  import { fileURLToPath } from 'node:url'
18
19
  import { parse, satisfies } from 'semver'
@@ -32,6 +33,7 @@ export class NextCapability extends BaseCapability {
32
33
  #child
33
34
  #server
34
35
  #configModified
36
+ #isStandalone
35
37
 
36
38
  constructor (root, config, context) {
37
39
  super('next', version, root, config, context)
@@ -42,6 +44,20 @@ export class NextCapability extends BaseCapability {
42
44
  async init () {
43
45
  await super.init()
44
46
 
47
+ if (this.isProduction) {
48
+ try {
49
+ const buildInfo = JSON.parse(await readFile(resolvePath(this.root, '.platformatic-build.json'), 'utf-8'))
50
+
51
+ if (buildInfo.standalone) {
52
+ this.#isStandalone = true
53
+ this.#nextVersion = parse(buildInfo.version)
54
+ }
55
+ return
56
+ } catch (error) {
57
+ // No-op
58
+ }
59
+ }
60
+
45
61
  // This is needed to avoid Next.js to throw an error when the lockfile is not correct
46
62
  // and the user is using npm but has pnpm in its $PATH.
47
63
  //
@@ -253,11 +269,10 @@ export class NextCapability extends BaseCapability {
253
269
  this.#getChildManagerScripts()
254
270
  )
255
271
 
256
- this.verifyOutputDirectory(resolvePath(this.root, '.next'))
257
-
258
- if (existsSync(resolvePath(this.root, '.next/standalone'))) {
272
+ if (this.#isStandalone) {
259
273
  return this.#startProductionStandaloneNext()
260
274
  } else {
275
+ this.verifyOutputDirectory(resolvePath(this.root, '.next'))
261
276
  return this.#startProductionNext()
262
277
  }
263
278
  }
@@ -300,19 +315,17 @@ export class NextCapability extends BaseCapability {
300
315
  }
301
316
 
302
317
  async #startProductionStandaloneNext () {
303
- const rootDir = resolvePath(this.root, '.next', 'standalone')
304
-
305
318
  // If built in standalone mode, the generated standalone directory is not on the root of the project but somewhere
306
319
  // inside .next/standalone due to turbopack limitations in determining the root of the project.
307
320
  // In that case we search a server.js next to a .next folder inside the .next /standalone folder.
308
321
  const serverEntrypoints = await Array.fromAsync(
309
- glob(['**/server.js'], { cwd: rootDir, ignore: ['node_modules', '**/node_modules/**'] })
322
+ glob(['**/server.js'], { cwd: this.root, ignore: ['node_modules', '**/node_modules/**'] })
310
323
  )
311
324
 
312
325
  let serverEntrypoint
313
326
  for (const entrypoint of serverEntrypoints) {
314
- if (existsSync(resolvePath(rootDir, dirname(entrypoint), '.next'))) {
315
- serverEntrypoint = resolvePath(rootDir, entrypoint)
327
+ if (existsSync(resolvePath(this.root, dirname(entrypoint), '.next'))) {
328
+ serverEntrypoint = resolvePath(this.root, entrypoint)
316
329
  break
317
330
  }
318
331
  }
@@ -370,7 +383,9 @@ export class NextCapability extends BaseCapability {
370
383
 
371
384
  // This is needed by Next.js standalone server to pick up the correct configuration
372
385
  process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
373
- const { startServer } = await importFile(resolvePath(this.#next, './dist/server/lib/start-server.js'))
386
+ const require = createRequire(serverEntrypoint)
387
+ const serverModule = require('next/dist/server/lib/start-server.js')
388
+ const { startServer } = serverModule.default ?? serverModule
374
389
 
375
390
  await startServer({
376
391
  dir: dirname(serverEntrypoint),
@@ -450,6 +465,16 @@ export class NextCapability extends BaseCapability {
450
465
  await writeFile(requiredServerFilesPath, JSON.stringify(requiredServerFiles, null, 2))
451
466
  }
452
467
  }
468
+
469
+ // This is needed to allow to have a standalone server working correctly
470
+ if (existsSync(resolvePath(distDir, 'standalone'))) {
471
+ await writeFile(
472
+ resolvePath(distDir, 'standalone/.platformatic-build.json'),
473
+ JSON.stringify({ standalone: true, version: this.#nextVersion.version }),
474
+ 'utf-8'
475
+ )
476
+ }
477
+
453
478
  return distDir
454
479
  }
455
480
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/next",
3
- "version": "3.31.0",
3
+ "version": "3.32.0-alpha.1",
4
4
  "description": "Platformatic Next.js Capability",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -23,8 +23,8 @@
23
23
  "iovalkey": "^0.3.0",
24
24
  "msgpackr": "^1.11.2",
25
25
  "semver": "^7.6.3",
26
- "@platformatic/basic": "3.31.0",
27
- "@platformatic/foundation": "3.31.0"
26
+ "@platformatic/basic": "3.32.0-alpha.1",
27
+ "@platformatic/foundation": "3.32.0-alpha.1"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@fastify/reply-from": "^12.0.0",
@@ -40,8 +40,8 @@
40
40
  "next": "^16.0.0",
41
41
  "typescript": "^5.5.4",
42
42
  "ws": "^8.18.0",
43
- "@platformatic/gateway": "3.31.0",
44
- "@platformatic/service": "3.31.0"
43
+ "@platformatic/gateway": "3.32.0-alpha.1",
44
+ "@platformatic/service": "3.32.0-alpha.1"
45
45
  },
46
46
  "engines": {
47
47
  "node": ">=22.19.0"
package/schema.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://schemas.platformatic.dev/@platformatic/next/3.31.0.json",
2
+ "$id": "https://schemas.platformatic.dev/@platformatic/next/3.32.0-alpha.1.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "title": "Platformatic Next.js Config",
5
5
  "type": "object",
@@ -1363,6 +1363,26 @@
1363
1363
  },
1364
1364
  "maxCount": {
1365
1365
  "type": "integer"
1366
+ },
1367
+ "origins": {
1368
+ "type": "array",
1369
+ "items": {
1370
+ "type": "string"
1371
+ },
1372
+ "description": "Whitelist of origins to cache. Supports exact strings and regex patterns (e.g., \"/https:\\\\/\\\\/.*\\\\.example\\\\.com/\")."
1373
+ },
1374
+ "cacheByDefault": {
1375
+ "type": "integer",
1376
+ "description": "Default cache duration in seconds for responses without explicit expiration headers."
1377
+ },
1378
+ "type": {
1379
+ "type": "string",
1380
+ "enum": [
1381
+ "shared",
1382
+ "private"
1383
+ ],
1384
+ "default": "shared",
1385
+ "description": "Cache type. \"shared\" caches may be shared between users, \"private\" caches are user-specific."
1366
1386
  }
1367
1387
  }
1368
1388
  }