@digigov/cli-app 2.4.3-nextjs-16.27-07-26-15-19 → 2.5.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/CHANGELOG.md CHANGED
@@ -1,24 +1,25 @@
1
1
  # Change Log - @digigov/cli-app
2
2
 
3
- <!-- This log was last generated on Mon, 27 Jul 2026 15:19:46 GMT and should not be manually modified. -->
3
+ <!-- This log was last generated on Mon, 27 Jul 2026 17:23:56 GMT and should not be manually modified. -->
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
- ## 2.4.3-nextjs-16.27-07-26-15-19
7
+ ## 2.5.0
8
8
 
9
- Mon, 27 Jul 2026 15:19:46 GMT
9
+ Mon, 27 Jul 2026 17:23:56 GMT
10
10
 
11
11
  ### Minor changes
12
12
 
13
- - Next.js 13.1.1 -> 16.2.12: builds now use static export (output: 'export', next export was removed in Next 14) while next dev keeps the regular dev server, and digigov app start serves out/ statically (-p/--port, -H/--hostname). Drop next-images/url-loader/babel-loader in favor of built-in static image imports, remove the rimraf peer dependency, and modernize the dev proxy to http-proxy-middleware v3 running in-process. (sangelopoulos@admin.grnet.gr)
14
- - Bump @digigov/cli-build to v2.4.3-nextjs-16.27-07-26-15-19
15
- - Bump @digigov/cli to v2.4.3-nextjs-16.27-07-26-15-19
16
- - Bump @digigov/cli-lint to v2.4.3-nextjs-16.27-07-26-15-19
17
- - Bump @digigov/css to v2.4.3-nextjs-16.27-07-26-15-19
13
+ - Next.js 13.1.1 -> 16.2.12: builds now use static export (output: 'export', next export was removed in Next 14) while next dev keeps the regular dev server, and digigov app start serves out/ statically (-p/--port, -H/--hostname). Drop next-images/url-loader/babel-loader in favor of built-in static image imports, remove the rimraf peer dependency, and modernize the dev proxy to http-proxy-middleware v3 running in-process, arming websocket upgrades for ws: true proxy entries at startup so sockets reconnecting right after a restart are not dropped. (sangelopoulos@admin.grnet.gr)
14
+ - Bump @digigov/cli-build to v2.5.0
15
+ - Bump @digigov/cli to v2.5.0
16
+ - Bump @digigov/cli-lint to v2.5.0
17
+ - Bump @digigov/css to v2.5.0
18
18
 
19
19
  ### Patches
20
20
 
21
21
  - default images.unoptimized in dev as well as build so dev image rendering matches the exported artifact and @digigov/nextjs Image's basePath prepend behaves the same everywhere (sangelopoulos@admin.grnet.gr)
22
+ - route dev proxy and Next config output through the @digigov/cli logger instead of bare console calls (sangelopoulos@admin.grnet.gr)
22
23
 
23
24
  ## 2.4.2
24
25
 
package/next.common.cjs CHANGED
@@ -1,4 +1,5 @@
1
1
  const lib = require('@digigov/cli/lib');
2
+ const { logger } = require('@digigov/cli/lib/logger');
2
3
  const { PHASE_DEVELOPMENT_SERVER } = require('next/constants');
3
4
  let aliases = lib.aliases(true);
4
5
 
@@ -23,7 +24,7 @@ function withStaticExport(config, phase) {
23
24
  ...common,
24
25
  };
25
26
  if (exported.output === 'export' && exported.i18n) {
26
- console.warn(
27
+ logger.warn(
27
28
  'Built-in i18n routing is not supported with static export; ' +
28
29
  'dropping the `i18n` config for this build. Locale routing must be ' +
29
30
  'handled in userland (e.g. i18next without the Next.js `i18n` key).'
@@ -42,7 +43,7 @@ function makeBaseConfig(dir) {
42
43
  ...digigov.aliases,
43
44
  };
44
45
  }
45
- console.log(`Creating aliases for ${Object.keys(aliases).join(', ')}`);
46
+ logger.info(`Creating aliases for ${Object.keys(aliases).join(', ')}`);
46
47
  return {
47
48
  poweredByHeader: false,
48
49
  trailingSlash: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digigov/cli-app",
3
- "version": "2.4.3-nextjs-16.27-07-26-15-19",
3
+ "version": "2.5.0",
4
4
  "description": "@digigov developer cli tool",
5
5
  "main": "./index.js",
6
6
  "type": "module",
@@ -13,7 +13,7 @@
13
13
  "commander": "12.1.0",
14
14
  "globby": "11.0.0",
15
15
  "publint": "0.1.8",
16
- "@digigov/cli-build": "2.4.3-nextjs-16.27-07-26-15-19"
16
+ "@digigov/cli-build": "2.5.0"
17
17
  },
18
18
  "peerDependencies": {
19
19
  "typescript": "5.6.2",
@@ -22,8 +22,8 @@
22
22
  "autoprefixer": "10.4.16",
23
23
  "postcss": "8.4.4",
24
24
  "tailwindcss": "3.4.13",
25
- "@digigov/cli": "2.4.3-nextjs-16.27-07-26-15-19",
26
- "@digigov/css": "2.4.3-nextjs-16.27-07-26-15-19"
25
+ "@digigov/cli": "2.5.0",
26
+ "@digigov/css": "2.5.0"
27
27
  },
28
28
  "exports": {
29
29
  ".": "./index.js",
@@ -41,8 +41,8 @@
41
41
  "typescript": "5.6.2",
42
42
  "eslint": "9.16.0",
43
43
  "prettier": "3.4.2",
44
- "@digigov/cli": "2.4.3-nextjs-16.27-07-26-15-19",
45
- "@digigov/cli-lint": "2.4.3-nextjs-16.27-07-26-15-19"
44
+ "@digigov/cli": "2.5.0",
45
+ "@digigov/cli-lint": "2.5.0"
46
46
  },
47
47
  "scripts": {
48
48
  "publint": "publint",
@@ -1,6 +1,8 @@
1
1
  import fs from 'fs';
2
+ import { createRequire } from 'module';
2
3
 
3
4
  import express from 'express';
5
+ import { PHASE_PRODUCTION_SERVER } from 'next/constants.js';
4
6
  import { DigigovCommand, resolveProject, logger } from '@digigov/cli/lib';
5
7
  import { EXEC_CONFIG } from '../common.js';
6
8
  import path from 'path';
@@ -19,12 +21,32 @@ startCommand
19
21
  )
20
22
  .option('-H, --hostname <hostname>', 'Hostname to bind to', '0.0.0.0')
21
23
  .action(async (options, ctx) => {
24
+ const port = parseInt(options.port, 10);
25
+ if (Number.isNaN(port)) {
26
+ logger.error(`Invalid port: ${options.port}`);
27
+ process.exit(1);
28
+ }
22
29
  const outDir = path.join(project.root, 'out');
23
30
  if (!fs.existsSync(outDir)) {
24
31
  await ctx.exec('next', ['build'], EXEC_CONFIG);
25
32
  }
33
+ // The exported HTML references pages and assets under `basePath`, so the
34
+ // static site must be mounted there — as `next start` used to do.
35
+ const configPath = path.join(project.root, 'next.config.js');
36
+ let conf = {};
37
+ if (fs.existsSync(configPath)) {
38
+ const confModule = createRequire(configPath)(configPath);
39
+ conf =
40
+ typeof confModule === 'function'
41
+ ? await confModule(PHASE_PRODUCTION_SERVER, { defaultConfig: {} })
42
+ : confModule;
43
+ }
44
+ const basePath = conf.basePath ?? '';
26
45
  const server = express();
27
- server.use(express.static(outDir, { extensions: ['html'] }));
46
+ server.use(
47
+ basePath || '/',
48
+ express.static(outDir, { extensions: ['html'] })
49
+ );
28
50
  server.use((_req, res) => {
29
51
  const notFoundPage = path.join(outDir, '404.html');
30
52
  if (fs.existsSync(notFoundPage)) {
@@ -33,11 +55,16 @@ startCommand
33
55
  res.status(404).send('Not Found');
34
56
  }
35
57
  });
36
- server.listen(parseInt(options.port, 10), options.hostname, () => {
37
- logger.info(
38
- `Serving ${outDir} on http://${options.hostname}:${options.port}`
39
- );
40
- });
58
+ server
59
+ .listen(port, options.hostname, () => {
60
+ logger.info(
61
+ `Serving ${outDir} on http://${options.hostname}:${port}${basePath}`
62
+ );
63
+ })
64
+ .on('error', (err) => {
65
+ logger.error(`Unable to start server: ${err.message}`);
66
+ process.exit(1);
67
+ });
41
68
  });
42
69
 
43
70
  export default startCommand;
@@ -3,8 +3,14 @@ import next from 'next';
3
3
  import path from 'path';
4
4
  import { createRequire } from 'module';
5
5
  import { createProxyMiddleware } from 'http-proxy-middleware';
6
+ // `next` publishes no `exports` map, so the subpath needs the explicit
7
+ // extension to resolve under ESM.
8
+ import {
9
+ PHASE_DEVELOPMENT_SERVER,
10
+ PHASE_PRODUCTION_SERVER,
11
+ } from 'next/constants.js';
6
12
 
7
- import { resolveProject } from '@digigov/cli/lib';
13
+ import { resolveProject, logger } from '@digigov/cli/lib';
8
14
 
9
15
  const port = parseInt(process.env['PORT'] ?? '3000', 10);
10
16
  const isDev = process.env.NODE_ENV !== 'production';
@@ -13,7 +19,17 @@ const project = resolveProject();
13
19
  const devProxy = project.digigov.proxy;
14
20
 
15
21
  const require = createRequire(import.meta.url);
16
- const conf = require(path.join(project.root, 'next.config.js'));
22
+ const confModule = require(path.join(project.root, 'next.config.js'));
23
+
24
+ // nextrc exports a phase → config function; `next({ conf })` spreads the
25
+ // value without invoking it, so the phase must be resolved here.
26
+ const conf =
27
+ typeof confModule === 'function'
28
+ ? await confModule(
29
+ isDev ? PHASE_DEVELOPMENT_SERVER : PHASE_PRODUCTION_SERVER,
30
+ { defaultConfig: {} }
31
+ )
32
+ : confModule;
17
33
 
18
34
  // Next 16 removed the CJS `.default` interop export: `module.exports` itself is
19
35
  // the server factory (on 13 too), but the d.ts still types the module as a
@@ -34,20 +50,42 @@ try {
34
50
  const server = express();
35
51
 
36
52
  // Set up the proxy.
53
+ const wsProxies = [];
37
54
  if (isDev && devProxy) {
38
55
  for (const [pathFilter, options] of Object.entries(devProxy)) {
39
- server.use(createProxyMiddleware({ pathFilter, ...options }));
56
+ const proxy = createProxyMiddleware({ pathFilter, ...options });
57
+ server.use(proxy);
58
+ if (options.ws) {
59
+ wsProxies.push(proxy);
60
+ }
40
61
  }
41
62
  }
42
63
 
43
64
  // Default catch-all handler to allow Next.js to handle all other routes
44
65
  server.use((req, res) => handle(req, res));
45
66
 
46
- server.listen(port, () => {
47
- console.log(`> Ready on port ${port}`);
67
+ const httpServer = server.listen(port, () => {
68
+ logger.info(`Ready on port ${port}`);
48
69
  });
70
+
71
+ // Next and http-proxy-middleware each register their own `upgrade` listener,
72
+ // but only lazily — on the first HTTP request they see. A websocket that
73
+ // connects right after a restart, before any HTTP request (e.g. an open tab
74
+ // reconnecting through a `ws: true` proxy), finds no listener and hangs.
75
+ // Arm the ws proxies up front: `upgrade` checks its own pathFilter and
76
+ // no-ops once the proxy's internal listener exists, so nothing is handled
77
+ // twice. Next needs no arming — its HMR socket always follows a page load.
78
+ if (wsProxies.length > 0) {
79
+ httpServer.on('upgrade', (req, socket, head) => {
80
+ for (const proxy of wsProxies) {
81
+ proxy.upgrade(req, socket, head);
82
+ }
83
+ });
84
+ }
49
85
  } catch (err) {
50
- console.log('An error occurred, unable to start the server');
51
- console.log(err);
86
+ logger.error(
87
+ 'Unable to start the server:',
88
+ err instanceof Error ? err.stack : err
89
+ );
52
90
  process.exit(1);
53
91
  }