ras-stack 2.0.1 → 2.0.2

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.
@@ -1,8 +1,15 @@
1
1
  import type { PostHogEnvironment } from './config.js';
2
+ type ProxyRequest = {
3
+ removeHeader(name: string): void;
4
+ };
5
+ type ViteProxyServer = {
6
+ on(event: 'proxyReq', listener: (request: ProxyRequest) => void): unknown;
7
+ };
2
8
  type ViteProxyTarget = {
3
9
  target: string;
4
10
  changeOrigin: true;
5
11
  rewrite: (path: string) => string;
12
+ configure: (proxy: ViteProxyServer) => void;
6
13
  };
7
14
  export declare const POSTHOG_DEFAULT_INGEST_PATH = "/t";
8
15
  export declare function postHogIngestProxy(input: Pick<PostHogEnvironment, 'host' | 'assetsHost'>, options?: {
@@ -14,7 +21,10 @@ export declare function postHogIngestProxy(input: Pick<PostHogEnvironment, 'host
14
21
  };
15
22
  nitro: {
16
23
  [x: string]: {
17
- proxy: string;
24
+ proxy: {
25
+ to: string;
26
+ filterHeaders: ("authorization" | "cookie")[];
27
+ };
18
28
  };
19
29
  };
20
30
  };
@@ -1,12 +1,24 @@
1
1
  import { postHogHttpUrl } from './config.js';
2
+ /**
3
+ * A same-origin proxy receives the application's session cookie and any bearer token with every
4
+ * request. PostHog reads neither, and forwarding them would hand a credential to a third party.
5
+ */
6
+ const PRIVATE_HEADERS = ['cookie', 'authorization'];
2
7
  function viteTarget(host, ingestPath) {
3
8
  const prefix = new RegExp(`^${escapeRegExp(ingestPath)}`);
4
9
  return {
5
10
  target: host,
6
11
  changeOrigin: true,
7
12
  rewrite: (path) => path.replace(prefix, ''),
13
+ configure: (proxy) => proxy.on('proxyReq', (request) => {
14
+ for (const name of PRIVATE_HEADERS)
15
+ request.removeHeader(name);
16
+ }),
8
17
  };
9
18
  }
19
+ function nitroTarget(to) {
20
+ return { proxy: { to, filterHeaders: [...PRIVATE_HEADERS] } };
21
+ }
10
22
  function escapeRegExp(value) {
11
23
  return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
12
24
  }
@@ -32,9 +44,9 @@ export function postHogIngestProxy(input, options = {}) {
32
44
  [`${segment}(?:/|$)`]: viteTarget(ingestionHost, path),
33
45
  },
34
46
  nitro: {
35
- [`${path}/static/**`]: { proxy: `${assetsHost}/static/**` },
36
- [`${path}/array/**`]: { proxy: `${assetsHost}/array/**` },
37
- [`${path}/**`]: { proxy: `${ingestionHost}/**` },
47
+ [`${path}/static/**`]: nitroTarget(`${assetsHost}/static/**`),
48
+ [`${path}/array/**`]: nitroTarget(`${assetsHost}/array/**`),
49
+ [`${path}/**`]: nitroTarget(`${ingestionHost}/**`),
38
50
  },
39
51
  };
40
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/posthog/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAS5C,SAAS,UAAU,CAAC,IAAY,EAAE,UAAkB;IAClD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;IACzD,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;KAC5C,CAAA;AACH,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;AACrD,CAAC;AAED,8FAA8F;AAC9F,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,CAAA;AAE/C,SAAS,oBAAoB,CAAC,IAAY;IACxC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5F,MAAM,IAAI,KAAK,CAAC,iGAAiG,CAAC,CAAA;IACpH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAsD,EAAE,OAAO,GAAsB,EAAE;IACxH,MAAM,aAAa,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACxD,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;IACjE,MAAM,IAAI,GAAG,oBAAoB,CAAC,OAAO,CAAC,IAAI,IAAI,2BAA2B,CAAC,CAAA;IAC9E,8GAA8G;IAC9G,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAA;IACxC,OAAO;QACL,IAAI;QACJ,IAAI,EAAE;YACJ,CAAC,GAAG,OAAO,SAAS,CAAC,EAAE,UAAU,CAAC,UAAU,EAAE,IAAI,CAAC;YACnD,CAAC,GAAG,OAAO,QAAQ,CAAC,EAAE,UAAU,CAAC,UAAU,EAAE,IAAI,CAAC;YAClD,CAAC,GAAG,OAAO,SAAS,CAAC,EAAE,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC;SACvD;QACD,KAAK,EAAE;YACL,CAAC,GAAG,IAAI,YAAY,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,UAAU,YAAY,EAAE;YAC3D,CAAC,GAAG,IAAI,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,UAAU,WAAW,EAAE;YACzD,CAAC,GAAG,IAAI,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,aAAa,KAAK,EAAE;SACjD;KACF,CAAA;AACH,CAAC","sourcesContent":["import { postHogHttpUrl } from './config.js'\nimport type { PostHogEnvironment } from './config.js'\n\ntype ViteProxyTarget = {\n target: string\n changeOrigin: true\n rewrite: (path: string) => string\n}\n\nfunction viteTarget(host: string, ingestPath: string): ViteProxyTarget {\n const prefix = new RegExp(`^${escapeRegExp(ingestPath)}`)\n return {\n target: host,\n changeOrigin: true,\n rewrite: (path) => path.replace(prefix, ''),\n }\n}\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n// Ad-blocker lists match the literal `/ingest` segment on any host, so the default avoids it.\nexport const POSTHOG_DEFAULT_INGEST_PATH = '/t'\n\nfunction normalizedIngestPath(path: string): string {\n if (!path.startsWith('/') || path.endsWith('/') || path.includes('?') || path.includes('#')) {\n throw new Error('PostHog ingest path must start with \"/\", have no trailing slash, and carry no query or fragment')\n }\n return path\n}\n\nexport function postHogIngestProxy(input: Pick<PostHogEnvironment, 'host' | 'assetsHost'>, options: { path?: string } = {}) {\n const ingestionHost = postHogHttpUrl(input.host, 'host')\n const assetsHost = postHogHttpUrl(input.assetsHost, 'assetsHost')\n const path = normalizedIngestPath(options.path ?? POSTHOG_DEFAULT_INGEST_PATH)\n // Vite matches string keys as bare prefixes, so a short path needs a regular expression bound to its segment.\n const segment = `^${escapeRegExp(path)}`\n return {\n path,\n vite: {\n [`${segment}/static`]: viteTarget(assetsHost, path),\n [`${segment}/array`]: viteTarget(assetsHost, path),\n [`${segment}(?:/|$)`]: viteTarget(ingestionHost, path),\n },\n nitro: {\n [`${path}/static/**`]: { proxy: `${assetsHost}/static/**` },\n [`${path}/array/**`]: { proxy: `${assetsHost}/array/**` },\n [`${path}/**`]: { proxy: `${ingestionHost}/**` },\n },\n }\n}\n"]}
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/posthog/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAG5C;;;GAGG;AACH,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,eAAe,CAAU,CAAA;AAY5D,SAAS,UAAU,CAAC,IAAY,EAAE,UAAkB;IAClD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;IACzD,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC3C,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CACnB,KAAK,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE;YAC/B,KAAK,MAAM,IAAI,IAAI,eAAe;gBAAE,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAA;QAChE,CAAC,CAAC;KACL,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,EAAU;IAC7B,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,GAAG,eAAe,CAAC,EAAE,EAAE,CAAA;AAC/D,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;AACrD,CAAC;AAED,8FAA8F;AAC9F,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,CAAA;AAE/C,SAAS,oBAAoB,CAAC,IAAY;IACxC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5F,MAAM,IAAI,KAAK,CAAC,iGAAiG,CAAC,CAAA;IACpH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAsD,EAAE,OAAO,GAAsB,EAAE;IACxH,MAAM,aAAa,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACxD,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;IACjE,MAAM,IAAI,GAAG,oBAAoB,CAAC,OAAO,CAAC,IAAI,IAAI,2BAA2B,CAAC,CAAA;IAC9E,8GAA8G;IAC9G,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAA;IACxC,OAAO;QACL,IAAI;QACJ,IAAI,EAAE;YACJ,CAAC,GAAG,OAAO,SAAS,CAAC,EAAE,UAAU,CAAC,UAAU,EAAE,IAAI,CAAC;YACnD,CAAC,GAAG,OAAO,QAAQ,CAAC,EAAE,UAAU,CAAC,UAAU,EAAE,IAAI,CAAC;YAClD,CAAC,GAAG,OAAO,SAAS,CAAC,EAAE,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC;SACvD;QACD,KAAK,EAAE;YACL,CAAC,GAAG,IAAI,YAAY,CAAC,EAAE,WAAW,CAAC,GAAG,UAAU,YAAY,CAAC;YAC7D,CAAC,GAAG,IAAI,WAAW,CAAC,EAAE,WAAW,CAAC,GAAG,UAAU,WAAW,CAAC;YAC3D,CAAC,GAAG,IAAI,KAAK,CAAC,EAAE,WAAW,CAAC,GAAG,aAAa,KAAK,CAAC;SACnD;KACF,CAAA;AACH,CAAC","sourcesContent":["import { postHogHttpUrl } from './config.js'\nimport type { PostHogEnvironment } from './config.js'\n\n/**\n * A same-origin proxy receives the application's session cookie and any bearer token with every\n * request. PostHog reads neither, and forwarding them would hand a credential to a third party.\n */\nconst PRIVATE_HEADERS = ['cookie', 'authorization'] as const\n\ntype ProxyRequest = { removeHeader(name: string): void }\ntype ViteProxyServer = { on(event: 'proxyReq', listener: (request: ProxyRequest) => void): unknown }\n\ntype ViteProxyTarget = {\n target: string\n changeOrigin: true\n rewrite: (path: string) => string\n configure: (proxy: ViteProxyServer) => void\n}\n\nfunction viteTarget(host: string, ingestPath: string): ViteProxyTarget {\n const prefix = new RegExp(`^${escapeRegExp(ingestPath)}`)\n return {\n target: host,\n changeOrigin: true,\n rewrite: (path) => path.replace(prefix, ''),\n configure: (proxy) =>\n proxy.on('proxyReq', (request) => {\n for (const name of PRIVATE_HEADERS) request.removeHeader(name)\n }),\n }\n}\n\nfunction nitroTarget(to: string) {\n return { proxy: { to, filterHeaders: [...PRIVATE_HEADERS] } }\n}\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n// Ad-blocker lists match the literal `/ingest` segment on any host, so the default avoids it.\nexport const POSTHOG_DEFAULT_INGEST_PATH = '/t'\n\nfunction normalizedIngestPath(path: string): string {\n if (!path.startsWith('/') || path.endsWith('/') || path.includes('?') || path.includes('#')) {\n throw new Error('PostHog ingest path must start with \"/\", have no trailing slash, and carry no query or fragment')\n }\n return path\n}\n\nexport function postHogIngestProxy(input: Pick<PostHogEnvironment, 'host' | 'assetsHost'>, options: { path?: string } = {}) {\n const ingestionHost = postHogHttpUrl(input.host, 'host')\n const assetsHost = postHogHttpUrl(input.assetsHost, 'assetsHost')\n const path = normalizedIngestPath(options.path ?? POSTHOG_DEFAULT_INGEST_PATH)\n // Vite matches string keys as bare prefixes, so a short path needs a regular expression bound to its segment.\n const segment = `^${escapeRegExp(path)}`\n return {\n path,\n vite: {\n [`${segment}/static`]: viteTarget(assetsHost, path),\n [`${segment}/array`]: viteTarget(assetsHost, path),\n [`${segment}(?:/|$)`]: viteTarget(ingestionHost, path),\n },\n nitro: {\n [`${path}/static/**`]: nitroTarget(`${assetsHost}/static/**`),\n [`${path}/array/**`]: nitroTarget(`${assetsHost}/array/**`),\n [`${path}/**`]: nitroTarget(`${ingestionHost}/**`),\n },\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ras-stack",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "Composable full-stack primitives shared across Richard Solomou's applications.",
5
5
  "keywords": [
6
6
  "authentication",