pixellint 0.40.0 → 0.42.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 CHANGED
@@ -57,6 +57,7 @@ finding.targets[0]; // { component: "whole_url", start: 0, end: 46, ... }
57
57
  | --- | --- |
58
58
  | `validate(artifact, options?)` | The full validation summary |
59
59
  | `validateMany(document)` | Document report for extracted artifacts |
60
+ | `validateSessions(request, options?)` | Explicit ad-session findings, document report and relationship coverage |
60
61
  | `isOk(summary)` | `false` when any error-severity finding is present |
61
62
  | `rulepacks()` | Every rulepack with its evidence level |
62
63
  | `vendors()` | The vendor endpoint directory |
@@ -76,6 +77,14 @@ The capture binds payload checks to the destination and adds method and header
76
77
  contracts. See [the HTTP capture schema](https://github.com/aleksUIX/pixellint/blob/main/docs/HTTP_REQUEST_SCHEMA.md)
77
78
  for representation limits and repeated fields.
78
79
 
80
+ `validateSessions` accepts the [session schema](https://github.com/aleksUIX/pixellint/blob/main/docs/SESSION_SCHEMA.md)
81
+ as an object or raw JSON string. The caller supplies actual session membership
82
+ using original zero-based artifact indexes. Options include `at` as a safe
83
+ integer Unix clock, `rulepacks` and `exceptRulepacks`. The initial IAS UVP
84
+ profile checks external-ID consistency and uniqueness. Inspect both
85
+ `report.summary.errors` and `report.coverage` when deciding whether the observed
86
+ relationships were fully evaluated.
87
+
79
88
  `vast` takes a tracking URL extracted from VAST and enables the IAB VAST
80
89
  macro-name checks. It does not accept a VAST XML document.
81
90
 
package/index.cjs CHANGED
@@ -35,6 +35,7 @@ function isOk(summary) {
35
35
  module.exports = {
36
36
  validate,
37
37
  validateMany,
38
+ validateSessions,
38
39
  importHar,
39
40
  validateHar,
40
41
  isOk,
@@ -43,3 +44,17 @@ module.exports = {
43
44
  vendorForHost: (host) => wasm.vendor_for_host(host),
44
45
  version: () => wasm.version(),
45
46
  };
47
+
48
+ /** Validate caller-declared ad sessions. Grouping is never inferred. */
49
+ function validateSessions(request, options = {}) {
50
+ if (!options || typeof options !== "object" || Array.isArray(options)) throw new TypeError("Session options must be an object");
51
+ for (const key of Object.keys(options)) {
52
+ if (!["at", "rulepacks", "exceptRulepacks"].includes(key)) throw new TypeError(`Unknown session option: ${key}`);
53
+ }
54
+ if (Object.hasOwn(options, "at") && !Number.isSafeInteger(options.at)) throw new TypeError("Session clock must be safe integer Unix seconds");
55
+ const wire = {};
56
+ if (Object.hasOwn(options, "at")) wire.at = options.at;
57
+ if (Object.hasOwn(options, "rulepacks")) wire.rulepacks = options.rulepacks;
58
+ if (Object.hasOwn(options, "exceptRulepacks")) wire.except_rulepacks = options.exceptRulepacks;
59
+ return wasm.validate_sessions(typeof request === "string" ? request : JSON.stringify(request), JSON.stringify(wire));
60
+ }
package/index.d.ts CHANGED
@@ -221,3 +221,19 @@ export function importHar(har: string | object, options?: HarOptions): HarImport
221
221
 
222
222
  /** Validate local HAR requests at their recorded clocks. Missing clocks require an explicit at override. */
223
223
  export function validateHar(har: string | object, options?: HarValidateOptions): HarReport;
224
+
225
+ export interface SessionGroup { session_id: string; artifact_indexes: number[]; }
226
+ export interface SessionRequest { document: DocumentRequest; sessions: SessionGroup[]; }
227
+ export type SessionRuleKind = "consistent_parameter" | "unique_parameter_across_sessions";
228
+ export type SessionEvaluationStatus = "evaluated" | "partially_evaluated" | "not_evaluated";
229
+ export type SessionSkipReason = "pack_not_selected" | "unsupported_artifact" | "invalid_url" | "endpoint_mismatch" | "missing_parameter" | "empty_parameter" | "installation_placeholder" | "unresolved_macro" | "conflicting_values" | "invalid_percent_encoding" | "invalid_utf8";
230
+ export interface SessionQuerySpan { component: "query_param"; name: string; value: string; start: number; end: number; }
231
+ export interface SessionArtifactTarget { artifact_index: number; artifact_id: string; session_id: string; query_spans: SessionQuerySpan[]; occurrences: ArtifactOccurrence[]; }
232
+ export interface SessionFinding extends Omit<Violation, "targets"> { plugin_id: string; detected_vendor: string | null; session_ids: string[]; targets: SessionArtifactTarget[]; }
233
+ export interface SessionSkippedArtifact { artifact_index: number; artifact_id: string; session_id: string; reason: SessionSkipReason; occurrences: ArtifactOccurrence[]; }
234
+ export interface SessionCheckCoverage { plugin_id: string; code: string; kind: SessionRuleKind; session_ids: string[]; status: SessionEvaluationStatus; participants_total: number; compared_total: number; reason?: "insufficient_observations"; skipped: SessionSkippedArtifact[]; }
235
+ export interface SessionCoverage { status: SessionEvaluationStatus; sessions_total: number; grouped_artifacts: number; ungrouped_artifact_indexes: number[]; profiles_total: number; checks_evaluated: number; checks_partially_evaluated: number; checks_not_evaluated: number; }
236
+ export interface SessionReport { document: DocumentReport; summary: FindingCounts; relationship_summary: FindingCounts; findings: SessionFinding[]; checks: SessionCheckCoverage[]; coverage: SessionCoverage; }
237
+ export interface SessionValidateOptions { at?: number; rulepacks?: string[]; exceptRulepacks?: string[]; }
238
+ /** Explicit grouping only. Show coverage with combined finding counts. */
239
+ export function validateSessions(request: SessionRequest | string, options?: SessionValidateOptions): SessionReport;
package/index.mjs CHANGED
@@ -72,3 +72,17 @@ export function isOk(summary) {
72
72
  report.violations.every((violation) => violation.severity !== "error"),
73
73
  );
74
74
  }
75
+
76
+ /** Validate caller-declared ad sessions. Grouping is never inferred. */
77
+ export function validateSessions(request, options = {}) {
78
+ if (!options || typeof options !== "object" || Array.isArray(options)) throw new TypeError("Session options must be an object");
79
+ for (const key of Object.keys(options)) {
80
+ if (!["at", "rulepacks", "exceptRulepacks"].includes(key)) throw new TypeError(`Unknown session option: ${key}`);
81
+ }
82
+ if (Object.hasOwn(options, "at") && !Number.isSafeInteger(options.at)) throw new TypeError("Session clock must be safe integer Unix seconds");
83
+ const wire = {};
84
+ if (Object.hasOwn(options, "at")) wire.at = options.at;
85
+ if (Object.hasOwn(options, "rulepacks")) wire.rulepacks = options.rulepacks;
86
+ if (Object.hasOwn(options, "exceptRulepacks")) wire.except_rulepacks = options.exceptRulepacks;
87
+ return wasm.validate_sessions(typeof request === "string" ? request : JSON.stringify(request), JSON.stringify(wire));
88
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixellint",
3
- "version": "0.40.0",
3
+ "version": "0.42.0",
4
4
  "description": "Validator for pixels, postbacks, conversion API payloads, and tracking URLs: Meta CAPI, Facebook pixel, GTM, and vendor rulepacks",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Aleks <aleks@vastlint.org>",
@@ -28,6 +28,11 @@ export function validate_har(har_json: string, header_policy: string, reference_
28
28
  */
29
29
  export function validate_many(document_json: string): any;
30
30
 
31
+ /**
32
+ * Validate explicitly grouped URL rows with optional clock and pack selection.
33
+ */
34
+ export function validate_sessions(session_json: string, options_json?: string | null): any;
35
+
31
36
  /**
32
37
  * Validates a URL artifact with default options, the common case.
33
38
  */
package/wasm/pixellint.js CHANGED
@@ -95,6 +95,25 @@ function validate_many(document_json) {
95
95
  }
96
96
  exports.validate_many = validate_many;
97
97
 
98
+ /**
99
+ * Validate explicitly grouped URL rows with optional clock and pack selection.
100
+ * @param {string} session_json
101
+ * @param {string | null} [options_json]
102
+ * @returns {any}
103
+ */
104
+ function validate_sessions(session_json, options_json) {
105
+ const ptr0 = passStringToWasm0(session_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
106
+ const len0 = WASM_VECTOR_LEN;
107
+ var ptr1 = isLikeNone(options_json) ? 0 : passStringToWasm0(options_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
108
+ var len1 = WASM_VECTOR_LEN;
109
+ const ret = wasm.validate_sessions(ptr0, len0, ptr1, len1);
110
+ if (ret[2]) {
111
+ throw takeFromExternrefTable0(ret[1]);
112
+ }
113
+ return takeFromExternrefTable0(ret[0]);
114
+ }
115
+ exports.validate_sessions = validate_sessions;
116
+
98
117
  /**
99
118
  * Validates a URL artifact with default options, the common case.
100
119
  * @param {string} artifact
@@ -190,7 +209,7 @@ function __wbg_get_imports() {
190
209
  const ret = new Object();
191
210
  return ret;
192
211
  },
193
- __wbg_now_5e729ff042c6a974: function() {
212
+ __wbg_now_cff8dc08ed8d60a6: function() {
194
213
  const ret = Date.now();
195
214
  return ret;
196
215
  },
Binary file
@@ -6,6 +6,7 @@ export const rulepacks: () => [number, number, number];
6
6
  export const validate: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => [number, number, number];
7
7
  export const validate_har: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number, number];
8
8
  export const validate_many: (a: number, b: number) => [number, number, number];
9
+ export const validate_sessions: (a: number, b: number, c: number, d: number) => [number, number, number];
9
10
  export const validate_url: (a: number, b: number) => [number, number, number];
10
11
  export const vendor_for_host: (a: number, b: number) => [number, number, number];
11
12
  export const vendors: () => [number, number, number];