@camstack/server 1.2.7 → 1.2.9

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.
@@ -33,7 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.AddonPackageService = exports.FRAMEWORK_PACKAGES = exports.SYSTEM_PACKAGE = void 0;
36
+ exports.AddonPackageService = exports.FRAMEWORK_PACKAGES = exports.AUTO_UPDATE_EXCLUDED_PACKAGES = exports.SYSTEM_PACKAGE = void 0;
37
+ exports.isVersionNewer = isVersionNewer;
37
38
  exports.isFrameworkPackage = isFrameworkPackage;
38
39
  exports.extractTgzStripped = extractTgzStripped;
39
40
  const fs = __importStar(require("node:fs"));
@@ -51,6 +52,53 @@ const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
51
52
  * export because `lifecycle-job-runner` + several tests reference it directly.
52
53
  */
53
54
  exports.SYSTEM_PACKAGE = '@camstack/system';
55
+ /**
56
+ * Packages the npm auto-updater must NEVER touch: the framework/system tier
57
+ * ships exclusively via `applyServerUpdate` (single-copy collapse). Listed
58
+ * explicitly (not via a manifest flag) because the updater runs against
59
+ * `listInstalled()` package names before any manifest is loaded.
60
+ */
61
+ exports.AUTO_UPDATE_EXCLUDED_PACKAGES = new Set([
62
+ exports.SYSTEM_PACKAGE,
63
+ '@camstack/types',
64
+ '@camstack/kernel',
65
+ '@camstack/core',
66
+ '@camstack/sdk',
67
+ '@camstack/ui-library',
68
+ '@camstack/server',
69
+ ]);
70
+ /**
71
+ * True when `target` is a STRICTLY newer semver than `current`. Minimal
72
+ * x.y.z(-prerelease) comparator — our registry versions are plain publishes,
73
+ * and a dedicated semver dependency isn't declared in this package. Numeric
74
+ * triples compare first; a prerelease ranks BELOW its release (1.2.6-dev <
75
+ * 1.2.6); when both carry prereleases they compare lexicographically.
76
+ * Unparseable versions are never "newer" (fail safe: no update).
77
+ */
78
+ function isVersionNewer(target, current) {
79
+ const parse = (v) => {
80
+ const m = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(v.trim());
81
+ if (!m)
82
+ return null;
83
+ return { nums: [Number(m[1]), Number(m[2]), Number(m[3])], pre: m[4] ?? null };
84
+ };
85
+ const t = parse(target);
86
+ const c = parse(current);
87
+ if (!t || !c)
88
+ return false;
89
+ for (let i = 0; i < 3; i += 1) {
90
+ if (t.nums[i] !== c.nums[i])
91
+ return t.nums[i] > c.nums[i];
92
+ }
93
+ // Same triple: release > prerelease; two prereleases compare lexically.
94
+ if (t.pre === null && c.pre !== null)
95
+ return true;
96
+ if (t.pre !== null && c.pre === null)
97
+ return false;
98
+ if (t.pre !== null && c.pre !== null)
99
+ return t.pre > c.pre;
100
+ return false;
101
+ }
54
102
  /**
55
103
  * Host-provided framework packages that take a special path through
56
104
  * `camstack deploy` (the addon-upload route) instead of the normal
@@ -1145,6 +1193,13 @@ class AddonPackageService {
1145
1193
  const targets = [];
1146
1194
  for (const pkg of installed) {
1147
1195
  try {
1196
+ // Framework packages NEVER auto-update from npm — they ship via
1197
+ // `applyServerUpdate` (single-copy collapse). The engine already
1198
+ // skipped a swept framework target; excluding it here also kills the
1199
+ // useless candidate churn that participated in the 2026-07-22 hub
1200
+ // wedge (mass staged swap right after a publish train).
1201
+ if (exports.AUTO_UPDATE_EXCLUDED_PACKAGES.has(pkg.name))
1202
+ continue;
1148
1203
  // Determine effective channel for this addon
1149
1204
  const addonId = pkg.name.replace('@camstack/addon-', '').replace('@camstack/', '');
1150
1205
  const override = this.autoUpdateConfig.overrides[addonId];
@@ -1165,7 +1220,13 @@ class AddonPackageService {
1165
1220
  const targetVersion = effectiveChannel === 'beta'
1166
1221
  ? asString(distTags['beta']) || asString(distTags['latest'])
1167
1222
  : asString(distTags['latest']);
1168
- if (!targetVersion || targetVersion === pkg.version)
1223
+ // FORWARD-ONLY: update only when the registry advertises a STRICTLY
1224
+ // NEWER semver. The old `!==` comparison happily "updated" BACKWARD —
1225
+ // on 2026-07-22 it replaced same-day CLI-deployed builds (labelled
1226
+ // with the older workspace version) with the freshly published npm
1227
+ // artifacts, rolling back live fixes. A dev build whose label equals
1228
+ // or exceeds the npm tag is left alone.
1229
+ if (!targetVersion || !isVersionNewer(targetVersion, pkg.version))
1169
1230
  continue;
1170
1231
  this.logger.info('Auto-update candidate', {
1171
1232
  meta: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/server",
3
- "version": "1.2.7",
3
+ "version": "1.2.9",
4
4
  "private": false,
5
5
  "files": [
6
6
  "dist",
@@ -33,19 +33,19 @@
33
33
  ]
34
34
  },
35
35
  "dependencies": {
36
- "@camstack/addon-admin-ui": "1.2.5",
36
+ "@camstack/addon-admin-ui": "1.2.6",
37
37
  "@camstack/addon-advanced-notifier": "1.2.4",
38
38
  "@camstack/addon-agent-ui": "1.2.4",
39
39
  "@camstack/addon-auth": "1.2.4",
40
40
  "@camstack/addon-decoder-nodeav": "1.2.4",
41
41
  "@camstack/addon-notifiers": "1.2.4",
42
- "@camstack/addon-pipeline": "1.2.5",
43
- "@camstack/addon-pipeline-orchestrator": "1.2.6",
44
- "@camstack/addon-post-analysis": "1.2.5",
42
+ "@camstack/addon-pipeline": "1.2.7",
43
+ "@camstack/addon-pipeline-orchestrator": "1.2.8",
44
+ "@camstack/addon-post-analysis": "1.2.7",
45
45
  "@camstack/sdk": "1.2.4",
46
46
  "@camstack/shm-ring": "1.1.4",
47
- "@camstack/system": "1.2.6",
48
- "@camstack/types": "1.2.6",
47
+ "@camstack/system": "1.2.8",
48
+ "@camstack/types": "1.2.8",
49
49
  "@camstack/ui-library": "1.2.5",
50
50
  "@fastify/compress": "^9.0.0",
51
51
  "@fastify/cookie": "^11.0.2",