MCPcopy Create free account
hub / github.com/adcontextprotocol/adcp / deserializeSession

Function deserializeSession

server/src/training-agent/state.ts:260–295  ·  view source on GitHub ↗

* Hydrate a stored doc back into a SessionState. * * Security invariant (per #2283 security review): `structuredDeserialize` * walks untrusted JSONB via `Object.entries` and can reconstitute a Map * whose entries include a "constructor" or "__proto__" key. Those are safe * on Map lookups (`.get

(data: Record<string, unknown>)

Source from the content-addressed store, hash-verified

258 * matching line here or it will hydrate as a raw envelope object.
259 */
260function deserializeSession(data: Record<string, unknown>): SessionState {
261 const hydratedWithMeta = structuredDeserialize(data) as Partial<SessionState> & { lastGetProductsContext?: unknown; __sessionKey?: unknown };
262 const { __sessionKey: _sessionKey, ...hydrated } = hydratedWithMeta;
263 const fresh = createSession();
264 const asMap = <V>(v: unknown, fallback: Map<string, V>): Map<string, V> =>
265 v instanceof Map ? (v as Map<string, V>) : fallback;
266 const hydratedComply = (hydrated.complyExtensions ?? {}) as Partial<SessionState['complyExtensions']>;
267 return {
268 ...fresh,
269 ...hydrated,
270 mediaBuys: asMap(hydrated.mediaBuys, fresh.mediaBuys),
271 creatives: asMap(hydrated.creatives, fresh.creatives),
272 signalActivations: asMap(hydrated.signalActivations, fresh.signalActivations),
273 governancePlans: asMap(hydrated.governancePlans, fresh.governancePlans),
274 governanceChecks: asMap(hydrated.governanceChecks, fresh.governanceChecks),
275 governanceOutcomes: asMap(hydrated.governanceOutcomes, fresh.governanceOutcomes),
276 propertyLists: asMap(hydrated.propertyLists, fresh.propertyLists),
277 collectionLists: asMap(hydrated.collectionLists, fresh.collectionLists),
278 contentStandards: asMap(hydrated.contentStandards, fresh.contentStandards),
279 rightsGrants: asMap(hydrated.rightsGrants, fresh.rightsGrants),
280 usageRecords: Array.isArray(hydrated.usageRecords) ? hydrated.usageRecords : [],
281 complyExtensions: {
282 accountStatuses: asMap(hydratedComply.accountStatuses, fresh.complyExtensions.accountStatuses),
283 siSessions: asMap(hydratedComply.siSessions, fresh.complyExtensions.siSessions),
284 deliverySimulations: asMap(hydratedComply.deliverySimulations, fresh.complyExtensions.deliverySimulations),
285 budgetSimulations: asMap(hydratedComply.budgetSimulations, fresh.complyExtensions.budgetSimulations),
286 seededProducts: asMap(hydratedComply.seededProducts, fresh.complyExtensions.seededProducts),
287 seededPricingOptions: asMap(hydratedComply.seededPricingOptions, fresh.complyExtensions.seededPricingOptions),
288 seededCreativeFormats: asMap(hydratedComply.seededCreativeFormats, fresh.complyExtensions.seededCreativeFormats),
289 forcedCreateMediaBuyArm: hydratedComply.forcedCreateMediaBuyArm,
290 },
291 lastGetProductsContext: (hydrated.lastGetProductsContext as SessionState['lastGetProductsContext']) ?? undefined,
292 createdAt: hydrated.createdAt instanceof Date ? hydrated.createdAt : fresh.createdAt,
293 lastAccessedAt: hydrated.lastAccessedAt instanceof Date ? hydrated.lastAccessedAt : fresh.lastAccessedAt,
294 };
295}
296
297// ── Public session API (async) ───────────────────────────────────
298

Callers 2

getSessionFunction · 0.85
findSessionMatchingFunction · 0.85

Calls 2

createSessionFunction · 0.85
asMapFunction · 0.85

Tested by

no test coverage detected