@blotout/qinto-cli 0.1.3 → 0.1.5
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/index.js +1567 -1451
- package/dist/index.js.map +1 -1
- package/dist/worker-artifact/app-runtime/index.js +310 -99
- package/dist/worker-artifact/main/{9301296b51353552dafe33a97c95e9755e6108db-q.js.txt → 9dcfd236748459af038da772477100c4bb0223b7-q.js.txt} +1 -1
- package/dist/worker-artifact/main/index.js +263 -43
- package/dist/worker-artifact/version.json +6 -6
- package/package.json +1 -1
- package/templates/app/full/ui/src/pages/index.astro +1 -1
|
@@ -14566,7 +14566,7 @@ var actionContextFields = {
|
|
|
14566
14566
|
locale: external_exports.string().min(1).max(64).optional(),
|
|
14567
14567
|
provenance: external_exports.enum(["edge", "caller"])
|
|
14568
14568
|
}).strict().optional(),
|
|
14569
|
-
session: external_exports.object({ id: external_exports.string().min(1).max(64), isNew: external_exports.boolean() }).strict().optional()
|
|
14569
|
+
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()
|
|
14570
14570
|
};
|
|
14571
14571
|
var actionContextSchema = external_exports.discriminatedUnion("source", [
|
|
14572
14572
|
external_exports.object({ source: external_exports.literal("browser"), ...actionContextFields }).strict(),
|
|
@@ -14585,7 +14585,7 @@ var envelopeRequestSchema = external_exports.object({
|
|
|
14585
14585
|
properties: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
14586
14586
|
geo: external_exports.record(external_exports.string(), external_exports.string()).optional()
|
|
14587
14587
|
}).strict(),
|
|
14588
|
-
consent: external_exports.object({ categories: external_exports.record(external_exports.string(), external_exports.boolean()), apps: external_exports.record(external_exports.string(), external_exports.boolean()) }).strict().optional(),
|
|
14588
|
+
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(),
|
|
14589
14589
|
geo: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
14590
14590
|
// Only what this app captured or wrote for this visitor; `updatedAt` is when the current value
|
|
14591
14591
|
// was first seen, which is the click time a CAPI `fbc` is built from.
|
|
@@ -14928,6 +14928,122 @@ var newSpanId = () => {
|
|
|
14928
14928
|
return randomHex(8);
|
|
14929
14929
|
};
|
|
14930
14930
|
|
|
14931
|
+
// ../../../libs/tail-trace/src/redact.ts
|
|
14932
|
+
var SENSITIVE_URL_PARAMS = /* @__PURE__ */ new Set([
|
|
14933
|
+
"access_token",
|
|
14934
|
+
"api_key",
|
|
14935
|
+
"api_secret",
|
|
14936
|
+
"client_secret",
|
|
14937
|
+
"code",
|
|
14938
|
+
"key",
|
|
14939
|
+
"password",
|
|
14940
|
+
"refresh_token",
|
|
14941
|
+
"secret",
|
|
14942
|
+
"session",
|
|
14943
|
+
"session_id",
|
|
14944
|
+
"token"
|
|
14945
|
+
]);
|
|
14946
|
+
var PARAM_MATCHER = /(^|[?&])([^=&?\s]+)=[^&\s]*/g;
|
|
14947
|
+
var SENSITIVE_KEY_STEMS = [
|
|
14948
|
+
"apikey",
|
|
14949
|
+
"authorization",
|
|
14950
|
+
"bearer",
|
|
14951
|
+
"credential",
|
|
14952
|
+
"passwd",
|
|
14953
|
+
"password",
|
|
14954
|
+
"privatekey",
|
|
14955
|
+
"secret",
|
|
14956
|
+
"sessionid",
|
|
14957
|
+
"signature",
|
|
14958
|
+
"token"
|
|
14959
|
+
];
|
|
14960
|
+
var isSensitiveKey = (key) => {
|
|
14961
|
+
const normalized = key.toLowerCase().replaceAll(/[^a-z0-9]/g, "");
|
|
14962
|
+
return SENSITIVE_KEY_STEMS.some((stem) => normalized.includes(stem));
|
|
14963
|
+
};
|
|
14964
|
+
var redactedJson = (value, redact) => {
|
|
14965
|
+
if (Array.isArray(value)) {
|
|
14966
|
+
return value.map((entry) => redactedJson(entry, redact));
|
|
14967
|
+
}
|
|
14968
|
+
if (typeof value === "object" && value !== null) {
|
|
14969
|
+
return Object.fromEntries(
|
|
14970
|
+
Object.entries(value).map(([key, entry]) => {
|
|
14971
|
+
return [key, isSensitiveKey(key) ? "[REDACTED]" : redactedJson(entry, redact)];
|
|
14972
|
+
})
|
|
14973
|
+
);
|
|
14974
|
+
}
|
|
14975
|
+
return typeof value === "string" ? redact(value) : value;
|
|
14976
|
+
};
|
|
14977
|
+
var redactedBody = (value, redact) => {
|
|
14978
|
+
let parsed;
|
|
14979
|
+
try {
|
|
14980
|
+
parsed = JSON.parse(value);
|
|
14981
|
+
} catch {
|
|
14982
|
+
return redact(value);
|
|
14983
|
+
}
|
|
14984
|
+
return typeof parsed === "object" && parsed !== null ? JSON.stringify(redactedJson(parsed, redact)) : redact(value);
|
|
14985
|
+
};
|
|
14986
|
+
var percentEncoded = (secret) => {
|
|
14987
|
+
try {
|
|
14988
|
+
return [encodeURIComponent(secret)];
|
|
14989
|
+
} catch {
|
|
14990
|
+
return [];
|
|
14991
|
+
}
|
|
14992
|
+
};
|
|
14993
|
+
var encodings = (secret) => {
|
|
14994
|
+
const form = String(new URLSearchParams({ v: secret })).slice(2);
|
|
14995
|
+
return [.../* @__PURE__ */ new Set([secret, JSON.stringify(secret).slice(1, -1), form, ...percentEncoded(secret)])];
|
|
14996
|
+
};
|
|
14997
|
+
var redactUrlParams = (value) => {
|
|
14998
|
+
return value.replaceAll(PARAM_MATCHER, (match, separator, param) => {
|
|
14999
|
+
return SENSITIVE_URL_PARAMS.has(param.toLowerCase()) ? `${separator}${param}=[REDACTED]` : match;
|
|
15000
|
+
});
|
|
15001
|
+
};
|
|
15002
|
+
var mappedAttrs = (attrs, redact) => {
|
|
15003
|
+
const redacted = {};
|
|
15004
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
15005
|
+
redacted[key] = typeof value === "string" ? redact(value) : value;
|
|
15006
|
+
}
|
|
15007
|
+
return redacted;
|
|
15008
|
+
};
|
|
15009
|
+
var redactAttrs = (attrs) => {
|
|
15010
|
+
return mappedAttrs(attrs, redactUrlParams);
|
|
15011
|
+
};
|
|
15012
|
+
var redactedEvent = (event, redact) => {
|
|
15013
|
+
return {
|
|
15014
|
+
...event,
|
|
15015
|
+
name: redact(event.name),
|
|
15016
|
+
...event.attrs === void 0 ? {} : { attrs: mappedAttrs(event.attrs, redact) }
|
|
15017
|
+
};
|
|
15018
|
+
};
|
|
15019
|
+
var redactedSpan = (span, redact) => {
|
|
15020
|
+
return {
|
|
15021
|
+
...span,
|
|
15022
|
+
name: redact(span.name),
|
|
15023
|
+
...span.attrs === void 0 ? {} : { attrs: mappedAttrs(span.attrs, redact) },
|
|
15024
|
+
...span.events === void 0 ? {} : { events: span.events.map((event) => redactedEvent(event, redact)) },
|
|
15025
|
+
...span.error === void 0 ? {} : { error: redact(span.error) }
|
|
15026
|
+
};
|
|
15027
|
+
};
|
|
15028
|
+
var redactSpans = (spans, redact) => {
|
|
15029
|
+
return spans.map((span) => {
|
|
15030
|
+
return redactedSpan(span, redact);
|
|
15031
|
+
});
|
|
15032
|
+
};
|
|
15033
|
+
var spanRedactor = (secrets) => {
|
|
15034
|
+
const forms = secrets.flatMap(encodings);
|
|
15035
|
+
const known = (value) => {
|
|
15036
|
+
let redacted = redactUrlParams(value);
|
|
15037
|
+
for (const form of forms) {
|
|
15038
|
+
redacted = redacted.replaceAll(form, "[REDACTED]");
|
|
15039
|
+
}
|
|
15040
|
+
return redacted;
|
|
15041
|
+
};
|
|
15042
|
+
return (value) => {
|
|
15043
|
+
return redactedBody(value, known);
|
|
15044
|
+
};
|
|
15045
|
+
};
|
|
15046
|
+
|
|
14931
15047
|
// ../../../libs/tail-trace/src/scope.ts
|
|
14932
15048
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
14933
15049
|
var scopes = new AsyncLocalStorage();
|
|
@@ -14984,7 +15100,7 @@ var logRecord = (record2) => {
|
|
|
14984
15100
|
console.log(formatSpansRecord(record2));
|
|
14985
15101
|
};
|
|
14986
15102
|
var runInvocation = async (input, run) => {
|
|
14987
|
-
const buffer = { spans: [], flushed: false };
|
|
15103
|
+
const buffer = { spans: [], flushed: false, pending: [] };
|
|
14988
15104
|
const traceId = input.trace?.traceId ?? newTraceId();
|
|
14989
15105
|
const root = startSpan({ traceId, parent: input.trace?.parent, name: input.name, attrs: input.attrs });
|
|
14990
15106
|
try {
|
|
@@ -14995,10 +15111,12 @@ var runInvocation = async (input, run) => {
|
|
|
14995
15111
|
throw error51;
|
|
14996
15112
|
} finally {
|
|
14997
15113
|
root.end = Date.now();
|
|
15114
|
+
await Promise.allSettled(buffer.pending);
|
|
14998
15115
|
buffer.spans.push(root);
|
|
14999
15116
|
buffer.flushed = true;
|
|
15000
15117
|
const emit = input.emit ?? logRecord;
|
|
15001
|
-
|
|
15118
|
+
const spans = input.redact === void 0 ? buffer.spans : redactSpans(buffer.spans, input.redact);
|
|
15119
|
+
emit(budgetSpans(spans, input.budget ?? MAX_SPANS_BYTES));
|
|
15002
15120
|
}
|
|
15003
15121
|
};
|
|
15004
15122
|
|
|
@@ -15031,54 +15149,6 @@ var parseTraceContext = (header) => {
|
|
|
15031
15149
|
return { traceId: parsed["traceId"], ...parent === void 0 ? {} : { parent } };
|
|
15032
15150
|
};
|
|
15033
15151
|
|
|
15034
|
-
// ../../../libs/tail-trace/src/redact.ts
|
|
15035
|
-
var SENSITIVE_URL_PARAMS = /* @__PURE__ */ new Set([
|
|
15036
|
-
"access_token",
|
|
15037
|
-
"api_key",
|
|
15038
|
-
"api_secret",
|
|
15039
|
-
"client_secret",
|
|
15040
|
-
"code",
|
|
15041
|
-
"key",
|
|
15042
|
-
"password",
|
|
15043
|
-
"refresh_token",
|
|
15044
|
-
"secret",
|
|
15045
|
-
"session",
|
|
15046
|
-
"session_id",
|
|
15047
|
-
"token"
|
|
15048
|
-
]);
|
|
15049
|
-
var PARAM_MATCHER = /(^|[?&])([^=&?\s]+)=[^&\s]*/g;
|
|
15050
|
-
var redactUrlParams = (value) => {
|
|
15051
|
-
return value.replaceAll(PARAM_MATCHER, (match, separator, param) => {
|
|
15052
|
-
return SENSITIVE_URL_PARAMS.has(param.toLowerCase()) ? `${separator}${param}=[REDACTED]` : match;
|
|
15053
|
-
});
|
|
15054
|
-
};
|
|
15055
|
-
var redactAttrs = (attrs) => {
|
|
15056
|
-
const redacted = {};
|
|
15057
|
-
for (const [key, value] of Object.entries(attrs)) {
|
|
15058
|
-
redacted[key] = typeof value === "string" ? redactUrlParams(value) : value;
|
|
15059
|
-
}
|
|
15060
|
-
return redacted;
|
|
15061
|
-
};
|
|
15062
|
-
var redactedEvent = (event) => {
|
|
15063
|
-
return {
|
|
15064
|
-
...event,
|
|
15065
|
-
name: redactUrlParams(event.name),
|
|
15066
|
-
...event.attrs === void 0 ? {} : { attrs: redactAttrs(event.attrs) }
|
|
15067
|
-
};
|
|
15068
|
-
};
|
|
15069
|
-
var redactedSpan = (span) => {
|
|
15070
|
-
return {
|
|
15071
|
-
...span,
|
|
15072
|
-
name: redactUrlParams(span.name),
|
|
15073
|
-
...span.attrs === void 0 ? {} : { attrs: redactAttrs(span.attrs) },
|
|
15074
|
-
...span.events === void 0 ? {} : { events: span.events.map(redactedEvent) },
|
|
15075
|
-
...span.error === void 0 ? {} : { error: redactUrlParams(span.error) }
|
|
15076
|
-
};
|
|
15077
|
-
};
|
|
15078
|
-
var redactAppSpans = (record2) => {
|
|
15079
|
-
return { ...record2, spans: record2.spans.map(redactedSpan) };
|
|
15080
|
-
};
|
|
15081
|
-
|
|
15082
15152
|
// ../../../libs/tail-trace/src/trace.ts
|
|
15083
15153
|
var traced = async (name, options, run) => {
|
|
15084
15154
|
const scope = currentScope();
|
|
@@ -15099,22 +15169,37 @@ var traced = async (name, options, run) => {
|
|
|
15099
15169
|
}
|
|
15100
15170
|
}
|
|
15101
15171
|
};
|
|
15102
|
-
var
|
|
15172
|
+
var liveScope = () => {
|
|
15103
15173
|
const scope = currentScope();
|
|
15104
15174
|
if (scope === void 0 || scope.buffer.flushed) {
|
|
15105
15175
|
return void 0;
|
|
15106
15176
|
}
|
|
15107
|
-
return scope
|
|
15177
|
+
return scope;
|
|
15108
15178
|
};
|
|
15109
15179
|
var setSpanAttributes = (attrs) => {
|
|
15110
|
-
const span =
|
|
15180
|
+
const span = liveScope()?.span;
|
|
15111
15181
|
if (span === void 0) {
|
|
15112
15182
|
return;
|
|
15113
15183
|
}
|
|
15114
15184
|
span.attrs = { ...span.attrs, ...attrs };
|
|
15115
15185
|
};
|
|
15186
|
+
var deferSpanAttributes = (values) => {
|
|
15187
|
+
const scope = liveScope();
|
|
15188
|
+
if (scope === void 0) {
|
|
15189
|
+
return;
|
|
15190
|
+
}
|
|
15191
|
+
scope.buffer.pending.push(
|
|
15192
|
+
// The continuation inherits the async context it was registered in, so this lands on the span
|
|
15193
|
+
// that was current when the capture began, not on whatever is current when the value arrives.
|
|
15194
|
+
values.then((attrs) => {
|
|
15195
|
+
if (attrs !== void 0) {
|
|
15196
|
+
setSpanAttributes(attrs);
|
|
15197
|
+
}
|
|
15198
|
+
})
|
|
15199
|
+
);
|
|
15200
|
+
};
|
|
15116
15201
|
var addSpanEvent = (name, options = {}) => {
|
|
15117
|
-
const span =
|
|
15202
|
+
const span = liveScope()?.span;
|
|
15118
15203
|
if (span === void 0) {
|
|
15119
15204
|
return;
|
|
15120
15205
|
}
|
|
@@ -15127,6 +15212,34 @@ var addSpanEvent = (name, options = {}) => {
|
|
|
15127
15212
|
span.events = [...span.events ?? [], event];
|
|
15128
15213
|
};
|
|
15129
15214
|
|
|
15215
|
+
// src/read-body.ts
|
|
15216
|
+
var MAX_ENVELOPE_BYTES = 1024 * 1024;
|
|
15217
|
+
var readBody = async (request, maxBytes = MAX_ENVELOPE_BYTES) => {
|
|
15218
|
+
const reader = request.body?.getReader();
|
|
15219
|
+
if (reader === void 0) {
|
|
15220
|
+
return "";
|
|
15221
|
+
}
|
|
15222
|
+
const chunks = [];
|
|
15223
|
+
let received = 0;
|
|
15224
|
+
let result = await reader.read();
|
|
15225
|
+
while (!result.done) {
|
|
15226
|
+
received += result.value.byteLength;
|
|
15227
|
+
if (received > maxBytes) {
|
|
15228
|
+
await reader.cancel();
|
|
15229
|
+
return null;
|
|
15230
|
+
}
|
|
15231
|
+
chunks.push(result.value);
|
|
15232
|
+
result = await reader.read();
|
|
15233
|
+
}
|
|
15234
|
+
const bytes = new Uint8Array(received);
|
|
15235
|
+
let offset = 0;
|
|
15236
|
+
for (const chunk of chunks) {
|
|
15237
|
+
bytes.set(chunk, offset);
|
|
15238
|
+
offset += chunk.byteLength;
|
|
15239
|
+
}
|
|
15240
|
+
return new TextDecoder().decode(bytes);
|
|
15241
|
+
};
|
|
15242
|
+
|
|
15130
15243
|
// src/apps-client.ts
|
|
15131
15244
|
var BROKER_URL = "https://site/__qinto/rpc";
|
|
15132
15245
|
var channelFetch = (env, init) => {
|
|
@@ -15146,7 +15259,20 @@ var askBroker = async (env, name, body) => {
|
|
|
15146
15259
|
headers[TRACE_HEADER] = serializeTraceContext(trace);
|
|
15147
15260
|
}
|
|
15148
15261
|
const response = await channelFetch(env, { method: "POST", headers, body: JSON.stringify(body) });
|
|
15149
|
-
const
|
|
15262
|
+
const raw = await readBody(response, MAX_RESPONSE_BYTES + 8 * 1024);
|
|
15263
|
+
if (raw === null) {
|
|
15264
|
+
throw new Error("the broker response exceeds the size cap");
|
|
15265
|
+
}
|
|
15266
|
+
let parsed;
|
|
15267
|
+
try {
|
|
15268
|
+
parsed = JSON.parse(raw);
|
|
15269
|
+
} catch {
|
|
15270
|
+
throw new Error("the broker returned invalid JSON");
|
|
15271
|
+
}
|
|
15272
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
15273
|
+
throw new Error("the broker returned invalid JSON");
|
|
15274
|
+
}
|
|
15275
|
+
const answer = parsed;
|
|
15150
15276
|
if (answer.error !== void 0 || !response.ok) {
|
|
15151
15277
|
throw new Error(answer.error ?? `the broker answered ${response.status}`);
|
|
15152
15278
|
}
|
|
@@ -15198,6 +15324,18 @@ var brokerContextWrite = async (env, userId, writes) => {
|
|
|
15198
15324
|
throw new Error(`the platform declined the ${declined.map((write) => write.level).join(" and ")} context write`);
|
|
15199
15325
|
}
|
|
15200
15326
|
};
|
|
15327
|
+
var brokerFactsRead = async (env, userId, input = {}) => {
|
|
15328
|
+
const continuation = "cursor" in input;
|
|
15329
|
+
const answer = await askBroker(env, "apps.facts read", {
|
|
15330
|
+
v: ENVELOPE_VERSION,
|
|
15331
|
+
kind: "factsRead",
|
|
15332
|
+
slug: callerSlug(env),
|
|
15333
|
+
key: env.QINTO_INTERNAL_KEY,
|
|
15334
|
+
userId,
|
|
15335
|
+
...continuation ? { cursor: input.cursor } : { query: input }
|
|
15336
|
+
});
|
|
15337
|
+
return { items: answer.items ?? [], nextCursor: answer.nextCursor ?? null };
|
|
15338
|
+
};
|
|
15201
15339
|
var brokerActive = async (env, input) => {
|
|
15202
15340
|
let response;
|
|
15203
15341
|
try {
|
|
@@ -15334,6 +15472,26 @@ var projectAppValues = (env, kinds) => {
|
|
|
15334
15472
|
}
|
|
15335
15473
|
return { appVariables, appSecrets };
|
|
15336
15474
|
};
|
|
15475
|
+
var secretValues = (env) => {
|
|
15476
|
+
const { variableKinds, appVariableKinds } = contextKindsOf(env);
|
|
15477
|
+
const values = /* @__PURE__ */ new Set();
|
|
15478
|
+
for (const [name, byOrd] of parseVariableMaps(env)) {
|
|
15479
|
+
if (variableKinds[name] !== "secret") {
|
|
15480
|
+
continue;
|
|
15481
|
+
}
|
|
15482
|
+
for (const value of Object.values(byOrd)) {
|
|
15483
|
+
if (typeof value === "string" && value !== "") {
|
|
15484
|
+
values.add(value);
|
|
15485
|
+
}
|
|
15486
|
+
}
|
|
15487
|
+
}
|
|
15488
|
+
for (const value of Object.values(projectAppValues(env, appVariableKinds).appSecrets)) {
|
|
15489
|
+
if (value !== "") {
|
|
15490
|
+
values.add(value);
|
|
15491
|
+
}
|
|
15492
|
+
}
|
|
15493
|
+
return [...values];
|
|
15494
|
+
};
|
|
15337
15495
|
var projectInstallValues = (maps, kinds, ord) => {
|
|
15338
15496
|
const variables = {};
|
|
15339
15497
|
const secrets = {};
|
|
@@ -15471,6 +15629,23 @@ var buildStartWorkflow = (stamp) => {
|
|
|
15471
15629
|
return workflow.create({ ...options, params: stampParams(stamp, params) });
|
|
15472
15630
|
};
|
|
15473
15631
|
};
|
|
15632
|
+
var buildUiStartWorkflow = (subject, installs) => {
|
|
15633
|
+
return async (workflow, params, options) => {
|
|
15634
|
+
const target = installs.find((install) => {
|
|
15635
|
+
return install.id === options?.installId;
|
|
15636
|
+
});
|
|
15637
|
+
if (options?.installId !== void 0) {
|
|
15638
|
+
if (target === void 0) {
|
|
15639
|
+
throw new Error(`No install ${options.installId} on this site.`);
|
|
15640
|
+
}
|
|
15641
|
+
if (!target.enabled) {
|
|
15642
|
+
throw new Error(`Install ${options.installId} is not enabled on this site.`);
|
|
15643
|
+
}
|
|
15644
|
+
}
|
|
15645
|
+
const stamp = target === void 0 ? subject : { ...subject, ord: target.ord, installId: target.id, installLabel: target.label };
|
|
15646
|
+
return workflow.create({ id: options?.id, params: stampParams(stamp, params) });
|
|
15647
|
+
};
|
|
15648
|
+
};
|
|
15474
15649
|
var readStamp = (payload) => {
|
|
15475
15650
|
const params = payload;
|
|
15476
15651
|
const stamp = params?.q;
|
|
@@ -15616,6 +15791,11 @@ var buildContext = ({
|
|
|
15616
15791
|
}
|
|
15617
15792
|
}
|
|
15618
15793
|
},
|
|
15794
|
+
facts: {
|
|
15795
|
+
list: (input) => {
|
|
15796
|
+
return brokerFactsRead(env, envelope.user.anonId, input);
|
|
15797
|
+
}
|
|
15798
|
+
},
|
|
15619
15799
|
context: {
|
|
15620
15800
|
private: {
|
|
15621
15801
|
entry: envelope.context?.private ?? null,
|
|
@@ -15638,40 +15818,12 @@ var buildContext = ({
|
|
|
15638
15818
|
// src/install-span.ts
|
|
15639
15819
|
var installSpan = (install, run) => {
|
|
15640
15820
|
return traced(
|
|
15641
|
-
|
|
15821
|
+
install.label,
|
|
15642
15822
|
{ attrs: { "app.install_id": install.id, "app.install_ord": install.ord, "app.install_label": install.label } },
|
|
15643
15823
|
run
|
|
15644
15824
|
);
|
|
15645
15825
|
};
|
|
15646
15826
|
|
|
15647
|
-
// src/read-body.ts
|
|
15648
|
-
var MAX_ENVELOPE_BYTES = 1024 * 1024;
|
|
15649
|
-
var readBody = async (request, maxBytes = MAX_ENVELOPE_BYTES) => {
|
|
15650
|
-
const reader = request.body?.getReader();
|
|
15651
|
-
if (reader === void 0) {
|
|
15652
|
-
return "";
|
|
15653
|
-
}
|
|
15654
|
-
const chunks = [];
|
|
15655
|
-
let received = 0;
|
|
15656
|
-
let result = await reader.read();
|
|
15657
|
-
while (!result.done) {
|
|
15658
|
-
received += result.value.byteLength;
|
|
15659
|
-
if (received > maxBytes) {
|
|
15660
|
-
await reader.cancel();
|
|
15661
|
-
return null;
|
|
15662
|
-
}
|
|
15663
|
-
chunks.push(result.value);
|
|
15664
|
-
result = await reader.read();
|
|
15665
|
-
}
|
|
15666
|
-
const bytes = new Uint8Array(received);
|
|
15667
|
-
let offset = 0;
|
|
15668
|
-
for (const chunk of chunks) {
|
|
15669
|
-
bytes.set(chunk, offset);
|
|
15670
|
-
offset += chunk.byteLength;
|
|
15671
|
-
}
|
|
15672
|
-
return new TextDecoder().decode(bytes);
|
|
15673
|
-
};
|
|
15674
|
-
|
|
15675
15827
|
// src/responses.ts
|
|
15676
15828
|
var MAX_ERROR_MESSAGE_LENGTH = 2048;
|
|
15677
15829
|
var json2 = (status, body) => {
|
|
@@ -16024,15 +16176,9 @@ var appSlug = (context) => {
|
|
|
16024
16176
|
return "app";
|
|
16025
16177
|
}
|
|
16026
16178
|
};
|
|
16027
|
-
var headerValue = (record2) => {
|
|
16028
|
-
const redacted = redactAppSpans(record2);
|
|
16029
|
-
const rebudgeted = budgetSpans(redacted.spans, APP_SPANS_JSON_BUDGET);
|
|
16030
|
-
const truncated = (record2.truncated ?? 0) + (rebudgeted.truncated ?? 0);
|
|
16031
|
-
return serializeAppSpans({ spans: rebudgeted.spans, ...truncated === 0 ? {} : { truncated } });
|
|
16032
|
-
};
|
|
16033
16179
|
var withSpans = (response, record2) => {
|
|
16034
16180
|
const headers = new Headers(response.headers);
|
|
16035
|
-
headers.set(APP_SPANS_HEADER,
|
|
16181
|
+
headers.set(APP_SPANS_HEADER, serializeAppSpans(record2));
|
|
16036
16182
|
return new Response(response.body, { status: response.status, statusText: response.statusText, headers });
|
|
16037
16183
|
};
|
|
16038
16184
|
var runAppInvocation = async (input, handle) => {
|
|
@@ -16043,6 +16189,7 @@ var runAppInvocation = async (input, handle) => {
|
|
|
16043
16189
|
name: appSlug(input.context),
|
|
16044
16190
|
trace: parseTraceContext(input.request.headers.get(TRACE_HEADER)),
|
|
16045
16191
|
budget: APP_SPANS_JSON_BUDGET,
|
|
16192
|
+
redact: spanRedactor(input.secrets),
|
|
16046
16193
|
emit: (emitted) => {
|
|
16047
16194
|
record2 = emitted;
|
|
16048
16195
|
}
|
|
@@ -16056,19 +16203,84 @@ var runAppInvocation = async (input, handle) => {
|
|
|
16056
16203
|
};
|
|
16057
16204
|
|
|
16058
16205
|
// src/traced-fetch.ts
|
|
16206
|
+
var MAX_BODY_CHARS = 65536;
|
|
16207
|
+
var TOO_LARGE = `[not recorded: the body is over ${MAX_BODY_CHARS} characters]`;
|
|
16208
|
+
var INCOMPLETE = "[not recorded: the body did not finish arriving]";
|
|
16209
|
+
var READ_BUDGET_MS = 100;
|
|
16059
16210
|
var requestParts = (input, init) => {
|
|
16060
16211
|
if (input instanceof Request) {
|
|
16061
16212
|
return { method: init?.method ?? input.method, url: input.url };
|
|
16062
16213
|
}
|
|
16063
16214
|
return { method: init?.method ?? "GET", url: String(input) };
|
|
16064
16215
|
};
|
|
16216
|
+
var abandon = (reader) => {
|
|
16217
|
+
void Promise.allSettled([reader.cancel()]);
|
|
16218
|
+
};
|
|
16219
|
+
var capturedBody = async (open) => {
|
|
16220
|
+
let timer;
|
|
16221
|
+
try {
|
|
16222
|
+
const body = open();
|
|
16223
|
+
if (body === null) {
|
|
16224
|
+
return void 0;
|
|
16225
|
+
}
|
|
16226
|
+
const reader = body.getReader();
|
|
16227
|
+
const decoder2 = new TextDecoder();
|
|
16228
|
+
const expired = new Promise((resolve) => {
|
|
16229
|
+
timer = setTimeout(() => resolve(null), READ_BUDGET_MS);
|
|
16230
|
+
});
|
|
16231
|
+
let text = "";
|
|
16232
|
+
for (; ; ) {
|
|
16233
|
+
const read = await Promise.race([reader.read(), expired]);
|
|
16234
|
+
if (read === null) {
|
|
16235
|
+
abandon(reader);
|
|
16236
|
+
return INCOMPLETE;
|
|
16237
|
+
}
|
|
16238
|
+
if (read.done) {
|
|
16239
|
+
break;
|
|
16240
|
+
}
|
|
16241
|
+
text += decoder2.decode(read.value, { stream: true });
|
|
16242
|
+
if (text.length > MAX_BODY_CHARS) {
|
|
16243
|
+
abandon(reader);
|
|
16244
|
+
return TOO_LARGE;
|
|
16245
|
+
}
|
|
16246
|
+
}
|
|
16247
|
+
return text === "" ? void 0 : text;
|
|
16248
|
+
} catch {
|
|
16249
|
+
return void 0;
|
|
16250
|
+
} finally {
|
|
16251
|
+
clearTimeout(timer);
|
|
16252
|
+
}
|
|
16253
|
+
};
|
|
16254
|
+
var requestBody = (input, init) => {
|
|
16255
|
+
const body = init?.body;
|
|
16256
|
+
if (body === void 0) {
|
|
16257
|
+
return input instanceof Request ? capturedBody(() => input.clone().body) : Promise.resolve(void 0);
|
|
16258
|
+
}
|
|
16259
|
+
if (body instanceof ReadableStream) {
|
|
16260
|
+
return Promise.resolve(void 0);
|
|
16261
|
+
}
|
|
16262
|
+
return capturedBody(() => new Request("https://qinto.invalid", { method: "POST", body }).body);
|
|
16263
|
+
};
|
|
16264
|
+
var responseBody = (response) => {
|
|
16265
|
+
if ((response.headers.get("content-type") ?? "").startsWith("text/event-stream")) {
|
|
16266
|
+
return Promise.resolve(void 0);
|
|
16267
|
+
}
|
|
16268
|
+
return capturedBody(() => response.clone().body);
|
|
16269
|
+
};
|
|
16270
|
+
var bodyAttribute = async (key, body) => {
|
|
16271
|
+
const text = await body;
|
|
16272
|
+
return text === void 0 ? void 0 : { [key]: text };
|
|
16273
|
+
};
|
|
16065
16274
|
var installTracedFetch = () => {
|
|
16066
16275
|
const original = globalThis.fetch.bind(globalThis);
|
|
16067
16276
|
globalThis.fetch = async (input, init) => {
|
|
16068
16277
|
const { method, url: url2 } = requestParts(input, init);
|
|
16278
|
+
const sent = requestBody(input, init);
|
|
16069
16279
|
return traced(`${method} ${new URL(url2).host}`, { attrs: { "http.request.method": method, "url.full": url2 } }, async () => {
|
|
16280
|
+
deferSpanAttributes(bodyAttribute("http.request.body", sent));
|
|
16070
16281
|
const response = await original(input, init);
|
|
16071
16282
|
setSpanAttributes({ "http.response.status_code": response.status });
|
|
16283
|
+
deferSpanAttributes(bodyAttribute("http.response.body", responseBody(response)));
|
|
16072
16284
|
return response;
|
|
16073
16285
|
});
|
|
16074
16286
|
};
|
|
@@ -16140,12 +16352,10 @@ var dispatchUi = async ({ request, env, versions }) => {
|
|
|
16140
16352
|
installs: projectAllInstallValues(maps, variableKinds, context.installs),
|
|
16141
16353
|
settings: buildSettings({ env, ticket: context.writeTicket }),
|
|
16142
16354
|
// The panel's viewer is a portal user, not a visitor, so a workflow it starts carries no subject.
|
|
16143
|
-
startWorkflow:
|
|
16144
|
-
ord: context.install.ord,
|
|
16145
|
-
|
|
16146
|
-
|
|
16147
|
-
anonId: null
|
|
16148
|
-
}),
|
|
16355
|
+
startWorkflow: buildUiStartWorkflow(
|
|
16356
|
+
{ ord: context.install.ord, installId: context.install.id, installLabel: context.install.label, anonId: null },
|
|
16357
|
+
context.installs
|
|
16358
|
+
),
|
|
16149
16359
|
variables,
|
|
16150
16360
|
secrets,
|
|
16151
16361
|
appVariables,
|
|
@@ -16415,6 +16625,7 @@ var createRuntime = (input) => {
|
|
|
16415
16625
|
{
|
|
16416
16626
|
request,
|
|
16417
16627
|
context: env.APP_CONTEXT,
|
|
16628
|
+
secrets: secretValues(env),
|
|
16418
16629
|
failure: () => {
|
|
16419
16630
|
return jsonError(500, "the app failed");
|
|
16420
16631
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(){var e=class extends Error{constructor(e){super(e),this.name=`QintoError`}},t=class extends e{constructor(e){super(e),this.name=`QintoTimeoutError`}},n=class extends e{constructor(e){super(e),this.name=`QintoEnvironmentError`}},r=`0123456789ABCDEFGHJKMNPQRSTVWXYZ`,i=e=>{let t=new Uint8Array(e);return globalThis.crypto.getRandomValues(t),t},a=e=>{let t=e,n=``;for(let e=0;e<10;e++)n=r.charAt(t%32)+n,t=Math.floor(t/32);let a=``,o=0,s=0;for(let e of i(10))for(o=o<<8|e,s+=8;s>=5;)s-=5,a+=r.charAt(o>>>s&31);return n+a},o=(e=Date.now())=>`evt_${a(e)}_${e}`,s=(e,t)=>{if(e!==void 0)return e;let n=t?.orderId;return typeof n==`string`&&n!==``?n:o()},c=()=>globalThis.document!==void 0,l=[`necessary`,`functional`,`analytics`,`marketing`,`salesOfData`],u=(e,t,n)=>n===void 0||!l.some(e=>e===n)?!1:n===`necessary`||e!==null&&e.categories[n]===!0&&e.apps[t]!==!1,d=()=>{},f=100,p=1024,m=32*1024,h=(e,t,n,r)=>!r||u(e,t,n),g=e=>Object.values(e.config?.apps??{}).some(e=>e.category!==`necessary`||e.capture!==void 0),ee=(e,t)=>{let{app:n,install:r,topic:i,to:a}=e;return typeof n!=`string`||typeof i!=`string`||r!==void 0&&typeof r!=`string`||t&&!(Array.isArray(a)&&a.every(e=>typeof e==`string`))},te=(e,t,n,r)=>r===null?e.slug===t&&(n===void 0||n===e.installId):r.has(e.slug),_=(e,t)=>{console.error(`[Qinto] A handler of app "${e.slug}" (install "${e.installId}") failed.`,t)},v=(e,t,n)=>{for(let r of t)try{let t=r(n);t instanceof Promise&&t.catch(t=>{_(e,t)})}catch(t){_(e,t)}},y=(e,t,n,r)=>{e.activated.add(r.id);let i={slug:t,installId:r.id,eventHandlers:[],consentHandlers:[],pushHandlers:[],sharedContextHandlers:[]};e.instances.push(i);let a={variables:r.variables,install:{id:r.id,label:r.label},track:(t,n)=>{e.client.track(t,n).catch(d)},onEvent:e=>{i.eventHandlers.push(e)},onConsent:e=>{i.consentHandlers.push(e)},onPush:e=>{i.pushHandlers.push(e)},onSharedContext:n=>{if(e.target.config?.apps?.[t]?.sharedContext!==!0){console.error(`[Qinto] App "${t}" reads shared context without declaring the sharedContext capability.`);return}i.sharedContextHandlers.push(n),e.sharedContext!==null&&S(e,t)&&v(i,[n],e.sharedContext)}};try{n(a)}catch(e){console.error(`[Qinto] App "${t}" failed to activate install "${r.id}".`,e)}},b=(e,t,n)=>{if(!h(e.consent,t,e.target.config?.apps?.[t]?.category,e.target.config?.consentConfiguration?.enabled===!0))return;let r=((`_appInstalls`in e.target?e.target._appInstalls:void 0)?.[t]??[]).filter(t=>!e.activated.has(t.id));if(r.length===0)return;let i=n.factory;if(i===void 0){try{i=n.loader()}catch(e){i=null,console.error(`[Qinto] App "${t}" failed to load.`,e)}e.apps.set(t,{...n,factory:i})}if(i!==null)for(let n of r)y(e,t,i,n)},x=(e,t,n)=>h(n,t,e.target.config?.apps?.[t]?.category,e.target.config?.consentConfiguration?.enabled===!0),S=(e,t)=>x(e,t,e.consent)?e.sharedContextConsent===void 0||x(e,t,e.sharedContextConsent):!1,C=e=>{let{categories:t,apps:n}=e;if(!(typeof t!=`object`||!t||typeof n!=`object`||!n))return{categories:t,apps:n}},w=(e,t)=>{let n=e;n.consent=t,n.sharedContextConsent=void 0;for(let n of e.instances)v(n,n.consentHandlers,t);e.onConsentSettled?.(t);for(let[t,n]of e.apps)b(e,t,n)},T=async e=>{try{w(e,await e.client.getConsent())}catch(e){console.error(`[Qinto] The apps consent read failed.`,e)}},ne=e=>{let t;try{t=JSON.stringify(e)}catch{return}if(!(t===void 0||new TextEncoder().encode(t).length>p))return JSON.parse(t)},re=e=>{let t={};for(let n of e){if(n.settled!==n.total||n.values.length!==1)continue;let e=ne(n.values[0]);if(e===void 0)continue;let r={...t[n.instance.slug]??{},[n.instance.installId]:e},i={...t,[n.instance.slug]:r};new TextEncoder().encode(JSON.stringify(i)).length<=m&&(t[n.instance.slug]=r)}return Object.keys(t).length===0?void 0:t},E=async(e,t)=>{e.onPageEvent?.(e.consent);let n=[],r=[];for(let i of e.instances){if(!h(e.consent,i.slug,e.target.config?.apps?.[i.slug]?.category,e.target.config?.consentConfiguration?.enabled===!0))continue;if(e.target.config?.apps?.[i.slug]?.eventResults?.includes(t.type)!==!0){v(i,i.eventHandlers,t);continue}let a={instance:i,total:i.eventHandlers.length,settled:0,values:[]};n.push(a);for(let e of i.eventHandlers){let n;try{n=e(t)}catch(e){a.settled+=1,_(i,e);continue}r.push(Promise.resolve(n).then(e=>{a.settled+=1,e!==void 0&&a.values.push(e)},e=>{a.settled+=1,_(i,e)}))}}if(r.length>0){let e=d,t=new Promise(t=>{e=t}),n=setTimeout(e,f);await Promise.race([Promise.all(r),t]),clearTimeout(n)}return re(n)},ie=e=>{let{client:t}=e;return{track:async(n,r,i)=>{let a=s(i?.eventId,r),o=t.actionContext(),c=await E(e,{type:`track`,event:n,eventId:a,properties:r??{}});return await t.submitTrack({event:n,eventId:a,properties:r,context:o,appResults:c}),{eventId:a}},identify:async(n,r)=>{let i=t.actionContext(),a=await E(e,{type:`identify`,event:`identify`,properties:n??{}});return t.submitIdentify({traits:n,id:r,context:i,appResults:a})},alias:t.alias,consent:async n=>{if(await t.submitConsent(n,t.actionContext()),e.onConsentMutation?.(),g(e.target)){let t=e;t.consent=null,await T(e)}},getAnonId:t.getAnonId,getConsent:t.getConsent,getSession:t.getSession,close:t.close}},ae=(e,t)=>{let n=new Map,r=null,i=null,a=e=>{let[t,i]=e;if(n.has(t))return;let a={loader:i};n.set(t,a),r?.(t,a)},o=e,s=`_apps`in o?o._apps:void 0,c=Array.isArray(s)?s:[];c.push=(...e)=>{for(let t of e)a(t);return 0},o._apps=c;for(let e of c.splice(0))a(e);return{sharedContext:e=>{let{context:t}=e;if(typeof t!=`object`||!t||Array.isArray(t)){console.error(`[Qinto] The server sent a malformed shared context.`,e);return}let n=i;if(n===null)return;n.sharedContext=t;let r=C(e),a=r??n.consent;n.sharedContextConsent=r;for(let e of n.instances)x(n,e.slug,a)&&v(e,e.sharedContextHandlers,n.sharedContext)},push:e=>{let{app:t,install:n,topic:r,scope:a,to:o}=e,s=a===`site`;if(ee(e,s)){console.error(`[Qinto] The server sent a malformed app push.`,e);return}let c=i;if(c===null)return;let l=s?new Set(o):null,u={topic:r,data:e.data,from:t};for(let e of c.instances)te(e,t,n,l)&&h(c.consent,e.slug,c.target.config?.apps?.[e.slug]?.category,c.target.config?.consentConfiguration?.enabled===!0)&&v(e,e.pushHandlers,u)},connect:async a=>{let o={target:e,client:a,apps:n,instances:[],activated:new Set,consent:null,sharedContext:i?.sharedContext??null,sharedContextConsent:i?.sharedContextConsent,onConsentSettled:t?.onConsentSettled,onConsentMutation:t?.onConsentMutation,onPageEvent:t?.onPageEvent};i=o,r=(e,t)=>{b(o,e,t),o.consent===null&&o.target.config?.consentConfiguration?.enabled===!0&&o.target.config?.apps?.[e]?.category!==`necessary`&&T(o)};for(let[e,t]of n)b(o,e,t);return e.config?.consentConfiguration?.enabled===!0&&g(e)?await T(o):o.onConsentSettled?.(o.consent),ie(o)}}},oe=`PageView`,D=()=>{},se=e=>{e.config?.autoCapture?.pageLoad===!0&&e.q.push([`track`,[oe],D,D])},O=512,k=1440*60*1e3,A=e=>Object.fromEntries(Object.entries(e).map(([e,t])=>[e,Object.fromEntries(Object.entries(t).map(([e,t])=>[e,t.value]))])),j=(e,t)=>`qinto:cap:${encodeURIComponent(e)}:${encodeURIComponent(t)}`,M=e=>{try{let t=window.sessionStorage.getItem(e);if(t===null)return null;let n=JSON.parse(t);return typeof n.at!=`number`||typeof n.anonId!=`string`||typeof n.apps!=`object`||n.apps===null||Date.now()-n.at>k?null:{at:n.at,anonId:n.anonId,apps:n.apps}}catch{return null}},N=(e,t)=>{try{window.sessionStorage.setItem(e,JSON.stringify(t))}catch{}},P=e=>{try{window.sessionStorage.removeItem(e)}catch{}},F=e=>{try{return decodeURIComponent(e)}catch{return e}},I=()=>{let e={};for(let t of document.cookie.split(`;`)){let n=t.indexOf(`=`);n>0&&(e[t.slice(0,n).trim()]=F(t.slice(n+1)))}return e},L=(e,t)=>{let n={};for(let r of e.queryParams){let e=t.params.get(r);e!==null&&e.length<=O&&(n[r]={value:e,source:`query`})}for(let r of e.cookies){let e=t.cookies[r];e!==void 0&&e.length<=O&&(n[r]={value:e,source:`cookie`})}return n},R=(e,t)=>{let n={params:new URLSearchParams(window.location.search),cookies:I()},r={};for(let[i,a]of Object.entries(e.config?.apps??{})){if(a.capture===void 0||!u(t,i,a.category))continue;let e=L(a.capture,n);Object.keys(e).length>0&&(r[i]=e)}return r},z=(e,t)=>{let n={};for(let[r,i]of Object.entries(e)){let e=t[r]??{},a={};for(let[t,n]of Object.entries(i))(e[t]?.value!==n.value||e[t]?.source!==n.source)&&(a[t]=n);Object.keys(a).length>0&&(n[r]=a)}return n},B=(e,t,n,r)=>{let i=j(r,n),a=M(i),o=a?.apps??{},s=a?.anonId??null,c=a===null,l={},u=0,d=(e,t)=>{s!==null&&s!==e.anonId&&(o={}),s=e.anonId;let n=new Set(Object.entries(e.accepted).flatMap(([e,t])=>t.map(t=>`${e}\u0000${t}`)));for(let[e,r]of Object.entries(t))for(let[t,i]of Object.entries(r))n.has(`${e}\u0000${t}`)&&(o[e]={...o[e],[t]:i});N(i,{at:Date.now(),anonId:s,apps:o})},f=null,p=()=>{u+=1,o={},l={},P(i)},m=n=>{if(f=n,!c)return;let r=z(R(e,n),{...o,...l});if(Object.keys(r).length===0)return;let i=u;l={...l,...r},t(A(r)).then(e=>{i===u&&d(e,r)}).catch(()=>{}).finally(()=>{l={}})};return{settled:e=>{m(e)},needsAnon:()=>!c,observedAnon:e=>{(e===null||s!==null&&s!==e)&&p(),s=e,c=!0,m(f)},clear:p}},V=Symbol.for(`qinto.connectGate`),H=()=>{},U=e=>{let t=globalThis,n=(t[V]??Promise.resolve()).then(e);return t[V]=n.then(H,H),n},W=class extends e{constructor(e){super(e),this.name=`QintoProtocolError`}},G=e=>{if(typeof e!=`string`)return null;let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=`object`||!t)return null;let n=t;return n.t===`ack`||n.t===`error`||n.t===`consentState`||n.t===`session`||n.t===`captureAck`||n.t===`appPush`||n.t===`sharedContext`?t:null},K=e=>{if(e.t===`consentState`)return{categories:e.categories,apps:e.apps};if(e.t===`session`)return{anonId:e.anonId,globalId:e.globalId};if(e.t===`captureAck`)return{anonId:e.anonId,accepted:e.accepted}},ce=e=>{let n=new Map,r=e=>{let t=n.get(e);if(t!==void 0)return clearTimeout(t.timer),n.delete(e),t};return{submit:r=>new Promise((i,a)=>{let o={frame:r,sent:e.send(r),resolve:i,reject:a,timer:setTimeout(()=>{n.delete(r.ref),a(new t(`The Qinto request timed out.`))},e.requestTimeoutMs)};n.set(r.ref,o)}),flush:()=>{for(let t of n.values())t.sent||=e.send(t.frame)},deliver:e=>{let t=e.ref===void 0?void 0:r(e.ref);if(t!==void 0){if(e.t===`error`){t.reject(new W(e.message));return}t.resolve(K(e))}},rejectAll:e=>{let t=[...n.values()];n.clear();for(let n of t)clearTimeout(n.timer),n.reject(e)}}},le=e=>new WebSocket(e),ue=500,de=3e4,fe=`session not initialized`,pe=(e,t)=>{let n=Math.min(ue*2**e,de);return Math.round(n/2+n/2*t)},me=(e,t)=>e.t===`appPush`?(t.onAppPush?.(e),!0):e.t===`sharedContext`?(t.onSharedContext?.(e),!0):!1,he=e=>{let t=`${e.destination.replace(/\/+$/,``)}/open`,n=null,r=null,i=0,a=null,o=ce({send:e=>n===null||n.readyState!==1?!1:(n.send(JSON.stringify(e)),!0),requestTimeoutMs:e.requestTimeoutMs}),s=t=>{e.onError?.(t)},c=()=>{if(r!==null&&(clearTimeout(r),r=null),n!==null){let e=n;n=null,e.close()}o.rejectAll(new W(`connection closed`))},l=()=>{let u=le(t);n=u,u.onopen=()=>{i=0;let e=a;a=null,o.flush(),e?.resolve()},u.onmessage=t=>{let n=G(t.data);if(n===null){s(new W(`invalid message`));return}me(n,e)||(`anonId`in n&&typeof n.anonId==`string`&&e.onAnonId?.(n.anonId),o.deliver(n),n.t===`error`&&n.message===fe&&u.close())},u.onerror=()=>{s(new W(`connection closed`))},u.onclose=()=>{if(n!==u)return;n=null;let e=a;if(e!==null){a=null,c(),e.reject(new W(`connection closed`));return}o.rejectAll(new W(`connection closed`)),r=setTimeout(()=>{r=null,l()},pe(i,Math.random())),i+=1}};return{connect:()=>new Promise((e,t)=>{a={resolve:e,reject:t},l()}),submit:e=>o.submit(e),close:()=>{c()}}},ge=1e4,_e=()=>{let e=0;return()=>(e+=1,`q${e}`)},ve=(e,t)=>{let n=`qinto:visit:${e.replace(/\/+$/,``)}:${t}`,r,i=!1;try{let e=sessionStorage.getItem(n);e===null||!/^vis_[0-9a-f-]{36}$/.test(e)?(r=`vis_${crypto.randomUUID()}`,sessionStorage.setItem(n,r),i=!0):r=e}catch{r=`vis_${crypto.randomUUID()}`,i=!0}return()=>{let e={id:r,isNew:i};return i=!1,e}},ye=(e,t,n,r)=>{let i=null,a=ve(n,r),o=()=>{let e=document.referrer;return{occurredAt:Date.now(),page:{url:window.location.href,...e===``?{}:{referrer:e}},session:a()}},c=async()=>{let n=await e.submit({t:`getSession`,ref:t()});return i=n.anonId,n};return{actionContext:o,submitIdentify:async({traits:n,id:r,context:i,appResults:a})=>{await e.submit({t:`identify`,ref:t(),traits:n,id:r,context:i,appResults:a})},submitTrack:async({event:n,eventId:r,properties:i,context:a,appResults:o})=>{await e.submit({t:`track`,ref:t(),event:n,eventId:r,properties:i,context:a,appResults:o})},submitConsent:async(n,r)=>{await e.submit({t:`consent`,ref:t(),categories:n.categories,apps:n.apps,context:r})},identify:async(n,r)=>{await e.submit({t:`identify`,ref:t(),traits:n,id:r,context:o()})},track:async(n,r,i)=>{let a=s(i?.eventId,r);return await e.submit({t:`track`,ref:t(),event:n,eventId:a,properties:r,context:o()}),{eventId:a}},alias:async n=>{await e.submit({t:`alias`,ref:t(),customId:n})},consent:async n=>{await e.submit({t:`consent`,ref:t(),categories:n.categories,apps:n.apps,context:o()})},getConsent:async()=>await e.submit({t:`getConsent`,ref:t()}),getSession:c,getAnonId:async()=>(i===null&&await c(),i),close:()=>{e.close()}}},be=async e=>{if(!c())throw new n(`You are calling init() in a server environment. Use createClient from @blotout/qinto-sdk-server there.`);let t=he({destination:e.destination,requestTimeoutMs:e.requestTimeoutMs??ge,onError:e.onError,onAppPush:e.onAppPush,onSharedContext:e.onSharedContext,onAnonId:e.onAnonId});await U(()=>t.connect());let r=_e();return{client:ye(t,r,e.destination,e.globalName??`qinto`),submitCapture:async e=>await t.submit({t:`capture`,ref:r(),apps:e})}},xe=[`then`,`ready`,`config`],q=()=>{},Se=(e,t)=>(...n)=>{let r=new Promise((r,i)=>{e.q.push([t,n,r,i])});return r.catch(q),r},J=e=>{let t=e;return t._q=1,t.q=[],new Proxy(t,{get:(e,n)=>typeof n!=`string`||xe.includes(n)||n in t?Reflect.get(t,n):(t[n]=Se(t,n),t[n])})},Ce=()=>{let e=document.currentScript?.dataset.qintoGlobal;return typeof e==`string`&&e!==``?e:`qinto`},we=e=>typeof e==`object`&&!!e&&e._q===1,Y=(e=`qinto`)=>{let t=globalThis;if(e in t){let n=t[e];if(!we(n))return null;let r=Array.isArray(n.q)?n:J(n);return r!==n&&Object.defineProperty(t,e,{value:r,writable:!0,enumerable:!0,configurable:!0}),r}let n=J({});return Object.defineProperty(t,e,{value:n,writable:!0,enumerable:!0,configurable:!0}),n},Te=(t,n)=>async(r,i)=>{let a=Reflect.get(t,r);if(typeof a!=`function`)throw new e(`[Qinto] ${n}.${r} is not a method of this tag.`);return a.apply(t,Array.from(i))},Ee=e=>()=>Promise.reject(e),X=(e,t)=>{let[n,r,i,a]=t;e(n,r).then(i,a)},De=e=>{let t=[];return t.push=(...t)=>{for(let n of t)X(e,n);return 0},t},Oe=(e,t,n=`window.qinto`)=>{let r=e.ready;if(r!==void 0)return r;let i=e,a=e=>{let t=i.q;i.q=De(e);for(let n of t)X(e,n)},o=t().then(e=>{a(Te(e,n))},e=>{throw a(Ee(e)),e});return o.catch(q),i.ready=o,o},Z=Ce(),Q=Y(Z),$=`window.${Z}`;if(Q!==null&&Q.ready===void 0){let e=null,t=ae(Q,{onConsentSettled:t=>{e?.settled(t)},onConsentMutation:()=>{e?.clear()},onPageEvent:t=>{e?.settled(t)}});se(Q),Oe(Q,async()=>{let n=Q.config?.destination;if(typeof n!=`string`||n===``)throw Error(`[Qinto] ${$}.config.destination is missing.`);let r=await be({destination:n,globalName:Z,onAppPush:t.push,onSharedContext:t.sharedContext,onAnonId:t=>{e?.observedAnon(t)}});e=B(Q,r.submitCapture,n,Z);let i=await t.connect(r.client);return e.needsAnon()&&e.observedAnon((await r.client.getSession()).anonId),i},$)}})();
|
|
1
|
+
(function(){var e=class extends Error{constructor(e){super(e),this.name=`QintoError`}},t=class extends e{constructor(e){super(e),this.name=`QintoTimeoutError`}},n=class extends e{constructor(e){super(e),this.name=`QintoEnvironmentError`}},r=`0123456789ABCDEFGHJKMNPQRSTVWXYZ`,i=e=>{let t=new Uint8Array(e);return globalThis.crypto.getRandomValues(t),t},a=e=>{let t=e,n=``;for(let e=0;e<10;e++)n=r.charAt(t%32)+n,t=Math.floor(t/32);let a=``,o=0,s=0;for(let e of i(10))for(o=o<<8|e,s+=8;s>=5;)s-=5,a+=r.charAt(o>>>s&31);return n+a},o=(e=Date.now())=>`evt_${a(e)}_${e}`,s=(e,t)=>{if(e!==void 0)return e;let n=t?.orderId;return typeof n==`string`&&n!==``?n:o()},c=()=>globalThis.document!==void 0,l=[`necessary`,`functional`,`analytics`,`marketing`,`salesOfData`],u=(e,t,n)=>n===void 0||!l.some(e=>e===n)?!1:n===`necessary`||e!==null&&e.categories[n]===!0&&e.apps[t]!==!1,d=()=>{},f=100,p=1024,m=32*1024,h=(e,t,n,r)=>!r||u(e,t,n),g=e=>Object.values(e.config?.apps??{}).some(e=>e.category!==`necessary`||e.capture!==void 0),ee=(e,t)=>{let{app:n,install:r,topic:i,to:a}=e;return typeof n!=`string`||typeof i!=`string`||r!==void 0&&typeof r!=`string`||t&&!(Array.isArray(a)&&a.every(e=>typeof e==`string`))},te=(e,t,n,r)=>r===null?e.slug===t&&(n===void 0||n===e.installId):r.has(e.slug),_=(e,t)=>{console.error(`[Qinto] A handler of app "${e.slug}" (install "${e.installId}") failed.`,t)},v=(e,t,n)=>{for(let r of t)try{let t=r(n);t instanceof Promise&&t.catch(t=>{_(e,t)})}catch(t){_(e,t)}},y=(e,t,n,r)=>{e.activated.add(r.id);let i={slug:t,installId:r.id,eventHandlers:[],consentHandlers:[],pushHandlers:[],sharedContextHandlers:[]};e.instances.push(i);let a={variables:r.variables,install:{id:r.id,label:r.label},track:(t,n)=>{e.client.track(t,n).catch(d)},onEvent:e=>{i.eventHandlers.push(e)},onConsent:e=>{i.consentHandlers.push(e)},onPush:e=>{i.pushHandlers.push(e)},onSharedContext:n=>{if(e.target.config?.apps?.[t]?.sharedContext!==!0){console.error(`[Qinto] App "${t}" reads shared context without declaring the sharedContext capability.`);return}i.sharedContextHandlers.push(n),e.sharedContext!==null&&S(e,t)&&v(i,[n],e.sharedContext)}};try{n(a)}catch(e){console.error(`[Qinto] App "${t}" failed to activate install "${r.id}".`,e)}},b=(e,t,n)=>{if(!h(e.consent,t,e.target.config?.apps?.[t]?.category,e.target.config?.consentConfiguration?.enabled===!0))return;let r=((`_appInstalls`in e.target?e.target._appInstalls:void 0)?.[t]??[]).filter(t=>!e.activated.has(t.id));if(r.length===0)return;let i=n.factory;if(i===void 0){try{i=n.loader()}catch(e){i=null,console.error(`[Qinto] App "${t}" failed to load.`,e)}e.apps.set(t,{...n,factory:i})}if(i!==null)for(let n of r)y(e,t,i,n)},x=(e,t,n)=>h(n,t,e.target.config?.apps?.[t]?.category,e.target.config?.consentConfiguration?.enabled===!0),S=(e,t)=>x(e,t,e.consent)?e.sharedContextConsent===void 0||x(e,t,e.sharedContextConsent):!1,C=e=>{let{categories:t,apps:n}=e;if(!(typeof t!=`object`||!t||typeof n!=`object`||!n))return{categories:t,apps:n}},w=(e,t)=>{let n=e;n.consent=t,n.sharedContextConsent=void 0;for(let n of e.instances)v(n,n.consentHandlers,t);e.onConsentSettled?.(t);for(let[t,n]of e.apps)b(e,t,n)},T=async e=>{try{w(e,await e.client.getConsent())}catch(e){console.error(`[Qinto] The apps consent read failed.`,e)}},ne=e=>{let t;try{t=JSON.stringify(e)}catch{return}if(!(t===void 0||new TextEncoder().encode(t).length>p))return JSON.parse(t)},re=e=>{let t={};for(let n of e){if(n.settled!==n.total||n.values.length!==1)continue;let e=ne(n.values[0]);if(e===void 0)continue;let r={...t[n.instance.slug]??{},[n.instance.installId]:e},i={...t,[n.instance.slug]:r};new TextEncoder().encode(JSON.stringify(i)).length<=m&&(t[n.instance.slug]=r)}return Object.keys(t).length===0?void 0:t},E=async(e,t)=>{e.onPageEvent?.(e.consent);let n=[],r=[];for(let i of e.instances){if(!h(e.consent,i.slug,e.target.config?.apps?.[i.slug]?.category,e.target.config?.consentConfiguration?.enabled===!0))continue;if(e.target.config?.apps?.[i.slug]?.eventResults?.includes(t.type)!==!0){v(i,i.eventHandlers,t);continue}let a={instance:i,total:i.eventHandlers.length,settled:0,values:[]};n.push(a);for(let e of i.eventHandlers){let n;try{n=e(t)}catch(e){a.settled+=1,_(i,e);continue}r.push(Promise.resolve(n).then(e=>{a.settled+=1,e!==void 0&&a.values.push(e)},e=>{a.settled+=1,_(i,e)}))}}if(r.length>0){let e=d,t=new Promise(t=>{e=t}),n=setTimeout(e,f);await Promise.race([Promise.all(r),t]),clearTimeout(n)}return re(n)},ie=e=>{let{client:t}=e;return{track:async(n,r,i)=>{let a=s(i?.eventId,r),o=t.actionContext(),c=await E(e,{type:`track`,event:n,eventId:a,properties:r??{}});return await t.submitTrack({event:n,eventId:a,properties:r,context:o,appResults:c}),{eventId:a}},identify:async(n,r)=>{let i=t.actionContext(),a=await E(e,{type:`identify`,event:`identify`,properties:n??{}});return t.submitIdentify({traits:n,id:r,context:i,appResults:a})},alias:t.alias,consent:async n=>{if(await t.submitConsent(n,t.actionContext()),e.onConsentMutation?.(),g(e.target)){let t=e;t.consent=null,await T(e)}},getAnonId:t.getAnonId,getConsent:t.getConsent,getSession:t.getSession,close:t.close}},ae=(e,t)=>{let n=new Map,r=null,i=null,a=e=>{let[t,i]=e;if(n.has(t))return;let a={loader:i};n.set(t,a),r?.(t,a)},o=e,s=`_apps`in o?o._apps:void 0,c=Array.isArray(s)?s:[];c.push=(...e)=>{for(let t of e)a(t);return 0},o._apps=c;for(let e of c.splice(0))a(e);return{sharedContext:e=>{let{context:t}=e;if(typeof t!=`object`||!t||Array.isArray(t)){console.error(`[Qinto] The server sent a malformed shared context.`,e);return}let n=i;if(n===null)return;n.sharedContext=t;let r=C(e),a=r??n.consent;n.sharedContextConsent=r;for(let e of n.instances)x(n,e.slug,a)&&v(e,e.sharedContextHandlers,n.sharedContext)},push:e=>{let{app:t,install:n,topic:r,scope:a,to:o}=e,s=a===`site`;if(ee(e,s)){console.error(`[Qinto] The server sent a malformed app push.`,e);return}let c=i;if(c===null)return;let l=s?new Set(o):null,u={topic:r,data:e.data,from:t};for(let e of c.instances)te(e,t,n,l)&&h(c.consent,e.slug,c.target.config?.apps?.[e.slug]?.category,c.target.config?.consentConfiguration?.enabled===!0)&&v(e,e.pushHandlers,u)},connect:async a=>{let o={target:e,client:a,apps:n,instances:[],activated:new Set,consent:null,sharedContext:i?.sharedContext??null,sharedContextConsent:i?.sharedContextConsent,onConsentSettled:t?.onConsentSettled,onConsentMutation:t?.onConsentMutation,onPageEvent:t?.onPageEvent};i=o,r=(e,t)=>{b(o,e,t),o.consent===null&&o.target.config?.consentConfiguration?.enabled===!0&&o.target.config?.apps?.[e]?.category!==`necessary`&&T(o)};for(let[e,t]of n)b(o,e,t);return e.config?.consentConfiguration?.enabled===!0&&g(e)?await T(o):o.onConsentSettled?.(o.consent),ie(o)}}},oe=`PageView`,D=()=>{},se=e=>{e.config?.autoCapture?.pageLoad===!0&&e.q.push([`track`,[oe],D,D])},O=512,k=1440*60*1e3,A=e=>Object.fromEntries(Object.entries(e).map(([e,t])=>[e,Object.fromEntries(Object.entries(t).map(([e,t])=>[e,t.value]))])),j=(e,t)=>`qinto:cap:${encodeURIComponent(e)}:${encodeURIComponent(t)}`,M=e=>{try{let t=window.sessionStorage.getItem(e);if(t===null)return null;let n=JSON.parse(t);return typeof n.at!=`number`||typeof n.anonId!=`string`||typeof n.apps!=`object`||n.apps===null||Date.now()-n.at>k?null:{at:n.at,anonId:n.anonId,apps:n.apps}}catch{return null}},N=(e,t)=>{try{window.sessionStorage.setItem(e,JSON.stringify(t))}catch{}},P=e=>{try{window.sessionStorage.removeItem(e)}catch{}},F=e=>{try{return decodeURIComponent(e)}catch{return e}},I=()=>{let e={};for(let t of document.cookie.split(`;`)){let n=t.indexOf(`=`);n>0&&(e[t.slice(0,n).trim()]=F(t.slice(n+1)))}return e},L=(e,t)=>{let n={};for(let r of e.queryParams){let e=t.params.get(r);e!==null&&e.length<=O&&(n[r]={value:e,source:`query`})}for(let r of e.cookies){let e=t.cookies[r];e!==void 0&&e.length<=O&&(n[r]={value:e,source:`cookie`})}return n},R=(e,t)=>{let n={params:new URLSearchParams(window.location.search),cookies:I()},r={};for(let[i,a]of Object.entries(e.config?.apps??{})){if(a.capture===void 0||!u(t,i,a.category))continue;let e=L(a.capture,n);Object.keys(e).length>0&&(r[i]=e)}return r},z=(e,t)=>{let n={};for(let[r,i]of Object.entries(e)){let e=t[r]??{},a={};for(let[t,n]of Object.entries(i))(e[t]?.value!==n.value||e[t]?.source!==n.source)&&(a[t]=n);Object.keys(a).length>0&&(n[r]=a)}return n},B=(e,t,n,r)=>{let i=j(r,n),a=M(i),o=a?.apps??{},s=a?.anonId??null,c=a===null,l={},u=0,d=(e,t)=>{s!==null&&s!==e.anonId&&(o={}),s=e.anonId;let n=new Set(Object.entries(e.accepted).flatMap(([e,t])=>t.map(t=>`${e}\u0000${t}`)));for(let[e,r]of Object.entries(t))for(let[t,i]of Object.entries(r))n.has(`${e}\u0000${t}`)&&(o[e]={...o[e],[t]:i});N(i,{at:Date.now(),anonId:s,apps:o})},f=null,p=()=>{u+=1,o={},l={},P(i)},m=n=>{if(f=n,!c)return;let r=z(R(e,n),{...o,...l});if(Object.keys(r).length===0)return;let i=u;l={...l,...r},t(A(r)).then(e=>{i===u&&d(e,r)}).catch(()=>{}).finally(()=>{l={}})};return{settled:e=>{m(e)},needsAnon:()=>!c,observedAnon:e=>{(e===null||s!==null&&s!==e)&&p(),s=e,c=!0,m(f)},clear:p}},V=Symbol.for(`qinto.connectGate`),H=()=>{},U=e=>{let t=globalThis,n=(t[V]??Promise.resolve()).then(e);return t[V]=n.then(H,H),n},W=class extends e{constructor(e){super(e),this.name=`QintoProtocolError`}},G=e=>{if(typeof e!=`string`)return null;let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=`object`||!t)return null;let n=t;return n.t===`ack`||n.t===`error`||n.t===`consentState`||n.t===`session`||n.t===`captureAck`||n.t===`appPush`||n.t===`sharedContext`?t:null},K=e=>{if(e.t===`consentState`)return{categories:e.categories,apps:e.apps};if(e.t===`session`)return{anonId:e.anonId,globalId:e.globalId};if(e.t===`captureAck`)return{anonId:e.anonId,accepted:e.accepted}},ce=e=>{let n=new Map,r=e=>{let t=n.get(e);if(t!==void 0)return clearTimeout(t.timer),n.delete(e),t};return{submit:r=>new Promise((i,a)=>{let o={frame:r,sent:e.send(r),resolve:i,reject:a,timer:setTimeout(()=>{n.delete(r.ref),a(new t(`The Qinto request timed out.`))},e.requestTimeoutMs)};n.set(r.ref,o)}),flush:()=>{for(let t of n.values())t.sent||=e.send(t.frame)},deliver:e=>{let t=e.ref===void 0?void 0:r(e.ref);if(t!==void 0){if(e.t===`error`){t.reject(new W(e.message));return}t.resolve(K(e))}},rejectAll:e=>{let t=[...n.values()];n.clear();for(let n of t)clearTimeout(n.timer),n.reject(e)}}},le=e=>new WebSocket(e),ue=500,de=3e4,fe=`session not initialized`,pe=(e,t)=>{let n=Math.min(ue*2**e,de);return Math.round(n/2+n/2*t)},me=(e,t)=>e.t===`appPush`?(t.onAppPush?.(e),!0):e.t===`sharedContext`?(t.onSharedContext?.(e),!0):!1,he=e=>{let t=`${e.destination.replace(/\/+$/,``)}/open`,n=null,r=null,i=0,a=null,o=ce({send:e=>n===null||n.readyState!==1?!1:(n.send(JSON.stringify(e)),!0),requestTimeoutMs:e.requestTimeoutMs}),s=t=>{e.onError?.(t)},c=()=>{if(r!==null&&(clearTimeout(r),r=null),n!==null){let e=n;n=null,e.close()}o.rejectAll(new W(`connection closed`))},l=()=>{let u=le(t);n=u,u.onopen=()=>{i=0;let e=a;a=null,o.flush(),e?.resolve()},u.onmessage=t=>{let n=G(t.data);if(n===null){s(new W(`invalid message`));return}me(n,e)||(`anonId`in n&&typeof n.anonId==`string`&&e.onAnonId?.(n.anonId),o.deliver(n),n.t===`error`&&n.message===fe&&u.close())},u.onerror=()=>{s(new W(`connection closed`))},u.onclose=()=>{if(n!==u)return;n=null;let e=a;if(e!==null){a=null,c(),e.reject(new W(`connection closed`));return}o.rejectAll(new W(`connection closed`)),r=setTimeout(()=>{r=null,l()},pe(i,Math.random())),i+=1}};return{connect:()=>new Promise((e,t)=>{a={resolve:e,reject:t},l()}),submit:e=>o.submit(e),close:()=>{c()}}},ge=1e4,_e=()=>{let e=0;return()=>(e+=1,`q${e}`)},ve=(e,t)=>{let n=`qinto:visit:${e.replace(/\/+$/,``)}:${t}`,r,i=!1;try{let e=sessionStorage.getItem(n),t=e===null?null:JSON.parse(e);t===null||typeof t.id!=`string`||!/^vis_[0-9a-f-]{36}$/.test(t.id)||!Number.isSafeInteger(t.startedAt)||t.startedAt<0?(r={id:`vis_${crypto.randomUUID()}`,startedAt:Date.now()},sessionStorage.setItem(n,JSON.stringify(r)),i=!0):r={id:t.id,startedAt:t.startedAt}}catch{r={id:`vis_${crypto.randomUUID()}`,startedAt:Date.now()},i=!0}return()=>{let e={...r,isNew:i};return i=!1,e}},ye=(e,t,n,r)=>{let i=null,a=ve(n,r),o=()=>{let e=document.referrer;return{occurredAt:Date.now(),page:{url:window.location.href,...e===``?{}:{referrer:e}},session:a()}},c=async()=>{let n=await e.submit({t:`getSession`,ref:t()});return i=n.anonId,n};return{actionContext:o,submitIdentify:async({traits:n,id:r,context:i,appResults:a})=>{await e.submit({t:`identify`,ref:t(),traits:n,id:r,context:i,appResults:a})},submitTrack:async({event:n,eventId:r,properties:i,context:a,appResults:o})=>{await e.submit({t:`track`,ref:t(),event:n,eventId:r,properties:i,context:a,appResults:o})},submitConsent:async(n,r)=>{await e.submit({t:`consent`,ref:t(),categories:n.categories,apps:n.apps,context:r})},identify:async(n,r)=>{await e.submit({t:`identify`,ref:t(),traits:n,id:r,context:o()})},track:async(n,r,i)=>{let a=s(i?.eventId,r);return await e.submit({t:`track`,ref:t(),event:n,eventId:a,properties:r,context:o()}),{eventId:a}},alias:async n=>{await e.submit({t:`alias`,ref:t(),customId:n})},consent:async n=>{await e.submit({t:`consent`,ref:t(),categories:n.categories,apps:n.apps,context:o()})},getConsent:async()=>await e.submit({t:`getConsent`,ref:t()}),getSession:c,getAnonId:async()=>(i===null&&await c(),i),close:()=>{e.close()}}},be=async e=>{if(!c())throw new n(`You are calling init() in a server environment. Use createClient from @blotout/qinto-sdk-server there.`);let t=he({destination:e.destination,requestTimeoutMs:e.requestTimeoutMs??ge,onError:e.onError,onAppPush:e.onAppPush,onSharedContext:e.onSharedContext,onAnonId:e.onAnonId});await U(()=>t.connect());let r=_e();return{client:ye(t,r,e.destination,e.globalName??`qinto`),submitCapture:async e=>await t.submit({t:`capture`,ref:r(),apps:e})}},xe=[`then`,`ready`,`config`],q=()=>{},Se=(e,t)=>(...n)=>{let r=new Promise((r,i)=>{e.q.push([t,n,r,i])});return r.catch(q),r},J=e=>{let t=e;return t._q=1,t.q=[],new Proxy(t,{get:(e,n)=>typeof n!=`string`||xe.includes(n)||n in t?Reflect.get(t,n):(t[n]=Se(t,n),t[n])})},Ce=()=>{let e=document.currentScript?.dataset.qintoGlobal;return typeof e==`string`&&e!==``?e:`qinto`},we=e=>typeof e==`object`&&!!e&&e._q===1,Y=(e=`qinto`)=>{let t=globalThis;if(e in t){let n=t[e];if(!we(n))return null;let r=Array.isArray(n.q)?n:J(n);return r!==n&&Object.defineProperty(t,e,{value:r,writable:!0,enumerable:!0,configurable:!0}),r}let n=J({});return Object.defineProperty(t,e,{value:n,writable:!0,enumerable:!0,configurable:!0}),n},Te=(t,n)=>async(r,i)=>{let a=Reflect.get(t,r);if(typeof a!=`function`)throw new e(`[Qinto] ${n}.${r} is not a method of this tag.`);return a.apply(t,Array.from(i))},Ee=e=>()=>Promise.reject(e),X=(e,t)=>{let[n,r,i,a]=t;e(n,r).then(i,a)},De=e=>{let t=[];return t.push=(...t)=>{for(let n of t)X(e,n);return 0},t},Oe=(e,t,n=`window.qinto`)=>{let r=e.ready;if(r!==void 0)return r;let i=e,a=e=>{let t=i.q;i.q=De(e);for(let n of t)X(e,n)},o=t().then(e=>{a(Te(e,n))},e=>{throw a(Ee(e)),e});return o.catch(q),i.ready=o,o},Z=Ce(),Q=Y(Z),$=`window.${Z}`;if(Q!==null&&Q.ready===void 0){let e=null,t=ae(Q,{onConsentSettled:t=>{e?.settled(t)},onConsentMutation:()=>{e?.clear()},onPageEvent:t=>{e?.settled(t)}});se(Q),Oe(Q,async()=>{let n=Q.config?.destination;if(typeof n!=`string`||n===``)throw Error(`[Qinto] ${$}.config.destination is missing.`);let r=await be({destination:n,globalName:Z,onAppPush:t.push,onSharedContext:t.sharedContext,onAnonId:t=>{e?.observedAnon(t)}});e=B(Q,r.submitCapture,n,Z);let i=await t.connect(r.client);return e.needsAnon()&&e.observedAnon((await r.client.getSession()).anonId),i},$)}})();
|