@blotout/qinto-cli 0.1.30 → 0.1.32
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 +8 -1
- package/dist/index.js +3962 -3838
- package/dist/index.js.map +1 -1
- package/dist/worker-artifact/app-runtime/index.js +161 -29
- package/dist/worker-artifact/main/73ef5f028ec35836560c0489d1abdeea83eceede-q.js.txt +1 -0
- package/dist/worker-artifact/main/index.js +1488 -1271
- package/dist/worker-artifact/version.json +11 -11
- package/dist/worker-artifact/wfp/index.js +2 -1
- package/package.json +1 -1
- package/dist/worker-artifact/main/8809017061697bf9b90fa4d72f7eb2e0f0e00ad4-q.js.txt +0 -1
|
@@ -19607,6 +19607,7 @@ var endpointSchema = external_exports.object({
|
|
|
19607
19607
|
var eventsSchema = external_exports.object({
|
|
19608
19608
|
publishes: external_exports.array(external_exports.string().min(1).max(MAX_EVENT_TOPIC_LENGTH).regex(EVENT_TOPIC)).max(MAX_PUBLISHED_TOPICS).default([])
|
|
19609
19609
|
}).strict();
|
|
19610
|
+
var dependenciesSchema = external_exports.array(external_exports.object({ app: external_exports.string().regex(APP_SLUG_PATTERN), description: renderableText(1, 200).optional() }).strict()).max(10);
|
|
19610
19611
|
var rpcSchema = external_exports.object({
|
|
19611
19612
|
exposes: external_exports.array(external_exports.object({ name: external_exports.string().regex(FUNCTION_NAME).max(64), visibility: external_exports.enum(["public", "private"]) }).strict()).max(32).optional(),
|
|
19612
19613
|
calls: external_exports.array(external_exports.object({ app: external_exports.string().regex(APP_SLUG_PATTERN), fn: external_exports.string().regex(FUNCTION_NAME).max(64) }).strict()).max(64).optional()
|
|
@@ -19650,6 +19651,9 @@ var baseSchema = external_exports.object({
|
|
|
19650
19651
|
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."
|
|
19651
19652
|
}),
|
|
19652
19653
|
resources: external_exports.array(resourceSchema).max(32).default([]).meta({ description: "The Cloudflare bindings the app worker is given." }),
|
|
19654
|
+
dependencies: dependenciesSchema.optional().meta({
|
|
19655
|
+
description: "The apps this app needs on the same site. Every app it calls over RPC must be listed."
|
|
19656
|
+
}),
|
|
19653
19657
|
rpc: rpcSchema.optional().meta({ description: "The functions this app exposes to other apps, and the ones it calls on them." }),
|
|
19654
19658
|
events: eventsSchema.optional().meta({
|
|
19655
19659
|
description: "The push topics this app broadcasts to every app on the site. Requires the `sharedContext` data capability; a topic left out reaches only this app\u2019s own browser code."
|
|
@@ -19966,9 +19970,30 @@ var validateRpc = (manifest, ctx) => {
|
|
|
19966
19970
|
["rpc", "exposes"],
|
|
19967
19971
|
"function"
|
|
19968
19972
|
);
|
|
19973
|
+
const dependencies = new Set((manifest.dependencies ?? []).map((dependency) => dependency.app));
|
|
19969
19974
|
for (const [index, call] of (manifest.rpc?.calls ?? []).entries()) {
|
|
19970
19975
|
if (call.app === manifest.slug) {
|
|
19971
19976
|
ctx.addIssue({ code: "custom", path: ["rpc", "calls", index, "app"], message: "An app cannot declare an RPC call to itself" });
|
|
19977
|
+
} else if (!dependencies.has(call.app)) {
|
|
19978
|
+
ctx.addIssue({
|
|
19979
|
+
code: "custom",
|
|
19980
|
+
path: ["rpc", "calls", index, "app"],
|
|
19981
|
+
message: `${call.app} is called over RPC, so it must be in dependencies. Add { "app": "${call.app}" } to dependencies; if your Qinto CLI rejects that field, upgrade it.`
|
|
19982
|
+
});
|
|
19983
|
+
}
|
|
19984
|
+
}
|
|
19985
|
+
};
|
|
19986
|
+
var validateDependencies = (manifest, ctx) => {
|
|
19987
|
+
const dependencies = manifest.dependencies ?? [];
|
|
19988
|
+
uniqueOrIssue(
|
|
19989
|
+
ctx,
|
|
19990
|
+
dependencies.map((dependency) => dependency.app),
|
|
19991
|
+
["dependencies"],
|
|
19992
|
+
"dependency"
|
|
19993
|
+
);
|
|
19994
|
+
for (const [index, dependency] of dependencies.entries()) {
|
|
19995
|
+
if (dependency.app === manifest.slug) {
|
|
19996
|
+
ctx.addIssue({ code: "custom", path: ["dependencies", index, "app"], message: "An app cannot depend on itself" });
|
|
19972
19997
|
}
|
|
19973
19998
|
}
|
|
19974
19999
|
};
|
|
@@ -20019,6 +20044,7 @@ var appManifestSchema = baseSchema.superRefine((manifest, ctx) => {
|
|
|
20019
20044
|
validateEndpoints(manifest, ctx);
|
|
20020
20045
|
validateCapture(manifest, ctx);
|
|
20021
20046
|
validateBrowserHooks(manifest, ctx);
|
|
20047
|
+
validateDependencies(manifest, ctx);
|
|
20022
20048
|
validateRpc(manifest, ctx);
|
|
20023
20049
|
validateEvents(manifest, ctx);
|
|
20024
20050
|
validateOauth(manifest, ctx);
|
|
@@ -20039,9 +20065,47 @@ var appRpcContractSchema = external_exports.record(external_exports.string().reg
|
|
|
20039
20065
|
return new TextEncoder().encode(JSON.stringify(contract)).length <= MAX_RPC_CONTRACT_BYTES;
|
|
20040
20066
|
}, "The RPC contract exceeds the size cap");
|
|
20041
20067
|
|
|
20068
|
+
// ../../../libs/app-envelope/src/geo.ts
|
|
20069
|
+
var cfString = external_exports.string().optional().catch(void 0);
|
|
20070
|
+
var requestGeoSchema = external_exports.object({
|
|
20071
|
+
country: cfString,
|
|
20072
|
+
city: cfString,
|
|
20073
|
+
region: cfString,
|
|
20074
|
+
regionCode: cfString,
|
|
20075
|
+
timezone: cfString,
|
|
20076
|
+
postalCode: cfString,
|
|
20077
|
+
continent: cfString,
|
|
20078
|
+
latitude: cfString,
|
|
20079
|
+
longitude: cfString,
|
|
20080
|
+
isEUCountry: cfString,
|
|
20081
|
+
botManagement: external_exports.object({
|
|
20082
|
+
ja4: cfString,
|
|
20083
|
+
ja3Hash: cfString,
|
|
20084
|
+
score: external_exports.number().optional().catch(void 0),
|
|
20085
|
+
verifiedBot: external_exports.boolean().optional().catch(void 0)
|
|
20086
|
+
}).optional().catch(void 0)
|
|
20087
|
+
});
|
|
20088
|
+
var userGeoSchema = external_exports.object({
|
|
20089
|
+
ip: external_exports.string().optional(),
|
|
20090
|
+
userAgent: external_exports.string().optional(),
|
|
20091
|
+
timezone: external_exports.string().optional(),
|
|
20092
|
+
city: external_exports.string().optional(),
|
|
20093
|
+
postalCode: external_exports.string().optional(),
|
|
20094
|
+
region: external_exports.string().optional(),
|
|
20095
|
+
regionCode: external_exports.string().optional(),
|
|
20096
|
+
country: external_exports.string().optional(),
|
|
20097
|
+
continent: external_exports.string().optional(),
|
|
20098
|
+
isEUCountry: external_exports.string().optional(),
|
|
20099
|
+
latitude: external_exports.string().optional(),
|
|
20100
|
+
longitude: external_exports.string().optional(),
|
|
20101
|
+
ja4: external_exports.string().optional(),
|
|
20102
|
+
ja3: external_exports.string().optional(),
|
|
20103
|
+
botScore: external_exports.string().optional()
|
|
20104
|
+
});
|
|
20105
|
+
|
|
20042
20106
|
// ../../../libs/app-envelope/src/envelope.ts
|
|
20043
20107
|
var ENVELOPE_VERSION = 3;
|
|
20044
|
-
var ENVELOPE_ERROR_CODES = ["invalid_arguments"];
|
|
20108
|
+
var ENVELOPE_ERROR_CODES = ["invalid_arguments", "result_too_large", "callee_timeout", "rpc_error"];
|
|
20045
20109
|
var MAX_INSTALLS_PER_APP = 15;
|
|
20046
20110
|
var MAX_APPS_PER_DOMAIN = 50;
|
|
20047
20111
|
var MAX_EMITS_PER_INSTALL = 10;
|
|
@@ -20055,6 +20119,7 @@ var MAX_SHARED_CONTEXT_ENTRY_BYTES = 4 * 1024;
|
|
|
20055
20119
|
var MAX_PUSH_BYTES = 16 * 1024;
|
|
20056
20120
|
var MAX_RESPONSE_BYTES = 1024 * 1024;
|
|
20057
20121
|
var MAX_RPC_BYTES = 128 * 1024;
|
|
20122
|
+
var TRAFFIC_CLASSES = ["hot", "cold"];
|
|
20058
20123
|
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();
|
|
20059
20124
|
var installRuleSchema = external_exports.object({
|
|
20060
20125
|
mode: external_exports.enum(["except", "only"]),
|
|
@@ -20114,11 +20179,21 @@ var envelopeRequestSchema = external_exports.object({
|
|
|
20114
20179
|
anonId: external_exports.string().min(1).max(64),
|
|
20115
20180
|
globalId: external_exports.string().min(1).max(64).nullable(),
|
|
20116
20181
|
createdAt: external_exports.number().int().optional(),
|
|
20117
|
-
properties: external_exports.record(external_exports.string(), external_exports.
|
|
20118
|
-
geo:
|
|
20182
|
+
properties: external_exports.record(external_exports.string(), external_exports.string()),
|
|
20183
|
+
geo: userGeoSchema.optional()
|
|
20184
|
+
}).strict().optional(),
|
|
20185
|
+
consent: external_exports.object({
|
|
20186
|
+
enabled: external_exports.boolean(),
|
|
20187
|
+
categories: external_exports.object({
|
|
20188
|
+
necessary: external_exports.literal(true),
|
|
20189
|
+
functional: external_exports.boolean(),
|
|
20190
|
+
analytics: external_exports.boolean(),
|
|
20191
|
+
marketing: external_exports.boolean(),
|
|
20192
|
+
salesOfData: external_exports.boolean()
|
|
20193
|
+
}),
|
|
20194
|
+
apps: external_exports.record(external_exports.string(), external_exports.boolean())
|
|
20119
20195
|
}).strict().optional(),
|
|
20120
|
-
|
|
20121
|
-
geo: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
20196
|
+
geo: requestGeoSchema.optional(),
|
|
20122
20197
|
// Connect envelopes only: the page the visitor's socket opened from, and the visit session it joined.
|
|
20123
20198
|
page: pageSchema.optional(),
|
|
20124
20199
|
session: sessionSchema.optional(),
|
|
@@ -20129,7 +20204,15 @@ var envelopeRequestSchema = external_exports.object({
|
|
|
20129
20204
|
context: external_exports.object({ private: contextEntrySchema.optional(), shared: external_exports.record(external_exports.string().min(1).max(30), contextEntrySchema).optional() }).strict().optional(),
|
|
20130
20205
|
// RPC depth is capped at 3 by the broker; hook depth at 2 by the emit path.
|
|
20131
20206
|
depth: external_exports.number().int().min(0).max(3),
|
|
20132
|
-
rpc: external_exports.object({
|
|
20207
|
+
rpc: external_exports.object({
|
|
20208
|
+
caller: external_exports.string().min(1).max(30).nullable(),
|
|
20209
|
+
fn: external_exports.string().min(1).max(64),
|
|
20210
|
+
args: external_exports.unknown(),
|
|
20211
|
+
// Optional on the wire: a site worker predating traffic classes sends none, which means hot.
|
|
20212
|
+
traffic: external_exports.enum(TRAFFIC_CLASSES).optional(),
|
|
20213
|
+
// Cold calls only: the broker mints it so the callee can query its own catalog.
|
|
20214
|
+
queryTicket: external_exports.string().min(1).max(2048).optional()
|
|
20215
|
+
}).strict().refine((rpc) => {
|
|
20133
20216
|
return new TextEncoder().encode(JSON.stringify(rpc.args ?? null)).length <= MAX_RPC_BYTES;
|
|
20134
20217
|
}, "RPC args exceed the size cap").optional(),
|
|
20135
20218
|
action: external_exports.object({
|
|
@@ -20379,7 +20462,7 @@ var endpointContextSchema = external_exports.object({
|
|
|
20379
20462
|
method: external_exports.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]),
|
|
20380
20463
|
mode: external_exports.enum(["webhook", "api"]),
|
|
20381
20464
|
version: external_exports.string().min(1).max(32),
|
|
20382
|
-
geo:
|
|
20465
|
+
geo: requestGeoSchema.optional(),
|
|
20383
20466
|
installs: external_exports.array(installSchema3).min(1).max(15),
|
|
20384
20467
|
user: external_exports.object({ anonId: external_exports.string().min(1).max(64) }).strict().optional()
|
|
20385
20468
|
}).strict().refine((context) => {
|
|
@@ -21212,7 +21295,7 @@ var brokerActive = async (env, input2) => {
|
|
|
21212
21295
|
}
|
|
21213
21296
|
return response.status >= 400 && response.status < 500 ? { kind: "refused" } : { kind: "unknown" };
|
|
21214
21297
|
};
|
|
21215
|
-
var buildAppsClient = (env, envelope) => {
|
|
21298
|
+
var buildAppsClient = (env, envelope, traffic) => {
|
|
21216
21299
|
const caller = callerSlug(env);
|
|
21217
21300
|
const subject = envelope.user?.anonId;
|
|
21218
21301
|
return {
|
|
@@ -21229,7 +21312,8 @@ var buildAppsClient = (env, envelope) => {
|
|
|
21229
21312
|
fn,
|
|
21230
21313
|
args,
|
|
21231
21314
|
...options?.installId === void 0 ? {} : { installId: options.installId },
|
|
21232
|
-
depth: envelope.depth + 1
|
|
21315
|
+
depth: envelope.depth + 1,
|
|
21316
|
+
traffic
|
|
21233
21317
|
});
|
|
21234
21318
|
return answer.result;
|
|
21235
21319
|
},
|
|
@@ -21738,10 +21822,14 @@ var buildWorkflowContext = (env, stamp) => {
|
|
|
21738
21822
|
const { variables, secrets } = projectInstallValues(parseVariableMaps(env), variableKinds, stamp.ord);
|
|
21739
21823
|
const { appVariables, appSecrets } = projectAppValues(env, appVariableKinds);
|
|
21740
21824
|
const install = { id: stamp.installId, label: stamp.installLabel };
|
|
21741
|
-
const apps = buildAppsClient(
|
|
21742
|
-
|
|
21743
|
-
|
|
21744
|
-
|
|
21825
|
+
const apps = buildAppsClient(
|
|
21826
|
+
env,
|
|
21827
|
+
{
|
|
21828
|
+
...stamp.anonId === null ? {} : { user: { anonId: stamp.anonId, globalId: null, properties: {} } },
|
|
21829
|
+
depth: 0
|
|
21830
|
+
},
|
|
21831
|
+
"cold"
|
|
21832
|
+
);
|
|
21745
21833
|
return {
|
|
21746
21834
|
env: appEnv(env),
|
|
21747
21835
|
install,
|
|
@@ -21816,7 +21904,8 @@ var buildContext = ({
|
|
|
21816
21904
|
pushes,
|
|
21817
21905
|
captures,
|
|
21818
21906
|
context,
|
|
21819
|
-
currency
|
|
21907
|
+
currency,
|
|
21908
|
+
traffic
|
|
21820
21909
|
}) => {
|
|
21821
21910
|
const { variables, secrets } = projectInstallValues(maps, kinds, install.ord);
|
|
21822
21911
|
const subject = envelope.user?.anonId ?? null;
|
|
@@ -21886,7 +21975,7 @@ var buildContext = ({
|
|
|
21886
21975
|
observability: buildObservability(install.ord),
|
|
21887
21976
|
identity: buildIdentity(env),
|
|
21888
21977
|
currency,
|
|
21889
|
-
apps: buildAppsClient(env, envelope)
|
|
21978
|
+
apps: buildAppsClient(env, envelope, traffic)
|
|
21890
21979
|
};
|
|
21891
21980
|
};
|
|
21892
21981
|
|
|
@@ -22007,7 +22096,7 @@ var dispatchSchedule = async (envelope, bundle, env) => {
|
|
|
22007
22096
|
observability: buildObservability(install.ord),
|
|
22008
22097
|
identity: buildIdentity(env),
|
|
22009
22098
|
currency,
|
|
22010
|
-
apps: buildAppsClient(env, { depth: 0 }),
|
|
22099
|
+
apps: buildAppsClient(env, { depth: 0 }, "cold"),
|
|
22011
22100
|
query: buildQuery({ env, ticket: install.queryTicket, installId: install.id }),
|
|
22012
22101
|
push: async (userId, message) => {
|
|
22013
22102
|
await brokerPush(env, {
|
|
@@ -22136,7 +22225,7 @@ var buildContext2 = (envelope, env) => {
|
|
|
22136
22225
|
observability: buildObservability(install.ord),
|
|
22137
22226
|
identity: buildIdentity(env),
|
|
22138
22227
|
currency: buildCurrency(env),
|
|
22139
|
-
apps: buildAppsClient(env, { depth: 0 }),
|
|
22228
|
+
apps: buildAppsClient(env, { depth: 0 }, "cold"),
|
|
22140
22229
|
query: buildQuery({ env, ticket: envelope.tool.queryTicket, installId: install.id }),
|
|
22141
22230
|
track: buildTrack(env, "tool", install.id),
|
|
22142
22231
|
fail: (message) => {
|
|
@@ -22403,7 +22492,7 @@ var buildContext3 = ({
|
|
|
22403
22492
|
geo,
|
|
22404
22493
|
params,
|
|
22405
22494
|
install: { id: install.id, label: install.label },
|
|
22406
|
-
...user === void 0 ? {} : { user: { anonId: user.anonId
|
|
22495
|
+
...user === void 0 ? {} : { user: { anonId: user.anonId } },
|
|
22407
22496
|
startWorkflow: buildStartWorkflow({
|
|
22408
22497
|
ord: install.ord,
|
|
22409
22498
|
installId: install.id,
|
|
@@ -22418,7 +22507,7 @@ var buildContext3 = ({
|
|
|
22418
22507
|
observability: buildObservability(install.ord),
|
|
22419
22508
|
identity: buildIdentity(env),
|
|
22420
22509
|
currency,
|
|
22421
|
-
apps: buildAppsClient(env, { depth: 0 }),
|
|
22510
|
+
apps: buildAppsClient(env, { depth: 0 }, "hot"),
|
|
22422
22511
|
push: async (userId, message) => {
|
|
22423
22512
|
await brokerPush(env, {
|
|
22424
22513
|
userId,
|
|
@@ -22667,6 +22756,17 @@ var checkAgainst = async (schema, value) => {
|
|
|
22667
22756
|
};
|
|
22668
22757
|
|
|
22669
22758
|
// src/rpc.ts
|
|
22759
|
+
var MAX_RPC_ERROR_MESSAGE_LENGTH = 1024;
|
|
22760
|
+
var rpcQuery = (env, rpc, installId) => {
|
|
22761
|
+
if (rpc.queryTicket !== void 0) {
|
|
22762
|
+
return buildQuery({ env, ticket: rpc.queryTicket, installId });
|
|
22763
|
+
}
|
|
22764
|
+
const reason = (rpc.traffic ?? "hot") === "hot" ? "catalog queries are not available on hot traffic" : "catalog queries are not available on this site until its next deploy";
|
|
22765
|
+
const refuse = async () => {
|
|
22766
|
+
throw new Error(reason);
|
|
22767
|
+
};
|
|
22768
|
+
return { catalog: refuse, analytics: refuse };
|
|
22769
|
+
};
|
|
22670
22770
|
var dispatchRpc = async (envelope, bundle, env) => {
|
|
22671
22771
|
if (envelope.installs.length > 1) {
|
|
22672
22772
|
return jsonError(400, "rpc envelope carries more than one install");
|
|
@@ -22694,14 +22794,29 @@ var dispatchRpc = async (envelope, bundle, env) => {
|
|
|
22694
22794
|
const currency = buildCurrency(env);
|
|
22695
22795
|
const subject = envelope.user?.anonId ?? null;
|
|
22696
22796
|
const ctx = {
|
|
22697
|
-
...buildContext({
|
|
22797
|
+
...buildContext({
|
|
22798
|
+
env,
|
|
22799
|
+
envelope,
|
|
22800
|
+
site,
|
|
22801
|
+
install,
|
|
22802
|
+
maps,
|
|
22803
|
+
kinds,
|
|
22804
|
+
appScope,
|
|
22805
|
+
emits,
|
|
22806
|
+
pushes,
|
|
22807
|
+
captures,
|
|
22808
|
+
context,
|
|
22809
|
+
currency,
|
|
22810
|
+
traffic: rpc.traffic ?? "hot"
|
|
22811
|
+
}),
|
|
22698
22812
|
context: fetchedContext(
|
|
22699
22813
|
env,
|
|
22700
22814
|
(what) => {
|
|
22701
22815
|
return requireSubject(subject, what);
|
|
22702
22816
|
},
|
|
22703
22817
|
context
|
|
22704
|
-
)
|
|
22818
|
+
),
|
|
22819
|
+
query: rpcQuery(env, rpc, install.id)
|
|
22705
22820
|
};
|
|
22706
22821
|
let value;
|
|
22707
22822
|
try {
|
|
@@ -22711,17 +22826,19 @@ var dispatchRpc = async (envelope, bundle, env) => {
|
|
|
22711
22826
|
} catch (error61) {
|
|
22712
22827
|
const message = failureMessage(error61);
|
|
22713
22828
|
console.warn(`rpc failed for install ${install.id}: ${message}`);
|
|
22829
|
+
if (error61?.__qintoRpcError === true) {
|
|
22830
|
+
return json2(200, { v: ENVELOPE_VERSION, error: { code: "rpc_error", message: message.slice(0, MAX_RPC_ERROR_MESSAGE_LENGTH) } });
|
|
22831
|
+
}
|
|
22714
22832
|
return json2(200, { v: ENVELOPE_VERSION, error: { message } });
|
|
22715
22833
|
}
|
|
22716
22834
|
const checked = await checkAgainst(definition.output, value);
|
|
22717
22835
|
if (!checked.ok) {
|
|
22718
22836
|
return jsonError(200, failureMessage(`rpc result does not match the output schema: ${checked.message}`));
|
|
22719
22837
|
}
|
|
22720
|
-
const
|
|
22721
|
-
|
|
22722
|
-
|
|
22723
|
-
}
|
|
22724
|
-
const body = { v: ENVELOPE_VERSION, rpc: { result } };
|
|
22838
|
+
const body = {
|
|
22839
|
+
v: ENVELOPE_VERSION,
|
|
22840
|
+
rpc: { result: checked.value === void 0 ? null : checked.value }
|
|
22841
|
+
};
|
|
22725
22842
|
const contextWrites = context.writes();
|
|
22726
22843
|
if (emits.length > 0 || pushes.length > 0 || captures.length > 0 || contextWrites.length > 0) {
|
|
22727
22844
|
body.effects = [{ ord: install.ord, emits, pushes, captures, context: contextWrites }];
|
|
@@ -22903,7 +23020,7 @@ var dispatchUi = async ({ request, env, versions }) => {
|
|
|
22903
23020
|
observability: buildObservability(context.install.ord),
|
|
22904
23021
|
identity: buildIdentity(env),
|
|
22905
23022
|
currency: buildCurrency(env),
|
|
22906
|
-
apps: buildAppsClient(env, { depth: 0 })
|
|
23023
|
+
apps: buildAppsClient(env, { depth: 0 }, "cold")
|
|
22907
23024
|
};
|
|
22908
23025
|
let response;
|
|
22909
23026
|
try {
|
|
@@ -22974,7 +23091,21 @@ var runInstalls = async (envelope, env, invoke) => {
|
|
|
22974
23091
|
const pushes = [];
|
|
22975
23092
|
const captures = [];
|
|
22976
23093
|
const context = contextCollector();
|
|
22977
|
-
const ctx = buildContext({
|
|
23094
|
+
const ctx = buildContext({
|
|
23095
|
+
env,
|
|
23096
|
+
envelope,
|
|
23097
|
+
site,
|
|
23098
|
+
install,
|
|
23099
|
+
maps,
|
|
23100
|
+
kinds,
|
|
23101
|
+
appScope,
|
|
23102
|
+
emits,
|
|
23103
|
+
pushes,
|
|
23104
|
+
captures,
|
|
23105
|
+
context,
|
|
23106
|
+
currency,
|
|
23107
|
+
traffic: "hot"
|
|
23108
|
+
});
|
|
22978
23109
|
try {
|
|
22979
23110
|
await installSpan(install, () => {
|
|
22980
23111
|
return invoke(ctx, install);
|
|
@@ -23039,7 +23170,8 @@ var runTransform = async (envelope, env, action, handler) => {
|
|
|
23039
23170
|
pushes,
|
|
23040
23171
|
captures,
|
|
23041
23172
|
context,
|
|
23042
|
-
currency: buildCurrency(env)
|
|
23173
|
+
currency: buildCurrency(env),
|
|
23174
|
+
traffic: "hot"
|
|
23043
23175
|
});
|
|
23044
23176
|
const ctx = {
|
|
23045
23177
|
...withoutApps,
|
|
@@ -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))},ee=e=>()=>Promise.reject(e),h=(e,t)=>{let[n,r,i,a]=t;e(n,r).then(i,a)},g=e=>{let t=[];return t.push=(...t)=>{for(let n of t)h(e,n);return 0},t},_=(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=g(e);for(let n of t)h(e,n)},o=t().then(e=>{a(m(e,n))},e=>{throw a(ee(e)),e});return o.catch(c),i.ready=o,o},v=(e,t,n)=>n===void 0||!o.some(e=>e===n)?!1:n===`necessary`||e!==null&&e.categories[n]===!0&&e.apps[t]!==!1,y=(e,t)=>e.config?.gpc===!0&&navigator.globalPrivacyControl===!0&&(t===`marketing`||t===`salesOfData`),b=(e,t,n)=>{let r=e.config?.apps?.[t]?.category;return y(e,r)?!1:e.config?.consentConfiguration?.enabled!==!0||v(n,t,r)},x=e=>Object.values(e.config?.apps??{}).some(e=>e.category!==`necessary`||e.capture!==void 0),te=(e,t,n,r)=>b(e,t,n)?r===void 0||b(e,t,r):!1,ne=e=>{let{categories:t,apps:n}=e;if(typeof t==`object`&&t&&typeof n==`object`&&n)return{categories:t,apps:n}},re=()=>{},S=(e,t)=>{console.error(`[Qinto] A handler of app "${e.slug}" (install "${e.installId}") failed.`,t)},C=(e,t,n)=>{for(let r of t)try{let t=r(n);t instanceof Promise&&t.catch(t=>{S(e,t)})}catch(t){S(e,t)}},w=(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(re)},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&&te(e.target,t,e.consent,e.sharedContextConsent)&&C(i,[n],e.sharedContext)}};try{n(a)}catch(e){console.error(`[Qinto] App "${t}" failed to activate install "${r.id}".`,e)}},T=100,E=1024,D=32768,ie=e=>{let t;try{t=JSON.stringify(e)}catch{return}if(!(t===void 0||new TextEncoder().encode(t).length>E))return JSON.parse(t)},ae=e=>{let t={};for(let n of e){if(n.settled!==n.total||n.values.length!==1)continue;let e=ie(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<=D&&(t[n.source.slug]=r)}return Object.keys(t).length===0?void 0:t},oe=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,T)});await Promise.race([Promise.all(o),t]),clearTimeout(e)}return ae(a)},se=(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`))}},ce=(e,t,n,r)=>{let i;try{i=t(n,r)}catch(t){S(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;S(e,TypeError(`A transform hook returned neither nothing, false, nor { installs }.`))},le=(e,t,n,r)=>{let i=r;for(let r of e)for(let e of r.transformHooks){let a=ce(r,e,t,n);if(a===!1)return!1;a!==void 0&&(i=i===void 0?a:se(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)w(e,t,i,n)},M=(e,t)=>{let n=e;n.consent=t,n.sharedContextConsent=void 0;for(let n of e.instances)C(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 oe(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=>{C(e,e.eventHandlers,t)},report:S})},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=le(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=ne(e),a=r??n.consent;n.sharedContextConsent=r;for(let e of n.instances)b(n.target,e.slug,a)&&C(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)&&C(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{}},ue=e=>{try{return decodeURIComponent(e)}catch{return e}},de=()=>{let e={};for(let t of document.cookie.split(`;`)){let n=t.indexOf(`=`);n>0&&(e[t.slice(0,n).trim()]=ue(t.slice(n+1)))}return e},fe=(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},pe=(e,t)=>{let n={params:new URLSearchParams(window.location.search),cookies:de()},r={};for(let[i,a]of Object.entries(e.config?.apps??{})){if(a.capture===void 0||y(e,a.category)||!v(t,i,a.category))continue;let o=fe(a.capture,n);Object.keys(o).length>0&&(r[i]=o)}return r},me=(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},G=(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=me(pe(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=()=>{},he=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`}},ge=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},_e=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},ve=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(_e(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}}},ye=e=>new WebSocket(e),be=500,xe=3e4,Se=1e4,X=4096,Ce=8192,we=(e,t,n)=>{let r=n?`${e}?reconnect=1`:e;if(t.url.length>X)return r;let i=new URLSearchParams({url:t.url});t.referrer!==void 0&&t.referrer.length<=X&&i.set(`referrer`,t.referrer),n&&i.set(`reconnect`,`1`);let a=`${e}?${i}`;return a.length<=Ce?a:r},Te=`session not initialized`,Ee=1e3,De=`erased`,Oe=(e,t)=>{let n=Math.min(be*2**e,xe);return Math.round(n/2+n/2*t)},ke=(e,t)=>e.t===`appPush`?(t.onAppPush?.(e),!0):e.t===`sharedContext`&&(t.onSharedContext?.(e),!0),Ae=e=>{let t=`${e.destination.replace(/\/+$/,``)}/open`,n=null,r=null,i=0,a=!1,o=!1,s=null,c=ve({send:e=>n===null||n.readyState!==1?!1:(n.send(JSON.stringify(e)),!0),requestTimeoutMs:e.requestTimeoutMs}),l=t=>{e.onError?.(t)},u=()=>{if(o=!0,document.removeEventListener(`visibilitychange`,p),r!==null&&(clearTimeout(r),r=null),n!==null){let e=n;n=null,e.close()}c.rejectAll(new J(`connection closed`))},d=()=>{document.visibilityState!==`hidden`&&(r=setTimeout(()=>{r=null,f()},Oe(i,Math.random())),i+=1)},f=()=>{let r=ye(we(t,Y(),a));a=!0,n=r;let o;r.onopen=()=>{o=Date.now();let e=s;s=null,c.flush(),e?.resolve()},r.onmessage=t=>{let n=ge(t.data);if(n===null){l(new J(`invalid message`));return}ke(n,e)||(`anonId`in n&&typeof n.anonId==`string`&&e.onAnonId?.(n.anonId),c.deliver(n),n.t===`error`&&n.message===Te&&r.close())},r.onerror=()=>{l(new J(`connection closed`))},r.onclose=e=>{if(n!==r)return;n=null;let t=s;if(t!==null){s=null,u(),t.reject(new J(`connection closed`));return}if(e.code===Ee&&e.reason===De){u();return}o!==void 0&&Date.now()-o>=Se&&(i=0),c.rejectAll(new J(`connection closed`)),d()}},p=()=>{if(document.visibilityState===`hidden`){r!==null&&(clearTimeout(r),r=null);return}n===null&&r===null&&f()};return{connect:()=>new Promise((e,t)=>{s={resolve:e,reject:t},document.addEventListener(`visibilitychange`,p),f()}),submit:e=>o?Promise.reject(new J(`connection closed`)):(n===null&&r===null&&f(),c.submit(e)),close:()=>{u()}}},je=1e4,Me=()=>{let e=0;return()=>(e+=1,`q${e}`)},Ne=(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()}}},Pe=async e=>{let t=Ae({destination:e.destination,requestTimeoutMs:e.requestTimeoutMs??je,onError:e.onError,onAppPush:e.onAppPush,onSharedContext:e.onSharedContext,onAnonId:e.onAnonId});await he(()=>t.connect());let n=Me();return{client:Ne(t,n,e.destination),submitCapture:async e=>await t.submit({t:`capture`,ref:n(),apps:e})}},Fe=(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 Pe({...i,onAppPush:r.push,onSharedContext:r.sharedContext,onAnonId:e=>{n?.observedAnon(e)}});n=G(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=Fe(Q,Z);t(Q),_(Q,async()=>{let t=Q.config?.destination;if(typeof t!=`string`||t===``)throw Error(`[Qinto] ${$}.config.destination is missing.`);return e.connect({destination:t})},$)}})();
|