Skip to content

Commit ac59e7e

Browse files
s1gr1dmydea
andauthored
feat(ioredis): Add integration for ioredis (#11856)
Integration for Node `integrations: [Sentry.experimental_redisIntegration()]` --------- Co-authored-by: Francesco Novy <francesco.novy@sentry.io>
1 parent 85da8cf commit ac59e7e

File tree

15 files changed

+221
-1
lines changed

15 files changed

+221
-1
lines changed

MIGRATION.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ We now support the following integrations out of the box without extra configura
351351
- `mongooseIntegration`: Automatically instruments Mongoose
352352
- `mysqlIntegration`: Automatically instruments MySQL
353353
- `mysql2Integration`: Automatically instruments MySQL2
354+
- `redisIntegration`: Automatically instruments Redis (supported clients: ioredis)
354355
- `nestIntegration`: Automatically instruments Nest.js
355356
- `postgresIntegration`: Automatically instruments PostgreSQL
356357
- `prismaIntegration`: Automatically instruments Prisma

dev-packages/node-integration-tests/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"express": "^4.17.3",
4545
"graphql": "^16.3.0",
4646
"http-terminator": "^3.2.0",
47+
"ioredis": "^5.4.1",
4748
"mongodb": "^3.7.3",
4849
"mongodb-memory-server-global": "^7.6.3",
4950
"mongoose": "^5.13.22",
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
version: '3.9'
2+
3+
services:
4+
db:
5+
image: redis:latest
6+
restart: always
7+
container_name: integration-tests-redis
8+
ports:
9+
- '6379:6379'
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
const { loggingTransport } = require('@sentry-internal/node-integration-tests');
2+
const Sentry = require('@sentry/node');
3+
4+
Sentry.init({
5+
dsn: 'https://public@dsn.ingest.sentry.io/1337',
6+
release: '1.0',
7+
tracesSampleRate: 1.0,
8+
transport: loggingTransport,
9+
});
10+
11+
// Stop the process from exiting before the transaction is sent
12+
setInterval(() => {}, 1000);
13+
14+
const Redis = require('ioredis');
15+
16+
const redis = new Redis({ port: 6379 });
17+
18+
async function run() {
19+
await Sentry.startSpan(
20+
{
21+
name: 'Test Transaction',
22+
op: 'transaction',
23+
},
24+
async () => {
25+
try {
26+
await redis.set('test-key', 'test-value');
27+
28+
await redis.get('test-key');
29+
} finally {
30+
await redis.disconnect();
31+
}
32+
},
33+
);
34+
}
35+
36+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
37+
run();
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
2+
3+
describe('redis auto instrumentation', () => {
4+
afterAll(() => {
5+
cleanupChildProcesses();
6+
});
7+
8+
test('should auto-instrument `ioredis` package when using redis.set() and redis.get()', done => {
9+
const EXPECTED_TRANSACTION = {
10+
transaction: 'Test Transaction',
11+
spans: expect.arrayContaining([
12+
expect.objectContaining({
13+
description: 'set test-key [1 other arguments]',
14+
op: 'db',
15+
data: expect.objectContaining({
16+
'db.system': 'redis',
17+
'net.peer.name': 'localhost',
18+
'net.peer.port': 6379,
19+
'db.statement': 'set test-key [1 other arguments]',
20+
}),
21+
}),
22+
expect.objectContaining({
23+
description: 'get test-key',
24+
op: 'db',
25+
data: expect.objectContaining({
26+
'db.system': 'redis',
27+
'net.peer.name': 'localhost',
28+
'net.peer.port': 6379,
29+
'db.statement': 'get test-key',
30+
}),
31+
}),
32+
]),
33+
};
34+
35+
createRunner(__dirname, 'scenario-ioredis.js')
36+
.withDockerCompose({ workingDirectory: [__dirname], readyMatches: ['port=6379'] })
37+
.expect({ transaction: EXPECTED_TRANSACTION })
38+
.start(done);
39+
});
40+
});

packages/astro/src/index.server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export {
8080
mongooseIntegration,
8181
mysqlIntegration,
8282
mysql2Integration,
83+
redisIntegration,
8384
nestIntegration,
8485
setupNestErrorHandler,
8586
postgresIntegration,

packages/aws-serverless/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export {
8585
mongooseIntegration,
8686
mysqlIntegration,
8787
mysql2Integration,
88+
redisIntegration,
8889
nestIntegration,
8990
setupNestErrorHandler,
9091
postgresIntegration,

packages/bun/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ export {
106106
mongooseIntegration,
107107
mysqlIntegration,
108108
mysql2Integration,
109+
redisIntegration,
109110
nestIntegration,
110111
setupNestErrorHandler,
111112
postgresIntegration,

packages/google-cloud-serverless/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export {
8585
mongooseIntegration,
8686
mysqlIntegration,
8787
mysql2Integration,
88+
redisIntegration,
8889
nestIntegration,
8990
setupNestErrorHandler,
9091
postgresIntegration,

packages/node/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"@opentelemetry/instrumentation-graphql": "0.39.0",
6464
"@opentelemetry/instrumentation-hapi": "0.36.0",
6565
"@opentelemetry/instrumentation-http": "0.48.0",
66+
"@opentelemetry/instrumentation-ioredis": "0.40.0",
6667
"@opentelemetry/instrumentation-koa": "0.39.0",
6768
"@opentelemetry/instrumentation-mongodb": "0.39.0",
6869
"@opentelemetry/instrumentation-mongoose": "0.37.0",

packages/node/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export { mongoIntegration } from './integrations/tracing/mongo';
1717
export { mongooseIntegration } from './integrations/tracing/mongoose';
1818
export { mysqlIntegration } from './integrations/tracing/mysql';
1919
export { mysql2Integration } from './integrations/tracing/mysql2';
20+
export { redisIntegration } from './integrations/tracing/redis';
2021
export { nestIntegration, setupNestErrorHandler } from './integrations/tracing/nest';
2122
export { postgresIntegration } from './integrations/tracing/postgres';
2223
export { prismaIntegration } from './integrations/tracing/prisma';

packages/node/src/integrations/tracing/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { mysqlIntegration } from './mysql';
1212
import { mysql2Integration } from './mysql2';
1313
import { nestIntegration } from './nest';
1414
import { postgresIntegration } from './postgres';
15+
import { redisIntegration } from './redis';
1516

1617
/**
1718
* With OTEL, all performance integrations will be added, as OTEL only initializes them when the patched package is actually required.
@@ -25,6 +26,7 @@ export function getAutoPerformanceIntegrations(): Integration[] {
2526
mongooseIntegration(),
2627
mysqlIntegration(),
2728
mysql2Integration(),
29+
redisIntegration(),
2830
postgresIntegration(),
2931
// For now, we do not include prisma by default because it has ESM issues
3032
// See https://github.com/prisma/prisma/issues/23410
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { IORedisInstrumentation } from '@opentelemetry/instrumentation-ioredis';
2+
import { defineIntegration } from '@sentry/core';
3+
import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry';
4+
import type { IntegrationFn } from '@sentry/types';
5+
6+
const _redisIntegration = (() => {
7+
return {
8+
name: 'Redis',
9+
setupOnce() {
10+
addOpenTelemetryInstrumentation([
11+
new IORedisInstrumentation({}),
12+
// todo: implement them gradually
13+
// new LegacyRedisInstrumentation({}),
14+
// new RedisInstrumentation({}),
15+
]);
16+
},
17+
};
18+
}) satisfies IntegrationFn;
19+
20+
/**
21+
* Redis integration for "ioredis"
22+
*
23+
* Capture tracing data for redis and ioredis.
24+
*/
25+
export const redisIntegration = defineIntegration(_redisIntegration);

packages/remix/src/index.server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ export {
8686
mongooseIntegration,
8787
mysqlIntegration,
8888
mysql2Integration,
89+
redisIntegration,
8990
nestIntegration,
9091
setupNestErrorHandler,
9192
postgresIntegration,

yarn.lock

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5077,6 +5077,11 @@
50775077
resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340"
50785078
integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==
50795079

5080+
"@ioredis/commands@^1.1.1":
5081+
version "1.2.0"
5082+
resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11"
5083+
integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==
5084+
50805085
"@isaacs/cliui@^8.0.2":
50815086
version "8.0.2"
50825087
resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
@@ -6114,6 +6119,13 @@
61146119
dependencies:
61156120
"@opentelemetry/api" "^1.0.0"
61166121

6122+
"@opentelemetry/api-logs@0.51.0":
6123+
version "0.51.0"
6124+
resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.51.0.tgz#71f296661d2215167c748ca044ff184a65d9426b"
6125+
integrity sha512-m/jtfBPEIXS1asltl8fPQtO3Sb1qMpuL61unQajUmM8zIxeMF1AlqzWXM3QedcYgTTFiJCew5uJjyhpmqhc0+g==
6126+
dependencies:
6127+
"@opentelemetry/api" "^1.0.0"
6128+
61176129
"@opentelemetry/api@1.8.0", "@opentelemetry/api@^1.0.0", "@opentelemetry/api@^1.6.0", "@opentelemetry/api@^1.8.0":
61186130
version "1.8.0"
61196131
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.8.0.tgz#5aa7abb48f23f693068ed2999ae627d2f7d902ec"
@@ -6235,6 +6247,15 @@
62356247
"@opentelemetry/semantic-conventions" "1.21.0"
62366248
semver "^7.5.2"
62376249

6250+
"@opentelemetry/instrumentation-ioredis@0.40.0":
6251+
version "0.40.0"
6252+
resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.40.0.tgz#3a747dc44c6244d7f4c8cc98a6b75b9856241eaf"
6253+
integrity sha512-Jv/fH7KhpWe4KBirsiqeUJIYrsdR2iu2l4nWhfOlRvaZ+zYIiLEzTQR6QhBbyRoAbU4OuYJzjWusOmmpGBnwng==
6254+
dependencies:
6255+
"@opentelemetry/instrumentation" "^0.51.0"
6256+
"@opentelemetry/redis-common" "^0.36.2"
6257+
"@opentelemetry/semantic-conventions" "^1.0.0"
6258+
62386259
"@opentelemetry/instrumentation-koa@0.39.0":
62396260
version "0.39.0"
62406261
resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.39.0.tgz#9c01d40a444e592a95b6e39ba0bbe94e096bfc31"
@@ -6301,6 +6322,24 @@
63016322
"@types/pg" "8.6.1"
63026323
"@types/pg-pool" "2.0.4"
63036324

6325+
"@opentelemetry/instrumentation-redis-4@0.39.0":
6326+
version "0.39.0"
6327+
resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-redis-4/-/instrumentation-redis-4-0.39.0.tgz#9f9950bca3eb7e2f1cfc53a003c4eef64d8846bc"
6328+
integrity sha512-Zpfqfi83KeKgVQ0C2083GZPon3ZPYQ5E59v9FAbhubtOoUb9Rh7n111YD8FPW3sgx6JKp1odXmBmfQhWCaTOpQ==
6329+
dependencies:
6330+
"@opentelemetry/instrumentation" "^0.51.0"
6331+
"@opentelemetry/redis-common" "^0.36.2"
6332+
"@opentelemetry/semantic-conventions" "^1.22.0"
6333+
6334+
"@opentelemetry/instrumentation-redis@0.39.0":
6335+
version "0.39.0"
6336+
resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.39.0.tgz#66a9d94a726deb0ef9c340ba504764ae457676a1"
6337+
integrity sha512-yjHWwufY7kfKtf20rliqlETgP32X3ZynGAfoP59NXSSHwTCZS7QMn+S+Hb0iLjwbca/iTM/BooiVFrB943kMrw==
6338+
dependencies:
6339+
"@opentelemetry/instrumentation" "^0.51.0"
6340+
"@opentelemetry/redis-common" "^0.36.2"
6341+
"@opentelemetry/semantic-conventions" "^1.22.0"
6342+
63046343
"@opentelemetry/instrumentation@0.48.0", "@opentelemetry/instrumentation@^0.48.0":
63056344
version "0.48.0"
63066345
resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.48.0.tgz#a6dee936e973f1270c464657a55bb570807194aa"
@@ -6335,6 +6374,18 @@
63356374
semver "^7.5.2"
63366375
shimmer "^1.2.1"
63376376

6377+
"@opentelemetry/instrumentation@^0.51.0":
6378+
version "0.51.0"
6379+
resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.51.0.tgz#93dbe96c87da539081d0ccd07475cfc0b0c61233"
6380+
integrity sha512-Eg/+Od5bEvzpvZQGhvMyKIkrzB9S7jW+6z9LHEI2VXhl/GrqQ3oBqlzJt4tA6pGtxRmqQWKWGM1wAbwDdW/gUA==
6381+
dependencies:
6382+
"@opentelemetry/api-logs" "0.51.0"
6383+
"@types/shimmer" "^1.0.2"
6384+
import-in-the-middle "1.7.1"
6385+
require-in-the-middle "^7.1.1"
6386+
semver "^7.5.2"
6387+
shimmer "^1.2.1"
6388+
63386389
"@opentelemetry/propagation-utils@^0.30.8":
63396390
version "0.30.8"
63406391
resolved "https://registry.yarnpkg.com/@opentelemetry/propagation-utils/-/propagation-utils-0.30.8.tgz#5ae1468250e4f225be98b70aed994586248e2de3"
@@ -6347,6 +6398,11 @@
63476398
dependencies:
63486399
"@opentelemetry/core" "^1.0.0"
63496400

6401+
"@opentelemetry/redis-common@^0.36.2":
6402+
version "0.36.2"
6403+
resolved "https://registry.yarnpkg.com/@opentelemetry/redis-common/-/redis-common-0.36.2.tgz#906ac8e4d804d4109f3ebd5c224ac988276fdc47"
6404+
integrity sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g==
6405+
63506406
"@opentelemetry/resources@1.23.0", "@opentelemetry/resources@^1.23.0", "@opentelemetry/resources@^1.8.0":
63516407
version "1.23.0"
63526408
resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.23.0.tgz#4c71430f3e20c4d88b67ef5629759fae108485e5"
@@ -12736,6 +12792,11 @@ clsx@^2.0.0:
1273612792
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b"
1273712793
integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==
1273812794

12795+
cluster-key-slot@^1.1.0:
12796+
version "1.1.2"
12797+
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac"
12798+
integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==
12799+
1273912800
cmd-shim@6.0.1:
1274012801
version "6.0.1"
1274112802
resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.1.tgz#a65878080548e1dca760b3aea1e21ed05194da9d"
@@ -18886,6 +18947,21 @@ invariant@^2.2.1, invariant@^2.2.2:
1888618947
dependencies:
1888718948
loose-envify "^1.0.0"
1888818949

18950+
ioredis@^5.4.1:
18951+
version "5.4.1"
18952+
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.4.1.tgz#1c56b70b759f01465913887375ed809134296f40"
18953+
integrity sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==
18954+
dependencies:
18955+
"@ioredis/commands" "^1.1.1"
18956+
cluster-key-slot "^1.1.0"
18957+
debug "^4.3.4"
18958+
denque "^2.1.0"
18959+
lodash.defaults "^4.2.0"
18960+
lodash.isarguments "^3.1.0"
18961+
redis-errors "^1.2.0"
18962+
redis-parser "^3.0.0"
18963+
standard-as-callback "^2.1.0"
18964+
1888918965
ip@^2.0.0:
1889018966
version "2.0.0"
1889118967
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
@@ -20915,6 +20991,11 @@ lodash.debounce@^4.0.8:
2091520991
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
2091620992
integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
2091720993

20994+
lodash.defaults@^4.2.0:
20995+
version "4.2.0"
20996+
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
20997+
integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==
20998+
2091820999
lodash.defaultsdeep@^4.6.1:
2091921000
version "4.6.1"
2092021001
resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6"
@@ -20943,7 +21024,7 @@ lodash.get@^4.4.2:
2094321024
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
2094421025
integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==
2094521026

20946-
lodash.isarguments@^3.0.0:
21027+
lodash.isarguments@^3.0.0, lodash.isarguments@^3.1.0:
2094721028
version "3.1.0"
2094821029
resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
2094921030
integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=
@@ -25963,6 +26044,18 @@ redeyed@~1.0.0:
2596326044
dependencies:
2596426045
esprima "~3.0.0"
2596526046

26047+
redis-errors@^1.0.0, redis-errors@^1.2.0:
26048+
version "1.2.0"
26049+
resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad"
26050+
integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==
26051+
26052+
redis-parser@^3.0.0:
26053+
version "3.0.0"
26054+
resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4"
26055+
integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==
26056+
dependencies:
26057+
redis-errors "^1.0.0"
26058+
2596626059
redux@^4.0.5:
2596726060
version "4.0.5"
2596826061
resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f"
@@ -27830,6 +27923,11 @@ stagehand@^1.0.0:
2783027923
dependencies:
2783127924
debug "^4.1.0"
2783227925

27926+
standard-as-callback@^2.1.0:
27927+
version "2.1.0"
27928+
resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45"
27929+
integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==
27930+
2783327931
static-extend@^0.1.1:
2783427932
version "0.1.2"
2783527933
resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"

0 commit comments

Comments
 (0)