@cunpingtai/webad-react-ad-scripts 0.1.0 → 0.2.0
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 +46 -218
- package/dist/index.d.ts +9 -25
- package/dist/index.js +145 -55
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14528,6 +14528,73 @@ function date4(params) {
|
|
|
14528
14528
|
// ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
14529
14529
|
config(en_default());
|
|
14530
14530
|
|
|
14531
|
+
// ../shared-contract/src/adsterra.ts
|
|
14532
|
+
var PLACEMENT_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
14533
|
+
var CONTAINER_ID = /^[A-Za-z][A-Za-z0-9:_-]{0,127}$/;
|
|
14534
|
+
var ZONE_KEY = /^[A-Za-z0-9]{1,128}$/;
|
|
14535
|
+
var PARAM_KEY = /^[A-Za-z0-9_-]{1,64}$/;
|
|
14536
|
+
var MAX_URL_LENGTH = 2048;
|
|
14537
|
+
var AdsterraValueSchema = external_exports.union([
|
|
14538
|
+
external_exports.string().max(256),
|
|
14539
|
+
external_exports.number().finite(),
|
|
14540
|
+
external_exports.boolean()
|
|
14541
|
+
]);
|
|
14542
|
+
var AdsterraParamsSchema = external_exports.record(external_exports.string().regex(PARAM_KEY), AdsterraValueSchema).refine((params) => Object.keys(params).length <= 16, {
|
|
14543
|
+
message: "Adsterra params must contain at most 16 entries"
|
|
14544
|
+
});
|
|
14545
|
+
var ManagedAdsterraUrlSchema = external_exports.string().min(1).max(MAX_URL_LENGTH).refine(isSafeManagedUrl, { message: "Invalid managed Adsterra URL" });
|
|
14546
|
+
var AdsterraBannerPlacementSchema = external_exports.object({
|
|
14547
|
+
kind: external_exports.literal("banner"),
|
|
14548
|
+
scriptSrc: ManagedAdsterraUrlSchema,
|
|
14549
|
+
zoneKey: external_exports.string().regex(ZONE_KEY),
|
|
14550
|
+
width: external_exports.number().int().min(1).max(2048),
|
|
14551
|
+
height: external_exports.number().int().min(1).max(2048),
|
|
14552
|
+
params: AdsterraParamsSchema
|
|
14553
|
+
}).strict();
|
|
14554
|
+
var AdsterraNativePlacementSchema = external_exports.object({
|
|
14555
|
+
kind: external_exports.literal("native"),
|
|
14556
|
+
scriptSrc: ManagedAdsterraUrlSchema,
|
|
14557
|
+
containerId: external_exports.string().regex(CONTAINER_ID)
|
|
14558
|
+
}).strict();
|
|
14559
|
+
var AdsterraPlacementSchema = external_exports.discriminatedUnion("kind", [
|
|
14560
|
+
AdsterraBannerPlacementSchema,
|
|
14561
|
+
AdsterraNativePlacementSchema
|
|
14562
|
+
]);
|
|
14563
|
+
var AdsterraPlacementsSchema = external_exports.record(
|
|
14564
|
+
external_exports.string().min(1).max(80).regex(PLACEMENT_NAME),
|
|
14565
|
+
AdsterraPlacementSchema
|
|
14566
|
+
).refine((placements) => Object.keys(placements).length <= 64, {
|
|
14567
|
+
message: "A site may contain at most 64 Adsterra placements"
|
|
14568
|
+
});
|
|
14569
|
+
var ManagedScriptSchema = external_exports.object({ scriptSrc: ManagedAdsterraUrlSchema }).strict();
|
|
14570
|
+
var ManagedSmartlinkSchema = external_exports.object({ href: ManagedAdsterraUrlSchema }).strict();
|
|
14571
|
+
var SiteAdsterraConfigSchema = external_exports.object({
|
|
14572
|
+
placements: AdsterraPlacementsSchema,
|
|
14573
|
+
socialBar: ManagedScriptSchema.optional(),
|
|
14574
|
+
popunder: ManagedScriptSchema.optional(),
|
|
14575
|
+
smartlink: ManagedSmartlinkSchema.optional()
|
|
14576
|
+
}).strict();
|
|
14577
|
+
function isSafeManagedUrl(value) {
|
|
14578
|
+
if (/\s/.test(value) || value.includes("#") || hasExplicitPort(value)) {
|
|
14579
|
+
return false;
|
|
14580
|
+
}
|
|
14581
|
+
try {
|
|
14582
|
+
const url2 = new URL(value);
|
|
14583
|
+
return url2.protocol === "https:" && url2.username === "" && url2.password === "" && url2.port === "" && url2.hash === "";
|
|
14584
|
+
} catch {
|
|
14585
|
+
return false;
|
|
14586
|
+
}
|
|
14587
|
+
}
|
|
14588
|
+
function hasExplicitPort(value) {
|
|
14589
|
+
const schemeEnd = value.indexOf(":");
|
|
14590
|
+
if (schemeEnd < 0) return false;
|
|
14591
|
+
const remainder = value.slice(schemeEnd + 1).replace(/^[\\/]+/, "");
|
|
14592
|
+
const authorityEnd = remainder.search(/[\\/?#]/);
|
|
14593
|
+
const authority = authorityEnd < 0 ? remainder : remainder.slice(0, authorityEnd);
|
|
14594
|
+
const host = authority.slice(authority.lastIndexOf("@") + 1);
|
|
14595
|
+
return host.startsWith("[") ? host.includes("]:") : host.includes(":");
|
|
14596
|
+
}
|
|
14597
|
+
|
|
14531
14598
|
// ../shared-contract/src/schemas.ts
|
|
14532
14599
|
var ScriptDescriptorSchema = external_exports.object({
|
|
14533
14600
|
id: external_exports.string().min(1).max(80),
|
|
@@ -14565,7 +14632,8 @@ var SiteConfigSchema = external_exports.object({
|
|
|
14565
14632
|
enabled: external_exports.boolean(),
|
|
14566
14633
|
mode: external_exports.union([external_exports.enum(AD_MODES), external_exports.literal("inherit")]),
|
|
14567
14634
|
aliases: external_exports.array(external_exports.string()).max(32),
|
|
14568
|
-
providers: ProviderOverridesSchema
|
|
14635
|
+
providers: ProviderOverridesSchema,
|
|
14636
|
+
adsterra: SiteAdsterraConfigSchema.optional()
|
|
14569
14637
|
}).strict();
|
|
14570
14638
|
var SnapshotSchema = external_exports.object({
|
|
14571
14639
|
schemaVersion: external_exports.literal(1),
|
|
@@ -14584,7 +14652,8 @@ var PublicConfigSchema = external_exports.object({
|
|
|
14584
14652
|
mode: external_exports.enum(AD_MODES),
|
|
14585
14653
|
allowedScriptHosts: external_exports.array(external_exports.string().min(1).max(253)).max(64),
|
|
14586
14654
|
scripts: external_exports.array(ScriptDescriptorSchema).max(32),
|
|
14587
|
-
ttlSeconds: external_exports.number().int().min(0).max(300)
|
|
14655
|
+
ttlSeconds: external_exports.number().int().min(0).max(300),
|
|
14656
|
+
adsterra: SiteAdsterraConfigSchema.optional()
|
|
14588
14657
|
}).strict();
|
|
14589
14658
|
|
|
14590
14659
|
// ../shared-contract/src/hostname.ts
|
|
@@ -14775,10 +14844,10 @@ function requestConfig(endpoint, host, timeoutMs) {
|
|
|
14775
14844
|
|
|
14776
14845
|
// src/validation.ts
|
|
14777
14846
|
var SLOT_ID = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
14778
|
-
var
|
|
14779
|
-
var
|
|
14780
|
-
var
|
|
14781
|
-
var
|
|
14847
|
+
var CONTAINER_ID2 = /^[A-Za-z][A-Za-z0-9:_-]{0,127}$/;
|
|
14848
|
+
var ZONE_KEY2 = /^[A-Za-z0-9]{1,128}$/;
|
|
14849
|
+
var PARAM_KEY2 = /^[A-Za-z0-9_-]{1,64}$/;
|
|
14850
|
+
var MAX_URL_LENGTH2 = 2048;
|
|
14782
14851
|
function validatePageKey(value) {
|
|
14783
14852
|
if (typeof value !== "string" || value.length < 1 || value.length > 2048) {
|
|
14784
14853
|
throw new Error("invalid pageKey");
|
|
@@ -14791,13 +14860,13 @@ function validateSlotId(value) {
|
|
|
14791
14860
|
}
|
|
14792
14861
|
return value;
|
|
14793
14862
|
}
|
|
14794
|
-
function
|
|
14863
|
+
function validateComponentScriptUrl(value) {
|
|
14795
14864
|
const url2 = parseAbsoluteUrl(value, "scriptSrc");
|
|
14796
14865
|
if (url2.protocol !== "https:") {
|
|
14797
14866
|
throw new Error("scriptSrc must use HTTPS");
|
|
14798
14867
|
}
|
|
14799
|
-
if (
|
|
14800
|
-
throw new Error("scriptSrc
|
|
14868
|
+
if (/[\t\n\r]/.test(value) || value.includes("#") || hasExplicitPort2(value)) {
|
|
14869
|
+
throw new Error("invalid scriptSrc");
|
|
14801
14870
|
}
|
|
14802
14871
|
return url2.toString();
|
|
14803
14872
|
}
|
|
@@ -14809,13 +14878,13 @@ function validateSmartlinkUrl(value) {
|
|
|
14809
14878
|
return url2.toString();
|
|
14810
14879
|
}
|
|
14811
14880
|
function validateContainerId(value) {
|
|
14812
|
-
if (typeof value !== "string" || !
|
|
14881
|
+
if (typeof value !== "string" || !CONTAINER_ID2.test(value)) {
|
|
14813
14882
|
throw new Error("invalid containerId");
|
|
14814
14883
|
}
|
|
14815
14884
|
return value;
|
|
14816
14885
|
}
|
|
14817
14886
|
function validateZoneKey(value) {
|
|
14818
|
-
if (typeof value !== "string" || !
|
|
14887
|
+
if (typeof value !== "string" || !ZONE_KEY2.test(value)) {
|
|
14819
14888
|
throw new Error("invalid zoneKey");
|
|
14820
14889
|
}
|
|
14821
14890
|
return value;
|
|
@@ -14838,7 +14907,7 @@ function validateParams(params) {
|
|
|
14838
14907
|
throw new Error("invalid params");
|
|
14839
14908
|
}
|
|
14840
14909
|
for (const [key, value] of entries) {
|
|
14841
|
-
if (!
|
|
14910
|
+
if (!PARAM_KEY2.test(key)) {
|
|
14842
14911
|
throw new Error("invalid params");
|
|
14843
14912
|
}
|
|
14844
14913
|
if (typeof value === "string") {
|
|
@@ -14860,7 +14929,7 @@ function validateParams(params) {
|
|
|
14860
14929
|
return { ...params };
|
|
14861
14930
|
}
|
|
14862
14931
|
function parseAbsoluteUrl(value, name) {
|
|
14863
|
-
if (typeof value !== "string" || value.length < 1 || value.length >
|
|
14932
|
+
if (typeof value !== "string" || value.length < 1 || value.length > MAX_URL_LENGTH2) {
|
|
14864
14933
|
throw new Error(`invalid ${name}`);
|
|
14865
14934
|
}
|
|
14866
14935
|
let url2;
|
|
@@ -14874,6 +14943,21 @@ function parseAbsoluteUrl(value, name) {
|
|
|
14874
14943
|
}
|
|
14875
14944
|
return url2;
|
|
14876
14945
|
}
|
|
14946
|
+
function hasExplicitPort2(value) {
|
|
14947
|
+
const source = value.trim();
|
|
14948
|
+
const schemeEnd = source.indexOf(":");
|
|
14949
|
+
if (schemeEnd < 0) {
|
|
14950
|
+
return false;
|
|
14951
|
+
}
|
|
14952
|
+
const remainder = source.slice(schemeEnd + 1).replace(/^[\\/]+/, "");
|
|
14953
|
+
const authorityEnd = remainder.search(/[\\/?#]/);
|
|
14954
|
+
const authority = authorityEnd < 0 ? remainder : remainder.slice(0, authorityEnd);
|
|
14955
|
+
const host = authority.slice(authority.lastIndexOf("@") + 1);
|
|
14956
|
+
if (host.startsWith("[")) {
|
|
14957
|
+
return host.includes("]:");
|
|
14958
|
+
}
|
|
14959
|
+
return host.includes(":");
|
|
14960
|
+
}
|
|
14877
14961
|
function validDimension(value) {
|
|
14878
14962
|
return Number.isSafeInteger(value) && value >= 1 && value <= 2048;
|
|
14879
14963
|
}
|
|
@@ -15051,12 +15135,7 @@ function isFormatAllowed(mode, format) {
|
|
|
15051
15135
|
// src/AdsterraBanner.tsx
|
|
15052
15136
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
15053
15137
|
function AdsterraBanner({
|
|
15054
|
-
|
|
15055
|
-
scriptSrc,
|
|
15056
|
-
zoneKey,
|
|
15057
|
-
width,
|
|
15058
|
-
height,
|
|
15059
|
-
params,
|
|
15138
|
+
placement,
|
|
15060
15139
|
className,
|
|
15061
15140
|
style
|
|
15062
15141
|
}) {
|
|
@@ -15065,14 +15144,17 @@ function AdsterraBanner({
|
|
|
15065
15144
|
let validated;
|
|
15066
15145
|
if (context !== null && isFormatAllowed(context.plan.mode, "banner")) {
|
|
15067
15146
|
try {
|
|
15068
|
-
validateSlotId(
|
|
15069
|
-
const
|
|
15070
|
-
|
|
15071
|
-
|
|
15072
|
-
|
|
15073
|
-
|
|
15074
|
-
|
|
15075
|
-
|
|
15147
|
+
validateSlotId(placement);
|
|
15148
|
+
const managed = context.plan.adsterra?.placements[placement];
|
|
15149
|
+
if (managed?.kind === "banner") {
|
|
15150
|
+
const dimensions = validateDimensions(managed.width, managed.height);
|
|
15151
|
+
validated = {
|
|
15152
|
+
src: validateComponentScriptUrl(managed.scriptSrc),
|
|
15153
|
+
zoneKey: validateZoneKey(managed.zoneKey),
|
|
15154
|
+
...dimensions,
|
|
15155
|
+
params: validateParams(managed.params)
|
|
15156
|
+
};
|
|
15157
|
+
}
|
|
15076
15158
|
} catch {
|
|
15077
15159
|
validated = void 0;
|
|
15078
15160
|
}
|
|
@@ -15082,7 +15164,12 @@ function AdsterraBanner({
|
|
|
15082
15164
|
if (context === null || validated === void 0 || container === null) {
|
|
15083
15165
|
return;
|
|
15084
15166
|
}
|
|
15085
|
-
if (!claimPageSlot(
|
|
15167
|
+
if (!claimPageSlot(
|
|
15168
|
+
document,
|
|
15169
|
+
context.providerId,
|
|
15170
|
+
context.pageViewId,
|
|
15171
|
+
placement
|
|
15172
|
+
)) {
|
|
15086
15173
|
return;
|
|
15087
15174
|
}
|
|
15088
15175
|
void enqueueBanner(document, async () => {
|
|
@@ -15103,7 +15190,7 @@ function AdsterraBanner({
|
|
|
15103
15190
|
await appendBannerScript(
|
|
15104
15191
|
container,
|
|
15105
15192
|
validated.src,
|
|
15106
|
-
|
|
15193
|
+
placement,
|
|
15107
15194
|
context.nonce
|
|
15108
15195
|
);
|
|
15109
15196
|
} finally {
|
|
@@ -15114,7 +15201,7 @@ function AdsterraBanner({
|
|
|
15114
15201
|
}
|
|
15115
15202
|
}
|
|
15116
15203
|
}).catch(() => void 0);
|
|
15117
|
-
}, [context,
|
|
15204
|
+
}, [context, placement, validated]);
|
|
15118
15205
|
if (validated === void 0) {
|
|
15119
15206
|
return null;
|
|
15120
15207
|
}
|
|
@@ -15122,7 +15209,7 @@ function AdsterraBanner({
|
|
|
15122
15209
|
"div",
|
|
15123
15210
|
{
|
|
15124
15211
|
ref: containerRef,
|
|
15125
|
-
"data-webad-banner-slot":
|
|
15212
|
+
"data-webad-banner-slot": placement,
|
|
15126
15213
|
className,
|
|
15127
15214
|
style: { ...style, width: validated.width, minHeight: validated.height }
|
|
15128
15215
|
}
|
|
@@ -15152,9 +15239,7 @@ function appendBannerScript(container, src, slotId, nonce) {
|
|
|
15152
15239
|
import { useEffect as useEffect3, useRef as useRef3 } from "react";
|
|
15153
15240
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
15154
15241
|
function AdsterraNativeBanner({
|
|
15155
|
-
|
|
15156
|
-
scriptSrc,
|
|
15157
|
-
containerId,
|
|
15242
|
+
placement,
|
|
15158
15243
|
className,
|
|
15159
15244
|
style
|
|
15160
15245
|
}) {
|
|
@@ -15164,12 +15249,12 @@ function AdsterraNativeBanner({
|
|
|
15164
15249
|
let validatedContainerId = null;
|
|
15165
15250
|
if (context !== null && isFormatAllowed(context.plan.mode, "native-banner")) {
|
|
15166
15251
|
try {
|
|
15167
|
-
validateSlotId(
|
|
15168
|
-
|
|
15169
|
-
|
|
15170
|
-
|
|
15171
|
-
|
|
15172
|
-
|
|
15252
|
+
validateSlotId(placement);
|
|
15253
|
+
const managed = context.plan.adsterra?.placements[placement];
|
|
15254
|
+
if (managed?.kind === "native") {
|
|
15255
|
+
validatedContainerId = validateContainerId(managed.containerId);
|
|
15256
|
+
validatedSrc = validateComponentScriptUrl(managed.scriptSrc);
|
|
15257
|
+
}
|
|
15173
15258
|
} catch {
|
|
15174
15259
|
validatedSrc = null;
|
|
15175
15260
|
validatedContainerId = null;
|
|
@@ -15180,19 +15265,24 @@ function AdsterraNativeBanner({
|
|
|
15180
15265
|
if (context === null || validatedSrc === null || validatedContainerId === null || container === null || document.getElementById(validatedContainerId) !== container) {
|
|
15181
15266
|
return;
|
|
15182
15267
|
}
|
|
15183
|
-
if (!claimPageSlot(
|
|
15268
|
+
if (!claimPageSlot(
|
|
15269
|
+
document,
|
|
15270
|
+
context.providerId,
|
|
15271
|
+
context.pageViewId,
|
|
15272
|
+
placement
|
|
15273
|
+
)) {
|
|
15184
15274
|
return;
|
|
15185
15275
|
}
|
|
15186
15276
|
const script = document.createElement("script");
|
|
15187
15277
|
script.src = validatedSrc;
|
|
15188
15278
|
script.async = true;
|
|
15189
15279
|
script.dataset.cfasync = "false";
|
|
15190
|
-
script.dataset.webadSlotId =
|
|
15280
|
+
script.dataset.webadSlotId = placement;
|
|
15191
15281
|
if (context.nonce !== void 0) {
|
|
15192
15282
|
script.nonce = context.nonce;
|
|
15193
15283
|
}
|
|
15194
15284
|
container.append(script);
|
|
15195
|
-
}, [context,
|
|
15285
|
+
}, [context, placement, validatedContainerId, validatedSrc]);
|
|
15196
15286
|
if (validatedSrc === null || validatedContainerId === null) {
|
|
15197
15287
|
return null;
|
|
15198
15288
|
}
|
|
@@ -15210,7 +15300,6 @@ function AdsterraNativeBanner({
|
|
|
15210
15300
|
// src/AdsterraSmartlink.tsx
|
|
15211
15301
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
15212
15302
|
function AdsterraSmartlink({
|
|
15213
|
-
href,
|
|
15214
15303
|
children,
|
|
15215
15304
|
target = "_blank",
|
|
15216
15305
|
className
|
|
@@ -15221,6 +15310,8 @@ function AdsterraSmartlink({
|
|
|
15221
15310
|
}
|
|
15222
15311
|
let validatedHref;
|
|
15223
15312
|
try {
|
|
15313
|
+
const href = context.plan.adsterra?.smartlink?.href;
|
|
15314
|
+
if (href === void 0) return null;
|
|
15224
15315
|
validatedHref = validateSmartlinkUrl(href);
|
|
15225
15316
|
} catch {
|
|
15226
15317
|
return null;
|
|
@@ -15240,25 +15331,24 @@ function AdsterraSmartlink({
|
|
|
15240
15331
|
// src/page-scripts.tsx
|
|
15241
15332
|
import { useEffect as useEffect4 } from "react";
|
|
15242
15333
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
15243
|
-
function AdsterraSocialBar(
|
|
15244
|
-
return /* @__PURE__ */ jsx5(PageScript, {
|
|
15334
|
+
function AdsterraSocialBar(_props) {
|
|
15335
|
+
return /* @__PURE__ */ jsx5(PageScript, { format: "social-bar", target: "body" });
|
|
15245
15336
|
}
|
|
15246
|
-
function AdsterraPopunder(
|
|
15247
|
-
return /* @__PURE__ */ jsx5(PageScript, {
|
|
15337
|
+
function AdsterraPopunder(_props) {
|
|
15338
|
+
return /* @__PURE__ */ jsx5(PageScript, { format: "popunder", target: "head" });
|
|
15248
15339
|
}
|
|
15249
|
-
function PageScript({ format,
|
|
15340
|
+
function PageScript({ format, target }) {
|
|
15250
15341
|
const context = useAdsContext();
|
|
15342
|
+
const slotId = format === "social-bar" ? "global-social-bar" : "global-popunder";
|
|
15251
15343
|
useEffect4(() => {
|
|
15252
15344
|
if (context === null || !isFormatAllowed(context.plan.mode, format)) {
|
|
15253
15345
|
return;
|
|
15254
15346
|
}
|
|
15255
15347
|
let validatedSrc;
|
|
15256
15348
|
try {
|
|
15257
|
-
|
|
15258
|
-
|
|
15259
|
-
|
|
15260
|
-
context.plan.allowedScriptHosts
|
|
15261
|
-
);
|
|
15349
|
+
const managed = format === "social-bar" ? context.plan.adsterra?.socialBar : context.plan.adsterra?.popunder;
|
|
15350
|
+
if (managed === void 0) return;
|
|
15351
|
+
validatedSrc = validateComponentScriptUrl(managed.scriptSrc);
|
|
15262
15352
|
} catch {
|
|
15263
15353
|
return;
|
|
15264
15354
|
}
|
|
@@ -15274,7 +15364,7 @@ function PageScript({ format, slotId, scriptSrc, target }) {
|
|
|
15274
15364
|
script.nonce = context.nonce;
|
|
15275
15365
|
}
|
|
15276
15366
|
document[target].append(script);
|
|
15277
|
-
}, [context, format,
|
|
15367
|
+
}, [context, format, slotId, target]);
|
|
15278
15368
|
return null;
|
|
15279
15369
|
}
|
|
15280
15370
|
export {
|