@blotout/qinto-cli 0.1.24 → 0.1.26
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/README.md +4 -3
- package/dist/index.js +2258 -2232
- package/dist/index.js.map +1 -1
- package/dist/worker-artifact/app-runtime/index.js +88 -47
- package/dist/worker-artifact/main/61afaba4cf160e30ef4b71a7ce30a398f71f13e8-q.js.txt +1 -0
- package/dist/worker-artifact/main/index.js +2007 -1583
- package/dist/worker-artifact/version.json +8 -8
- package/package.json +1 -1
- package/dist/worker-artifact/main/944c722e73fe144b1067da970f87716a835c697e-q.js.txt +0 -1
|
@@ -19140,7 +19140,7 @@ var endpointPathParams = (route) => {
|
|
|
19140
19140
|
};
|
|
19141
19141
|
|
|
19142
19142
|
// ../../../libs/app-manifest/src/tools.ts
|
|
19143
|
-
var MAX_APP_TOOLS =
|
|
19143
|
+
var MAX_APP_TOOLS = 20;
|
|
19144
19144
|
var MAX_APP_TOOL_TITLE_LENGTH = 60;
|
|
19145
19145
|
var MIN_APP_TOOL_DESCRIPTION = 20;
|
|
19146
19146
|
var MAX_APP_TOOL_DESCRIPTION = 16 * 1024;
|
|
@@ -19148,7 +19148,7 @@ var MAX_APP_TOOL_PROPERTY_DESCRIPTION = 200;
|
|
|
19148
19148
|
var MAX_APP_TOOL_PROPERTIES = 24;
|
|
19149
19149
|
var MAX_APP_TOOL_SCHEMA_DEPTH = 4;
|
|
19150
19150
|
var MAX_APP_TOOL_ENUM_VALUES = 32;
|
|
19151
|
-
var MAX_MANIFEST_TOOLS_BYTES =
|
|
19151
|
+
var MAX_MANIFEST_TOOLS_BYTES = 375 * 1024;
|
|
19152
19152
|
var TOOL_PROPERTY_NAME = /^[a-zA-Z][a-zA-Z0-9_]*$/;
|
|
19153
19153
|
var RESERVED_TOOL_ARGUMENTS = ["teamId", "siteId", "installId"];
|
|
19154
19154
|
var TOOL_STRING_FORMATS = ["uuid", "date", "date-time", "email", "uri"];
|
|
@@ -19354,6 +19354,7 @@ var APP_FLOWS = ["transform", "destination"];
|
|
|
19354
19354
|
var TRANSFORM_ACTION_TYPES = ["track", "identify"];
|
|
19355
19355
|
var EVENT_ACTION_TYPES = ["track", "identify", "consent"];
|
|
19356
19356
|
var BROWSER_RESULT_ACTION_TYPES = ["track", "identify"];
|
|
19357
|
+
var BROWSER_HOOKS = ["transform"];
|
|
19357
19358
|
var APP_LIFECYCLE_TYPES = ["installed", "configurationChanged", "enabled", "disabled", "versionChanged", "uninstalled"];
|
|
19358
19359
|
var API_CAPABILITIES = ["track", "identify", "alias", "consentWrite", "consentRead", "propertiesRead", "sessionRead"];
|
|
19359
19360
|
var DATA_CAPABILITIES = [
|
|
@@ -19364,7 +19365,8 @@ var DATA_CAPABILITIES = [
|
|
|
19364
19365
|
"eventContext",
|
|
19365
19366
|
"sharedContext",
|
|
19366
19367
|
"facts",
|
|
19367
|
-
"identity"
|
|
19368
|
+
"identity",
|
|
19369
|
+
"siteInstalls"
|
|
19368
19370
|
];
|
|
19369
19371
|
var MAX_APP_VARIABLES = 32;
|
|
19370
19372
|
var MAX_APP_SCOPE_VARIABLES = 16;
|
|
@@ -19642,7 +19644,8 @@ var baseSchema = external_exports.object({
|
|
|
19642
19644
|
browser: external_exports.object({
|
|
19643
19645
|
entry: external_exports.string().min(1).max(255).optional(),
|
|
19644
19646
|
capture: captureSchema.optional(),
|
|
19645
|
-
eventResults: external_exports.array(external_exports.enum(BROWSER_RESULT_ACTION_TYPES)).max(BROWSER_RESULT_ACTION_TYPES.length).optional()
|
|
19647
|
+
eventResults: external_exports.array(external_exports.enum(BROWSER_RESULT_ACTION_TYPES)).max(BROWSER_RESULT_ACTION_TYPES.length).optional(),
|
|
19648
|
+
hooks: external_exports.array(external_exports.enum(BROWSER_HOOKS)).max(BROWSER_HOOKS.length).optional()
|
|
19646
19649
|
}).strict().optional().meta({
|
|
19647
19650
|
description: "The app's browser surface: an optional entry for the bundle that ships inside the site's q.js, and the query params and cookies it declares for capture."
|
|
19648
19651
|
}),
|
|
@@ -19946,6 +19949,15 @@ var validateCapture = (manifest, ctx) => {
|
|
|
19946
19949
|
}
|
|
19947
19950
|
}
|
|
19948
19951
|
};
|
|
19952
|
+
var validateBrowserHooks = (manifest, ctx) => {
|
|
19953
|
+
const hooks = manifest.browser?.hooks ?? [];
|
|
19954
|
+
if (hooks.length > 0 && manifest.browser?.entry === void 0) {
|
|
19955
|
+
ctx.addIssue({ code: "custom", path: ["browser", "hooks"], message: "hooks needs a browser entry" });
|
|
19956
|
+
}
|
|
19957
|
+
if (hooks.includes("transform") && !manifest.flows.includes("transform")) {
|
|
19958
|
+
ctx.addIssue({ code: "custom", path: ["browser", "hooks"], message: "The browser transform hook needs the transform flow" });
|
|
19959
|
+
}
|
|
19960
|
+
};
|
|
19949
19961
|
var validateRpc = (manifest, ctx) => {
|
|
19950
19962
|
const exposes = manifest.rpc?.exposes ?? [];
|
|
19951
19963
|
uniqueOrIssue(
|
|
@@ -20006,6 +20018,7 @@ var appManifestSchema = baseSchema.superRefine((manifest, ctx) => {
|
|
|
20006
20018
|
validatePipelines(manifest, ctx);
|
|
20007
20019
|
validateEndpoints(manifest, ctx);
|
|
20008
20020
|
validateCapture(manifest, ctx);
|
|
20021
|
+
validateBrowserHooks(manifest, ctx);
|
|
20009
20022
|
validateRpc(manifest, ctx);
|
|
20010
20023
|
validateEvents(manifest, ctx);
|
|
20011
20024
|
validateOauth(manifest, ctx);
|
|
@@ -20030,6 +20043,7 @@ var appRpcContractSchema = external_exports.record(external_exports.string().reg
|
|
|
20030
20043
|
var ENVELOPE_VERSION = 3;
|
|
20031
20044
|
var ENVELOPE_ERROR_CODES = ["invalid_arguments"];
|
|
20032
20045
|
var MAX_INSTALLS_PER_APP = 15;
|
|
20046
|
+
var MAX_APPS_PER_DOMAIN = 50;
|
|
20033
20047
|
var MAX_EMITS_PER_INSTALL = 10;
|
|
20034
20048
|
var MAX_PUSHES_PER_INSTALL = 10;
|
|
20035
20049
|
var MAX_CAPTURE_WRITES_PER_INSTALL = 10;
|
|
@@ -20043,6 +20057,10 @@ var MAX_RESPONSE_BYTES = 1024 * 1024;
|
|
|
20043
20057
|
var MAX_RPC_BYTES = 128 * 1024;
|
|
20044
20058
|
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();
|
|
20045
20059
|
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();
|
|
20060
|
+
var installRuleSchema = external_exports.object({
|
|
20061
|
+
mode: external_exports.enum(["except", "only"]),
|
|
20062
|
+
installIds: external_exports.array(external_exports.string().min(1).max(64)).max(MAX_APPS_PER_DOMAIN * MAX_INSTALLS_PER_APP)
|
|
20063
|
+
}).strict();
|
|
20046
20064
|
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) => {
|
|
20047
20065
|
return new TextEncoder().encode(JSON.stringify(push.data ?? null)).length <= MAX_PUSH_BYTES;
|
|
20048
20066
|
}, "Push data exceeds the per-message size cap");
|
|
@@ -20129,7 +20147,11 @@ var envelopeRequestSchema = external_exports.object({
|
|
|
20129
20147
|
var envelopeResponseSchema = external_exports.object({
|
|
20130
20148
|
v: external_exports.literal(ENVELOPE_VERSION),
|
|
20131
20149
|
// Transform invocations only: pass the action through, drop it, or replace its payload (§5.4).
|
|
20132
|
-
result: external_exports.union([
|
|
20150
|
+
result: external_exports.union([
|
|
20151
|
+
external_exports.literal("pass"),
|
|
20152
|
+
external_exports.literal("drop"),
|
|
20153
|
+
external_exports.object({ payload: external_exports.record(external_exports.string(), external_exports.unknown()).optional(), installs: installRuleSchema.optional() }).strict()
|
|
20154
|
+
]).optional(),
|
|
20133
20155
|
effects: external_exports.array(effectGroupSchema).optional(),
|
|
20134
20156
|
rpc: external_exports.object({ result: external_exports.unknown() }).strict().refine((rpc) => {
|
|
20135
20157
|
return new TextEncoder().encode(JSON.stringify(rpc.result ?? null)).length <= MAX_RPC_BYTES;
|
|
@@ -20471,6 +20493,12 @@ var appUiAnalyticsQueryPath = (domainId, appSlug2, resourceIdentifier) => {
|
|
|
20471
20493
|
return `/app-ui/sites/${domainId}/apps/${appSlug2}/analytics/${resourceIdentifier}/query`;
|
|
20472
20494
|
};
|
|
20473
20495
|
var uiInstallSchema = external_exports.object({ id: external_exports.string().min(1).max(64), ord: external_exports.number().int().min(1), label: external_exports.string().max(100), enabled: external_exports.boolean() }).strict();
|
|
20496
|
+
var siteInstallSchema = external_exports.object({
|
|
20497
|
+
id: external_exports.string().min(1).max(64),
|
|
20498
|
+
appSlug: external_exports.string().min(1).max(30),
|
|
20499
|
+
appName: external_exports.string().min(1).max(100),
|
|
20500
|
+
label: external_exports.string().max(100)
|
|
20501
|
+
}).strict();
|
|
20474
20502
|
var uiContextSchema = external_exports.object({
|
|
20475
20503
|
version: external_exports.string().min(1).max(32),
|
|
20476
20504
|
viewer: external_exports.object({
|
|
@@ -20481,8 +20509,10 @@ var uiContextSchema = external_exports.object({
|
|
|
20481
20509
|
}).strict(),
|
|
20482
20510
|
install: uiInstallSchema,
|
|
20483
20511
|
installs: external_exports.array(uiInstallSchema).min(1).max(MAX_INSTALLS_PER_APP),
|
|
20512
|
+
siteInstalls: external_exports.array(siteInstallSchema).max(MAX_APPS_PER_DOMAIN * MAX_INSTALLS_PER_APP).optional(),
|
|
20484
20513
|
writeTicket: external_exports.string().min(1).max(2048).optional()
|
|
20485
20514
|
}).strict();
|
|
20515
|
+
var MAX_UI_SITE_INSTALLS_BYTES = 64 * 1024;
|
|
20486
20516
|
var parseUiContext = (raw) => {
|
|
20487
20517
|
if (raw === null) {
|
|
20488
20518
|
return null;
|
|
@@ -20946,6 +20976,18 @@ var addSpanEvent = (name, options = {}) => {
|
|
|
20946
20976
|
span.events = [...span.events ?? [], event];
|
|
20947
20977
|
};
|
|
20948
20978
|
|
|
20979
|
+
// src/emitted-event.ts
|
|
20980
|
+
var checkEmittedEvent = (event) => {
|
|
20981
|
+
if (event.type !== "track") {
|
|
20982
|
+
throw new Error("only track events may be emitted");
|
|
20983
|
+
}
|
|
20984
|
+
const occurredAt = event.occurredAt ?? Date.now();
|
|
20985
|
+
if (!Number.isSafeInteger(occurredAt) || occurredAt < 0) {
|
|
20986
|
+
throw new Error("an emitted event occurredAt must be non-negative Unix milliseconds");
|
|
20987
|
+
}
|
|
20988
|
+
return { ...event, occurredAt };
|
|
20989
|
+
};
|
|
20990
|
+
|
|
20949
20991
|
// src/read-body.ts
|
|
20950
20992
|
var MAX_ENVELOPE_BYTES = 1024 * 1024;
|
|
20951
20993
|
var readBody = async (request, maxBytes = MAX_ENVELOPE_BYTES) => {
|
|
@@ -21038,17 +21080,21 @@ var brokerPush = async (env, input2) => {
|
|
|
21038
21080
|
data: input2.data
|
|
21039
21081
|
});
|
|
21040
21082
|
};
|
|
21041
|
-
var
|
|
21042
|
-
|
|
21043
|
-
|
|
21044
|
-
|
|
21045
|
-
|
|
21046
|
-
|
|
21047
|
-
|
|
21048
|
-
|
|
21049
|
-
|
|
21050
|
-
|
|
21051
|
-
|
|
21083
|
+
var buildTrack = (env, source, installId) => {
|
|
21084
|
+
return async (userId, event, options) => {
|
|
21085
|
+
const checked = checkEmittedEvent(event);
|
|
21086
|
+
await askBroker(env, `apps.track ${checked.payload["event"]}`, {
|
|
21087
|
+
v: ENVELOPE_VERSION,
|
|
21088
|
+
kind: "track",
|
|
21089
|
+
slug: callerSlug(env),
|
|
21090
|
+
key: env.QINTO_INTERNAL_KEY,
|
|
21091
|
+
source,
|
|
21092
|
+
userId,
|
|
21093
|
+
installId,
|
|
21094
|
+
installs: options?.installs,
|
|
21095
|
+
event: checked
|
|
21096
|
+
});
|
|
21097
|
+
};
|
|
21052
21098
|
};
|
|
21053
21099
|
var brokerContextRead = async (env, userId) => {
|
|
21054
21100
|
const answer = await askBroker(env, "apps.context read", {
|
|
@@ -21113,6 +21159,16 @@ var buildIdentity = (env) => {
|
|
|
21113
21159
|
return {
|
|
21114
21160
|
resolve: (identifier, options) => {
|
|
21115
21161
|
return brokerIdentityRead(env, identifier, options);
|
|
21162
|
+
},
|
|
21163
|
+
upsert: async (person) => {
|
|
21164
|
+
const answer = await askBroker(env, "apps.identity upsert", {
|
|
21165
|
+
v: ENVELOPE_VERSION,
|
|
21166
|
+
kind: "identityUpsert",
|
|
21167
|
+
slug: callerSlug(env),
|
|
21168
|
+
key: env.QINTO_INTERNAL_KEY,
|
|
21169
|
+
person
|
|
21170
|
+
});
|
|
21171
|
+
return { anonId: answer.anonId, created: answer.created };
|
|
21116
21172
|
}
|
|
21117
21173
|
};
|
|
21118
21174
|
};
|
|
@@ -21173,18 +21229,6 @@ var buildAppsClient = (env, envelope) => {
|
|
|
21173
21229
|
};
|
|
21174
21230
|
};
|
|
21175
21231
|
|
|
21176
|
-
// src/emitted-event.ts
|
|
21177
|
-
var checkEmittedEvent = (event) => {
|
|
21178
|
-
if (event.type !== "track") {
|
|
21179
|
-
throw new Error("only track events may be emitted");
|
|
21180
|
-
}
|
|
21181
|
-
const occurredAt = event.occurredAt ?? Date.now();
|
|
21182
|
-
if (!Number.isSafeInteger(occurredAt) || occurredAt < 0) {
|
|
21183
|
-
throw new Error("an emitted event occurredAt must be non-negative Unix milliseconds");
|
|
21184
|
-
}
|
|
21185
|
-
return { ...event, occurredAt };
|
|
21186
|
-
};
|
|
21187
|
-
|
|
21188
21232
|
// src/oauth.ts
|
|
21189
21233
|
var EXPIRY_FLOOR_MS = 1e3;
|
|
21190
21234
|
var read = (env, id, ord, now) => {
|
|
@@ -21670,9 +21714,7 @@ var buildWorkflowContext = (env, stamp) => {
|
|
|
21670
21714
|
broadcast: message.broadcast
|
|
21671
21715
|
});
|
|
21672
21716
|
},
|
|
21673
|
-
track:
|
|
21674
|
-
await brokerTrack(env, { source: "workflow", userId, installId: install.id, event: checkEmittedEvent(event) });
|
|
21675
|
-
},
|
|
21717
|
+
track: buildTrack(env, "workflow", install.id),
|
|
21676
21718
|
apps
|
|
21677
21719
|
};
|
|
21678
21720
|
};
|
|
@@ -21957,9 +21999,7 @@ var dispatchSchedule = async (envelope, bundle, env) => {
|
|
|
21957
21999
|
broadcast: message.broadcast
|
|
21958
22000
|
});
|
|
21959
22001
|
},
|
|
21960
|
-
track:
|
|
21961
|
-
await brokerTrack(env, { source: "scheduled", userId, installId: install.id, event: checkEmittedEvent(event2) });
|
|
21962
|
-
},
|
|
22002
|
+
track: buildTrack(env, "scheduled", install.id),
|
|
21963
22003
|
context: (userId) => {
|
|
21964
22004
|
return asyncContext(env, () => {
|
|
21965
22005
|
return userId;
|
|
@@ -22079,9 +22119,7 @@ var buildContext2 = (envelope, env) => {
|
|
|
22079
22119
|
currency: buildCurrency(env),
|
|
22080
22120
|
apps: buildAppsClient(env, { depth: 0 }),
|
|
22081
22121
|
query: buildQuery({ env, ticket: envelope.tool.queryTicket, installId: install.id }),
|
|
22082
|
-
track:
|
|
22083
|
-
await brokerTrack(env, { source: "tool", userId, installId: install.id, event: checkEmittedEvent(event) });
|
|
22084
|
-
},
|
|
22122
|
+
track: buildTrack(env, "tool", install.id),
|
|
22085
22123
|
fail: (message) => {
|
|
22086
22124
|
return { kind: "tool_error", message: truncate(message) };
|
|
22087
22125
|
}
|
|
@@ -22371,9 +22409,7 @@ var buildContext3 = ({
|
|
|
22371
22409
|
broadcast: message.broadcast
|
|
22372
22410
|
});
|
|
22373
22411
|
},
|
|
22374
|
-
track:
|
|
22375
|
-
await brokerTrack(env, { source: "webhook", userId, installId: install.id, event: checkEmittedEvent(event) });
|
|
22376
|
-
},
|
|
22412
|
+
track: buildTrack(env, "webhook", install.id),
|
|
22377
22413
|
context: (userId) => {
|
|
22378
22414
|
return asyncContext(env, () => {
|
|
22379
22415
|
return userId;
|
|
@@ -22829,6 +22865,7 @@ var dispatchUi = async ({ request, env, versions }) => {
|
|
|
22829
22865
|
site,
|
|
22830
22866
|
install: { id: context.install.id, label: context.install.label },
|
|
22831
22867
|
installs: projectAllInstallValues(maps, variableKinds, context.installs),
|
|
22868
|
+
...context.siteInstalls === void 0 ? {} : { siteInstalls: context.siteInstalls },
|
|
22832
22869
|
// The install is named rather than inherited: one panel serves every install, and reading the
|
|
22833
22870
|
// subject install's token while showing another account's UI would be silently wrong.
|
|
22834
22871
|
oauth: buildUiOauth(env, context.installs),
|
|
@@ -22846,6 +22883,7 @@ var dispatchUi = async ({ request, env, versions }) => {
|
|
|
22846
22883
|
viewer: { ...context.viewer, appRole: context.viewer.appRole ?? "full" },
|
|
22847
22884
|
observability: buildObservability(context.install.ord),
|
|
22848
22885
|
identity: buildIdentity(env),
|
|
22886
|
+
currency: buildCurrency(env),
|
|
22849
22887
|
apps: buildAppsClient(env, { depth: 0 })
|
|
22850
22888
|
};
|
|
22851
22889
|
let response;
|
|
@@ -22946,14 +22984,17 @@ var toTransformResult = (value) => {
|
|
|
22946
22984
|
if (typeof value !== "object" || value === null) {
|
|
22947
22985
|
return null;
|
|
22948
22986
|
}
|
|
22949
|
-
const { kind } = value;
|
|
22950
|
-
if (kind === "
|
|
22987
|
+
const { kind, installs } = value;
|
|
22988
|
+
if (kind === "drop") {
|
|
22951
22989
|
return kind;
|
|
22952
22990
|
}
|
|
22991
|
+
if (kind === "pass") {
|
|
22992
|
+
return installs === void 0 ? kind : { installs };
|
|
22993
|
+
}
|
|
22953
22994
|
if (kind === "replace") {
|
|
22954
22995
|
const { payload } = value;
|
|
22955
22996
|
if (typeof payload === "object" && payload !== null && !Array.isArray(payload)) {
|
|
22956
|
-
return { payload };
|
|
22997
|
+
return { payload, installs };
|
|
22957
22998
|
}
|
|
22958
22999
|
}
|
|
22959
23000
|
return null;
|
|
@@ -22983,14 +23024,14 @@ var runTransform = async (envelope, env, action, handler) => {
|
|
|
22983
23024
|
});
|
|
22984
23025
|
const ctx = {
|
|
22985
23026
|
...withoutApps,
|
|
22986
|
-
pass: () => {
|
|
22987
|
-
return { kind: "pass" };
|
|
23027
|
+
pass: (options) => {
|
|
23028
|
+
return { kind: "pass", installs: options?.installs };
|
|
22988
23029
|
},
|
|
22989
23030
|
drop: () => {
|
|
22990
23031
|
return { kind: "drop" };
|
|
22991
23032
|
},
|
|
22992
|
-
replace: (payload) => {
|
|
22993
|
-
return { kind: "replace", payload };
|
|
23033
|
+
replace: (payload, options) => {
|
|
23034
|
+
return { kind: "replace", payload, installs: options?.installs };
|
|
22994
23035
|
}
|
|
22995
23036
|
};
|
|
22996
23037
|
let value;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){var e=()=>{},t=t=>{t.config?.autoCapture?.pageLoad===!0&&t.q.push([`track`,[`PageView`],e,e])},n=class extends Error{constructor(e){super(e),this.name=`QintoError`}},r=class extends n{constructor(e){super(e),this.name=`QintoTimeoutError`}},i=(e=Date.now())=>`evt_${globalThis.crypto.randomUUID()}_${e}`,a=(e,t)=>{if(e!==void 0)return e;let n=t?.orderId;return typeof n==`string`&&n!==``?n:i()},o=[`necessary`,`functional`,`analytics`,`marketing`,`salesOfData`],s=[`then`,`ready`,`config`],c=()=>{},l=(e,t)=>(...n)=>{let r=new Promise((r,i)=>{e.q.push([t,n,r,i])});return r.catch(c),r},u=e=>{let t=e;return t._q=1,t.q=[],new Proxy(t,{get:(e,n)=>typeof n!=`string`||s.includes(n)||n in t?Reflect.get(t,n):(t[n]=l(t,n),t[n])})},d=()=>{let e=document.currentScript?.dataset.qintoGlobal;return typeof e==`string`&&e!==``?e:`qinto`},f=e=>typeof e==`object`&&!!e&&e._q===1,p=(e=`qinto`)=>{let t=globalThis;if(e in t){let n=t[e];if(!f(n))return null;let r=Array.isArray(n.q)?n:u(n);return r!==n&&Object.defineProperty(t,e,{value:r,writable:!0,enumerable:!0,configurable:!0}),r}let n=u({});return Object.defineProperty(t,e,{value:n,writable:!0,enumerable:!0,configurable:!0}),n},m=(e,t)=>async(r,i)=>{let a=Reflect.get(e,r);if(typeof a!=`function`)throw new n(`[Qinto] ${t}.${r} is not a method of this tag.`);return a.apply(e,Array.from(i))},h=e=>()=>Promise.reject(e),g=(e,t)=>{let[n,r,i,a]=t;e(n,r).then(i,a)},_=e=>{let t=[];return t.push=(...t)=>{for(let n of t)g(e,n);return 0},t},v=(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=_(e);for(let n of t)g(e,n)},o=t().then(e=>{a(m(e,n))},e=>{throw a(h(e)),e});return o.catch(c),i.ready=o,o},y=(e,t,n)=>n===void 0||!o.some(e=>e===n)?!1:n===`necessary`||e!==null&&e.categories[n]===!0&&e.apps[t]!==!1,b=(e,t,n)=>e.config?.consentConfiguration?.enabled!==!0||y(n,t,e.config?.apps?.[t]?.category),x=e=>Object.values(e.config?.apps??{}).some(e=>e.category!==`necessary`||e.capture!==void 0),ee=(e,t,n,r)=>b(e,t,n)?r===void 0||b(e,t,r):!1,te=e=>{let{categories:t,apps:n}=e;if(typeof t==`object`&&t&&typeof n==`object`&&n)return{categories:t,apps:n}},S=()=>{},C=(e,t)=>{console.error(`[Qinto] A handler of app "${e.slug}" (install "${e.installId}") failed.`,t)},w=(e,t,n)=>{for(let r of t)try{let t=r(n);t instanceof Promise&&t.catch(t=>{C(e,t)})}catch(t){C(e,t)}},T=(e,t,n,r)=>{e.activated.add(r.id);let i={slug:t,installId:r.id,eventHandlers:[],transformHooks:[],consentHandlers:[],pushHandlers:[],sharedContextHandlers:[]};e.instances.push(i);let a={variables:r.variables,install:{id:r.id,label:r.label},getSession:async()=>{let n=await e.client.getSession();return e.target.config?.apps?.[t]?.geo===!0?n:{...n,ip:null,geo:null}},track:(t,n)=>{e.client.track(t,n).catch(S)},onEvent:e=>{i.eventHandlers.push(e)},onTransform:e=>{if(r.transform!==!0){console.error(`[Qinto] App "${t}" registers a transform hook without declaring browser.hooks: ["transform"].`);return}i.transformHooks.push(e)},onConsent:e=>{i.consentHandlers.push(e)},onPush:e=>{i.pushHandlers.push(e)},fetch:async(n,i)=>{let a=new URL(`${e.client.destination}/app/${t}${n}`);if(!n.startsWith(`/`)||!a.pathname.startsWith(`/app/${t}/`))throw TypeError(`[Qinto] App "${t}" fetched "${n}"; the path must be absolute and stay inside the app.`);let o=new Headers(i?.headers);return o.set(`x-qinto-install`,r.id),fetch(a,{...i,headers:o,credentials:`include`})},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&&ee(e.target,t,e.consent,e.sharedContextConsent)&&w(i,[n],e.sharedContext)}};try{n(a)}catch(e){console.error(`[Qinto] App "${t}" failed to activate install "${r.id}".`,e)}},E=100,D=1024,ne=32768,re=e=>{let t;try{t=JSON.stringify(e)}catch{return}if(!(t===void 0||new TextEncoder().encode(t).length>D))return JSON.parse(t)},ie=e=>{let t={};for(let n of e){if(n.settled!==n.total||n.values.length!==1)continue;let e=re(n.values[0]);if(e===void 0)continue;let r={...t[n.source.slug]??{},[n.source.installId]:e},i={...t,[n.source.slug]:r};new TextEncoder().encode(JSON.stringify(i)).length<=ne&&(t[n.source.slug]=r)}return Object.keys(t).length===0?void 0:t},ae=async(e,t,{declares:n,notify:r,report:i})=>{let a=[],o=[];for(let s of e){if(!n(s)){r(s);continue}let e={source:s,total:s.eventHandlers.length,settled:0,values:[]};a.push(e);for(let n of s.eventHandlers){let r;try{r=n(t)}catch(t){e.settled+=1,i(s,t);continue}o.push(Promise.resolve(r).then(t=>{e.settled+=1,t!==void 0&&e.values.push(t)},t=>{e.settled+=1,i(s,t)}))}}if(o.length>0){let e,t=new Promise(t=>{e=setTimeout(t,E)});await Promise.race([Promise.all(o),t]),clearTimeout(e)}return ie(a)},oe=(e,t)=>{if(e.mode===`except`&&t.mode===`except`)return{mode:`except`,installIds:[...new Set([...e.installIds,...t.installIds])]};let[n,r]=e.mode===`only`?[e,t]:[t,e],i=new Set(r.installIds);return{mode:`only`,installIds:n.installIds.filter(e=>i.has(e)===(r.mode===`only`))}},se=(e,t,n,r)=>{let i;try{i=t(n,r)}catch(t){C(e,t);return}if(i===void 0||i===!1)return i;let a=i?.installs;if((a?.mode===`except`||a?.mode===`only`)&&Array.isArray(a.installIds))return a;C(e,TypeError(`A transform hook returned neither nothing, false, nor { installs }.`))},ce=(e,t,n,r)=>{let i=r;for(let r of e)for(let e of r.transformHooks){let a=se(r,e,t,n);if(a===!1)return!1;a!==void 0&&(i=i===void 0?a:oe(i,a))}return i},O=(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`))},k=(e,t,n,r)=>r===null?e.slug===t&&(n===void 0||n===e.installId):r.has(e.slug),A=e=>`_appInstalls`in e?e._appInstalls:void 0,j=(e,t,n)=>{if(!b(e.target,t,e.consent))return;let r=(A(e.target)?.[t]??[]).filter(t=>!e.activated.has(t.id)&&(t.geoFilter!==!0||e.geoAllowed.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)T(e,t,i,n)},M=(e,t)=>{let n=e;n.consent=t,n.sharedContextConsent=void 0;for(let n of e.instances)w(n,n.consentHandlers,t);e.onConsentSettled?.(t);for(let[t,n]of e.apps)j(e,t,n)},N=async e=>{try{M(e,await e.client.getConsent())}catch(e){console.error(`[Qinto] The apps consent read failed.`,e)}},P=async e=>{if(e.geoRequested||!Object.values(A(e.target)??{}).some(e=>e.some(e=>e.geoFilter===!0)))return;let t=e;t.geoRequested=!0;try{t.geoAllowed=new Set(await e.client.getGeoInstalls())}catch(e){console.error(`[Qinto] The geo filter read failed; geo-filtered installs stay off on this page.`,e);return}for(let[t,n]of e.apps)j(e,t,n)},F=async(e,t,n)=>{e.onPageEvent?.(e.consent);let r=new Set(n?.installIds);return ae(e.instances.filter(t=>b(e.target,t.slug,e.consent)&&(n===void 0||r.has(t.installId)===(n.mode===`only`))),t,{declares:n=>e.target.config?.apps?.[n.slug]?.eventResults?.includes(t.type)===!0,notify:e=>{w(e,e.eventHandlers,t)},report:C})},I=e=>{let{client:t}=e;return{track:async(n,r,i)=>{let o=a(i?.eventId,r),s=t.actionContext(),c={type:`track`,event:n,eventId:o,properties:r??{}},l=i?.installs,u=ce(e.instances,c,s.page.url,l);if(u===!1)return{eventId:o};let d=await F(e,c,u);return await t.submitTrack({event:n,eventId:o,properties:r,context:s,appResults:d,installs:l}),{eventId:o}},identify:async(n,r)=>{let i=t.actionContext(),a=await F(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?.(),x(e.target)){let t=e;t.consent=null,await N(e)}},getAnonId:t.getAnonId,getConsent:t.getConsent,getSession:t.getSession,close:t.close}},L=(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=te(e),a=r??n.consent;n.sharedContextConsent=r;for(let e of n.instances)b(n.target,e.slug,a)&&w(e,e.sharedContextHandlers,n.sharedContext)},push:e=>{let{app:t,install:n,topic:r,scope:a,to:o}=e,s=a===`site`;if(O(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)k(e,t,n,l)&&b(c.target,e.slug,c.consent)&&w(e,e.pushHandlers,u)},connect:async a=>{let o={target:e,client:a,apps:n,instances:[],activated:new Set,consent:null,geoAllowed:new Set,geoRequested:!1,sharedContext:i?.sharedContext??null,sharedContextConsent:i?.sharedContextConsent,onConsentSettled:t?.onConsentSettled,onConsentMutation:t?.onConsentMutation,onPageEvent:t?.onPageEvent};i=o,r=(e,t)=>{j(o,e,t),o.consent===null&&o.target.config?.consentConfiguration?.enabled===!0&&o.target.config?.apps?.[e]?.category!==`necessary`&&N(o),P(o)};for(let[e,t]of n)j(o,e,t);let s=P(o);return e.config?.consentConfiguration?.enabled===!0&&x(e)?await N(o):o.onConsentSettled?.(o.consent),await s,I(o)}}},R=512,z=864e5,B=e=>Object.fromEntries(Object.entries(e).map(([e,t])=>[e,Object.fromEntries(Object.entries(t).map(([e,t])=>[e,t.value]))])),V=(e,t)=>`qinto:cap:${encodeURIComponent(e)}:${encodeURIComponent(t)}`,H=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>z?null:{at:n.at,anonId:n.anonId,apps:n.apps}}catch{return null}},U=(e,t)=>{try{window.sessionStorage.setItem(e,JSON.stringify(t))}catch{}},W=e=>{try{window.sessionStorage.removeItem(e)}catch{}},G=e=>{try{return decodeURIComponent(e)}catch{return e}},le=()=>{let e={};for(let t of document.cookie.split(`;`)){let n=t.indexOf(`=`);n>0&&(e[t.slice(0,n).trim()]=G(t.slice(n+1)))}return e},ue=(e,t)=>{let n={};for(let r of e.queryParams){let e=t.params.get(r);e!==null&&e.length<=R&&(n[r]={value:e,source:`query`})}for(let r of e.cookies){let e=t.cookies[r];e!==void 0&&e.length<=R&&(n[r]={value:e,source:`cookie`})}return n},de=(e,t)=>{let n={params:new URLSearchParams(window.location.search),cookies:le()},r={};for(let[i,a]of Object.entries(e.config?.apps??{})){if(a.capture===void 0||!y(t,i,a.category))continue;let e=ue(a.capture,n);Object.keys(e).length>0&&(r[i]=e)}return r},fe=(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},pe=(e,t,n,r)=>{let i=V(r,n),a=H(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});U(i,{at:Date.now(),anonId:s,apps:o})},f=null,p=()=>{u+=1,o={},l={},W(i)},m=n=>{if(f=n,!c)return;let r=fe(de(e,n),{...o,...l});if(Object.keys(r).length===0)return;let i=u;l={...l,...r},t(B(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}},K=Symbol.for(`qinto.connectGate`),q=()=>{},me=e=>{let t=globalThis,n=(t[K]??Promise.resolve()).then(e);return t[K]=n.then(q,q),n},J=class extends n{constructor(e){super(e),this.name=`QintoProtocolError`}},he=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===`geoInstalls`||n.t===`appPush`||n.t===`sharedContext`?t:null},ge=e=>{if(e.t===`consentState`)return{categories:e.categories,apps:e.apps};if(e.t===`session`)return{anonId:e.anonId,globalId:e.globalId,ip:e.ip,geo:e.geo};if(e.t===`captureAck`)return{anonId:e.anonId,accepted:e.accepted};if(e.t===`geoInstalls`)return e.installs},_e=e=>{let t=new Map,n=e=>{let n=t.get(e);if(n!==void 0)return clearTimeout(n.timer),t.delete(e),n};return{submit:n=>new Promise((i,a)=>{let o={frame:n,sent:e.send(n),resolve:i,reject:a,timer:setTimeout(()=>{t.delete(n.ref),a(new r(`The Qinto request timed out.`))},e.requestTimeoutMs)};t.set(n.ref,o)}),flush:()=>{for(let n of t.values())n.sent||=e.send(n.frame)},deliver:e=>{let t=e.ref===void 0?void 0:n(e.ref);if(t!==void 0){if(e.t===`error`){t.reject(new J(e.message));return}t.resolve(ge(e))}},rejectAll:e=>{let n=[...t.values()];t.clear();for(let t of n)clearTimeout(t.timer),t.reject(e)}}},Y=()=>{let e=document.referrer;return{url:window.location.href,...e===``?{}:{referrer:e}}},ve=e=>new WebSocket(e),ye=500,be=3e4,X=4096,xe=8192,Se=(e,t)=>{if(t.url.length>X)return e;let n=new URLSearchParams({url:t.url});t.referrer!==void 0&&t.referrer.length<=X&&n.set(`referrer`,t.referrer);let r=`${e}?${n}`;return r.length<=xe?r:e},Ce=`session not initialized`,we=(e,t)=>{let n=Math.min(ye*2**e,be);return Math.round(n/2+n/2*t)},Te=(e,t)=>e.t===`appPush`?(t.onAppPush?.(e),!0):e.t===`sharedContext`&&(t.onSharedContext?.(e),!0),Ee=e=>{let t=`${e.destination.replace(/\/+$/,``)}/open`,n=null,r=null,i=0,a=null,o=_e({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 J(`connection closed`))},l=()=>{let u=ve(Se(t,Y()));n=u,u.onopen=()=>{i=0;let e=a;a=null,o.flush(),e?.resolve()},u.onmessage=t=>{let n=he(t.data);if(n===null){s(new J(`invalid message`));return}Te(n,e)||(`anonId`in n&&typeof n.anonId==`string`&&e.onAnonId?.(n.anonId),o.deliver(n),n.t===`error`&&n.message===Ce&&u.close())},u.onerror=()=>{s(new J(`connection closed`))},u.onclose=()=>{if(n!==u)return;n=null;let e=a;if(e!==null){a=null,c(),e.reject(new J(`connection closed`));return}o.rejectAll(new J(`connection closed`)),r=setTimeout(()=>{r=null,l()},we(i,Math.random())),i+=1}};return{connect:()=>new Promise((e,t)=>{a={resolve:e,reject:t},l()}),submit:e=>o.submit(e),close:()=>{c()}}},De=1e4,Oe=()=>{let e=0;return()=>(e+=1,`q${e}`)},ke=(e,t,n)=>{let r=null,i=()=>({occurredAt:Date.now(),page:Y()}),o=async()=>{let n=await e.submit({t:`getSession`,ref:t()});return r=n.anonId,n};return{destination:n.replace(/\/+$/,``),actionContext:i,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,installs:s})=>{await e.submit({t:`track`,ref:t(),event:n,eventId:r,properties:i,context:a,appResults:o,installs:s})},submitConsent:async(n,r)=>{await e.submit({t:`consent`,ref:t(),categories:n.categories,apps:n.apps,context:r})},track:async(n,r,o)=>{let s=a(o?.eventId,r);return await e.submit({t:`track`,ref:t(),event:n,eventId:s,properties:r,context:i(),installs:o?.installs}),{eventId:s}},alias:async n=>{await e.submit({t:`alias`,ref:t(),alias:n})},getConsent:async()=>await e.submit({t:`getConsent`,ref:t()}),getGeoInstalls:async()=>await e.submit({t:`getGeoInstalls`,ref:t()}),getSession:o,getAnonId:async()=>(r===null&&await o(),r),close:async()=>{e.close()}}},Ae=async e=>{let t=Ee({destination:e.destination,requestTimeoutMs:e.requestTimeoutMs??De,onError:e.onError,onAppPush:e.onAppPush,onSharedContext:e.onSharedContext,onAnonId:e.onAnonId});await me(()=>t.connect());let n=Oe();return{client:ke(t,n,e.destination),submitCapture:async e=>await t.submit({t:`capture`,ref:n(),apps:e})}},je=(e,t)=>{let n=null,r=L(e,{onConsentSettled:e=>{n?.settled(e)},onConsentMutation:()=>{n?.clear()},onPageEvent:e=>{n?.settled(e)}});return{connect:async i=>{let a=await Ae({...i,onAppPush:r.push,onSharedContext:r.sharedContext,onAnonId:e=>{n?.observedAnon(e)}});n=pe(e,a.submitCapture,i.destination,t);let o=await r.connect(a.client);return n.needsAnon()&&n.observedAnon((await a.client.getSession()).anonId),o}}},Z=d(),Q=p(Z),$=`window.${Z}`;if(Q!==null&&Q.ready===void 0){let e=je(Q,Z);t(Q),v(Q,async()=>{let t=Q.config?.destination;if(typeof t!=`string`||t===``)throw Error(`[Qinto] ${$}.config.destination is missing.`);return e.connect({destination:t})},$)}})();
|