@platformatic/next 3.32.0 → 3.33.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
@@ -619,6 +619,7 @@ export interface PlatformaticNextJsConfig {
619
619
  };
620
620
  };
621
621
  next?: {
622
+ standalone?: boolean;
622
623
  trailingSlash?: boolean;
623
624
  useExperimentalAdapter?: boolean;
624
625
  };
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,30 +44,12 @@ export class NextCapability extends BaseCapability {
42
44
  async init () {
43
45
  await super.init()
44
46
 
45
- // This is needed to avoid Next.js to throw an error when the lockfile is not correct
46
- // and the user is using npm but has pnpm in its $PATH.
47
- //
48
- // See: https://github.com/platformatic/composer-next-node-fastify/pull/3
49
- //
50
- // PS by Paolo: Sob.
51
- process.env.NEXT_IGNORE_INCORRECT_LOCKFILE = 'true'
52
-
53
- this.#next = resolvePath(dirname(await resolvePackageViaCJS(this.root, 'next')), '../..')
54
- const nextPackage = JSON.parse(await readFile(resolvePath(this.#next, 'package.json'), 'utf-8'))
55
- this.#nextVersion = parse(nextPackage.version)
56
-
57
- if (this.#nextVersion.major < 15 || (this.#nextVersion.major <= 15 && this.#nextVersion.minor < 1)) {
58
- await import('./create-context-patch.js')
47
+ if (this.isProduction && this.config.next?.standalone) {
48
+ this.#isStandalone = true
49
+ return
59
50
  }
60
51
 
61
- if (this.#nextVersion.major < 16 && this.config.next?.useExperimentalAdapter === true) {
62
- this.config.next.useExperimentalAdapter = false
63
- }
64
-
65
- /* c8 ignore next 3 */
66
- if (!supportedVersions.some(v => satisfies(nextPackage.version, v))) {
67
- throw new basicErrors.UnsupportedVersion('next', nextPackage.version, supportedVersions)
68
- }
52
+ return this.#init()
69
53
  }
70
54
 
71
55
  async start ({ listen }) {
@@ -124,7 +108,7 @@ export class NextCapability extends BaseCapability {
124
108
 
125
109
  async build () {
126
110
  if (!this.#nextVersion) {
127
- await this.init()
111
+ await this.#init()
128
112
  }
129
113
 
130
114
  const config = this.config
@@ -172,6 +156,33 @@ export class NextCapability extends BaseCapability {
172
156
  return context
173
157
  }
174
158
 
159
+ async #init () {
160
+ // This is needed to avoid Next.js to throw an error when the lockfile is not correct
161
+ // and the user is using npm but has pnpm in its $PATH.
162
+ //
163
+ // See: https://github.com/platformatic/composer-next-node-fastify/pull/3
164
+ //
165
+ // PS by Paolo: Sob.
166
+ process.env.NEXT_IGNORE_INCORRECT_LOCKFILE = 'true'
167
+
168
+ this.#next = resolvePath(dirname(await resolvePackageViaCJS(this.root, 'next')), '../..')
169
+ const nextPackage = JSON.parse(await readFile(resolvePath(this.#next, 'package.json'), 'utf-8'))
170
+ this.#nextVersion = parse(nextPackage.version)
171
+
172
+ if (this.#nextVersion.major < 15 || (this.#nextVersion.major <= 15 && this.#nextVersion.minor < 1)) {
173
+ await import('./create-context-patch.js')
174
+ }
175
+
176
+ if (this.#nextVersion.major < 16 && this.config.next?.useExperimentalAdapter === true) {
177
+ this.config.next.useExperimentalAdapter = false
178
+ }
179
+
180
+ /* c8 ignore next 3 */
181
+ if (!supportedVersions.some(v => satisfies(nextPackage.version, v))) {
182
+ throw new basicErrors.UnsupportedVersion('next', nextPackage.version, supportedVersions)
183
+ }
184
+ }
185
+
175
186
  async #startDevelopment () {
176
187
  const config = this.config
177
188
  const loaderUrl = new URL('./loader.js', import.meta.url)
@@ -253,11 +264,10 @@ export class NextCapability extends BaseCapability {
253
264
  this.#getChildManagerScripts()
254
265
  )
255
266
 
256
- this.verifyOutputDirectory(resolvePath(this.root, '.next'))
257
-
258
- if (existsSync(resolvePath(this.root, '.next/standalone'))) {
267
+ if (this.#isStandalone) {
259
268
  return this.#startProductionStandaloneNext()
260
269
  } else {
270
+ this.verifyOutputDirectory(resolvePath(this.root, '.next'))
261
271
  return this.#startProductionNext()
262
272
  }
263
273
  }
@@ -300,19 +310,17 @@ export class NextCapability extends BaseCapability {
300
310
  }
301
311
 
302
312
  async #startProductionStandaloneNext () {
303
- const rootDir = resolvePath(this.root, '.next', 'standalone')
304
-
305
313
  // If built in standalone mode, the generated standalone directory is not on the root of the project but somewhere
306
314
  // inside .next/standalone due to turbopack limitations in determining the root of the project.
307
315
  // In that case we search a server.js next to a .next folder inside the .next /standalone folder.
308
316
  const serverEntrypoints = await Array.fromAsync(
309
- glob(['**/server.js'], { cwd: rootDir, ignore: ['node_modules', '**/node_modules/**'] })
317
+ glob(['**/server.js'], { cwd: this.root, ignore: ['node_modules', '**/node_modules/**'] })
310
318
  )
311
319
 
312
320
  let serverEntrypoint
313
321
  for (const entrypoint of serverEntrypoints) {
314
- if (existsSync(resolvePath(rootDir, dirname(entrypoint), '.next'))) {
315
- serverEntrypoint = resolvePath(rootDir, entrypoint)
322
+ if (existsSync(resolvePath(this.root, dirname(entrypoint), '.next'))) {
323
+ serverEntrypoint = resolvePath(this.root, entrypoint)
316
324
  break
317
325
  }
318
326
  }
@@ -370,7 +378,7 @@ export class NextCapability extends BaseCapability {
370
378
 
371
379
  // This is needed by Next.js standalone server to pick up the correct configuration
372
380
  process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
373
- const { startServer } = await importFile(resolvePath(this.#next, './dist/server/lib/start-server.js'))
381
+ const { startServer } = this.#requireStandaloneEntrypoint(serverEntrypoint)
374
382
 
375
383
  await startServer({
376
384
  dir: dirname(serverEntrypoint),
@@ -450,6 +458,19 @@ export class NextCapability extends BaseCapability {
450
458
  await writeFile(requiredServerFilesPath, JSON.stringify(requiredServerFiles, null, 2))
451
459
  }
452
460
  }
461
+
453
462
  return distDir
454
463
  }
464
+
465
+ #requireStandaloneEntrypoint (serverEntrypoint) {
466
+ let serverModule
467
+
468
+ try {
469
+ serverModule = createRequire(serverEntrypoint)('next/dist/server/lib/start-server.js')
470
+ } catch (e) { // Fallback to bundled capability
471
+ serverModule = createRequire(import.meta.file)('next/dist/server/lib/start-server.js')
472
+ }
473
+
474
+ return serverModule.default ?? serverModule
475
+ }
455
476
  }
package/lib/schema.js CHANGED
@@ -42,6 +42,9 @@ export const cache = {
42
42
  const next = {
43
43
  type: 'object',
44
44
  properties: {
45
+ standalone: {
46
+ type: 'boolean',
47
+ },
45
48
  trailingSlash: {
46
49
  type: 'boolean',
47
50
  default: false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/next",
3
- "version": "3.32.0",
3
+ "version": "3.33.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.32.0",
27
- "@platformatic/foundation": "3.32.0"
26
+ "@platformatic/basic": "3.33.0-alpha.1",
27
+ "@platformatic/foundation": "3.33.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.32.0",
44
- "@platformatic/service": "3.32.0"
43
+ "@platformatic/gateway": "3.33.0-alpha.1",
44
+ "@platformatic/service": "3.33.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.32.0.json",
2
+ "$id": "https://schemas.platformatic.dev/@platformatic/next/3.33.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",
@@ -2316,6 +2316,9 @@
2316
2316
  "next": {
2317
2317
  "type": "object",
2318
2318
  "properties": {
2319
+ "standalone": {
2320
+ "type": "boolean"
2321
+ },
2319
2322
  "trailingSlash": {
2320
2323
  "type": "boolean",
2321
2324
  "default": false