@c15t/scripts 2.0.0-rc.0 → 2.0.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.
Files changed (59) hide show
  1. package/README.md +3 -3
  2. package/dist/databuddy.cjs +103 -48
  3. package/dist/databuddy.js +99 -47
  4. package/dist/engine/compile.cjs +126 -0
  5. package/dist/engine/compile.js +89 -0
  6. package/dist/engine/runtime.cjs +379 -0
  7. package/dist/engine/runtime.js +345 -0
  8. package/dist/google-tag-manager.cjs +78 -86
  9. package/dist/google-tag-manager.js +74 -79
  10. package/dist/google-tag.cjs +86 -37
  11. package/dist/google-tag.js +82 -36
  12. package/dist/linkedin-insights.cjs +51 -33
  13. package/dist/linkedin-insights.js +46 -31
  14. package/dist/meta-pixel.cjs +90 -28
  15. package/dist/meta-pixel.js +86 -27
  16. package/dist/microsoft-uet.cjs +90 -50
  17. package/dist/microsoft-uet.js +86 -49
  18. package/dist/posthog.cjs +100 -51
  19. package/dist/posthog.js +96 -50
  20. package/dist/resolve.cjs +67 -0
  21. package/dist/resolve.js +33 -0
  22. package/dist/tiktok-pixel.cjs +91 -29
  23. package/dist/tiktok-pixel.js +86 -27
  24. package/dist/types.cjs +47 -0
  25. package/dist/types.js +7 -0
  26. package/dist/x-pixel.cjs +48 -14
  27. package/dist/x-pixel.js +43 -12
  28. package/dist-types/databuddy.d.ts +144 -0
  29. package/dist-types/engine/compile.d.ts +3 -0
  30. package/dist-types/engine/runtime.d.ts +3 -0
  31. package/dist-types/engine.test.d.ts +1 -0
  32. package/dist-types/google-tag-manager.d.ts +97 -0
  33. package/dist-types/google-tag.d.ts +96 -0
  34. package/dist-types/helpers.test.d.ts +1 -0
  35. package/dist-types/linkedin-insights.d.ts +79 -0
  36. package/{dist → dist-types}/meta-pixel.d.ts +61 -14
  37. package/dist-types/microsoft-uet.d.ts +94 -0
  38. package/dist-types/posthog.d.ts +112 -0
  39. package/dist-types/resolve.d.ts +9 -0
  40. package/dist-types/tiktok-pixel.d.ts +91 -0
  41. package/dist-types/types.d.ts +259 -0
  42. package/{dist → dist-types}/x-pixel.d.ts +38 -12
  43. package/package.json +10 -9
  44. package/dist/databuddy.d.ts +0 -104
  45. package/dist/databuddy.d.ts.map +0 -1
  46. package/dist/google-tag-manager.d.ts +0 -63
  47. package/dist/google-tag-manager.d.ts.map +0 -1
  48. package/dist/google-tag.d.ts +0 -38
  49. package/dist/google-tag.d.ts.map +0 -1
  50. package/dist/linkedin-insights.d.ts +0 -48
  51. package/dist/linkedin-insights.d.ts.map +0 -1
  52. package/dist/meta-pixel.d.ts.map +0 -1
  53. package/dist/microsoft-uet.d.ts +0 -40
  54. package/dist/microsoft-uet.d.ts.map +0 -1
  55. package/dist/posthog.d.ts +0 -54
  56. package/dist/posthog.d.ts.map +0 -1
  57. package/dist/tiktok-pixel.d.ts +0 -44
  58. package/dist/tiktok-pixel.d.ts.map +0 -1
  59. package/dist/x-pixel.d.ts.map +0 -1
package/README.md CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
  [![GitHub stars](https://img.shields.io/github/stars/c15t/c15t?style=flat-square)](https://github.com/c15t/c15t)
13
13
  [![CI](https://img.shields.io/github/actions/workflow/status/c15t/c15t/ci.yml?style=flat-square)](https://github.com/c15t/c15t/actions/workflows/ci.yml)
14
- [![License](https://img.shields.io/badge/license-GPL--3.0-blue.svg?style=flat-square)](https://github.com/c15t/c15t/blob/main/LICENSE.md)
14
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square)](https://github.com/c15t/c15t/blob/main/LICENSE.md)
15
15
  [![Discord](https://img.shields.io/discord/1312171102268690493?style=flat-square)](https://c15t.link/discord)
16
16
  [![npm version](https://img.shields.io/npm/v/%40c15t%2Fscripts?style=flat-square)](https://www.npmjs.com/package/@c15t/scripts)
17
17
  [![Top Language](https://img.shields.io/github/languages/top/c15t/c15t?style=flat-square)](https://github.com/c15t/c15t)
@@ -74,8 +74,8 @@ Our preference is that you make use of GitHub's private vulnerability reporting
74
74
 
75
75
  ## License
76
76
 
77
- [GNU General Public License v3.0](https://github.com/c15t/c15t/blob/main/LICENSE.md)
77
+ [Apache License 2.0](https://github.com/c15t/c15t/blob/main/LICENSE.md)
78
78
 
79
79
  ---
80
80
 
81
- **Built with ❤️ by the [consent.io](https://www.consent.io?utm_source=github&utm_medium=repopage_%40c15t%2Fscripts) team**
81
+ **Built by [Inth](https://inth.com?utm_source=github&utm_medium=repopage_%40c15t%2Fscripts)**
@@ -13,7 +13,7 @@ var __webpack_require__ = {};
13
13
  })();
14
14
  (()=>{
15
15
  __webpack_require__.r = (exports1)=>{
16
- if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
16
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
17
  value: 'Module'
18
18
  });
19
19
  Object.defineProperty(exports1, '__esModule', {
@@ -24,61 +24,116 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
+ databuddyManifest: ()=>databuddyManifest,
27
28
  databuddy: ()=>databuddy
28
29
  });
29
- function databuddy(options) {
30
- const { script } = options;
31
- const handleConsentOpt = (hasConsent)=>{
32
- if (!window.databuddy) return;
33
- if (hasConsent && window.databuddy.options.disabled) window.databuddy.options.disabled = false;
34
- else if (!hasConsent && !window.databuddy.options.disabled) window.databuddy.options.disabled = true;
35
- };
36
- return {
37
- id: script?.id ?? 'databuddy',
38
- category: script?.category ?? 'measurement',
39
- src: options.scriptUrl ?? 'https://cdn.databuddy.cc/databuddy.js',
40
- async: true,
41
- attributes: {
42
- crossorigin: 'anonymous',
43
- 'data-client-id': options.clientId,
44
- ...options.apiUrl ? {
45
- 'data-api-url': options.apiUrl
46
- } : {}
47
- },
48
- alwaysLoad: true,
49
- onBeforeLoad: ({ hasConsent, ...rest })=>{
50
- if (!window.databuddyConfig) window.databuddyConfig = {
51
- clientId: options.clientId,
52
- ...options.apiUrl ? {
53
- apiUrl: options.apiUrl
54
- } : {},
55
- ...options.options || {},
56
- disabled: !hasConsent
57
- };
58
- script?.onBeforeLoad?.({
59
- hasConsent,
60
- ...rest
61
- });
30
+ const external_resolve_cjs_namespaceObject = require("./resolve.cjs");
31
+ const external_types_cjs_namespaceObject = require("./types.cjs");
32
+ const databuddyManifest = {
33
+ ...external_types_cjs_namespaceObject.vendorManifestContract,
34
+ vendor: 'databuddy',
35
+ category: 'measurement',
36
+ alwaysLoad: true,
37
+ install: [
38
+ {
39
+ type: 'loadScript',
40
+ src: "{{scriptUrl}}",
41
+ async: true,
42
+ attributes: {
43
+ crossorigin: 'anonymous',
44
+ 'data-client-id': '{{clientId}}',
45
+ 'data-api-url': '{{apiUrl}}'
46
+ }
47
+ }
48
+ ],
49
+ onBeforeLoadGranted: [
50
+ {
51
+ type: 'setGlobal',
52
+ name: 'databuddyConfig',
53
+ value: '{{configWhenGranted}}',
54
+ ifUndefined: true
55
+ }
56
+ ],
57
+ onBeforeLoadDenied: [
58
+ {
59
+ type: 'setGlobal',
60
+ name: 'databuddyConfig',
61
+ value: '{{configWhenDenied}}',
62
+ ifUndefined: true
63
+ }
64
+ ],
65
+ onLoadGranted: [
66
+ {
67
+ type: 'setGlobalPath',
68
+ path: [
69
+ 'databuddy',
70
+ 'options',
71
+ 'disabled'
72
+ ],
73
+ value: false
74
+ }
75
+ ],
76
+ onLoadDenied: [
77
+ {
78
+ type: 'setGlobalPath',
79
+ path: [
80
+ 'databuddy',
81
+ 'options',
82
+ 'disabled'
83
+ ],
84
+ value: true
85
+ }
86
+ ],
87
+ onConsentGranted: [
88
+ {
89
+ type: 'setGlobal',
90
+ name: 'databuddyConfig',
91
+ value: '{{configWhenGranted}}',
92
+ ifUndefined: false
62
93
  },
63
- onLoad: ({ hasConsent, ...rest })=>{
64
- if (window.databuddy) handleConsentOpt(hasConsent);
65
- script?.onLoad?.({
66
- hasConsent,
67
- ...rest
68
- });
94
+ {
95
+ type: 'setGlobalPath',
96
+ path: [
97
+ 'databuddy',
98
+ 'options',
99
+ 'disabled'
100
+ ],
101
+ value: false
102
+ }
103
+ ],
104
+ onConsentDenied: [
105
+ {
106
+ type: 'setGlobal',
107
+ name: 'databuddyConfig',
108
+ value: '{{configWhenDenied}}',
109
+ ifUndefined: false
69
110
  },
70
- onConsentChange: ({ hasConsent, ...rest })=>{
71
- handleConsentOpt(hasConsent);
72
- script?.onConsentChange?.({
73
- hasConsent,
74
- ...rest
75
- });
111
+ {
112
+ type: 'setGlobalPath',
113
+ path: [
114
+ 'databuddy',
115
+ 'options',
116
+ 'disabled'
117
+ ],
118
+ value: true
76
119
  }
77
- };
120
+ ]
121
+ };
122
+ function databuddy(options) {
123
+ const resolved = (0, external_resolve_cjs_namespaceObject.resolveManifest)(databuddyManifest, {
124
+ clientId: options.clientId,
125
+ apiUrl: options.apiUrl,
126
+ configWhenGranted: options.configWhenGranted,
127
+ configWhenDenied: options.configWhenDenied,
128
+ scriptUrl: options.scriptUrl ?? 'https://cdn.databuddy.cc/databuddy.js'
129
+ });
130
+ return resolved;
78
131
  }
79
132
  exports.databuddy = __webpack_exports__.databuddy;
133
+ exports.databuddyManifest = __webpack_exports__.databuddyManifest;
80
134
  for(var __rspack_i in __webpack_exports__)if (-1 === [
81
- "databuddy"
135
+ "databuddy",
136
+ "databuddyManifest"
82
137
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
83
138
  Object.defineProperty(exports, '__esModule', {
84
139
  value: true
package/dist/databuddy.js CHANGED
@@ -1,51 +1,103 @@
1
- function databuddy(options) {
2
- const { script } = options;
3
- const handleConsentOpt = (hasConsent)=>{
4
- if (!window.databuddy) return;
5
- if (hasConsent && window.databuddy.options.disabled) window.databuddy.options.disabled = false;
6
- else if (!hasConsent && !window.databuddy.options.disabled) window.databuddy.options.disabled = true;
7
- };
8
- return {
9
- id: script?.id ?? 'databuddy',
10
- category: script?.category ?? 'measurement',
11
- src: options.scriptUrl ?? 'https://cdn.databuddy.cc/databuddy.js',
12
- async: true,
13
- attributes: {
14
- crossorigin: 'anonymous',
15
- 'data-client-id': options.clientId,
16
- ...options.apiUrl ? {
17
- 'data-api-url': options.apiUrl
18
- } : {}
19
- },
20
- alwaysLoad: true,
21
- onBeforeLoad: ({ hasConsent, ...rest })=>{
22
- if (!window.databuddyConfig) window.databuddyConfig = {
23
- clientId: options.clientId,
24
- ...options.apiUrl ? {
25
- apiUrl: options.apiUrl
26
- } : {},
27
- ...options.options || {},
28
- disabled: !hasConsent
29
- };
30
- script?.onBeforeLoad?.({
31
- hasConsent,
32
- ...rest
33
- });
1
+ import { resolveManifest } from "./resolve.js";
2
+ import { vendorManifestContract } from "./types.js";
3
+ const databuddyManifest = {
4
+ ...vendorManifestContract,
5
+ vendor: 'databuddy',
6
+ category: 'measurement',
7
+ alwaysLoad: true,
8
+ install: [
9
+ {
10
+ type: 'loadScript',
11
+ src: "{{scriptUrl}}",
12
+ async: true,
13
+ attributes: {
14
+ crossorigin: 'anonymous',
15
+ 'data-client-id': '{{clientId}}',
16
+ 'data-api-url': '{{apiUrl}}'
17
+ }
18
+ }
19
+ ],
20
+ onBeforeLoadGranted: [
21
+ {
22
+ type: 'setGlobal',
23
+ name: 'databuddyConfig',
24
+ value: '{{configWhenGranted}}',
25
+ ifUndefined: true
26
+ }
27
+ ],
28
+ onBeforeLoadDenied: [
29
+ {
30
+ type: 'setGlobal',
31
+ name: 'databuddyConfig',
32
+ value: '{{configWhenDenied}}',
33
+ ifUndefined: true
34
+ }
35
+ ],
36
+ onLoadGranted: [
37
+ {
38
+ type: 'setGlobalPath',
39
+ path: [
40
+ 'databuddy',
41
+ 'options',
42
+ 'disabled'
43
+ ],
44
+ value: false
45
+ }
46
+ ],
47
+ onLoadDenied: [
48
+ {
49
+ type: 'setGlobalPath',
50
+ path: [
51
+ 'databuddy',
52
+ 'options',
53
+ 'disabled'
54
+ ],
55
+ value: true
56
+ }
57
+ ],
58
+ onConsentGranted: [
59
+ {
60
+ type: 'setGlobal',
61
+ name: 'databuddyConfig',
62
+ value: '{{configWhenGranted}}',
63
+ ifUndefined: false
34
64
  },
35
- onLoad: ({ hasConsent, ...rest })=>{
36
- if (window.databuddy) handleConsentOpt(hasConsent);
37
- script?.onLoad?.({
38
- hasConsent,
39
- ...rest
40
- });
65
+ {
66
+ type: 'setGlobalPath',
67
+ path: [
68
+ 'databuddy',
69
+ 'options',
70
+ 'disabled'
71
+ ],
72
+ value: false
73
+ }
74
+ ],
75
+ onConsentDenied: [
76
+ {
77
+ type: 'setGlobal',
78
+ name: 'databuddyConfig',
79
+ value: '{{configWhenDenied}}',
80
+ ifUndefined: false
41
81
  },
42
- onConsentChange: ({ hasConsent, ...rest })=>{
43
- handleConsentOpt(hasConsent);
44
- script?.onConsentChange?.({
45
- hasConsent,
46
- ...rest
47
- });
82
+ {
83
+ type: 'setGlobalPath',
84
+ path: [
85
+ 'databuddy',
86
+ 'options',
87
+ 'disabled'
88
+ ],
89
+ value: true
48
90
  }
49
- };
91
+ ]
92
+ };
93
+ function databuddy(options) {
94
+ const resolved = resolveManifest(databuddyManifest, {
95
+ clientId: options.clientId,
96
+ apiUrl: options.apiUrl,
97
+ configWhenGranted: options.configWhenGranted,
98
+ configWhenDenied: options.configWhenDenied,
99
+ scriptUrl: options.scriptUrl ?? 'https://cdn.databuddy.cc/databuddy.js'
100
+ });
101
+ return resolved;
50
102
  }
51
- export { databuddy };
103
+ export { databuddy, databuddyManifest };
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ compileManifest: ()=>compileManifest,
28
+ interpolateValue: ()=>interpolateValue
29
+ });
30
+ const external_types_cjs_namespaceObject = require("../types.cjs");
31
+ const EXACT_PLACEHOLDER_PATTERN = /^\{\{([A-Za-z0-9_]+)\}\}$/;
32
+ const PLACEHOLDER_PATTERN = /\{\{([A-Za-z0-9_]+)\}\}/g;
33
+ function getConfigValue(config, key) {
34
+ if (!(key in config)) throw new Error(`Missing manifest interpolation value for '${key}'.`);
35
+ const value = config[key];
36
+ if ('function' == typeof value) throw new Error(`Manifest interpolation value for '${key}' must be serializable.`);
37
+ return value;
38
+ }
39
+ function stringifyInterpolatedValue(value, key) {
40
+ if (void 0 === value) throw new Error(`Missing manifest interpolation value for '${key}'.`);
41
+ if ('string' == typeof value) return value;
42
+ if (null === value) return 'null';
43
+ if ('object' == typeof value) return JSON.stringify(value);
44
+ return String(value);
45
+ }
46
+ function interpolateString(template, config) {
47
+ const exactMatch = template.match(EXACT_PLACEHOLDER_PATTERN);
48
+ if (exactMatch) return getConfigValue(config, exactMatch[1]);
49
+ return template.replace(PLACEHOLDER_PATTERN, (_match, key)=>{
50
+ const value = getConfigValue(config, key);
51
+ return stringifyInterpolatedValue(value, key);
52
+ });
53
+ }
54
+ function interpolateValue(value, config) {
55
+ if ('string' == typeof value) return interpolateString(value, config);
56
+ if (Array.isArray(value)) return value.map((item)=>interpolateValue(item, config));
57
+ if (null !== value && 'object' == typeof value) {
58
+ const result = {};
59
+ for (const [key, nestedValue] of Object.entries(value)){
60
+ const interpolated = interpolateValue(nestedValue, config);
61
+ if (void 0 !== interpolated) result[key] = interpolated;
62
+ }
63
+ return result;
64
+ }
65
+ return value;
66
+ }
67
+ function interpolateSteps(steps, config) {
68
+ if (!steps) return [];
69
+ return steps.map((step)=>interpolateValue(step, config));
70
+ }
71
+ function extractInstallArtifacts(install) {
72
+ const loadScriptSteps = install.filter((step)=>'loadScript' === step.type);
73
+ if (loadScriptSteps.length > 1) throw new Error('Vendor manifests may only declare a single loadScript step in install.');
74
+ if (1 === loadScriptSteps.length) {
75
+ const loadScript = loadScriptSteps[0];
76
+ if ('string' != typeof loadScript.src || 0 === loadScript.src.trim().length) throw new Error('loadScript steps must include a non-empty src after manifest interpolation.');
77
+ return {
78
+ loadScript,
79
+ setupSteps: install.filter((step)=>'loadScript' !== step.type)
80
+ };
81
+ }
82
+ return {
83
+ setupSteps: install
84
+ };
85
+ }
86
+ function validateManifestContract(manifest) {
87
+ if (manifest.kind !== external_types_cjs_namespaceObject.VENDOR_MANIFEST_KIND) throw new Error(`Unsupported manifest kind '${String(manifest.kind)}'. Expected '${external_types_cjs_namespaceObject.VENDOR_MANIFEST_KIND}'.`);
88
+ if (manifest.schemaVersion !== external_types_cjs_namespaceObject.VENDOR_MANIFEST_SCHEMA_VERSION) throw new Error(`Unsupported manifest schema version '${String(manifest.schemaVersion)}'. Expected '${external_types_cjs_namespaceObject.VENDOR_MANIFEST_SCHEMA_VERSION}'.`);
89
+ }
90
+ function compileManifest(manifest, config = {}) {
91
+ validateManifestContract(manifest);
92
+ const bootstrapSteps = interpolateSteps(manifest.bootstrap, config);
93
+ const install = interpolateSteps(manifest.install, config);
94
+ const { loadScript, setupSteps } = extractInstallArtifacts(install);
95
+ return {
96
+ kind: manifest.kind,
97
+ schemaVersion: manifest.schemaVersion,
98
+ vendor: manifest.vendor,
99
+ category: interpolateValue(manifest.category, config),
100
+ alwaysLoad: void 0 === manifest.alwaysLoad ? void 0 : interpolateValue(manifest.alwaysLoad, config),
101
+ persistAfterConsentRevoked: void 0 === manifest.persistAfterConsentRevoked ? void 0 : interpolateValue(manifest.persistAfterConsentRevoked, config),
102
+ bootstrapSteps,
103
+ setupSteps,
104
+ loadScript,
105
+ afterLoadSteps: interpolateSteps(manifest.afterLoad, config),
106
+ onBeforeLoadGrantedSteps: interpolateSteps(manifest.onBeforeLoadGranted, config),
107
+ onBeforeLoadDeniedSteps: interpolateSteps(manifest.onBeforeLoadDenied, config),
108
+ onLoadGrantedSteps: interpolateSteps(manifest.onLoadGranted, config),
109
+ onLoadDeniedSteps: interpolateSteps(manifest.onLoadDenied, config),
110
+ onConsentChangeSteps: interpolateSteps(manifest.onConsentChange, config),
111
+ onConsentGrantedSteps: interpolateSteps(manifest.onConsentGranted, config),
112
+ onConsentDeniedSteps: interpolateSteps(manifest.onConsentDenied, config),
113
+ consentMapping: manifest.consentMapping ? interpolateValue(manifest.consentMapping, config) : void 0,
114
+ consentSignal: manifest.consentSignal,
115
+ consentSignalTarget: 'string' == typeof manifest.consentSignalTarget ? interpolateValue(manifest.consentSignalTarget, config) : manifest.consentSignalTarget
116
+ };
117
+ }
118
+ exports.compileManifest = __webpack_exports__.compileManifest;
119
+ exports.interpolateValue = __webpack_exports__.interpolateValue;
120
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
121
+ "compileManifest",
122
+ "interpolateValue"
123
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
124
+ Object.defineProperty(exports, '__esModule', {
125
+ value: true
126
+ });
@@ -0,0 +1,89 @@
1
+ import { VENDOR_MANIFEST_KIND, VENDOR_MANIFEST_SCHEMA_VERSION } from "../types.js";
2
+ const EXACT_PLACEHOLDER_PATTERN = /^\{\{([A-Za-z0-9_]+)\}\}$/;
3
+ const PLACEHOLDER_PATTERN = /\{\{([A-Za-z0-9_]+)\}\}/g;
4
+ function getConfigValue(config, key) {
5
+ if (!(key in config)) throw new Error(`Missing manifest interpolation value for '${key}'.`);
6
+ const value = config[key];
7
+ if ('function' == typeof value) throw new Error(`Manifest interpolation value for '${key}' must be serializable.`);
8
+ return value;
9
+ }
10
+ function stringifyInterpolatedValue(value, key) {
11
+ if (void 0 === value) throw new Error(`Missing manifest interpolation value for '${key}'.`);
12
+ if ('string' == typeof value) return value;
13
+ if (null === value) return 'null';
14
+ if ('object' == typeof value) return JSON.stringify(value);
15
+ return String(value);
16
+ }
17
+ function interpolateString(template, config) {
18
+ const exactMatch = template.match(EXACT_PLACEHOLDER_PATTERN);
19
+ if (exactMatch) return getConfigValue(config, exactMatch[1]);
20
+ return template.replace(PLACEHOLDER_PATTERN, (_match, key)=>{
21
+ const value = getConfigValue(config, key);
22
+ return stringifyInterpolatedValue(value, key);
23
+ });
24
+ }
25
+ function interpolateValue(value, config) {
26
+ if ('string' == typeof value) return interpolateString(value, config);
27
+ if (Array.isArray(value)) return value.map((item)=>interpolateValue(item, config));
28
+ if (null !== value && 'object' == typeof value) {
29
+ const result = {};
30
+ for (const [key, nestedValue] of Object.entries(value)){
31
+ const interpolated = interpolateValue(nestedValue, config);
32
+ if (void 0 !== interpolated) result[key] = interpolated;
33
+ }
34
+ return result;
35
+ }
36
+ return value;
37
+ }
38
+ function interpolateSteps(steps, config) {
39
+ if (!steps) return [];
40
+ return steps.map((step)=>interpolateValue(step, config));
41
+ }
42
+ function extractInstallArtifacts(install) {
43
+ const loadScriptSteps = install.filter((step)=>'loadScript' === step.type);
44
+ if (loadScriptSteps.length > 1) throw new Error('Vendor manifests may only declare a single loadScript step in install.');
45
+ if (1 === loadScriptSteps.length) {
46
+ const loadScript = loadScriptSteps[0];
47
+ if ('string' != typeof loadScript.src || 0 === loadScript.src.trim().length) throw new Error('loadScript steps must include a non-empty src after manifest interpolation.');
48
+ return {
49
+ loadScript,
50
+ setupSteps: install.filter((step)=>'loadScript' !== step.type)
51
+ };
52
+ }
53
+ return {
54
+ setupSteps: install
55
+ };
56
+ }
57
+ function validateManifestContract(manifest) {
58
+ if (manifest.kind !== VENDOR_MANIFEST_KIND) throw new Error(`Unsupported manifest kind '${String(manifest.kind)}'. Expected '${VENDOR_MANIFEST_KIND}'.`);
59
+ if (manifest.schemaVersion !== VENDOR_MANIFEST_SCHEMA_VERSION) throw new Error(`Unsupported manifest schema version '${String(manifest.schemaVersion)}'. Expected '${VENDOR_MANIFEST_SCHEMA_VERSION}'.`);
60
+ }
61
+ function compileManifest(manifest, config = {}) {
62
+ validateManifestContract(manifest);
63
+ const bootstrapSteps = interpolateSteps(manifest.bootstrap, config);
64
+ const install = interpolateSteps(manifest.install, config);
65
+ const { loadScript, setupSteps } = extractInstallArtifacts(install);
66
+ return {
67
+ kind: manifest.kind,
68
+ schemaVersion: manifest.schemaVersion,
69
+ vendor: manifest.vendor,
70
+ category: interpolateValue(manifest.category, config),
71
+ alwaysLoad: void 0 === manifest.alwaysLoad ? void 0 : interpolateValue(manifest.alwaysLoad, config),
72
+ persistAfterConsentRevoked: void 0 === manifest.persistAfterConsentRevoked ? void 0 : interpolateValue(manifest.persistAfterConsentRevoked, config),
73
+ bootstrapSteps,
74
+ setupSteps,
75
+ loadScript,
76
+ afterLoadSteps: interpolateSteps(manifest.afterLoad, config),
77
+ onBeforeLoadGrantedSteps: interpolateSteps(manifest.onBeforeLoadGranted, config),
78
+ onBeforeLoadDeniedSteps: interpolateSteps(manifest.onBeforeLoadDenied, config),
79
+ onLoadGrantedSteps: interpolateSteps(manifest.onLoadGranted, config),
80
+ onLoadDeniedSteps: interpolateSteps(manifest.onLoadDenied, config),
81
+ onConsentChangeSteps: interpolateSteps(manifest.onConsentChange, config),
82
+ onConsentGrantedSteps: interpolateSteps(manifest.onConsentGranted, config),
83
+ onConsentDeniedSteps: interpolateSteps(manifest.onConsentDenied, config),
84
+ consentMapping: manifest.consentMapping ? interpolateValue(manifest.consentMapping, config) : void 0,
85
+ consentSignal: manifest.consentSignal,
86
+ consentSignalTarget: 'string' == typeof manifest.consentSignalTarget ? interpolateValue(manifest.consentSignalTarget, config) : manifest.consentSignalTarget
87
+ };
88
+ }
89
+ export { compileManifest, interpolateValue };