@trieb.work/nextjs-turbo-redis-cache 1.12.0 → 1.14.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/.github/workflows/ci.yml +11 -13
- package/.github/workflows/release.yml +68 -7
- package/CHANGELOG.md +28 -0
- package/README.md +29 -21
- package/dist/index.d.mts +8 -3
- package/dist/index.d.ts +8 -3
- package/dist/index.js +64 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +54 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -3
- package/playwright.config.ts +1 -1
- package/src/CacheComponentsHandler.ts +11 -5
- package/src/CachedHandler.ts +16 -2
- package/src/RedisStringsHandler.ts +4 -2
- package/src/utils/prefix.test.ts +115 -0
- package/src/utils/prefix.ts +44 -0
- package/test/cache-components/cache-components.integration.spec.ts +1 -1
- package/test/integration/build-id-prefix.integration.test.ts +102 -0
- package/test/integration/next-app-15-0-3/pnpm-lock.yaml +32 -1
- package/test/integration/next-app-15-3-2/pnpm-lock.yaml +33 -1
- package/test/integration/next-app-15-4-7/pnpm-lock.yaml +36 -1
- package/test/integration/next-app-16-0-3/pnpm-lock.yaml +37 -1
- package/test/integration/next-app-16-0-3/postcss.config.mjs +7 -7
- package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/package.json +3 -3
- package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/pnpm-lock.yaml +98 -55
- package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/postcss.config.mjs +7 -7
- package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/package.json +3 -3
- package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/pnpm-lock.yaml +98 -55
- package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/postcss.config.mjs +7 -7
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/README.md +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/eslint.config.mjs +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/next.config.ts +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/api/cached-static-fetch/route.ts +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/api/nested-fetch-in-api-route/revalidated-fetch/route.ts +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/api/revalidatePath/route.ts +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/api/revalidateTag/route.ts +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/api/revalidated-fetch/route.ts +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/api/uncached-fetch/route.ts +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/favicon.ico +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/globals.css +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/layout.tsx +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/cached-static-fetch/default--force-dynamic-page/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/cached-static-fetch/revalidate15--default-page/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/cached-static-fetch/revalidate15--force-dynamic-page/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/no-fetch/default-page/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/revalidated-fetch/default--force-dynamic-page/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/revalidated-fetch/revalidate15--default-page/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/revalidated-fetch/revalidate15--force-dynamic-page/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/uncached-fetch/default--force-dynamic-page/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/uncached-fetch/revalidate15--default-page/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/uncached-fetch/revalidate15--force-dynamic-page/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/revalidation-interface.tsx +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/update-tag-test/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/tsconfig.json +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/README.md +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/cache-handler.js +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/eslint.config.mjs +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/next.config.ts +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/public/file.svg +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/public/globe.svg +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/public/next.svg +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/public/vercel.svg +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/public/window.svg +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/api/cached-static-fetch/route.ts +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/api/cached-with-tag/route.ts +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/api/revalidate-tag/route.ts +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/api/revalidated-fetch/route.ts +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/cache-lab/cachelife-short/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/cache-lab/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/cache-lab/runtime-data-suspense/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/cache-lab/stale-while-revalidate/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/cache-lab/tag-invalidation/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/cache-lab/use-cache-nondeterministic/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/favicon.ico +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/globals.css +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/layout.tsx +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/revalidation-interface.tsx +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/update-tag-test/page.tsx +0 -0
- /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/tsconfig.json +0 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { resolveKeyPrefix } from './prefix';
|
|
6
|
+
|
|
7
|
+
function withEnv<T>(env: Partial<NodeJS.ProcessEnv>, fn: () => T): T {
|
|
8
|
+
const original: NodeJS.ProcessEnv = { ...process.env };
|
|
9
|
+
Object.entries(env).forEach(([k, v]) => {
|
|
10
|
+
const envRec = process.env as Record<string, string | undefined>;
|
|
11
|
+
if (v === undefined) delete envRec[k];
|
|
12
|
+
else envRec[k] = v as string;
|
|
13
|
+
});
|
|
14
|
+
try {
|
|
15
|
+
return fn();
|
|
16
|
+
} finally {
|
|
17
|
+
process.env = original;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function makeBuildIdTree(buildId: string) {
|
|
22
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'prefix-test-'));
|
|
23
|
+
const nextDir = path.join(tmp, '.next');
|
|
24
|
+
const serverDir = path.join(nextDir, 'server');
|
|
25
|
+
fs.mkdirSync(serverDir, { recursive: true });
|
|
26
|
+
fs.writeFileSync(path.join(nextDir, 'BUILD_ID'), buildId, 'utf8');
|
|
27
|
+
return {
|
|
28
|
+
serverDistDir: serverDir,
|
|
29
|
+
cleanup: () => fs.rmSync(tmp, { recursive: true, force: true }),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
describe('resolveKeyPrefix', () => {
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
const envRec = process.env as Record<string, string | undefined>;
|
|
36
|
+
delete envRec.KEY_PREFIX;
|
|
37
|
+
delete envRec.VERCEL_URL;
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('returns option keyPrefix when provided (including empty string)', () => {
|
|
41
|
+
const p1 = resolveKeyPrefix({ optionKeyPrefix: 'opt_', env: process.env });
|
|
42
|
+
expect(p1).toBe('opt_');
|
|
43
|
+
|
|
44
|
+
const p2 = resolveKeyPrefix({ optionKeyPrefix: '', env: process.env });
|
|
45
|
+
expect(p2).toBe('');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('uses KEY_PREFIX when option is undefined', () => {
|
|
49
|
+
const res = withEnv({ KEY_PREFIX: 'envkp_' }, () =>
|
|
50
|
+
resolveKeyPrefix({ optionKeyPrefix: undefined, env: process.env }),
|
|
51
|
+
);
|
|
52
|
+
expect(res).toBe('envkp_');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('uses BUILD_ID when KEY_PREFIX and VERCEL_URL are absent and BUILD_ID readable', () => {
|
|
56
|
+
const { serverDistDir, cleanup } = makeBuildIdTree('BID123');
|
|
57
|
+
try {
|
|
58
|
+
const res = resolveKeyPrefix({
|
|
59
|
+
optionKeyPrefix: undefined,
|
|
60
|
+
env: process.env,
|
|
61
|
+
serverDistDir,
|
|
62
|
+
});
|
|
63
|
+
expect(res).toBe('BID123');
|
|
64
|
+
} finally {
|
|
65
|
+
cleanup();
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('uses VERCEL_URL before BUILD_ID when both are available', () => {
|
|
70
|
+
const { serverDistDir, cleanup } = makeBuildIdTree('BIDXYZ');
|
|
71
|
+
try {
|
|
72
|
+
const res = withEnv({ VERCEL_URL: 'vercel.example' }, () =>
|
|
73
|
+
resolveKeyPrefix({
|
|
74
|
+
optionKeyPrefix: undefined,
|
|
75
|
+
env: process.env,
|
|
76
|
+
serverDistDir,
|
|
77
|
+
}),
|
|
78
|
+
);
|
|
79
|
+
expect(res).toBe('vercel.example');
|
|
80
|
+
} finally {
|
|
81
|
+
cleanup();
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('uses VERCEL_URL when KEY_PREFIX and BUILD_ID not available', () => {
|
|
86
|
+
const res = withEnv({ VERCEL_URL: 'vercel.example' }, () =>
|
|
87
|
+
resolveKeyPrefix({ optionKeyPrefix: undefined, env: process.env }),
|
|
88
|
+
);
|
|
89
|
+
expect(res).toBe('vercel.example');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('falls back to UNDEFINED_URL_ when nothing else available', () => {
|
|
93
|
+
const res = resolveKeyPrefix({
|
|
94
|
+
optionKeyPrefix: undefined,
|
|
95
|
+
env: process.env,
|
|
96
|
+
});
|
|
97
|
+
expect(res).toBe('UNDEFINED_URL_');
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('treats empty env values as absent', () => {
|
|
101
|
+
const { serverDistDir, cleanup } = makeBuildIdTree('BIDX');
|
|
102
|
+
try {
|
|
103
|
+
const res = withEnv({ KEY_PREFIX: '', VERCEL_URL: '' }, () =>
|
|
104
|
+
resolveKeyPrefix({
|
|
105
|
+
optionKeyPrefix: undefined,
|
|
106
|
+
env: process.env,
|
|
107
|
+
serverDistDir,
|
|
108
|
+
}),
|
|
109
|
+
);
|
|
110
|
+
expect(res).toBe('BIDX');
|
|
111
|
+
} finally {
|
|
112
|
+
cleanup();
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
export function readBuildId(serverDistDir?: string): string | undefined {
|
|
5
|
+
try {
|
|
6
|
+
if (serverDistDir) {
|
|
7
|
+
const buildIdPath = path.join(serverDistDir, '..', 'BUILD_ID');
|
|
8
|
+
const buildId = fs.readFileSync(buildIdPath, 'utf8').trim();
|
|
9
|
+
return buildId || undefined;
|
|
10
|
+
}
|
|
11
|
+
} catch {
|
|
12
|
+
// fall through to cwd-based read
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
const fromCwd = path.join(process.cwd(), '.next', 'BUILD_ID');
|
|
16
|
+
const buildId = fs.readFileSync(fromCwd, 'utf8').trim();
|
|
17
|
+
return buildId || undefined;
|
|
18
|
+
} catch {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function resolveKeyPrefix({
|
|
24
|
+
optionKeyPrefix,
|
|
25
|
+
serverDistDir,
|
|
26
|
+
env,
|
|
27
|
+
}: {
|
|
28
|
+
optionKeyPrefix?: string;
|
|
29
|
+
serverDistDir?: string;
|
|
30
|
+
env: NodeJS.ProcessEnv;
|
|
31
|
+
}): string {
|
|
32
|
+
// If the option is explicitly provided, honor it even if it's an empty string
|
|
33
|
+
if (optionKeyPrefix !== undefined) {
|
|
34
|
+
return optionKeyPrefix;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const keyPrefixEnv =
|
|
38
|
+
env.KEY_PREFIX && env.KEY_PREFIX.length > 0 ? env.KEY_PREFIX : undefined;
|
|
39
|
+
const vercelUrl =
|
|
40
|
+
env.VERCEL_URL && env.VERCEL_URL.length > 0 ? env.VERCEL_URL : undefined;
|
|
41
|
+
const buildId = readBuildId(serverDistDir);
|
|
42
|
+
|
|
43
|
+
return keyPrefixEnv ?? vercelUrl ?? buildId ?? 'UNDEFINED_URL_';
|
|
44
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
2
|
+
import { spawn, ChildProcessWithoutNullStreams } from 'child_process';
|
|
3
|
+
import { createClient, RedisClientType } from 'redis';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import fetch from 'node-fetch';
|
|
7
|
+
|
|
8
|
+
const NEXT_APP = 'next-app-15-4-7';
|
|
9
|
+
const PORT = 3075;
|
|
10
|
+
const BASE_URL = `http://localhost:${PORT}`;
|
|
11
|
+
|
|
12
|
+
async function waitForServer(url: string, timeout = 20000) {
|
|
13
|
+
const start = Date.now();
|
|
14
|
+
while (Date.now() - start < timeout) {
|
|
15
|
+
try {
|
|
16
|
+
const res = await fetch(url + '/api/cached-static-fetch');
|
|
17
|
+
if (res.ok) return;
|
|
18
|
+
} catch {}
|
|
19
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
20
|
+
}
|
|
21
|
+
throw new Error('Next.js server did not start in time');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe('BUILD_ID-based key prefix (Next handlers)', () => {
|
|
25
|
+
let nextProcess: ChildProcessWithoutNullStreams | undefined;
|
|
26
|
+
let redis: RedisClientType;
|
|
27
|
+
let appDir: string;
|
|
28
|
+
let buildId: string;
|
|
29
|
+
|
|
30
|
+
beforeAll(async () => {
|
|
31
|
+
appDir = path.join(__dirname, NEXT_APP);
|
|
32
|
+
|
|
33
|
+
// Ensure clean env so BUILD_ID precedence kicks in
|
|
34
|
+
delete (process.env as Record<string, string | undefined>).KEY_PREFIX;
|
|
35
|
+
delete (process.env as Record<string, string | undefined>).VERCEL_URL;
|
|
36
|
+
process.env.VERCEL_ENV = 'production';
|
|
37
|
+
process.env.REDISHOST = process.env.REDISHOST || 'localhost';
|
|
38
|
+
process.env.REDISPORT = process.env.REDISPORT || '6379';
|
|
39
|
+
|
|
40
|
+
// Install + build
|
|
41
|
+
await new Promise<void>((resolve, reject) => {
|
|
42
|
+
const p = spawn('pnpm', ['install'], { cwd: appDir, stdio: 'inherit' });
|
|
43
|
+
p.on('close', (code) =>
|
|
44
|
+
code === 0 ? resolve() : reject(new Error('pnpm i failed')),
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
await new Promise<void>((resolve, reject) => {
|
|
48
|
+
const p = spawn('pnpm', ['build'], { cwd: appDir, stdio: 'inherit' });
|
|
49
|
+
p.on('close', (code) =>
|
|
50
|
+
code === 0 ? resolve() : reject(new Error('pnpm build failed')),
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Read BUILD_ID from the built app
|
|
55
|
+
buildId = fs
|
|
56
|
+
.readFileSync(path.join(appDir, '.next', 'BUILD_ID'), 'utf8')
|
|
57
|
+
.trim();
|
|
58
|
+
|
|
59
|
+
// Start server without KEY_PREFIX/VERCEL_URL
|
|
60
|
+
nextProcess = spawn('npx', ['next', 'start', '-p', String(PORT)], {
|
|
61
|
+
cwd: appDir,
|
|
62
|
+
env: { ...process.env, SKIP_KEYSPACE_CONFIG_CHECK: 'true' },
|
|
63
|
+
stdio: 'pipe',
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
nextProcess.stderr?.on(
|
|
67
|
+
'data',
|
|
68
|
+
(d) => process.env.DEBUG_INTEGRATION && console.error(String(d)),
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
await waitForServer(BASE_URL);
|
|
72
|
+
|
|
73
|
+
// Connect Redis
|
|
74
|
+
redis = createClient({
|
|
75
|
+
url: `redis://${process.env.REDISHOST}:${process.env.REDISPORT}`,
|
|
76
|
+
});
|
|
77
|
+
await redis.connect();
|
|
78
|
+
}, 180000);
|
|
79
|
+
|
|
80
|
+
afterAll(async () => {
|
|
81
|
+
try {
|
|
82
|
+
if (redis) await redis.quit();
|
|
83
|
+
} finally {
|
|
84
|
+
if (nextProcess) nextProcess.kill();
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('uses BUILD_ID as the Redis key prefix when no KEY_PREFIX/VERCEL_URL set', async () => {
|
|
89
|
+
// Warm cache twice to ensure a set occurs even if first was during startup
|
|
90
|
+
const res1 = await fetch(BASE_URL + '/api/cached-static-fetch');
|
|
91
|
+
expect(res1.ok).toBe(true);
|
|
92
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
93
|
+
const res2 = await fetch(BASE_URL + '/api/cached-static-fetch');
|
|
94
|
+
expect(res2.ok).toBe(true);
|
|
95
|
+
|
|
96
|
+
// Allow background syncs
|
|
97
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
98
|
+
|
|
99
|
+
const keys = await redis.keys(`${buildId}*`);
|
|
100
|
+
expect(keys.length).toBeGreaterThan(0);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
@@ -155,67 +155,79 @@ packages:
|
|
|
155
155
|
resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==}
|
|
156
156
|
cpu: [arm64]
|
|
157
157
|
os: [linux]
|
|
158
|
+
libc: [glibc]
|
|
158
159
|
|
|
159
160
|
'@img/sharp-libvips-linux-arm@1.0.5':
|
|
160
161
|
resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==}
|
|
161
162
|
cpu: [arm]
|
|
162
163
|
os: [linux]
|
|
164
|
+
libc: [glibc]
|
|
163
165
|
|
|
164
166
|
'@img/sharp-libvips-linux-s390x@1.0.4':
|
|
165
167
|
resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==}
|
|
166
168
|
cpu: [s390x]
|
|
167
169
|
os: [linux]
|
|
170
|
+
libc: [glibc]
|
|
168
171
|
|
|
169
172
|
'@img/sharp-libvips-linux-x64@1.0.4':
|
|
170
173
|
resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==}
|
|
171
174
|
cpu: [x64]
|
|
172
175
|
os: [linux]
|
|
176
|
+
libc: [glibc]
|
|
173
177
|
|
|
174
178
|
'@img/sharp-libvips-linuxmusl-arm64@1.0.4':
|
|
175
179
|
resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==}
|
|
176
180
|
cpu: [arm64]
|
|
177
181
|
os: [linux]
|
|
182
|
+
libc: [musl]
|
|
178
183
|
|
|
179
184
|
'@img/sharp-libvips-linuxmusl-x64@1.0.4':
|
|
180
185
|
resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==}
|
|
181
186
|
cpu: [x64]
|
|
182
187
|
os: [linux]
|
|
188
|
+
libc: [musl]
|
|
183
189
|
|
|
184
190
|
'@img/sharp-linux-arm64@0.33.5':
|
|
185
191
|
resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==}
|
|
186
192
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
|
187
193
|
cpu: [arm64]
|
|
188
194
|
os: [linux]
|
|
195
|
+
libc: [glibc]
|
|
189
196
|
|
|
190
197
|
'@img/sharp-linux-arm@0.33.5':
|
|
191
198
|
resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==}
|
|
192
199
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
|
193
200
|
cpu: [arm]
|
|
194
201
|
os: [linux]
|
|
202
|
+
libc: [glibc]
|
|
195
203
|
|
|
196
204
|
'@img/sharp-linux-s390x@0.33.5':
|
|
197
205
|
resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==}
|
|
198
206
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
|
199
207
|
cpu: [s390x]
|
|
200
208
|
os: [linux]
|
|
209
|
+
libc: [glibc]
|
|
201
210
|
|
|
202
211
|
'@img/sharp-linux-x64@0.33.5':
|
|
203
212
|
resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==}
|
|
204
213
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
|
205
214
|
cpu: [x64]
|
|
206
215
|
os: [linux]
|
|
216
|
+
libc: [glibc]
|
|
207
217
|
|
|
208
218
|
'@img/sharp-linuxmusl-arm64@0.33.5':
|
|
209
219
|
resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==}
|
|
210
220
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
|
211
221
|
cpu: [arm64]
|
|
212
222
|
os: [linux]
|
|
223
|
+
libc: [musl]
|
|
213
224
|
|
|
214
225
|
'@img/sharp-linuxmusl-x64@0.33.5':
|
|
215
226
|
resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==}
|
|
216
227
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
|
217
228
|
cpu: [x64]
|
|
218
229
|
os: [linux]
|
|
230
|
+
libc: [musl]
|
|
219
231
|
|
|
220
232
|
'@img/sharp-wasm32@0.33.5':
|
|
221
233
|
resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==}
|
|
@@ -260,24 +272,28 @@ packages:
|
|
|
260
272
|
engines: {node: '>= 10'}
|
|
261
273
|
cpu: [arm64]
|
|
262
274
|
os: [linux]
|
|
275
|
+
libc: [glibc]
|
|
263
276
|
|
|
264
277
|
'@next/swc-linux-arm64-musl@15.0.3':
|
|
265
278
|
resolution: {integrity: sha512-WkAk6R60mwDjH4lG/JBpb2xHl2/0Vj0ZRu1TIzWuOYfQ9tt9NFsIinI1Epma77JVgy81F32X/AeD+B2cBu/YQA==}
|
|
266
279
|
engines: {node: '>= 10'}
|
|
267
280
|
cpu: [arm64]
|
|
268
281
|
os: [linux]
|
|
282
|
+
libc: [musl]
|
|
269
283
|
|
|
270
284
|
'@next/swc-linux-x64-gnu@15.0.3':
|
|
271
285
|
resolution: {integrity: sha512-gWL/Cta1aPVqIGgDb6nxkqy06DkwJ9gAnKORdHWX1QBbSZZB+biFYPFti8aKIQL7otCE1pjyPaXpFzGeG2OS2w==}
|
|
272
286
|
engines: {node: '>= 10'}
|
|
273
287
|
cpu: [x64]
|
|
274
288
|
os: [linux]
|
|
289
|
+
libc: [glibc]
|
|
275
290
|
|
|
276
291
|
'@next/swc-linux-x64-musl@15.0.3':
|
|
277
292
|
resolution: {integrity: sha512-QQEMwFd8r7C0GxQS62Zcdy6GKx999I/rTO2ubdXEe+MlZk9ZiinsrjwoiBL5/57tfyjikgh6GOU2WRQVUej3UA==}
|
|
278
293
|
engines: {node: '>= 10'}
|
|
279
294
|
cpu: [x64]
|
|
280
295
|
os: [linux]
|
|
296
|
+
libc: [musl]
|
|
281
297
|
|
|
282
298
|
'@next/swc-win32-arm64-msvc@15.0.3':
|
|
283
299
|
resolution: {integrity: sha512-9TEp47AAd/ms9fPNgtgnT7F3M1Hf7koIYYWCMQ9neOwjbVWJsHZxrFbI3iEDJ8rf1TDGpmHbKxXf2IFpAvheIQ==}
|
|
@@ -386,24 +402,28 @@ packages:
|
|
|
386
402
|
engines: {node: '>= 10'}
|
|
387
403
|
cpu: [arm64]
|
|
388
404
|
os: [linux]
|
|
405
|
+
libc: [glibc]
|
|
389
406
|
|
|
390
407
|
'@tailwindcss/oxide-linux-arm64-musl@4.1.4':
|
|
391
408
|
resolution: {integrity: sha512-X3As2xhtgPTY/m5edUtddmZ8rCruvBvtxYLMw9OsZdH01L2gS2icsHRwxdU0dMItNfVmrBezueXZCHxVeeb7Aw==}
|
|
392
409
|
engines: {node: '>= 10'}
|
|
393
410
|
cpu: [arm64]
|
|
394
411
|
os: [linux]
|
|
412
|
+
libc: [musl]
|
|
395
413
|
|
|
396
414
|
'@tailwindcss/oxide-linux-x64-gnu@4.1.4':
|
|
397
415
|
resolution: {integrity: sha512-2VG4DqhGaDSmYIu6C4ua2vSLXnJsb/C9liej7TuSO04NK+JJJgJucDUgmX6sn7Gw3Cs5ZJ9ZLrnI0QRDOjLfNQ==}
|
|
398
416
|
engines: {node: '>= 10'}
|
|
399
417
|
cpu: [x64]
|
|
400
418
|
os: [linux]
|
|
419
|
+
libc: [glibc]
|
|
401
420
|
|
|
402
421
|
'@tailwindcss/oxide-linux-x64-musl@4.1.4':
|
|
403
422
|
resolution: {integrity: sha512-v+mxVgH2kmur/X5Mdrz9m7TsoVjbdYQT0b4Z+dr+I4RvreCNXyCFELZL/DO0M1RsidZTrm6O1eMnV6zlgEzTMQ==}
|
|
404
423
|
engines: {node: '>= 10'}
|
|
405
424
|
cpu: [x64]
|
|
406
425
|
os: [linux]
|
|
426
|
+
libc: [musl]
|
|
407
427
|
|
|
408
428
|
'@tailwindcss/oxide-wasm32-wasi@4.1.4':
|
|
409
429
|
resolution: {integrity: sha512-2TLe9ir+9esCf6Wm+lLWTMbgklIjiF0pbmDnwmhR9MksVOq+e8aP3TSsXySnBDDvTTVd/vKu1aNttEGj3P6l8Q==}
|
|
@@ -439,7 +459,7 @@ packages:
|
|
|
439
459
|
'@trieb.work/nextjs-turbo-redis-cache@file:../../..':
|
|
440
460
|
resolution: {directory: ../../.., type: directory}
|
|
441
461
|
peerDependencies:
|
|
442
|
-
next: '>=15.0.3
|
|
462
|
+
next: '>=15.0.3 <16.3.0'
|
|
443
463
|
redis: 4.7.0
|
|
444
464
|
|
|
445
465
|
'@tybys/wasm-util@0.9.0':
|
|
@@ -541,36 +561,43 @@ packages:
|
|
|
541
561
|
resolution: {integrity: sha512-FX2FV7vpLE/+Z0NZX9/1pwWud5Wocm/2PgpUXbT5aSV3QEB10kBPJAzssOQylvdj8mOHoKl5pVkXpbCwww/T2g==}
|
|
542
562
|
cpu: [arm64]
|
|
543
563
|
os: [linux]
|
|
564
|
+
libc: [glibc]
|
|
544
565
|
|
|
545
566
|
'@unrs/resolver-binding-linux-arm64-musl@1.5.0':
|
|
546
567
|
resolution: {integrity: sha512-+gF97xst1BZb28T3nwwzEtq2ewCoMDGKsenYsZuvpmNrW0019G1iUAunZN+FG55L21y+uP7zsGX06OXDQ/viKw==}
|
|
547
568
|
cpu: [arm64]
|
|
548
569
|
os: [linux]
|
|
570
|
+
libc: [musl]
|
|
549
571
|
|
|
550
572
|
'@unrs/resolver-binding-linux-ppc64-gnu@1.5.0':
|
|
551
573
|
resolution: {integrity: sha512-5bEmVcQw9js8JYM2LkUBw5SeELSIxX+qKf9bFrfFINKAp4noZ//hUxLpbF7u/3gTBN1GsER6xOzIZlw/VTdXtA==}
|
|
552
574
|
cpu: [ppc64]
|
|
553
575
|
os: [linux]
|
|
576
|
+
libc: [glibc]
|
|
554
577
|
|
|
555
578
|
'@unrs/resolver-binding-linux-riscv64-gnu@1.5.0':
|
|
556
579
|
resolution: {integrity: sha512-GGk/8TPUsf1Q99F+lzMdjE6sGL26uJCwQ9TlvBs8zR3cLQNw/MIumPN7zrs3GFGySjnwXc8gA6J3HKbejywmqA==}
|
|
557
580
|
cpu: [riscv64]
|
|
558
581
|
os: [linux]
|
|
582
|
+
libc: [glibc]
|
|
559
583
|
|
|
560
584
|
'@unrs/resolver-binding-linux-s390x-gnu@1.5.0':
|
|
561
585
|
resolution: {integrity: sha512-5uRkFYYVNAeVaA4W/CwugjFN3iDOHCPqsBLCCOoJiMfFMMz4evBRsg+498OFa9w6VcTn2bD5aI+RRayaIgk2Sw==}
|
|
562
586
|
cpu: [s390x]
|
|
563
587
|
os: [linux]
|
|
588
|
+
libc: [glibc]
|
|
564
589
|
|
|
565
590
|
'@unrs/resolver-binding-linux-x64-gnu@1.5.0':
|
|
566
591
|
resolution: {integrity: sha512-j905CZH3nehYy6NimNqC2B14pxn4Ltd7guKMyPTzKehbFXTUgihQS/ZfHQTdojkMzbSwBOSgq1dOrY+IpgxDsA==}
|
|
567
592
|
cpu: [x64]
|
|
568
593
|
os: [linux]
|
|
594
|
+
libc: [glibc]
|
|
569
595
|
|
|
570
596
|
'@unrs/resolver-binding-linux-x64-musl@1.5.0':
|
|
571
597
|
resolution: {integrity: sha512-dmLevQTuzQRwu5A+mvj54R5aye5I4PVKiWqGxg8tTaYP2k2oTs/3Mo8mgnhPk28VoYCi0fdFYpgzCd4AJndQvQ==}
|
|
572
598
|
cpu: [x64]
|
|
573
599
|
os: [linux]
|
|
600
|
+
libc: [musl]
|
|
574
601
|
|
|
575
602
|
'@unrs/resolver-binding-wasm32-wasi@1.5.0':
|
|
576
603
|
resolution: {integrity: sha512-LtJMhwu7avhoi+kKfAZOKN773RtzLBVVF90YJbB0wyMpUj9yQPeA+mteVUI9P70OG/opH47FeV5AWeaNWWgqJg==}
|
|
@@ -1284,24 +1311,28 @@ packages:
|
|
|
1284
1311
|
engines: {node: '>= 12.0.0'}
|
|
1285
1312
|
cpu: [arm64]
|
|
1286
1313
|
os: [linux]
|
|
1314
|
+
libc: [glibc]
|
|
1287
1315
|
|
|
1288
1316
|
lightningcss-linux-arm64-musl@1.29.2:
|
|
1289
1317
|
resolution: {integrity: sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==}
|
|
1290
1318
|
engines: {node: '>= 12.0.0'}
|
|
1291
1319
|
cpu: [arm64]
|
|
1292
1320
|
os: [linux]
|
|
1321
|
+
libc: [musl]
|
|
1293
1322
|
|
|
1294
1323
|
lightningcss-linux-x64-gnu@1.29.2:
|
|
1295
1324
|
resolution: {integrity: sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==}
|
|
1296
1325
|
engines: {node: '>= 12.0.0'}
|
|
1297
1326
|
cpu: [x64]
|
|
1298
1327
|
os: [linux]
|
|
1328
|
+
libc: [glibc]
|
|
1299
1329
|
|
|
1300
1330
|
lightningcss-linux-x64-musl@1.29.2:
|
|
1301
1331
|
resolution: {integrity: sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==}
|
|
1302
1332
|
engines: {node: '>= 12.0.0'}
|
|
1303
1333
|
cpu: [x64]
|
|
1304
1334
|
os: [linux]
|
|
1335
|
+
libc: [musl]
|
|
1305
1336
|
|
|
1306
1337
|
lightningcss-win32-arm64-msvc@1.29.2:
|
|
1307
1338
|
resolution: {integrity: sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==}
|