@contentful/field-editor-shared 2.17.0-alpha.0 → 2.17.1-alpha.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.
- package/dist/cjs/index.js +10 -0
- package/dist/cjs/queryClient.js +117 -0
- package/dist/cjs/utils/entityHelpers.js +2 -4
- package/dist/cjs/utils/entityHelpers.test.js +69 -48
- package/dist/esm/index.js +1 -0
- package/dist/esm/queryClient.js +55 -0
- package/dist/esm/utils/entityHelpers.js +2 -4
- package/dist/esm/utils/entityHelpers.test.js +69 -48
- package/dist/types/index.d.ts +1 -0
- package/dist/types/queryClient.d.ts +9 -0
- package/dist/types/utils/entityHelpers.d.ts +2 -2
- package/package.json +9 -2
package/dist/cjs/index.js
CHANGED
|
@@ -75,6 +75,9 @@ _export(exports, {
|
|
|
75
75
|
PredefinedValuesError: function() {
|
|
76
76
|
return _PredefinedValuesError.PredefinedValuesError;
|
|
77
77
|
},
|
|
78
|
+
SharedQueryClientProvider: function() {
|
|
79
|
+
return _queryClient.SharedQueryClientProvider;
|
|
80
|
+
},
|
|
78
81
|
SpaceAPI: function() {
|
|
79
82
|
return _appsdk.SpaceAPI;
|
|
80
83
|
},
|
|
@@ -92,6 +95,12 @@ _export(exports, {
|
|
|
92
95
|
},
|
|
93
96
|
toLocaleString: function() {
|
|
94
97
|
return _shortenStorageUnit.toLocaleString;
|
|
98
|
+
},
|
|
99
|
+
useQuery: function() {
|
|
100
|
+
return _queryClient.useQuery;
|
|
101
|
+
},
|
|
102
|
+
useQueryClient: function() {
|
|
103
|
+
return _queryClient.useQueryClient;
|
|
95
104
|
}
|
|
96
105
|
});
|
|
97
106
|
const _ModalDialogLauncher = /*#__PURE__*/ _interop_require_wildcard(require("./ModalDialogLauncher"));
|
|
@@ -113,6 +122,7 @@ _export_star(require("./ReleaseEntityStatusBadge"), exports);
|
|
|
113
122
|
_export_star(require("./utils/determineReleaseAction"), exports);
|
|
114
123
|
_export_star(require("./utils/getEntityReleaseStatus"), exports);
|
|
115
124
|
_export_star(require("./utils/getReleaseStatusBadgeConfig"), exports);
|
|
125
|
+
const _queryClient = require("./queryClient");
|
|
116
126
|
function _export_star(from, to) {
|
|
117
127
|
Object.keys(from).forEach(function(k) {
|
|
118
128
|
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: all[name]
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
SharedQueryClientProvider: function() {
|
|
13
|
+
return SharedQueryClientProvider;
|
|
14
|
+
},
|
|
15
|
+
useQuery: function() {
|
|
16
|
+
return useQuery;
|
|
17
|
+
},
|
|
18
|
+
useQueryClient: function() {
|
|
19
|
+
return useQueryClient;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
|
|
23
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
24
|
+
if (typeof WeakMap !== "function") return null;
|
|
25
|
+
var cacheBabelInterop = new WeakMap();
|
|
26
|
+
var cacheNodeInterop = new WeakMap();
|
|
27
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
28
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
29
|
+
})(nodeInterop);
|
|
30
|
+
}
|
|
31
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
32
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
33
|
+
return obj;
|
|
34
|
+
}
|
|
35
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
36
|
+
return {
|
|
37
|
+
default: obj
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
41
|
+
if (cache && cache.has(obj)) {
|
|
42
|
+
return cache.get(obj);
|
|
43
|
+
}
|
|
44
|
+
var newObj = {
|
|
45
|
+
__proto__: null
|
|
46
|
+
};
|
|
47
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
48
|
+
for(var key in obj){
|
|
49
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
50
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
51
|
+
if (desc && (desc.get || desc.set)) {
|
|
52
|
+
Object.defineProperty(newObj, key, desc);
|
|
53
|
+
} else {
|
|
54
|
+
newObj[key] = obj[key];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
newObj.default = obj;
|
|
59
|
+
if (cache) {
|
|
60
|
+
cache.set(obj, newObj);
|
|
61
|
+
}
|
|
62
|
+
return newObj;
|
|
63
|
+
}
|
|
64
|
+
let QueryClient;
|
|
65
|
+
let useRQ;
|
|
66
|
+
let useHostQueryClient = ()=>undefined;
|
|
67
|
+
try {
|
|
68
|
+
const rq = require('@tanstack/react-query');
|
|
69
|
+
QueryClient = rq.QueryClient;
|
|
70
|
+
useRQ = rq.useQuery;
|
|
71
|
+
useHostQueryClient = rq.useQueryClient;
|
|
72
|
+
} catch {}
|
|
73
|
+
const clientContext = /*#__PURE__*/ _react.createContext(undefined);
|
|
74
|
+
function useMaybeHostQueryClient() {
|
|
75
|
+
try {
|
|
76
|
+
return useHostQueryClient();
|
|
77
|
+
} catch {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function useQueryClient() {
|
|
82
|
+
const client = _react.useContext(clientContext);
|
|
83
|
+
const hostClient = useMaybeHostQueryClient();
|
|
84
|
+
return _react.useMemo(()=>{
|
|
85
|
+
if (client) {
|
|
86
|
+
return client;
|
|
87
|
+
}
|
|
88
|
+
if (hostClient) return hostClient;
|
|
89
|
+
return new QueryClient({
|
|
90
|
+
defaultOptions: {
|
|
91
|
+
queries: {
|
|
92
|
+
useErrorBoundary: false,
|
|
93
|
+
refetchOnWindowFocus: false,
|
|
94
|
+
refetchOnReconnect: true,
|
|
95
|
+
refetchOnMount: false,
|
|
96
|
+
staleTime: Infinity,
|
|
97
|
+
retry: false
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}, [
|
|
102
|
+
client,
|
|
103
|
+
hostClient
|
|
104
|
+
]);
|
|
105
|
+
}
|
|
106
|
+
function useQuery(queryKey, queryFn, options) {
|
|
107
|
+
return useRQ(queryKey, queryFn, {
|
|
108
|
+
...options,
|
|
109
|
+
context: clientContext
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function SharedQueryClientProvider({ children }) {
|
|
113
|
+
const client = useQueryClient();
|
|
114
|
+
return /*#__PURE__*/ _react.createElement(clientContext.Provider, {
|
|
115
|
+
value: client
|
|
116
|
+
}, children);
|
|
117
|
+
}
|
|
@@ -239,14 +239,12 @@ const getEntryImage = async ({ entry, contentType, localeCode }, getAsset)=>{
|
|
|
239
239
|
return null;
|
|
240
240
|
}
|
|
241
241
|
};
|
|
242
|
-
const DOWNLOADS_ENDPOINT = 'downloads.ctfassets.net';
|
|
243
|
-
const TRANSFORMATIONS_ENDPOINT = 'images.ctfassets.net';
|
|
244
242
|
const getResolvedImageUrl = (url, params)=>{
|
|
245
243
|
try {
|
|
246
244
|
const urlToParse = url.startsWith('//') ? `https:${url}` : url;
|
|
247
245
|
const parsedUrl = new URL(urlToParse);
|
|
248
|
-
if (parsedUrl.hostname
|
|
249
|
-
parsedUrl.hostname =
|
|
246
|
+
if (parsedUrl.hostname.startsWith('downloads.')) {
|
|
247
|
+
parsedUrl.hostname = parsedUrl.hostname.replace(/^downloads\./, 'images.');
|
|
250
248
|
}
|
|
251
249
|
if (params) {
|
|
252
250
|
Object.entries(params).forEach(([key, value])=>{
|
|
@@ -151,72 +151,72 @@ describe('getEntityStatus', ()=>{
|
|
|
151
151
|
});
|
|
152
152
|
describe('getResolvedImageUrl', ()=>{
|
|
153
153
|
describe('URL parsing and domain replacement', ()=>{
|
|
154
|
-
test('replaces downloads
|
|
155
|
-
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.
|
|
156
|
-
expect(result).toBe('https://images.
|
|
154
|
+
test('replaces downloads.* with images.*', ()=>{
|
|
155
|
+
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.example.com/space/asset.jpg');
|
|
156
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg');
|
|
157
157
|
});
|
|
158
158
|
test('handles protocol-relative URLs', ()=>{
|
|
159
|
-
const result = (0, _entityHelpers.getResolvedImageUrl)('//downloads.
|
|
160
|
-
expect(result).toBe('//images.
|
|
159
|
+
const result = (0, _entityHelpers.getResolvedImageUrl)('//downloads.example.com/space/asset.jpg');
|
|
160
|
+
expect(result).toBe('//images.example.com/space/asset.jpg');
|
|
161
161
|
});
|
|
162
|
-
test('does not modify URLs that
|
|
162
|
+
test('does not modify URLs that do not start with downloads.', ()=>{
|
|
163
163
|
const result = (0, _entityHelpers.getResolvedImageUrl)('https://example.com/image.jpg');
|
|
164
164
|
expect(result).toBe('https://example.com/image.jpg');
|
|
165
165
|
});
|
|
166
|
-
test('does not modify images
|
|
167
|
-
const result = (0, _entityHelpers.getResolvedImageUrl)('https://images.
|
|
168
|
-
expect(result).toBe('https://images.
|
|
166
|
+
test('does not modify images.* URLs', ()=>{
|
|
167
|
+
const result = (0, _entityHelpers.getResolvedImageUrl)('https://images.example.com/space/asset.jpg');
|
|
168
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg');
|
|
169
169
|
});
|
|
170
170
|
});
|
|
171
171
|
describe('query parameters', ()=>{
|
|
172
172
|
test('adds width parameter', ()=>{
|
|
173
|
-
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.
|
|
174
|
-
|
|
173
|
+
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.example.com/space/asset.jpg', {
|
|
174
|
+
w: 100
|
|
175
175
|
});
|
|
176
|
-
expect(result).toBe('https://images.
|
|
176
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg?w=100');
|
|
177
177
|
});
|
|
178
178
|
test('adds height parameter', ()=>{
|
|
179
|
-
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.
|
|
180
|
-
|
|
179
|
+
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.example.com/space/asset.jpg', {
|
|
180
|
+
h: 200
|
|
181
181
|
});
|
|
182
|
-
expect(result).toBe('https://images.
|
|
182
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg?h=200');
|
|
183
183
|
});
|
|
184
184
|
test('adds fit parameter', ()=>{
|
|
185
|
-
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.
|
|
185
|
+
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.example.com/space/asset.jpg', {
|
|
186
186
|
fit: 'thumb'
|
|
187
187
|
});
|
|
188
|
-
expect(result).toBe('https://images.
|
|
188
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg?fit=thumb');
|
|
189
189
|
});
|
|
190
190
|
test('adds multiple parameters', ()=>{
|
|
191
|
-
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.example.com/space/asset.jpg', {
|
|
192
|
+
w: 100,
|
|
193
|
+
h: 200,
|
|
194
194
|
fit: 'thumb'
|
|
195
195
|
});
|
|
196
|
-
expect(result).toContain('
|
|
197
|
-
expect(result).toContain('
|
|
196
|
+
expect(result).toContain('w=100');
|
|
197
|
+
expect(result).toContain('h=200');
|
|
198
198
|
expect(result).toContain('fit=thumb');
|
|
199
|
-
expect(result).toContain('images.
|
|
199
|
+
expect(result).toContain('images.example.com');
|
|
200
200
|
});
|
|
201
201
|
test('skips undefined parameters', ()=>{
|
|
202
|
-
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.
|
|
203
|
-
|
|
204
|
-
|
|
202
|
+
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.example.com/space/asset.jpg', {
|
|
203
|
+
w: 100,
|
|
204
|
+
h: undefined,
|
|
205
205
|
fit: 'thumb'
|
|
206
206
|
});
|
|
207
|
-
expect(result).toBe('https://images.
|
|
207
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg?w=100&fit=thumb');
|
|
208
208
|
});
|
|
209
209
|
test('returns URL without query string when no params provided', ()=>{
|
|
210
|
-
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.
|
|
211
|
-
expect(result).toBe('https://images.
|
|
210
|
+
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.example.com/space/asset.jpg');
|
|
211
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg');
|
|
212
212
|
});
|
|
213
213
|
test('returns URL without query string when all params are undefined', ()=>{
|
|
214
|
-
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.
|
|
215
|
-
|
|
216
|
-
|
|
214
|
+
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.example.com/space/asset.jpg', {
|
|
215
|
+
w: undefined,
|
|
216
|
+
h: undefined,
|
|
217
217
|
fit: undefined
|
|
218
218
|
});
|
|
219
|
-
expect(result).toBe('https://images.
|
|
219
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg');
|
|
220
220
|
});
|
|
221
221
|
});
|
|
222
222
|
describe('relative URL fallback', ()=>{
|
|
@@ -226,41 +226,62 @@ describe('getResolvedImageUrl', ()=>{
|
|
|
226
226
|
});
|
|
227
227
|
test('appends query params to relative URLs', ()=>{
|
|
228
228
|
const result = (0, _entityHelpers.getResolvedImageUrl)('/assets/image.jpg', {
|
|
229
|
-
|
|
230
|
-
|
|
229
|
+
w: 100,
|
|
230
|
+
h: 200
|
|
231
231
|
});
|
|
232
|
-
expect(result).toBe('/assets/image.jpg?
|
|
232
|
+
expect(result).toBe('/assets/image.jpg?w=100&h=200');
|
|
233
233
|
});
|
|
234
234
|
test('handles relative URLs with undefined params', ()=>{
|
|
235
235
|
const result = (0, _entityHelpers.getResolvedImageUrl)('/assets/image.jpg', {
|
|
236
|
-
|
|
237
|
-
|
|
236
|
+
w: 100,
|
|
237
|
+
h: undefined
|
|
238
238
|
});
|
|
239
|
-
expect(result).toBe('/assets/image.jpg?
|
|
239
|
+
expect(result).toBe('/assets/image.jpg?w=100');
|
|
240
240
|
});
|
|
241
241
|
test('returns relative URL unchanged when all params are undefined', ()=>{
|
|
242
242
|
const result = (0, _entityHelpers.getResolvedImageUrl)('/assets/image.jpg', {
|
|
243
|
-
|
|
244
|
-
|
|
243
|
+
w: undefined,
|
|
244
|
+
h: undefined
|
|
245
245
|
});
|
|
246
246
|
expect(result).toBe('/assets/image.jpg');
|
|
247
247
|
});
|
|
248
248
|
});
|
|
249
249
|
describe('edge cases', ()=>{
|
|
250
250
|
test('preserves existing query parameters', ()=>{
|
|
251
|
-
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.
|
|
252
|
-
|
|
251
|
+
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.example.com/space/asset.jpg?foo=bar', {
|
|
252
|
+
w: 100
|
|
253
253
|
});
|
|
254
254
|
expect(result).toContain('foo=bar');
|
|
255
|
-
expect(result).toContain('
|
|
255
|
+
expect(result).toContain('w=100');
|
|
256
256
|
});
|
|
257
257
|
test('handles URLs with fragments', ()=>{
|
|
258
|
-
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.
|
|
259
|
-
|
|
258
|
+
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.example.com/space/asset.jpg#section', {
|
|
259
|
+
w: 100
|
|
260
260
|
});
|
|
261
|
-
expect(result).toContain('images.
|
|
262
|
-
expect(result).toContain('
|
|
261
|
+
expect(result).toContain('images.example.com');
|
|
262
|
+
expect(result).toContain('w=100');
|
|
263
263
|
expect(result).toContain('#section');
|
|
264
264
|
});
|
|
265
265
|
});
|
|
266
|
+
describe('pattern-based domain replacement', ()=>{
|
|
267
|
+
test('replaces any downloads.* domain with images.*', ()=>{
|
|
268
|
+
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.example.com/space/asset.jpg');
|
|
269
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg');
|
|
270
|
+
});
|
|
271
|
+
test('handles protocol-relative downloads URLs', ()=>{
|
|
272
|
+
const result = (0, _entityHelpers.getResolvedImageUrl)('//downloads.example.com/space/asset.jpg');
|
|
273
|
+
expect(result).toBe('//images.example.com/space/asset.jpg');
|
|
274
|
+
});
|
|
275
|
+
test('adds query params to any downloads.* domain', ()=>{
|
|
276
|
+
const result = (0, _entityHelpers.getResolvedImageUrl)('https://downloads.another-example.com/space/asset.jpg', {
|
|
277
|
+
w: 150,
|
|
278
|
+
h: 150,
|
|
279
|
+
fit: 'thumb'
|
|
280
|
+
});
|
|
281
|
+
expect(result).toContain('images.another-example.com');
|
|
282
|
+
expect(result).toContain('w=150');
|
|
283
|
+
expect(result).toContain('h=150');
|
|
284
|
+
expect(result).toContain('fit=thumb');
|
|
285
|
+
});
|
|
286
|
+
});
|
|
266
287
|
});
|
package/dist/esm/index.js
CHANGED
|
@@ -17,3 +17,4 @@ export * from './ReleaseEntityStatusBadge';
|
|
|
17
17
|
export * from './utils/determineReleaseAction';
|
|
18
18
|
export * from './utils/getEntityReleaseStatus';
|
|
19
19
|
export * from './utils/getReleaseStatusBadgeConfig';
|
|
20
|
+
export { SharedQueryClientProvider, useQueryClient, useQuery } from './queryClient';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
let QueryClient;
|
|
3
|
+
let useRQ;
|
|
4
|
+
let useHostQueryClient = ()=>undefined;
|
|
5
|
+
try {
|
|
6
|
+
const rq = require('@tanstack/react-query');
|
|
7
|
+
QueryClient = rq.QueryClient;
|
|
8
|
+
useRQ = rq.useQuery;
|
|
9
|
+
useHostQueryClient = rq.useQueryClient;
|
|
10
|
+
} catch {}
|
|
11
|
+
const clientContext = /*#__PURE__*/ React.createContext(undefined);
|
|
12
|
+
function useMaybeHostQueryClient() {
|
|
13
|
+
try {
|
|
14
|
+
return useHostQueryClient();
|
|
15
|
+
} catch {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function useQueryClient() {
|
|
20
|
+
const client = React.useContext(clientContext);
|
|
21
|
+
const hostClient = useMaybeHostQueryClient();
|
|
22
|
+
return React.useMemo(()=>{
|
|
23
|
+
if (client) {
|
|
24
|
+
return client;
|
|
25
|
+
}
|
|
26
|
+
if (hostClient) return hostClient;
|
|
27
|
+
return new QueryClient({
|
|
28
|
+
defaultOptions: {
|
|
29
|
+
queries: {
|
|
30
|
+
useErrorBoundary: false,
|
|
31
|
+
refetchOnWindowFocus: false,
|
|
32
|
+
refetchOnReconnect: true,
|
|
33
|
+
refetchOnMount: false,
|
|
34
|
+
staleTime: Infinity,
|
|
35
|
+
retry: false
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}, [
|
|
40
|
+
client,
|
|
41
|
+
hostClient
|
|
42
|
+
]);
|
|
43
|
+
}
|
|
44
|
+
export function useQuery(queryKey, queryFn, options) {
|
|
45
|
+
return useRQ(queryKey, queryFn, {
|
|
46
|
+
...options,
|
|
47
|
+
context: clientContext
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
export function SharedQueryClientProvider({ children }) {
|
|
51
|
+
const client = useQueryClient();
|
|
52
|
+
return /*#__PURE__*/ React.createElement(clientContext.Provider, {
|
|
53
|
+
value: client
|
|
54
|
+
}, children);
|
|
55
|
+
}
|
|
@@ -189,14 +189,12 @@ export const getEntryImage = async ({ entry, contentType, localeCode }, getAsset
|
|
|
189
189
|
return null;
|
|
190
190
|
}
|
|
191
191
|
};
|
|
192
|
-
const DOWNLOADS_ENDPOINT = 'downloads.ctfassets.net';
|
|
193
|
-
const TRANSFORMATIONS_ENDPOINT = 'images.ctfassets.net';
|
|
194
192
|
export const getResolvedImageUrl = (url, params)=>{
|
|
195
193
|
try {
|
|
196
194
|
const urlToParse = url.startsWith('//') ? `https:${url}` : url;
|
|
197
195
|
const parsedUrl = new URL(urlToParse);
|
|
198
|
-
if (parsedUrl.hostname
|
|
199
|
-
parsedUrl.hostname =
|
|
196
|
+
if (parsedUrl.hostname.startsWith('downloads.')) {
|
|
197
|
+
parsedUrl.hostname = parsedUrl.hostname.replace(/^downloads\./, 'images.');
|
|
200
198
|
}
|
|
201
199
|
if (params) {
|
|
202
200
|
Object.entries(params).forEach(([key, value])=>{
|
|
@@ -147,72 +147,72 @@ describe('getEntityStatus', ()=>{
|
|
|
147
147
|
});
|
|
148
148
|
describe('getResolvedImageUrl', ()=>{
|
|
149
149
|
describe('URL parsing and domain replacement', ()=>{
|
|
150
|
-
test('replaces downloads
|
|
151
|
-
const result = getResolvedImageUrl('https://downloads.
|
|
152
|
-
expect(result).toBe('https://images.
|
|
150
|
+
test('replaces downloads.* with images.*', ()=>{
|
|
151
|
+
const result = getResolvedImageUrl('https://downloads.example.com/space/asset.jpg');
|
|
152
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg');
|
|
153
153
|
});
|
|
154
154
|
test('handles protocol-relative URLs', ()=>{
|
|
155
|
-
const result = getResolvedImageUrl('//downloads.
|
|
156
|
-
expect(result).toBe('//images.
|
|
155
|
+
const result = getResolvedImageUrl('//downloads.example.com/space/asset.jpg');
|
|
156
|
+
expect(result).toBe('//images.example.com/space/asset.jpg');
|
|
157
157
|
});
|
|
158
|
-
test('does not modify URLs that
|
|
158
|
+
test('does not modify URLs that do not start with downloads.', ()=>{
|
|
159
159
|
const result = getResolvedImageUrl('https://example.com/image.jpg');
|
|
160
160
|
expect(result).toBe('https://example.com/image.jpg');
|
|
161
161
|
});
|
|
162
|
-
test('does not modify images
|
|
163
|
-
const result = getResolvedImageUrl('https://images.
|
|
164
|
-
expect(result).toBe('https://images.
|
|
162
|
+
test('does not modify images.* URLs', ()=>{
|
|
163
|
+
const result = getResolvedImageUrl('https://images.example.com/space/asset.jpg');
|
|
164
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg');
|
|
165
165
|
});
|
|
166
166
|
});
|
|
167
167
|
describe('query parameters', ()=>{
|
|
168
168
|
test('adds width parameter', ()=>{
|
|
169
|
-
const result = getResolvedImageUrl('https://downloads.
|
|
170
|
-
|
|
169
|
+
const result = getResolvedImageUrl('https://downloads.example.com/space/asset.jpg', {
|
|
170
|
+
w: 100
|
|
171
171
|
});
|
|
172
|
-
expect(result).toBe('https://images.
|
|
172
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg?w=100');
|
|
173
173
|
});
|
|
174
174
|
test('adds height parameter', ()=>{
|
|
175
|
-
const result = getResolvedImageUrl('https://downloads.
|
|
176
|
-
|
|
175
|
+
const result = getResolvedImageUrl('https://downloads.example.com/space/asset.jpg', {
|
|
176
|
+
h: 200
|
|
177
177
|
});
|
|
178
|
-
expect(result).toBe('https://images.
|
|
178
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg?h=200');
|
|
179
179
|
});
|
|
180
180
|
test('adds fit parameter', ()=>{
|
|
181
|
-
const result = getResolvedImageUrl('https://downloads.
|
|
181
|
+
const result = getResolvedImageUrl('https://downloads.example.com/space/asset.jpg', {
|
|
182
182
|
fit: 'thumb'
|
|
183
183
|
});
|
|
184
|
-
expect(result).toBe('https://images.
|
|
184
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg?fit=thumb');
|
|
185
185
|
});
|
|
186
186
|
test('adds multiple parameters', ()=>{
|
|
187
|
-
const result = getResolvedImageUrl('https://downloads.
|
|
188
|
-
|
|
189
|
-
|
|
187
|
+
const result = getResolvedImageUrl('https://downloads.example.com/space/asset.jpg', {
|
|
188
|
+
w: 100,
|
|
189
|
+
h: 200,
|
|
190
190
|
fit: 'thumb'
|
|
191
191
|
});
|
|
192
|
-
expect(result).toContain('
|
|
193
|
-
expect(result).toContain('
|
|
192
|
+
expect(result).toContain('w=100');
|
|
193
|
+
expect(result).toContain('h=200');
|
|
194
194
|
expect(result).toContain('fit=thumb');
|
|
195
|
-
expect(result).toContain('images.
|
|
195
|
+
expect(result).toContain('images.example.com');
|
|
196
196
|
});
|
|
197
197
|
test('skips undefined parameters', ()=>{
|
|
198
|
-
const result = getResolvedImageUrl('https://downloads.
|
|
199
|
-
|
|
200
|
-
|
|
198
|
+
const result = getResolvedImageUrl('https://downloads.example.com/space/asset.jpg', {
|
|
199
|
+
w: 100,
|
|
200
|
+
h: undefined,
|
|
201
201
|
fit: 'thumb'
|
|
202
202
|
});
|
|
203
|
-
expect(result).toBe('https://images.
|
|
203
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg?w=100&fit=thumb');
|
|
204
204
|
});
|
|
205
205
|
test('returns URL without query string when no params provided', ()=>{
|
|
206
|
-
const result = getResolvedImageUrl('https://downloads.
|
|
207
|
-
expect(result).toBe('https://images.
|
|
206
|
+
const result = getResolvedImageUrl('https://downloads.example.com/space/asset.jpg');
|
|
207
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg');
|
|
208
208
|
});
|
|
209
209
|
test('returns URL without query string when all params are undefined', ()=>{
|
|
210
|
-
const result = getResolvedImageUrl('https://downloads.
|
|
211
|
-
|
|
212
|
-
|
|
210
|
+
const result = getResolvedImageUrl('https://downloads.example.com/space/asset.jpg', {
|
|
211
|
+
w: undefined,
|
|
212
|
+
h: undefined,
|
|
213
213
|
fit: undefined
|
|
214
214
|
});
|
|
215
|
-
expect(result).toBe('https://images.
|
|
215
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg');
|
|
216
216
|
});
|
|
217
217
|
});
|
|
218
218
|
describe('relative URL fallback', ()=>{
|
|
@@ -222,41 +222,62 @@ describe('getResolvedImageUrl', ()=>{
|
|
|
222
222
|
});
|
|
223
223
|
test('appends query params to relative URLs', ()=>{
|
|
224
224
|
const result = getResolvedImageUrl('/assets/image.jpg', {
|
|
225
|
-
|
|
226
|
-
|
|
225
|
+
w: 100,
|
|
226
|
+
h: 200
|
|
227
227
|
});
|
|
228
|
-
expect(result).toBe('/assets/image.jpg?
|
|
228
|
+
expect(result).toBe('/assets/image.jpg?w=100&h=200');
|
|
229
229
|
});
|
|
230
230
|
test('handles relative URLs with undefined params', ()=>{
|
|
231
231
|
const result = getResolvedImageUrl('/assets/image.jpg', {
|
|
232
|
-
|
|
233
|
-
|
|
232
|
+
w: 100,
|
|
233
|
+
h: undefined
|
|
234
234
|
});
|
|
235
|
-
expect(result).toBe('/assets/image.jpg?
|
|
235
|
+
expect(result).toBe('/assets/image.jpg?w=100');
|
|
236
236
|
});
|
|
237
237
|
test('returns relative URL unchanged when all params are undefined', ()=>{
|
|
238
238
|
const result = getResolvedImageUrl('/assets/image.jpg', {
|
|
239
|
-
|
|
240
|
-
|
|
239
|
+
w: undefined,
|
|
240
|
+
h: undefined
|
|
241
241
|
});
|
|
242
242
|
expect(result).toBe('/assets/image.jpg');
|
|
243
243
|
});
|
|
244
244
|
});
|
|
245
245
|
describe('edge cases', ()=>{
|
|
246
246
|
test('preserves existing query parameters', ()=>{
|
|
247
|
-
const result = getResolvedImageUrl('https://downloads.
|
|
248
|
-
|
|
247
|
+
const result = getResolvedImageUrl('https://downloads.example.com/space/asset.jpg?foo=bar', {
|
|
248
|
+
w: 100
|
|
249
249
|
});
|
|
250
250
|
expect(result).toContain('foo=bar');
|
|
251
|
-
expect(result).toContain('
|
|
251
|
+
expect(result).toContain('w=100');
|
|
252
252
|
});
|
|
253
253
|
test('handles URLs with fragments', ()=>{
|
|
254
|
-
const result = getResolvedImageUrl('https://downloads.
|
|
255
|
-
|
|
254
|
+
const result = getResolvedImageUrl('https://downloads.example.com/space/asset.jpg#section', {
|
|
255
|
+
w: 100
|
|
256
256
|
});
|
|
257
|
-
expect(result).toContain('images.
|
|
258
|
-
expect(result).toContain('
|
|
257
|
+
expect(result).toContain('images.example.com');
|
|
258
|
+
expect(result).toContain('w=100');
|
|
259
259
|
expect(result).toContain('#section');
|
|
260
260
|
});
|
|
261
261
|
});
|
|
262
|
+
describe('pattern-based domain replacement', ()=>{
|
|
263
|
+
test('replaces any downloads.* domain with images.*', ()=>{
|
|
264
|
+
const result = getResolvedImageUrl('https://downloads.example.com/space/asset.jpg');
|
|
265
|
+
expect(result).toBe('https://images.example.com/space/asset.jpg');
|
|
266
|
+
});
|
|
267
|
+
test('handles protocol-relative downloads URLs', ()=>{
|
|
268
|
+
const result = getResolvedImageUrl('//downloads.example.com/space/asset.jpg');
|
|
269
|
+
expect(result).toBe('//images.example.com/space/asset.jpg');
|
|
270
|
+
});
|
|
271
|
+
test('adds query params to any downloads.* domain', ()=>{
|
|
272
|
+
const result = getResolvedImageUrl('https://downloads.another-example.com/space/asset.jpg', {
|
|
273
|
+
w: 150,
|
|
274
|
+
h: 150,
|
|
275
|
+
fit: 'thumb'
|
|
276
|
+
});
|
|
277
|
+
expect(result).toContain('images.another-example.com');
|
|
278
|
+
expect(result).toContain('w=150');
|
|
279
|
+
expect(result).toContain('h=150');
|
|
280
|
+
expect(result).toContain('fit=thumb');
|
|
281
|
+
});
|
|
282
|
+
});
|
|
262
283
|
});
|
package/dist/types/index.d.ts
CHANGED
|
@@ -19,3 +19,4 @@ export * from './ReleaseEntityStatusBadge';
|
|
|
19
19
|
export * from './utils/determineReleaseAction';
|
|
20
20
|
export * from './utils/getEntityReleaseStatus';
|
|
21
21
|
export * from './utils/getReleaseStatusBadgeConfig';
|
|
22
|
+
export { SharedQueryClientProvider, useQueryClient, useQuery } from './queryClient';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { QueryClient as QC, UseQueryOptions, UseQueryResult, QueryKey, QueryFunction } from '@tanstack/react-query';
|
|
3
|
+
export declare function useQueryClient(): QC;
|
|
4
|
+
export declare function useQuery<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(queryKey: TQueryKey, queryFn: QueryFunction<TQueryFnData, TQueryKey>, options?: Omit<UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>, 'queryKey' | 'queryFn'>): UseQueryResult<TData, TError>;
|
|
5
|
+
/**
|
|
6
|
+
* Provides access to a query client either by sharing an existing client or
|
|
7
|
+
* creating a new one.
|
|
8
|
+
*/
|
|
9
|
+
export declare function SharedQueryClientProvider({ children }: React.PropsWithChildren<{}>): React.JSX.Element;
|
|
@@ -82,8 +82,8 @@ export declare const getEntryImage: ({ entry, contentType, localeCode, }: {
|
|
|
82
82
|
defaultLocaleCode: string;
|
|
83
83
|
}, getAsset: (assetId: string) => Promise<unknown>) => Promise<null | File>;
|
|
84
84
|
export declare const getResolvedImageUrl: (url: string, params?: {
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
w?: number;
|
|
86
|
+
h?: number;
|
|
87
87
|
fit?: string;
|
|
88
88
|
}) => string;
|
|
89
89
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/field-editor-shared",
|
|
3
|
-
"version": "2.17.
|
|
3
|
+
"version": "2.17.1-alpha.0",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"types": "dist/types/index.d.ts",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"@contentful/app-sdk": "^4.42.0",
|
|
40
40
|
"@contentful/field-editor-test-utils": "^1.7.0",
|
|
41
41
|
"@lingui/core": "5.3.0",
|
|
42
|
+
"@tanstack/react-query": "^4.3.9",
|
|
42
43
|
"@testing-library/react": "16.3.0"
|
|
43
44
|
},
|
|
44
45
|
"dependencies": {
|
|
@@ -54,11 +55,17 @@
|
|
|
54
55
|
"peerDependencies": {
|
|
55
56
|
"@contentful/app-sdk": "^4.29.0",
|
|
56
57
|
"@lingui/core": "^5.3.0",
|
|
58
|
+
"@tanstack/react-query": "^4.3.9",
|
|
57
59
|
"react": ">=16.8.0",
|
|
58
60
|
"react-dom": ">=16.8.0"
|
|
59
61
|
},
|
|
62
|
+
"peerDependenciesMeta": {
|
|
63
|
+
"@tanstack/react-query": {
|
|
64
|
+
"optional": true
|
|
65
|
+
}
|
|
66
|
+
},
|
|
60
67
|
"publishConfig": {
|
|
61
68
|
"registry": "https://npm.pkg.github.com/"
|
|
62
69
|
},
|
|
63
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "447875c5a2ef25eb4552c29b990d90ec40bc6985"
|
|
64
71
|
}
|