@prezly/theme-kit-nextjs 10.9.2 → 10.10.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.
@@ -0,0 +1,165 @@
1
+ function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
2
+ function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
3
+ import { createObservedFetch, upstreamRoute } from "./telemetry.mjs";
4
+ import { createBoundedFetch, FetchScheduler } from "./requests.mjs";
5
+ import { PrezlyAdapter } from "./server.mjs";
6
+ var nativeFetch = globalThis.fetch;
7
+ var tick = () => new Promise(resolve => setImmediate(resolve));
8
+ afterEach(() => {
9
+ globalThis.fetch = nativeFetch;
10
+ jest.useRealTimers();
11
+ });
12
+ it.each([['/v2/newsrooms/private-id', 'newsroom'], ['/v2/newsrooms/private-id/languages/en_GB', 'languages'], ['/v2/newsrooms/private-id/categories', 'categories'], ['/v2/stories/by-slug/private-slug?token=secret', 'story_by_slug'], ['/v2/stories/search', 'stories'], ['/v2/stories/private-uuid', 'story'], ['/custom/private-path', 'other']])('classifies %s without retaining URL values', (path, expected) => {
13
+ expect(upstreamRoute("https://private-origin.test".concat(path))).toBe(expected);
14
+ });
15
+ it('observes raw response headers without consuming the body or adding a signal', /*#__PURE__*/_asyncToGenerator(function* () {
16
+ var events = [];
17
+ var response = new Response('private-body');
18
+ var read = jest.spyOn(response, 'arrayBuffer');
19
+ var fetchMock = jest.fn(/*#__PURE__*/_asyncToGenerator(function* () {
20
+ return response;
21
+ }));
22
+ var options = {
23
+ headers: {
24
+ Authorization: 'private-token'
25
+ }
26
+ };
27
+ var observed = createObservedFetch(fetchMock, {
28
+ observe: e => {
29
+ events.push(e);
30
+ },
31
+ source: 'custom'
32
+ }, 'raw');
33
+ expect(yield observed('https://private-origin.test/v2/stories/private-uuid', options)).toBe(response);
34
+ expect(read).not.toHaveBeenCalled();
35
+ expect(fetchMock).toHaveBeenCalledWith('https://private-origin.test/v2/stories/private-uuid', options);
36
+ expect(events).toEqual([expect.objectContaining({
37
+ type: 'upstream',
38
+ client: 'raw',
39
+ route: 'story',
40
+ source: 'custom',
41
+ status: '2xx'
42
+ })]);
43
+ expect(JSON.stringify(events)).not.toMatch(/private-/);
44
+ }));
45
+ it('keeps telemetry outside the source/cache identity when adapters share work', /*#__PURE__*/_asyncToGenerator(function* () {
46
+ var events = [];
47
+ var config = {
48
+ newsroom: 'private-room',
49
+ accessToken: 'private-token'
50
+ };
51
+ var cache = {
52
+ memory: true,
53
+ latestVersion: 1,
54
+ namespace: 'metrics-adapter-sharing'
55
+ };
56
+ globalThis.fetch = jest.fn(/*#__PURE__*/_asyncToGenerator(function* () {
57
+ return Response.json({
58
+ newsroom: {
59
+ name: 'room'
60
+ }
61
+ });
62
+ }));
63
+ var observed = PrezlyAdapter.connect(config, {
64
+ cache,
65
+ telemetry: e => {
66
+ events.push(e);
67
+ }
68
+ }).usePrezlyClient();
69
+ var plain = PrezlyAdapter.connect(config, {
70
+ cache
71
+ }).usePrezlyClient();
72
+ yield Promise.all([observed.contentDelivery.newsroom(), plain.contentDelivery.newsroom()]);
73
+ expect(globalThis.fetch).toHaveBeenCalledTimes(1);
74
+ yield tick();
75
+ yield observed.contentDelivery.newsroom();
76
+ expect(globalThis.fetch).toHaveBeenCalledTimes(1);
77
+ expect(events.filter(e => e.type === 'upstream')).toHaveLength(1);
78
+ expect(events.some(e => e.type === 'cache_hit')).toBe(true);
79
+ }));
80
+ it('reports queued, full, accepted and completed wait without changing admission limits', /*#__PURE__*/_asyncToGenerator(function* () {
81
+ var events = [];
82
+ var telemetry = {
83
+ observe: e => {
84
+ events.push(e);
85
+ }
86
+ };
87
+ var scheduler = new FetchScheduler({
88
+ concurrency: 1,
89
+ queueLimit: 1
90
+ });
91
+ var release;
92
+ var active = scheduler.run(() => new Promise(r => {
93
+ release = r;
94
+ }), undefined, telemetry, 'story');
95
+ var queued = scheduler.run(/*#__PURE__*/_asyncToGenerator(function* () {
96
+ return 42;
97
+ }), undefined, telemetry, 'story');
98
+ yield expect(scheduler.run(/*#__PURE__*/_asyncToGenerator(function* () {
99
+ return 0;
100
+ }), undefined, telemetry, 'story')).rejects.toThrow('queue is full');
101
+ yield tick();
102
+ release();
103
+ yield active;
104
+ expect(yield queued).toBe(42);
105
+ yield tick();
106
+ expect(events.filter(e => e.type === 'fetch_queue').map(e => e.outcome)).toEqual(['accepted', 'queued', 'full', 'accepted']);
107
+ }));
108
+ it('reports queue timeout and body deadline independently of successful HTTP headers', /*#__PURE__*/_asyncToGenerator(function* () {
109
+ jest.useFakeTimers();
110
+ var events = [];
111
+ var telemetry = {
112
+ observe: e => {
113
+ events.push(e);
114
+ }
115
+ };
116
+ var scheduler = new FetchScheduler({
117
+ concurrency: 1,
118
+ queueLimit: 1,
119
+ queueTimeout: 10,
120
+ requestTimeout: 30
121
+ });
122
+ var finish;
123
+ var fetchMock = jest.fn(/*#__PURE__*/_asyncToGenerator(function* () {
124
+ return new Response(new ReadableStream({
125
+ start(controller) {
126
+ finish = () => controller.close();
127
+ }
128
+ }));
129
+ }));
130
+ var fetch = createBoundedFetch(createObservedFetch(fetchMock, telemetry, 'content'), scheduler, telemetry);
131
+ var first = fetch('https://example.test/v2/stories/search');
132
+ var failed = expect(first).rejects.toThrow('timed out');
133
+ var next = fetch('https://example.test/v2/stories/search');
134
+ var queued = expect(next).rejects.toThrow('queue wait timed out');
135
+ yield jest.advanceTimersByTimeAsync(31);
136
+ yield failed;
137
+ yield queued;
138
+ expect(events.filter(e => e.type === 'upstream')).toEqual([expect.objectContaining({
139
+ status: '2xx'
140
+ })]);
141
+ expect(events.filter(e => e.type === 'fetch_timeout')).toHaveLength(1);
142
+ expect(events).toContainEqual(expect.objectContaining({
143
+ type: 'fetch_queue',
144
+ outcome: 'wait_timeout'
145
+ }));
146
+ finish();
147
+ yield jest.advanceTimersByTimeAsync(0);
148
+ expect(jest.getTimerCount()).toBe(0);
149
+ }));
150
+ it('a throwing or rejecting observer cannot change successful fetch outcomes', /*#__PURE__*/_asyncToGenerator(function* () {
151
+ var response = new Response('ok');
152
+ for (var observe of [() => {
153
+ throw Error('metrics');
154
+ }, /*#__PURE__*/_asyncToGenerator(function* () {
155
+ throw Error('metrics');
156
+ })]) {
157
+ var fetch = createObservedFetch(/*#__PURE__*/_asyncToGenerator(function* () {
158
+ return response;
159
+ }), {
160
+ observe
161
+ }, 'raw');
162
+ expect(yield fetch('https://example.test')).toBe(response);
163
+ }
164
+ yield tick();
165
+ }));
package/package.json CHANGED
@@ -1,118 +1,115 @@
1
1
  {
2
- "name": "@prezly/theme-kit-nextjs",
3
- "version": "10.9.2",
4
- "description": "Data layer and utility library for developing Prezly themes with NextJS",
5
- "type": "module",
6
- "main": "build/index.mjs",
7
- "types": "build/index.d.ts",
8
- "files": [
9
- "build",
10
- "README.md"
11
- ],
12
- "exports": {
13
- ".": {
14
- "types": "./build/index.d.ts",
15
- "require": "./build/index.cjs",
16
- "default": "./build/index.mjs"
2
+ "name": "@prezly/theme-kit-nextjs",
3
+ "version": "10.10.0",
4
+ "description": "Data layer and utility library for developing Prezly themes with NextJS",
5
+ "type": "module",
6
+ "main": "build/index.mjs",
7
+ "types": "build/index.d.ts",
8
+ "files": [
9
+ "build",
10
+ "README.md"
11
+ ],
12
+ "exports": {
13
+ ".": {
14
+ "types": "./build/index.d.ts",
15
+ "require": "./build/index.cjs",
16
+ "default": "./build/index.mjs"
17
+ },
18
+ "./server": {
19
+ "types": "./build/server.d.ts",
20
+ "require": "./build/server.cjs",
21
+ "default": "./build/server.mjs"
22
+ },
23
+ "./middleware": {
24
+ "types": "./build/middleware/index.d.ts",
25
+ "require": "./build/middleware/index.cjs",
26
+ "default": "./build/middleware/index.mjs"
27
+ },
28
+ "./next-config": {
29
+ "types": "./build/next-config/index.d.ts",
30
+ "require": "./build/next-config/index.cjs",
31
+ "default": "./build/next-config/index.mjs"
32
+ },
33
+ "./sentry": {
34
+ "types": "./build/sentry/index.d.ts",
35
+ "require": "./build/sentry/index.cjs",
36
+ "default": "./build/sentry/index.mjs"
37
+ },
38
+ "./playwright": {
39
+ "types": "./build/playwright/index.d.ts",
40
+ "require": "./build/playwright/index.cjs",
41
+ "default": "./build/playwright/index.mjs"
42
+ }
17
43
  },
18
- "./server": {
19
- "types": "./build/server.d.ts",
20
- "require": "./build/server.cjs",
21
- "default": "./build/server.mjs"
44
+ "engines": {
45
+ "node": ">= 18.18.0",
46
+ "npm": ">= 8.x"
22
47
  },
23
- "./middleware": {
24
- "types": "./build/middleware/index.d.ts",
25
- "require": "./build/middleware/index.cjs",
26
- "default": "./build/middleware/index.mjs"
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://github.com/prezly/theme-kit-js.git",
51
+ "directory": "packages/nextjs"
27
52
  },
28
- "./next-config": {
29
- "types": "./build/next-config/index.d.ts",
30
- "require": "./build/next-config/index.cjs",
31
- "default": "./build/next-config/index.mjs"
53
+ "keywords": [
54
+ "prezly",
55
+ "nextjs"
56
+ ],
57
+ "author": "Prezly Team",
58
+ "license": "MIT",
59
+ "bugs": {
60
+ "url": "https://github.com/prezly/theme-kit-js/issues"
32
61
  },
33
- "./sentry": {
34
- "types": "./build/sentry/index.d.ts",
35
- "require": "./build/sentry/index.cjs",
36
- "default": "./build/sentry/index.mjs"
62
+ "homepage": "https://github.com/prezly/theme-kit-js/tree/main/packages/nextjs#readme",
63
+ "scripts": {
64
+ "prepack": "pnpm test:build",
65
+ "prebuild": "rimraf --glob build/* *.tsbuildinfo",
66
+ "build": "pnpm build:types && pnpm build:esm && pnpm build:cjs",
67
+ "build:types": "tsc --project .",
68
+ "build:esm": "babel --config-file=../../babel.esm.json src/ --extensions=.ts,.tsx --out-dir=build/ --out-file-extension=.mjs",
69
+ "build:cjs": "babel --config-file=../../babel.cjs.json src/ --extensions=.ts,.tsx --out-dir=build/ --out-file-extension=.cjs",
70
+ "dev": "tsc --watch --preserveWatchOutput --project .",
71
+ "typecheck": "tsc --noEmit --emitDeclarationOnly false --incremental --project .",
72
+ "lint": "biome lint src",
73
+ "lint:fix": "biome lint --write src",
74
+ "format": "biome format src",
75
+ "format:fix": "biome format --write src",
76
+ "test": "pnpm test:unit && pnpm test:build",
77
+ "test:unit": "jest",
78
+ "test:redis": "node tests/test-redis-resilience.cjs",
79
+ "test:build": "pnpm test:build:cjs && pnpm test:build:esm && pnpm test:build:types",
80
+ "test:build:types": "tsc --esModuleInterop --noEmit --target es2020 --moduleResolution node tests/test-build-types.ts",
81
+ "test:build:esm": "node tests/test-build.mjs",
82
+ "test:build:cjs": "node tests/test-build.cjs"
37
83
  },
38
- "./playwright": {
39
- "types": "./build/playwright/index.d.ts",
40
- "require": "./build/playwright/index.cjs",
41
- "default": "./build/playwright/index.mjs"
42
- }
43
- },
44
- "engines": {
45
- "node": ">= 16.x",
46
- "npm": ">= 8.x"
47
- },
48
- "devEngines": {
49
- "node": ">= 16.x",
50
- "npm": ">= 8.x"
51
- },
52
- "repository": {
53
- "type": "git",
54
- "url": "git+https://github.com/prezly/theme-kit-js.git",
55
- "directory": "packages/nextjs"
56
- },
57
- "keywords": [
58
- "prezly",
59
- "nextjs"
60
- ],
61
- "author": "Prezly Team",
62
- "license": "MIT",
63
- "bugs": {
64
- "url": "https://github.com/prezly/theme-kit-js/issues"
65
- },
66
- "homepage": "https://github.com/prezly/theme-kit-js/tree/main/packages/nextjs#readme",
67
- "peerDependencies": {
68
- "@playwright/test": "1.x",
69
- "@prezly/sdk": "21.12.0 || ^23.x",
70
- "next": "^14.x || ^15.x",
71
- "react": "^18.x || ^19.x",
72
- "react-dom": "^18.x || ^19.x"
73
- },
74
- "peerDependenciesMeta": {
75
- "@playwright/test": {
76
- "optional": true
77
- }
78
- },
79
- "dependencies": {
80
- "@noble/hashes": "1.8.0",
81
- "@prezly/theme-kit-core": "^10.9.2",
82
- "@prezly/theme-kit-intl": "^10.9.1",
83
- "@prezly/theme-kit-react": "^10.9.1",
84
- "@technically/is-not-undefined": "^1.0.0",
85
- "@technically/omit-undefined": "^1.0.4",
86
- "json-stable-stringify": "^1.2.1",
87
- "redis": "^4.7.0",
88
- "url-pattern": "^1.0.3"
89
- },
90
- "devDependencies": {
91
- "@sentry/nextjs": "7.120.4"
92
- },
93
- "publishConfig": {
94
- "access": "public"
95
- },
96
- "sideEffects": false,
97
- "gitHead": "0d33a99980bcf409578f25a666ce4b3f93877caf",
98
- "scripts": {
99
- "prebuild": "rimraf --glob build/* *.tsbuildinfo",
100
- "build": "pnpm build:types && pnpm build:esm && pnpm build:cjs",
101
- "build:types": "tsc --project .",
102
- "build:esm": "babel --config-file=../../babel.esm.json src/ --extensions=.ts,.tsx --out-dir=build/ --out-file-extension=.mjs",
103
- "build:cjs": "babel --config-file=../../babel.cjs.json src/ --extensions=.ts,.tsx --out-dir=build/ --out-file-extension=.cjs",
104
- "dev": "tsc --watch --preserveWatchOutput --project .",
105
- "typecheck": "tsc --noEmit --emitDeclarationOnly false --incremental --project .",
106
- "lint": "biome lint src",
107
- "lint:fix": "biome lint --write src",
108
- "format": "biome format src",
109
- "format:fix": "biome format --write src",
110
- "test": "pnpm test:unit && pnpm test:build",
111
- "test:unit": "jest",
112
- "test:redis": "node tests/test-redis-resilience.cjs",
113
- "test:build": "pnpm test:build:cjs && pnpm test:build:esm && pnpm test:build:types",
114
- "test:build:types": "tsc --esModuleInterop --noEmit build/index.d.ts",
115
- "test:build:esm": "node tests/test-build.mjs",
116
- "test:build:cjs": "node tests/test-build.cjs"
117
- }
118
- }
84
+ "peerDependencies": {
85
+ "@playwright/test": "1.x",
86
+ "@prezly/sdk": "21.12.0 || ^23.x",
87
+ "next": "^14.x || ^15.x",
88
+ "react": "^18.x || ^19.x",
89
+ "react-dom": "^18.x || ^19.x"
90
+ },
91
+ "peerDependenciesMeta": {
92
+ "@playwright/test": {
93
+ "optional": true
94
+ }
95
+ },
96
+ "dependencies": {
97
+ "@noble/hashes": "1.8.0",
98
+ "@prezly/theme-kit-core": "workspace:^",
99
+ "@prezly/theme-kit-intl": "workspace:^",
100
+ "@prezly/theme-kit-react": "workspace:^",
101
+ "@technically/is-not-undefined": "^1.0.0",
102
+ "@technically/omit-undefined": "^1.0.4",
103
+ "json-stable-stringify": "^1.2.1",
104
+ "redis": "^4.7.0",
105
+ "url-pattern": "^1.0.3"
106
+ },
107
+ "devDependencies": {
108
+ "@sentry/nextjs": "7.120.4"
109
+ },
110
+ "publishConfig": {
111
+ "access": "public"
112
+ },
113
+ "sideEffects": false,
114
+ "gitHead": "51b1ce99cf8ce2c886001077bcaf95cb143f86ce"
115
+ }