chore(): Improve caching rollout (#13702)

* chore(): Improve caching rollout

* Create bright-cobras-complain.md

* chore(): Improve caching rollout

* downgrade orm to 6.4.3

* chore(): Improve caching rollout

* chore(): Improve caching rollout

* chore(): Improve caching rollout

* chore(): Improve caching rollout

* chore(): Improve caching rollout

* fix

* update changeset

* update modules definition

* update engine tests

* update engine tests

* improve integration

* improve integration

* gracefully disconnect

* update test

* another attempt

* another attempt

* fix workflow storage

* fix remote joiner

* fix remote joiner

---------

Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
Adrien de Peretti
2025-10-08 17:44:00 +02:00
committed by GitHub
co-authored by Oli Juhl
parent e9b7a8c1f3
commit 0cbd9f0bc3
13 changed files with 248 additions and 182 deletions
+9
View File
@@ -0,0 +1,9 @@
---
"@medusajs/core-flows": patch
"@medusajs/types": patch
"@medusajs/deps": patch
"@medusajs/modules-sdk": patch
"@medusajs/orchestration": patch
---
chore(): Improve caching rollout
@@ -1,9 +1,8 @@
import { MedusaContainer } from "@medusajs/framework/types"
import {
IRegionModuleService,
IStoreModuleService,
MedusaContainer,
} from "@medusajs/framework/types"
import { MedusaError, Modules, useCache } from "@medusajs/framework/utils"
ContainerRegistrationKeys,
MedusaError,
} from "@medusajs/framework/utils"
import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk"
/**
@@ -17,45 +16,54 @@ export type FindOneOrAnyRegionStepInput = {
}
async function fetchRegionById(regionId: string, container: MedusaContainer) {
const service = container.resolve<IRegionModuleService>(Modules.REGION)
const query = container.resolve(ContainerRegistrationKeys.QUERY)
const args = [
regionId,
const { data } = await query.graph(
{
relations: ["countries"],
entity: "region",
filters: { id: regionId },
fields: ["*", "countries.*"],
},
] as Parameters<IRegionModuleService["retrieveRegion"]>
{
cache: { enable: true },
}
)
return await useCache(async () => service.retrieveRegion(...args), {
container,
key: args,
})
return data?.[0]
}
async function fetchDefaultStore(container: MedusaContainer) {
const storeModule = container.resolve<IStoreModuleService>(Modules.STORE)
const query = container.resolve(ContainerRegistrationKeys.QUERY)
return await useCache(async () => storeModule.listStores(), {
container,
key: "find-one-or-any-region-default-store",
})
const { data } = await query.graph(
{
entity: "store",
fields: ["*"],
},
{
cache: { enable: true },
}
)
return data?.[0]
}
async function fetchDefaultRegion(
defaultRegionId: string,
container: MedusaContainer
) {
const service = container.resolve<IRegionModuleService>(Modules.REGION)
const query = container.resolve(ContainerRegistrationKeys.QUERY)
const args = [
{ id: defaultRegionId },
{ relations: ["countries"] },
] as Parameters<IRegionModuleService["listRegions"]>
const { data } = await query.graph(
{
entity: "region",
filters: { id: defaultRegionId },
fields: ["*", "countries.*"],
},
{ cache: { enable: true } }
)
return await useCache(async () => service.listRegions(...args), {
container,
key: args,
})
return data?.[0]
}
export const findOneOrAnyRegionStepId = "find-one-or-any-region"
@@ -74,16 +82,13 @@ export const findOneOrAnyRegionStep = createStep(
}
}
const [store] = await fetchDefaultStore(container)
const store = await fetchDefaultStore(container)
if (!store) {
throw new MedusaError(MedusaError.Types.NOT_FOUND, "Store not found")
}
const [region] = await fetchDefaultRegion(
store.default_region_id!,
container
)
const region = await fetchDefaultRegion(store.default_region_id!, container)
if (!region) {
return new StepResponse(null)
@@ -24,7 +24,6 @@ import {
createRemoteLinkStep,
emitEventStep,
useQueryGraphStep,
useRemoteQueryStep,
} from "../../common"
import { acquireLockStep } from "../../locking/steps/acquire-lock"
import { releaseLockStep } from "../../locking/steps/release-lock"
@@ -118,17 +117,19 @@ export const completeCartWorkflow = createWorkflow(
return orderCart?.data?.order_id
})
const cart = useRemoteQueryStep({
entry_point: "cart",
const cartData = useQueryGraphStep({
entity: "cart",
fields: completeCartFields,
variables: { id: input.id },
list: false,
filters: { id: input.id },
options: {
isList: false,
},
}).config({
name: "cart-query",
})
// this needs to be before the validation step
const paymentSessions = validateCartPaymentsStep({ cart })
const paymentSessions = validateCartPaymentsStep({ cart: cartData.data })
// purpose of this step is to run compensation if cart completion fails
// and tries to refund the payment if captured
compensatePaymentIfNeededStep({
@@ -137,48 +138,58 @@ export const completeCartWorkflow = createWorkflow(
const validate = createHook("validate", {
input,
cart,
cart: cartData.data,
})
// If order ID does not exist, we are completing the cart for the first time
const order = when("create-order", { orderId }, ({ orderId }) => {
return !orderId
}).then(() => {
const cartOptionIds = transform({ cart }, ({ cart }) => {
const cartOptionIds = transform({ cart: cartData.data }, ({ cart }) => {
return cart.shipping_methods?.map((sm) => sm.shipping_option_id)
})
const shippingOptions = useRemoteQueryStep({
entry_point: "shipping_option",
const shippingOptionsData = useQueryGraphStep({
entity: "shipping_option",
fields: ["id", "shipping_profile_id"],
variables: { id: cartOptionIds },
list: true,
filters: { id: cartOptionIds },
options: {
cache: {
enable: true,
},
},
}).config({
name: "shipping-options-query",
})
validateShippingStep({ cart, shippingOptions })
const { variants, sales_channel_id } = transform({ cart }, (data) => {
const variantsMap: Record<string, any> = {}
const allItems = data.cart?.items?.map((item) => {
variantsMap[item.variant_id] = item.variant
return {
id: item.id,
variant_id: item.variant_id,
quantity: item.quantity,
}
})
return {
variants: Object.values(variantsMap),
items: allItems,
sales_channel_id: data.cart.sales_channel_id,
}
validateShippingStep({
cart: cartData.data,
shippingOptions: shippingOptionsData.data,
})
const cartToOrder = transform({ cart }, ({ cart }) => {
const { variants, sales_channel_id } = transform(
{ cart: cartData.data },
(data) => {
const variantsMap: Record<string, any> = {}
const allItems = data.cart?.items?.map((item) => {
variantsMap[item.variant_id] = item.variant
return {
id: item.id,
variant_id: item.variant_id,
quantity: item.quantity,
}
})
return {
variants: Object.values(variantsMap),
items: allItems,
sales_channel_id: data.cart.sales_channel_id,
}
}
)
const cartToOrder = transform({ cart: cartData.data }, ({ cart }) => {
const allItems = (cart.items ?? []).map((item) => {
const input: PrepareLineItemDataInput = {
item,
@@ -290,15 +301,18 @@ export const completeCartWorkflow = createWorkflow(
prepareConfirmInventoryInput
)
const updateCompletedAt = transform({ cart }, ({ cart }) => {
return {
id: cart.id,
completed_at: new Date(),
const updateCompletedAt = transform(
{ cart: cartData.data },
({ cart }) => {
return {
id: cart.id,
completed_at: new Date(),
}
}
})
)
const promotionUsage = transform(
{ cart },
{ cart: cartData.data },
({ cart }: { cart: CartWorkflowDTO }) => {
const promotionUsage: UsageComputedActions[] = []
@@ -329,7 +343,7 @@ export const completeCartWorkflow = createWorkflow(
)
const linksToCreate = transform(
{ cart, createdOrder },
{ cart: cartData.data, createdOrder },
({ cart, createdOrder }) => {
const links: LinkDefinition[] = [
{
@@ -414,7 +428,7 @@ export const completeCartWorkflow = createWorkflow(
*/
createHook("orderCreated", {
order_id: createdOrder.id,
cart_id: cart.id,
cart_id: cartData.data.id,
})
return createdOrder
@@ -1,4 +1,8 @@
import { isDefined, ShippingOptionPriceType } from "@medusajs/framework/utils"
import {
isDefined,
QueryContext,
ShippingOptionPriceType,
} from "@medusajs/framework/utils"
import {
createHook,
createWorkflow,
@@ -11,6 +15,7 @@ import {
AdditionalData,
CalculateShippingOptionPriceDTO,
ListShippingOptionsForCartWithPricingWorkflowInput,
QueryContextType,
} from "@medusajs/framework/types"
import { useQueryGraphStep, validatePresenceOfStep } from "../../common"
@@ -206,14 +211,21 @@ export const listShippingOptionsForCartWithPricingWorkflow = createWorkflow(
setShippingOptionsContext.getResult()
const commonOptions = transform(
{ input, cart, fulfillmentSetIds, setShippingOptionsContextResult },
{
input,
cart,
fulfillmentSetIds,
optionIds,
setShippingOptionsContextResult,
},
({
input,
cart,
fulfillmentSetIds,
optionIds,
setShippingOptionsContextResult,
}) => ({
context: {
context: QueryContext({
...(setShippingOptionsContextResult
? setShippingOptionsContextResult
: {}),
@@ -223,9 +235,10 @@ export const listShippingOptionsForCartWithPricingWorkflow = createWorkflow(
: input.enabled_in_store
? "true"
: "false",
},
}),
filters: {
id: optionIds.length ? optionIds : undefined,
fulfillment_set_id: fulfillmentSetIds,
address: {
@@ -238,21 +251,19 @@ export const listShippingOptionsForCartWithPricingWorkflow = createWorkflow(
})
)
const typeQueryFilters = transform(
{ optionIds, commonOptions },
({ optionIds, commonOptions }) => ({
id: optionIds.length ? optionIds : undefined,
...commonOptions,
})
)
/**
* We need to prefetch exact same SO as in the final result but only to determine pricing calculations first.
*/
const initialOptions = useRemoteQueryStep({
entry_point: "shipping_options",
variables: typeQueryFilters,
const { data: initialOptions } = useQueryGraphStep({
entity: "shipping_options",
fields: ["id", "price_type"],
filters: commonOptions.filters,
context: commonOptions.context as QueryContextType,
options: {
cache: {
enable: true,
},
},
}).config({ name: "shipping-options-price-type-query" })
/**
@@ -261,7 +272,7 @@ export const listShippingOptionsForCartWithPricingWorkflow = createWorkflow(
const { flatRateOptionsQuery, calculatedShippingOptionsQuery } = transform(
{
cart,
initialOptions,
initialOptions: initialOptions,
commonOptions,
},
({ cart, initialOptions, commonOptions }) => {
@@ -83,12 +83,16 @@ export const transferCartCustomerWorkflow = createWorkflow(
entity: "customer",
filters: { id: input.customer_id },
fields: ["id", "email"],
options: { throwIfKeyNotFound: true },
options: {
throwIfKeyNotFound: true,
isList: false,
cache: { enable: true },
},
}).config({ name: "get-customer" })
const customer = transform(
{ customerQuery },
({ customerQuery }) => customerQuery.data[0]
({ customerQuery }) => customerQuery.data
)
// If its the same customer, we don't want the email to be overridden, so we skip the
@@ -72,11 +72,17 @@ export const listShippingOptionsForOrderWorkflow = createWorkflow(
entity: "sales_channels",
filters: { id: order.sales_channel_id },
fields: [
"id",
"stock_locations.fulfillment_sets.id",
"stock_locations.id",
"stock_locations.name",
"stock_locations.address.*",
],
options: {
cache: {
enable: true,
},
},
}).config({ name: "sales_channels-fulfillment-query" })
const scFulfillmentSets = transform(
@@ -70,10 +70,10 @@ export const maybeRefreshShippingMethodsWorkflowId =
/**
* This workflows refreshes shipping method prices of an order and its changes. It's used in Return Merchandise Authorization (RMA) flows. It's used
* by other workflows, such as {@link refreshExchangeShippingWorkflow}.
*
*
* You can use this workflow within your customizations or your own custom workflows, allowing you to wrap custom logic around
* refreshing shipping methods in your custom flows.
*
*
* @example
* const { result } = await maybeRefreshShippingMethodsWorkflow(container)
* .run({
@@ -92,9 +92,9 @@ export const maybeRefreshShippingMethodsWorkflowId =
* }
* }
* })
*
*
* @summary
*
*
* Refreshes the shipping method prices of an order and its changes.
*/
export const maybeRefreshShippingMethodsWorkflow = createWorkflow(
@@ -116,6 +116,11 @@ export const maybeRefreshShippingMethodsWorkflow = createWorkflow(
entity: "shipping_option",
fields: [...COMMON_OPTIONS_FIELDS],
filters: { id: shippingMethod.shipping_option_id },
options: {
cache: {
enable: true,
},
},
}).config({ name: "calculated-option" })
const shippingOption = transform(shippingOptionQuery, ({ data }) => data[0])
@@ -53,6 +53,17 @@ export const ModulesDefinition: {
scope: MODULE_SCOPE.INTERNAL,
},
},
[Modules.CACHING]: {
key: Modules.CACHING,
defaultPackage: false,
label: upperCaseFirst(Modules.CACHING),
isRequired: false,
isQueryable: false,
dependencies: [Modules.EVENT_BUS, ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
},
},
[Modules.PRODUCT]: {
key: Modules.PRODUCT,
defaultPackage: false,
@@ -307,7 +307,7 @@ export class RemoteQuery {
private async executeFetchRequest(params: {
expand: RemoteExpandProperty
keyField: string
ids?: (unknown | unknown[])[]
ids?: (unknown | unknown[])[] | object
relationship?: JoinerRelationship
}): Promise<{
data: unknown[] | { [path: string]: unknown }
@@ -351,10 +351,6 @@ export class RemoteQuery {
}
}
if (ids) {
filters[keyField] = ids
}
delete options.args?.[BASE_PREFIX]
if (Object.keys(options.args ?? {}).length) {
filters = {
@@ -365,6 +361,28 @@ export class RemoteQuery {
}
const hasPagination = this.hasPagination(options)
const isIdsArray = Array.isArray(ids)
const idsLength = isIdsArray ? ids.length : 1
if (ids) {
if (isIdsArray && !idsLength) {
if (hasPagination) {
return {
data: {
rows: [],
metadata: this.buildPagination(options, 0),
},
path: "rows",
}
} else {
return {
data: [],
}
}
}
filters[keyField] = ids
}
let methodName = hasPagination ? "listAndCount" : "list"
@@ -380,11 +398,11 @@ export class RemoteQuery {
)
}
if (ids?.length && !hasPagination) {
if (isIdsArray && idsLength && !hasPagination) {
options.take = null
}
if (ids && ids.length >= MAX_BATCH_SIZE && !hasPagination) {
if (isIdsArray && idsLength >= MAX_BATCH_SIZE && !hasPagination) {
const data = await this.fetchRemoteDataBatched({
serviceName: serviceConfig.serviceName,
keyField,
@@ -620,6 +620,9 @@ export class RemoteJoiner {
isObject(ids) &&
Object.keys(ids).some((key) => !!FilterOperatorMap[key])
uniqueIds = isIdsUsingOperatorMap ? ids : Array.isArray(ids) ? ids : [ids]
uniqueIds = Array.isArray(uniqueIds)
? uniqueIds.filter((id) => id != null)
: uniqueIds
}
if (uniqueIds && Array.isArray(uniqueIds)) {
@@ -635,8 +638,6 @@ export class RemoteJoiner {
} else {
uniqueIds = Array.from(new Set(uniqueIds.flat()))
}
uniqueIds = uniqueIds.filter((id) => isDefined(id))
}
let pkFieldAdjusted = pkField
+2 -2
View File
@@ -71,7 +71,7 @@ export interface ICachingModuleService extends IModuleService {
*
* This example will try to get the data from the `caching-redis` provider first, and if not found, it will try to get it from the `caching-memcached` provider.
*/
get<T>({
get({
key,
tags,
providers,
@@ -92,7 +92,7 @@ export interface ICachingModuleService extends IModuleService {
* If not provided, the [default provider](https://docs.medusajs.com/infrastructure-modules/caching/providers#default-caching-module-provider) is used.
*/
providers?: string[]
}): Promise<T | null>
}): Promise<any | null>
/**
* This method stores data in the cache.
+5 -5
View File
@@ -37,11 +37,11 @@
"build": "rimraf dist && tsc --build"
},
"dependencies": {
"@mikro-orm/cli": "6.4.16",
"@mikro-orm/core": "6.4.16",
"@mikro-orm/knex": "6.4.16",
"@mikro-orm/migrations": "6.4.16",
"@mikro-orm/postgresql": "6.4.16",
"@mikro-orm/cli": "6.4.3",
"@mikro-orm/core": "6.4.3",
"@mikro-orm/knex": "6.4.3",
"@mikro-orm/migrations": "6.4.3",
"@mikro-orm/postgresql": "6.4.3",
"@opentelemetry/instrumentation-pg": "^0.44.0",
"@opentelemetry/resources": "^1.26.0",
"@opentelemetry/sdk-node": "^0.53.0",
+53 -71
View File
@@ -6439,11 +6439,11 @@ __metadata:
version: 0.0.0-use.local
resolution: "@medusajs/deps@workspace:packages/deps"
dependencies:
"@mikro-orm/cli": 6.4.16
"@mikro-orm/core": 6.4.16
"@mikro-orm/knex": 6.4.16
"@mikro-orm/migrations": 6.4.16
"@mikro-orm/postgresql": 6.4.16
"@mikro-orm/cli": 6.4.3
"@mikro-orm/core": 6.4.3
"@mikro-orm/knex": 6.4.3
"@mikro-orm/migrations": 6.4.3
"@mikro-orm/postgresql": 6.4.3
"@opentelemetry/instrumentation-pg": ^0.44.0
"@opentelemetry/resources": ^1.26.0
"@opentelemetry/sdk-node": ^0.53.0
@@ -7564,43 +7564,43 @@ __metadata:
languageName: unknown
linkType: soft
"@mikro-orm/cli@npm:6.4.16":
version: 6.4.16
resolution: "@mikro-orm/cli@npm:6.4.16"
"@mikro-orm/cli@npm:6.4.3":
version: 6.4.3
resolution: "@mikro-orm/cli@npm:6.4.3"
dependencies:
"@jercle/yargonaut": 1.1.5
"@mikro-orm/core": 6.4.16
"@mikro-orm/knex": 6.4.16
fs-extra: 11.3.0
"@mikro-orm/core": 6.4.3
"@mikro-orm/knex": 6.4.3
fs-extra: 11.2.0
tsconfig-paths: 4.2.0
yargs: 17.7.2
bin:
mikro-orm: ./cli
mikro-orm-esm: ./esm
checksum: c58cfc6a89a4770671c58e3c40a60c8a38229a74e1722d1fb6c14a8d19a43303aa26557ec6a0000ac1d494270f3cfd98e32e38c69163f6b9cafb7c3ef6804b00
checksum: de49d269d942fad5b3bde9cc4d21d0252a38543e00e70335024c98c1dfbc12fb30ff6271215b998d5a3c56f0c5cc5bab30c0109cda76b47f8b64d81f312c8698
languageName: node
linkType: hard
"@mikro-orm/core@npm:6.4.16":
version: 6.4.16
resolution: "@mikro-orm/core@npm:6.4.16"
"@mikro-orm/core@npm:6.4.3":
version: 6.4.3
resolution: "@mikro-orm/core@npm:6.4.3"
dependencies:
dataloader: 2.2.3
dotenv: 16.5.0
dotenv: 16.4.7
esprima: 4.0.1
fs-extra: 11.3.0
fs-extra: 11.2.0
globby: 11.1.0
mikro-orm: 6.4.16
mikro-orm: 6.4.3
reflect-metadata: 0.2.2
checksum: beeb614134d908674916105326c4846fe80fb9a7adc1251a8b9bd70f4db1115256a1bdaa08107fab1577986bbca46dd24b0ff24d87753925f382d1ef216bea18
checksum: d056eb9323a10f940e101a8a95454dcb2c4fa3429517e1a14a1b706869f53e92c2d2d2c9dfe330c02afbef101612787b1184db255ac5d74df5b0df0059928dd2
languageName: node
linkType: hard
"@mikro-orm/knex@npm:6.4.16":
version: 6.4.16
resolution: "@mikro-orm/knex@npm:6.4.16"
"@mikro-orm/knex@npm:6.4.3":
version: 6.4.3
resolution: "@mikro-orm/knex@npm:6.4.3"
dependencies:
fs-extra: 11.3.0
fs-extra: 11.2.0
knex: 3.1.0
sqlstring: 2.3.3
peerDependencies:
@@ -7615,35 +7615,35 @@ __metadata:
optional: true
mariadb:
optional: true
checksum: b0584fe3bd79b131512712ec9e31a1b76e272dcff519d5607daebfd5b3dd856116d9aae836c86baa006abc58e0331926aa3bd4ef4bba1a7ced4781d8c6fd3d21
checksum: 08dabcf1ea99d6a976892b4973e5de3f4b53e7ed0d3a1e3dcec20dd9349ba5a3ed153bbb96173990cd12367b3744df17f27bb3de751624207592e5d2f6e8637d
languageName: node
linkType: hard
"@mikro-orm/migrations@npm:6.4.16":
version: 6.4.16
resolution: "@mikro-orm/migrations@npm:6.4.16"
"@mikro-orm/migrations@npm:6.4.3":
version: 6.4.3
resolution: "@mikro-orm/migrations@npm:6.4.3"
dependencies:
"@mikro-orm/knex": 6.4.16
fs-extra: 11.3.0
"@mikro-orm/knex": 6.4.3
fs-extra: 11.2.0
umzug: 3.8.2
peerDependencies:
"@mikro-orm/core": ^6.0.0
checksum: 1d5beb2423c20879cffc9c51f035b2f24b963997bea4d69445f1686616686a3bd8d7b34c2081fcb421df24c0f14ee2c51b4ed01299b5c9dbf2af4fc4cbc22de5
checksum: 04e7e2405a3d0d94213f2bf40c34988e190f8f0df5ff4565ef23c750680b198f293247418ee60c0605edfcbca119177f2e87dc01d3e6abfc15ec7c4dc976324a
languageName: node
linkType: hard
"@mikro-orm/postgresql@npm:6.4.16":
version: 6.4.16
resolution: "@mikro-orm/postgresql@npm:6.4.16"
"@mikro-orm/postgresql@npm:6.4.3":
version: 6.4.3
resolution: "@mikro-orm/postgresql@npm:6.4.3"
dependencies:
"@mikro-orm/knex": 6.4.16
pg: 8.16.0
postgres-array: 3.0.4
"@mikro-orm/knex": 6.4.3
pg: 8.13.1
postgres-array: 3.0.2
postgres-date: 2.1.0
postgres-interval: 4.0.2
peerDependencies:
"@mikro-orm/core": ^6.0.0
checksum: 0d7b6dd04f9c476d445fd31b5544be88d38da9b3c5c3666c2c84c1fb35db55de27a98e23b62ba26528f9056bb28966cc8dc5673418bf4b2da6bf6bfeb6af0264
checksum: c0068dbd8f81d646de1171e9933e1385cd24faedb8a4347b9ab2c24e9bfa19a56cc5a6245aaf84fc8a19b355d02a7f1c160400483aa12411e3487e82b854e12c
languageName: node
linkType: hard
@@ -20897,10 +20897,10 @@ __metadata:
languageName: node
linkType: hard
"dotenv@npm:16.5.0":
version: 16.5.0
resolution: "dotenv@npm:16.5.0"
checksum: 5bc94c919fbd955bf0ba44d33922a1e93d1078e64a1db5c30faeded1d996e7a83c55332cb8ea4fae5a9ca4d0be44cbceb95c5811e70f9f095298df09d1997dd9
"dotenv@npm:16.4.7":
version: 16.4.7
resolution: "dotenv@npm:16.4.7"
checksum: be9f597e36a8daf834452daa1f4cc30e5375a5968f98f46d89b16b983c567398a330580c88395069a77473943c06b877d1ca25b4afafcdd6d4adb549e8293462
languageName: node
linkType: hard
@@ -23278,14 +23278,14 @@ __metadata:
languageName: node
linkType: hard
"fs-extra@npm:11.3.0":
version: 11.3.0
resolution: "fs-extra@npm:11.3.0"
"fs-extra@npm:11.2.0, fs-extra@npm:^11.1.0, fs-extra@npm:^11.2.0":
version: 11.2.0
resolution: "fs-extra@npm:11.2.0"
dependencies:
graceful-fs: ^4.2.0
jsonfile: ^6.0.1
universalify: ^2.0.0
checksum: 5f95e996186ff45463059feb115a22fb048bdaf7e487ecee8a8646c78ed8fdca63630e3077d4c16ce677051f5e60d3355a06f3cd61f3ca43f48cc58822a44d0a
checksum: d77a9a9efe60532d2e790e938c81a02c1b24904ef7a3efb3990b835514465ba720e99a6ea56fd5e2db53b4695319b644d76d5a0e9988a2beef80aa7b1da63398
languageName: node
linkType: hard
@@ -23311,17 +23311,6 @@ __metadata:
languageName: node
linkType: hard
"fs-extra@npm:^11.1.0, fs-extra@npm:^11.2.0":
version: 11.2.0
resolution: "fs-extra@npm:11.2.0"
dependencies:
graceful-fs: ^4.2.0
jsonfile: ^6.0.1
universalify: ^2.0.0
checksum: d77a9a9efe60532d2e790e938c81a02c1b24904ef7a3efb3990b835514465ba720e99a6ea56fd5e2db53b4695319b644d76d5a0e9988a2beef80aa7b1da63398
languageName: node
linkType: hard
"fs-extra@npm:^7.0.1, fs-extra@npm:~7.0.1":
version: 7.0.1
resolution: "fs-extra@npm:7.0.1"
@@ -27561,10 +27550,10 @@ __metadata:
languageName: node
linkType: hard
"mikro-orm@npm:6.4.16":
version: 6.4.16
resolution: "mikro-orm@npm:6.4.16"
checksum: 6a7d6ad717503433eba0372f890fc66c8f0f80927b40ae8666bc0795006b0a5a089e662a7a5fc121d3e0fbdb1350c1878dc3bee2c1c6bc4028c729b2c4a45f7a
"mikro-orm@npm:6.4.3":
version: 6.4.3
resolution: "mikro-orm@npm:6.4.3"
checksum: 6d489b7ba8ee9e97545bf035c0d1571e5e00baba4653c24713f4f4703311461f10d467d42f230674049282add6340fc9f33f3e3034827f86d89b5d62b3cc0180
languageName: node
linkType: hard
@@ -30234,10 +30223,10 @@ __metadata:
languageName: node
linkType: hard
"postgres-array@npm:3.0.4":
version: 3.0.4
resolution: "postgres-array@npm:3.0.4"
checksum: 47f3e648da512bacdd6a5ed55cf770605ec271330789faeece0fd13805a49f376d6e5c9e0e353377be11a9545e727dceaa2473566c505432bf06366ccd04c6b2
"postgres-array@npm:3.0.2, postgres-array@npm:~3.0.1":
version: 3.0.2
resolution: "postgres-array@npm:3.0.2"
checksum: 644aa071f67a66a59f641f8e623887d2b915bc102a32643e2aa8b54c11acd343c5ad97831ea444dd37bd4b921ba35add4aa2cb0c6b76700a8252c2324aeba5b4
languageName: node
linkType: hard
@@ -30248,13 +30237,6 @@ __metadata:
languageName: node
linkType: hard
"postgres-array@npm:~3.0.1":
version: 3.0.2
resolution: "postgres-array@npm:3.0.2"
checksum: 644aa071f67a66a59f641f8e623887d2b915bc102a32643e2aa8b54c11acd343c5ad97831ea444dd37bd4b921ba35add4aa2cb0c6b76700a8252c2324aeba5b4
languageName: node
linkType: hard
"postgres-bytea@npm:~1.0.0":
version: 1.0.0
resolution: "postgres-bytea@npm:1.0.0"