@platformatic/next 3.38.0 → 3.39.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/config.d.ts CHANGED
@@ -55,6 +55,10 @@ export interface PlatformaticNextJsConfig {
55
55
  customLevels?: {
56
56
  [k: string]: unknown;
57
57
  };
58
+ openTelemetryExporter?: {
59
+ protocol: "grpc" | "http";
60
+ url: string;
61
+ };
58
62
  [k: string]: unknown;
59
63
  };
60
64
  server?: {
@@ -186,6 +190,10 @@ export interface PlatformaticNextJsConfig {
186
190
  customLevels?: {
187
191
  [k: string]: unknown;
188
192
  };
193
+ openTelemetryExporter?: {
194
+ protocol: "grpc" | "http";
195
+ url: string;
196
+ };
189
197
  [k: string]: unknown;
190
198
  };
191
199
  server?: {
@@ -648,6 +656,12 @@ export interface PlatformaticNextJsConfig {
648
656
  standalone?: boolean;
649
657
  trailingSlash?: boolean;
650
658
  useExperimentalAdapter?: boolean;
659
+ https?: {
660
+ enabled?: boolean | string;
661
+ key?: string;
662
+ cert?: string;
663
+ ca?: string;
664
+ };
651
665
  };
652
666
  cache?: {
653
667
  enabled?: boolean | string;
package/index.js CHANGED
@@ -106,7 +106,6 @@ export async function create (configOrRoot, sourceOrConfig, context) {
106
106
  return new NextCapability(config[kMetadata].root, config, context)
107
107
  }
108
108
 
109
- export * as cachingValkey from './lib/caching/valkey-isr.js'
110
109
  export * from './lib/capability.js'
111
110
  export * as errors from './lib/errors.js'
112
111
  export { packageJson, schema, schemaComponents, version } from './lib/schema.js'
@@ -1,12 +1,24 @@
1
1
  import { buildPinoFormatters, buildPinoTimestamp } from '@platformatic/foundation'
2
- import { Redis } from 'iovalkey'
3
- import { pack, unpack } from 'msgpackr'
2
+ import { createRequire } from 'node:module'
4
3
  import { existsSync, readFileSync } from 'node:fs'
5
4
  import { hostname } from 'node:os'
6
5
  import { resolve } from 'node:path'
7
6
  import { fileURLToPath } from 'node:url'
8
7
  import { pino } from 'pino'
9
8
 
9
+ // commonjs require is superior because it allows lazy loading
10
+ const require = createRequire(import.meta.url)
11
+
12
+ let Redis
13
+ let msgpackr
14
+
15
+ function loadMsgpackr () {
16
+ if (!msgpackr) {
17
+ msgpackr = require('msgpackr')
18
+ }
19
+ return msgpackr
20
+ }
21
+
10
22
  globalThis.platformatic ??= {}
11
23
  globalThis.platformatic.valkeyClients = new Map()
12
24
 
@@ -34,6 +46,10 @@ export function getConnection (url) {
34
46
  let client = globalThis.platformatic.valkeyClients.get(url)
35
47
 
36
48
  if (!client) {
49
+ if (!Redis) {
50
+ Redis = require('iovalkey').Redis
51
+ loadMsgpackr()
52
+ }
37
53
  client = new Redis(url, { enableAutoPipelining: true })
38
54
  globalThis.platformatic.valkeyClients.set(url, client)
39
55
 
@@ -93,9 +109,9 @@ export function getPlatformaticMeta () {
93
109
  }
94
110
 
95
111
  export function serialize (data) {
96
- return pack(data).toString('base64url')
112
+ return loadMsgpackr().pack(data).toString('base64url')
97
113
  }
98
114
 
99
115
  export function deserialize (data) {
100
- return unpack(Buffer.from(data, 'base64url'))
116
+ return loadMsgpackr().unpack(Buffer.from(data, 'base64url'))
101
117
  }
package/lib/capability.js CHANGED
@@ -159,9 +159,8 @@ export class NextCapability extends BaseCapability {
159
159
 
160
160
  let command = config.application.commands.build
161
161
 
162
- if (!command || !config.next?.standalone) {
163
- await this.init(true)
164
- }
162
+ // Always init to ensure #nextVersion is set (needed by #getChildManagerScripts)
163
+ await this.init(true)
165
164
 
166
165
  if (!command) {
167
166
  command = ['node', resolvePath(this.#next, './dist/bin/next'), 'build', this.root]
@@ -240,21 +239,71 @@ export class NextCapability extends BaseCapability {
240
239
  this.#ensurePipeableStreamsInFork()
241
240
 
242
241
  if (this.#nextVersion.major === 14 && this.#nextVersion.minor < 2) {
243
- await nextDev({
242
+ const devOptions = {
244
243
  '--hostname': serverOptions.host,
245
244
  '--port': serverOptions.port,
246
245
  _: [this.root]
247
- })
246
+ }
247
+
248
+ const httpsOptions = this.config.next?.https ?? {}
249
+
250
+ if (httpsOptions.enabled) {
251
+ devOptions['--experimental-https-key'] = true
252
+
253
+ if (httpsOptions.key) {
254
+ devOptions['--experimental-https-key'] = resolvePath(this.root, httpsOptions.key)
255
+ }
256
+
257
+ if (httpsOptions.cert) {
258
+ devOptions['--experimental-https-cert'] = resolvePath(this.root, httpsOptions.cert)
259
+ }
260
+
261
+ if (httpsOptions.ca) {
262
+ devOptions['--experimental-https-ca'] = resolvePath(this.root, httpsOptions.ca)
263
+ }
264
+ }
265
+
266
+ await nextDev(devOptions)
248
267
  } else {
268
+ const nextConfig = this.config.next ?? {}
269
+ const httpsOptions = nextConfig.https ?? {}
270
+
271
+ if (httpsOptions.enabled) {
272
+ serverOptions.experimentalHttps = true
273
+
274
+ if (httpsOptions.key) {
275
+ serverOptions.experimentalHttpsKey = resolvePath(this.root, httpsOptions.key)
276
+ }
277
+
278
+ if (httpsOptions.cert) {
279
+ serverOptions.experimentalHttpsCert = resolvePath(this.root, httpsOptions.cert)
280
+ }
281
+
282
+ if (httpsOptions.ca) {
283
+ serverOptions.experimentalHttpsCa = resolvePath(this.root, httpsOptions.ca)
284
+ }
285
+ }
286
+
249
287
  await nextDev(serverOptions, 'default', this.root)
250
288
  }
251
289
 
252
290
  this.#child = await childPromise
253
- this.#child.stdout.setEncoding('utf8')
254
- this.#child.stderr.setEncoding('utf8')
255
291
 
256
- this.#child.stdout.pipe(process.stdout, { end: false })
257
- this.#child.stderr.pipe(process.stderr, { end: false })
292
+ // Paolo: I couldn't really reproduce this, but in some environments our child_process patch
293
+ // might not work and thus the stdio streams are not pipeable.
294
+ // Rathen than throwing an error in that case, we log a warning and continue without redirecting the output,
295
+ // as the worst thing is that the user will lose our formatted output.
296
+ //
297
+ // This should be fixable once https://github.com/nodejs/node/pull/61836 lands and it is broadly available.
298
+ if (typeof this.#child.stdout?.pipe === 'function' && typeof this.#child.stderr?.pipe === 'function') {
299
+ this.#child.stdout.setEncoding('utf8')
300
+ this.#child.stderr.setEncoding('utf8')
301
+
302
+ this.#child.stdout.pipe(process.stdout, { end: false })
303
+ this.#child.stderr.pipe(process.stderr, { end: false })
304
+ } else {
305
+ this.logger.warn('Unable to redirect Next.js development server output to the main process')
306
+ }
258
307
  } finally {
259
308
  await this.childManager.eject()
260
309
  }
@@ -494,7 +543,8 @@ export class NextCapability extends BaseCapability {
494
543
 
495
544
  try {
496
545
  serverModule = createRequire(serverEntrypoint)('next/dist/server/lib/start-server.js')
497
- } catch (e) { // Fallback to bundled capability
546
+ } catch (e) {
547
+ // Fallback to bundled capability
498
548
  serverModule = createRequire(import.meta.file)('next/dist/server/lib/start-server.js')
499
549
  }
500
550
 
package/lib/schema.js CHANGED
@@ -63,7 +63,7 @@ const next = {
63
63
  type: 'object',
64
64
  properties: {
65
65
  standalone: {
66
- type: 'boolean',
66
+ type: 'boolean'
67
67
  },
68
68
  trailingSlash: {
69
69
  type: 'boolean',
@@ -72,6 +72,31 @@ const next = {
72
72
  useExperimentalAdapter: {
73
73
  type: 'boolean',
74
74
  default: false
75
+ },
76
+ https: {
77
+ type: 'object',
78
+ properties: {
79
+ enabled: {
80
+ anyOf: [
81
+ {
82
+ type: 'boolean'
83
+ },
84
+ {
85
+ type: 'string'
86
+ }
87
+ ]
88
+ },
89
+ key: {
90
+ type: 'string'
91
+ },
92
+ cert: {
93
+ type: 'string'
94
+ },
95
+ ca: {
96
+ type: 'string'
97
+ }
98
+ },
99
+ additionalProperties: false
75
100
  }
76
101
  },
77
102
  default: {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/next",
3
- "version": "3.38.0",
3
+ "version": "3.39.0",
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.38.0",
27
- "@platformatic/foundation": "3.38.0"
26
+ "@platformatic/foundation": "3.39.0",
27
+ "@platformatic/basic": "3.39.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@fastify/reply-from": "^12.0.0",
@@ -37,11 +37,11 @@
37
37
  "fastify": "^5.7.0",
38
38
  "json-schema-to-typescript": "^15.0.1",
39
39
  "neostandard": "^0.12.0",
40
- "next": "^16.0.0",
40
+ "next": "^16.1.0",
41
41
  "typescript": "^5.5.4",
42
42
  "ws": "^8.18.0",
43
- "@platformatic/service": "3.38.0",
44
- "@platformatic/gateway": "3.38.0"
43
+ "@platformatic/gateway": "3.39.0",
44
+ "@platformatic/service": "3.39.0"
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.38.0.json",
2
+ "$id": "https://schemas.platformatic.dev/@platformatic/next/3.39.0.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "title": "Platformatic Next.js Config",
5
5
  "type": "object",
@@ -152,6 +152,26 @@
152
152
  "customLevels": {
153
153
  "type": "object",
154
154
  "additionalProperties": true
155
+ },
156
+ "openTelemetryExporter": {
157
+ "type": "object",
158
+ "properties": {
159
+ "protocol": {
160
+ "type": "string",
161
+ "enum": [
162
+ "grpc",
163
+ "http"
164
+ ]
165
+ },
166
+ "url": {
167
+ "type": "string"
168
+ }
169
+ },
170
+ "required": [
171
+ "protocol",
172
+ "url"
173
+ ],
174
+ "additionalProperties": false
155
175
  }
156
176
  },
157
177
  "default": {},
@@ -935,6 +955,26 @@
935
955
  "customLevels": {
936
956
  "type": "object",
937
957
  "additionalProperties": true
958
+ },
959
+ "openTelemetryExporter": {
960
+ "type": "object",
961
+ "properties": {
962
+ "protocol": {
963
+ "type": "string",
964
+ "enum": [
965
+ "grpc",
966
+ "http"
967
+ ]
968
+ },
969
+ "url": {
970
+ "type": "string"
971
+ }
972
+ },
973
+ "required": [
974
+ "protocol",
975
+ "url"
976
+ ],
977
+ "additionalProperties": false
938
978
  }
939
979
  },
940
980
  "default": {},
@@ -2372,6 +2412,31 @@
2372
2412
  "useExperimentalAdapter": {
2373
2413
  "type": "boolean",
2374
2414
  "default": false
2415
+ },
2416
+ "https": {
2417
+ "type": "object",
2418
+ "properties": {
2419
+ "enabled": {
2420
+ "anyOf": [
2421
+ {
2422
+ "type": "boolean"
2423
+ },
2424
+ {
2425
+ "type": "string"
2426
+ }
2427
+ ]
2428
+ },
2429
+ "key": {
2430
+ "type": "string"
2431
+ },
2432
+ "cert": {
2433
+ "type": "string"
2434
+ },
2435
+ "ca": {
2436
+ "type": "string"
2437
+ }
2438
+ },
2439
+ "additionalProperties": false
2375
2440
  }
2376
2441
  },
2377
2442
  "default": {},