@classytic/mongokit 3.24.0 → 3.28.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.
Files changed (38) hide show
  1. package/README.md +12 -2
  2. package/dist/{PaginationEngine-BnZ24ehC.d.mts → PaginationEngine-CBS1XGzp.d.mts} +2 -1
  3. package/dist/{Repository-ClOraFjT.mjs → Repository-BFBTAMlA.mjs} +177 -54
  4. package/dist/actions/index.d.mts +1 -1
  5. package/dist/adapter/index.d.mts +1 -1
  6. package/dist/adapter/index.mjs +1 -1
  7. package/dist/{adapter-BWgJ_Jdc.mjs → adapter-CLvUHiTW.mjs} +1 -1
  8. package/dist/ai/index.d.mts +1 -1
  9. package/dist/better-auth/index.mjs +2 -2
  10. package/dist/core-62oo3N1C.d.mts +50 -0
  11. package/dist/{create-repository-CVupgeRG.mjs → create-repository-2DMwkYVz.mjs} +2 -2
  12. package/dist/{create-repository-Cn1LkvL7.d.mts → create-repository-D4ZU94b3.d.mts} +33 -5
  13. package/dist/{id-resolution-P2OzcyRl.mjs → id-resolution-BqDrk0S2.mjs} +12 -1
  14. package/dist/{index-DLQ6pjal.d.mts → index-DceInCTX.d.mts} +3 -1
  15. package/dist/index.d.mts +70 -213
  16. package/dist/index.mjs +1071 -922
  17. package/dist/{mongooseToJsonSchema-CVnrKFDq.mjs → mongooseToJsonSchema-CByt1VhQ.mjs} +1 -1
  18. package/dist/{multi-tenant.plugin-BjXXuc_g.d.mts → multi-tenant.plugin-DVyVGREb.d.mts} +117 -18
  19. package/dist/operations-C8IcCHF9.d.mts +463 -0
  20. package/dist/pagination/PaginationEngine.d.mts +1 -1
  21. package/dist/pagination-jSUdrACK.d.mts +158 -0
  22. package/dist/plugin-options-vFufQZMZ.d.mts +125 -0
  23. package/dist/plugins/index.d.mts +4 -4
  24. package/dist/plugins/index.mjs +3 -3
  25. package/dist/query/primitives/coercion.mjs +1 -1
  26. package/dist/query/primitives/geo.d.mts +1 -1
  27. package/dist/repository-DCHRWRXw.d.mts +511 -0
  28. package/dist/testkit/index.d.mts +1 -1
  29. package/dist/testkit/index.mjs +1 -1
  30. package/dist/{timestamp.plugin-BhSX0Lu_.mjs → timestamp.plugin-ennbatTW.mjs} +192 -46
  31. package/dist/{to-plain-g8-gsVxZ.d.mts → to-plain-DkF5px0R.d.mts} +12 -16
  32. package/dist/type-utils-CLzRFtIA.d.mts +163 -0
  33. package/dist/utils/index.d.mts +2 -2
  34. package/dist/utils/index.mjs +3 -3
  35. package/dist/{validation-chain.plugin-CFJbr964.d.mts → validation-chain.plugin-Cm0Ttnd8.d.mts} +140 -2
  36. package/dist/{validation-chain.plugin-Dtt4tO7R.mjs → validation-chain.plugin-k9joH2qw.mjs} +149 -2
  37. package/package.json +7 -5
  38. package/dist/types-BtMuhoX5.d.mts +0 -1830
@@ -1,4 +1,6 @@
1
- import { B as ObjectId, C as FieldPreset, G as Plugin, J as PopulateSpec, Q as RepositoryContext, _t as ValidationChainOptions, et as RepositoryInstance, it as SelectSpec, j as Logger, l as CascadeOptions, st as SoftDeleteOptions, ut as SortSpec, vt as ValidatorDefinition } from "./types-BtMuhoX5.mjs";
1
+ import { a as PopulateSpec, i as ObjectId, l as SortSpec, s as SelectSpec } from "./core-62oo3N1C.mjs";
2
+ import { h as RepositoryInstance, l as Plugin, p as RepositoryContext } from "./repository-DCHRWRXw.mjs";
3
+ import { c as ValidationChainOptions, i as Logger, l as ValidatorDefinition, o as SoftDeleteOptions, r as FieldPreset, t as CascadeOptions } from "./plugin-options-vFufQZMZ.mjs";
2
4
  import { BulkWriteResult } from "@classytic/repo-core/repository";
3
5
  import { AsyncLocalStorage } from "node:async_hooks";
4
6
  import { OffsetPaginationResult } from "@classytic/repo-core/pagination";
@@ -224,6 +226,142 @@ interface ImmutableStatesPluginOptions {
224
226
  }
225
227
  declare function immutableStatesPlugin(options: ImmutableStatesPluginOptions): Plugin;
226
228
  //#endregion
229
+ //#region src/plugins/idempotency-store.plugin.d.ts
230
+ interface IdempotencyStorePluginOptions {
231
+ /** Field carrying the deterministic operation key. @default `'key'` */
232
+ keyField?: string;
233
+ /** Field carrying the row's claim status. @default `'status'` */
234
+ statusField?: string;
235
+ /** Field carrying the current holder's lease token. @default `'leaseToken'` */
236
+ leaseTokenField?: string;
237
+ /** Field carrying the lease expiry timestamp. @default `'leaseExpiresAt'` */
238
+ leaseExpiresAtField?: string;
239
+ /** Field counting claim acquisitions (1 = first). @default `'attempts'` */
240
+ attemptsField?: string;
241
+ /** Field carrying saga resume data (Mixed). @default `'progress'` */
242
+ progressField?: string;
243
+ /** Field carrying the replayable success outcome (Mixed). @default `'result'` */
244
+ resultField?: string;
245
+ /** Field carrying the terminal failure code. @default `'failureCode'` */
246
+ failureCodeField?: string;
247
+ /** Field carrying the last error message (diagnostics). @default `'lastError'` */
248
+ lastErrorField?: string;
249
+ /** Status value of an in-flight claim. @default `'in_flight'` */
250
+ inFlightStatus?: string;
251
+ /** Terminal success status. @default `'succeeded'` */
252
+ succeededStatus?: string;
253
+ /** Terminal failure status. @default `'failed'` */
254
+ failedStatus?: string;
255
+ /** Claim lease (ms) — must outlive the longest guarded execution. @default 60_000 */
256
+ defaultLeaseMs?: number;
257
+ /**
258
+ * Re-acquisition ceiling. When > 0, an expired in-flight claim whose
259
+ * `attempts` already reached this value returns `exhausted` instead of
260
+ * re-acquiring — the bounded-retry escalation valve for operations whose
261
+ * external side effect is idempotent but may be wedged. 0 = unbounded
262
+ * (flow/order semantics: recovery always re-claims). @default 0
263
+ */
264
+ maxAttempts?: number;
265
+ }
266
+ /** Outcome of `claimKey()` — the claim decision matrix. */
267
+ type IdempotencyClaim<TProgress = Record<string, unknown>, TResult = unknown> =
268
+ /**
269
+ * This caller owns the lease — execute. `progress` present ⇒ a stale-lease
270
+ * re-acquire after a previous attempt persisted resume data (crash
271
+ * recovery): resume from it instead of re-running completed pivots.
272
+ * `attempt` is 1 on a fresh claim.
273
+ */
274
+ {
275
+ kind: 'acquired';
276
+ leaseToken: string;
277
+ attempt: number;
278
+ progress?: TProgress;
279
+ } |
280
+ /** A previous execution succeeded — replay its stored outcome. */
281
+ {
282
+ kind: 'completed';
283
+ result?: TResult;
284
+ } |
285
+ /** A previous execution failed terminally — replay the recorded code. */
286
+ {
287
+ kind: 'failed';
288
+ failureCode?: string;
289
+ error?: string;
290
+ } |
291
+ /** Another caller holds a live lease. `progress` (when persisted) lets a
292
+ * domain layer act on completed pivots without owning the lease — e.g.
293
+ * finish an idempotent post-pivot sync while the holder is wedged. */
294
+ {
295
+ kind: 'busy';
296
+ progress?: TProgress;
297
+ leaseToken?: string;
298
+ } |
299
+ /** `maxAttempts` re-acquisitions exhausted — escalate to a human. */
300
+ {
301
+ kind: 'exhausted';
302
+ attempts: number;
303
+ progress?: TProgress;
304
+ };
305
+ /**
306
+ * Methods contributed by `idempotencyStorePlugin()`. Use as a type assertion
307
+ * when constructing the repo (same convention as `LeaseMethods`).
308
+ */
309
+ interface IdempotencyStoreMethods<TProgress = Record<string, unknown>, TResult = unknown> {
310
+ /**
311
+ * Atomically claim `key`. Exactly one concurrent caller acquires; the rest
312
+ * branch on the row's durable state — see {@link IdempotencyClaim}.
313
+ *
314
+ * `seed` merges extra fields into the row on FIRST insert only (domain
315
+ * columns, tenant stamp). It never mutates an existing row.
316
+ */
317
+ claimKey(key: string, opts?: {
318
+ leaseMs?: number;
319
+ seed?: Record<string, unknown>;
320
+ }): Promise<IdempotencyClaim<TProgress, TResult>>;
321
+ /**
322
+ * Persist saga resume data (post-pivot, pre-complete). Lease-token-guarded —
323
+ * a stale crashed holder can't clobber a re-acquirer's record. Optional
324
+ * `where` adds domain guards to the CAS filter.
325
+ */
326
+ saveClaimProgress(key: string, leaseToken: string, progress: TProgress, opts?: {
327
+ where?: Record<string, unknown>;
328
+ }): Promise<boolean>;
329
+ /**
330
+ * CAS the claim to the terminal SUCCESS status, storing `result` for
331
+ * replay. Loses cleanly (returns false) when the lease was re-acquired.
332
+ */
333
+ completeClaim(key: string, leaseToken: string, result?: TResult, opts?: {
334
+ where?: Record<string, unknown>;
335
+ }): Promise<boolean>;
336
+ /**
337
+ * CAS the claim to the terminal FAILURE status. Later claims replay
338
+ * `failureCode` instead of re-executing. Use ONLY for definitive failures
339
+ * where the external side effect is known NOT to have happened.
340
+ */
341
+ failClaim(key: string, leaseToken: string, failure: {
342
+ code: string;
343
+ error?: string;
344
+ }, opts?: {
345
+ where?: Record<string, unknown>;
346
+ }): Promise<boolean>;
347
+ /**
348
+ * Delete the caller's own in-flight row on definitive PRE-side-effect
349
+ * failure so a retry re-executes cleanly. Never deletes a terminal row or
350
+ * a re-acquired lease.
351
+ */
352
+ releaseClaim(key: string, leaseToken: string): Promise<boolean>;
353
+ /**
354
+ * Record an AMBIGUOUS error and lapse the lease immediately (keeps the row
355
+ * in-flight) so a recovery sweep re-claims without waiting out the lease.
356
+ * The bridge between "this attempt is giving up" and "the operation is not
357
+ * over" — e.g. a network error mid-external-call.
358
+ */
359
+ expireClaim(key: string, leaseToken: string, opts?: {
360
+ error?: string;
361
+ }): Promise<boolean>;
362
+ }
363
+ declare function idempotencyStorePlugin(options?: IdempotencyStorePluginOptions): Plugin;
364
+ //#endregion
227
365
  //#region src/plugins/lease.plugin.d.ts
228
366
  interface LeasePluginOptions {
229
367
  /** Field carrying the row's status. @default `'status'` */
@@ -820,4 +958,4 @@ declare function immutableField(field: string): ValidatorDefinition;
820
958
  */
821
959
  declare function uniqueField(field: string, errorMessage?: string): ValidatorDefinition;
822
960
  //#endregion
823
- export { elasticSearchPlugin as A, LeasePluginOptions as C, immutableStatesPlugin as D, ImmutableStatesPluginOptions as E, auditLogPlugin as F, AppendOnlyPluginOptions as I, appendOnlyPlugin as L, BatchOperationsMethods as M, BulkWriteResult as N, fieldFilterPlugin as O, batchOperationsPlugin as P, AggregateHelpersMethods as R, LeaseMethods as S, ImmutableClaimView as T, observabilityPlugin as _, uniqueField as a, MethodRegistryRepository as b, TenantContext as c, SubdocumentMethods as d, subdocumentPlugin as f, OperationMetric as g, ObservabilityOptions as h, requireField as i, cascadePlugin as j, ElasticSearchOptions as k, TenantStore as l, softDeletePlugin as m, blockIf as n, validationChainPlugin as o, SoftDeleteMethods as p, immutableField as r, timestampPlugin as s, autoInject as t, createTenantContext as u, MongoOperationsMethods as v, leasePlugin as w, methodRegistryPlugin as x, mongoOperationsPlugin as y, aggregateHelpersPlugin as z };
961
+ export { ImmutableStatesPluginOptions as A, AppendOnlyPluginOptions as B, LeasePluginOptions as C, IdempotencyStorePluginOptions as D, IdempotencyStoreMethods as E, cascadePlugin as F, AggregateHelpersMethods as H, BatchOperationsMethods as I, BulkWriteResult as L, fieldFilterPlugin as M, ElasticSearchOptions as N, idempotencyStorePlugin as O, elasticSearchPlugin as P, batchOperationsPlugin as R, LeaseMethods as S, IdempotencyClaim as T, aggregateHelpersPlugin as U, appendOnlyPlugin as V, observabilityPlugin as _, uniqueField as a, MethodRegistryRepository as b, TenantContext as c, SubdocumentMethods as d, subdocumentPlugin as f, OperationMetric as g, ObservabilityOptions as h, requireField as i, immutableStatesPlugin as j, ImmutableClaimView as k, TenantStore as l, softDeletePlugin as m, blockIf as n, validationChainPlugin as o, SoftDeleteMethods as p, immutableField as r, timestampPlugin as s, autoInject as t, createTenantContext as u, MongoOperationsMethods as v, leasePlugin as w, methodRegistryPlugin as x, mongoOperationsPlugin as y, auditLogPlugin as z };
@@ -1,4 +1,4 @@
1
- import { l as OP_REGISTRY, s as ALL_OPERATIONS } from "./Repository-ClOraFjT.mjs";
1
+ import { c as ALL_OPERATIONS, u as OP_REGISTRY } from "./Repository-BFBTAMlA.mjs";
2
2
  import { _ as upsert } from "./update-1Lq9OMD2.mjs";
3
3
  import { n as warn } from "./logger-K7dPmu2U.mjs";
4
4
  import { t as createError } from "./error-BuByZwKU.mjs";
@@ -610,6 +610,153 @@ function immutableStatesPlugin(options) {
610
610
  };
611
611
  }
612
612
  //#endregion
613
+ //#region src/plugins/idempotency-store.plugin.ts
614
+ function randomToken() {
615
+ const bytes = /* @__PURE__ */ new Uint8Array(16);
616
+ globalThis.crypto.getRandomValues(bytes);
617
+ return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
618
+ }
619
+ function idempotencyStorePlugin(options = {}) {
620
+ const keyField = options.keyField ?? "key";
621
+ const statusField = options.statusField ?? "status";
622
+ const leaseTokenField = options.leaseTokenField ?? "leaseToken";
623
+ const leaseExpiresAtField = options.leaseExpiresAtField ?? "leaseExpiresAt";
624
+ const attemptsField = options.attemptsField ?? "attempts";
625
+ const progressField = options.progressField ?? "progress";
626
+ const resultField = options.resultField ?? "result";
627
+ const failureCodeField = options.failureCodeField ?? "failureCode";
628
+ const lastErrorField = options.lastErrorField ?? "lastError";
629
+ const inFlightStatus = options.inFlightStatus ?? "in_flight";
630
+ const succeededStatus = options.succeededStatus ?? "succeeded";
631
+ const failedStatus = options.failedStatus ?? "failed";
632
+ const defaultLeaseMs = options.defaultLeaseMs ?? 6e4;
633
+ const maxAttempts = options.maxAttempts ?? 0;
634
+ return {
635
+ name: "idempotencyStore",
636
+ apply(repo) {
637
+ if (!repo.registerMethod) throw new Error("idempotencyStorePlugin requires methodRegistryPlugin. Add methodRegistryPlugin() before idempotencyStorePlugin().");
638
+ const asDoc = (d) => d;
639
+ repo.registerMethod("claimKey", async function(key, opts = {}) {
640
+ if (typeof key !== "string" || key.length === 0) throw createError(400, "idempotencyStorePlugin.claimKey: key must be a non-empty string");
641
+ const leaseMs = opts.leaseMs ?? defaultLeaseMs;
642
+ const now = /* @__PURE__ */ new Date();
643
+ const leaseToken = randomToken();
644
+ const { doc, created } = await this.getOrCreate({ [keyField]: key }, {
645
+ ...opts.seed ?? {},
646
+ [keyField]: key,
647
+ [statusField]: inFlightStatus,
648
+ [leaseTokenField]: leaseToken,
649
+ [leaseExpiresAtField]: new Date(now.getTime() + leaseMs),
650
+ [attemptsField]: 1
651
+ });
652
+ if (created) return {
653
+ kind: "acquired",
654
+ leaseToken,
655
+ attempt: 1
656
+ };
657
+ const row = asDoc(doc);
658
+ if (row[statusField] === succeededStatus) return {
659
+ kind: "completed",
660
+ result: row[resultField]
661
+ };
662
+ if (row[statusField] === failedStatus) return {
663
+ kind: "failed",
664
+ failureCode: row[failureCodeField],
665
+ error: row[lastErrorField]
666
+ };
667
+ const leaseExpiresAt = row[leaseExpiresAtField];
668
+ const progress = row[progressField];
669
+ if (leaseExpiresAt && leaseExpiresAt > now) return {
670
+ kind: "busy",
671
+ ...progress !== void 0 ? { progress } : {},
672
+ ...row[leaseTokenField] !== void 0 ? { leaseToken: row[leaseTokenField] } : {}
673
+ };
674
+ const attempts = row[attemptsField] ?? 1;
675
+ if (maxAttempts > 0 && attempts >= maxAttempts) return {
676
+ kind: "exhausted",
677
+ attempts,
678
+ ...progress !== void 0 ? { progress } : {}
679
+ };
680
+ const reclaimed = await this.findOneAndUpdate({
681
+ [keyField]: key,
682
+ [statusField]: inFlightStatus,
683
+ [leaseExpiresAtField]: { $lte: now }
684
+ }, {
685
+ $set: {
686
+ [leaseTokenField]: leaseToken,
687
+ [leaseExpiresAtField]: new Date(now.getTime() + leaseMs)
688
+ },
689
+ $inc: { [attemptsField]: 1 }
690
+ }, { returnDocument: "after" });
691
+ if (reclaimed) {
692
+ const rec = asDoc(reclaimed);
693
+ const recProgress = rec[progressField];
694
+ return {
695
+ kind: "acquired",
696
+ leaseToken,
697
+ attempt: rec[attemptsField] ?? attempts + 1,
698
+ ...recProgress !== void 0 ? { progress: recProgress } : {}
699
+ };
700
+ }
701
+ return {
702
+ kind: "busy",
703
+ ...progress !== void 0 ? { progress } : {}
704
+ };
705
+ });
706
+ repo.registerMethod("saveClaimProgress", async function(key, leaseToken, progress, opts = {}) {
707
+ return await this.findOneAndUpdate({
708
+ ...opts.where ?? {},
709
+ [keyField]: key,
710
+ [leaseTokenField]: leaseToken,
711
+ [statusField]: inFlightStatus
712
+ }, { $set: { [progressField]: progress } }, { returnDocument: "after" }) !== null;
713
+ });
714
+ repo.registerMethod("completeClaim", async function(key, leaseToken, result, opts = {}) {
715
+ return await this.findOneAndUpdate({
716
+ ...opts.where ?? {},
717
+ [keyField]: key,
718
+ [leaseTokenField]: leaseToken,
719
+ [statusField]: inFlightStatus
720
+ }, { $set: {
721
+ [statusField]: succeededStatus,
722
+ ...result !== void 0 ? { [resultField]: result } : {}
723
+ } }, { returnDocument: "after" }) !== null;
724
+ });
725
+ repo.registerMethod("failClaim", async function(key, leaseToken, failure, opts = {}) {
726
+ if (!failure || typeof failure.code !== "string" || failure.code.length === 0) throw createError(400, "idempotencyStorePlugin.failClaim: failure.code must be a non-empty string");
727
+ return await this.findOneAndUpdate({
728
+ ...opts.where ?? {},
729
+ [keyField]: key,
730
+ [leaseTokenField]: leaseToken,
731
+ [statusField]: inFlightStatus
732
+ }, { $set: {
733
+ [statusField]: failedStatus,
734
+ [failureCodeField]: failure.code,
735
+ ...failure.error !== void 0 ? { [lastErrorField]: failure.error } : {}
736
+ } }, { returnDocument: "after" }) !== null;
737
+ });
738
+ repo.registerMethod("releaseClaim", async function(key, leaseToken) {
739
+ const res = await this.deleteMany({
740
+ [keyField]: key,
741
+ [leaseTokenField]: leaseToken,
742
+ [statusField]: inFlightStatus
743
+ });
744
+ return (typeof res === "number" ? res : res?.deletedCount ?? 0) > 0;
745
+ });
746
+ repo.registerMethod("expireClaim", async function(key, leaseToken, opts = {}) {
747
+ return await this.findOneAndUpdate({
748
+ [keyField]: key,
749
+ [leaseTokenField]: leaseToken,
750
+ [statusField]: inFlightStatus
751
+ }, { $set: {
752
+ [leaseExpiresAtField]: /* @__PURE__ */ new Date(),
753
+ ...opts.error !== void 0 ? { [lastErrorField]: opts.error } : {}
754
+ } }, { returnDocument: "after" }) !== null;
755
+ });
756
+ }
757
+ };
758
+ }
759
+ //#endregion
613
760
  //#region src/plugins/lease.plugin.ts
614
761
  function leasePlugin(options = {}) {
615
762
  const statusField = options.statusField ?? "status";
@@ -1304,4 +1451,4 @@ function uniqueField(field, errorMessage) {
1304
1451
  };
1305
1452
  }
1306
1453
  //#endregion
1307
- export { appendOnlyPlugin as _, uniqueField as a, subdocumentPlugin as c, mongoOperationsPlugin as d, leasePlugin as f, cascadePlugin as g, elasticSearchPlugin as h, requireField as i, observabilityPlugin as l, fieldFilterPlugin as m, blockIf as n, validationChainPlugin as o, immutableStatesPlugin as p, immutableField as r, createTenantContext as s, autoInject as t, MONGOKIT_PLUGIN_NAMES as u, aggregateHelpersPlugin as v };
1454
+ export { cascadePlugin as _, uniqueField as a, subdocumentPlugin as c, mongoOperationsPlugin as d, leasePlugin as f, elasticSearchPlugin as g, fieldFilterPlugin as h, requireField as i, observabilityPlugin as l, immutableStatesPlugin as m, blockIf as n, validationChainPlugin as o, idempotencyStorePlugin as p, immutableField as r, createTenantContext as s, autoInject as t, MONGOKIT_PLUGIN_NAMES as u, appendOnlyPlugin as v, aggregateHelpersPlugin as y };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/mongokit",
3
- "version": "3.24.0",
3
+ "version": "3.28.0",
4
4
  "description": "Production-grade MongoDB repositories - smart pagination, events, and plugins. Built on @classytic/repo-core.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -113,7 +113,7 @@
113
113
  },
114
114
  "homepage": "https://github.com/classytic/mongokit#readme",
115
115
  "peerDependencies": {
116
- "@classytic/repo-core": ">=0.14.0",
116
+ "@classytic/repo-core": ">=0.17.0",
117
117
  "mongoose": ">=9.4.1"
118
118
  },
119
119
  "engines": {
@@ -139,8 +139,10 @@
139
139
  "lint:package": "publint && attw --pack . --profile esm-only",
140
140
  "format": "biome format src/ --write",
141
141
  "check": "biome ci src/ --diagnostic-level=error",
142
+ "check:dead-code": "knip",
143
+ "ci": "npm run check && npm run typecheck && npm run typecheck:tests && npm run build && npm run lint:package && npm run check:dead-code && npm test",
142
144
  "push": "classytic-push",
143
- "prepublishOnly": "npm run check && npm run build && publint && npm run typecheck && npm run typecheck:tests && npm test",
145
+ "prepublishOnly": "npm run ci",
144
146
  "publish:dry": "npm publish --dry-run --access public",
145
147
  "publish:npm": "npm publish --access public",
146
148
  "release:tag": "node -e \"require('child_process').execSync('npm run push -- v'+require('./package.json').version,{stdio:'inherit'})\"",
@@ -155,7 +157,7 @@
155
157
  "@better-auth/mongo-adapter": "^1.6.22",
156
158
  "@biomejs/biome": "^2.4.10",
157
159
  "@classytic/dev-tools": "^0.2.0",
158
- "@classytic/repo-core": "^0.14.0",
160
+ "@classytic/repo-core": "^0.17.0",
159
161
  "@types/node": "^22.0.0",
160
162
  "@vitest/coverage-v8": "^4.1.4",
161
163
  "ajv": "^8.18.0",
@@ -168,7 +170,7 @@
168
170
  "mongoose": "^9.4.1",
169
171
  "publint": "^0.3.18",
170
172
  "tsdown": "^0.22.5",
171
- "typescript": "^7.0.2",
173
+ "typescript": "~5.9.0",
172
174
  "vitest": "^4.1.4"
173
175
  },
174
176
  "overrides": {