vastlint-client 0.4.20
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 +21 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +5 -0
- package/dist/media.d.ts +4 -0
- package/dist/media.js +113 -0
- package/dist/playback-queue.d.ts +2 -0
- package/dist/playback-queue.js +550 -0
- package/dist/playback.d.ts +2 -0
- package/dist/playback.js +420 -0
- package/dist/resolved.d.ts +7 -0
- package/dist/resolved.js +488 -0
- package/dist/session.d.ts +2 -0
- package/dist/session.js +818 -0
- package/dist/tracking.d.ts +7 -0
- package/dist/tracking.js +161 -0
- package/dist/types.d.ts +374 -0
- package/dist/types.js +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { VastTrackableEvent, VastTrackingPlan, VastTrackingTarget, VastWrapperHop } from "./types.js";
|
|
2
|
+
type TrackingSourceHop = Pick<VastWrapperHop, "index" | "url" | "xml">;
|
|
3
|
+
export declare function createEmptyTrackingPlan(): VastTrackingPlan;
|
|
4
|
+
export declare function buildTrackingPlan(hops: readonly TrackingSourceHop[]): VastTrackingPlan;
|
|
5
|
+
export declare function selectTrackingTargets(plan: VastTrackingPlan, event: VastTrackableEvent, offset?: string): VastTrackingTarget[];
|
|
6
|
+
export declare function expandTrackingUrl(url: string, macros?: Record<string, string | number>): string;
|
|
7
|
+
export {};
|
package/dist/tracking.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
const XML_ENTITIES = {
|
|
2
|
+
amp: "&",
|
|
3
|
+
apos: "'",
|
|
4
|
+
gt: ">",
|
|
5
|
+
lt: "<",
|
|
6
|
+
quot: '"',
|
|
7
|
+
};
|
|
8
|
+
const CLICK_TRACKING_TAGS = [
|
|
9
|
+
"ClickTracking",
|
|
10
|
+
"CompanionClickTracking",
|
|
11
|
+
"IconClickTracking",
|
|
12
|
+
"NonLinearClickTracking",
|
|
13
|
+
];
|
|
14
|
+
const CLICK_THROUGH_TAGS = [
|
|
15
|
+
"ClickThrough",
|
|
16
|
+
"CompanionClickThrough",
|
|
17
|
+
"IconClickThrough",
|
|
18
|
+
"NonLinearClickThrough",
|
|
19
|
+
];
|
|
20
|
+
const VIEWABILITY_TAGS = [
|
|
21
|
+
["Viewable", "viewable"],
|
|
22
|
+
["NotViewable", "notViewable"],
|
|
23
|
+
["ViewUndetermined", "viewUndetermined"],
|
|
24
|
+
];
|
|
25
|
+
export function createEmptyTrackingPlan() {
|
|
26
|
+
return {
|
|
27
|
+
impressions: [],
|
|
28
|
+
errors: [],
|
|
29
|
+
clickTrackings: [],
|
|
30
|
+
clickThroughs: [],
|
|
31
|
+
events: [],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function normalizeWhitespace(value) {
|
|
35
|
+
return value.replace(/\s+/g, " ").trim();
|
|
36
|
+
}
|
|
37
|
+
function decodeXmlEntities(value) {
|
|
38
|
+
return value.replace(/&(#x?[0-9a-fA-F]+|amp|apos|gt|lt|quot);/g, (_match, entity) => {
|
|
39
|
+
if (entity in XML_ENTITIES) {
|
|
40
|
+
return XML_ENTITIES[entity];
|
|
41
|
+
}
|
|
42
|
+
if (entity.startsWith("#x")) {
|
|
43
|
+
return String.fromCodePoint(Number.parseInt(entity.slice(2), 16));
|
|
44
|
+
}
|
|
45
|
+
if (entity.startsWith("#")) {
|
|
46
|
+
return String.fromCodePoint(Number.parseInt(entity.slice(1), 10));
|
|
47
|
+
}
|
|
48
|
+
return `&${entity};`;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function cleanXmlText(value, collapseWhitespace = false) {
|
|
52
|
+
const withoutCdata = value.replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g, "$1");
|
|
53
|
+
const decoded = decodeXmlEntities(withoutCdata);
|
|
54
|
+
return collapseWhitespace ? normalizeWhitespace(decoded) : decoded.trim();
|
|
55
|
+
}
|
|
56
|
+
function extractAttribute(rawAttributes, attributeName) {
|
|
57
|
+
const match = new RegExp(`${attributeName}=("([^"]*)"|'([^']*)')`, "i").exec(rawAttributes);
|
|
58
|
+
if (!match) {
|
|
59
|
+
return "";
|
|
60
|
+
}
|
|
61
|
+
return cleanXmlText(match[2] ?? match[3] ?? "", false);
|
|
62
|
+
}
|
|
63
|
+
function buildTarget(kind, event, rawValue, hop, offset = null) {
|
|
64
|
+
const url = cleanXmlText(rawValue, false);
|
|
65
|
+
if (!url) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
kind,
|
|
70
|
+
event,
|
|
71
|
+
url,
|
|
72
|
+
hopIndex: hop.index,
|
|
73
|
+
sourceUrl: hop.url,
|
|
74
|
+
offset,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function collectTagTargets(xml, tagName, kind, event, hop) {
|
|
78
|
+
const targets = [];
|
|
79
|
+
const pattern = new RegExp(`<${tagName}\\b[^>]*>([\\s\\S]*?)<\\/${tagName}>`, "gi");
|
|
80
|
+
for (const match of xml.matchAll(pattern)) {
|
|
81
|
+
const target = buildTarget(kind, event, match[1] ?? "", hop);
|
|
82
|
+
if (target) {
|
|
83
|
+
targets.push(target);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return targets;
|
|
87
|
+
}
|
|
88
|
+
function collectTrackingEvents(xml, hop) {
|
|
89
|
+
const targets = [];
|
|
90
|
+
const pattern = /<Tracking\b([^>]*)>([\s\S]*?)<\/Tracking>/gi;
|
|
91
|
+
for (const match of xml.matchAll(pattern)) {
|
|
92
|
+
const rawAttributes = match[1] ?? "";
|
|
93
|
+
const event = extractAttribute(rawAttributes, "event");
|
|
94
|
+
if (!event) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const offset = extractAttribute(rawAttributes, "offset") || null;
|
|
98
|
+
const target = buildTarget("event", event, match[2] ?? "", hop, offset);
|
|
99
|
+
if (target) {
|
|
100
|
+
targets.push(target);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return targets;
|
|
104
|
+
}
|
|
105
|
+
export function buildTrackingPlan(hops) {
|
|
106
|
+
const plan = createEmptyTrackingPlan();
|
|
107
|
+
for (const hop of hops) {
|
|
108
|
+
plan.impressions.push(...collectTagTargets(hop.xml, "Impression", "impression", "impression", hop));
|
|
109
|
+
plan.errors.push(...collectTagTargets(hop.xml, "Error", "error", "error", hop));
|
|
110
|
+
for (const tagName of CLICK_TRACKING_TAGS) {
|
|
111
|
+
plan.clickTrackings.push(...collectTagTargets(hop.xml, tagName, "clickTracking", "clickTracking", hop));
|
|
112
|
+
}
|
|
113
|
+
for (const tagName of CLICK_THROUGH_TAGS) {
|
|
114
|
+
plan.clickThroughs.push(...collectTagTargets(hop.xml, tagName, "clickThrough", "clickThrough", hop));
|
|
115
|
+
}
|
|
116
|
+
for (const [tagName, eventName] of VIEWABILITY_TAGS) {
|
|
117
|
+
plan.events.push(...collectTagTargets(hop.xml, tagName, "event", eventName, hop));
|
|
118
|
+
}
|
|
119
|
+
plan.events.push(...collectTrackingEvents(hop.xml, hop));
|
|
120
|
+
}
|
|
121
|
+
return plan;
|
|
122
|
+
}
|
|
123
|
+
export function selectTrackingTargets(plan, event, offset) {
|
|
124
|
+
if (event === "impression") {
|
|
125
|
+
return [...plan.impressions];
|
|
126
|
+
}
|
|
127
|
+
if (event === "error") {
|
|
128
|
+
return [...plan.errors];
|
|
129
|
+
}
|
|
130
|
+
if (event === "clickTracking") {
|
|
131
|
+
return [...plan.clickTrackings];
|
|
132
|
+
}
|
|
133
|
+
return plan.events.filter((target) => {
|
|
134
|
+
if (target.event !== event) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
if (offset === undefined) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
return target.offset === offset;
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
function randomCacheBustingValue() {
|
|
144
|
+
return Math.floor(Math.random() * 100000000)
|
|
145
|
+
.toString()
|
|
146
|
+
.padStart(8, "0");
|
|
147
|
+
}
|
|
148
|
+
export function expandTrackingUrl(url, macros) {
|
|
149
|
+
const values = {
|
|
150
|
+
CACHEBUSTING: randomCacheBustingValue(),
|
|
151
|
+
TIMESTAMP: new Date().toISOString(),
|
|
152
|
+
};
|
|
153
|
+
for (const [key, value] of Object.entries(macros ?? {})) {
|
|
154
|
+
values[key.toUpperCase()] = String(value);
|
|
155
|
+
}
|
|
156
|
+
return url.replace(/\[([A-Z0-9_]+)\]|%%([A-Z0-9_]+)%%/gi, (match, bracketName, legacyName) => {
|
|
157
|
+
const key = String(bracketName ?? legacyName ?? "").toUpperCase();
|
|
158
|
+
const replacement = values[key];
|
|
159
|
+
return replacement === undefined ? match : encodeURIComponent(replacement);
|
|
160
|
+
});
|
|
161
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import type { FixResult, ValidateOptions, ValidationResult } from "vastlint";
|
|
2
|
+
export type VastSessionStatus = "idle" | "loading" | "ready" | "validating" | "resolved" | "fixing" | "error";
|
|
3
|
+
export type VastSessionEventType = "session:created" | "source:loading" | "source:loaded" | "validate:started" | "validate:completed" | "fix:started" | "fix:completed" | "resolve:started" | "resolve:hop" | "resolve:completed" | "track:started" | "track:completed" | "session:error";
|
|
4
|
+
export type VastAdType = "Wrapper" | "InLine" | "Unknown";
|
|
5
|
+
export type VastTrackableEvent = "impression" | "error" | "clickTracking" | "viewable" | "notViewable" | "viewUndetermined" | "creativeView" | "start" | "firstQuartile" | "midpoint" | "thirdQuartile" | "complete" | "mute" | "unmute" | "pause" | "resume" | "rewind" | "skip" | "playerExpand" | "playerCollapse" | "acceptInvitationLinear" | "closeLinear" | "close" | "progress" | "fullscreen" | "exitFullscreen" | (string & {});
|
|
6
|
+
export type VastTrackingEntryKind = "impression" | "error" | "clickTracking" | "clickThrough" | "event";
|
|
7
|
+
export interface VastTrackingTarget {
|
|
8
|
+
kind: VastTrackingEntryKind;
|
|
9
|
+
event: VastTrackableEvent | "clickThrough";
|
|
10
|
+
url: string;
|
|
11
|
+
hopIndex: number;
|
|
12
|
+
sourceUrl: string | null;
|
|
13
|
+
offset: string | null;
|
|
14
|
+
}
|
|
15
|
+
export interface VastTrackingPlan {
|
|
16
|
+
impressions: VastTrackingTarget[];
|
|
17
|
+
errors: VastTrackingTarget[];
|
|
18
|
+
clickTrackings: VastTrackingTarget[];
|
|
19
|
+
clickThroughs: VastTrackingTarget[];
|
|
20
|
+
events: VastTrackingTarget[];
|
|
21
|
+
}
|
|
22
|
+
export interface VastTrackingDispatchResult {
|
|
23
|
+
event: VastTrackableEvent;
|
|
24
|
+
url: string;
|
|
25
|
+
resolvedUrl: string;
|
|
26
|
+
hopIndex: number;
|
|
27
|
+
sourceUrl: string | null;
|
|
28
|
+
offset: string | null;
|
|
29
|
+
ok: boolean;
|
|
30
|
+
status: number | null;
|
|
31
|
+
dispatchedAt: string;
|
|
32
|
+
error: string | null;
|
|
33
|
+
}
|
|
34
|
+
export interface VastTrackingState {
|
|
35
|
+
plan: VastTrackingPlan;
|
|
36
|
+
history: VastTrackingDispatchResult[];
|
|
37
|
+
}
|
|
38
|
+
export interface VastTrackOptions {
|
|
39
|
+
macros?: Record<string, string | number>;
|
|
40
|
+
offset?: string;
|
|
41
|
+
dedupe?: boolean;
|
|
42
|
+
}
|
|
43
|
+
export interface VastAdIndexSelector {
|
|
44
|
+
adIndex: number;
|
|
45
|
+
}
|
|
46
|
+
export interface VastAdIdSelector {
|
|
47
|
+
adId: string;
|
|
48
|
+
}
|
|
49
|
+
export interface VastAdSequenceSelector {
|
|
50
|
+
sequence: number;
|
|
51
|
+
}
|
|
52
|
+
export type VastAdSelector = number | VastAdIndexSelector | VastAdIdSelector | VastAdSequenceSelector;
|
|
53
|
+
export interface VastCompanionIndexSelector {
|
|
54
|
+
companionIndex: number;
|
|
55
|
+
}
|
|
56
|
+
export interface VastCompanionIdSelector {
|
|
57
|
+
companionId: string;
|
|
58
|
+
}
|
|
59
|
+
export interface VastCompanionAdSlotSelector {
|
|
60
|
+
adSlotId: string;
|
|
61
|
+
}
|
|
62
|
+
export type VastCompanionSelector = number | VastCompanionIndexSelector | VastCompanionIdSelector | VastCompanionAdSlotSelector;
|
|
63
|
+
export interface VastXmlSource {
|
|
64
|
+
kind: "xml";
|
|
65
|
+
xml: string;
|
|
66
|
+
label?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface VastUrlSource {
|
|
69
|
+
kind: "url";
|
|
70
|
+
url: string;
|
|
71
|
+
request?: RequestInit;
|
|
72
|
+
label?: string;
|
|
73
|
+
}
|
|
74
|
+
export type VastSessionSource = VastXmlSource | VastUrlSource;
|
|
75
|
+
export interface VastSessionEvent {
|
|
76
|
+
type: VastSessionEventType;
|
|
77
|
+
timestamp: string;
|
|
78
|
+
detail?: Record<string, unknown>;
|
|
79
|
+
}
|
|
80
|
+
export interface VastMediaFile {
|
|
81
|
+
url: string;
|
|
82
|
+
mimeType: string;
|
|
83
|
+
delivery: string;
|
|
84
|
+
width: string;
|
|
85
|
+
height: string;
|
|
86
|
+
bitrate: string;
|
|
87
|
+
}
|
|
88
|
+
export type VastCreativeResourceKind = "static" | "iframe" | "html";
|
|
89
|
+
export interface VastCreativeResource {
|
|
90
|
+
kind: VastCreativeResourceKind;
|
|
91
|
+
content: string;
|
|
92
|
+
creativeType: string | null;
|
|
93
|
+
xmlEncoded: string | null;
|
|
94
|
+
}
|
|
95
|
+
export interface VastCompanionAd {
|
|
96
|
+
id: string | null;
|
|
97
|
+
width: string;
|
|
98
|
+
height: string;
|
|
99
|
+
assetWidth: string | null;
|
|
100
|
+
assetHeight: string | null;
|
|
101
|
+
expandedWidth: string | null;
|
|
102
|
+
expandedHeight: string | null;
|
|
103
|
+
apiFramework: string | null;
|
|
104
|
+
adSlotId: string | null;
|
|
105
|
+
pxratio: string | null;
|
|
106
|
+
renderingMode: string | null;
|
|
107
|
+
language: string | null;
|
|
108
|
+
resources: VastCreativeResource[];
|
|
109
|
+
clickThroughUrl: string | null;
|
|
110
|
+
clickTrackingUrls: string[];
|
|
111
|
+
trackingEvents: Record<string, string[]>;
|
|
112
|
+
}
|
|
113
|
+
export interface VastIcon {
|
|
114
|
+
program: string | null;
|
|
115
|
+
width: string;
|
|
116
|
+
height: string;
|
|
117
|
+
xPosition: string | null;
|
|
118
|
+
yPosition: string | null;
|
|
119
|
+
offset: string | null;
|
|
120
|
+
duration: string | null;
|
|
121
|
+
apiFramework: string | null;
|
|
122
|
+
pxratio: string | null;
|
|
123
|
+
resources: VastCreativeResource[];
|
|
124
|
+
clickThroughUrl: string | null;
|
|
125
|
+
clickTrackingUrls: string[];
|
|
126
|
+
viewTrackingUrls: string[];
|
|
127
|
+
}
|
|
128
|
+
export interface VastUniversalAdId {
|
|
129
|
+
creativeId: string | null;
|
|
130
|
+
creativeIndex: number;
|
|
131
|
+
idRegistry: string | null;
|
|
132
|
+
idValue: string | null;
|
|
133
|
+
value: string;
|
|
134
|
+
}
|
|
135
|
+
export interface VastCategory {
|
|
136
|
+
authority: string | null;
|
|
137
|
+
value: string;
|
|
138
|
+
}
|
|
139
|
+
export type VastVerificationResourceKind = "javascript" | "executable";
|
|
140
|
+
export interface VastVerificationResource {
|
|
141
|
+
kind: VastVerificationResourceKind;
|
|
142
|
+
url: string;
|
|
143
|
+
apiFramework: string | null;
|
|
144
|
+
mimeType: string | null;
|
|
145
|
+
browserOptional: string | null;
|
|
146
|
+
}
|
|
147
|
+
export interface VastAdVerification {
|
|
148
|
+
vendor: string | null;
|
|
149
|
+
resources: VastVerificationResource[];
|
|
150
|
+
verificationParameters: string | null;
|
|
151
|
+
}
|
|
152
|
+
export interface VastAdPodMetadata {
|
|
153
|
+
adId: string | null;
|
|
154
|
+
sequence: number | null;
|
|
155
|
+
adType: string | null;
|
|
156
|
+
adServingId: string | null;
|
|
157
|
+
isAdPod: boolean;
|
|
158
|
+
}
|
|
159
|
+
export interface VastMediaSelectionOptions {
|
|
160
|
+
supportedMimeTypes?: string[];
|
|
161
|
+
preferredMimeTypes?: string[];
|
|
162
|
+
preferredDelivery?: string[];
|
|
163
|
+
targetBitrate?: number;
|
|
164
|
+
maxBitrate?: number;
|
|
165
|
+
targetWidth?: number;
|
|
166
|
+
targetHeight?: number;
|
|
167
|
+
}
|
|
168
|
+
export interface VastMediaSelectionCandidate {
|
|
169
|
+
mediaFile: VastMediaFile;
|
|
170
|
+
score: number;
|
|
171
|
+
reasons: string[];
|
|
172
|
+
}
|
|
173
|
+
export interface VastMediaSelectionResult {
|
|
174
|
+
selected: VastMediaFile | null;
|
|
175
|
+
candidates: VastMediaSelectionCandidate[];
|
|
176
|
+
}
|
|
177
|
+
export interface VastWrapperHop {
|
|
178
|
+
index: number;
|
|
179
|
+
source: VastSessionSource;
|
|
180
|
+
url: string | null;
|
|
181
|
+
xml: string;
|
|
182
|
+
fetchedAt: string;
|
|
183
|
+
fetchMs: number;
|
|
184
|
+
adType: VastAdType;
|
|
185
|
+
adSystem: string;
|
|
186
|
+
adTitle: string;
|
|
187
|
+
duration: string;
|
|
188
|
+
impressionCount: number;
|
|
189
|
+
trackingEventCount: number;
|
|
190
|
+
companionCount: number;
|
|
191
|
+
mediaFiles: VastMediaFile[];
|
|
192
|
+
wrapperUri: string | null;
|
|
193
|
+
validation: ValidationResult | null;
|
|
194
|
+
}
|
|
195
|
+
export interface VastResolutionSummary {
|
|
196
|
+
hopCount: number;
|
|
197
|
+
resolved: boolean;
|
|
198
|
+
chainValid: boolean;
|
|
199
|
+
totalErrors: number;
|
|
200
|
+
totalWarnings: number;
|
|
201
|
+
totalInfos: number;
|
|
202
|
+
stoppedReason: string | null;
|
|
203
|
+
}
|
|
204
|
+
export interface VastResolvedAd {
|
|
205
|
+
resolved: boolean;
|
|
206
|
+
finalHopIndex: number | null;
|
|
207
|
+
finalUrl: string | null;
|
|
208
|
+
adType: VastAdType;
|
|
209
|
+
adSystem: string;
|
|
210
|
+
adTitle: string;
|
|
211
|
+
duration: string;
|
|
212
|
+
skipOffset: string | null;
|
|
213
|
+
mediaFiles: VastMediaFile[];
|
|
214
|
+
companions: VastCompanionAd[];
|
|
215
|
+
icons: VastIcon[];
|
|
216
|
+
universalAdIds: VastUniversalAdId[];
|
|
217
|
+
categories: VastCategory[];
|
|
218
|
+
adVerifications: VastAdVerification[];
|
|
219
|
+
adPod: VastAdPodMetadata;
|
|
220
|
+
impressionUrls: string[];
|
|
221
|
+
errorUrls: string[];
|
|
222
|
+
clickTrackingUrls: string[];
|
|
223
|
+
clickThroughUrls: string[];
|
|
224
|
+
clickThroughUrl: string | null;
|
|
225
|
+
trackingPlan: VastTrackingPlan;
|
|
226
|
+
trackingEvents: Record<string, string[]>;
|
|
227
|
+
companionCount: number;
|
|
228
|
+
wrapperHopCount: number;
|
|
229
|
+
stoppedReason: string | null;
|
|
230
|
+
}
|
|
231
|
+
export interface VastSessionSnapshot {
|
|
232
|
+
status: VastSessionStatus;
|
|
233
|
+
source: VastSessionSource;
|
|
234
|
+
xml: string | null;
|
|
235
|
+
rootXml: string | null;
|
|
236
|
+
validation: ValidationResult | null;
|
|
237
|
+
fixed: FixResult | null;
|
|
238
|
+
wrapperChain: VastWrapperHop[];
|
|
239
|
+
resolution: VastResolutionSummary | null;
|
|
240
|
+
tracking: VastTrackingState;
|
|
241
|
+
resolvedAd: VastResolvedAd | null;
|
|
242
|
+
resolvedAds: VastResolvedAd[];
|
|
243
|
+
events: VastSessionEvent[];
|
|
244
|
+
error: Error | null;
|
|
245
|
+
}
|
|
246
|
+
export interface VastSessionOptions {
|
|
247
|
+
source: VastSessionSource;
|
|
248
|
+
validateOptions?: ValidateOptions;
|
|
249
|
+
fetch?: typeof globalThis.fetch;
|
|
250
|
+
timeoutMs?: number;
|
|
251
|
+
maxWrapperDepth?: number;
|
|
252
|
+
}
|
|
253
|
+
export interface VastSession {
|
|
254
|
+
load(): Promise<VastSessionSnapshot>;
|
|
255
|
+
validate(): Promise<ValidationResult>;
|
|
256
|
+
fix(): Promise<FixResult>;
|
|
257
|
+
resolve(): Promise<VastSessionSnapshot>;
|
|
258
|
+
getTracking(): VastTrackingState;
|
|
259
|
+
getAdCompanions(adSelector: VastAdSelector): VastCompanionAd[];
|
|
260
|
+
getAdTrackingTargets(adSelector: VastAdSelector, event: VastTrackableEvent, options?: Pick<VastTrackOptions, "offset">): VastTrackingTarget[];
|
|
261
|
+
getCompanionTrackingTargets(adSelector: VastAdSelector, companionSelector: VastCompanionSelector, event: VastTrackableEvent): VastTrackingTarget[];
|
|
262
|
+
track(event: VastTrackableEvent, options?: VastTrackOptions): Promise<VastTrackingDispatchResult[]>;
|
|
263
|
+
trackAd(adSelector: VastAdSelector, event: VastTrackableEvent, options?: VastTrackOptions): Promise<VastTrackingDispatchResult[]>;
|
|
264
|
+
trackCompanion(adSelector: VastAdSelector, companionSelector: VastCompanionSelector, event: VastTrackableEvent, options?: VastTrackOptions): Promise<VastTrackingDispatchResult[]>;
|
|
265
|
+
getSnapshot(): VastSessionSnapshot;
|
|
266
|
+
subscribe(listener: (snapshot: VastSessionSnapshot) => void): () => void;
|
|
267
|
+
}
|
|
268
|
+
export type VastPlaybackStatus = "idle" | "ready" | "playing" | "paused" | "ended" | "error";
|
|
269
|
+
export type VastPlaybackViewability = "viewable" | "notViewable" | "viewUndetermined";
|
|
270
|
+
export interface VastPlaybackMilestones {
|
|
271
|
+
start: boolean;
|
|
272
|
+
firstQuartile: boolean;
|
|
273
|
+
midpoint: boolean;
|
|
274
|
+
thirdQuartile: boolean;
|
|
275
|
+
complete: boolean;
|
|
276
|
+
}
|
|
277
|
+
export interface VastPlaybackSnapshot {
|
|
278
|
+
status: VastPlaybackStatus;
|
|
279
|
+
session: VastSessionSnapshot;
|
|
280
|
+
resolvedAd: VastResolvedAd | null;
|
|
281
|
+
mediaSelection: VastMediaSelectionResult;
|
|
282
|
+
currentTimeSec: number;
|
|
283
|
+
durationSec: number | null;
|
|
284
|
+
impressionTracked: boolean;
|
|
285
|
+
muted: boolean;
|
|
286
|
+
fullscreen: boolean;
|
|
287
|
+
skipped: boolean;
|
|
288
|
+
viewability: VastPlaybackViewability | null;
|
|
289
|
+
milestones: VastPlaybackMilestones;
|
|
290
|
+
clickThroughUrl: string | null;
|
|
291
|
+
error: string | null;
|
|
292
|
+
}
|
|
293
|
+
export interface VastPlaybackControllerOptions {
|
|
294
|
+
session: VastSession;
|
|
295
|
+
mediaSelection?: VastMediaSelectionOptions;
|
|
296
|
+
autoResolve?: boolean;
|
|
297
|
+
}
|
|
298
|
+
export interface VastPlaybackClickResult {
|
|
299
|
+
clickThroughUrl: string | null;
|
|
300
|
+
tracking: VastTrackingDispatchResult[];
|
|
301
|
+
snapshot: VastPlaybackSnapshot;
|
|
302
|
+
}
|
|
303
|
+
export interface VastPlaybackQueueItem {
|
|
304
|
+
adIndex: number;
|
|
305
|
+
resolvedAd: VastResolvedAd;
|
|
306
|
+
mediaSelection: VastMediaSelectionResult;
|
|
307
|
+
currentTimeSec: number;
|
|
308
|
+
durationSec: number | null;
|
|
309
|
+
impressionTracked: boolean;
|
|
310
|
+
skipped: boolean;
|
|
311
|
+
milestones: VastPlaybackMilestones;
|
|
312
|
+
status: VastPlaybackStatus;
|
|
313
|
+
clickThroughUrl: string | null;
|
|
314
|
+
error: string | null;
|
|
315
|
+
}
|
|
316
|
+
export interface VastPlaybackQueueSnapshot {
|
|
317
|
+
status: VastPlaybackStatus;
|
|
318
|
+
session: VastSessionSnapshot;
|
|
319
|
+
resolvedAds: VastResolvedAd[];
|
|
320
|
+
items: VastPlaybackQueueItem[];
|
|
321
|
+
currentAdIndex: number | null;
|
|
322
|
+
currentItem: VastPlaybackQueueItem | null;
|
|
323
|
+
hasNext: boolean;
|
|
324
|
+
muted: boolean;
|
|
325
|
+
fullscreen: boolean;
|
|
326
|
+
viewability: VastPlaybackViewability | null;
|
|
327
|
+
error: string | null;
|
|
328
|
+
}
|
|
329
|
+
export interface VastPlaybackQueueControllerOptions {
|
|
330
|
+
session: VastSession;
|
|
331
|
+
mediaSelection?: VastMediaSelectionOptions;
|
|
332
|
+
autoResolve?: boolean;
|
|
333
|
+
fetch?: typeof globalThis.fetch;
|
|
334
|
+
}
|
|
335
|
+
export interface VastPlaybackQueueClickResult {
|
|
336
|
+
clickThroughUrl: string | null;
|
|
337
|
+
tracking: VastTrackingDispatchResult[];
|
|
338
|
+
snapshot: VastPlaybackQueueSnapshot;
|
|
339
|
+
}
|
|
340
|
+
export interface VastPlaybackQueueController {
|
|
341
|
+
initialize(): Promise<VastPlaybackQueueSnapshot>;
|
|
342
|
+
start(): Promise<VastPlaybackQueueSnapshot>;
|
|
343
|
+
pause(): Promise<VastPlaybackQueueSnapshot>;
|
|
344
|
+
resume(): Promise<VastPlaybackQueueSnapshot>;
|
|
345
|
+
updateProgress(currentTimeSec: number, durationSec?: number): Promise<VastPlaybackQueueSnapshot>;
|
|
346
|
+
completeCurrent(): Promise<VastPlaybackQueueSnapshot>;
|
|
347
|
+
next(): Promise<VastPlaybackQueueSnapshot>;
|
|
348
|
+
setMuted(muted: boolean): Promise<VastPlaybackQueueSnapshot>;
|
|
349
|
+
setFullscreen(fullscreen: boolean): Promise<VastPlaybackQueueSnapshot>;
|
|
350
|
+
setViewability(viewability: VastPlaybackViewability): Promise<VastPlaybackQueueSnapshot>;
|
|
351
|
+
click(options?: VastTrackOptions): Promise<VastPlaybackQueueClickResult>;
|
|
352
|
+
skip(): Promise<VastPlaybackQueueSnapshot>;
|
|
353
|
+
signalError(options?: VastTrackOptions): Promise<VastPlaybackQueueSnapshot>;
|
|
354
|
+
getSnapshot(): VastPlaybackQueueSnapshot;
|
|
355
|
+
subscribe(listener: (snapshot: VastPlaybackQueueSnapshot) => void): () => void;
|
|
356
|
+
dispose(): void;
|
|
357
|
+
}
|
|
358
|
+
export interface VastPlaybackController {
|
|
359
|
+
initialize(): Promise<VastPlaybackSnapshot>;
|
|
360
|
+
start(): Promise<VastPlaybackSnapshot>;
|
|
361
|
+
pause(): Promise<VastPlaybackSnapshot>;
|
|
362
|
+
resume(): Promise<VastPlaybackSnapshot>;
|
|
363
|
+
updateProgress(currentTimeSec: number, durationSec?: number): Promise<VastPlaybackSnapshot>;
|
|
364
|
+
complete(): Promise<VastPlaybackSnapshot>;
|
|
365
|
+
setMuted(muted: boolean): Promise<VastPlaybackSnapshot>;
|
|
366
|
+
setFullscreen(fullscreen: boolean): Promise<VastPlaybackSnapshot>;
|
|
367
|
+
setViewability(viewability: VastPlaybackViewability): Promise<VastPlaybackSnapshot>;
|
|
368
|
+
click(options?: VastTrackOptions): Promise<VastPlaybackClickResult>;
|
|
369
|
+
skip(): Promise<VastPlaybackSnapshot>;
|
|
370
|
+
signalError(options?: VastTrackOptions): Promise<VastPlaybackSnapshot>;
|
|
371
|
+
getSnapshot(): VastPlaybackSnapshot;
|
|
372
|
+
subscribe(listener: (snapshot: VastPlaybackSnapshot) => void): () => void;
|
|
373
|
+
dispose(): void;
|
|
374
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vastlint-client",
|
|
3
|
+
"version": "0.4.20",
|
|
4
|
+
"description": "Headless VAST session/runtime package built on top of vastlint.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "Alex Sekowski <alex@vastlint.org>",
|
|
7
|
+
"homepage": "https://vastlint.org",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/aleksUIX/vastlint.git",
|
|
11
|
+
"directory": "packages/vastlint-client"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/aleksUIX/vastlint/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"vast",
|
|
18
|
+
"vast-client",
|
|
19
|
+
"vast-xml",
|
|
20
|
+
"vast-wrapper",
|
|
21
|
+
"adtech",
|
|
22
|
+
"ctv",
|
|
23
|
+
"video",
|
|
24
|
+
"advertising",
|
|
25
|
+
"programmatic"
|
|
26
|
+
],
|
|
27
|
+
"type": "module",
|
|
28
|
+
"main": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"import": "./dist/index.js"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"README.md"
|
|
39
|
+
],
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsc -p tsconfig.json",
|
|
42
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
43
|
+
"test": "npm run build && node --test test/**/*.test.mjs"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"vastlint": "^0.4.20"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"typescript": "^5.9.3"
|
|
56
|
+
}
|
|
57
|
+
}
|