@brandlab-digital/site-next 1.0.0-rc.2 → 1.0.0-rc.21
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/analytics.d.ts +23 -0
- package/dist/analytics.d.ts.map +1 -1
- package/dist/analytics.js +61 -0
- package/dist/analytics.js.map +1 -1
- package/dist/blog.d.ts.map +1 -1
- package/dist/blog.js +5 -2
- package/dist/blog.js.map +1 -1
- package/dist/contact/attribution.d.ts +11 -0
- package/dist/contact/attribution.d.ts.map +1 -0
- package/dist/contact/attribution.js +145 -0
- package/dist/contact/attribution.js.map +1 -0
- package/dist/contact/client.d.ts +7 -1
- package/dist/contact/client.d.ts.map +1 -1
- package/dist/contact/client.js +32 -1
- package/dist/contact/client.js.map +1 -1
- package/dist/contact/context.d.ts +4 -0
- package/dist/contact/context.d.ts.map +1 -1
- package/dist/contact/context.js +56 -7
- package/dist/contact/context.js.map +1 -1
- package/dist/contact/contract.d.ts +3 -4
- package/dist/contact/contract.d.ts.map +1 -1
- package/dist/contact/contract.js +3 -5
- package/dist/contact/contract.js.map +1 -1
- package/dist/contact/email.d.ts +1 -0
- package/dist/contact/email.d.ts.map +1 -1
- package/dist/contact/email.js +137 -54
- package/dist/contact/email.js.map +1 -1
- package/dist/contact/image-sanitizer.d.ts +1 -1
- package/dist/contact/image-sanitizer.d.ts.map +1 -1
- package/dist/contact/image-sanitizer.js +12 -17
- package/dist/contact/image-sanitizer.js.map +1 -1
- package/dist/contact/index.d.ts +1 -0
- package/dist/contact/index.d.ts.map +1 -1
- package/dist/contact/index.js +2 -0
- package/dist/contact/index.js.map +1 -1
- package/dist/contact/production.d.ts +3 -1
- package/dist/contact/production.d.ts.map +1 -1
- package/dist/contact/production.js +31 -60
- package/dist/contact/production.js.map +1 -1
- package/dist/contact/resend.d.ts +1 -1
- package/dist/contact/resend.js +1 -1
- package/dist/contact/server-entry.d.ts +13 -0
- package/dist/contact/server-entry.d.ts.map +1 -0
- package/dist/contact/server-entry.js +13 -0
- package/dist/contact/server-entry.js.map +1 -0
- package/dist/contact/server.d.ts.map +1 -1
- package/dist/contact/server.js +27 -28
- package/dist/contact/server.js.map +1 -1
- package/dist/contact/shared.d.ts +3 -6
- package/dist/contact/shared.d.ts.map +1 -1
- package/dist/contact/shared.js.map +1 -1
- package/dist/google-reviews-client.d.ts +20 -0
- package/dist/google-reviews-client.d.ts.map +1 -0
- package/dist/google-reviews-client.js +85 -0
- package/dist/google-reviews-client.js.map +1 -0
- package/dist/google-reviews-durable.d.ts +22 -0
- package/dist/google-reviews-durable.d.ts.map +1 -0
- package/dist/google-reviews-durable.js +81 -0
- package/dist/google-reviews-durable.js.map +1 -0
- package/dist/google-reviews-server.d.ts +58 -0
- package/dist/google-reviews-server.d.ts.map +1 -0
- package/dist/google-reviews-server.js +151 -0
- package/dist/google-reviews-server.js.map +1 -0
- package/dist/google-reviews-ui.d.ts +599 -0
- package/dist/google-reviews-ui.d.ts.map +1 -0
- package/dist/google-reviews-ui.js +188 -0
- package/dist/google-reviews-ui.js.map +1 -0
- package/dist/google-reviews.d.ts +4 -322
- package/dist/google-reviews.d.ts.map +1 -1
- package/dist/google-reviews.js +4 -252
- package/dist/google-reviews.js.map +1 -1
- package/dist/google-tag-plan.d.ts +19 -0
- package/dist/google-tag-plan.d.ts.map +1 -0
- package/dist/google-tag-plan.js +85 -0
- package/dist/google-tag-plan.js.map +1 -0
- package/dist/google-tag.d.ts +17 -0
- package/dist/google-tag.d.ts.map +1 -0
- package/dist/google-tag.js +18 -0
- package/dist/google-tag.js.map +1 -0
- package/dist/instrumentation-client.d.ts +2 -0
- package/dist/instrumentation-client.d.ts.map +1 -1
- package/dist/instrumentation-client.js +39 -3
- package/dist/instrumentation-client.js.map +1 -1
- package/dist/redis-rest.d.ts +12 -0
- package/dist/redis-rest.d.ts.map +1 -0
- package/dist/redis-rest.js +83 -0
- package/dist/redis-rest.js.map +1 -0
- package/package.json +29 -36
package/dist/google-reviews.js
CHANGED
|
@@ -1,256 +1,8 @@
|
|
|
1
1
|
import 'server-only';
|
|
2
|
-
import { createElement } from 'react';
|
|
3
|
-
import { GOOGLE_MAPS_ATTRIBUTION_LABEL, GOOGLE_MAPS_ATTRIBUTION_TEXT, GOOGLE_PLACE_REVIEWS_MAX_REVIEWS, createGooglePlaceReviewsUnavailableSnapshot, fetchGooglePlaceReviewsSnapshot, normalizeGooglePlaceId, normalizeGooglePlacePublicUrl, } from '@brandlab-digital/site-core/google-reviews';
|
|
4
|
-
import { GOOGLE_MAPS_ATTRIBUTION_LOGO_DATA_URL, GOOGLE_MAPS_ATTRIBUTION_LOGO_HEIGHT, GOOGLE_MAPS_ATTRIBUTION_LOGO_WIDTH, } from './google-maps-attribution-assets.js';
|
|
5
|
-
export const GOOGLE_PLACE_REVIEWS_UNAVAILABLE_HEADERS = {
|
|
6
|
-
'Cache-Control': 'private, no-store, max-age=0',
|
|
7
|
-
};
|
|
8
|
-
export const GOOGLE_PLACE_REVIEWS_AVAILABLE_HEADERS = {
|
|
9
|
-
'Cache-Control': 'private, no-store, max-age=0',
|
|
10
|
-
};
|
|
11
|
-
const inFlightByFetcher = new WeakMap();
|
|
12
|
-
function coalescingKey(options) {
|
|
13
|
-
return JSON.stringify([
|
|
14
|
-
normalizeGooglePlaceId(options.placeId) ?? '',
|
|
15
|
-
options.maxReviews ?? null,
|
|
16
|
-
options.fallbackGoogleMapsUri ?? '',
|
|
17
|
-
]);
|
|
18
|
-
}
|
|
19
|
-
async function loadGooglePlaceReviewsSnapshot(options) {
|
|
20
|
-
const placeId = normalizeGooglePlaceId(options.placeId);
|
|
21
|
-
if (!options.apiKey?.trim() || !placeId) {
|
|
22
|
-
return { snapshot: await fetchGooglePlaceReviewsSnapshot(options) };
|
|
23
|
-
}
|
|
24
|
-
if (typeof options.quotaGuard !== 'function') {
|
|
25
|
-
return {
|
|
26
|
-
snapshot: createGooglePlaceReviewsUnavailableSnapshot('quota-guard-unavailable', options.fallbackGoogleMapsUri),
|
|
27
|
-
forcedStatus: 503,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
let decision;
|
|
31
|
-
try {
|
|
32
|
-
decision = await options.quotaGuard({ placeId });
|
|
33
|
-
if (typeof decision?.allowed !== 'boolean' ||
|
|
34
|
-
(decision.retryAfterSeconds !== undefined && (!Number.isSafeInteger(decision.retryAfterSeconds) ||
|
|
35
|
-
decision.retryAfterSeconds < 1 ||
|
|
36
|
-
decision.retryAfterSeconds > 86_400))) {
|
|
37
|
-
throw new Error('Invalid quota decision.');
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
catch {
|
|
41
|
-
return {
|
|
42
|
-
snapshot: createGooglePlaceReviewsUnavailableSnapshot('quota-guard-unavailable', options.fallbackGoogleMapsUri),
|
|
43
|
-
forcedStatus: 503,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
if (!decision.allowed) {
|
|
47
|
-
return {
|
|
48
|
-
snapshot: createGooglePlaceReviewsUnavailableSnapshot('quota-exhausted', options.fallbackGoogleMapsUri),
|
|
49
|
-
forcedStatus: 429,
|
|
50
|
-
...(decision.retryAfterSeconds
|
|
51
|
-
? { retryAfterSeconds: decision.retryAfterSeconds }
|
|
52
|
-
: {}),
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
return { snapshot: await fetchGooglePlaceReviewsSnapshot(options) };
|
|
56
|
-
}
|
|
57
|
-
function getGooglePlaceReviewsRequest(options) {
|
|
58
|
-
const fetcher = options.fetcher ?? fetch;
|
|
59
|
-
const requests = inFlightByFetcher.get(fetcher) ?? new Map();
|
|
60
|
-
inFlightByFetcher.set(fetcher, requests);
|
|
61
|
-
const key = coalescingKey(options);
|
|
62
|
-
const existing = requests.get(key);
|
|
63
|
-
if (existing)
|
|
64
|
-
return existing;
|
|
65
|
-
const request = loadGooglePlaceReviewsSnapshot(options).finally(() => {
|
|
66
|
-
requests.delete(key);
|
|
67
|
-
if (requests.size === 0)
|
|
68
|
-
inFlightByFetcher.delete(fetcher);
|
|
69
|
-
});
|
|
70
|
-
requests.set(key, request);
|
|
71
|
-
return request;
|
|
72
|
-
}
|
|
73
|
-
function assertNonEmptyText(value, field) {
|
|
74
|
-
if (typeof value !== 'string' || !value.trim()) {
|
|
75
|
-
throw new Error(`${field} is required for a policy-complete Google Places rendering.`);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
function assertPublicUrl(value, field, required = false) {
|
|
79
|
-
if (value === undefined && !required)
|
|
80
|
-
return;
|
|
81
|
-
if (typeof value !== 'string' || !normalizeGooglePlacePublicUrl(value)) {
|
|
82
|
-
throw new Error(`${field} must be a credential-free HTTPS URL.`);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
function assertGooglePlaceReviewsSnapshotIsRenderable(snapshot) {
|
|
86
|
-
assertNonEmptyText(snapshot.businessName, 'snapshot.businessName');
|
|
87
|
-
assertPublicUrl(snapshot.googleMapsUri, 'snapshot.googleMapsUri', true);
|
|
88
|
-
if (snapshot.attribution?.label !== GOOGLE_MAPS_ATTRIBUTION_LABEL ||
|
|
89
|
-
snapshot.attribution?.text !== GOOGLE_MAPS_ATTRIBUTION_TEXT) {
|
|
90
|
-
throw new Error('Google Maps attribution must use the unmodified shared label and text.');
|
|
91
|
-
}
|
|
92
|
-
if (!Array.isArray(snapshot.reviews) || snapshot.reviews.length > GOOGLE_PLACE_REVIEWS_MAX_REVIEWS) {
|
|
93
|
-
throw new Error(`Google Places rendering supports at most ${GOOGLE_PLACE_REVIEWS_MAX_REVIEWS} reviews.`);
|
|
94
|
-
}
|
|
95
|
-
if (!Array.isArray(snapshot.thirdPartyAttributions)) {
|
|
96
|
-
throw new Error('snapshot.thirdPartyAttributions is required for provider attribution.');
|
|
97
|
-
}
|
|
98
|
-
snapshot.reviews.forEach((review, index) => {
|
|
99
|
-
assertNonEmptyText(review.authorName, `snapshot.reviews[${index}].authorName`);
|
|
100
|
-
assertNonEmptyText(review.text, `snapshot.reviews[${index}].text`);
|
|
101
|
-
assertPublicUrl(review.googleMapsUri, `snapshot.reviews[${index}].googleMapsUri`, true);
|
|
102
|
-
assertPublicUrl(review.authorUri, `snapshot.reviews[${index}].authorUri`);
|
|
103
|
-
assertPublicUrl(review.authorPhotoUri, `snapshot.reviews[${index}].authorPhotoUri`);
|
|
104
|
-
assertPublicUrl(review.flagContentUri, `snapshot.reviews[${index}].flagContentUri`);
|
|
105
|
-
});
|
|
106
|
-
snapshot.thirdPartyAttributions.forEach((item, index) => {
|
|
107
|
-
assertNonEmptyText(item.provider, `snapshot.thirdPartyAttributions[${index}].provider`);
|
|
108
|
-
assertPublicUrl(item.providerUri, `snapshot.thirdPartyAttributions[${index}].providerUri`);
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
function googleMapsAttributionStyle(tone) {
|
|
112
|
-
return {
|
|
113
|
-
color: tone === 'dark' ? '#ffffff' : '#5e5e5e',
|
|
114
|
-
fontFamily: 'Roboto, Arial, sans-serif',
|
|
115
|
-
fontSize: 12,
|
|
116
|
-
fontWeight: 400,
|
|
117
|
-
whiteSpace: 'nowrap',
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
function googleMapsContentContainerStyle(tone) {
|
|
121
|
-
return {
|
|
122
|
-
backgroundColor: tone === 'dark' ? '#1f1f1f' : '#ffffff',
|
|
123
|
-
border: `1px solid ${tone === 'dark' ? '#5e5e5e' : '#d9d9d9'}`,
|
|
124
|
-
boxSizing: 'border-box',
|
|
125
|
-
color: tone === 'dark' ? '#ffffff' : '#1f1f1f',
|
|
126
|
-
padding: 16,
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
function googleMapsLogoClearSpaceStyle() {
|
|
130
|
-
return {
|
|
131
|
-
display: 'inline-flex',
|
|
132
|
-
lineHeight: 0,
|
|
133
|
-
padding: '10px 10px 5px',
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
function externalLinkProps(href) {
|
|
137
|
-
return {
|
|
138
|
-
href,
|
|
139
|
-
referrerPolicy: 'no-referrer',
|
|
140
|
-
rel: 'noopener noreferrer',
|
|
141
|
-
target: '_blank',
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
function renderGoogleMapsAttribution(attributionUrl, mode, tone) {
|
|
145
|
-
const content = mode === 'logo'
|
|
146
|
-
? createElement('img', {
|
|
147
|
-
alt: GOOGLE_MAPS_ATTRIBUTION_LABEL,
|
|
148
|
-
decoding: 'async',
|
|
149
|
-
draggable: false,
|
|
150
|
-
height: GOOGLE_MAPS_ATTRIBUTION_LOGO_HEIGHT,
|
|
151
|
-
src: GOOGLE_MAPS_ATTRIBUTION_LOGO_DATA_URL[tone],
|
|
152
|
-
style: {
|
|
153
|
-
display: 'block',
|
|
154
|
-
height: GOOGLE_MAPS_ATTRIBUTION_LOGO_HEIGHT,
|
|
155
|
-
width: GOOGLE_MAPS_ATTRIBUTION_LOGO_WIDTH,
|
|
156
|
-
},
|
|
157
|
-
width: GOOGLE_MAPS_ATTRIBUTION_LOGO_WIDTH,
|
|
158
|
-
})
|
|
159
|
-
: createElement('span', {
|
|
160
|
-
'data-brandlab-google-maps-attribution': 'text-constrained-space',
|
|
161
|
-
style: googleMapsAttributionStyle(tone),
|
|
162
|
-
translate: 'no',
|
|
163
|
-
}, GOOGLE_MAPS_ATTRIBUTION_TEXT);
|
|
164
|
-
if (!attributionUrl)
|
|
165
|
-
return content;
|
|
166
|
-
return createElement('a', {
|
|
167
|
-
...externalLinkProps(attributionUrl),
|
|
168
|
-
'aria-label': GOOGLE_MAPS_ATTRIBUTION_LABEL,
|
|
169
|
-
'data-brandlab-google-maps-attribution': mode,
|
|
170
|
-
...(mode === 'logo' ? { style: googleMapsLogoClearSpaceStyle() } : {}),
|
|
171
|
-
}, content);
|
|
172
|
-
}
|
|
173
|
-
function renderReview(review, index, props) {
|
|
174
|
-
const authorUri = normalizeGooglePlacePublicUrl(review.authorUri);
|
|
175
|
-
const authorPhotoUri = normalizeGooglePlacePublicUrl(review.authorPhotoUri);
|
|
176
|
-
const sourceUrl = normalizeGooglePlacePublicUrl(review.googleMapsUri);
|
|
177
|
-
const flagContentUri = normalizeGooglePlacePublicUrl(review.flagContentUri);
|
|
178
|
-
return createElement('article', { className: props.reviewClassName, key: `${review.authorName}:${review.publishTime ?? index}` }, createElement('header', null, authorPhotoUri
|
|
179
|
-
? createElement('img', {
|
|
180
|
-
alt: '',
|
|
181
|
-
decoding: 'async',
|
|
182
|
-
height: 40,
|
|
183
|
-
loading: 'lazy',
|
|
184
|
-
referrerPolicy: 'no-referrer',
|
|
185
|
-
src: authorPhotoUri,
|
|
186
|
-
width: 40,
|
|
187
|
-
})
|
|
188
|
-
: null, authorUri
|
|
189
|
-
? createElement('a', { ...externalLinkProps(authorUri), className: props.authorClassName }, review.authorName)
|
|
190
|
-
: createElement('span', { className: props.authorClassName }, review.authorName), review.rating
|
|
191
|
-
? createElement('span', { 'aria-label': `${review.rating} out of 5 stars` }, `${review.rating}/5`)
|
|
192
|
-
: null, review.relativePublishTimeDescription
|
|
193
|
-
? createElement('time', { dateTime: review.publishTime }, review.relativePublishTimeDescription)
|
|
194
|
-
: null), createElement('blockquote', { className: props.textClassName }, createElement('p', null, review.text)), createElement('footer', null, sourceUrl
|
|
195
|
-
? createElement('a', externalLinkProps(sourceUrl), 'Read this review on Google Maps')
|
|
196
|
-
: null, flagContentUri
|
|
197
|
-
? createElement('a', externalLinkProps(flagContentUri), 'Report this review to Google')
|
|
198
|
-
: null));
|
|
199
|
-
}
|
|
200
2
|
/**
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
* links present in the upstream response.
|
|
3
|
+
* Backwards-compatible server entrypoint for RC.11 consumers. New code must
|
|
4
|
+
* use the explicit /server, /client or /ui subpath so the RSC boundary is clear.
|
|
204
5
|
*/
|
|
205
|
-
export
|
|
206
|
-
|
|
207
|
-
return null;
|
|
208
|
-
assertGooglePlaceReviewsSnapshotIsRenderable(snapshot);
|
|
209
|
-
const props = {
|
|
210
|
-
...sectionProps,
|
|
211
|
-
snapshot,
|
|
212
|
-
reviewClassName,
|
|
213
|
-
authorClassName,
|
|
214
|
-
textClassName,
|
|
215
|
-
attributionClassName,
|
|
216
|
-
attributionTone,
|
|
217
|
-
attributionMode,
|
|
218
|
-
};
|
|
219
|
-
const attributionUrl = normalizeGooglePlacePublicUrl(snapshot.googleMapsUri);
|
|
220
|
-
return createElement('section', {
|
|
221
|
-
...sectionProps,
|
|
222
|
-
'aria-label': sectionProps['aria-label'] ?? `${snapshot.businessName} reviews on Google Maps`,
|
|
223
|
-
'data-brandlab-google-reviews': 'attribution-complete',
|
|
224
|
-
'data-brandlab-google-attribution-mode': attributionMode,
|
|
225
|
-
}, createElement('div', {
|
|
226
|
-
'data-brandlab-google-content-container': 'visually-distinguished',
|
|
227
|
-
style: googleMapsContentContainerStyle(attributionTone),
|
|
228
|
-
}, snapshot.rating
|
|
229
|
-
? createElement('p', {
|
|
230
|
-
'aria-label': `Average rating ${snapshot.rating} out of 5${snapshot.userRatingCount === undefined ? '' : ` from ${snapshot.userRatingCount} reviews`}`,
|
|
231
|
-
}, `${snapshot.rating}/5${snapshot.userRatingCount === undefined ? '' : ` from ${snapshot.userRatingCount} reviews`}`)
|
|
232
|
-
: null, createElement('p', { 'data-brandlab-google-review-ordering': 'google-relevance' }, `Reviews are selected and ordered by Google Maps by relevance. Up to ${snapshot.reviews.length} returned reviews are displayed without reordering.`), ...snapshot.reviews.map((review, index) => renderReview(review, index, props)), ...snapshot.thirdPartyAttributions.map((item) => {
|
|
233
|
-
const providerUri = normalizeGooglePlacePublicUrl(item.providerUri);
|
|
234
|
-
return createElement('p', { key: `${item.provider}:${providerUri ?? ''}` }, 'Data provider: ', providerUri
|
|
235
|
-
? createElement('a', externalLinkProps(providerUri), item.provider)
|
|
236
|
-
: item.provider);
|
|
237
|
-
}), createElement('p', { className: attributionClassName }, 'Reviews provided by ', renderGoogleMapsAttribution(attributionUrl, attributionMode, attributionTone))));
|
|
238
|
-
}
|
|
239
|
-
export async function createGooglePlaceReviewsRouteResponse(options) {
|
|
240
|
-
const result = await getGooglePlaceReviewsRequest(options);
|
|
241
|
-
const snapshot = result.snapshot;
|
|
242
|
-
const cacheHeaders = snapshot.status === 'available'
|
|
243
|
-
? GOOGLE_PLACE_REVIEWS_AVAILABLE_HEADERS
|
|
244
|
-
: GOOGLE_PLACE_REVIEWS_UNAVAILABLE_HEADERS;
|
|
245
|
-
const headers = new Headers(options.responseInit?.headers);
|
|
246
|
-
headers.set('Cache-Control', cacheHeaders['Cache-Control']);
|
|
247
|
-
if (result.retryAfterSeconds) {
|
|
248
|
-
headers.set('Retry-After', String(result.retryAfterSeconds));
|
|
249
|
-
}
|
|
250
|
-
return Response.json(snapshot, {
|
|
251
|
-
...options.responseInit,
|
|
252
|
-
status: result.forcedStatus ?? options.responseInit?.status,
|
|
253
|
-
headers,
|
|
254
|
-
});
|
|
255
|
-
}
|
|
6
|
+
export * from './google-reviews-server.js';
|
|
7
|
+
export * from './google-reviews-ui.js';
|
|
256
8
|
//# sourceMappingURL=google-reviews.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google-reviews.js","sourceRoot":"","sources":["../src/google-reviews.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"google-reviews.js","sourceRoot":"","sources":["../src/google-reviews.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAEpB;;;GAGG;AACH,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type BrandlabAnalyticsContract } from '@brandlab-digital/site-core/analytics';
|
|
2
|
+
export interface BrandlabGoogleTagConfig {
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
measurementId?: string | null;
|
|
5
|
+
googleAdsConversionId?: string | null;
|
|
6
|
+
googleAdsWebsiteCallConversionLabel?: string | null;
|
|
7
|
+
}
|
|
8
|
+
export interface BrandlabGoogleTagPlan {
|
|
9
|
+
loaderId: string;
|
|
10
|
+
source: string;
|
|
11
|
+
inlineScript: string;
|
|
12
|
+
destinations: readonly string[];
|
|
13
|
+
websiteCallDestination: string | null;
|
|
14
|
+
}
|
|
15
|
+
export declare function resolveBrandlabGoogleTagConfig(contract: BrandlabAnalyticsContract, environment: Readonly<Record<string, string | undefined>>, options: {
|
|
16
|
+
enabled: boolean;
|
|
17
|
+
}): BrandlabGoogleTagConfig;
|
|
18
|
+
export declare function createBrandlabGoogleTagPlan(config: BrandlabGoogleTagConfig, phoneNumber?: string | null): BrandlabGoogleTagPlan | null;
|
|
19
|
+
//# sourceMappingURL=google-tag-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-tag-plan.d.ts","sourceRoot":"","sources":["../src/google-tag-plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,yBAAyB,EAC/B,MAAM,uCAAuC,CAAA;AAE9C,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAA;IAChB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrC,mCAAmC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACpD;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;IAC/B,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAA;CACtC;AAKD,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,yBAAyB,EACnC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,EACzD,OAAO,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,GAC5B,uBAAuB,CAYzB;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,uBAAuB,EAC/B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAC1B,qBAAqB,GAAG,IAAI,CAyC9B"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { defineAnalyticsContract, getGoogleAdsWebsiteCallSendTo, } from '@brandlab-digital/site-core/analytics';
|
|
2
|
+
const GA4_MEASUREMENT_ID_PATTERN = /^G-[A-Z0-9]{4,20}$/i;
|
|
3
|
+
const GOOGLE_ADS_CONVERSION_ID_PATTERN = /^(?:AW-)?\d{6,20}$/;
|
|
4
|
+
export function resolveBrandlabGoogleTagConfig(contract, environment, options) {
|
|
5
|
+
defineAnalyticsContract(contract);
|
|
6
|
+
return {
|
|
7
|
+
enabled: options.enabled,
|
|
8
|
+
measurementId: environment[contract.measurementIdEnv],
|
|
9
|
+
googleAdsConversionId: contract.googleAds
|
|
10
|
+
? environment[contract.googleAds.conversionIdEnv]
|
|
11
|
+
: undefined,
|
|
12
|
+
googleAdsWebsiteCallConversionLabel: contract.googleAds?.websiteCalls
|
|
13
|
+
? environment[contract.googleAds.websiteCalls.conversionLabelEnv]
|
|
14
|
+
: undefined,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function createBrandlabGoogleTagPlan(config, phoneNumber) {
|
|
18
|
+
if (!config.enabled)
|
|
19
|
+
return null;
|
|
20
|
+
const measurementId = validMeasurementId(config.measurementId);
|
|
21
|
+
const googleAdsConversionId = validGoogleAdsConversionId(config.googleAdsConversionId);
|
|
22
|
+
const loaderId = measurementId ?? googleAdsConversionId;
|
|
23
|
+
if (!loaderId)
|
|
24
|
+
return null;
|
|
25
|
+
const destinations = [...new Set([
|
|
26
|
+
...(measurementId ? [measurementId] : []),
|
|
27
|
+
...(googleAdsConversionId ? [googleAdsConversionId] : []),
|
|
28
|
+
])];
|
|
29
|
+
const displayPhone = safeDisplayedBusinessPhone(phoneNumber);
|
|
30
|
+
const websiteCallDestination = displayPhone
|
|
31
|
+
? getGoogleAdsWebsiteCallSendTo({
|
|
32
|
+
conversionId: googleAdsConversionId,
|
|
33
|
+
conversionLabel: config.googleAdsWebsiteCallConversionLabel,
|
|
34
|
+
}) ?? null
|
|
35
|
+
: null;
|
|
36
|
+
const configCommands = destinations.map((destination) => `window.gtag('config', ${safeJson(destination)});`);
|
|
37
|
+
if (websiteCallDestination && displayPhone) {
|
|
38
|
+
configCommands.push(`window.gtag('config', ${safeJson(websiteCallDestination)}, ${safeJson({
|
|
39
|
+
phone_conversion_number: displayPhone,
|
|
40
|
+
})});`);
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
loaderId,
|
|
44
|
+
source: `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(loaderId)}`,
|
|
45
|
+
inlineScript: [
|
|
46
|
+
'window.dataLayer = window.dataLayer || [];',
|
|
47
|
+
'window.gtag = window.gtag || function(){window.dataLayer.push(arguments);};',
|
|
48
|
+
"window.gtag('js', new Date());",
|
|
49
|
+
...configCommands,
|
|
50
|
+
].join('\n'),
|
|
51
|
+
destinations,
|
|
52
|
+
websiteCallDestination,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function validMeasurementId(value) {
|
|
56
|
+
const normalized = value?.trim();
|
|
57
|
+
return normalized && GA4_MEASUREMENT_ID_PATTERN.test(normalized)
|
|
58
|
+
? normalized.toUpperCase()
|
|
59
|
+
: undefined;
|
|
60
|
+
}
|
|
61
|
+
function validGoogleAdsConversionId(value) {
|
|
62
|
+
const normalized = value?.trim();
|
|
63
|
+
if (!normalized || !GOOGLE_ADS_CONVERSION_ID_PATTERN.test(normalized))
|
|
64
|
+
return undefined;
|
|
65
|
+
return normalized.startsWith('AW-') ? normalized : `AW-${normalized}`;
|
|
66
|
+
}
|
|
67
|
+
function safeDisplayedBusinessPhone(value) {
|
|
68
|
+
const normalized = value?.trim();
|
|
69
|
+
const digits = normalized?.replace(/\D/g, '') ?? '';
|
|
70
|
+
return normalized &&
|
|
71
|
+
normalized.length <= 32 &&
|
|
72
|
+
digits.length >= 6 &&
|
|
73
|
+
/^[0-9+().\s-]+$/.test(normalized)
|
|
74
|
+
? normalized
|
|
75
|
+
: undefined;
|
|
76
|
+
}
|
|
77
|
+
function safeJson(value) {
|
|
78
|
+
return JSON.stringify(value)
|
|
79
|
+
.replace(/</g, '\\u003c')
|
|
80
|
+
.replace(/>/g, '\\u003e')
|
|
81
|
+
.replace(/&/g, '\\u0026')
|
|
82
|
+
.replace(/\u2028/g, '\\u2028')
|
|
83
|
+
.replace(/\u2029/g, '\\u2029');
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=google-tag-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-tag-plan.js","sourceRoot":"","sources":["../src/google-tag-plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type BrandlabGoogleTagConfig } from './google-tag-plan.js';
|
|
2
|
+
export { createBrandlabGoogleTagPlan, resolveBrandlabGoogleTagConfig, } from './google-tag-plan.js';
|
|
3
|
+
export type { BrandlabGoogleTagConfig, BrandlabGoogleTagPlan, } from './google-tag-plan.js';
|
|
4
|
+
export interface BrandlabGoogleTagProps extends BrandlabGoogleTagConfig {
|
|
5
|
+
/** Must match the verified public number exactly as it is rendered on the page. */
|
|
6
|
+
phoneNumber?: string | null;
|
|
7
|
+
nonce?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Shared Google tag and website-call forwarding-number snippet.
|
|
11
|
+
*
|
|
12
|
+
* Render this exactly once from the root layout. The enabled flag remains the
|
|
13
|
+
* project consent/production gate; account-side conversion settings remain
|
|
14
|
+
* outside website runtime.
|
|
15
|
+
*/
|
|
16
|
+
export declare function BrandlabGoogleTag(props: BrandlabGoogleTagProps): import("react/jsx-runtime").JSX.Element | null;
|
|
17
|
+
//# sourceMappingURL=google-tag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-tag.d.ts","sourceRoot":"","sources":["../src/google-tag.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACL,2BAA2B,EAC3B,8BAA8B,GAC/B,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EACV,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,sBAAsB,CAAA;AAE7B,MAAM,WAAW,sBAAuB,SAAQ,uBAAuB;IACrE,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,kDAqB9D"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import Script from 'next/script';
|
|
3
|
+
import { createBrandlabGoogleTagPlan, } from './google-tag-plan.js';
|
|
4
|
+
export { createBrandlabGoogleTagPlan, resolveBrandlabGoogleTagConfig, } from './google-tag-plan.js';
|
|
5
|
+
/**
|
|
6
|
+
* Shared Google tag and website-call forwarding-number snippet.
|
|
7
|
+
*
|
|
8
|
+
* Render this exactly once from the root layout. The enabled flag remains the
|
|
9
|
+
* project consent/production gate; account-side conversion settings remain
|
|
10
|
+
* outside website runtime.
|
|
11
|
+
*/
|
|
12
|
+
export function BrandlabGoogleTag(props) {
|
|
13
|
+
const plan = createBrandlabGoogleTagPlan(props, props.phoneNumber);
|
|
14
|
+
if (!plan)
|
|
15
|
+
return null;
|
|
16
|
+
return (_jsxs(_Fragment, { children: [_jsx(Script, { id: "brandlab-google-tag-loader", "data-brandlab-google-tag": "loader", src: plan.source, strategy: "afterInteractive", nonce: props.nonce }), _jsx(Script, { id: "brandlab-google-tag-config", "data-brandlab-google-tag": "config", strategy: "afterInteractive", nonce: props.nonce, dangerouslySetInnerHTML: { __html: plan.inlineScript } })] }));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=google-tag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-tag.js","sourceRoot":"","sources":["../src/google-tag.tsx"],"names":[],"mappings":";AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,EACL,2BAA2B,GAE5B,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACL,2BAA2B,EAC3B,8BAA8B,GAC/B,MAAM,sBAAsB,CAAA;AAY7B;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAA6B;IAC7D,MAAM,IAAI,GAAG,2BAA2B,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,CAAA;IAClE,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAA;IACtB,OAAO,CACL,8BACE,KAAC,MAAM,IACL,EAAE,EAAC,4BAA4B,8BACN,QAAQ,EACjC,GAAG,EAAE,IAAI,CAAC,MAAM,EAChB,QAAQ,EAAC,kBAAkB,EAC3B,KAAK,EAAE,KAAK,CAAC,KAAK,GAClB,EACF,KAAC,MAAM,IACL,EAAE,EAAC,4BAA4B,8BACN,QAAQ,EACjC,QAAQ,EAAC,kBAAkB,EAC3B,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,uBAAuB,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,GACtD,IACD,CACJ,CAAA;AACH,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ContactAttributionSummary } from '@brandlab-digital/site-core/contact';
|
|
1
2
|
export type PhoneCallLocation = 'header' | 'footer' | 'hero' | 'cta' | 'fab' | 'contact' | 'location' | 'page';
|
|
2
3
|
export interface LastPhoneCallEvent {
|
|
3
4
|
key: string;
|
|
@@ -15,6 +16,7 @@ export declare function shouldTrackPhoneCallClick(options: {
|
|
|
15
16
|
}): boolean;
|
|
16
17
|
export declare function persistInitialLanding(win?: Window): void;
|
|
17
18
|
export declare function getInitialLandingPath(win?: Window): string | undefined;
|
|
19
|
+
export declare function getInitialContactAttribution(win?: Window): ContactAttributionSummary;
|
|
18
20
|
export declare function getPhoneCallLocation(link: HTMLAnchorElement): PhoneCallLocation;
|
|
19
21
|
export declare function installPhoneClickListener(options: {
|
|
20
22
|
trackPhoneCall: (context: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation-client.d.ts","sourceRoot":"","sources":["../src/instrumentation-client.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GACzB,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,KAAK,GACL,KAAK,GACL,SAAS,GACT,UAAU,GACV,MAAM,CAAA;AAEV,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,EAAE,EAAE,MAAM,CAAA;CACX;AAED,eAAO,MAAM,8BAA8B,6BAA6B,CAAA;AACxE,eAAO,MAAM,mCAAmC,OAAO,CAAA;AAEvD,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,UAe9E;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAEtE;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE;IACjD,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,kBAAkB,CAAA;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,WAOA;AAED,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,MAAe,
|
|
1
|
+
{"version":3,"file":"instrumentation-client.d.ts","sourceRoot":"","sources":["../src/instrumentation-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,qCAAqC,CAAA;AAM5C,MAAM,MAAM,iBAAiB,GACzB,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,KAAK,GACL,KAAK,GACL,SAAS,GACT,UAAU,GACV,MAAM,CAAA;AAEV,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,EAAE,EAAE,MAAM,CAAA;CACX;AAED,eAAO,MAAM,8BAA8B,6BAA6B,CAAA;AACxE,eAAO,MAAM,mCAAmC,OAAO,CAAA;AAEvD,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,UAe9E;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAEtE;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE;IACjD,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,kBAAkB,CAAA;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,WAOA;AAED,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,MAAe,QAgCzD;AAED,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,MAAe,sBAOzD;AAED,wBAAgB,4BAA4B,CAAC,GAAG,GAAE,MAAe,GAAG,yBAAyB,CAkB5F;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,iBAAiB,CAU/E;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE;IACjD,cAAc,EAAE,CAAC,OAAO,EAAE;QACxB,QAAQ,EAAE,MAAM,CAAA;QAChB,QAAQ,EAAE,iBAAiB,CAAA;QAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAA;KAC5B,KAAK,IAAI,CAAA;IACV,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,cAwCA"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isContactVisitSource, } from '@brandlab-digital/site-core/contact';
|
|
2
|
+
import { classifyContactAttribution, normalizeContactAttributionSummary, } from './contact/attribution.js';
|
|
1
3
|
export const INITIAL_LANDING_STORAGE_PREFIX = 'brandlab.initialLanding.';
|
|
2
4
|
export const DEFAULT_PHONE_CALL_DEDUPE_WINDOW_MS = 1200;
|
|
3
5
|
export function normalizeInitialLandingPath(pathname) {
|
|
@@ -25,11 +27,29 @@ export function shouldTrackPhoneCallClick(options) {
|
|
|
25
27
|
}
|
|
26
28
|
export function persistInitialLanding(win = window) {
|
|
27
29
|
try {
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
+
const pathKey = `${INITIAL_LANDING_STORAGE_PREFIX}path`;
|
|
31
|
+
const sourceKey = `${INITIAL_LANDING_STORAGE_PREFIX}source`;
|
|
32
|
+
const detailKey = `${INITIAL_LANDING_STORAGE_PREFIX}sourceDetail`;
|
|
33
|
+
const existingPath = win.sessionStorage.getItem(pathKey);
|
|
30
34
|
const safePath = normalizeInitialLandingPath(existingPath ?? win.location.pathname);
|
|
31
35
|
if (existingPath !== safePath) {
|
|
32
|
-
win.sessionStorage.setItem(
|
|
36
|
+
win.sessionStorage.setItem(pathKey, safePath);
|
|
37
|
+
}
|
|
38
|
+
const existingSource = win.sessionStorage.getItem(sourceKey);
|
|
39
|
+
if (!isContactVisitSource(existingSource)) {
|
|
40
|
+
const attribution = classifyContactAttribution({
|
|
41
|
+
initialLandingPath: safePath,
|
|
42
|
+
search: win.location.search,
|
|
43
|
+
referrer: win.document.referrer,
|
|
44
|
+
siteOrigin: win.location.origin,
|
|
45
|
+
});
|
|
46
|
+
win.sessionStorage.setItem(sourceKey, attribution.visitSource);
|
|
47
|
+
if (attribution.visitSourceDetail) {
|
|
48
|
+
win.sessionStorage.setItem(detailKey, attribution.visitSourceDetail);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
win.sessionStorage.removeItem(detailKey);
|
|
52
|
+
}
|
|
33
53
|
}
|
|
34
54
|
// Remove values written by the pre-RC privacy contract. Query strings and
|
|
35
55
|
// referrers are not needed for canonical lead measurement.
|
|
@@ -49,6 +69,22 @@ export function getInitialLandingPath(win = window) {
|
|
|
49
69
|
return undefined;
|
|
50
70
|
}
|
|
51
71
|
}
|
|
72
|
+
export function getInitialContactAttribution(win = window) {
|
|
73
|
+
const fallbackPath = normalizeInitialLandingPath(win.location.pathname);
|
|
74
|
+
try {
|
|
75
|
+
const initialLandingPath = normalizeInitialLandingPath(win.sessionStorage.getItem(`${INITIAL_LANDING_STORAGE_PREFIX}path`) ?? fallbackPath);
|
|
76
|
+
const visitSource = win.sessionStorage.getItem(`${INITIAL_LANDING_STORAGE_PREFIX}source`);
|
|
77
|
+
const visitSourceDetail = win.sessionStorage.getItem(`${INITIAL_LANDING_STORAGE_PREFIX}sourceDetail`);
|
|
78
|
+
return normalizeContactAttributionSummary({
|
|
79
|
+
initialLandingPath,
|
|
80
|
+
visitSource: isContactVisitSource(visitSource) ? visitSource : 'direct-or-unknown',
|
|
81
|
+
...(visitSourceDetail ? { visitSourceDetail } : {}),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return { initialLandingPath: fallbackPath, visitSource: 'direct-or-unknown' };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
52
88
|
export function getPhoneCallLocation(link) {
|
|
53
89
|
const explicitLocation = link.dataset.phoneLocation;
|
|
54
90
|
if (explicitLocation)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation-client.js","sourceRoot":"","sources":["../src/instrumentation-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"instrumentation-client.js","sourceRoot":"","sources":["../src/instrumentation-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import 'server-only';
|
|
2
|
+
export interface BrandlabAtomicRedisClient {
|
|
3
|
+
eval(script: string, keys: readonly string[], args: readonly (string | number)[]): Promise<unknown>;
|
|
4
|
+
}
|
|
5
|
+
/** Shared server-only Upstash REST boundary used by Brandlab durable runtimes. */
|
|
6
|
+
export declare function createBrandlabUpstashRedisEvalClient(options: {
|
|
7
|
+
url: string;
|
|
8
|
+
token: string;
|
|
9
|
+
fetcher?: typeof fetch;
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
}): BrandlabAtomicRedisClient;
|
|
12
|
+
//# sourceMappingURL=redis-rest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-rest.d.ts","sourceRoot":"","sources":["../src/redis-rest.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAKpB,MAAM,WAAW,yBAAyB;IACxC,IAAI,CACF,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GACjC,OAAO,CAAC,OAAO,CAAC,CAAA;CACpB;AAwBD,kFAAkF;AAClF,wBAAgB,oCAAoC,CAAC,OAAO,EAAE;IAC5D,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,GAAG,yBAAyB,CAyD5B"}
|