@blotout/qinto-cli 0.1.27 → 0.1.29

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.
@@ -21028,13 +21028,13 @@ var variableSchema = external_exports.object({
21028
21028
  label: external_exports.string().min(1).max(100),
21029
21029
  required: external_exports.boolean().optional(),
21030
21030
  browser: external_exports.boolean().optional(),
21031
- owner: external_exports.enum(["site", "developer"]).optional(),
21031
+ owner: external_exports.enum(["site", "developer", "app"]).optional(),
21032
21032
  helpText: external_exports.string().min(1).max(MAX_VARIABLE_HELP_TEXT).optional(),
21033
21033
  helpUrl: httpsUrl("helpUrl").optional()
21034
21034
  }).strict().refine((variable) => !(variable.kind === "secret" && variable.browser === true), {
21035
21035
  message: "A secret variable can never be browser-exposed"
21036
- }).refine((variable) => !(variable.required === true && variable.owner === "developer"), {
21037
- message: "A developer-owned variable cannot be required"
21036
+ }).refine((variable) => !(variable.required === true && (variable.owner === "developer" || variable.owner === "app")), {
21037
+ message: "A developer- or app-owned variable cannot be required"
21038
21038
  });
21039
21039
  var appVariableSchema = external_exports.object({
21040
21040
  name: external_exports.string().min(1).max(64).regex(VARIABLE_NAME),
@@ -21530,11 +21530,16 @@ var MAX_PUSH_BYTES = 16 * 1024;
21530
21530
  var MAX_RESPONSE_BYTES = 1024 * 1024;
21531
21531
  var MAX_RPC_BYTES = 128 * 1024;
21532
21532
  var installSchema = external_exports.object({ id: external_exports.string().min(1).max(64), ord: external_exports.number().int().min(1), label: external_exports.string().max(100) }).strict();
21533
- var emitSchema = external_exports.object({ type: external_exports.literal("track"), occurredAt: external_exports.number().int().nonnegative().safe(), payload: external_exports.record(external_exports.string(), external_exports.unknown()) }).strict();
21534
21533
  var installRuleSchema = external_exports.object({
21535
21534
  mode: external_exports.enum(["except", "only"]),
21536
21535
  installIds: external_exports.array(external_exports.string().min(1).max(64)).max(MAX_APPS_PER_DOMAIN * MAX_INSTALLS_PER_APP)
21537
21536
  }).strict();
21537
+ var emitSchema = external_exports.object({
21538
+ type: external_exports.literal("track"),
21539
+ occurredAt: external_exports.number().int().nonnegative().safe(),
21540
+ payload: external_exports.record(external_exports.string(), external_exports.unknown()),
21541
+ installs: installRuleSchema.optional()
21542
+ }).strict();
21538
21543
  var pushSchema = external_exports.object({ topic: external_exports.string().min(1).max(64), data: external_exports.unknown(), broadcast: external_exports.enum(PUSH_BROADCASTS).optional() }).strict().refine((push) => {
21539
21544
  return new TextEncoder().encode(JSON.stringify(push.data ?? null)).length <= MAX_PUSH_BYTES;
21540
21545
  }, "Push data exceeds the per-message size cap");
@@ -21557,6 +21562,7 @@ var effectGroupSchema = external_exports.object({
21557
21562
  }).strict();
21558
21563
  var captureValueSchema = external_exports.object({ value: external_exports.string().max(512), createdAt: external_exports.number().int(), updatedAt: external_exports.number().int(), type: external_exports.enum(CAPTURE_TYPES) }).strict();
21559
21564
  var pageSchema = external_exports.object({ url: external_exports.string().min(1).max(4096), referrer: external_exports.string().min(1).max(4096).optional() }).strict();
21565
+ var sessionSchema = external_exports.object({ id: external_exports.string().min(1).max(64), isNew: external_exports.boolean(), startedAt: external_exports.number().int().nonnegative().safe() }).strict();
21560
21566
  var actionContextFields = {
21561
21567
  occurredAt: external_exports.number().int().nonnegative().safe(),
21562
21568
  page: pageSchema.optional(),
@@ -21566,7 +21572,7 @@ var actionContextFields = {
21566
21572
  locale: external_exports.string().min(1).max(64).optional(),
21567
21573
  provenance: external_exports.enum(["edge", "caller"])
21568
21574
  }).strict().optional(),
21569
- session: external_exports.object({ id: external_exports.string().min(1).max(64), isNew: external_exports.boolean(), startedAt: external_exports.number().int().nonnegative().safe() }).strict().optional()
21575
+ session: sessionSchema.optional()
21570
21576
  };
21571
21577
  var actionContextSchema = external_exports.discriminatedUnion("source", [
21572
21578
  external_exports.object({ source: external_exports.literal("browser"), ...actionContextFields }).strict(),
@@ -21587,8 +21593,9 @@ var envelopeRequestSchema = external_exports.object({
21587
21593
  }).strict().optional(),
21588
21594
  consent: external_exports.object({ enabled: external_exports.boolean(), categories: external_exports.record(external_exports.string(), external_exports.boolean()), apps: external_exports.record(external_exports.string(), external_exports.boolean()) }).strict().optional(),
21589
21595
  geo: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
21590
- // Connect envelopes only: the page the visitor's socket opened from.
21596
+ // Connect envelopes only: the page the visitor's socket opened from, and the visit session it joined.
21591
21597
  page: pageSchema.optional(),
21598
+ session: sessionSchema.optional(),
21592
21599
  // Only what this app captured or wrote for this visitor; `updatedAt` is when the current value
21593
21600
  // was first seen, which is the click time a CAPI `fbc` is built from.
21594
21601
  captures: external_exports.record(external_exports.string().max(64), captureValueSchema).optional(),
@@ -26513,7 +26520,14 @@ var consentEnforcedFor = /* @__PURE__ */ __name((raw2) => {
26513
26520
  var consentEnforced = /* @__PURE__ */ __name((env) => {
26514
26521
  return consentEnforcedFor(env.CONSENT_CONFIGURATION ?? "");
26515
26522
  }, "consentEnforced");
26516
- var consentAllows = /* @__PURE__ */ __name((consent2, slug, category, enforced) => {
26523
+ var GPC_DENIED_CATEGORIES = ["marketing", "salesOfData"];
26524
+ var gpcDenies = /* @__PURE__ */ __name((category, gpc) => {
26525
+ return gpc && GPC_DENIED_CATEGORIES.includes(category);
26526
+ }, "gpcDenies");
26527
+ var consentAllows = /* @__PURE__ */ __name((consent2, slug, category, { enforced, gpc }) => {
26528
+ if (gpcDenies(category, gpc)) {
26529
+ return false;
26530
+ }
26517
26531
  if (!enforced) {
26518
26532
  return true;
26519
26533
  }
@@ -27585,7 +27599,7 @@ var trackBody = external_exports.object({
27585
27599
  userId: external_exports.string().min(1).max(64),
27586
27600
  installId: external_exports.string().min(1).max(64),
27587
27601
  installs: installRuleSchema.optional(),
27588
- event: emitSchema
27602
+ event: emitSchema.omit({ installs: true })
27589
27603
  }).strict();
27590
27604
  var handleTrack = /* @__PURE__ */ __name(async (env, body) => {
27591
27605
  const app2 = siteRegistry().registry.apps[body.slug];
@@ -27785,14 +27799,14 @@ var allContext = /* @__PURE__ */ __name((sql, level, cache) => {
27785
27799
 
27786
27800
  // src/apps/context-visibility.ts
27787
27801
  var SHARED_CONTEXT_CAPABILITY = "sharedContext";
27788
- var readableSharedContext = /* @__PURE__ */ __name((registry3, consent2, enforced, stored) => {
27802
+ var readableSharedContext = /* @__PURE__ */ __name((registry3, consent2, policy, stored) => {
27789
27803
  const readable = {};
27790
27804
  for (const [slug, entry] of Object.entries(stored)) {
27791
27805
  const app2 = registry3.apps[slug];
27792
27806
  if (app2 === void 0) {
27793
27807
  continue;
27794
27808
  }
27795
- if (!app2.data.includes(SHARED_CONTEXT_CAPABILITY) || !consentAllows(consent2, slug, app2.consent.category, enforced)) {
27809
+ if (!app2.data.includes(SHARED_CONTEXT_CAPABILITY) || !consentAllows(consent2, slug, app2.consent.category, policy)) {
27796
27810
  continue;
27797
27811
  }
27798
27812
  readable[slug] = entry;
@@ -27804,7 +27818,7 @@ var siteEventReceivers = /* @__PURE__ */ __name((registry3, consent2, enforced)
27804
27818
  return app2.data.includes(SHARED_CONTEXT_CAPABILITY) && app2.installs.some((install) => install.active) && // The receiver's own consent, resolved here rather than left to the page: the tag's
27805
27819
  // `state.consent` does not see a revocation made on another device (apps.ts), so a browser
27806
27820
  // recheck alone would keep notifying an app the visitor has since turned off.
27807
- consentAllows(consent2, slug, app2.consent.category, enforced);
27821
+ consentAllows(consent2, slug, app2.consent.category, { enforced, gpc: false });
27808
27822
  }).map(([slug]) => slug);
27809
27823
  }, "siteEventReceivers");
27810
27824
  var sharedContextWire = /* @__PURE__ */ __name((entries) => {
@@ -28538,11 +28552,18 @@ var eventAction = /* @__PURE__ */ __name((target, trigger, snapshot) => {
28538
28552
  ...trigger.action.origin !== void 0 ? { origin: trigger.action.origin } : {}
28539
28553
  };
28540
28554
  }, "eventAction");
28555
+ var connectContext = /* @__PURE__ */ __name((trigger) => {
28556
+ return {
28557
+ ...trigger.page === void 0 ? {} : { page: trigger.page },
28558
+ ...trigger.session === void 0 ? {} : { session: trigger.session }
28559
+ };
28560
+ }, "connectContext");
28541
28561
  var buildEnvelope = /* @__PURE__ */ __name((target, trigger, snapshot, context) => {
28542
28562
  const buckets = target.app.data;
28543
28563
  const geoAllowed = buckets.includes("geo");
28544
28564
  const currentGeo = trigger.kind === "event" ? trigger.action.geo : trigger.geo;
28545
- const consented = consentAllows(snapshot.consent, target.slug, target.app.consent.category, context.consentEnforced);
28565
+ const gpc = trigger.kind === "event" ? trigger.action.gpc === true : trigger.gpc === true;
28566
+ const consented = consentAllows(snapshot.consent, target.slug, target.app.consent.category, { enforced: context.consentEnforced, gpc });
28546
28567
  const captures = consented ? deliverableCaptures(target, snapshot.captures[target.slug]) : void 0;
28547
28568
  const visitorContext = deliverableContext({ target, consented, ...snapshot.context });
28548
28569
  return {
@@ -28563,7 +28584,7 @@ var buildEnvelope = /* @__PURE__ */ __name((target, trigger, snapshot, context)
28563
28584
  },
28564
28585
  ...buckets.includes("consentState") ? { consent: { enabled: context.consentEnforced, categories: snapshot.consent.categories, apps: snapshot.consent.apps } } : {},
28565
28586
  ...geoAllowed && currentGeo !== void 0 ? { geo: currentGeo } : {},
28566
- ...trigger.kind === "connect" && trigger.page !== void 0 && buckets.includes("eventContext") ? { page: trigger.page } : {},
28587
+ ...trigger.kind === "connect" && buckets.includes("eventContext") ? connectContext(trigger) : {},
28567
28588
  // Not gated on a capabilities.data bucket: an app only ever sees what it captured or wrote.
28568
28589
  ...captures === void 0 ? {} : { captures },
28569
28590
  ...visitorContext === void 0 ? {} : { context: visitorContext },
@@ -28571,36 +28592,38 @@ var buildEnvelope = /* @__PURE__ */ __name((target, trigger, snapshot, context)
28571
28592
  ...trigger.kind === "event" ? { action: eventAction(target, trigger, snapshot) } : {}
28572
28593
  };
28573
28594
  }, "buildEnvelope");
28574
- var ingestEmit = /* @__PURE__ */ __name(async (ingest2, { slug, ord, depth, emit, anonId, geo, host, context, fromSocket }) => {
28595
+ var emitContext = /* @__PURE__ */ __name((occurredAt, context, host) => ({
28596
+ ...context ?? {},
28597
+ source: "app",
28598
+ occurredAt,
28599
+ ...context !== void 0 || host === void 0 ? {} : {
28600
+ network: {
28601
+ ...host.ip === void 0 ? {} : { ip: host.ip },
28602
+ ...host.userAgent === void 0 ? {} : { userAgent: host.userAgent },
28603
+ ...host.locale === void 0 ? {} : { locale: host.locale },
28604
+ provenance: "edge"
28605
+ }
28606
+ },
28607
+ offline: context === void 0 || context.source === "browser" ? false : context.offline,
28608
+ replay: context === void 0 || context.source === "browser" ? false : context.replay
28609
+ }), "emitContext");
28610
+ var ingestEmit = /* @__PURE__ */ __name(async (ingest2, { slug, ord, depth, emit, anonId, geo, host, context, fromSocket, gpc }) => {
28575
28611
  const parsed = emitPayloadSchema.safeParse(emit.payload);
28576
28612
  if (!parsed.success) {
28577
28613
  addSpanEvent("emit payload rejected", { level: "warn", attrs: { app: slug, ord } });
28578
28614
  return;
28579
28615
  }
28580
28616
  const { event, eventId, properties: properties2 } = parsed.data;
28581
- const inherited = {
28582
- ...context ?? {},
28583
- source: "app",
28584
- occurredAt: emit.occurredAt,
28585
- ...context !== void 0 || host === void 0 ? {} : {
28586
- network: {
28587
- ...host.ip === void 0 ? {} : { ip: host.ip },
28588
- ...host.userAgent === void 0 ? {} : { userAgent: host.userAgent },
28589
- ...host.locale === void 0 ? {} : { locale: host.locale },
28590
- provenance: "edge"
28591
- }
28592
- },
28593
- offline: context === void 0 || context.source === "browser" ? false : context.offline,
28594
- replay: context === void 0 || context.source === "browser" ? false : context.replay
28595
- };
28596
28617
  const action = buildAction({
28597
28618
  type: "track",
28598
28619
  userId: anonId,
28599
28620
  source: "app",
28600
28621
  payload: { event, eventId: emittedEventId(eventId, properties2), properties: properties2 ?? {} },
28601
- context: inherited,
28622
+ context: emitContext(emit.occurredAt, context, host),
28602
28623
  origin: { app: slug, install: ord, depth: depth + 1 },
28624
+ ...emit.installs === void 0 ? {} : { installs: emit.installs },
28603
28625
  fromSocket,
28626
+ gpc,
28604
28627
  geo,
28605
28628
  host
28606
28629
  });
@@ -28645,7 +28668,8 @@ var applyEffects = /* @__PURE__ */ __name(async ({
28645
28668
  geo,
28646
28669
  host,
28647
28670
  context,
28648
- fromSocket
28671
+ fromSocket,
28672
+ gpc
28649
28673
  }) => {
28650
28674
  const captures = groups.flatMap((group) => group.captures);
28651
28675
  if (captures.length > 0) {
@@ -28665,7 +28689,7 @@ var applyEffects = /* @__PURE__ */ __name(async ({
28665
28689
  continue;
28666
28690
  }
28667
28691
  for (const emit of group.emits) {
28668
- await ingestEmit(ingest2, { slug, ord: group.ord, depth, emit, anonId, geo, host, context, fromSocket });
28692
+ await ingestEmit(ingest2, { slug, ord: group.ord, depth, emit, anonId, geo, host, context, fromSocket, gpc });
28669
28693
  }
28670
28694
  }
28671
28695
  }, "applyEffects");
@@ -28727,6 +28751,7 @@ var runInvokeApp = /* @__PURE__ */ __name(async (env, { target, trigger, snapsho
28727
28751
  geo: trigger.kind === "event" ? trigger.action.geo : trigger.geo,
28728
28752
  host: trigger.kind === "event" ? trigger.action.host : trigger.host,
28729
28753
  context: trigger.kind === "event" ? trigger.action.context : void 0,
28754
+ gpc: trigger.kind === "event" ? trigger.action.gpc : trigger.gpc,
28730
28755
  ...startedOnSocket(trigger) ? { fromSocket: true } : {}
28731
28756
  });
28732
28757
  } catch (error61) {
@@ -29810,6 +29835,9 @@ var originAllowed = /* @__PURE__ */ __name((request, env) => {
29810
29835
  if (origin === null) {
29811
29836
  return true;
29812
29837
  }
29838
+ if (JSON.parse(env.ALLOWED_ORIGINS).includes(origin)) {
29839
+ return true;
29840
+ }
29813
29841
  let host;
29814
29842
  try {
29815
29843
  host = new URL(origin).host;
@@ -29852,6 +29880,11 @@ var authorize = /* @__PURE__ */ __name(async (c, { slug, app: app2 }) => {
29852
29880
  if (install === void 0) {
29853
29881
  return refuse(403, "forbidden");
29854
29882
  }
29883
+ const gpc = c.env.GPC === "1" && c.req.header("sec-gpc") === "1";
29884
+ if (gpcDenies(app2.consent.category, gpc)) {
29885
+ addSpanEvent("visitor endpoint refused: Global Privacy Control", { attrs: { app: slug } });
29886
+ return refuse(403, "forbidden");
29887
+ }
29855
29888
  if (await rateLimited(c.env, `${slug}:${anonId}:visitor`, "VISITOR_RATE_LIMITER")) {
29856
29889
  return refuse(429, "rate_limited");
29857
29890
  }
@@ -30626,6 +30659,7 @@ var createApiRouter = /* @__PURE__ */ __name(() => new OpenAPIHono({ defaultHook
30626
30659
  // src/id-graph/anon/connection.ts
30627
30660
  var CONNECTION_CF_HEADER = "x-connection-cf";
30628
30661
  var SESSION_HEADER = "x-session";
30662
+ var GPC_HEADER = "x-gpc";
30629
30663
  var OPEN_PAGE_PARAMS = ["url", "referrer"];
30630
30664
  var MAX_HOST_USER_AGENT_LENGTH = 512;
30631
30665
  var MAX_HOST_LOCALE_LENGTH = 64;
@@ -30636,6 +30670,7 @@ var INTERNAL_HEADERS = /* @__PURE__ */ new Set([
30636
30670
  SITE_ID_HEADER,
30637
30671
  CONNECTION_CF_HEADER,
30638
30672
  SESSION_HEADER,
30673
+ GPC_HEADER,
30639
30674
  TRACE_HEADER,
30640
30675
  CF_DATA_HEADER
30641
30676
  ]);
@@ -30691,7 +30726,8 @@ var connectAttrs = /* @__PURE__ */ __name((request, geo) => {
30691
30726
  "url.full": withoutPageParams(request.url),
30692
30727
  "http.request.headers": JSON.stringify(headers),
30693
30728
  ...cf === void 0 ? {} : { "qinto.cf": JSON.stringify(cf) },
30694
- ...geo === void 0 ? {} : { "qinto.geo": JSON.stringify(loggableGeo(geo)) }
30729
+ ...geo === void 0 ? {} : { "qinto.geo": JSON.stringify(loggableGeo(geo)) },
30730
+ ...request.headers.get(GPC_HEADER) === "1" ? { "qinto.gpc": true } : {}
30695
30731
  };
30696
30732
  }, "connectAttrs");
30697
30733
  var withoutQuery = /* @__PURE__ */ __name((url2) => {
@@ -30737,12 +30773,14 @@ var connectionAttachment = /* @__PURE__ */ __name((request, geo, siteId) => {
30737
30773
  const browserGeoBytes = attachmentFieldBytes("browserGeo", browserGeo);
30738
30774
  const session2 = forwardedSession(request);
30739
30775
  const sessionBytes = attachmentFieldBytes("session", session2);
30776
+ const gpc = request.headers.get(GPC_HEADER) === "1";
30777
+ const gpcBytes = attachmentFieldBytes("gpc", gpc ? true : void 0);
30740
30778
  const siteBytes = attachmentFieldBytes("siteId", siteId);
30741
30779
  const cf = forwardedCf(request);
30742
30780
  const cfSuffix = cf === void 0 ? "" : `,"cf":${JSON.stringify(cf)}`;
30743
30781
  const cfBytes = new TextEncoder().encode(cfSuffix).length;
30744
30782
  const emptyAttrsBytes = new TextEncoder().encode(JSON.stringify({ attrs: {} })).length;
30745
- const fixedBytes = siteBytes + sessionBytes + hostBytes + browserGeoBytes;
30783
+ const fixedBytes = siteBytes + sessionBytes + hostBytes + browserGeoBytes + gpcBytes;
30746
30784
  const includedCf = cfBytes <= MAX_ATTACHMENT_BYTES - emptyAttrsBytes - fixedBytes ? cf : void 0;
30747
30785
  const budgeted = budgetAttrs(attrs, MAX_ATTACHMENT_BYTES - fixedBytes - (includedCf === void 0 ? 0 : cfBytes));
30748
30786
  return {
@@ -30751,7 +30789,8 @@ var connectionAttachment = /* @__PURE__ */ __name((request, geo, siteId) => {
30751
30789
  ...session2 === void 0 ? {} : { session: session2 },
30752
30790
  ...browserGeo === void 0 ? {} : { browserGeo },
30753
30791
  ...includedCf === void 0 ? {} : { cf: includedCf },
30754
- ...host === void 0 ? {} : { host }
30792
+ ...host === void 0 ? {} : { host },
30793
+ ...gpc ? { gpc: true } : {}
30755
30794
  };
30756
30795
  }, "connectionAttachment");
30757
30796
 
@@ -31191,6 +31230,12 @@ var open2 = /* @__PURE__ */ __name(async (c) => {
31191
31230
  if (cf !== void 0) {
31192
31231
  headers.set(CONNECTION_CF_HEADER, cf);
31193
31232
  }
31233
+ headers.delete(GPC_HEADER);
31234
+ const gpc = c.env.GPC === "1" && c.req.header("sec-gpc") === "1";
31235
+ if (gpc) {
31236
+ headers.set(GPC_HEADER, "1");
31237
+ setSpanAttributes({ "qinto.gpc": true });
31238
+ }
31194
31239
  const res = await traced("rpc anon.connect", {}, () => {
31195
31240
  headers.delete(TRACE_HEADER);
31196
31241
  const trace = currentTraceContext();
@@ -31224,14 +31269,14 @@ var open2 = /* @__PURE__ */ __name(async (c) => {
31224
31269
 
31225
31270
  // browser-artifact/meta.json
31226
31271
  var meta_default = {
31227
- version: "0.1.13",
31228
- gitSha: "21a2eff7e038bc98c8c087656c9793c8f3a82434",
31229
- builtAt: "2026-10-01T08:32:14.748Z",
31230
- hash: "3d5d7fe29d7e160413d4cb0e08de724613f89eb314feed6d5d1ec2e7473f7afd"
31272
+ version: "0.1.14",
31273
+ gitSha: "38d2892377935b8b457db896715c24891fc3b1ae",
31274
+ builtAt: "2026-10-02T07:54:26.292Z",
31275
+ hash: "50484908a3b28aa31a614fda30b1b3d803fe5922c8a485079f12e6bbf24cd9c1"
31231
31276
  };
31232
31277
 
31233
31278
  // src/paths/q-js.ts
31234
- import qScript from "./61afaba4cf160e30ef4b71a7ce30a398f71f13e8-q.js.txt";
31279
+ import qScript from "./8809017061697bf9b90fa4d72f7eb2e0f0e00ad4-q.js.txt";
31235
31280
 
31236
31281
  // src/apps-q.ts
31237
31282
  import appsQScript from "./apps-q.json";
@@ -31295,12 +31340,12 @@ var appsMetadata = /* @__PURE__ */ __name(() => {
31295
31340
  })
31296
31341
  );
31297
31342
  }, "appsMetadata");
31298
- var configPrelude = /* @__PURE__ */ __name(({ destination, autoCapture, consentConfiguration, apps }) => {
31299
- const config2 = JSON.stringify({ destination, autoCapture, consentConfiguration, apps });
31343
+ var configPrelude = /* @__PURE__ */ __name(({ destination, autoCapture, consentConfiguration, gpc, apps }) => {
31344
+ const config2 = JSON.stringify({ destination, autoCapture, consentConfiguration, gpc, apps });
31300
31345
  return '(function(d){var s=d.currentScript,g=(s&&s.dataset?s.dataset.qintoGlobal:void 0)||"qinto";var w=window,o=g in w?w[g]:null;if(o&&o._q){o.config=' + config2 + ';}else if(g in w){console.error("window."+g+" is already in use");}else{Object.defineProperty(w,g,{value:{_q:1,config:' + config2 + "},writable:true,enumerable:true,configurable:true});}})(document);\n";
31301
31346
  }, "configPrelude");
31302
- var scriptEtag = /* @__PURE__ */ __name(async ({ destination, autoCapture, consentConfiguration, apps }, withTag) => {
31303
- const settings = await digestFor(JSON.stringify({ autoCapture, consentConfiguration, apps }));
31347
+ var scriptEtag = /* @__PURE__ */ __name(async ({ destination, autoCapture, consentConfiguration, gpc, apps }, withTag) => {
31348
+ const settings = await digestFor(JSON.stringify({ autoCapture, consentConfiguration, gpc, apps }));
31304
31349
  const tag = withTag ? meta_default.hash.slice(0, 32) : "sdk";
31305
31350
  return `"${tag}-${appsQHash}-${encodeURIComponent(destination)}-${settings}"`;
31306
31351
  }, "scriptEtag");
@@ -31311,6 +31356,8 @@ var qJs = /* @__PURE__ */ __name(async (c) => {
31311
31356
  destination,
31312
31357
  autoCapture: parseSettings("AUTO_CAPTURE", c.env.AUTO_CAPTURE),
31313
31358
  consentConfiguration: parseSettings("CONSENT_CONFIGURATION", c.env.CONSENT_CONFIGURATION),
31359
+ // `wrangler types` narrows GPC to its dev default; a site not redeployed since GPC shipped has none.
31360
+ gpc: c.env.GPC === "1",
31314
31361
  apps: appsMetadata()
31315
31362
  };
31316
31363
  const etag = await scriptEtag(config2, withTag);
@@ -31791,14 +31838,14 @@ var wantsTrigger = /* @__PURE__ */ __name((app2, trigger) => {
31791
31838
  }
31792
31839
  return app2.hooks.onEvent.includes(trigger.action.type);
31793
31840
  }, "wantsTrigger");
31794
- var gatePasses = /* @__PURE__ */ __name((entry, trigger, consent2, enforced) => {
31841
+ var gatePasses = /* @__PURE__ */ __name((entry, trigger, consent2, policy) => {
31795
31842
  if (trigger.kind === "event" && trigger.action.origin?.app === entry.slug) {
31796
31843
  return false;
31797
31844
  }
31798
31845
  if (trigger.kind === "event" && trigger.action.type === "consent") {
31799
- return true;
31846
+ return !gpcDenies(entry.app.consent.category, policy.gpc);
31800
31847
  }
31801
- return consentAllows(consent2, entry.slug, entry.app.consent.category, enforced);
31848
+ return consentAllows(consent2, entry.slug, entry.app.consent.category, policy);
31802
31849
  }, "gatePasses");
31803
31850
  var eligibleApps = /* @__PURE__ */ __name((registry3, trigger, consent2, enforced) => {
31804
31851
  const location = visitorLocation(trigger);
@@ -31807,9 +31854,17 @@ var eligibleApps = /* @__PURE__ */ __name((registry3, trigger, consent2, enforce
31807
31854
  const keepListed = rule?.mode === "only";
31808
31855
  const targets = [];
31809
31856
  const geoSkipped = [];
31857
+ const gpcSkipped = [];
31858
+ const gpc = trigger.kind === "connect" ? trigger.gpc === true : trigger.action.gpc === true;
31810
31859
  for (const slug of registry3.order) {
31811
31860
  const app2 = registry3.apps[slug];
31812
- if (app2 === void 0 || !wantsTrigger(app2, trigger) || !gatePasses({ slug, app: app2 }, trigger, consent2, enforced)) {
31861
+ if (app2 === void 0 || !wantsTrigger(app2, trigger)) {
31862
+ continue;
31863
+ }
31864
+ if (!gatePasses({ slug, app: app2 }, trigger, consent2, { enforced, gpc })) {
31865
+ if (gpc && gatePasses({ slug, app: app2 }, trigger, consent2, { enforced, gpc: false })) {
31866
+ gpcSkipped.push(slug);
31867
+ }
31813
31868
  continue;
31814
31869
  }
31815
31870
  const { runs, skipped } = geoRunnableInstalls(slug, app2, location);
@@ -31820,20 +31875,21 @@ var eligibleApps = /* @__PURE__ */ __name((registry3, trigger, consent2, enforce
31820
31875
  }
31821
31876
  targets.push({ slug, app: app2, installs });
31822
31877
  }
31823
- return { targets, geoSkipped };
31878
+ return { targets, geoSkipped, gpcSkipped };
31824
31879
  }, "eligibleApps");
31825
31880
 
31826
31881
  // src/apps/fan-out.ts
31827
31882
  var fanOutToApps = /* @__PURE__ */ __name(async (env, { trigger, snapshot, trace }, { deliverEffects }) => {
31828
31883
  const { registry: registry3, error: error61 } = siteRegistry();
31829
- const { targets, geoSkipped } = eligibleApps(registry3, trigger, snapshot.consent, consentEnforced(env));
31830
- if (error61 === void 0 && targets.length === 0 && geoSkipped.length === 0) {
31884
+ const { targets, geoSkipped, gpcSkipped } = eligibleApps(registry3, trigger, snapshot.consent, consentEnforced(env));
31885
+ if (error61 === void 0 && targets.length === 0 && geoSkipped.length === 0 && gpcSkipped.length === 0) {
31831
31886
  return;
31832
31887
  }
31833
31888
  const attrs = {
31834
31889
  "fan_out.kind": trigger.kind,
31835
31890
  "fan_out.apps": targets.length,
31836
- ...geoSkipped.length === 0 ? {} : { "fan_out.geo_skipped": geoSkipped.join(",") }
31891
+ ...geoSkipped.length === 0 ? {} : { "fan_out.geo_skipped": geoSkipped.join(",") },
31892
+ ...gpcSkipped.length === 0 ? {} : { "fan_out.gpc_skipped": gpcSkipped.join(",") }
31837
31893
  };
31838
31894
  await runInvocation({ name: "app.fan_out", trace, attrs }, async () => {
31839
31895
  if (error61 !== void 0) {
@@ -31912,18 +31968,23 @@ var chainEntries = /* @__PURE__ */ __name((registry3, action) => {
31912
31968
  const location = visitorLocation({ kind: "event", action });
31913
31969
  const entries = [];
31914
31970
  const geoSkipped = [];
31971
+ const gpcSkipped = [];
31915
31972
  for (const slug of registry3.order) {
31916
31973
  const app2 = registry3.apps[slug];
31917
31974
  if (app2 === void 0 || !app2.hooks.transform.includes(action.type)) {
31918
31975
  continue;
31919
31976
  }
31977
+ if (gpcDenies(app2.consent.category, action.gpc === true)) {
31978
+ gpcSkipped.push(slug);
31979
+ continue;
31980
+ }
31920
31981
  const { runs, skipped } = geoRunnableInstalls(slug, app2, location);
31921
31982
  geoSkipped.push(...skipped);
31922
31983
  for (const install of runs) {
31923
31984
  entries.push({ slug, app: app2, install: { id: install.id, ord: install.ord, label: install.label } });
31924
31985
  }
31925
31986
  }
31926
- return { entries, geoSkipped };
31987
+ return { entries, geoSkipped, gpcSkipped };
31927
31988
  }, "chainEntries");
31928
31989
  var trackPayloadSchema = external_exports.object({
31929
31990
  event: external_exports.string().min(1),
@@ -32056,6 +32117,7 @@ var buildEffectsRelease = /* @__PURE__ */ __name(({ effects, action, deliveries
32056
32117
  geo: action.geo,
32057
32118
  host: action.host,
32058
32119
  context: action.context,
32120
+ gpc: action.gpc,
32059
32121
  ...startedOnSocket({ kind: "event", action }) ? { fromSocket: true } : {}
32060
32122
  });
32061
32123
  }
@@ -32066,13 +32128,14 @@ var runTransformChain = /* @__PURE__ */ __name(async (env, { action, snapshot, d
32066
32128
  if (error61 !== void 0) {
32067
32129
  throw new TransformChainError(`the apps registry is malformed: ${error61}`);
32068
32130
  }
32069
- const { entries, geoSkipped } = chainEntries(registry3, action);
32131
+ const { entries, geoSkipped, gpcSkipped } = chainEntries(registry3, action);
32070
32132
  const attrs = {
32071
32133
  "transform.entries": entries.length,
32072
- ...geoSkipped.length === 0 ? {} : { "transform.geo_skipped": geoSkipped.join(",") }
32134
+ ...geoSkipped.length === 0 ? {} : { "transform.geo_skipped": geoSkipped.join(",") },
32135
+ ...gpcSkipped.length === 0 ? {} : { "transform.gpc_skipped": gpcSkipped.join(",") }
32073
32136
  };
32074
32137
  if (entries.length === 0) {
32075
- if (geoSkipped.length > 0) {
32138
+ if (geoSkipped.length > 0 || gpcSkipped.length > 0) {
32076
32139
  await traced("apps.transform_chain", { attrs }, () => Promise.resolve());
32077
32140
  }
32078
32141
  return { dropped: false, action, effects: [] };
@@ -32326,7 +32389,7 @@ var allCaptures = /* @__PURE__ */ __name((sql, now, cache) => {
32326
32389
  }, "allCaptures");
32327
32390
 
32328
32391
  // src/apps/capture.ts
32329
- var appWriteAllowed = /* @__PURE__ */ __name((registry3, slug, { consent: consent2, enforced, location }) => {
32392
+ var appWriteAllowed = /* @__PURE__ */ __name((registry3, slug, { consent: consent2, enforced, gpc, location }) => {
32330
32393
  const app2 = registry3.apps[slug];
32331
32394
  if (app2 === void 0) {
32332
32395
  addSpanEvent("capture dropped: the app is not in the registry", { level: "warn", attrs: { app: slug } });
@@ -32336,7 +32399,7 @@ var appWriteAllowed = /* @__PURE__ */ __name((registry3, slug, { consent: consen
32336
32399
  addSpanEvent("capture dropped: no install runs for this visitor", { level: "warn", attrs: { app: slug } });
32337
32400
  return false;
32338
32401
  }
32339
- if (!consentAllows(consent2, slug, app2.consent.category, enforced)) {
32402
+ if (!consentAllows(consent2, slug, app2.consent.category, { enforced, gpc })) {
32340
32403
  addSpanEvent("capture dropped by the consent gate", { attrs: { app: slug } });
32341
32404
  return false;
32342
32405
  }
@@ -33139,7 +33202,7 @@ var appPushFrame = /* @__PURE__ */ __name(({ push, context, consent: consent2 })
33139
33202
  addSpanEvent("app push dropped: the app is not in the registry", { level: "warn", attrs: { app: slug } });
33140
33203
  return null;
33141
33204
  }
33142
- if (!consentAllows(consent2, slug, app2.consent.category, enforced)) {
33205
+ if (!consentAllows(consent2, slug, app2.consent.category, { enforced, gpc: false })) {
33143
33206
  addSpanEvent("app push dropped by the consent gate", { attrs: { app: slug } });
33144
33207
  return null;
33145
33208
  }
@@ -33167,10 +33230,18 @@ var appPushFrame = /* @__PURE__ */ __name(({ push, context, consent: consent2 })
33167
33230
  }
33168
33231
  return frame;
33169
33232
  }, "appPushFrame");
33170
- var connectionPushFrame = /* @__PURE__ */ __name((frame, registry3, location) => {
33233
+ var connectionPushFrame = /* @__PURE__ */ __name((frame, registry3, location, gpc) => {
33234
+ const sender = registry3.apps[frame.app];
33235
+ if (sender !== void 0 && gpcDenies(sender.consent.category, gpc)) {
33236
+ addSpanEvent("app push skipped: Global Privacy Control", { attrs: { app: frame.app } });
33237
+ return null;
33238
+ }
33171
33239
  const runningApps = /* @__PURE__ */ new Set();
33172
33240
  const runningInstalls = /* @__PURE__ */ new Set();
33173
33241
  for (const [slug, app2] of Object.entries(registry3.apps)) {
33242
+ if (gpcDenies(app2.consent.category, gpc)) {
33243
+ continue;
33244
+ }
33174
33245
  for (const install of geoRunnableInstalls(slug, app2, location).runs) {
33175
33246
  runningApps.add(slug);
33176
33247
  runningInstalls.add(install.id);
@@ -33183,8 +33254,8 @@ var connectionPushFrame = /* @__PURE__ */ __name((frame, registry3, location) =>
33183
33254
  const reaches = frame.install === void 0 ? runningApps.has(frame.app) : runningInstalls.has(frame.install);
33184
33255
  return reaches ? JSON.stringify(frame) : null;
33185
33256
  }, "connectionPushFrame");
33186
- var sharedContextFrame = /* @__PURE__ */ __name((context, consent2, stored) => {
33187
- const readable = readableSharedContext(context.registry, consent2, context.consentEnforced, stored);
33257
+ var sharedContextFrame = /* @__PURE__ */ __name((context, consent2, stored, gpc) => {
33258
+ const readable = readableSharedContext(context.registry, consent2, { enforced: context.consentEnforced, gpc }, stored);
33188
33259
  return JSON.stringify({ t: "sharedContext", context: sharedContextWire(readable), ...consent2 });
33189
33260
  }, "sharedContextFrame");
33190
33261
  var socketsBySite = /* @__PURE__ */ __name((ctx) => {
@@ -33454,7 +33525,7 @@ var browserActionContext = /* @__PURE__ */ __name((frame, host, session2) => {
33454
33525
  return context;
33455
33526
  }, "browserActionContext");
33456
33527
  var actionFromFrame = /* @__PURE__ */ __name((frame, userId, connection = {}) => {
33457
- const { cf: geo, host, session: session2 } = connection;
33528
+ const { cf: geo, host, session: session2, gpc } = connection;
33458
33529
  switch (frame.t) {
33459
33530
  case "identify": {
33460
33531
  const identifier = frame.id === void 0 ? void 0 : classifyIdentifier(frame.id);
@@ -33467,7 +33538,8 @@ var actionFromFrame = /* @__PURE__ */ __name((frame, userId, connection = {}) =>
33467
33538
  context: browserActionContext(frame.context, host, session2),
33468
33539
  browserResults: frame.appResults,
33469
33540
  geo,
33470
- host
33541
+ host,
33542
+ gpc
33471
33543
  });
33472
33544
  }
33473
33545
  case "track": {
@@ -33480,11 +33552,12 @@ var actionFromFrame = /* @__PURE__ */ __name((frame, userId, connection = {}) =>
33480
33552
  browserResults: frame.appResults,
33481
33553
  geo,
33482
33554
  host,
33555
+ gpc,
33483
33556
  ...frame.installs === void 0 ? {} : { installs: frame.installs }
33484
33557
  });
33485
33558
  }
33486
33559
  case "alias": {
33487
- return buildAction({ type: "alias", userId, source: "website", payload: { alias: frame.alias }, geo, host });
33560
+ return buildAction({ type: "alias", userId, source: "website", payload: { alias: frame.alias }, geo, host, gpc });
33488
33561
  }
33489
33562
  case "consent": {
33490
33563
  return buildAction({
@@ -33494,7 +33567,8 @@ var actionFromFrame = /* @__PURE__ */ __name((frame, userId, connection = {}) =>
33494
33567
  payload: { categories: frame.categories ?? {}, apps: frame.apps ?? {} },
33495
33568
  context: browserActionContext(frame.context, host, session2),
33496
33569
  geo,
33497
- host
33570
+ host,
33571
+ gpc
33498
33572
  });
33499
33573
  }
33500
33574
  }
@@ -33575,7 +33649,9 @@ var AnonDO = class extends DurableObject2 {
33575
33649
  kind: "connect",
33576
33650
  ...attachment.cf === void 0 ? {} : { geo: attachment.cf },
33577
33651
  host: attachment.host,
33578
- ...page === void 0 ? {} : { page }
33652
+ ...page === void 0 ? {} : { page },
33653
+ ...attachment.session === void 0 ? {} : { session: attachment.session },
33654
+ gpc: attachment.gpc
33579
33655
  },
33580
33656
  userId,
33581
33657
  context
@@ -33616,7 +33692,10 @@ var AnonDO = class extends DurableObject2 {
33616
33692
  return null;
33617
33693
  }
33618
33694
  if (frame.t === "capture") {
33619
- const { accepted } = await this.capture({ apps: frame.apps, location: socketLocation(attachment.cf) }, site);
33695
+ const { accepted } = await this.capture(
33696
+ { apps: frame.apps, location: socketLocation(attachment.cf), gpc: attachment.gpc === true },
33697
+ site
33698
+ );
33620
33699
  this.respond(ws, { t: "captureAck", ref, anonId: userId, accepted });
33621
33700
  return null;
33622
33701
  }
@@ -33762,7 +33841,7 @@ var AnonDO = class extends DurableObject2 {
33762
33841
  addSpanEvent("capture dropped: no visitor state", { level: "warn" });
33763
33842
  return { accepted: {} };
33764
33843
  }
33765
- return this.runCaptures(input2.apps, site, input2.location);
33844
+ return this.runCaptures(input2.apps, site, { location: input2.location, gpc: input2.gpc });
33766
33845
  });
33767
33846
  });
33768
33847
  }
@@ -33776,7 +33855,7 @@ var AnonDO = class extends DurableObject2 {
33776
33855
  this.cleanupAlarm = await seedCleanupAlarm(this.ctx.storage, now, lastActivityAt(this.kv) ?? now, this.cleanupAlarm);
33777
33856
  seedMeta(this.kv, input2.anonId, now);
33778
33857
  touchActivity(this.kv, now);
33779
- return this.runCaptures(input2.apps, site, null);
33858
+ return this.runCaptures(input2.apps, site, { location: null, gpc: false });
33780
33859
  });
33781
33860
  });
33782
33861
  }
@@ -33793,6 +33872,7 @@ var AnonDO = class extends DurableObject2 {
33793
33872
  if (!appWriteAllowed(context.registry, input2.slug, {
33794
33873
  consent: consentState2(this.kv),
33795
33874
  enforced: context.consentEnforced,
33875
+ gpc: false,
33796
33876
  location: null
33797
33877
  })) {
33798
33878
  return;
@@ -33805,9 +33885,14 @@ var AnonDO = class extends DurableObject2 {
33805
33885
  });
33806
33886
  });
33807
33887
  }
33808
- async runCaptures(apps, site, location) {
33888
+ async runCaptures(apps, site, { location, gpc }) {
33809
33889
  const context = await this.sites.resolve(site, Date.now());
33810
- const writes = acceptedCaptures(context.registry, apps, { consent: consentState2(this.kv), enforced: context.consentEnforced, location });
33890
+ const writes = acceptedCaptures(context.registry, apps, {
33891
+ consent: consentState2(this.kv),
33892
+ enforced: context.consentEnforced,
33893
+ gpc,
33894
+ location
33895
+ });
33811
33896
  return { accepted: this.storeCaptures(writes) };
33812
33897
  }
33813
33898
  storeCaptures(writes) {
@@ -33836,7 +33921,12 @@ var AnonDO = class extends DurableObject2 {
33836
33921
  }
33837
33922
  const context = await this.sites.resolve(site, Date.now());
33838
33923
  const { registry: registry3 } = context;
33839
- if (!appWriteAllowed(registry3, input2.slug, { consent: consentState2(this.kv), enforced: context.consentEnforced, location: null })) {
33924
+ if (!appWriteAllowed(registry3, input2.slug, {
33925
+ consent: consentState2(this.kv),
33926
+ enforced: context.consentEnforced,
33927
+ gpc: false,
33928
+ location: null
33929
+ })) {
33840
33930
  return [];
33841
33931
  }
33842
33932
  const granted = registry3.apps[input2.slug]?.data.includes(SHARED_CONTEXT_CAPABILITY) === true;
@@ -33883,9 +33973,11 @@ var AnonDO = class extends DurableObject2 {
33883
33973
  // sent even when there is nothing stored: without that baseline a browser app cannot tell an empty
33884
33974
  // context from one that has not arrived yet.
33885
33975
  sendSharedContext(sockets, context) {
33886
- const serialized = sharedContextFrame(context, consentState2(this.kv), allContext(this.sql, "shared", this.contextMirror));
33976
+ const consent2 = consentState2(this.kv);
33977
+ const stored = allContext(this.sql, "shared", this.contextMirror);
33887
33978
  for (const socket of sockets) {
33888
- sendFrame(socket, serialized);
33979
+ const { gpc } = socket.deserializeAttachment();
33980
+ sendFrame(socket, sharedContextFrame(context, consent2, stored, gpc === true));
33889
33981
  }
33890
33982
  }
33891
33983
  // Every open socket, each under its own site's registry and consent policy. A site whose context
@@ -33926,10 +34018,10 @@ var AnonDO = class extends DurableObject2 {
33926
34018
  }
33927
34019
  const consent2 = consentState2(this.kv);
33928
34020
  const enforced = context.consentEnforced;
33929
- if (!consentAllows(consent2, slug, app2.consent.category, enforced)) {
34021
+ if (!consentAllows(consent2, slug, app2.consent.category, { enforced, gpc: false })) {
33930
34022
  return readableContext(void 0, {});
33931
34023
  }
33932
- const shared = app2.data.includes(SHARED_CONTEXT_CAPABILITY) ? readableSharedContext(registry3, consent2, enforced, allContext(this.sql, "shared", this.contextMirror)) : {};
34024
+ const shared = app2.data.includes(SHARED_CONTEXT_CAPABILITY) ? readableSharedContext(registry3, consent2, { enforced, gpc: false }, allContext(this.sql, "shared", this.contextMirror)) : {};
33933
34025
  return readableContext(contextEntry(this.sql, "private", slug, this.contextMirror), shared);
33934
34026
  });
33935
34027
  });
@@ -33944,7 +34036,7 @@ var AnonDO = class extends DurableObject2 {
33944
34036
  if (unused || app2 === void 0 || !app2.data.includes("facts")) {
33945
34037
  return null;
33946
34038
  }
33947
- if (!consentAllows(consentState2(this.kv), slug, app2.consent.category, context.consentEnforced)) {
34039
+ if (!consentAllows(consentState2(this.kv), slug, app2.consent.category, { enforced: context.consentEnforced, gpc: false })) {
33948
34040
  return null;
33949
34041
  }
33950
34042
  if (this.wiped) {
@@ -33963,7 +34055,7 @@ var AnonDO = class extends DurableObject2 {
33963
34055
  if (app2 === void 0) {
33964
34056
  return false;
33965
34057
  }
33966
- return consentAllows(consentState2(this.kv), slug, app2.consent.category, context.consentEnforced);
34058
+ return consentAllows(consentState2(this.kv), slug, app2.consent.category, { enforced: context.consentEnforced, gpc: false });
33967
34059
  });
33968
34060
  });
33969
34061
  }
@@ -33975,8 +34067,8 @@ var AnonDO = class extends DurableObject2 {
33975
34067
  return;
33976
34068
  }
33977
34069
  for (const socket of this.ctx.getWebSockets(context.domainId)) {
33978
- const { cf } = socket.deserializeAttachment();
33979
- const serialized = connectionPushFrame(frame, context.registry, socketLocation(cf));
34070
+ const { cf, gpc } = socket.deserializeAttachment();
34071
+ const serialized = connectionPushFrame(frame, context.registry, socketLocation(cf), gpc === true);
33980
34072
  if (serialized !== null) {
33981
34073
  sendFrame(socket, serialized);
33982
34074
  }
@@ -34122,7 +34214,7 @@ var AnonDO = class extends DurableObject2 {
34122
34214
  shared: readableSharedContext(
34123
34215
  context.registry,
34124
34216
  consentState2(this.kv),
34125
- context.consentEnforced,
34217
+ { enforced: context.consentEnforced, gpc: false },
34126
34218
  allContext(this.sql, "shared", this.contextMirror)
34127
34219
  )
34128
34220
  },
@@ -34138,8 +34230,8 @@ var AnonDO = class extends DurableObject2 {
34138
34230
  }
34139
34231
  appFanOut(trigger, anonId, context) {
34140
34232
  const { registry: registry3, registryError, consentEnforced: consentEnforced2 } = context;
34141
- const { targets, geoSkipped } = eligibleApps(registry3, trigger, consentState2(this.kv), consentEnforced2);
34142
- if (registryError === void 0 && targets.length === 0 && geoSkipped.length === 0) {
34233
+ const { targets, geoSkipped, gpcSkipped } = eligibleApps(registry3, trigger, consentState2(this.kv), consentEnforced2);
34234
+ if (registryError === void 0 && targets.length === 0 && geoSkipped.length === 0 && gpcSkipped.length === 0) {
34143
34235
  return;
34144
34236
  }
34145
34237
  const job = { trigger, snapshot: this.appsSnapshot(anonId, context), trace: currentTraceContext() };
@@ -34752,7 +34844,7 @@ var GlobalDO = class extends DurableObject3 {
34752
34844
  if (await this.discardIfUnused()) {
34753
34845
  return null;
34754
34846
  }
34755
- if (!consentAllows(globalConsentState(this.sql), gate.slug, gate.category, gate.enforced)) {
34847
+ if (!consentAllows(globalConsentState(this.sql), gate.slug, gate.category, { enforced: gate.enforced, gpc: false })) {
34756
34848
  return null;
34757
34849
  }
34758
34850
  return linkedAnonsPage(this.sql, afterRowId, limit);