@valbuild/server 0.148.2 → 0.148.4

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,5 +1,29 @@
1
1
  # @valbuild/server
2
2
 
3
+ ## 0.148.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`7c432b3`](https://github.com/valbuild/val/commit/7c432b3f05af414bd6cbc37cd58a71a783056caa)]:
8
+ - @valbuild/ui@0.148.4
9
+
10
+ ## 0.148.3
11
+
12
+ ### Patch Changes
13
+
14
+ - [#881](https://github.com/valbuild/val/pull/881) [`0139436`](https://github.com/valbuild/val/commit/0139436426142d91cbb29ec6c696dfb86f34ab9d) Thanks [@freekh](https://github.com/freekh)! - The content analytics script. With analytics on (it is off by default, and turned on in a hosted project's settings), a TanStack site counts which content each visitor's page **rendered** and which they actually **viewed** (at least half on screen for a second), and sends it to `/api/val/analytics`.
15
+
16
+ - No cookies, no storage, no visitor IDs. Each page view also says where it came from (the referring site's host and any `utm_source` / `utm_medium` / `utm_campaign`) and whether it was a phone, tablet or desktop.
17
+ - A page is sent as its route's pattern (`/posts/$postId`), never its address, so a path that holds something about one visitor (an order number, a token) is never stored. `startValAnalytics` takes this as `routeFor`; `ValProvider` passes TanStack's matched route.
18
+ - Editors are never counted: nothing is sent in draft mode, in the Studio, with Val enabled, or at a proposal's address, and nothing from automated browsers. A page the browser prerenders counts nothing until it is shown.
19
+ - The script is the new `@valbuild/react/analytics` entry, loaded only for visitors of a site with analytics on, after the page has hydrated. It imports nothing else from Val.
20
+ - Storing the counts and showing them is part of Val's hosting, which takes these beacons before they reach the site. Anywhere else, `/api/val/analytics` checks each beacon and stores nothing; in local development, with `VAL_DEBUG=1`, it logs a line per beacon, so you can see it working.
21
+ - `ValProvider`'s Studio check now matches `/val` and what is below it only, not every route starting with those letters (`/values`). The same fix is in `@valbuild/next`.
22
+
23
+ - Updated dependencies [[`0139436`](https://github.com/valbuild/val/commit/0139436426142d91cbb29ec6c696dfb86f34ab9d), [`5eff8a0`](https://github.com/valbuild/val/commit/5eff8a055a4ef50d476797c28f9c3e50deb73c89)]:
24
+ - @valbuild/shared@0.148.3
25
+ - @valbuild/ui@0.148.3
26
+
3
27
  ## 0.148.2
4
28
 
5
29
  ### Patch Changes
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var core = require('@valbuild/core');
6
- var ValRouterCore = require('../../dist/ValRouterCore-72594062.cjs.dev.js');
6
+ var ValRouterCore = require('../../dist/ValRouterCore-fec2cbca.cjs.dev.js');
7
7
  require('@valbuild/shared/internal');
8
8
  require('zod');
9
9
  require('zod-validation-error');
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var core = require('@valbuild/core');
6
- var ValRouterCore = require('../../dist/ValRouterCore-dd465930.cjs.prod.js');
6
+ var ValRouterCore = require('../../dist/ValRouterCore-dfb7b578.cjs.prod.js');
7
7
  require('@valbuild/shared/internal');
8
8
  require('zod');
9
9
  require('zod-validation-error');
@@ -1,5 +1,5 @@
1
1
  import { DEFAULT_CONTENT_HOST } from '@valbuild/core';
2
- import { j as ValOpsMemory, E as bytesToBase64, y as ValServer, z as createValRequestHandler } from '../../dist/ValRouterCore-ad10b6cf.esm.js';
2
+ import { j as ValOpsMemory, E as bytesToBase64, y as ValServer, z as createValRequestHandler } from '../../dist/ValRouterCore-2579e663.esm.js';
3
3
  import '@valbuild/shared/internal';
4
4
  import 'zod';
5
5
  import 'zod-validation-error';
@@ -1,5 +1,5 @@
1
1
  import { Internal, VAL_EXTENSION, extractValModules, computeValModuleShas, ImageSchema, DEFAULT_CONTENT_HOST, hasRemoteFileSchema } from '@valbuild/core';
2
- import { isSchemaSourceFixError, resolveSchemaSourceFixForError, SerializedSchema, VAL_ENABLE_COOKIE_NAME, VAL_STATE_COOKIE, VAL_SESSION_COOKIE, newestCommitSha, parseJob, VAL_STUDIO_HEADER, getErrorMessageFromUnknownJson, Api } from '@valbuild/shared/internal';
2
+ import { isSchemaSourceFixError, resolveSchemaSourceFixForError, SerializedSchema, AnalyticsBeacon, VAL_ENABLE_COOKIE_NAME, VAL_STATE_COOKIE, VAL_SESSION_COOKIE, newestCommitSha, parseJob, VAL_STUDIO_HEADER, getErrorMessageFromUnknownJson, Api } from '@valbuild/shared/internal';
3
3
  import { z } from 'zod';
4
4
  import { fromError } from 'zod-validation-error';
5
5
  import { result, array } from '@valbuild/core/fp';
@@ -6005,6 +6005,50 @@ const ValServer = (valModules, options, callbacks, platform) => {
6005
6005
  };
6006
6006
  }
6007
6007
  },
6008
+ /**
6009
+ * Content analytics beacons, outside the hosted platform.
6010
+ *
6011
+ * On a site Val hosts, the platform's loader answers this route before a
6012
+ * request reaches the app, and counts. Everywhere else nothing counts yet:
6013
+ * this checks the beacon and answers, so a site with analytics on does not
6014
+ * fill its visitors' consoles with 404s. In local dev it also logs a line
6015
+ * per beacon, which is how the showcase shows analytics working.
6016
+ */
6017
+ "/analytics": {
6018
+ POST: async req => {
6019
+ const parsed = AnalyticsBeacon.safeParse(req.body);
6020
+ if (!parsed.success) {
6021
+ const body = req.body;
6022
+ const version = typeof body === "object" && body !== null && "v" in body ? body.v : undefined;
6023
+ if (typeof version === "number" && version !== 1) {
6024
+ // A newer format than this server knows: not an error.
6025
+ return {
6026
+ status: 200,
6027
+ json: {
6028
+ counted: false
6029
+ }
6030
+ };
6031
+ }
6032
+ return {
6033
+ status: 400,
6034
+ json: {
6035
+ message: "Not a valid Val analytics beacon"
6036
+ }
6037
+ };
6038
+ }
6039
+ if (options.mode === "fs") {
6040
+ const beacon = parsed.data;
6041
+ const count = paths => Object.values(paths).reduce((n, list) => n + list.length, 0);
6042
+ Internal.log.debug(`analytics: ${beacon.route}${beacon.view ? " (page view)" : ""}: ${count(beacon.rendered)} rendered, ${count(beacon.viewed)} viewed`);
6043
+ }
6044
+ return {
6045
+ status: 200,
6046
+ json: {
6047
+ counted: false
6048
+ }
6049
+ };
6050
+ }
6051
+ },
6008
6052
  "/draft/stat": {
6009
6053
  GET: async req => {
6010
6054
  const cookies = req.cookies;
@@ -9052,7 +9096,7 @@ const ValServer = (valModules, options, callbacks, platform) => {
9052
9096
  // TypeScript compiler. See `patch/ts/publishKit.ts`.
9053
9097
  const {
9054
9098
  getJsonEntryAtCommit
9055
- } = await import('./getJsonEntryAtCommit-e32a470b.esm.js');
9099
+ } = await import('./getJsonEntryAtCommit-66544899.esm.js');
9056
9100
  const res = await getJsonEntryAtCommit(serverOps, req.query.commit_sha, req.query.path, req.query.key);
9057
9101
  if (result.isErr(res)) {
9058
9102
  return historyErrorResponse(res.error);
@@ -6011,6 +6011,50 @@ const ValServer = (valModules, options, callbacks, platform) => {
6011
6011
  };
6012
6012
  }
6013
6013
  },
6014
+ /**
6015
+ * Content analytics beacons, outside the hosted platform.
6016
+ *
6017
+ * On a site Val hosts, the platform's loader answers this route before a
6018
+ * request reaches the app, and counts. Everywhere else nothing counts yet:
6019
+ * this checks the beacon and answers, so a site with analytics on does not
6020
+ * fill its visitors' consoles with 404s. In local dev it also logs a line
6021
+ * per beacon, which is how the showcase shows analytics working.
6022
+ */
6023
+ "/analytics": {
6024
+ POST: async req => {
6025
+ const parsed = internal.AnalyticsBeacon.safeParse(req.body);
6026
+ if (!parsed.success) {
6027
+ const body = req.body;
6028
+ const version = typeof body === "object" && body !== null && "v" in body ? body.v : undefined;
6029
+ if (typeof version === "number" && version !== 1) {
6030
+ // A newer format than this server knows: not an error.
6031
+ return {
6032
+ status: 200,
6033
+ json: {
6034
+ counted: false
6035
+ }
6036
+ };
6037
+ }
6038
+ return {
6039
+ status: 400,
6040
+ json: {
6041
+ message: "Not a valid Val analytics beacon"
6042
+ }
6043
+ };
6044
+ }
6045
+ if (options.mode === "fs") {
6046
+ const beacon = parsed.data;
6047
+ const count = paths => Object.values(paths).reduce((n, list) => n + list.length, 0);
6048
+ core.Internal.log.debug(`analytics: ${beacon.route}${beacon.view ? " (page view)" : ""}: ${count(beacon.rendered)} rendered, ${count(beacon.viewed)} viewed`);
6049
+ }
6050
+ return {
6051
+ status: 200,
6052
+ json: {
6053
+ counted: false
6054
+ }
6055
+ };
6056
+ }
6057
+ },
6014
6058
  "/draft/stat": {
6015
6059
  GET: async req => {
6016
6060
  const cookies = req.cookies;
@@ -9058,7 +9102,7 @@ const ValServer = (valModules, options, callbacks, platform) => {
9058
9102
  // TypeScript compiler. See `patch/ts/publishKit.ts`.
9059
9103
  const {
9060
9104
  getJsonEntryAtCommit
9061
- } = await Promise.resolve().then(function () { return require('./getJsonEntryAtCommit-2a0e9eaf.cjs.prod.js'); });
9105
+ } = await Promise.resolve().then(function () { return require('./getJsonEntryAtCommit-6bbe1c9d.cjs.prod.js'); });
9062
9106
  const res = await getJsonEntryAtCommit(serverOps, req.query.commit_sha, req.query.path, req.query.key);
9063
9107
  if (fp.result.isErr(res)) {
9064
9108
  return historyErrorResponse(res.error);
@@ -6011,6 +6011,50 @@ const ValServer = (valModules, options, callbacks, platform) => {
6011
6011
  };
6012
6012
  }
6013
6013
  },
6014
+ /**
6015
+ * Content analytics beacons, outside the hosted platform.
6016
+ *
6017
+ * On a site Val hosts, the platform's loader answers this route before a
6018
+ * request reaches the app, and counts. Everywhere else nothing counts yet:
6019
+ * this checks the beacon and answers, so a site with analytics on does not
6020
+ * fill its visitors' consoles with 404s. In local dev it also logs a line
6021
+ * per beacon, which is how the showcase shows analytics working.
6022
+ */
6023
+ "/analytics": {
6024
+ POST: async req => {
6025
+ const parsed = internal.AnalyticsBeacon.safeParse(req.body);
6026
+ if (!parsed.success) {
6027
+ const body = req.body;
6028
+ const version = typeof body === "object" && body !== null && "v" in body ? body.v : undefined;
6029
+ if (typeof version === "number" && version !== 1) {
6030
+ // A newer format than this server knows: not an error.
6031
+ return {
6032
+ status: 200,
6033
+ json: {
6034
+ counted: false
6035
+ }
6036
+ };
6037
+ }
6038
+ return {
6039
+ status: 400,
6040
+ json: {
6041
+ message: "Not a valid Val analytics beacon"
6042
+ }
6043
+ };
6044
+ }
6045
+ if (options.mode === "fs") {
6046
+ const beacon = parsed.data;
6047
+ const count = paths => Object.values(paths).reduce((n, list) => n + list.length, 0);
6048
+ core.Internal.log.debug(`analytics: ${beacon.route}${beacon.view ? " (page view)" : ""}: ${count(beacon.rendered)} rendered, ${count(beacon.viewed)} viewed`);
6049
+ }
6050
+ return {
6051
+ status: 200,
6052
+ json: {
6053
+ counted: false
6054
+ }
6055
+ };
6056
+ }
6057
+ },
6014
6058
  "/draft/stat": {
6015
6059
  GET: async req => {
6016
6060
  const cookies = req.cookies;
@@ -9058,7 +9102,7 @@ const ValServer = (valModules, options, callbacks, platform) => {
9058
9102
  // TypeScript compiler. See `patch/ts/publishKit.ts`.
9059
9103
  const {
9060
9104
  getJsonEntryAtCommit
9061
- } = await Promise.resolve().then(function () { return require('./getJsonEntryAtCommit-85159574.cjs.dev.js'); });
9105
+ } = await Promise.resolve().then(function () { return require('./getJsonEntryAtCommit-80bf8f02.cjs.dev.js'); });
9062
9106
  const res = await getJsonEntryAtCommit(serverOps, req.query.commit_sha, req.query.path, req.query.key);
9063
9107
  if (fp.result.isErr(res)) {
9064
9108
  return historyErrorResponse(res.error);
@@ -1,5 +1,5 @@
1
1
  import ts from 'typescript';
2
- import { F as bytesToUtf8, G as posixPath } from './ValRouterCore-ad10b6cf.esm.js';
2
+ import { F as bytesToUtf8, G as posixPath } from './ValRouterCore-2579e663.esm.js';
3
3
  import { result } from '@valbuild/core/fp';
4
4
  import { a as analyzeValModule, c as analyzeJsonValuesEntries } from './jsonValuesModule-427d68c8.esm.js';
5
5
  import '@valbuild/core';
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var ts = require('typescript');
4
- var ValRouterCore = require('./ValRouterCore-dd465930.cjs.prod.js');
4
+ var ValRouterCore = require('./ValRouterCore-dfb7b578.cjs.prod.js');
5
5
  var fp = require('@valbuild/core/fp');
6
6
  var jsonValuesModule = require('./jsonValuesModule-d1bb8d8f.cjs.prod.js');
7
7
  require('@valbuild/core');
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var ts = require('typescript');
4
- var ValRouterCore = require('./ValRouterCore-72594062.cjs.dev.js');
4
+ var ValRouterCore = require('./ValRouterCore-fec2cbca.cjs.dev.js');
5
5
  var fp = require('@valbuild/core/fp');
6
6
  var jsonValuesModule = require('./jsonValuesModule-8ae503a8.cjs.dev.js');
7
7
  require('@valbuild/core');
@@ -12,7 +12,7 @@ var path = require('path');
12
12
  var fs = require('fs');
13
13
  var vm = require('node:vm');
14
14
  var node_module = require('node:module');
15
- var ValRouterCore = require('./ValRouterCore-72594062.cjs.dev.js');
15
+ var ValRouterCore = require('./ValRouterCore-fec2cbca.cjs.dev.js');
16
16
  var server = require('@valbuild/ui/server');
17
17
  var z = require('zod');
18
18
  var zodValidationError = require('zod-validation-error');
@@ -12,7 +12,7 @@ var path = require('path');
12
12
  var fs = require('fs');
13
13
  var vm = require('node:vm');
14
14
  var node_module = require('node:module');
15
- var ValRouterCore = require('./ValRouterCore-dd465930.cjs.prod.js');
15
+ var ValRouterCore = require('./ValRouterCore-dfb7b578.cjs.prod.js');
16
16
  var server = require('@valbuild/ui/server');
17
17
  var z = require('zod');
18
18
  var zodValidationError = require('zod-validation-error');
@@ -10,8 +10,8 @@ import path from 'path';
10
10
  import fs from 'fs';
11
11
  import vm from 'node:vm';
12
12
  import { Module } from 'node:module';
13
- import { r as resolveExistingJsonPath, f as findNestedJsonValuesRecords, v as validateJsonValuesEntries, i as isJsonValuesRootOp, a as rebaseContentOp, c as classifyJsonValuesOp, V as ValOps, b as bufferFromDataUrl, g as getFieldsForType, u as uploadRemoteFile, d as getFileExt, e as guessMimeTypeFromPath, h as createMetadataFromBuffer, j as ValOpsMemory, k as isHlsMasterPlaylist, s as sumHlsSegmentDurations, p as parseHlsMasterVariants, l as largestHlsVariant, m as fallbackRefOf, n as mapHlsUris, o as movedRemoteHost, q as needsHostCheck, t as rewriteRefHost, w as fallbackRemoteHost, x as checkRemoteFiles, y as ValServer, z as createValRequestHandler, A as getNewJsonEntryPaths, B as formatPatchSourceError } from './ValRouterCore-ad10b6cf.esm.js';
14
- export { I as InMemoryPatchStore, j as ValOpsMemory, C as askOncePerHost, c as classifyJsonValuesOp, B as formatPatchSourceError, d as getFileExt, D as getSettings, a as rebaseContentOp, u as uploadRemoteFile } from './ValRouterCore-ad10b6cf.esm.js';
13
+ import { r as resolveExistingJsonPath, f as findNestedJsonValuesRecords, v as validateJsonValuesEntries, i as isJsonValuesRootOp, a as rebaseContentOp, c as classifyJsonValuesOp, V as ValOps, b as bufferFromDataUrl, g as getFieldsForType, u as uploadRemoteFile, d as getFileExt, e as guessMimeTypeFromPath, h as createMetadataFromBuffer, j as ValOpsMemory, k as isHlsMasterPlaylist, s as sumHlsSegmentDurations, p as parseHlsMasterVariants, l as largestHlsVariant, m as fallbackRefOf, n as mapHlsUris, o as movedRemoteHost, q as needsHostCheck, t as rewriteRefHost, w as fallbackRemoteHost, x as checkRemoteFiles, y as ValServer, z as createValRequestHandler, A as getNewJsonEntryPaths, B as formatPatchSourceError } from './ValRouterCore-2579e663.esm.js';
14
+ export { I as InMemoryPatchStore, j as ValOpsMemory, C as askOncePerHost, c as classifyJsonValuesOp, B as formatPatchSourceError, d as getFileExt, D as getSettings, a as rebaseContentOp, u as uploadRemoteFile } from './ValRouterCore-2579e663.esm.js';
15
15
  import { createUIRequestHandler } from '@valbuild/ui/server';
16
16
  import z$1, { z } from 'zod';
17
17
  import { fromError } from 'zod-validation-error';
package/package.json CHANGED
@@ -27,7 +27,7 @@
27
27
  ],
28
28
  "exports": true
29
29
  },
30
- "version": "0.148.2",
30
+ "version": "0.148.4",
31
31
  "devDependencies": {
32
32
  "@prettier/sync": "^0.6.1",
33
33
  "@types/jest": "^30.0.0",
@@ -42,8 +42,8 @@
42
42
  "zod": "^4.4.3",
43
43
  "zod-validation-error": "^5.0.0",
44
44
  "@valbuild/core": "0.148.2",
45
- "@valbuild/shared": "0.148.2",
46
- "@valbuild/ui": "0.148.2"
45
+ "@valbuild/shared": "0.148.3",
46
+ "@valbuild/ui": "0.148.4"
47
47
  },
48
48
  "engines": {
49
49
  "node": "^20.19.0 || >=22"