@camstack/server 1.1.55 → 1.1.57

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.
@@ -6389,6 +6389,15 @@ function createCapRouter_snapshot(getProvider, createRemoteProxy) {
6389
6389
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
6390
6390
  return p.invalidateCache(methodInput);
6391
6391
  }),
6392
+ getSnapshotOverview: trpc_middleware_js_1.protectedProcedure
6393
+ .input(types_91.snapshotCapability.methods.getSnapshotOverview.input.loose())
6394
+ .output(types_91.snapshotCapability.methods.getSnapshotOverview.output)
6395
+ .query(async ({ input, ctx }) => {
6396
+ const { nodeId, ...methodInput } = input;
6397
+ const p = resolveProvider('snapshot', nodeId, () => getProvider(ctx), createRemoteProxy);
6398
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
6399
+ return p.getSnapshotOverview(methodInput);
6400
+ }),
6392
6401
  });
6393
6402
  }
6394
6403
  function createCapRouter_ssoBridge(getProvider, createRemoteProxy) {
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.AddonWidgetsService = void 0;
37
+ exports.stripBundleVersionSegment = stripBundleVersionSegment;
37
38
  const path = __importStar(require("node:path"));
38
39
  const fs = __importStar(require("node:fs"));
39
40
  /**
@@ -45,6 +46,23 @@ function stripNodeSuffix(registryKey) {
45
46
  const at = registryKey.indexOf('@');
46
47
  return at === -1 ? registryKey : registryKey.slice(0, at);
47
48
  }
49
+ /** A content-version namespace segment: `v<hex>` (the aggregator's dir hash). */
50
+ const VERSION_SEGMENT_RE = /^v[0-9a-f]{6,}$/;
51
+ /**
52
+ * Strip the optional leading content-version segment (`v<hash>/`) from a
53
+ * requested bundle path. The version is a cache-busting NAMESPACE only — the
54
+ * real file lives at `distDir/<rest>`; MF relative imports resolve against the
55
+ * versioned URL, so `v<hash>/_stub.js` must resolve to `_stub.js`. Returns
56
+ * `{ filePath, versioned }` — `versioned` lets the route serve content-
57
+ * addressed files as `immutable`. Pure + exported for the spec.
58
+ */
59
+ function stripBundleVersionSegment(rawPath) {
60
+ const slash = rawPath.indexOf('/');
61
+ if (slash > 0 && VERSION_SEGMENT_RE.test(rawPath.slice(0, slash))) {
62
+ return { filePath: rawPath.slice(slash + 1), versioned: true };
63
+ }
64
+ return { filePath: rawPath, versioned: false };
65
+ }
48
66
  /**
49
67
  * AddonWidgetsService — server-side helper that backs the static file
50
68
  * route `/api/addon-widgets/:addonId/*` (registered in `main.ts`).
@@ -103,8 +121,11 @@ class AddonWidgetsService {
103
121
  this.logger.warn('Bundle resolve failed: addon install path not found', { tags: { addonId } });
104
122
  return null;
105
123
  }
124
+ // Drop the content-version namespace (`v<hash>/`) the aggregator stamps —
125
+ // it exists only to atomically cache-bust the bundle on update.
126
+ const { filePath: bareFilePath } = stripBundleVersionSegment(filePath);
106
127
  const resolvedBase = path.resolve(installPath.distDir);
107
- const resolvedFile = path.resolve(installPath.distDir, filePath);
128
+ const resolvedFile = path.resolve(installPath.distDir, bareFilePath);
108
129
  // Path traversal protection
109
130
  if (!resolvedFile.startsWith(resolvedBase + path.sep) && resolvedFile !== resolvedBase) {
110
131
  this.logger.warn('Path traversal denied for addon', { tags: { addonId }, meta: { filePath } });
package/dist/main.js CHANGED
@@ -475,11 +475,17 @@ async function bootstrap() {
475
475
  : ext === '.html'
476
476
  ? 'text/html'
477
477
  : 'application/octet-stream';
478
+ // A content-versioned request (`v<hash>/…`) is content-addressed: the
479
+ // URL changes iff the bundle changed, so EVERYTHING under it — even the
480
+ // fixed-name `_stub.js`/`remoteEntry.js` — is safely immutable (this
481
+ // defeats a CDN edge serving a stale stub). Legacy unversioned requests
482
+ // keep the per-file revalidation policy.
483
+ const { versioned } = (0, addon_widgets_service_1.stripBundleVersionSegment)(filePath);
484
+ const cacheControl = versioned
485
+ ? 'public, max-age=31536000, immutable'
486
+ : (0, spa_static_1.addonBundleCacheControl)(resolved);
478
487
  const stream = fs.createReadStream(resolved);
479
- return reply
480
- .header('cache-control', (0, spa_static_1.addonBundleCacheControl)(resolved))
481
- .type(contentType)
482
- .send(stream);
488
+ return reply.header('cache-control', cacheControl).type(contentType).send(stream);
483
489
  });
484
490
  // Serve static assets (e.g. SVG icons) from an addon's package directory
485
491
  fastify.get('/api/addon-assets/:addonId/*', async (request, reply) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/server",
3
- "version": "1.1.55",
3
+ "version": "1.1.57",
4
4
  "private": false,
5
5
  "files": [
6
6
  "dist",
@@ -28,14 +28,14 @@
28
28
  "@camstack/addon-auth": "1.1.6",
29
29
  "@camstack/addon-decoder-nodeav": "1.1.9",
30
30
  "@camstack/addon-notifiers": "1.1.21",
31
- "@camstack/addon-pipeline": "1.1.51",
32
- "@camstack/addon-pipeline-orchestrator": "1.1.40",
33
- "@camstack/addon-post-analysis": "1.1.23",
31
+ "@camstack/addon-pipeline": "1.1.52",
32
+ "@camstack/addon-pipeline-orchestrator": "1.1.42",
33
+ "@camstack/addon-post-analysis": "1.1.24",
34
34
  "@camstack/sdk": "1.1.22",
35
35
  "@camstack/shm-ring": "1.0.21",
36
- "@camstack/system": "1.1.42",
37
- "@camstack/types": "1.1.39",
38
- "@camstack/ui-library": "1.1.31",
36
+ "@camstack/system": "1.1.44",
37
+ "@camstack/types": "1.1.40",
38
+ "@camstack/ui-library": "1.1.32",
39
39
  "@fastify/compress": "^9.0.0",
40
40
  "@fastify/cookie": "^11.0.2",
41
41
  "@fastify/multipart": "^10.0.0",