Skip to content

Commit fb1c4d6

Browse files
authored
Merge branch 'main' into otelmewhatyouwant
2 parents 974b534 + 513df96 commit fb1c4d6

35 files changed

+816
-284
lines changed

.release-please-manifest.json

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
{
2-
"packages/blobs": "10.0.6",
3-
"packages/cache": "3.0.7",
4-
"packages/dev": "4.4.5",
5-
"packages/dev-utils": "4.0.0",
6-
"packages/edge-functions": "2.16.1",
7-
"packages/functions": "4.1.13",
8-
"packages/headers": "2.0.6",
9-
"packages/images": "1.2.2",
10-
"packages/nuxt-module": "0.1.5",
2+
"packages/blobs": "10.0.7",
3+
"packages/cache": "3.0.8",
4+
"packages/dev": "4.5.0",
5+
"packages/dev-utils": "4.1.0",
6+
"packages/edge-functions": "2.16.2",
7+
"packages/functions": "4.1.15",
8+
"packages/headers": "2.0.7",
9+
"packages/images": "1.2.3",
10+
"packages/nuxt-module": "0.1.7",
1111
"packages/otel": "3.1.0",
12-
"packages/redirects": "3.0.6",
13-
"packages/runtime": "4.0.10",
12+
"packages/redirects": "3.0.7",
13+
"packages/runtime": "4.0.11",
1414
"packages/runtime-utils": "2.1.0",
15-
"packages/static": "3.0.6",
15+
"packages/static": "3.0.7",
1616
"packages/types": "2.0.2",
17-
"packages/vite-plugin": "2.4.5"
17+
"packages/vite-plugin": "2.5.0"
1818
}

eslint.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ export default tseslint.config(
119119
},
120120
],
121121
'n/no-unsupported-features/node-builtins': 'off',
122+
123+
// Disable unsafe assignment for test files due to vitest expect matchers returning `any`
124+
// See: https://github.com/vitest-dev/vitest/issues/7015
125+
'@typescript-eslint/no-unsafe-assignment': 'off',
122126
},
123127
},
124128

package-lock.json

Lines changed: 221 additions & 228 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/blobs/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## [10.0.7](https://github.com/netlify/primitives/compare/blobs-v10.0.6...blobs-v10.0.7) (2025-07-23)
4+
5+
6+
### Dependencies
7+
8+
* The following workspace dependencies were updated
9+
* dependencies
10+
* @netlify/dev-utils bumped from 4.0.0 to 4.1.0
11+
312
## [10.0.6](https://github.com/netlify/primitives/compare/blobs-v10.0.5...blobs-v10.0.6) (2025-07-17)
413

514

packages/blobs/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@netlify/blobs",
3-
"version": "10.0.6",
3+
"version": "10.0.7",
44
"description": "TypeScript client for Netlify Blobs",
55
"type": "module",
66
"engines": {
@@ -76,7 +76,7 @@
7676
"vitest": "^3.0.0"
7777
},
7878
"dependencies": {
79-
"@netlify/dev-utils": "4.0.0",
79+
"@netlify/dev-utils": "4.1.0",
8080
"@netlify/runtime-utils": "2.1.0"
8181
}
8282
}

packages/cache/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## [3.0.8](https://github.com/netlify/primitives/compare/cache-v3.0.7...cache-v3.0.8) (2025-07-23)
4+
5+
6+
### Dependencies
7+
8+
* The following workspace dependencies were updated
9+
* devDependencies
10+
* @netlify/dev-utils bumped from 4.0.0 to 4.1.0
11+
312
## [3.0.7](https://github.com/netlify/primitives/compare/cache-v3.0.6...cache-v3.0.7) (2025-07-17)
413

514

packages/cache/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@netlify/cache",
3-
"version": "3.0.7",
3+
"version": "3.0.8",
44
"description": "TypeScript utilities for interacting with the Netlify cache",
55
"type": "module",
66
"engines": {
@@ -68,7 +68,7 @@
6868
},
6969
"author": "Netlify Inc.",
7070
"devDependencies": {
71-
"@netlify/dev-utils": "4.0.0",
71+
"@netlify/dev-utils": "4.1.0",
7272
"@netlify/types": "2.0.2",
7373
"npm-run-all2": "^7.0.2",
7474
"tsup": "^8.0.0",

packages/dev-utils/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## [4.1.0](https://github.com/netlify/primitives/compare/dev-utils-v4.0.0...dev-utils-v4.1.0) (2025-07-23)
4+
5+
6+
### Features
7+
8+
* add actual dev geolocation to functions and edge functions context ([#345](https://github.com/netlify/primitives/issues/345)) ([916c38b](https://github.com/netlify/primitives/commit/916c38b84632b705a1d6ab4bfc6d60bfebd1ed2c))
9+
310
## [4.0.0](https://github.com/netlify/primitives/compare/dev-utils-v3.3.0...dev-utils-v4.0.0) (2025-07-17)
411

512

packages/dev-utils/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@netlify/dev-utils",
3-
"version": "4.0.0",
3+
"version": "4.1.0",
44
"description": "TypeScript utilities for the local emulation of the Netlify environment",
55
"type": "module",
66
"engines": {
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
import { describe, expect, test, vi, beforeEach, afterEach } from 'vitest'
2+
import type { MockedFunction } from 'vitest'
3+
4+
import { getGeoLocation, mockLocation } from './geo-location.js'
5+
import { MockFetch } from '../test/fetch.js'
6+
7+
describe('geolocation', () => {
8+
let mockState: {
9+
get: MockedFunction<(key: string) => unknown>
10+
set: MockedFunction<(key: string, value: unknown) => void>
11+
}
12+
let mockFetch: MockFetch
13+
14+
beforeEach(() => {
15+
vi.clearAllMocks()
16+
mockState = {
17+
get: vi.fn(),
18+
set: vi.fn(),
19+
}
20+
mockFetch = new MockFetch()
21+
})
22+
23+
afterEach(() => {
24+
mockFetch.restore()
25+
})
26+
27+
describe('getGeoLocation', () => {
28+
test('returns mock location when enabled is false', async () => {
29+
const result = await getGeoLocation({
30+
enabled: false,
31+
state: mockState,
32+
})
33+
34+
expect(result).toEqual(mockLocation)
35+
expect(mockState.get).not.toHaveBeenCalled()
36+
expect(mockState.set).not.toHaveBeenCalled()
37+
expect(mockFetch.fulfilled).toBe(true)
38+
})
39+
40+
test('returns cached data when cache is enabled and data is fresh', async () => {
41+
const cachedData = {
42+
city: 'Cached City',
43+
country: { code: 'CA', name: 'Canada' },
44+
subdivision: { code: 'ON', name: 'Ontario' },
45+
longitude: -79.3832,
46+
latitude: 43.6532,
47+
timezone: 'America/Toronto',
48+
}
49+
50+
mockState.get.mockReturnValue({
51+
data: cachedData,
52+
timestamp: Date.now() - 1000 * 60 * 60, // 1 hour ago
53+
})
54+
55+
const result = await getGeoLocation({
56+
enabled: true,
57+
cache: true,
58+
state: mockState,
59+
})
60+
61+
expect(result).toEqual(cachedData)
62+
expect(mockState.get).toHaveBeenCalledWith('geolocation')
63+
expect(mockFetch.fulfilled).toBe(true)
64+
})
65+
66+
test('fetches new data when cache is enabled but data is stale', async () => {
67+
const staleData = {
68+
city: 'Stale City',
69+
country: { code: 'CA', name: 'Canada' },
70+
subdivision: { code: 'ON', name: 'Ontario' },
71+
longitude: -79.3832,
72+
latitude: 43.6532,
73+
timezone: 'America/Toronto',
74+
}
75+
76+
const freshData = {
77+
city: 'Fresh City',
78+
country: { code: 'US', name: 'United States' },
79+
subdivision: { code: 'NY', name: 'New York' },
80+
longitude: -74.006,
81+
latitude: 40.7128,
82+
timezone: 'America/New_York',
83+
}
84+
85+
mockState.get.mockReturnValue({
86+
data: staleData,
87+
timestamp: Date.now() - 1000 * 60 * 60 * 25, // 25 hours ago (stale)
88+
})
89+
90+
mockFetch
91+
.get({
92+
url: 'https://netlifind.netlify.app',
93+
response: new Response(JSON.stringify({ geo: freshData }), {
94+
headers: { 'Content-Type': 'application/json' },
95+
}),
96+
})
97+
.inject()
98+
99+
const result = await getGeoLocation({
100+
enabled: true,
101+
cache: true,
102+
state: mockState,
103+
})
104+
105+
expect(result).toEqual(freshData)
106+
expect(mockState.get).toHaveBeenCalledWith('geolocation')
107+
expect(mockState.set).toHaveBeenCalledWith('geolocation', {
108+
data: freshData,
109+
timestamp: expect.any(Number),
110+
})
111+
expect(mockFetch.fulfilled).toBe(true)
112+
})
113+
114+
test('always fetches new data when cache is disabled', async () => {
115+
const cachedData = {
116+
city: 'Cached City',
117+
country: { code: 'CA', name: 'Canada' },
118+
subdivision: { code: 'ON', name: 'Ontario' },
119+
longitude: -79.3832,
120+
latitude: 43.6532,
121+
timezone: 'America/Toronto',
122+
}
123+
124+
const freshData = {
125+
city: 'Fresh City',
126+
country: { code: 'US', name: 'United States' },
127+
subdivision: { code: 'NY', name: 'New York' },
128+
longitude: -74.006,
129+
latitude: 40.7128,
130+
timezone: 'America/New_York',
131+
}
132+
133+
mockState.get.mockReturnValue({
134+
data: cachedData,
135+
timestamp: Date.now() - 1000 * 60 * 60, // 1 hour ago (fresh)
136+
})
137+
138+
mockFetch
139+
.get({
140+
url: 'https://netlifind.netlify.app',
141+
response: new Response(JSON.stringify({ geo: freshData }), {
142+
headers: { 'Content-Type': 'application/json' },
143+
}),
144+
})
145+
.inject()
146+
147+
const result = await getGeoLocation({
148+
enabled: true,
149+
cache: false,
150+
state: mockState,
151+
})
152+
153+
expect(result).toEqual(freshData)
154+
expect(mockState.set).toHaveBeenCalledWith('geolocation', {
155+
data: freshData,
156+
timestamp: expect.any(Number),
157+
})
158+
expect(mockFetch.fulfilled).toBe(true)
159+
})
160+
161+
test('returns mock location when API request fails', async () => {
162+
mockState.get.mockReturnValue(undefined)
163+
164+
mockFetch
165+
.get({
166+
url: 'https://netlifind.netlify.app',
167+
response: new Error('Network error'),
168+
})
169+
.inject()
170+
171+
const result = await getGeoLocation({
172+
enabled: true,
173+
cache: false,
174+
state: mockState,
175+
})
176+
177+
expect(result).toEqual(mockLocation)
178+
expect(mockFetch.fulfilled).toBe(true)
179+
})
180+
})
181+
})

0 commit comments

Comments
 (0)