astro-consent 1.0.5 → 1.0.6
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/dist/cli.cjs +17 -171
- package/dist/config/defaults.js +12 -4
- package/dist/config/loadConfig.js +10 -19
- package/dist/index.js +20 -190
- package/dist/templates/cssTemplate.js +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -69,8 +69,9 @@ let source = fs.readFileSync(configPath, "utf8");
|
|
|
69
69
|
REMOVE MODE
|
|
70
70
|
───────────────────────────────────── */
|
|
71
71
|
if (command === "remove") {
|
|
72
|
-
source = source
|
|
73
|
-
|
|
72
|
+
source = source
|
|
73
|
+
.replace(/\s*astroConsent\s*\([\s\S]*?\),?/gm, "")
|
|
74
|
+
.replace(/import\s+astroConsent\s+from\s+["']astro-consent["'];?\n?/, "");
|
|
74
75
|
fs.writeFileSync(configPath, source.trim() + "\n", "utf8");
|
|
75
76
|
const cssFile = path.join(CWD, "src", "cookiebanner.css");
|
|
76
77
|
if (fs.existsSync(cssFile))
|
|
@@ -87,29 +88,26 @@ if (!fs.existsSync(cssDir)) {
|
|
|
87
88
|
fs.mkdirSync(cssDir, { recursive: true });
|
|
88
89
|
}
|
|
89
90
|
/* ─────────────────────────────────────
|
|
90
|
-
Create
|
|
91
|
+
Create CSS override file (ONCE)
|
|
91
92
|
───────────────────────────────────── */
|
|
92
93
|
if (!fs.existsSync(cssFile)) {
|
|
93
94
|
fs.writeFileSync(cssFile, `/* =========================================================
|
|
94
95
|
astro-consent — FULL THEME VARIABLES
|
|
95
|
-
|
|
96
|
-
This file is NEVER overwritten.
|
|
96
|
+
This file is NEVER overwritten
|
|
97
97
|
========================================================= */
|
|
98
98
|
|
|
99
99
|
:root {
|
|
100
|
-
/* ───── Core ───── */
|
|
101
100
|
--cb-font: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
|
102
101
|
|
|
103
|
-
|
|
104
|
-
--cb-bg: rgba(12,18,32,0.88);
|
|
102
|
+
--cb-bg: #0c1220;
|
|
105
103
|
--cb-border: rgba(255,255,255,0.08);
|
|
106
|
-
--cb-text: #
|
|
104
|
+
--cb-text: #ffffff;
|
|
107
105
|
--cb-muted: #9ca3af;
|
|
108
106
|
--cb-link: #60a5fa;
|
|
107
|
+
|
|
109
108
|
--cb-radius: 16px;
|
|
110
109
|
--cb-shadow: 0 20px 40px rgba(0,0,0,0.35);
|
|
111
110
|
|
|
112
|
-
/* ───── Buttons ───── */
|
|
113
111
|
--cb-btn-radius: 999px;
|
|
114
112
|
--cb-btn-padding: 10px 18px;
|
|
115
113
|
|
|
@@ -117,195 +115,43 @@ if (!fs.existsSync(cssFile)) {
|
|
|
117
115
|
--cb-accept-text: #052e16;
|
|
118
116
|
|
|
119
117
|
--cb-reject-bg: #374151;
|
|
120
|
-
--cb-reject-text: #
|
|
118
|
+
--cb-reject-text: #ffffff;
|
|
121
119
|
|
|
122
120
|
--cb-manage-bg: transparent;
|
|
123
|
-
--cb-manage-text: #
|
|
121
|
+
--cb-manage-text: #ffffff;
|
|
124
122
|
--cb-manage-border: rgba(255,255,255,0.15);
|
|
125
123
|
|
|
126
|
-
/* ───── Modal ───── */
|
|
127
|
-
--cb-modal-backdrop: rgba(0,0,0,0.55);
|
|
128
124
|
--cb-modal-bg: #0c1220;
|
|
125
|
+
--cb-modal-backdrop: rgba(0,0,0,0.55);
|
|
129
126
|
--cb-modal-radius: 18px;
|
|
130
127
|
--cb-modal-width: 480px;
|
|
131
128
|
|
|
132
|
-
/* ───── Toggles ───── */
|
|
133
129
|
--cb-toggle-off-bg: #374151;
|
|
134
130
|
--cb-toggle-on-bg: #22c55e;
|
|
135
131
|
--cb-toggle-knob: #ffffff;
|
|
136
132
|
}
|
|
137
|
-
|
|
138
|
-
/* =========================================================
|
|
139
|
-
Banner
|
|
140
|
-
========================================================= */
|
|
141
|
-
|
|
142
|
-
#astro-cookie-banner {
|
|
143
|
-
position: fixed;
|
|
144
|
-
left: 16px;
|
|
145
|
-
right: 16px;
|
|
146
|
-
bottom: 16px;
|
|
147
|
-
z-index: 9999;
|
|
148
|
-
font-family: var(--cb-font);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
.cb-container {
|
|
152
|
-
max-width: 1200px;
|
|
153
|
-
margin: 0 auto;
|
|
154
|
-
padding: 20px 24px;
|
|
155
|
-
display: flex;
|
|
156
|
-
gap: 24px;
|
|
157
|
-
justify-content: space-between;
|
|
158
|
-
align-items: center;
|
|
159
|
-
|
|
160
|
-
background: var(--cb-bg);
|
|
161
|
-
backdrop-filter: blur(14px);
|
|
162
|
-
border-radius: var(--cb-radius);
|
|
163
|
-
border: 1px solid var(--cb-border);
|
|
164
|
-
box-shadow: var(--cb-shadow);
|
|
165
|
-
color: var(--cb-text);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
.cb-title {
|
|
169
|
-
font-size: 16px;
|
|
170
|
-
font-weight: 600;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
.cb-desc {
|
|
174
|
-
font-size: 14px;
|
|
175
|
-
color: var(--cb-muted);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
.cb-desc a {
|
|
179
|
-
color: var(--cb-link);
|
|
180
|
-
text-decoration: none;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
.cb-actions {
|
|
184
|
-
display: flex;
|
|
185
|
-
gap: 10px;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/* =========================================================
|
|
189
|
-
Buttons
|
|
190
|
-
========================================================= */
|
|
191
|
-
|
|
192
|
-
.cb-actions button {
|
|
193
|
-
padding: var(--cb-btn-padding);
|
|
194
|
-
border-radius: var(--cb-btn-radius);
|
|
195
|
-
border: 0;
|
|
196
|
-
font-size: 14px;
|
|
197
|
-
font-weight: 600;
|
|
198
|
-
cursor: pointer;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
.cb-accept {
|
|
202
|
-
background: var(--cb-accept-bg);
|
|
203
|
-
color: var(--cb-accept-text);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
.cb-reject {
|
|
207
|
-
background: var(--cb-reject-bg);
|
|
208
|
-
color: var(--cb-reject-text);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
.cb-manage {
|
|
212
|
-
background: var(--cb-manage-bg);
|
|
213
|
-
color: var(--cb-manage-text);
|
|
214
|
-
border: 1px solid var(--cb-manage-border);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/* =========================================================
|
|
218
|
-
Modal
|
|
219
|
-
========================================================= */
|
|
220
|
-
|
|
221
|
-
#astro-cookie-modal {
|
|
222
|
-
position: fixed;
|
|
223
|
-
inset: 0;
|
|
224
|
-
background: var(--cb-modal-backdrop);
|
|
225
|
-
display: flex;
|
|
226
|
-
align-items: center;
|
|
227
|
-
justify-content: center;
|
|
228
|
-
z-index: 10000;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
.cb-modal {
|
|
232
|
-
width: 100%;
|
|
233
|
-
max-width: var(--cb-modal-width);
|
|
234
|
-
background: var(--cb-modal-bg);
|
|
235
|
-
border-radius: var(--cb-modal-radius);
|
|
236
|
-
padding: 24px;
|
|
237
|
-
color: var(--cb-text);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/* =========================================================
|
|
241
|
-
Toggles
|
|
242
|
-
========================================================= */
|
|
243
|
-
|
|
244
|
-
.cb-toggle {
|
|
245
|
-
width: 44px;
|
|
246
|
-
height: 24px;
|
|
247
|
-
background: var(--cb-toggle-off-bg);
|
|
248
|
-
border-radius: 999px;
|
|
249
|
-
position: relative;
|
|
250
|
-
cursor: pointer;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
.cb-toggle span {
|
|
254
|
-
position: absolute;
|
|
255
|
-
width: 18px;
|
|
256
|
-
height: 18px;
|
|
257
|
-
background: var(--cb-toggle-knob);
|
|
258
|
-
border-radius: 50%;
|
|
259
|
-
top: 3px;
|
|
260
|
-
left: 3px;
|
|
261
|
-
transition: transform 0.2s ease;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
.cb-toggle.active {
|
|
265
|
-
background: var(--cb-toggle-on-bg);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
.cb-toggle.active span {
|
|
269
|
-
transform: translateX(20px);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/* =========================================================
|
|
273
|
-
Mobile
|
|
274
|
-
========================================================= */
|
|
275
|
-
|
|
276
|
-
@media (max-width: 640px) {
|
|
277
|
-
.cb-container {
|
|
278
|
-
flex-direction: column;
|
|
279
|
-
align-items: stretch;
|
|
280
|
-
gap: 16px;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
133
|
`, "utf8");
|
|
284
|
-
console.log("🎨 Created src/cookiebanner.css
|
|
134
|
+
console.log("🎨 Created src/cookiebanner.css");
|
|
285
135
|
}
|
|
286
136
|
/* ─────────────────────────────────────
|
|
287
|
-
Inject Astro integration
|
|
137
|
+
Inject Astro integration ONLY
|
|
288
138
|
───────────────────────────────────── */
|
|
289
139
|
if (!source.includes(`from "astro-consent"`)) {
|
|
290
140
|
source = `import astroConsent from "astro-consent";\n${source}`;
|
|
291
141
|
}
|
|
292
142
|
if (!source.includes("astroConsent(")) {
|
|
293
|
-
|
|
143
|
+
source = source.replace(/integrations\s*:\s*\[/, match => `${match}
|
|
144
|
+
astroConsent({
|
|
294
145
|
siteName: "My Website",
|
|
295
146
|
policyUrl: "/privacy",
|
|
296
147
|
consent: {
|
|
297
148
|
days: 30,
|
|
298
149
|
storageKey: "astro-consent"
|
|
299
|
-
},
|
|
300
|
-
categories: {
|
|
301
|
-
analytics: false,
|
|
302
|
-
marketing: false
|
|
303
150
|
}
|
|
304
151
|
}),
|
|
305
|
-
|
|
306
|
-
source = source.replace(/integrations\s*:\s*\[/, match => `${match}\n${injection}`);
|
|
152
|
+
`);
|
|
307
153
|
}
|
|
308
154
|
fs.writeFileSync(configPath, source, "utf8");
|
|
309
155
|
console.log("\n🎉 astro-consent installed successfully");
|
|
310
|
-
console.log("👉
|
|
156
|
+
console.log("👉 Style everything via src/cookiebanner.css");
|
|
311
157
|
console.log("👉 Run `astro-consent remove` to uninstall\n");
|
package/dist/config/defaults.js
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* DEFAULT_CONFIG
|
|
3
|
+
* ---------------------------------------------------------
|
|
4
|
+
* Fallback values ONLY.
|
|
5
|
+
*
|
|
6
|
+
* These are used:
|
|
7
|
+
* - when the user omits a value
|
|
8
|
+
* - during internal normalisation
|
|
9
|
+
*
|
|
10
|
+
* User-provided config ALWAYS takes priority.
|
|
5
11
|
*/
|
|
6
12
|
export const DEFAULT_CONFIG = {
|
|
7
13
|
siteName: "This website",
|
|
8
14
|
policyUrl: "/privacy",
|
|
9
15
|
consent: {
|
|
10
16
|
enabled: true,
|
|
17
|
+
// Number of days consent remains valid
|
|
11
18
|
days: 30,
|
|
12
|
-
|
|
19
|
+
// Must match runtime + frontend API
|
|
20
|
+
storageKey: "astro-consent"
|
|
13
21
|
},
|
|
14
22
|
categories: {
|
|
15
23
|
essential: {
|
|
@@ -8,11 +8,9 @@ import { DEFAULT_CONFIG } from "./defaults.js";
|
|
|
8
8
|
* Cache-busted to ensure updates are picked up during dev.
|
|
9
9
|
*/
|
|
10
10
|
export async function loadUserConfig(projectRoot) {
|
|
11
|
-
const configPath = path.join(projectRoot, "src", "
|
|
11
|
+
const configPath = path.join(projectRoot, "src", "astro-consent", "config.ts");
|
|
12
12
|
let userConfig = {};
|
|
13
13
|
try {
|
|
14
|
-
// 🔑 IMPORTANT:
|
|
15
|
-
// Bust Node ESM import cache using file modified time
|
|
16
14
|
const stat = fs.statSync(configPath);
|
|
17
15
|
const cacheBuster = `?v=${stat.mtimeMs}`;
|
|
18
16
|
const imported = await import(
|
|
@@ -21,20 +19,11 @@ export async function loadUserConfig(projectRoot) {
|
|
|
21
19
|
userConfig = imported?.default ?? {};
|
|
22
20
|
}
|
|
23
21
|
catch (err) {
|
|
24
|
-
console.warn("[
|
|
22
|
+
console.warn("[astro-consent] Failed to load user config, falling back to defaults");
|
|
25
23
|
}
|
|
26
24
|
return {
|
|
27
|
-
/* ─────────────────────────────
|
|
28
|
-
Site name
|
|
29
|
-
───────────────────────────── */
|
|
30
25
|
siteName: userConfig.siteName ?? DEFAULT_CONFIG.siteName,
|
|
31
|
-
/* ─────────────────────────────
|
|
32
|
-
Policy URL
|
|
33
|
-
───────────────────────────── */
|
|
34
26
|
policyUrl: userConfig.policyUrl ?? DEFAULT_CONFIG.policyUrl,
|
|
35
|
-
/* ─────────────────────────────
|
|
36
|
-
Consent settings
|
|
37
|
-
───────────────────────────── */
|
|
38
27
|
consent: {
|
|
39
28
|
enabled: userConfig.consent?.enabled ??
|
|
40
29
|
DEFAULT_CONFIG.consent.enabled,
|
|
@@ -43,15 +32,14 @@ export async function loadUserConfig(projectRoot) {
|
|
|
43
32
|
storageKey: userConfig.consent?.storageKey ??
|
|
44
33
|
DEFAULT_CONFIG.consent.storageKey
|
|
45
34
|
},
|
|
46
|
-
/* ─────────────────────────────
|
|
47
|
-
Categories
|
|
48
|
-
───────────────────────────── */
|
|
49
35
|
categories: mergeCategories(userConfig.categories, DEFAULT_CONFIG.categories)
|
|
50
36
|
};
|
|
51
37
|
}
|
|
52
38
|
/**
|
|
53
39
|
* Merge category config safely.
|
|
54
|
-
* Defaults are preserved
|
|
40
|
+
* - Defaults are preserved
|
|
41
|
+
* - User overrides win
|
|
42
|
+
* - Custom categories are supported
|
|
55
43
|
*/
|
|
56
44
|
function mergeCategories(userCategories, defaultCategories) {
|
|
57
45
|
const merged = {};
|
|
@@ -62,11 +50,14 @@ function mergeCategories(userCategories, defaultCategories) {
|
|
|
62
50
|
...(userCategories?.[key] ?? {})
|
|
63
51
|
};
|
|
64
52
|
}
|
|
65
|
-
//
|
|
53
|
+
// Add user-defined custom categories safely
|
|
66
54
|
if (userCategories) {
|
|
67
55
|
for (const key of Object.keys(userCategories)) {
|
|
68
56
|
if (!merged[key]) {
|
|
69
|
-
merged[key] =
|
|
57
|
+
merged[key] = {
|
|
58
|
+
...userCategories[key],
|
|
59
|
+
enabled: userCategories[key].enabled ?? false
|
|
60
|
+
};
|
|
70
61
|
}
|
|
71
62
|
}
|
|
72
63
|
}
|
package/dist/index.js
CHANGED
|
@@ -15,201 +15,31 @@ export default function astroConsent(options = {}) {
|
|
|
15
15
|
hooks: {
|
|
16
16
|
"astro:config:setup": ({ injectScript }) => {
|
|
17
17
|
/* ─────────────────────────────────────
|
|
18
|
-
|
|
19
|
-
───────────────────────────────────── */
|
|
20
|
-
injectScript("head-inline", `
|
|
21
|
-
const style = document.createElement("style");
|
|
22
|
-
style.innerHTML = \`
|
|
23
|
-
:root {
|
|
24
|
-
--cb-bg: rgba(12,18,32,.88);
|
|
25
|
-
--cb-border: rgba(255,255,255,.08);
|
|
26
|
-
--cb-text: #e5e7eb;
|
|
27
|
-
--cb-muted: #9ca3af;
|
|
28
|
-
--cb-link: #60a5fa;
|
|
29
|
-
--cb-accept: #22c55e;
|
|
30
|
-
--cb-reject: #374151;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/* ───── Banner ───── */
|
|
34
|
-
|
|
35
|
-
#astro-consent-banner {
|
|
36
|
-
position: fixed;
|
|
37
|
-
left: 16px;
|
|
38
|
-
right: 16px;
|
|
39
|
-
bottom: 16px;
|
|
40
|
-
z-index: 9999;
|
|
41
|
-
font-family: system-ui,-apple-system,BlinkMacSystemFont,sans-serif;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.cb-container {
|
|
45
|
-
max-width: 1200px;
|
|
46
|
-
margin: 0 auto;
|
|
47
|
-
padding: 20px 24px;
|
|
48
|
-
display: flex;
|
|
49
|
-
gap: 24px;
|
|
50
|
-
justify-content: space-between;
|
|
51
|
-
align-items: center;
|
|
52
|
-
|
|
53
|
-
background: var(--cb-bg);
|
|
54
|
-
backdrop-filter: blur(14px);
|
|
55
|
-
border-radius: 16px;
|
|
56
|
-
border: 1px solid var(--cb-border);
|
|
57
|
-
box-shadow: 0 20px 40px rgba(0,0,0,.35);
|
|
58
|
-
|
|
59
|
-
color: var(--cb-text);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
.cb-text {
|
|
63
|
-
max-width: 760px;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.cb-title {
|
|
67
|
-
font-size: 16px;
|
|
68
|
-
font-weight: 600;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
.cb-desc {
|
|
72
|
-
font-size: 14px;
|
|
73
|
-
color: var(--cb-muted);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.cb-desc a {
|
|
77
|
-
color: var(--cb-link);
|
|
78
|
-
text-decoration: none;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.cb-desc a:hover {
|
|
82
|
-
text-decoration: underline;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
.cb-actions {
|
|
86
|
-
display: flex;
|
|
87
|
-
gap: 10px;
|
|
88
|
-
flex-shrink: 0;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
.cb-actions button {
|
|
92
|
-
padding: 10px 18px;
|
|
93
|
-
border-radius: 999px;
|
|
94
|
-
border: 0;
|
|
95
|
-
font-size: 14px;
|
|
96
|
-
font-weight: 600;
|
|
97
|
-
cursor: pointer;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
.cb-accept {
|
|
101
|
-
background: var(--cb-accept);
|
|
102
|
-
color: #052e16;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.cb-reject {
|
|
106
|
-
background: var(--cb-reject);
|
|
107
|
-
color: #e5e7eb;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
.cb-manage {
|
|
111
|
-
background: transparent;
|
|
112
|
-
color: var(--cb-text);
|
|
113
|
-
border: 1px solid var(--cb-border);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/* ───── Modal ───── */
|
|
117
|
-
|
|
118
|
-
#astro-consent-modal {
|
|
119
|
-
position: fixed;
|
|
120
|
-
inset: 0;
|
|
121
|
-
background: rgba(0,0,0,.55);
|
|
122
|
-
display: flex;
|
|
123
|
-
align-items: center;
|
|
124
|
-
justify-content: center;
|
|
125
|
-
z-index: 10000;
|
|
126
|
-
font-family: system-ui,-apple-system,BlinkMacSystemFont,sans-serif;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
.cb-modal {
|
|
130
|
-
width: 100%;
|
|
131
|
-
max-width: 480px;
|
|
132
|
-
background: #0c1220;
|
|
133
|
-
border-radius: 18px;
|
|
134
|
-
padding: 24px;
|
|
135
|
-
border: 1px solid var(--cb-border);
|
|
136
|
-
color: var(--cb-text);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
.cb-row {
|
|
140
|
-
display: flex;
|
|
141
|
-
justify-content: space-between;
|
|
142
|
-
align-items: center;
|
|
143
|
-
padding: 12px 0;
|
|
144
|
-
border-bottom: 1px solid var(--cb-border);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
.cb-row:last-child {
|
|
148
|
-
border-bottom: 0;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
.cb-toggle {
|
|
152
|
-
width: 44px;
|
|
153
|
-
height: 24px;
|
|
154
|
-
background: #374151;
|
|
155
|
-
border-radius: 999px;
|
|
156
|
-
position: relative;
|
|
157
|
-
cursor: pointer;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
.cb-toggle span {
|
|
161
|
-
position: absolute;
|
|
162
|
-
width: 18px;
|
|
163
|
-
height: 18px;
|
|
164
|
-
background: #fff;
|
|
165
|
-
border-radius: 50%;
|
|
166
|
-
top: 3px;
|
|
167
|
-
left: 3px;
|
|
168
|
-
transition: transform .2s;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
.cb-toggle.active {
|
|
172
|
-
background: var(--cb-accept);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
.cb-toggle.active span {
|
|
176
|
-
transform: translateX(20px);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
@media (max-width: 640px) {
|
|
180
|
-
.cb-container {
|
|
181
|
-
flex-direction: column;
|
|
182
|
-
align-items: stretch;
|
|
183
|
-
gap: 16px;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
\`;
|
|
187
|
-
document.head.appendChild(style);
|
|
188
|
-
`);
|
|
189
|
-
/* ─────────────────────────────────────
|
|
190
|
-
Consent runtime
|
|
18
|
+
Consent runtime (NO CSS)
|
|
191
19
|
───────────────────────────────────── */
|
|
192
20
|
injectScript("page", `
|
|
193
21
|
(() => {
|
|
194
22
|
const KEY = "${storageKey}";
|
|
195
23
|
const TTL = ${ttl};
|
|
196
24
|
|
|
197
|
-
function now(){ return Date.now(); }
|
|
25
|
+
function now() { return Date.now(); }
|
|
198
26
|
|
|
199
|
-
function read(){
|
|
200
|
-
try{
|
|
27
|
+
function read() {
|
|
28
|
+
try {
|
|
201
29
|
const raw = localStorage.getItem(KEY);
|
|
202
|
-
if(!raw) return null;
|
|
30
|
+
if (!raw) return null;
|
|
203
31
|
const data = JSON.parse(raw);
|
|
204
|
-
if(data.expiresAt < now()){
|
|
32
|
+
if (data.expiresAt < now()) {
|
|
205
33
|
localStorage.removeItem(KEY);
|
|
206
34
|
return null;
|
|
207
35
|
}
|
|
208
36
|
return data;
|
|
209
|
-
}catch{
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
210
40
|
}
|
|
211
41
|
|
|
212
|
-
function write(categories){
|
|
42
|
+
function write(categories) {
|
|
213
43
|
localStorage.setItem(KEY, JSON.stringify({
|
|
214
44
|
updatedAt: now(),
|
|
215
45
|
expiresAt: now() + TTL,
|
|
@@ -220,7 +50,7 @@ document.head.appendChild(style);
|
|
|
220
50
|
window.astroConsent = {
|
|
221
51
|
get: read,
|
|
222
52
|
set: write,
|
|
223
|
-
reset(){
|
|
53
|
+
reset() {
|
|
224
54
|
localStorage.removeItem(KEY);
|
|
225
55
|
location.reload();
|
|
226
56
|
}
|
|
@@ -228,7 +58,7 @@ document.head.appendChild(style);
|
|
|
228
58
|
})();
|
|
229
59
|
`);
|
|
230
60
|
/* ─────────────────────────────────────
|
|
231
|
-
Banner + modal UI
|
|
61
|
+
Banner + modal UI (NO CSS)
|
|
232
62
|
───────────────────────────────────── */
|
|
233
63
|
injectScript("page", `
|
|
234
64
|
(() => {
|
|
@@ -241,7 +71,7 @@ document.head.appendChild(style);
|
|
|
241
71
|
|
|
242
72
|
banner.innerHTML = \`
|
|
243
73
|
<div class="cb-container">
|
|
244
|
-
<div
|
|
74
|
+
<div>
|
|
245
75
|
<div class="cb-title">${siteName} uses cookies</div>
|
|
246
76
|
<div class="cb-desc">
|
|
247
77
|
Choose how your data is used.
|
|
@@ -259,18 +89,18 @@ document.head.appendChild(style);
|
|
|
259
89
|
document.body.appendChild(banner);
|
|
260
90
|
|
|
261
91
|
banner.querySelector(".cb-accept").onclick = () => {
|
|
262
|
-
window.astroConsent.set({ essential:true, analytics:true, marketing:true });
|
|
92
|
+
window.astroConsent.set({ essential: true, analytics: true, marketing: true });
|
|
263
93
|
banner.remove();
|
|
264
94
|
};
|
|
265
95
|
|
|
266
96
|
banner.querySelector(".cb-reject").onclick = () => {
|
|
267
|
-
window.astroConsent.set({ essential:true });
|
|
97
|
+
window.astroConsent.set({ essential: true });
|
|
268
98
|
banner.remove();
|
|
269
99
|
};
|
|
270
100
|
|
|
271
101
|
banner.querySelector(".cb-manage").onclick = openModal;
|
|
272
102
|
|
|
273
|
-
function openModal(){
|
|
103
|
+
function openModal() {
|
|
274
104
|
const modal = document.createElement("div");
|
|
275
105
|
modal.id = "astro-consent-modal";
|
|
276
106
|
|
|
@@ -293,7 +123,7 @@ document.head.appendChild(style);
|
|
|
293
123
|
<div class="cb-toggle" data-key="marketing"><span></span></div>
|
|
294
124
|
</div>
|
|
295
125
|
|
|
296
|
-
<div class="cb-actions"
|
|
126
|
+
<div class="cb-actions">
|
|
297
127
|
<button class="cb-accept">Save preferences</button>
|
|
298
128
|
</div>
|
|
299
129
|
</div>
|
|
@@ -303,7 +133,7 @@ document.head.appendChild(style);
|
|
|
303
133
|
|
|
304
134
|
modal.querySelectorAll(".cb-toggle").forEach(toggle => {
|
|
305
135
|
const key = toggle.getAttribute("data-key");
|
|
306
|
-
if(state[key]) toggle.classList.add("active");
|
|
136
|
+
if (state[key]) toggle.classList.add("active");
|
|
307
137
|
|
|
308
138
|
toggle.onclick = () => {
|
|
309
139
|
state[key] = !state[key];
|
|
@@ -312,13 +142,13 @@ document.head.appendChild(style);
|
|
|
312
142
|
});
|
|
313
143
|
|
|
314
144
|
modal.querySelector(".cb-accept").onclick = () => {
|
|
315
|
-
window.astroConsent.set({ essential:true, ...state });
|
|
145
|
+
window.astroConsent.set({ essential: true, ...state });
|
|
316
146
|
modal.remove();
|
|
317
147
|
banner.remove();
|
|
318
148
|
};
|
|
319
149
|
|
|
320
150
|
modal.onclick = e => {
|
|
321
|
-
if(e.target === modal) modal.remove();
|
|
151
|
+
if (e.target === modal) modal.remove();
|
|
322
152
|
};
|
|
323
153
|
}
|
|
324
154
|
})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro-consent",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "A privacy-first, GDPR-compliant cookie consent banner for Astro with a built-in preferences modal, zero dependencies, and full theme control.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": {
|