@monetizationos/proxy 1.0.0 → 1.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.
- package/dist/adapters/ClientMetadataProvider.d.ts +5 -4
- package/dist/adapters/ClientMetadataProvider.js.map +1 -1
- package/dist/apiRequestHeaders.d.ts +4 -3
- package/dist/apiRequestHeaders.js +7 -4
- package/dist/apiRequestHeaders.js.map +1 -1
- package/dist/clientRuntime.d.ts +7 -0
- package/dist/clientRuntime.js +59 -0
- package/dist/clientRuntime.js.map +1 -0
- package/dist/stages/customEndpoint.js +2 -2
- package/dist/stages/customEndpoint.js.map +1 -1
- package/dist/stages/fetchSurfaceDecisions.js +3 -4
- package/dist/stages/fetchSurfaceDecisions.js.map +1 -1
- package/package.json +64 -55
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Supplies platform-specific request metadata
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Supplies platform-specific request metadata. The returned object is spread
|
|
3
|
+
* into the surface-decisions request body at the top level, so each runtime
|
|
4
|
+
* picks its own key — matching the shape the MOS API already accepts from the
|
|
5
|
+
* platform-native workers.
|
|
5
6
|
*
|
|
6
|
-
* - Cloudflare: `{ cf: request.cf }`
|
|
7
|
+
* - Cloudflare: `{ cloudflare: { cf: request.cf } }`
|
|
7
8
|
* - Fastly: `{ fastly: { client: event.client, sigsci: {...} } }`
|
|
8
9
|
* - Akamai / unknown: `{}` is fine
|
|
9
10
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClientMetadataProvider.js","sourceRoot":"","sources":["../../src/adapters/ClientMetadataProvider.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Supplies platform-specific request metadata
|
|
1
|
+
{"version":3,"file":"ClientMetadataProvider.js","sourceRoot":"","sources":["../../src/adapters/ClientMetadataProvider.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Supplies platform-specific request metadata. The returned object is spread\n * into the surface-decisions request body at the top level, so each runtime\n * picks its own key — matching the shape the MOS API already accepts from the\n * platform-native workers.\n *\n * - Cloudflare: `{ cloudflare: { cf: request.cf } }`\n * - Fastly: `{ fastly: { client: event.client, sigsci: {...} } }`\n * - Akamai / unknown: `{}` is fine\n */\nexport interface ClientMetadataProvider {\n build(request: Request): Record<string, unknown>\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const MOS_PROXY_VERSION_HEADER = "X-MOS-Proxy-Version";
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const
|
|
2
|
+
export declare const MOS_PROXY_CLIENT_HEADER = "X-MOS-Proxy-Client";
|
|
3
|
+
export declare const MOS_PROXY_PACKAGE_VERSION = "1.0.2";
|
|
4
|
+
export declare const setMosProxyHeaders: (headers: Headers) => void;
|
|
5
|
+
export declare const withMosProxyHeaders: (headers?: HeadersInit) => Headers;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import { formatClientRuntimeHeader } from './clientRuntime';
|
|
1
2
|
export const MOS_PROXY_VERSION_HEADER = 'X-MOS-Proxy-Version';
|
|
2
|
-
export const
|
|
3
|
-
export const
|
|
3
|
+
export const MOS_PROXY_CLIENT_HEADER = 'X-MOS-Proxy-Client';
|
|
4
|
+
export const MOS_PROXY_PACKAGE_VERSION = '1.0.2';
|
|
5
|
+
export const setMosProxyHeaders = (headers) => {
|
|
4
6
|
headers.set(MOS_PROXY_VERSION_HEADER, MOS_PROXY_PACKAGE_VERSION);
|
|
7
|
+
headers.set(MOS_PROXY_CLIENT_HEADER, formatClientRuntimeHeader());
|
|
5
8
|
};
|
|
6
|
-
export const
|
|
9
|
+
export const withMosProxyHeaders = (headers) => {
|
|
7
10
|
const next = new Headers(headers);
|
|
8
|
-
|
|
11
|
+
setMosProxyHeaders(next);
|
|
9
12
|
return next;
|
|
10
13
|
};
|
|
11
14
|
//# sourceMappingURL=apiRequestHeaders.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiRequestHeaders.js","sourceRoot":"","sources":["../src/apiRequestHeaders.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,wBAAwB,GAAG,qBAAqB,CAAA;AAC7D,MAAM,CAAC,MAAM,yBAAyB,GAAG,OAAO,CAAA;AAEhD,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"apiRequestHeaders.js","sourceRoot":"","sources":["../src/apiRequestHeaders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAA;AAE3D,MAAM,CAAC,MAAM,wBAAwB,GAAG,qBAAqB,CAAA;AAC7D,MAAM,CAAC,MAAM,uBAAuB,GAAG,oBAAoB,CAAA;AAC3D,MAAM,CAAC,MAAM,yBAAyB,GAAG,OAAO,CAAA;AAEhD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAgB,EAAQ,EAAE;IACzD,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,yBAAyB,CAAC,CAAA;IAChE,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,yBAAyB,EAAE,CAAC,CAAA;AACrE,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAqB,EAAW,EAAE;IAClE,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;IACjC,kBAAkB,CAAC,IAAI,CAAC,CAAA;IACxB,OAAO,IAAI,CAAA;AACf,CAAC,CAAA","sourcesContent":["import { formatClientRuntimeHeader } from './clientRuntime'\n\nexport const MOS_PROXY_VERSION_HEADER = 'X-MOS-Proxy-Version'\nexport const MOS_PROXY_CLIENT_HEADER = 'X-MOS-Proxy-Client'\nexport const MOS_PROXY_PACKAGE_VERSION = '1.0.2'\n\nexport const setMosProxyHeaders = (headers: Headers): void => {\n headers.set(MOS_PROXY_VERSION_HEADER, MOS_PROXY_PACKAGE_VERSION)\n headers.set(MOS_PROXY_CLIENT_HEADER, formatClientRuntimeHeader())\n}\n\nexport const withMosProxyHeaders = (headers?: HeadersInit): Headers => {\n const next = new Headers(headers)\n setMosProxyHeaders(next)\n return next\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type ClientRuntime = {
|
|
2
|
+
runtime: 'cloudflare-workers' | 'fastly-compute' | 'vercel-edge' | 'deno-deploy' | 'deno' | 'bun' | 'node' | 'browser' | 'unknown';
|
|
3
|
+
runtimeVersion?: string;
|
|
4
|
+
provider?: 'vercel' | 'aws-lambda' | 'cloud-run' | 'netlify';
|
|
5
|
+
};
|
|
6
|
+
export declare const getClientRuntime: () => ClientRuntime;
|
|
7
|
+
export declare const formatClientRuntimeHeader: (info?: ClientRuntime) => string;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const NODE_PROVIDER_ENV = [
|
|
2
|
+
['VERCEL', 'vercel'],
|
|
3
|
+
['AWS_LAMBDA_FUNCTION_NAME', 'aws-lambda'],
|
|
4
|
+
['K_SERVICE', 'cloud-run'],
|
|
5
|
+
['NETLIFY', 'netlify'],
|
|
6
|
+
];
|
|
7
|
+
const detectNodeProvider = (env) => {
|
|
8
|
+
for (const [key, provider] of NODE_PROVIDER_ENV) {
|
|
9
|
+
if (env[key])
|
|
10
|
+
return provider;
|
|
11
|
+
}
|
|
12
|
+
return undefined;
|
|
13
|
+
};
|
|
14
|
+
export const getClientRuntime = () => {
|
|
15
|
+
// Edge runtimes first: some (Vercel Edge, Deno Deploy) also expose a partial `process` shim,
|
|
16
|
+
// so a Node check earlier would match them by mistake.
|
|
17
|
+
try {
|
|
18
|
+
// biome-ignore lint/suspicious/noExplicitAny: runtime globals are not typed
|
|
19
|
+
const g = globalThis;
|
|
20
|
+
if (typeof navigator !== 'undefined' && navigator.userAgent === 'Cloudflare-Workers') {
|
|
21
|
+
return { runtime: 'cloudflare-workers' };
|
|
22
|
+
}
|
|
23
|
+
if (typeof g.fastly !== 'undefined') {
|
|
24
|
+
return { runtime: 'fastly-compute' };
|
|
25
|
+
}
|
|
26
|
+
if (typeof g.EdgeRuntime !== 'undefined') {
|
|
27
|
+
return { runtime: 'vercel-edge' };
|
|
28
|
+
}
|
|
29
|
+
if (typeof g.Deno !== 'undefined') {
|
|
30
|
+
const version = g.Deno.version?.deno;
|
|
31
|
+
return g.Deno.env?.get?.('DENO_DEPLOYMENT_ID')
|
|
32
|
+
? { runtime: 'deno-deploy', runtimeVersion: version }
|
|
33
|
+
: { runtime: 'deno', runtimeVersion: version };
|
|
34
|
+
}
|
|
35
|
+
if (typeof g.Bun !== 'undefined') {
|
|
36
|
+
return { runtime: 'bun', runtimeVersion: g.Bun.version };
|
|
37
|
+
}
|
|
38
|
+
const proc = g.process;
|
|
39
|
+
if (proc?.versions?.node) {
|
|
40
|
+
return { runtime: 'node', runtimeVersion: proc.versions.node, provider: detectNodeProvider(proc.env ?? {}) };
|
|
41
|
+
}
|
|
42
|
+
if (typeof window !== 'undefined') {
|
|
43
|
+
return { runtime: 'browser' };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Sandboxed environments may throw on bare global property access; fall through to 'unknown'.
|
|
48
|
+
}
|
|
49
|
+
return { runtime: 'unknown' };
|
|
50
|
+
};
|
|
51
|
+
export const formatClientRuntimeHeader = (info = getClientRuntime()) => {
|
|
52
|
+
const parts = [`runtime=${info.runtime}`];
|
|
53
|
+
if (info.runtimeVersion)
|
|
54
|
+
parts.push(`runtime-version=${info.runtimeVersion}`);
|
|
55
|
+
if (info.provider)
|
|
56
|
+
parts.push(`provider=${info.provider}`);
|
|
57
|
+
return parts.join('; ');
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=clientRuntime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientRuntime.js","sourceRoot":"","sources":["../src/clientRuntime.ts"],"names":[],"mappings":"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","sourcesContent":["export type ClientRuntime = {\n runtime: 'cloudflare-workers' | 'fastly-compute' | 'vercel-edge' | 'deno-deploy' | 'deno' | 'bun' | 'node' | 'browser' | 'unknown'\n runtimeVersion?: string\n provider?: 'vercel' | 'aws-lambda' | 'cloud-run' | 'netlify'\n}\n\nconst NODE_PROVIDER_ENV: ReadonlyArray<readonly [string, NonNullable<ClientRuntime['provider']>]> = [\n ['VERCEL', 'vercel'],\n ['AWS_LAMBDA_FUNCTION_NAME', 'aws-lambda'],\n ['K_SERVICE', 'cloud-run'],\n ['NETLIFY', 'netlify'],\n]\n\nconst detectNodeProvider = (env: Record<string, string | undefined>): ClientRuntime['provider'] => {\n for (const [key, provider] of NODE_PROVIDER_ENV) {\n if (env[key]) return provider\n }\n return undefined\n}\n\nexport const getClientRuntime = (): ClientRuntime => {\n // Edge runtimes first: some (Vercel Edge, Deno Deploy) also expose a partial `process` shim,\n // so a Node check earlier would match them by mistake.\n try {\n // biome-ignore lint/suspicious/noExplicitAny: runtime globals are not typed\n const g = globalThis as any\n if (typeof navigator !== 'undefined' && navigator.userAgent === 'Cloudflare-Workers') {\n return { runtime: 'cloudflare-workers' }\n }\n if (typeof g.fastly !== 'undefined') {\n return { runtime: 'fastly-compute' }\n }\n if (typeof g.EdgeRuntime !== 'undefined') {\n return { runtime: 'vercel-edge' }\n }\n if (typeof g.Deno !== 'undefined') {\n const version = g.Deno.version?.deno\n return g.Deno.env?.get?.('DENO_DEPLOYMENT_ID')\n ? { runtime: 'deno-deploy', runtimeVersion: version }\n : { runtime: 'deno', runtimeVersion: version }\n }\n if (typeof g.Bun !== 'undefined') {\n return { runtime: 'bun', runtimeVersion: g.Bun.version }\n }\n const proc = g.process\n if (proc?.versions?.node) {\n return { runtime: 'node', runtimeVersion: proc.versions.node, provider: detectNodeProvider(proc.env ?? {}) }\n }\n if (typeof window !== 'undefined') {\n return { runtime: 'browser' }\n }\n } catch {\n // Sandboxed environments may throw on bare global property access; fall through to 'unknown'.\n }\n return { runtime: 'unknown' }\n}\n\nexport const formatClientRuntimeHeader = (info: ClientRuntime = getClientRuntime()): string => {\n const parts = [`runtime=${info.runtime}`]\n if (info.runtimeVersion) parts.push(`runtime-version=${info.runtimeVersion}`)\n if (info.provider) parts.push(`provider=${info.provider}`)\n return parts.join('; ')\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { setMosProxyHeaders } from '../apiRequestHeaders';
|
|
2
2
|
export default async function customEndpointRequest(ctx, request, apiFetcher) {
|
|
3
3
|
const { config } = ctx;
|
|
4
4
|
const requestUrl = new URL(request.url);
|
|
@@ -12,7 +12,7 @@ export default async function customEndpointRequest(ctx, request, apiFetcher) {
|
|
|
12
12
|
target.port = config.mosHost.port;
|
|
13
13
|
target.pathname = `/api/v1/envs/${config.mosEnvironment}/endpoints/${requestUrl.pathname.slice(prefix.length).replace(/^\//, '')}`;
|
|
14
14
|
const apiRequest = new Request(target, request);
|
|
15
|
-
|
|
15
|
+
setMosProxyHeaders(apiRequest.headers);
|
|
16
16
|
return apiFetcher(apiRequest);
|
|
17
17
|
}
|
|
18
18
|
//# sourceMappingURL=customEndpoint.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"customEndpoint.js","sourceRoot":"","sources":["../../src/stages/customEndpoint.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"customEndpoint.js","sourceRoot":"","sources":["../../src/stages/customEndpoint.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAGzD,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,qBAAqB,CAAC,GAAoB,EAAE,OAAgB,EAAE,UAAmB;IAC3G,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAA;IACtB,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACvC,MAAM,MAAM,GAAG,MAAM,CAAC,kBAAkB,CAAA;IAExC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAA;IACf,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACnC,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAA;IACzC,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAA;IACjC,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAA;IACjC,MAAM,CAAC,QAAQ,GAAG,gBAAgB,MAAM,CAAC,cAAc,cAAc,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAA;IAElI,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/C,kBAAkB,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;IACtC,OAAO,UAAU,CAAC,UAAU,CAAC,CAAA;AACjC,CAAC","sourcesContent":["import type { Fetcher } from '../adapters/Fetcher'\nimport { setMosProxyHeaders } from '../apiRequestHeaders'\nimport type { PipelineContext } from '../context'\n\nexport default async function customEndpointRequest(ctx: PipelineContext, request: Request, apiFetcher: Fetcher): Promise<Response | null> {\n const { config } = ctx\n const requestUrl = new URL(request.url)\n const prefix = config.mosEndpointsPrefix\n\n if (!requestUrl.pathname.startsWith(prefix)) {\n return null\n }\n\n const target = new URL(request.url)\n target.protocol = config.mosHost.protocol\n target.host = config.mosHost.host\n target.port = config.mosHost.port\n target.pathname = `/api/v1/envs/${config.mosEnvironment}/endpoints/${requestUrl.pathname.slice(prefix.length).replace(/^\\//, '')}`\n\n const apiRequest = new Request(target, request)\n setMosProxyHeaders(apiRequest.headers)\n return apiFetcher(apiRequest)\n}\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { withMosProxyHeaders } from '../apiRequestHeaders';
|
|
2
2
|
export default async function fetchSurfaceDecisions(ctx, { anonymousIdentifier, userJwt, path, url, clientMetadata, pageMetadata, userAgent, originStatus }, apiFetcher) {
|
|
3
3
|
const { config } = ctx;
|
|
4
4
|
const body = JSON.stringify({
|
|
5
|
+
...clientMetadata,
|
|
5
6
|
surfaceSlug: config.surfaceSlug,
|
|
6
7
|
identity: buildIdentity({ anonymousIdentifier, userJwt }),
|
|
7
8
|
resource: {
|
|
@@ -15,13 +16,11 @@ export default async function fetchSurfaceDecisions(ctx, { anonymousIdentifier,
|
|
|
15
16
|
status: originStatus,
|
|
16
17
|
},
|
|
17
18
|
},
|
|
18
|
-
// Legacy field name kept to avoid breaking the API schema; opaque to the proxy core.
|
|
19
|
-
cloudflare: clientMetadata,
|
|
20
19
|
});
|
|
21
20
|
const request = new Request(new URL('/api/v1/surface-decisions', config.mosHost), {
|
|
22
21
|
method: 'POST',
|
|
23
22
|
body,
|
|
24
|
-
headers:
|
|
23
|
+
headers: withMosProxyHeaders({
|
|
25
24
|
'Content-Type': 'application/json',
|
|
26
25
|
Authorization: `Bearer ${config.mosSecretKey}`,
|
|
27
26
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchSurfaceDecisions.js","sourceRoot":"","sources":["../../src/stages/fetchSurfaceDecisions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"fetchSurfaceDecisions.js","sourceRoot":"","sources":["../../src/stages/fetchSurfaceDecisions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AA8B1D,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,qBAAqB,CAC/C,GAAoB,EACpB,EAAE,mBAAmB,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAA6B,EAC7H,UAAmB;IAEnB,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAA;IACtB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;QACxB,GAAG,cAAc;QACjB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,QAAQ,EAAE,aAAa,CAAC,EAAE,mBAAmB,EAAE,OAAO,EAAE,CAAC;QACzD,QAAQ,EAAE;YACN,EAAE,EAAE,IAAI;YACR,IAAI,EAAE,YAAY;SACrB;QACD,IAAI,EAAE;YACF,GAAG;YACH,SAAS;YACT,WAAW,EAAE;gBACT,MAAM,EAAE,YAAY;aACvB;SACJ;KACJ,CAAC,CAAA;IAEF,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,GAAG,CAAC,2BAA2B,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE;QAC9E,MAAM,EAAE,MAAM;QACd,IAAI;QACJ,OAAO,EAAE,mBAAmB,CAAC;YACzB,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,MAAM,CAAC,YAAY,EAAE;SACjD,CAAC;KACL,CAAC,CAAA;IAEF,IAAI,QAAkB,CAAA;IACtB,IAAI,CAAC;QACD,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAA;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAA;IACzD,CAAC;IAED,IAAI,IAAa,CAAA;IACjB,IAAI,CAAC;QACD,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAA;IAChF,CAAC;IAED,IAAI,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,OAAO;YACH,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,WAAW;YACnB,KAAK,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;YAC9B,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,IAAI,CAAC,UAAU;SAC9B,CAAA;IACL,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACf,OAAO;YACH,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,YAAY;YACpB,KAAK,EAAE,IAAI,KAAK,CAAC,uCAAuC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC1E,MAAM,EAAE,QAAQ,CAAC,MAAM;SAC1B,CAAA;IACL,CAAC;IAED,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,OAAO;YACH,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,kBAAkB;YAC1B,KAAK,EAAE,IAAI,KAAK,CAAC,0DAA0D,CAAC;YAC5E,MAAM,EAAE,QAAQ,CAAC,MAAM;SAC1B,CAAA;IACL,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;AAC7B,CAAC;AAED,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAA;AAElH,MAAM,aAAa,GAAG,CAAC,EAAE,mBAAmB,EAAE,OAAO,EAAsE,EAAE,EAAE;IAC3H,IAAI,CAAC,mBAAmB,IAAI,CAAC,OAAO,EAAE,CAAC;QACnC,OAAO,EAAE,yBAAyB,EAAE,IAAI,EAAE,CAAA;IAC9C,CAAC;IACD,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,mBAAmB,EAAE,CAAA;AAC1D,CAAC,CAAA;AAED,MAAM,sBAAsB,GAAG,CAAC,KAAc,EAAiC,EAAE,CAC7E,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAA;AAE5H,MAAM,yBAAyB,GAAG,CAAC,KAAc,EAAoC,EAAE,CACnF,QAAQ,CAAC,KAAK,CAAC;IACf,KAAK,CAAC,MAAM,KAAK,SAAS;IAC1B,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC;IAC/B,OAAO,KAAK,CAAC,iBAAiB,KAAK,SAAS;IAC5C,QAAQ,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAA","sourcesContent":["import type { Fetcher } from '../adapters/Fetcher'\nimport { withMosProxyHeaders } from '../apiRequestHeaders'\nimport type { PipelineContext } from '../context'\nimport type { PageMetadata, SurfaceDecisionError, SurfaceDecisionResponse } from '../types'\n\nexport type FetchSurfaceDecisionsArgs = {\n anonymousIdentifier?: string | undefined\n userJwt?: string | undefined\n path: string\n url: string\n clientMetadata: Record<string, unknown>\n pageMetadata?: PageMetadata\n userAgent?: string | undefined\n originStatus: number\n}\n\nexport type FetchSurfaceDecisionsFailureReason = 'request-failed' | 'invalid-json' | 'api-error' | 'http-error' | 'invalid-response'\n\nexport type FetchSurfaceDecisionsResult =\n | {\n ok: true\n data: SurfaceDecisionResponse\n }\n | {\n ok: false\n reason: FetchSurfaceDecisionsFailureReason\n error: unknown\n status?: number\n statusCode?: number\n }\n\nexport default async function fetchSurfaceDecisions(\n ctx: PipelineContext,\n { anonymousIdentifier, userJwt, path, url, clientMetadata, pageMetadata, userAgent, originStatus }: FetchSurfaceDecisionsArgs,\n apiFetcher: Fetcher,\n): Promise<FetchSurfaceDecisionsResult> {\n const { config } = ctx\n const body = JSON.stringify({\n ...clientMetadata,\n surfaceSlug: config.surfaceSlug,\n identity: buildIdentity({ anonymousIdentifier, userJwt }),\n resource: {\n id: path,\n meta: pageMetadata,\n },\n http: {\n url,\n userAgent,\n proxyOrigin: {\n status: originStatus,\n },\n },\n })\n\n const request = new Request(new URL('/api/v1/surface-decisions', config.mosHost), {\n method: 'POST',\n body,\n headers: withMosProxyHeaders({\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.mosSecretKey}`,\n }),\n })\n\n let response: Response\n try {\n response = await apiFetcher(request)\n } catch (error) {\n return { ok: false, reason: 'request-failed', error }\n }\n\n let data: unknown\n try {\n data = await response.json()\n } catch (error) {\n return { ok: false, reason: 'invalid-json', error, status: response.status }\n }\n\n if (isSurfaceDecisionError(data)) {\n return {\n ok: false,\n reason: 'api-error',\n error: new Error(data.message),\n status: response.status,\n statusCode: data.statusCode,\n }\n }\n\n if (!response.ok) {\n return {\n ok: false,\n reason: 'http-error',\n error: new Error(`Surface decisions API returned HTTP ${response.status}`),\n status: response.status,\n }\n }\n\n if (!isSurfaceDecisionResponse(data)) {\n return {\n ok: false,\n reason: 'invalid-response',\n error: new Error('Surface decisions API returned an invalid response shape'),\n status: response.status,\n }\n }\n\n return { ok: true, data }\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null\n\nconst buildIdentity = ({ anonymousIdentifier, userJwt }: Pick<FetchSurfaceDecisionsArgs, 'anonymousIdentifier' | 'userJwt'>) => {\n if (!anonymousIdentifier && !userJwt) {\n return { createAnonymousIdentifier: true }\n }\n return userJwt ? { userJwt } : { anonymousIdentifier }\n}\n\nconst isSurfaceDecisionError = (value: unknown): value is SurfaceDecisionError =>\n isRecord(value) && value.status === 'error' && typeof value.message === 'string' && typeof value.statusCode === 'number'\n\nconst isSurfaceDecisionResponse = (value: unknown): value is SurfaceDecisionResponse =>\n isRecord(value) &&\n value.status === 'success' &&\n isRecord(value.identity) &&\n isRecord(value.features) &&\n isRecord(value.customer) &&\n isRecord(value.surfaceBehavior) &&\n typeof value.componentsSkipped === 'boolean' &&\n isRecord(value.componentBehaviors)\n"]}
|
package/package.json
CHANGED
|
@@ -1,57 +1,66 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
},
|
|
13
|
-
"./package.json": "./package.json"
|
|
2
|
+
"name": "@monetizationos/proxy",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Platform-agnostic MonetizationOS proxy core",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
14
12
|
},
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/MonetizationOS/mos-proxy.git"
|
|
24
|
+
},
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/MonetizationOS/mos-proxy/issues"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/MonetizationOS/mos-proxy#readme",
|
|
29
|
+
"keywords": [
|
|
30
|
+
"monetization",
|
|
31
|
+
"proxy",
|
|
32
|
+
"cloudflare-workers",
|
|
33
|
+
"fastly",
|
|
34
|
+
"akamai",
|
|
35
|
+
"html-rewriter"
|
|
36
|
+
],
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=22"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"cookie": "^1.1.1"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@biomejs/biome": "2.4.15",
|
|
48
|
+
"@changesets/changelog-github": "^0.7.0",
|
|
49
|
+
"@changesets/cli": "^2.31.0",
|
|
50
|
+
"@types/node": "^24.12.3",
|
|
51
|
+
"html-rewriter-wasm": "^0.4.1",
|
|
52
|
+
"typescript": "^6.0.3",
|
|
53
|
+
"vitest": "~4.1.5"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"build": "tsc -p tsconfig.build.json",
|
|
57
|
+
"test": "vitest",
|
|
58
|
+
"test:run": "vitest run",
|
|
59
|
+
"typecheck": "tsc --noEmit",
|
|
60
|
+
"lint": "biome check --diagnostic-level=error --no-errors-on-unmatched",
|
|
61
|
+
"format": "biome check --write --no-errors-on-unmatched",
|
|
62
|
+
"changeset": "changeset",
|
|
63
|
+
"version": "changeset version && node scripts/sync-version.mjs && pnpm run format",
|
|
64
|
+
"release": "changeset publish"
|
|
65
|
+
}
|
|
66
|
+
}
|