@o-a/cms-agent 0.1.0 → 0.1.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.
@@ -153,6 +153,20 @@ function parseCheckpointIntervalMs(value) {
153
153
  // restart, since this loads once at boot - matches the existing
154
154
  // "agent upgrade = restart" story already established for schema
155
155
  // migrations, a deliberate decision, not an accident.
156
+ // PORT overrides site.config.json's own "port" (or its default) without
157
+ // editing a file - the universal Node/12-factor convention, and how
158
+ // several hosting platforms (Railway, Render, etc.) already inject the
159
+ // port a process must bind. An invalid value is ignored, not a hard
160
+ // failure - a stray non-numeric PORT shouldn't stop the whole site from
161
+ // booting when the configured/default port would have worked fine.
162
+ function resolvePort(configuredPort) {
163
+ const envPort = process.env.PORT;
164
+ if (envPort === undefined) {
165
+ return configuredPort;
166
+ }
167
+ const parsed = Number(envPort);
168
+ return Number.isInteger(parsed) && parsed >= 0 ? parsed : configuredPort;
169
+ }
156
170
  export function loadServerConfig(siteRoot) {
157
171
  const configPath = join(siteRoot, VHOST_DIR_NAME, 'site.config.json');
158
172
  let raw;
@@ -161,7 +175,7 @@ export function loadServerConfig(siteRoot) {
161
175
  }
162
176
  catch {
163
177
  return {
164
- port: DEFAULT_PORT,
178
+ port: resolvePort(DEFAULT_PORT),
165
179
  tokens: [],
166
180
  rateLimit: DEFAULT_RATE_LIMIT,
167
181
  trustProxy: false,
@@ -192,5 +206,5 @@ export function loadServerConfig(siteRoot) {
192
206
  const ipAllowlist = parseIpAllowlist(record.ipAllowlist);
193
207
  const checkpointIntervalMs = parseCheckpointIntervalMs(record.checkpointIntervalMs);
194
208
  const media = parseMedia(record.media);
195
- return { port, tokens, rateLimit, trustProxy, ipAllowlist, checkpointIntervalMs, media };
209
+ return { port: resolvePort(port), tokens, rateLimit, trustProxy, ipAllowlist, checkpointIntervalMs, media };
196
210
  }
package/dist/server.js CHANGED
@@ -142,7 +142,23 @@ export async function startServer(siteRoot, options = {}) {
142
142
  });
143
143
  // host: '0.0.0.0' - Fastify's own default binds 127.0.0.1 only,
144
144
  // which is unreachable from outside any container or remote host.
145
- await app.listen({ port: serverConfig.port, host: '0.0.0.0' });
145
+ try {
146
+ await app.listen({ port: serverConfig.port, host: '0.0.0.0' });
147
+ }
148
+ catch (error) {
149
+ // A raw EADDRINUSE crash is a wall of Node internals with no
150
+ // indication of what to actually do about it. This is the single
151
+ // most likely startup failure a developer hits on their own
152
+ // machine (something else already using the default port) - tell
153
+ // them the two real ways to pick a different one instead of
154
+ // rethrowing Node's own stack trace.
155
+ if (error instanceof Error && 'code' in error && error.code === 'EADDRINUSE') {
156
+ console.error(`Port ${serverConfig.port} is already in use.`);
157
+ console.error(`Set a different port with the PORT environment variable (e.g. PORT=3001 node server.js), or "port" in vhost/site.config.json.`);
158
+ process.exit(1);
159
+ }
160
+ throw error;
161
+ }
146
162
  if (options.tunnel) {
147
163
  try {
148
164
  tunnel = await (options.startTunnel ?? startDevTunnel)(serverConfig.port);
package/package.json CHANGED
@@ -1,12 +1,17 @@
1
1
  {
2
2
  "name": "@o-a/cms-agent",
3
- "version": "0.1.0",
3
+ "version": "0.1.5",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
8
8
  "description": "Self-hosted, git-backed CMS agent, distributed as a compiled npm package.",
9
9
  "license": "SEE LICENSE IN LICENSE",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/o-a-com-au/granitecms.git"
13
+ },
14
+ "homepage": "https://github.com/o-a-com-au/granitecms",
10
15
  "main": "dist/index.js",
11
16
  "types": "dist/index.d.ts",
12
17
  "exports": {