corsair 0.1.18 → 0.1.19

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.
@@ -1 +1 @@
1
- {"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../../../core/endpoints/bind.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGrD,OAAO,KAAK,EACX,qBAAqB,EAErB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,MAAM,YAAY,CAAC;AAMpB;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,EACxC,SAAS,EACT,KAAK,EACL,GAAG,EACH,IAAI,EACJ,QAAQ,EACR,aAAa,EACb,WAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,YAAY,EACZ,QAAQ,EACR,cAAc,GACd,EAAE;IACF,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC3C,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,mBAAmB,CAAC;IACnC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,mGAAmG;IACnG,iBAAiB,CAAC,EAAE;QACnB,IAAI,EAAE,cAAc,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;KAC7C,CAAC;IACF,sGAAsG;IACtG,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACjD,gFAAgF;IAChF,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,qEAAqE;IACrE,cAAc,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;CACpE,GAAG,IAAI,CAwJP"}
1
+ {"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../../../core/endpoints/bind.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGrD,OAAO,KAAK,EACX,qBAAqB,EAErB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,MAAM,YAAY,CAAC;AAMpB;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,EACxC,SAAS,EACT,KAAK,EACL,GAAG,EACH,IAAI,EACJ,QAAQ,EACR,aAAa,EACb,WAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,YAAY,EACZ,QAAQ,EACR,cAAc,GACd,EAAE;IACF,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC3C,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,mBAAmB,CAAC;IACnC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,mGAAmG;IACnG,iBAAiB,CAAC,EAAE;QACnB,IAAI,EAAE,cAAc,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;KAC7C,CAAC;IACF,sGAAsG;IACtG,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACjD,gFAAgF;IAChF,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,qEAAqE;IACrE,cAAc,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;CACpE,GAAG,IAAI,CA2JP"}
@@ -33,9 +33,10 @@ export function bindEndpointsRecursively({ endpoints, hooks, ctx, tree, pluginId
33
33
  const operationPath = [...currentPath, key].join('.');
34
34
  const boundFn = async (args) => {
35
35
  // ── Permission guard ────────────────────────────────────────────────────────────────
36
+ let onPermissionComplete;
36
37
  if (permissionsConfig) {
37
38
  const meta = endpointMeta?.[operationPath];
38
- const permResult = await enforcePermission({
39
+ const { result: permResult, onComplete } = await enforcePermission({
39
40
  pluginId,
40
41
  endpointPath: operationPath,
41
42
  args,
@@ -51,6 +52,7 @@ export function bindEndpointsRecursively({ endpoints, hooks, ctx, tree, pluginId
51
52
  });
52
53
  if (permResult === 'blocked')
53
54
  return null;
55
+ onPermissionComplete = onComplete;
54
56
  }
55
57
  const call = async (attemptNumber, callCtx, callArgs) => {
56
58
  try {
@@ -105,24 +107,25 @@ export function bindEndpointsRecursively({ endpoints, hooks, ctx, tree, pluginId
105
107
  };
106
108
  const key = keyBuilder ? await keyBuilder(ctx, 'endpoint') : undefined;
107
109
  if (!endpointHooks?.before && !endpointHooks?.after) {
108
- return call(0, { ...ctx, key }, args);
109
- }
110
- return (async () => {
111
- const ctxWithKey = { ...ctx, key };
112
- const beforeResult = endpointHooks.before
113
- ? await endpointHooks.before(ctxWithKey, args)
114
- : {
115
- ctx: ctxWithKey,
116
- args,
117
- continue: true,
118
- passToAfter: undefined,
119
- };
120
- if (beforeResult.continue === false)
121
- return;
122
- const res = await call(0, beforeResult.ctx, beforeResult.args);
123
- await endpointHooks.after?.(beforeResult.ctx, res, beforeResult.passToAfter);
110
+ const res = await call(0, { ...ctx, key }, args);
111
+ await onPermissionComplete?.();
124
112
  return res;
125
- })();
113
+ }
114
+ const ctxWithKey = { ...ctx, key };
115
+ const beforeResult = endpointHooks.before
116
+ ? await endpointHooks.before(ctxWithKey, args)
117
+ : {
118
+ ctx: ctxWithKey,
119
+ args,
120
+ continue: true,
121
+ passToAfter: undefined,
122
+ };
123
+ if (beforeResult.continue === false)
124
+ return;
125
+ const res = await call(0, beforeResult.ctx, beforeResult.args);
126
+ await endpointHooks.after?.(beforeResult.ctx, res, beforeResult.passToAfter);
127
+ await onPermissionComplete?.();
128
+ return res;
126
129
  };
127
130
  tree[key] = boundFn;
128
131
  }
@@ -38,7 +38,7 @@ export type { AllProviders, AuthTypes, BaseProviders } from './constants';
38
38
  export type { BindEndpoints, BoundEndpointFn, BoundEndpointTree, CorsairContext, CorsairEndpoint, EndpointPathsOf, EndpointTree, } from './endpoints';
39
39
  export type { CorsairErrorHandler, ErrorContext, ErrorHandler, ErrorHandlerAndMatchFunction, ErrorMatcher, RetryStrategies, RetryStrategy, } from './errors';
40
40
  export type { CorsairInspectMethods, EndpointSchemaResult } from './inspect';
41
- export type { EnforcePermissionOptions } from './permissions';
41
+ export type { EnforcePermissionOptions, EnforcePermissionResult } from './permissions';
42
42
  export type { BeforeHookResult, CorsairIntegration, CorsairKeyBuilder, CorsairKeyBuilderBase, CorsairPlugin, CorsairPluginContext, EndpointHooks, EndpointMetaEntry, EndpointRiskLevel, KeyBuilderContext, PermissionMode, PermissionPolicy, PluginEndpointMeta, PluginPermissionsConfig, RequiredPluginEndpointMeta, RequiredPluginEndpointSchemas, RequiredPluginWebhookSchemas, WebhookHooks, } from './plugins';
43
43
  export type { Bivariant, UnionToIntersection } from './utils';
44
44
  export type { BindWebhooks, BoundWebhook, BoundWebhookTree, CorsairWebhook, CorsairWebhookHandler, CorsairWebhookMatcher, RawWebhookRequest, WebhookPathsOf, WebhookRequest, WebhookResponse, WebhookTree, } from './webhooks';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../core/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../core/index.ts"],"names":[],"mappings":"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"}
@@ -17,13 +17,28 @@ export type EnforcePermissionOptions = {
17
17
  db?: CorsairDatabase;
18
18
  timeoutMs?: number;
19
19
  };
20
+ export type EnforcePermissionResult = {
21
+ result: 'allow' | 'blocked';
22
+ /**
23
+ * Called by the endpoint binding layer after the endpoint executes successfully.
24
+ * Marks the permission record as 'completed' (single-use approval consumed).
25
+ * Only present when an 'approved' record was found and the call is allowed through.
26
+ */
27
+ onComplete?: () => Promise<void>;
28
+ };
20
29
  /**
21
30
  * Evaluates the permission policy and returns whether the action is allowed.
22
31
  *
23
- * - `'allow'` → returns 'allow', caller proceeds normally
24
- * - `'deny'` logs a blocked message, returns 'blocked'
25
- * - `'require_approval'` creates a `corsair_permissions` record, logs the token, returns 'blocked'
26
- * (falls back to deny if no database is configured)
32
+ * Lifecycle:
33
+ * - `'allow'` policy permits, caller proceeds normally
34
+ * - `'deny'` blocked by policy mode; no DB record created
35
+ * - `'require_approval'` checks for an existing matching permission record first:
36
+ * - `pending` (not expired) → already waiting for approval, returns 'blocked'
37
+ * - `approved` (not expired) → approved and ready; returns 'allow' + onComplete callback
38
+ * that marks the record 'completed' after the endpoint runs
39
+ * - otherwise → creates a new 'pending' record, returns 'blocked'
40
+ *
41
+ * Falls back to deny if no database is configured.
27
42
  */
28
- export declare function enforcePermission(opts: EnforcePermissionOptions): Promise<'allow' | 'blocked'>;
43
+ export declare function enforcePermission(opts: EnforcePermissionOptions): Promise<EnforcePermissionResult>;
29
44
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/permissions/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EACX,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,MAAM,YAAY,CAAC;AAgBpB,4HAA4H;AAC5H,wBAAgB,kBAAkB,CACjC,SAAS,EAAE,iBAAiB,EAC5B,IAAI,EAAE,cAAc,EACpB,QAAQ,CAAC,EAAE,gBAAgB,GACzB,gBAAgB,CAGlB;AAMD,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAsBxD;AAMD,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,qFAAqF;IACrF,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,kGAAkG;IAClG,EAAE,CAAC,EAAE,eAAe,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACtC,IAAI,EAAE,wBAAwB,GAC5B,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAkD9B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/permissions/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EACX,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,MAAM,YAAY,CAAC;AAgBpB,4HAA4H;AAC5H,wBAAgB,kBAAkB,CACjC,SAAS,EAAE,iBAAiB,EAC5B,IAAI,EAAE,cAAc,EACpB,QAAQ,CAAC,EAAE,gBAAgB,GACzB,gBAAgB,CAGlB;AAMD,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAsBxD;AAMD,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,qFAAqF;IACrF,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,kGAAkG;IAClG,EAAE,CAAC,EAAE,eAAe,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACrC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CACtC,IAAI,EAAE,wBAAwB,GAC5B,OAAO,CAAC,uBAAuB,CAAC,CA4FlC"}
@@ -45,24 +45,64 @@ export function parseDurationMs(duration) {
45
45
  /**
46
46
  * Evaluates the permission policy and returns whether the action is allowed.
47
47
  *
48
- * - `'allow'` → returns 'allow', caller proceeds normally
49
- * - `'deny'` logs a blocked message, returns 'blocked'
50
- * - `'require_approval'` creates a `corsair_permissions` record, logs the token, returns 'blocked'
51
- * (falls back to deny if no database is configured)
48
+ * Lifecycle:
49
+ * - `'allow'` policy permits, caller proceeds normally
50
+ * - `'deny'` blocked by policy mode; no DB record created
51
+ * - `'require_approval'` checks for an existing matching permission record first:
52
+ * - `pending` (not expired) → already waiting for approval, returns 'blocked'
53
+ * - `approved` (not expired) → approved and ready; returns 'allow' + onComplete callback
54
+ * that marks the record 'completed' after the endpoint runs
55
+ * - otherwise → creates a new 'pending' record, returns 'blocked'
56
+ *
57
+ * Falls back to deny if no database is configured.
52
58
  */
53
59
  export async function enforcePermission(opts) {
54
60
  const policy = evaluatePermission(opts.riskLevel, opts.mode, opts.override);
55
61
  if (policy === 'allow')
56
- return 'allow';
62
+ return { result: 'allow' };
57
63
  const irreversibleNote = opts.meta?.irreversible ? ' (irreversible)' : '';
58
64
  const description = opts.meta?.description
59
65
  ? `${opts.meta.description}${irreversibleNote}`
60
66
  : `${opts.pluginId}.${opts.endpointPath}${irreversibleNote}`;
61
67
  if (policy === 'deny' || !opts.db) {
62
68
  console.log(`[corsair/${opts.pluginId}] '${opts.endpointPath}' blocked — denied by permission mode '${opts.mode}'.`, `\n Action: ${description}`, `\n To allow this, update the permission mode or add an override in your corsair config.`);
63
- return 'blocked';
69
+ return { result: 'blocked' };
70
+ }
71
+ const argsJson = JSON.stringify(opts.args);
72
+ const now = new Date().toISOString();
73
+ // Check for an existing, non-expired permission record for this plugin + endpoint + args
74
+ const existing = await opts.db.db
75
+ .selectFrom('corsair_permissions')
76
+ .selectAll()
77
+ .where('plugin', '=', opts.pluginId)
78
+ .where('endpoint', '=', opts.endpointPath)
79
+ .where('args', '=', argsJson)
80
+ .where('expires_at', '>', now)
81
+ .where('status', 'in', ['pending', 'approved'])
82
+ .orderBy('created_at', 'desc')
83
+ .limit(1)
84
+ .executeTakeFirst();
85
+ if (existing) {
86
+ if (existing.status === 'approved') {
87
+ // Single-use: let the call through; onComplete will mark it 'completed'
88
+ const db = opts.db;
89
+ const permissionId = existing.id;
90
+ return {
91
+ result: 'allow',
92
+ onComplete: async () => {
93
+ await db.db
94
+ .updateTable('corsair_permissions')
95
+ .set({ status: 'completed', updated_at: new Date() })
96
+ .where('id', '=', permissionId)
97
+ .execute();
98
+ },
99
+ };
100
+ }
101
+ // status === 'pending': already waiting for approval, don't create a duplicate
102
+ console.log(`[corsair/${opts.pluginId}] '${opts.endpointPath}' blocked — approval already pending.`, `\n Action: ${description}`, `\n Permission ID: ${existing.id}`, `\n Use the token to approve or deny this request.`);
103
+ return { result: 'blocked' };
64
104
  }
65
- // require_approval: create a pending record and log the token
105
+ // No existing actionable record — create a new pending approval request
66
106
  const id = uuidv4();
67
107
  const token = randomBytes(32).toString('hex');
68
108
  const timeoutMs = opts.timeoutMs ?? 10 * 60 * 1_000;
@@ -76,12 +116,11 @@ export async function enforcePermission(opts) {
76
116
  token,
77
117
  plugin: opts.pluginId,
78
118
  endpoint: opts.endpointPath,
79
- // unknown args serialized to JSON; available for inspection or re-execution
80
- args: JSON.stringify(opts.args),
119
+ args: argsJson,
81
120
  status: 'pending',
82
121
  expires_at: expiresAt,
83
122
  })
84
123
  .execute();
85
124
  console.log(`[corsair/${opts.pluginId}] '${opts.endpointPath}' blocked — approval required.`, `\n Action: ${description}`, `\n Permission ID: ${id}`, `\n Permission token: ${token}`, `\n Expires at: ${expiresAt}`, `\n Use the token to approve or deny this request.`);
86
- return 'blocked';
125
+ return { result: 'blocked' };
87
126
  }
@@ -122,14 +122,14 @@ export declare const CorsairPermissionsSchema: z.ZodObject<{
122
122
  /** Full public review page URL (ngrok URL + path + token query param) */
123
123
  review_url: z.ZodOptional<z.ZodString>;
124
124
  /** Current state of the approval request */
125
- status: z.ZodDefault<z.ZodEnum<["pending", "approved", "denied", "expired"]>>;
125
+ status: z.ZodDefault<z.ZodEnum<["pending", "approved", "completed", "denied", "expired"]>>;
126
126
  /** ISO8601 timestamp — when this request becomes invalid */
127
127
  expires_at: z.ZodString;
128
128
  }, "strip", z.ZodTypeAny, {
129
129
  id: string;
130
130
  created_at: Date;
131
131
  updated_at: Date;
132
- status: "pending" | "approved" | "denied" | "expired";
132
+ status: "pending" | "completed" | "approved" | "denied" | "expired";
133
133
  token: string;
134
134
  plugin: string;
135
135
  endpoint: string;
@@ -147,7 +147,7 @@ export declare const CorsairPermissionsSchema: z.ZodObject<{
147
147
  endpoint: string;
148
148
  args: string;
149
149
  expires_at: string;
150
- status?: "pending" | "approved" | "denied" | "expired" | undefined;
150
+ status?: "pending" | "completed" | "approved" | "denied" | "expired" | undefined;
151
151
  session_id?: string | undefined;
152
152
  callback_url?: string | undefined;
153
153
  review_url?: string | undefined;
@@ -164,7 +164,7 @@ export type CorsairPermissionInsert = {
164
164
  session_id?: string;
165
165
  callback_url?: string;
166
166
  review_url?: string;
167
- status?: 'pending' | 'approved' | 'denied' | 'expired';
167
+ status?: 'pending' | 'approved' | 'completed' | 'denied' | 'expired';
168
168
  expires_at: string;
169
169
  };
170
170
  export type CorsairTableName = 'corsair_integrations' | 'corsair_accounts' | 'corsair_entities' | 'corsair_events' | 'corsair_permissions' | (string & {});
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../db/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../db/index.ts"],"names":[],"mappings":"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"}
package/dist/db/index.js CHANGED
@@ -89,7 +89,7 @@ export const CorsairPermissionsSchema = z.object({
89
89
  review_url: z.string().optional(),
90
90
  /** Current state of the approval request */
91
91
  status: z
92
- .enum(['pending', 'approved', 'denied', 'expired'])
92
+ .enum(['pending', 'approved', 'completed', 'denied', 'expired'])
93
93
  .default('pending'),
94
94
  /** ISO8601 timestamp — when this request becomes invalid */
95
95
  expires_at: z.string(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "corsair",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",