@envelop/sentry 4.0.0-alpha-4ba70ab.0 → 4.0.0-alpha-d0d0776.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/README.md +3 -0
- package/index.d.ts +5 -0
- package/index.js +78 -43
- package/index.mjs +63 -48
- package/package.json +20 -8
package/README.md
CHANGED
|
@@ -32,6 +32,8 @@ yarn add @sentry/node @sentry/tracing @envelop/sentry
|
|
|
32
32
|
```ts
|
|
33
33
|
import { envelop } from '@envelop/core';
|
|
34
34
|
import { useSentry } from '@envelop/sentry';
|
|
35
|
+
// do this only once in you entry file.
|
|
36
|
+
import "@sentry/tracing";
|
|
35
37
|
|
|
36
38
|
const getEnveloped = envelop({
|
|
37
39
|
plugins: [
|
|
@@ -62,3 +64,4 @@ const getEnveloped = envelop({
|
|
|
62
64
|
- `operationName` - Produces a "op" (operation) of created Span.
|
|
63
65
|
- `skip` (default: none) - Produces a "op" (operation) of created Span.
|
|
64
66
|
- `skipError` (default: ignored `EnvelopError`) - Indicates whether or not to skip Sentry exception reporting for a given error. By default, this plugin skips all `EnvelopError` errors and does not report it to Sentry.
|
|
67
|
+
- `eventIdKey` (default: `'sentryEventId'`) - The key in the error's extensions field used to expose the generated Sentry event id. Set to `null` to disable.
|
package/index.d.ts
CHANGED
|
@@ -34,6 +34,11 @@ export declare type SentryPluginOptions = {
|
|
|
34
34
|
* @default false
|
|
35
35
|
*/
|
|
36
36
|
includeExecuteVariables?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The key of the event id in the error's extension. `null` to disable.
|
|
39
|
+
* @default sentryEventId
|
|
40
|
+
*/
|
|
41
|
+
eventIdKey?: string | null;
|
|
37
42
|
/**
|
|
38
43
|
* Adds custom tags to every Transaction.
|
|
39
44
|
*/
|
package/index.js
CHANGED
|
@@ -6,15 +6,33 @@ const core = require('@envelop/core');
|
|
|
6
6
|
const Sentry = require('@sentry/node');
|
|
7
7
|
const graphql = require('graphql');
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
function _interopNamespace(e) {
|
|
10
|
+
if (e && e.__esModule) return e;
|
|
11
|
+
const n = Object.create(null);
|
|
12
|
+
if (e) {
|
|
13
|
+
for (const k in e) {
|
|
14
|
+
if (k !== 'default') {
|
|
15
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
16
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return e[k]; }
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
n["default"] = e;
|
|
24
|
+
return Object.freeze(n);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const Sentry__namespace = /*#__PURE__*/_interopNamespace(Sentry);
|
|
28
|
+
|
|
10
29
|
function defaultSkipError(error) {
|
|
11
30
|
return error instanceof core.EnvelopError;
|
|
12
31
|
}
|
|
13
32
|
const sentryTracingSymbol = Symbol('sentryTracing');
|
|
14
33
|
const useSentry = (options = {}) => {
|
|
15
34
|
function pick(key, defaultValue) {
|
|
16
|
-
|
|
17
|
-
return (_a = options[key]) !== null && _a !== void 0 ? _a : defaultValue;
|
|
35
|
+
return options[key] ?? defaultValue;
|
|
18
36
|
}
|
|
19
37
|
const startTransaction = pick('startTransaction', true);
|
|
20
38
|
const trackResolvers = pick('trackResolvers', true);
|
|
@@ -24,6 +42,16 @@ const useSentry = (options = {}) => {
|
|
|
24
42
|
const renameTransaction = pick('renameTransaction', false);
|
|
25
43
|
const skipOperation = pick('skip', () => false);
|
|
26
44
|
const skipError = pick('skipError', defaultSkipError);
|
|
45
|
+
function addEventId(err, eventId) {
|
|
46
|
+
if (options.eventIdKey === null) {
|
|
47
|
+
return err;
|
|
48
|
+
}
|
|
49
|
+
const eventIdKey = options.eventIdKey ?? 'sentryEventId';
|
|
50
|
+
return new graphql.GraphQLError(err.message, err.nodes, err.source, err.positions, err.path, undefined, {
|
|
51
|
+
...err.extensions,
|
|
52
|
+
[eventIdKey]: eventId,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
27
55
|
const onResolverCalled = trackResolvers
|
|
28
56
|
? ({ args: resolversArgs, info, context }) => {
|
|
29
57
|
const { rootSpan, opName, operationType } = context[sentryTracingSymbol];
|
|
@@ -47,8 +75,11 @@ const useSentry = (options = {}) => {
|
|
|
47
75
|
childSpan.setData('result', result);
|
|
48
76
|
}
|
|
49
77
|
if (result instanceof Error && !skipError(result)) {
|
|
50
|
-
|
|
51
|
-
|
|
78
|
+
// Map index values in list to $index for better grouping of events.
|
|
79
|
+
const errorPath = graphql.responsePathAsArray(info.path)
|
|
80
|
+
.map(v => (typeof v === 'number' ? '$index' : v))
|
|
81
|
+
.join(' > ');
|
|
82
|
+
Sentry__namespace.captureException(result, {
|
|
52
83
|
fingerprint: ['graphql', errorPath, opName, operationType],
|
|
53
84
|
});
|
|
54
85
|
}
|
|
@@ -61,14 +92,13 @@ const useSentry = (options = {}) => {
|
|
|
61
92
|
return {
|
|
62
93
|
onResolverCalled,
|
|
63
94
|
onExecute({ args, extendContext }) {
|
|
64
|
-
var _a;
|
|
65
95
|
if (skipOperation(args)) {
|
|
66
96
|
return;
|
|
67
97
|
}
|
|
68
98
|
const rootOperation = args.document.definitions.find(o => o.kind === graphql.Kind.OPERATION_DEFINITION);
|
|
69
99
|
const operationType = rootOperation.operation;
|
|
70
100
|
const document = graphql.print(args.document);
|
|
71
|
-
const opName = args.operationName ||
|
|
101
|
+
const opName = args.operationName || rootOperation.name?.value || 'Anonymous Operation';
|
|
72
102
|
const addedTags = (options.appendTags && options.appendTags(args)) || {};
|
|
73
103
|
const transactionName = options.transactionName ? options.transactionName(args) : opName;
|
|
74
104
|
const op = options.operationName ? options.operationName(args) : 'execute';
|
|
@@ -79,21 +109,22 @@ const useSentry = (options = {}) => {
|
|
|
79
109
|
};
|
|
80
110
|
let rootSpan;
|
|
81
111
|
if (startTransaction) {
|
|
82
|
-
rootSpan =
|
|
112
|
+
rootSpan = Sentry__namespace.startTransaction({
|
|
83
113
|
name: transactionName,
|
|
84
114
|
op,
|
|
85
115
|
tags,
|
|
86
116
|
});
|
|
87
117
|
}
|
|
88
118
|
else {
|
|
89
|
-
const scope =
|
|
90
|
-
const parentSpan = scope
|
|
91
|
-
const span = parentSpan
|
|
119
|
+
const scope = Sentry__namespace.getCurrentHub().getScope();
|
|
120
|
+
const parentSpan = scope?.getSpan();
|
|
121
|
+
const span = parentSpan?.startChild({
|
|
92
122
|
description: transactionName,
|
|
93
123
|
op,
|
|
94
124
|
tags,
|
|
95
125
|
});
|
|
96
126
|
if (!span) {
|
|
127
|
+
// eslint-disable-next-line no-console
|
|
97
128
|
console.warn([
|
|
98
129
|
`Flag "startTransaction" is enabled but Sentry failed to find a transaction.`,
|
|
99
130
|
`Try to create a transaction before GraphQL execution phase is started.`,
|
|
@@ -107,7 +138,7 @@ const useSentry = (options = {}) => {
|
|
|
107
138
|
}
|
|
108
139
|
rootSpan.setData('document', document);
|
|
109
140
|
if (options.configureScope) {
|
|
110
|
-
|
|
141
|
+
Sentry__namespace.configureScope(scope => options.configureScope(args, scope));
|
|
111
142
|
}
|
|
112
143
|
if (onResolverCalled) {
|
|
113
144
|
const sentryContext = {
|
|
@@ -118,19 +149,13 @@ const useSentry = (options = {}) => {
|
|
|
118
149
|
extendContext({ [sentryTracingSymbol]: sentryContext });
|
|
119
150
|
}
|
|
120
151
|
return {
|
|
121
|
-
onExecuteDone(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (includeRawResult) {
|
|
129
|
-
rootSpan.setData('result', result);
|
|
130
|
-
}
|
|
131
|
-
if (result.errors && result.errors.length > 0) {
|
|
132
|
-
for (const err of result.errors) {
|
|
133
|
-
Sentry.withScope(scope => {
|
|
152
|
+
onExecuteDone(payload) {
|
|
153
|
+
const handleResult = ({ result, setResult }) => {
|
|
154
|
+
if (includeRawResult) {
|
|
155
|
+
rootSpan.setData('result', result);
|
|
156
|
+
}
|
|
157
|
+
if (result.errors && result.errors.length > 0) {
|
|
158
|
+
Sentry__namespace.withScope(scope => {
|
|
134
159
|
scope.setTransactionName(opName);
|
|
135
160
|
scope.setTag('operation', operationType);
|
|
136
161
|
scope.setTag('operationName', opName);
|
|
@@ -142,28 +167,38 @@ const useSentry = (options = {}) => {
|
|
|
142
167
|
if (includeExecuteVariables) {
|
|
143
168
|
scope.setExtra('variables', args.variableValues);
|
|
144
169
|
}
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
170
|
+
const errors = result.errors?.map(err => {
|
|
171
|
+
const errorPath = (err.path ?? []).join(' > ');
|
|
172
|
+
if (errorPath) {
|
|
173
|
+
scope.addBreadcrumb({
|
|
174
|
+
category: 'execution-path',
|
|
175
|
+
message: errorPath,
|
|
176
|
+
level: 'debug',
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
// Map index values in list to $index for better grouping of events.
|
|
180
|
+
const errorPathWithIndex = (err.path ?? []).map(v => (typeof v === 'number' ? '$index' : v)).join(' > ');
|
|
181
|
+
const eventId = Sentry__namespace.captureException(err, {
|
|
182
|
+
fingerprint: ['graphql', errorPathWithIndex, opName, operationType],
|
|
183
|
+
contexts: {
|
|
184
|
+
GraphQL: {
|
|
185
|
+
operationName: opName,
|
|
186
|
+
operationType,
|
|
187
|
+
variables: args.variableValues,
|
|
188
|
+
},
|
|
160
189
|
},
|
|
161
|
-
}
|
|
190
|
+
});
|
|
191
|
+
return addEventId(err, eventId);
|
|
192
|
+
});
|
|
193
|
+
setResult({
|
|
194
|
+
...result,
|
|
195
|
+
errors,
|
|
162
196
|
});
|
|
163
197
|
});
|
|
164
198
|
}
|
|
165
|
-
|
|
166
|
-
|
|
199
|
+
rootSpan.finish();
|
|
200
|
+
};
|
|
201
|
+
return core.handleStreamOrSingleExecutionResult(payload, handleResult);
|
|
167
202
|
},
|
|
168
203
|
};
|
|
169
204
|
},
|
package/index.mjs
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
import { EnvelopError,
|
|
2
|
-
import
|
|
3
|
-
import { Kind, print,
|
|
1
|
+
import { EnvelopError, handleStreamOrSingleExecutionResult } from '@envelop/core';
|
|
2
|
+
import * as Sentry from '@sentry/node';
|
|
3
|
+
import { responsePathAsArray, Kind, print, GraphQLError } from 'graphql';
|
|
4
4
|
|
|
5
|
-
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
6
5
|
function defaultSkipError(error) {
|
|
7
6
|
return error instanceof EnvelopError;
|
|
8
7
|
}
|
|
9
8
|
const sentryTracingSymbol = Symbol('sentryTracing');
|
|
10
9
|
const useSentry = (options = {}) => {
|
|
11
10
|
function pick(key, defaultValue) {
|
|
12
|
-
|
|
13
|
-
return (_a = options[key]) !== null && _a !== void 0 ? _a : defaultValue;
|
|
11
|
+
return options[key] ?? defaultValue;
|
|
14
12
|
}
|
|
15
|
-
const startTransaction
|
|
13
|
+
const startTransaction = pick('startTransaction', true);
|
|
16
14
|
const trackResolvers = pick('trackResolvers', true);
|
|
17
15
|
const includeResolverArgs = pick('includeResolverArgs', false);
|
|
18
16
|
const includeRawResult = pick('includeRawResult', false);
|
|
@@ -20,6 +18,16 @@ const useSentry = (options = {}) => {
|
|
|
20
18
|
const renameTransaction = pick('renameTransaction', false);
|
|
21
19
|
const skipOperation = pick('skip', () => false);
|
|
22
20
|
const skipError = pick('skipError', defaultSkipError);
|
|
21
|
+
function addEventId(err, eventId) {
|
|
22
|
+
if (options.eventIdKey === null) {
|
|
23
|
+
return err;
|
|
24
|
+
}
|
|
25
|
+
const eventIdKey = options.eventIdKey ?? 'sentryEventId';
|
|
26
|
+
return new GraphQLError(err.message, err.nodes, err.source, err.positions, err.path, undefined, {
|
|
27
|
+
...err.extensions,
|
|
28
|
+
[eventIdKey]: eventId,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
23
31
|
const onResolverCalled = trackResolvers
|
|
24
32
|
? ({ args: resolversArgs, info, context }) => {
|
|
25
33
|
const { rootSpan, opName, operationType } = context[sentryTracingSymbol];
|
|
@@ -43,8 +51,11 @@ const useSentry = (options = {}) => {
|
|
|
43
51
|
childSpan.setData('result', result);
|
|
44
52
|
}
|
|
45
53
|
if (result instanceof Error && !skipError(result)) {
|
|
46
|
-
|
|
47
|
-
|
|
54
|
+
// Map index values in list to $index for better grouping of events.
|
|
55
|
+
const errorPath = responsePathAsArray(info.path)
|
|
56
|
+
.map(v => (typeof v === 'number' ? '$index' : v))
|
|
57
|
+
.join(' > ');
|
|
58
|
+
Sentry.captureException(result, {
|
|
48
59
|
fingerprint: ['graphql', errorPath, opName, operationType],
|
|
49
60
|
});
|
|
50
61
|
}
|
|
@@ -57,14 +68,13 @@ const useSentry = (options = {}) => {
|
|
|
57
68
|
return {
|
|
58
69
|
onResolverCalled,
|
|
59
70
|
onExecute({ args, extendContext }) {
|
|
60
|
-
var _a;
|
|
61
71
|
if (skipOperation(args)) {
|
|
62
72
|
return;
|
|
63
73
|
}
|
|
64
74
|
const rootOperation = args.document.definitions.find(o => o.kind === Kind.OPERATION_DEFINITION);
|
|
65
75
|
const operationType = rootOperation.operation;
|
|
66
76
|
const document = print(args.document);
|
|
67
|
-
const opName = args.operationName ||
|
|
77
|
+
const opName = args.operationName || rootOperation.name?.value || 'Anonymous Operation';
|
|
68
78
|
const addedTags = (options.appendTags && options.appendTags(args)) || {};
|
|
69
79
|
const transactionName = options.transactionName ? options.transactionName(args) : opName;
|
|
70
80
|
const op = options.operationName ? options.operationName(args) : 'execute';
|
|
@@ -74,22 +84,23 @@ const useSentry = (options = {}) => {
|
|
|
74
84
|
...(addedTags || {}),
|
|
75
85
|
};
|
|
76
86
|
let rootSpan;
|
|
77
|
-
if (startTransaction
|
|
78
|
-
rootSpan = startTransaction({
|
|
87
|
+
if (startTransaction) {
|
|
88
|
+
rootSpan = Sentry.startTransaction({
|
|
79
89
|
name: transactionName,
|
|
80
90
|
op,
|
|
81
91
|
tags,
|
|
82
92
|
});
|
|
83
93
|
}
|
|
84
94
|
else {
|
|
85
|
-
const scope = getCurrentHub().getScope();
|
|
86
|
-
const parentSpan = scope
|
|
87
|
-
const span = parentSpan
|
|
95
|
+
const scope = Sentry.getCurrentHub().getScope();
|
|
96
|
+
const parentSpan = scope?.getSpan();
|
|
97
|
+
const span = parentSpan?.startChild({
|
|
88
98
|
description: transactionName,
|
|
89
99
|
op,
|
|
90
100
|
tags,
|
|
91
101
|
});
|
|
92
102
|
if (!span) {
|
|
103
|
+
// eslint-disable-next-line no-console
|
|
93
104
|
console.warn([
|
|
94
105
|
`Flag "startTransaction" is enabled but Sentry failed to find a transaction.`,
|
|
95
106
|
`Try to create a transaction before GraphQL execution phase is started.`,
|
|
@@ -103,7 +114,7 @@ const useSentry = (options = {}) => {
|
|
|
103
114
|
}
|
|
104
115
|
rootSpan.setData('document', document);
|
|
105
116
|
if (options.configureScope) {
|
|
106
|
-
configureScope(scope => options.configureScope(args, scope));
|
|
117
|
+
Sentry.configureScope(scope => options.configureScope(args, scope));
|
|
107
118
|
}
|
|
108
119
|
if (onResolverCalled) {
|
|
109
120
|
const sentryContext = {
|
|
@@ -114,19 +125,13 @@ const useSentry = (options = {}) => {
|
|
|
114
125
|
extendContext({ [sentryTracingSymbol]: sentryContext });
|
|
115
126
|
}
|
|
116
127
|
return {
|
|
117
|
-
onExecuteDone(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (includeRawResult) {
|
|
125
|
-
rootSpan.setData('result', result);
|
|
126
|
-
}
|
|
127
|
-
if (result.errors && result.errors.length > 0) {
|
|
128
|
-
for (const err of result.errors) {
|
|
129
|
-
withScope(scope => {
|
|
128
|
+
onExecuteDone(payload) {
|
|
129
|
+
const handleResult = ({ result, setResult }) => {
|
|
130
|
+
if (includeRawResult) {
|
|
131
|
+
rootSpan.setData('result', result);
|
|
132
|
+
}
|
|
133
|
+
if (result.errors && result.errors.length > 0) {
|
|
134
|
+
Sentry.withScope(scope => {
|
|
130
135
|
scope.setTransactionName(opName);
|
|
131
136
|
scope.setTag('operation', operationType);
|
|
132
137
|
scope.setTag('operationName', opName);
|
|
@@ -138,28 +143,38 @@ const useSentry = (options = {}) => {
|
|
|
138
143
|
if (includeExecuteVariables) {
|
|
139
144
|
scope.setExtra('variables', args.variableValues);
|
|
140
145
|
}
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
146
|
+
const errors = result.errors?.map(err => {
|
|
147
|
+
const errorPath = (err.path ?? []).join(' > ');
|
|
148
|
+
if (errorPath) {
|
|
149
|
+
scope.addBreadcrumb({
|
|
150
|
+
category: 'execution-path',
|
|
151
|
+
message: errorPath,
|
|
152
|
+
level: 'debug',
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
// Map index values in list to $index for better grouping of events.
|
|
156
|
+
const errorPathWithIndex = (err.path ?? []).map(v => (typeof v === 'number' ? '$index' : v)).join(' > ');
|
|
157
|
+
const eventId = Sentry.captureException(err, {
|
|
158
|
+
fingerprint: ['graphql', errorPathWithIndex, opName, operationType],
|
|
159
|
+
contexts: {
|
|
160
|
+
GraphQL: {
|
|
161
|
+
operationName: opName,
|
|
162
|
+
operationType,
|
|
163
|
+
variables: args.variableValues,
|
|
164
|
+
},
|
|
156
165
|
},
|
|
157
|
-
}
|
|
166
|
+
});
|
|
167
|
+
return addEventId(err, eventId);
|
|
168
|
+
});
|
|
169
|
+
setResult({
|
|
170
|
+
...result,
|
|
171
|
+
errors,
|
|
158
172
|
});
|
|
159
173
|
});
|
|
160
174
|
}
|
|
161
|
-
|
|
162
|
-
|
|
175
|
+
rootSpan.finish();
|
|
176
|
+
};
|
|
177
|
+
return handleStreamOrSingleExecutionResult(payload, handleResult);
|
|
163
178
|
},
|
|
164
179
|
};
|
|
165
180
|
},
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@envelop/sentry",
|
|
3
|
-
"version": "4.0.0-alpha-
|
|
3
|
+
"version": "4.0.0-alpha-d0d0776.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"peerDependencies": {
|
|
6
|
-
"@envelop/core": "
|
|
7
|
-
"@sentry/node": "^6",
|
|
6
|
+
"@envelop/core": "3.0.0-alpha-d0d0776.0",
|
|
7
|
+
"@sentry/node": "^6 || ^7",
|
|
8
8
|
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
|
|
9
9
|
},
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
|
-
"url": "https://github.com/
|
|
12
|
+
"url": "https://github.com/n1ru4l/envelop.git",
|
|
13
13
|
"directory": "packages/plugins/sentry"
|
|
14
14
|
},
|
|
15
15
|
"author": "Dotan Simha <dotansimha@gmail.com>",
|
|
@@ -22,12 +22,24 @@
|
|
|
22
22
|
},
|
|
23
23
|
"exports": {
|
|
24
24
|
".": {
|
|
25
|
-
"require":
|
|
26
|
-
|
|
25
|
+
"require": {
|
|
26
|
+
"default": "./index.js",
|
|
27
|
+
"types": "./index.d.ts"
|
|
28
|
+
},
|
|
29
|
+
"import": {
|
|
30
|
+
"default": "./index.mjs",
|
|
31
|
+
"types": "./index.d.ts"
|
|
32
|
+
}
|
|
27
33
|
},
|
|
28
34
|
"./*": {
|
|
29
|
-
"require":
|
|
30
|
-
|
|
35
|
+
"require": {
|
|
36
|
+
"default": "./*.js",
|
|
37
|
+
"types": "./*.d.ts"
|
|
38
|
+
},
|
|
39
|
+
"import": {
|
|
40
|
+
"default": "./*.mjs",
|
|
41
|
+
"types": "./*.d.ts"
|
|
42
|
+
}
|
|
31
43
|
},
|
|
32
44
|
"./package.json": "./package.json"
|
|
33
45
|
}
|