@stacksjs/defaults 0.74.67 → 0.74.69
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.
|
@@ -122,6 +122,13 @@ interface GoogleAnalyticsConfig {
|
|
|
122
122
|
debug?: boolean // debug_mode -> DebugView
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
interface AnalyticsHqConfig {
|
|
126
|
+
siteId: string // the data-site id AnalyticsHQ minted
|
|
127
|
+
scriptUrl?: string // self-hosted instance or verified custom domain
|
|
128
|
+
respectDnt?: boolean // false counts DNT/GPC visitors (skipped by default)
|
|
129
|
+
vitals?: boolean // false stops Core Web Vitals beacons
|
|
130
|
+
}
|
|
131
|
+
|
|
125
132
|
interface SelfHostedConfig {
|
|
126
133
|
siteId: string // unique site identifier
|
|
127
134
|
apiEndpoint: string // analytics API URL
|
|
@@ -135,8 +142,9 @@ interface SelfHostedConfig {
|
|
|
135
142
|
|
|
136
143
|
```typescript
|
|
137
144
|
{
|
|
138
|
-
driver: 'fathom', // 'fathom' | 'plausible' | 'google-analytics' | 'self-hosted'
|
|
145
|
+
driver: 'fathom', // 'fathom' | 'plausible' | 'google-analytics' | 'self-hosted' | 'analyticshq'
|
|
139
146
|
drivers: {
|
|
147
|
+
analyticshq: { siteId: '' },
|
|
140
148
|
googleAnalytics: { trackingId: '' },
|
|
141
149
|
fathom: { siteId: '' },
|
|
142
150
|
plausible: { domain: '' },
|
|
@@ -167,3 +175,4 @@ Analytics dashboard at `/dashboard/analytics` displays:
|
|
|
167
175
|
- Fathom is a paid service - self-hosted is free but requires infrastructure
|
|
168
176
|
- `trackOutboundLinks` adds click handlers to external `<a>` tags
|
|
169
177
|
- `capturePageviews` is server-side and independent of `driver`
|
|
178
|
+
- AnalyticsHQ custom events need no script: `data-analyticshq-event="Ticket click"` on any element, with other `data-analyticshq-*` attributes as properties
|
package/ide/vscode/package.json
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/defaults",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.74.
|
|
5
|
+
"version": "0.74.69",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/stacksjs/stacks.git",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@iconify-json/f7": "^1.2.2",
|
|
57
57
|
"@iconify-json/hugeicons": "^1.2.27",
|
|
58
|
-
"@stacksjs/mobile": "^0.74.
|
|
58
|
+
"@stacksjs/mobile": "^0.74.69",
|
|
59
59
|
"@stacksjs/sanitizer": "^0.2.113",
|
|
60
60
|
"ts-qr-codes": "^0.1.8"
|
|
61
61
|
}
|
package/routes/email.ts
CHANGED
|
@@ -53,8 +53,8 @@ function emailConfig(): EmailConfigShape {
|
|
|
53
53
|
// Unsubscribe — signed-link opt-out (stacksjs/stacks#1880)
|
|
54
54
|
// ============================================================================
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
const params = (req as
|
|
56
|
+
async function unsubscribe(req: unknown): Promise<Response> {
|
|
57
|
+
const params = (req as { params?: { token?: string } }).params
|
|
58
58
|
const token = params?.token ?? ''
|
|
59
59
|
const result = verifyUnsubscribeToken(token)
|
|
60
60
|
if (!result.valid || !result.email) {
|
|
@@ -68,7 +68,17 @@ route.get('/_stacks/email/unsubscribe/{token}', async (req) => {
|
|
|
68
68
|
`You've been unsubscribed. We won't email ${result.email} again.`,
|
|
69
69
|
{ status: 200, headers: { 'Content-Type': 'text/plain; charset=utf-8' } },
|
|
70
70
|
)
|
|
71
|
-
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// A person clicking the link in the message.
|
|
74
|
+
route.get('/_stacks/email/unsubscribe/{token}', unsubscribe).skipCsrf()
|
|
75
|
+
|
|
76
|
+
// The mail client's own unsubscribe button. `buildListUnsubscribeHeaders`
|
|
77
|
+
// sends `List-Unsubscribe-Post: List-Unsubscribe=One-Click`, and RFC 8058 has
|
|
78
|
+
// the client POST that body to the same URL. Only GET was mounted, so the
|
|
79
|
+
// button Gmail and Apple Mail show next to the sender reached no route and
|
|
80
|
+
// nobody was unsubscribed.
|
|
81
|
+
route.post('/_stacks/email/unsubscribe/{token}', unsubscribe).skipCsrf()
|
|
72
82
|
|
|
73
83
|
// ============================================================================
|
|
74
84
|
// Provider webhooks (stacksjs/stacks#1881)
|
|
@@ -43,7 +43,9 @@ jobs:
|
|
|
43
43
|
node-modules-
|
|
44
44
|
|
|
45
45
|
- name: Install Dependencies
|
|
46
|
-
|
|
46
|
+
# Frozen: a lockfile that no longer matches package.json fails here,
|
|
47
|
+
# not in the deploy that installs from it.
|
|
48
|
+
run: bun install --frozen-lockfile
|
|
47
49
|
|
|
48
50
|
- name: Lint
|
|
49
51
|
run: bun buddy lint
|
|
@@ -74,7 +76,9 @@ jobs:
|
|
|
74
76
|
node-modules-
|
|
75
77
|
|
|
76
78
|
- name: Install dependencies
|
|
77
|
-
|
|
79
|
+
# Frozen: a lockfile that no longer matches package.json fails here,
|
|
80
|
+
# not in the deploy that installs from it.
|
|
81
|
+
run: bun install --frozen-lockfile
|
|
78
82
|
|
|
79
83
|
- name: Set Application Key
|
|
80
84
|
run: bun buddy key:generate
|
|
@@ -108,7 +112,9 @@ jobs:
|
|
|
108
112
|
node-modules-
|
|
109
113
|
|
|
110
114
|
- name: Install Dependencies
|
|
111
|
-
|
|
115
|
+
# Frozen: a lockfile that no longer matches package.json fails here,
|
|
116
|
+
# not in the deploy that installs from it.
|
|
117
|
+
run: bun install --frozen-lockfile
|
|
112
118
|
|
|
113
119
|
- name: Set Application Key
|
|
114
120
|
run: bun buddy key:generate
|