mirror of
https://github.com/suitenumerique/docs.git
synced 2026-09-26 11:35:05 +02:00
✨(collaboration) report yhub errors to sentry
Sentry can be used to report errors in yhub-server service
This commit is contained in:
@@ -15,6 +15,8 @@ and this project adheres to
|
||||
- ✨(backend) expose the attachment max size in the config endpoint #2577
|
||||
- ✨(frontend) warn before uploading an attachment over the size limit #2577
|
||||
- ✨(frontend) add keyboard shortcut to open presentation mode #2697
|
||||
- ✨(collaboration) report yhub errors to sentry, configured through
|
||||
`SENTRY_*`
|
||||
- ✨(backend) add opt-in prometheus metrics on `/metrics`, protected by a
|
||||
bearer token
|
||||
- ✨(helm) add a dedicated ingress for the prometheus metrics
|
||||
|
||||
@@ -194,6 +194,11 @@ documents what each of them changes.
|
||||
| YHUB_TASK_CONCURRENCY | Tasks one worker process claims at once | 5 |
|
||||
| YHUB_TASK_DEBOUNCE_MS | How long an update waits on the redis stream before a worker persists it | 10000 |
|
||||
| YHUB_MIN_MESSAGE_LIFETIME_MS | How long persisted updates stay replayable from redis rather than read back from postgres | 60000 |
|
||||
| SENTRY_DSN | Sentry DSN, unset disables it: the SDK is then not even loaded. Can be read from a file with SENTRY_DSN_FILE | |
|
||||
| SENTRY_ENVIRONMENT | Environment the events are reported under | production |
|
||||
| SENTRY_RELEASE | Release the events are reported under. Detected by the SDK when unset | |
|
||||
| SENTRY_TRACES_SAMPLE_RATE | Share of the traces sent to Sentry, between `0` and `1` | 0 |
|
||||
| SENTRY_PROFILES_SAMPLE_RATE | Share of the sampled traces that are also profiled, between `0` and `1`. The native profiler is only loaded above `0` | 0 |
|
||||
| SOFT_MIGRATION | Set to "true" to seed a room from the legacy Django/S3 document store the first time it is opened | false |
|
||||
| LEGACY_S3_ENDPOINT_URL | Required by SOFT_MIGRATION, endpoint of the legacy media bucket, without a path | |
|
||||
| LEGACY_S3_ACCESS_KEY_ID | Required by SOFT_MIGRATION, read access to that bucket (or LEGACY_S3_ACCESS_KEY_ID_FILE) | |
|
||||
|
||||
@@ -70,4 +70,6 @@ USER ${DOCKER_USER}
|
||||
|
||||
ENTRYPOINT [ "/usr/local/bin/entrypoint" ]
|
||||
|
||||
CMD ["node", "dist/server.js"]
|
||||
# sentry.js is preloaded so that error reporting is in place before anything else
|
||||
# is imported; it does nothing without a SENTRY_DSN
|
||||
CMD ["node", "--import", "./dist/sentry.js", "dist/server.js"]
|
||||
|
||||
@@ -391,6 +391,43 @@ made *versioned*, so what is exercised is what a deployment runs rather than a
|
||||
simpler case. Watch it with `mc ls --versions --recursive impress/yhub-storage`
|
||||
from an `mc` container on the stack's network.
|
||||
|
||||
## Error reporting (Sentry)
|
||||
|
||||
`src/sentry.ts` is preloaded by the start command
|
||||
(`node --import ./dist/sentry.js dist/server.js`), the way y-provider does it:
|
||||
the SDK hooks the modules it instruments as they are loaded, so it has to be
|
||||
there before `server.ts` imports anything. A deployment that overrides the
|
||||
command of the container has to keep the `--import`.
|
||||
|
||||
| Variable | Default | What it changes |
|
||||
| -------- | ------- | --------------- |
|
||||
| `SENTRY_DSN` | — | Where to report. Unset: nothing is reported and the SDK is not loaded (or `…_FILE`) |
|
||||
| `SENTRY_ENVIRONMENT` | `production` | Environment the events are reported under |
|
||||
| `SENTRY_RELEASE` | detected | Release the events are reported under |
|
||||
| `SENTRY_TRACES_SAMPLE_RATE` | `0` | Share of the traces that are sent, `0` to `1` |
|
||||
| `SENTRY_PROFILES_SAMPLE_RATE` | `0` | Share of the sampled traces that are profiled, `0` to `1` |
|
||||
|
||||
A rate that is not a number between 0 and 1 is a startup error.
|
||||
|
||||
What is reported:
|
||||
|
||||
- uncaught exceptions and unhandled rejections. The process still ends on an
|
||||
unhandled rejection, as it does without Sentry: the SDK's default would
|
||||
report it and carry on;
|
||||
- every `error` and `fatal` line of the logger, with its fields as context.
|
||||
yhub and this wrapper share one pino logger, and that is where a failed
|
||||
upgrade, compaction or migration ends up — none of them is thrown to anything
|
||||
that could report it. `warn` lines (a backend that did not answer, a lost
|
||||
`content-updated` notification) are not sent.
|
||||
|
||||
Every event carries the tags `application: yhub-server` and `role` (the
|
||||
`YHUB_ROLE` of the process), the server and the worker being one image.
|
||||
|
||||
Traces are of limited use here: the websocket server is uWebSockets.js, which
|
||||
the SDK does not instrument, so there is no span for an upgrade or a message.
|
||||
What is traced is the outgoing side — the calls to the backend, postgres,
|
||||
redis — when something starts a trace around them.
|
||||
|
||||
## Tests
|
||||
|
||||
`yarn test` runs the **vitest** suite under `__tests__/*.spec.ts`
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
// sentry.ts — the module preloaded with `node --import`. Tested with both SDK
|
||||
// packages mocked: the environment goes in, and what is handed to `Sentry.init`
|
||||
// (or the fact that the SDK was never touched) comes out.
|
||||
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
const sentry = vi.hoisted(() => ({
|
||||
loaded: vi.fn(),
|
||||
init: vi.fn(),
|
||||
setTag: vi.fn(),
|
||||
pinoIntegration: vi.fn((options: unknown) => ({ name: 'Pino', options })),
|
||||
onUnhandledRejectionIntegration: vi.fn((options: unknown) => ({
|
||||
name: 'OnUnhandledRejection',
|
||||
options,
|
||||
})),
|
||||
}));
|
||||
const profiling = vi.hoisted(() => ({
|
||||
loaded: vi.fn(),
|
||||
nodeProfilingIntegration: vi.fn(() => ({ name: 'ProfilingIntegration' })),
|
||||
}));
|
||||
|
||||
vi.mock('@sentry/node', () => {
|
||||
sentry.loaded();
|
||||
return sentry;
|
||||
});
|
||||
vi.mock('@sentry/profiling-node', () => {
|
||||
profiling.loaded();
|
||||
return profiling;
|
||||
});
|
||||
|
||||
const load = () => import('../src/sentry.js');
|
||||
|
||||
beforeEach(() => {
|
||||
vi.unstubAllEnvs();
|
||||
vi.resetModules();
|
||||
vi.clearAllMocks();
|
||||
for (const key of [
|
||||
'SENTRY_DSN',
|
||||
'SENTRY_DSN_FILE',
|
||||
'SENTRY_ENVIRONMENT',
|
||||
'SENTRY_RELEASE',
|
||||
'SENTRY_TRACES_SAMPLE_RATE',
|
||||
'SENTRY_PROFILES_SAMPLE_RATE',
|
||||
'YHUB_ROLE',
|
||||
]) {
|
||||
vi.stubEnv(key, '');
|
||||
}
|
||||
});
|
||||
|
||||
describe('without a SENTRY_DSN', () => {
|
||||
it('does not even import the SDK', async () => {
|
||||
await load();
|
||||
|
||||
expect(sentry.loaded).not.toHaveBeenCalled();
|
||||
expect(profiling.loaded).not.toHaveBeenCalled();
|
||||
expect(sentry.init).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('ignores the other settings', async () => {
|
||||
vi.stubEnv('SENTRY_TRACES_SAMPLE_RATE', '1');
|
||||
vi.stubEnv('SENTRY_PROFILES_SAMPLE_RATE', '1');
|
||||
|
||||
await load();
|
||||
|
||||
expect(sentry.loaded).not.toHaveBeenCalled();
|
||||
expect(profiling.loaded).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('with a SENTRY_DSN', () => {
|
||||
beforeEach(() => {
|
||||
vi.stubEnv('SENTRY_DSN', 'https://key@sentry.example.com/1');
|
||||
});
|
||||
|
||||
it('reports errors only, by default', async () => {
|
||||
await load();
|
||||
|
||||
expect(sentry.init).toHaveBeenCalledTimes(1);
|
||||
expect(sentry.init).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
dsn: 'https://key@sentry.example.com/1',
|
||||
environment: undefined,
|
||||
release: undefined,
|
||||
tracesSampleRate: 0,
|
||||
profilesSampleRate: 0,
|
||||
}),
|
||||
);
|
||||
// the native profiler is not loaded by a deployment that does not profile
|
||||
expect(profiling.loaded).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('reports the error lines of the logger and keeps node crashing on unhandled rejections', async () => {
|
||||
await load();
|
||||
|
||||
expect(sentry.pinoIntegration).toHaveBeenCalledWith({
|
||||
error: { levels: ['error', 'fatal'] },
|
||||
});
|
||||
expect(sentry.onUnhandledRejectionIntegration).toHaveBeenCalledWith({
|
||||
mode: 'strict',
|
||||
});
|
||||
const { integrations } = sentry.init.mock.calls[0][0] as {
|
||||
integrations: Array<{ name: string }>;
|
||||
};
|
||||
expect(integrations.map(({ name }) => name)).toEqual([
|
||||
'Pino',
|
||||
'OnUnhandledRejection',
|
||||
]);
|
||||
});
|
||||
|
||||
it('takes the environment, the release and the sampling rates from the environment', async () => {
|
||||
vi.stubEnv('SENTRY_ENVIRONMENT', 'preprod');
|
||||
vi.stubEnv('SENTRY_RELEASE', 'docs@5.0.0');
|
||||
vi.stubEnv('SENTRY_TRACES_SAMPLE_RATE', '0.25');
|
||||
vi.stubEnv('SENTRY_PROFILES_SAMPLE_RATE', '0.5');
|
||||
|
||||
await load();
|
||||
|
||||
expect(sentry.init).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
environment: 'preprod',
|
||||
release: 'docs@5.0.0',
|
||||
tracesSampleRate: 0.25,
|
||||
profilesSampleRate: 0.5,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('loads the profiler only when profiles are sampled', async () => {
|
||||
vi.stubEnv('SENTRY_PROFILES_SAMPLE_RATE', '0.5');
|
||||
|
||||
await load();
|
||||
|
||||
expect(profiling.nodeProfilingIntegration).toHaveBeenCalledTimes(1);
|
||||
const { integrations } = sentry.init.mock.calls[0][0] as {
|
||||
integrations: Array<{ name: string }>;
|
||||
};
|
||||
expect(integrations.map(({ name }) => name)).toContain(
|
||||
'ProfilingIntegration',
|
||||
);
|
||||
});
|
||||
|
||||
it('tags the events with the application and the role of the process', async () => {
|
||||
vi.stubEnv('YHUB_ROLE', 'worker');
|
||||
|
||||
await load();
|
||||
|
||||
expect(sentry.setTag).toHaveBeenCalledWith('application', 'yhub-server');
|
||||
expect(sentry.setTag).toHaveBeenCalledWith('role', 'worker');
|
||||
});
|
||||
|
||||
it.each([
|
||||
['SENTRY_TRACES_SAMPLE_RATE', 'abc'],
|
||||
['SENTRY_TRACES_SAMPLE_RATE', '1.5'],
|
||||
['SENTRY_PROFILES_SAMPLE_RATE', '-0.1'],
|
||||
])('refuses to start when %s is "%s"', async (name, value) => {
|
||||
vi.stubEnv(name, value);
|
||||
|
||||
await expect(load()).rejects.toThrow(
|
||||
`${name} must be a number between 0 and 1 (got "${value}")`,
|
||||
);
|
||||
expect(sentry.init).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -5,7 +5,7 @@
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.build.json",
|
||||
"typecheck": "tsc -p tsconfig.json --noEmit",
|
||||
"start": "node dist/server.js",
|
||||
"start": "node --import ./dist/sentry.js dist/server.js",
|
||||
"dev": "nodemon --config nodemon.json",
|
||||
"init-db": "node node_modules/@y/hub/bin/init-db.js",
|
||||
"lint": "eslint",
|
||||
@@ -14,6 +14,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "3.1110.0",
|
||||
"@sentry/node": "10.70.0",
|
||||
"@sentry/profiling-node": "10.70.0",
|
||||
"@y/hub": "0.9.0",
|
||||
"@y/y": "14.0.0-rc.25",
|
||||
"jose": "6.2.8"
|
||||
|
||||
@@ -24,6 +24,17 @@ const intEnv = (name: string, dflt: number, min = 1): number => {
|
||||
return value;
|
||||
};
|
||||
|
||||
// A sampling rate, refused rather than guessed when it is not a number between
|
||||
// 0 and 1: Sentry reads anything else as "drop everything" and says so nowhere.
|
||||
const rateEnv = (name: string, dflt: number): number => {
|
||||
const raw = process.env[name];
|
||||
const value = raw == null || raw === '' ? dflt : Number(raw);
|
||||
if (!Number.isFinite(value) || value < 0 || value > 1) {
|
||||
throw new Error(`${name} must be a number between 0 and 1 (got "${raw}")`);
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
export const PORT = Number(process.env.PORT || 3002);
|
||||
export const REDIS = process.env.REDIS;
|
||||
export const POSTGRES = process.env.POSTGRES;
|
||||
@@ -155,3 +166,20 @@ export const BACKEND_TOKEN_MARGIN_MS = 10000;
|
||||
// signs to call us: no long-lived shared secret, only our private key here and
|
||||
// its public half published on the JWKS endpoint.
|
||||
export const YHUB_JWT_PRIVATE_KEY = secret('YHUB_JWT_PRIVATE_KEY', '');
|
||||
|
||||
// Error reporting, set up by `sentry.ts` before anything else is loaded. No DSN,
|
||||
// no Sentry: the SDK is not even imported.
|
||||
export const SENTRY_DSN = secret('SENTRY_DSN', '');
|
||||
// Left to the SDK when unset: it reports "production", and reads the release
|
||||
// from what the platform exposes.
|
||||
export const SENTRY_ENVIRONMENT = process.env.SENTRY_ENVIRONMENT || undefined;
|
||||
export const SENTRY_RELEASE = process.env.SENTRY_RELEASE || undefined;
|
||||
// Both off by default, like the backend. The websocket server is not an http
|
||||
// server the SDK knows how to trace, so a trace here is the outgoing calls (the
|
||||
// backend, postgres, redis) rather than a request from end to end.
|
||||
export const SENTRY_TRACES_SAMPLE_RATE = rateEnv('SENTRY_TRACES_SAMPLE_RATE', 0);
|
||||
// Relative to the traces: the share of sampled traces that are also profiled.
|
||||
export const SENTRY_PROFILES_SAMPLE_RATE = rateEnv(
|
||||
'SENTRY_PROFILES_SAMPLE_RATE',
|
||||
0,
|
||||
);
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Error reporting. Preloaded with `node --import ./dist/sentry.js`, the way
|
||||
* y-provider does it: the SDK hooks the modules it instruments as they are
|
||||
* loaded, so it has to be initialised before `server.ts` imports any of them.
|
||||
*
|
||||
* Everything is read from the environment (`config.ts`), and without a
|
||||
* `SENTRY_DSN` nothing happens at all — the SDK is imported on demand, so a
|
||||
* deployment that does not use Sentry does not pay for it.
|
||||
*
|
||||
* What reaches Sentry:
|
||||
* - uncaught exceptions and unhandled rejections;
|
||||
* - every `error` and `fatal` line of the pino logger, ours and yhub's — it is
|
||||
* one logger, and it is where a failed upgrade, compaction or migration ends
|
||||
* up, none of them being thrown to anything that could report it;
|
||||
* - traces and profiles, when their sampling rates ask for them.
|
||||
*/
|
||||
import {
|
||||
ROLE,
|
||||
SENTRY_DSN,
|
||||
SENTRY_ENVIRONMENT,
|
||||
SENTRY_PROFILES_SAMPLE_RATE,
|
||||
SENTRY_RELEASE,
|
||||
SENTRY_TRACES_SAMPLE_RATE,
|
||||
} from './config.js';
|
||||
|
||||
if (SENTRY_DSN) {
|
||||
const Sentry = await import('@sentry/node');
|
||||
|
||||
const integrations = [
|
||||
Sentry.pinoIntegration({ error: { levels: ['error', 'fatal'] } }),
|
||||
// Node ends the process on an unhandled rejection. The SDK's default would
|
||||
// report it and carry on, which makes a server behave differently with and
|
||||
// without error reporting: report it, then end as Node would have.
|
||||
Sentry.onUnhandledRejectionIntegration({ mode: 'strict' }),
|
||||
];
|
||||
if (SENTRY_PROFILES_SAMPLE_RATE > 0) {
|
||||
// a native module: only loaded by the deployments that profile
|
||||
const { nodeProfilingIntegration } = await import('@sentry/profiling-node');
|
||||
integrations.push(nodeProfilingIntegration());
|
||||
}
|
||||
|
||||
Sentry.init({
|
||||
dsn: SENTRY_DSN,
|
||||
environment: SENTRY_ENVIRONMENT,
|
||||
release: SENTRY_RELEASE,
|
||||
integrations,
|
||||
tracesSampleRate: SENTRY_TRACES_SAMPLE_RATE,
|
||||
profilesSampleRate: SENTRY_PROFILES_SAMPLE_RATE,
|
||||
});
|
||||
Sentry.setTag('application', 'yhub-server');
|
||||
// the server and the worker are the same image: tell them apart
|
||||
Sentry.setTag('role', ROLE);
|
||||
}
|
||||
+236
-3
@@ -2,6 +2,37 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@apm-js-collab/code-transformer-bundler-plugins@^0.7.3":
|
||||
version "0.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@apm-js-collab/code-transformer-bundler-plugins/-/code-transformer-bundler-plugins-0.7.4.tgz#f323d5f723565e34f1409aa96e445ad489020f76"
|
||||
integrity sha512-nAfOeZPSUAQvJa1iFT/5oCrTm5YQhMMrfCNthNnaXHZiOQhu1KGuLoIx7HtbAi3wfwaBYLaICPIeenIaEwcXIg==
|
||||
dependencies:
|
||||
"@apm-js-collab/code-transformer" "^0.18.1"
|
||||
es-module-lexer "^2.1.0"
|
||||
magic-string "^0.30.21"
|
||||
module-details-from-path "^1.0.4"
|
||||
|
||||
"@apm-js-collab/code-transformer@^0.18.0", "@apm-js-collab/code-transformer@^0.18.1":
|
||||
version "0.18.1"
|
||||
resolved "https://registry.yarnpkg.com/@apm-js-collab/code-transformer/-/code-transformer-0.18.1.tgz#66ce01cfe9607779b4abebb4f54c49a46e8b48ca"
|
||||
integrity sha512-u1Hb6bHjWtkSpiprwVP6YaHC1DTN4RAU3zYkUDUe7WMnJwdyU1pwTL9dFKiSJB9IiLue/EQovmyx6xhU7FFtAQ==
|
||||
dependencies:
|
||||
"@types/estree" "^1.0.8"
|
||||
astring "^1.9.0"
|
||||
esquery "^1.7.0"
|
||||
meriyah "^6.1.4"
|
||||
semifies "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
"@apm-js-collab/tracing-hooks@^0.13.0":
|
||||
version "0.13.2"
|
||||
resolved "https://registry.yarnpkg.com/@apm-js-collab/tracing-hooks/-/tracing-hooks-0.13.2.tgz#c219d04bf115bf7828a8887e437c0d6c888159f0"
|
||||
integrity sha512-jk3acBAJecK8ctMGlkappcX5CtymTxmd0GGnUqh4ZX3Pk1RbXei/vzGEDTeOHcXJ6wsRkm8PhHsfOba0jxB67A==
|
||||
dependencies:
|
||||
"@apm-js-collab/code-transformer" "^0.18.0"
|
||||
debug "^4.4.1"
|
||||
module-details-from-path "^1.0.4"
|
||||
|
||||
"@aws-sdk/checksums@^3.1000.27":
|
||||
version "3.1000.29"
|
||||
resolved "https://registry.yarnpkg.com/@aws-sdk/checksums/-/checksums-3.1000.29.tgz#f12a6926eb3789057f5f16582fc226fe533c87fa"
|
||||
@@ -450,6 +481,66 @@
|
||||
resolved "https://registry.yarnpkg.com/@nodable/entities/-/entities-3.0.0.tgz#694703bc864d30eaed55c2e3def00dbd61493670"
|
||||
integrity sha512-8L9xFeTYKhm49xfIypoe2W5wV1m/3Z58kT+7kR9A8OyFxcPduI4VmxaUMQyKYrRjUoLLSXv6EKKID5Tvj9cUVw==
|
||||
|
||||
"@opentelemetry/api-logs@0.220.0":
|
||||
version "0.220.0"
|
||||
resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.220.0.tgz#b2ed235de4b5f3c1769adfa5f3bc247d82cdfbc9"
|
||||
integrity sha512-CmVa4ImJ+ynfrPMNaAXHET6Bhb44SwzmfyVJFq9ni2jgXJR/l7C6gfVFddNmHP+ZOkP9cf4f9DBe68qVLTHc9w==
|
||||
dependencies:
|
||||
"@opentelemetry/api" "^1.3.0"
|
||||
|
||||
"@opentelemetry/api@^1.3.0", "@opentelemetry/api@^1.9.1":
|
||||
version "1.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.1.tgz#c1b0346de336ba55af2d5a7970882037baedec05"
|
||||
integrity sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==
|
||||
|
||||
"@opentelemetry/core@2.11.0":
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-2.11.0.tgz#97849d3808bba652568b7d53e20c9fc38bcb7c49"
|
||||
integrity sha512-7YP44XH0tV6+Mb54x2YGf84i7yi+31MBZlE8JwvozkxyTvXbSp10X7cI7YE49ChJ3shMJoBmCJF3+1QFBJctGA==
|
||||
dependencies:
|
||||
"@opentelemetry/semantic-conventions" "^1.29.0"
|
||||
|
||||
"@opentelemetry/instrumentation@^0.220.0":
|
||||
version "0.220.0"
|
||||
resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.220.0.tgz#542b36bf4871dd83dc84e1373ac4bbcd35a8bfb8"
|
||||
integrity sha512-xQx3E2WxP1mDvKzxLxX+CTCtNLa560YJZ3087qYHerl2YmiKpv7AH+dAy7vmx+eVrZ5BwhfWUAVoKOoxCNHcpw==
|
||||
dependencies:
|
||||
"@opentelemetry/api-logs" "0.220.0"
|
||||
import-in-the-middle "^3.0.0"
|
||||
require-in-the-middle "^8.0.0"
|
||||
|
||||
"@opentelemetry/resources@2.11.0":
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-2.11.0.tgz#b4e60ba92a4f122dc979f3402aea9713a98eac5b"
|
||||
integrity sha512-Ie7+8q8MDF4FAEQCKVMTx3ReUvxiIAgIiiW3c9JdmP8+HMcDy20puT+AHjexnExgnbvBxjQ9fjkFDWrikJ2jQA==
|
||||
dependencies:
|
||||
"@opentelemetry/core" "2.11.0"
|
||||
"@opentelemetry/semantic-conventions" "^1.29.0"
|
||||
|
||||
"@opentelemetry/sdk-trace-base@^2.9.0":
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.11.0.tgz#3f725401fcfb16e5b2335c103cdc9488829632d1"
|
||||
integrity sha512-H19x/TX/LZdqiYOjM7fqtSxwlplC5pgelavqbQdHbhdq0q/AI/TGkM2dfGuuynTXmJPeF2HoZVoPDu+TGoW78A==
|
||||
dependencies:
|
||||
"@opentelemetry/core" "2.11.0"
|
||||
"@opentelemetry/resources" "2.11.0"
|
||||
"@opentelemetry/sdk-trace" "2.11.0"
|
||||
"@opentelemetry/semantic-conventions" "^1.29.0"
|
||||
|
||||
"@opentelemetry/sdk-trace@2.11.0":
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace/-/sdk-trace-2.11.0.tgz#46bbba9d366755df7d6faded0f7cd25af7f265c2"
|
||||
integrity sha512-fFnTqGm8/G73GQVnxYi7LXa1ZVYEUvgL6XI1LpvV0bPC7WQ/ZGgKxCSl8FnlZBKto9JHHEFTO6s6CUpvvtwFrA==
|
||||
dependencies:
|
||||
"@opentelemetry/core" "2.11.0"
|
||||
"@opentelemetry/resources" "2.11.0"
|
||||
"@opentelemetry/semantic-conventions" "^1.29.0"
|
||||
|
||||
"@opentelemetry/semantic-conventions@^1.29.0":
|
||||
version "1.43.0"
|
||||
resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.43.0.tgz#f3f467e36c27332f0e735ec86cdcd78dd6f27865"
|
||||
integrity sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==
|
||||
|
||||
"@pinojs/redact@^0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@pinojs/redact/-/redact-0.4.0.tgz#c3de060dd12640dcc838516aa2a6803cc7b2e9d6"
|
||||
@@ -607,6 +698,79 @@
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.63.1.tgz#cd19d691330cbd52ebb13620acb6cf7140b95e80"
|
||||
integrity sha512-at8QVep6S3h5Y6gSbdGU06bRY5WJkf6WUduM9YtvYMbYhB1MOFfUgc6kehitQXzOtMSaT70q7f9ydPhpqu821w==
|
||||
|
||||
"@sentry/conventions@^0.16.0":
|
||||
version "0.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/conventions/-/conventions-0.16.0.tgz#3b58d15714cf44dca1518496c00749eec5525009"
|
||||
integrity sha512-fO9PLmHdVURcSPUpWCItWAtgKiMwGdJHbovoSEyLplX5sxs2ugvI4CBPTrkkgqhObnZOD0CnWBKDzSVQYBKEyQ==
|
||||
|
||||
"@sentry/core@10.70.0":
|
||||
version "10.70.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-10.70.0.tgz#96eb9f2beab7d4b3b10c1b59ec7833e4dfe5fb73"
|
||||
integrity sha512-ozhCTDqg89oB4XmWfAwuHshABpvT7AkRpaPnogopPfMAaI61G1t8EKCJ4W7aum8JSBonlfyjPCyW5oYZFm0KvA==
|
||||
dependencies:
|
||||
"@sentry/conventions" "^0.16.0"
|
||||
|
||||
"@sentry/node-core@10.70.0":
|
||||
version "10.70.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/node-core/-/node-core-10.70.0.tgz#d7998eaf9d0efa06d05ba6d9c001afcb8e68dcb5"
|
||||
integrity sha512-oPOEVVNxv5WHtckx2i06Wi9FLWyvOg/1DUeX732jZ4iqT2nupINaMH4nF4f4kSvUThFnxkFSRQxwqOxgzMKhKA==
|
||||
dependencies:
|
||||
"@sentry/conventions" "^0.16.0"
|
||||
"@sentry/core" "10.70.0"
|
||||
"@sentry/opentelemetry" "10.70.0"
|
||||
import-in-the-middle "^3.0.0"
|
||||
|
||||
"@sentry/node-cpu-profiler@^2.4.3":
|
||||
version "2.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/node-cpu-profiler/-/node-cpu-profiler-2.4.4.tgz#b275d249bd6e0c98c1e4f2ebc87acf702e6ae04d"
|
||||
integrity sha512-FaYbFWxEyTTVqXLJccokJCkwx2cTuvTiRaM9kA+O4HbZVT49xYXqSV9cNLI5UqJhgdHiZDhelBd5LB4wj7IIRA==
|
||||
dependencies:
|
||||
detect-libc "^2.0.3"
|
||||
node-abi "^3.73.0"
|
||||
|
||||
"@sentry/node@10.70.0":
|
||||
version "10.70.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-10.70.0.tgz#99fa23d90147c92e8291b8da9d706d3759468bc1"
|
||||
integrity sha512-SPOOVxmKTVIEtqvOKkQT163e/pOwucjS7OPsCHyRs8sFR4nfBNu0EThplyqnvqd5BWBMTPH6WTBQfo+QWHV+HA==
|
||||
dependencies:
|
||||
"@opentelemetry/api" "^1.9.1"
|
||||
"@opentelemetry/instrumentation" "^0.220.0"
|
||||
"@opentelemetry/sdk-trace-base" "^2.9.0"
|
||||
"@sentry/conventions" "^0.16.0"
|
||||
"@sentry/core" "10.70.0"
|
||||
"@sentry/node-core" "10.70.0"
|
||||
"@sentry/opentelemetry" "10.70.0"
|
||||
"@sentry/server-utils" "10.70.0"
|
||||
import-in-the-middle "^3.0.0"
|
||||
|
||||
"@sentry/opentelemetry@10.70.0":
|
||||
version "10.70.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/opentelemetry/-/opentelemetry-10.70.0.tgz#40823a9d16b5d271a52de65244a3e2faeba43fbb"
|
||||
integrity sha512-UNV/2tqypcUK6FDzerAsFJn1Km/c4VZCYkUZDNbnV5S0cwAq2BYKMo4M5vovaLDBQlxA+Wk9ovbxi5wYjjl9fw==
|
||||
dependencies:
|
||||
"@sentry/conventions" "^0.16.0"
|
||||
"@sentry/core" "10.70.0"
|
||||
|
||||
"@sentry/profiling-node@10.70.0":
|
||||
version "10.70.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/profiling-node/-/profiling-node-10.70.0.tgz#ca7b288d4db741923b5920c78a64a38e5d8cfdc1"
|
||||
integrity sha512-bOL1nd+t6H4dHM2BB768Thm26UXBxIqBORIMr7nM+QLID+6DjHRcknRZbyklGNUVzAggsprzQ3f61i2xdRmTEA==
|
||||
dependencies:
|
||||
"@sentry/core" "10.70.0"
|
||||
"@sentry/node" "10.70.0"
|
||||
"@sentry/node-cpu-profiler" "^2.4.3"
|
||||
|
||||
"@sentry/server-utils@10.70.0":
|
||||
version "10.70.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/server-utils/-/server-utils-10.70.0.tgz#df7ab00caae3f7398338062ba91d7a355ca27489"
|
||||
integrity sha512-rzegZjMFFgCp3o+N8+XU13rfSvz4B+f8rU0ijBGrQcHdMNyfsFDTu1UTm262JofmrV2u+s+D0u0vFTnqtOGkbA==
|
||||
dependencies:
|
||||
"@apm-js-collab/code-transformer-bundler-plugins" "^0.7.3"
|
||||
"@apm-js-collab/tracing-hooks" "^0.13.0"
|
||||
"@sentry/conventions" "^0.16.0"
|
||||
"@sentry/core" "10.70.0"
|
||||
meriyah "^6.1.4"
|
||||
|
||||
"@smithy/core@^3.31.1", "@smithy/core@^3.33.2", "@smithy/core@^3.33.3":
|
||||
version "3.33.3"
|
||||
resolved "https://registry.yarnpkg.com/@smithy/core/-/core-3.33.3.tgz#c1e801fe17160bcbf6c714cf16e832057e6bf79e"
|
||||
@@ -922,6 +1086,11 @@ assertion-error@^2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7"
|
||||
integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==
|
||||
|
||||
astring@^1.9.0:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/astring/-/astring-1.9.0.tgz#cc73e6062a7eb03e7d19c22d8b0b3451fd9bfeef"
|
||||
integrity sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==
|
||||
|
||||
async@^3.2.4:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce"
|
||||
@@ -1014,6 +1183,11 @@ chokidar@^3.5.2:
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
cjs-module-lexer@^2.2.0:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-2.2.1.tgz#ab35b03c56ade05fe170c70e67ae89f60666847c"
|
||||
integrity sha512-Ca8swihM+/4yKecYHY52kgJd300hi2lADU/a1RxNTRe+RJ9jvqQlESpbz9DnG9mowez8qwXHB8qYdIUw9e+F5Q==
|
||||
|
||||
cluster-key-slot@1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac"
|
||||
@@ -1028,7 +1202,7 @@ cross-spawn@^7.0.6:
|
||||
shebang-command "^2.0.0"
|
||||
which "^2.0.1"
|
||||
|
||||
debug@^4, debug@^4.3.1, debug@^4.3.2, debug@^4.4.1, debug@^4.4.3:
|
||||
debug@^4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.5, debug@^4.4.1, debug@^4.4.3:
|
||||
version "4.4.3"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a"
|
||||
integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
|
||||
@@ -1050,11 +1224,26 @@ deep-is@^0.1.3:
|
||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
|
||||
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
|
||||
|
||||
detect-libc@^2.0.3:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad"
|
||||
integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==
|
||||
|
||||
es-module-lexer@^1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a"
|
||||
integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==
|
||||
|
||||
es-module-lexer@^2.1.0:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.3.2.tgz#311fa4f40168c1975c505477c51b23234d41ad55"
|
||||
integrity sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==
|
||||
|
||||
es-module-lexer@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-3.0.2.tgz#8cc09097dd80a9cbb79437fd405b935cac76cda3"
|
||||
integrity sha512-BuIB67FngDSyQ/dpQNOZybwdEBDUGJQvOqwWr4ha/ufYiqzuEwPkKO2zLhRAgay28tStRIHUeWmszZAJo3GCOg==
|
||||
|
||||
"esbuild@^0.27.0 || ^0.28.0":
|
||||
version "0.28.2"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.28.2.tgz#0f43bd1bad955b72d24e2261e3abe5957ccf0816"
|
||||
@@ -1322,6 +1511,15 @@ ignore@^7.0.5:
|
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.8.tgz#84d8466899958458ee30b4190c839ee1446cc88d"
|
||||
integrity sha512-YYNsSlXBjMk92SKnkwvB5LOVSa6OznlFUGcsvrFgNJbJCd0M1XKeFVRc8ZByeCqz32FivYNHJVooLmdqrmvp/Q==
|
||||
|
||||
import-in-the-middle@^3.0.0:
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-3.5.1.tgz#74fc490851751005dc2f776a87bc8a075904b474"
|
||||
integrity sha512-mPKuL8bPQzecui2KK6Gb+M8JvJoHnhS1FeYGa22QopBmlevF5F0FE6ued/B5EgHDeIoMTONIpDWWFKUPOG0DBQ==
|
||||
dependencies:
|
||||
cjs-module-lexer "^2.2.0"
|
||||
es-module-lexer "^3.0.2"
|
||||
module-details-from-path "^1.0.4"
|
||||
|
||||
imurmurhash@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||
@@ -1433,13 +1631,18 @@ loupe@^3.1.0, loupe@^3.1.4:
|
||||
resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.2.1.tgz#0095cf56dc5b7a9a7c08ff5b1a8796ec8ad17e76"
|
||||
integrity sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==
|
||||
|
||||
magic-string@^0.30.17:
|
||||
magic-string@^0.30.17, magic-string@^0.30.21:
|
||||
version "0.30.21"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.21.tgz#56763ec09a0fa8091df27879fd94d19078c00d91"
|
||||
integrity sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==
|
||||
dependencies:
|
||||
"@jridgewell/sourcemap-codec" "^1.5.5"
|
||||
|
||||
meriyah@^6.1.4:
|
||||
version "6.1.4"
|
||||
resolved "https://registry.yarnpkg.com/meriyah/-/meriyah-6.1.4.tgz#2d49a8934fbcd9205c20564579c3560d9b1e077b"
|
||||
integrity sha512-Sz8FzjzI0kN13GK/6MVEsVzMZEPvOhnmmI1lU5+/1cGOiK3QUahntrNNtdVeihrO7t9JpoH75iMNXg6R6uWflQ==
|
||||
|
||||
mime-db@1.52.0:
|
||||
version "1.52.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
||||
@@ -1478,6 +1681,11 @@ minio@^8.0.6:
|
||||
through2 "^4.0.2"
|
||||
xml2js "^0.5.0 || ^0.6.2"
|
||||
|
||||
module-details-from-path@^1.0.3, module-details-from-path@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.4.tgz#b662fdcd93f6c83d3f25289da0ce81c8d9685b94"
|
||||
integrity sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==
|
||||
|
||||
ms@^2.1.3:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
@@ -1493,6 +1701,13 @@ natural-compare@^1.4.0:
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
|
||||
|
||||
node-abi@^3.73.0:
|
||||
version "3.96.0"
|
||||
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.96.0.tgz#8b038bc6cca97d6cec2e9aafdb81b900da1ff80d"
|
||||
integrity sha512-rebQ/lz7i0EkoLzUVSrKRzA69zMkwLp95kKMWoMDkkM00Suxz0D7zEQPwRml5fQum24mj7bPvmlgLAmu2JCiYg==
|
||||
dependencies:
|
||||
semver "^7.3.5"
|
||||
|
||||
nodemon@3.1.14:
|
||||
version "3.1.14"
|
||||
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.1.14.tgz#8487ca379c515301d221ec007f27f24ecafa2b51"
|
||||
@@ -1700,6 +1915,14 @@ redis@^5.10.0:
|
||||
"@redis/search" "5.12.1"
|
||||
"@redis/time-series" "5.12.1"
|
||||
|
||||
require-in-the-middle@^8.0.0:
|
||||
version "8.0.1"
|
||||
resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-8.0.1.tgz#dbde2587f669398626d56b20c868ab87bf01cce4"
|
||||
integrity sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==
|
||||
dependencies:
|
||||
debug "^4.3.5"
|
||||
module-details-from-path "^1.0.3"
|
||||
|
||||
rollup@^4.43.0:
|
||||
version "4.63.1"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.63.1.tgz#a9b96d5b2558d034babb12ad8b67a043bc870ac4"
|
||||
@@ -1750,7 +1973,12 @@ sax@>=0.6.0:
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.6.1.tgz#4c23cf608c0b693ab54b4b5888e92cfe977b9843"
|
||||
integrity sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==
|
||||
|
||||
semver@^7.5.3, semver@^7.7.3:
|
||||
semifies@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/semifies/-/semifies-1.0.0.tgz#b69569f32c2ba2ac04f705ea82831364289b2ae2"
|
||||
integrity sha512-xXR3KGeoxTNWPD4aBvL5NUpMTT7WMANr3EWnaS190QVkY52lqqcVRD7Q05UVbBhiWDGWMlJEUam9m7uFFGVScw==
|
||||
|
||||
semver@^7.3.5, semver@^7.5.3, semver@^7.7.3:
|
||||
version "7.8.5"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.8.5.tgz#39b646037dd50c14fb451e7e4cac58ed8b863f69"
|
||||
integrity sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==
|
||||
@@ -1791,6 +2019,11 @@ source-map-js@^1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
|
||||
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
|
||||
|
||||
source-map@^0.6.0:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
|
||||
split-on-first@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f"
|
||||
|
||||
Reference in New Issue
Block a user