breaking: move shared HTTP utils to the framework (#9402)

Fixes: FRMW-2728, FRMW-2729

After this PR gets merged the following middleware will be exported from the `@medusajs/framework/http` import path.

- applyParamsAsFilters
- clearFiltersByKey
- applyDefaultFilters
- setContext
- getQueryConfig
- httpCompression
- maybeApplyLinkFilter
- refetchEntities
- unlessPath
- validateBody
- validateQuery

Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
This commit is contained in:
Harminder VirkandAdrien de Peretti authored and GitHub committed 2024-10-03 09:42:00 +00:00
1 parent 193f93464f
commit 48e00169d2
557 files changed
+2365 -3499

No files matched your search

@@ -25,7 +25,10 @@ import {
installNextjsStarter, installNextjsStarter,
startNextjsStarter, startNextjsStarter,
} from "../utils/nextjs-utils.js" } from "../utils/nextjs-utils.js"
import { getNodeVersion, MIN_SUPPORTED_NODE_VERSION } from "../utils/node-version.js" import {
getNodeVersion,
MIN_SUPPORTED_NODE_VERSION,
} from "../utils/node-version.js"
const slugify = slugifyType.default const slugify = slugifyType.default
@@ -1,6 +1,9 @@
import { EOL } from "os" import { EOL } from "os"
import pg from "pg" import pg from "pg"
import postgresClient, { DEFAULT_HOST, DEFAULT_PORT } from "./postgres-client.js" import postgresClient, {
DEFAULT_HOST,
DEFAULT_PORT,
} from "./postgres-client.js"
import inquirer from "inquirer" import inquirer from "inquirer"
import logMessage from "./log-message.js" import logMessage from "./log-message.js"
import formatConnectionString from "./format-connection-string.js" import formatConnectionString from "./format-connection-string.js"
@@ -16,8 +19,13 @@ export default async function createDb({ client, db }: CreateDbOptions) {
await client.query(`CREATE DATABASE "${db}"`) await client.query(`CREATE DATABASE "${db}"`)
} }
async function doesDbExist (client: pg.Client, dbName: string): Promise<boolean> { async function doesDbExist(
const result = await client.query(`SELECT datname FROM pg_catalog.pg_database WHERE datname='${dbName}';`) client: pg.Client,
dbName: string
): Promise<boolean> {
const result = await client.query(
`SELECT datname FROM pg_catalog.pg_database WHERE datname='${dbName}';`
)
return !!result.rowCount return !!result.rowCount
} }
@@ -75,14 +83,14 @@ async function getForDbName({
const defaultConnectionOptions = { const defaultConnectionOptions = {
host: DEFAULT_HOST, host: DEFAULT_HOST,
port: DEFAULT_PORT port: DEFAULT_PORT,
} }
try { try {
client = await postgresClient({ client = await postgresClient({
user: postgresUsername, user: postgresUsername,
password: postgresPassword, password: postgresPassword,
...defaultConnectionOptions ...defaultConnectionOptions,
}) })
} catch (e) { } catch (e) {
if (verbose) { if (verbose) {
@@ -129,7 +137,7 @@ async function getForDbName({
user: postgresUsername, user: postgresUsername,
password: postgresPassword, password: postgresPassword,
database: userDbName, database: userDbName,
...defaultConnectionOptions ...defaultConnectionOptions,
}) })
} catch (e) { } catch (e) {
logMessage({ logMessage({
@@ -148,7 +156,9 @@ async function getForDbName({
message: `A database already exists with the name ${dbName}, please enter a name for the database:`, message: `A database already exists with the name ${dbName}, please enter a name for the database:`,
default: dbName, default: dbName,
validate: (input) => { validate: (input) => {
return typeof input === "string" && input.length > 0 && input !== dbName return (
typeof input === "string" && input.length > 0 && input !== dbName
)
}, },
}, },
]) ])
@@ -167,7 +177,7 @@ async function getForDbName({
return { return {
client, client,
dbConnectionString, dbConnectionString,
dbName dbName,
} }
} }
@@ -32,7 +32,7 @@ const facts = [
"The event bus module is responsible for triggering events and relaying them to subscribers.", "The event bus module is responsible for triggering events and relaying them to subscribers.",
"The cache module is responsible for caching data that requires heavy computation.", "The cache module is responsible for caching data that requires heavy computation.",
"A workflow is a series of steps that are defined once and executed anywhere. Workflows are created under the src/workflows directory.", "A workflow is a series of steps that are defined once and executed anywhere. Workflows are created under the src/workflows directory.",
"A workflow's steps can be retried or rolled back in case of an error." "A workflow's steps can be retried or rolled back in case of an error.",
] ]
export const getFact = () => { export const getFact = () => {
@@ -1,7 +1,7 @@
import inquirer from "inquirer" import inquirer from "inquirer"
import { exec } from "child_process" import { exec } from "child_process"
import execute from "./execute.js" import execute from "./execute.js"
import { FactBoxOptions, displayFactBox } from "./facts.js" import { displayFactBox, FactBoxOptions } from "./facts.js"
import fs from "fs" import fs from "fs"
import path from "path" import path from "path"
import { customAlphabet } from "nanoid" import { customAlphabet } from "nanoid"
@@ -37,7 +37,7 @@ export async function installNextjsStarter({
abortController, abortController,
factBoxOptions, factBoxOptions,
verbose = false, verbose = false,
processManager processManager,
}: InstallOptions): Promise<string> { }: InstallOptions): Promise<string> {
factBoxOptions.interval = displayFactBox({ factBoxOptions.interval = displayFactBox({
...factBoxOptions, ...factBoxOptions,
@@ -72,7 +72,7 @@ export async function installNextjsStarter({
) )
const execOptions = { const execOptions = {
signal: abortController?.signal, signal: abortController?.signal,
cwd: nextjsDirectory cwd: nextjsDirectory,
} }
await processManager.runProcess({ await processManager.runProcess({
process: async () => { process: async () => {
@@ -1,7 +1,7 @@
export function getNodeVersion(): number { export function getNodeVersion(): number {
const [major] = process.versions.node.split('.').map(Number) const [major] = process.versions.node.split(".").map(Number)
return major return major
} }
export const MIN_SUPPORTED_NODE_VERSION = 20 export const MIN_SUPPORTED_NODE_VERSION = 20
@@ -1,4 +1,5 @@
import pg from "pg" import pg from "pg"
const { Client } = pg const { Client } = pg
export const DEFAULT_HOST = "localhost" export const DEFAULT_HOST = "localhost"
+1
View File
@@ -47,6 +47,7 @@
}, },
"dependencies": { "dependencies": {
"@medusajs/utils": "1.11.9", "@medusajs/utils": "1.11.9",
"@types/express": "^4.17.17",
"chalk": "^4.0.0", "chalk": "^4.0.0",
"configstore": "5.0.1", "configstore": "5.0.1",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
+1 -4
View File
@@ -22,10 +22,7 @@ import reporter from "../reporter"
import { getPackageManager, setPackageManager } from "../util/package-manager" import { getPackageManager, setPackageManager } from "../util/package-manager"
import { PanicId } from "../reporter/panic-handler" import { PanicId } from "../reporter/panic-handler"
import { clearProject } from "../util/clear-project" import { clearProject } from "../util/clear-project"
import { import { getNodeVersion, MIN_SUPPORTED_NODE_VERSION } from "@medusajs/utils"
getNodeVersion,
MIN_SUPPORTED_NODE_VERSION,
} from "@medusajs/utils"
const removeUndefined = (obj) => { const removeUndefined = (obj) => {
return Object.fromEntries( return Object.fromEntries(
@@ -1,19 +1,19 @@
const signalExit = require(`signal-exit`); const signalExit = require(`signal-exit`)
const cleanupTasks = new Set(); const cleanupTasks = new Set()
exports.registerCleanupTask = (taskFn) => { exports.registerCleanupTask = (taskFn) => {
cleanupTasks.add(taskFn); cleanupTasks.add(taskFn)
return () => { return () => {
const result = taskFn(); const result = taskFn()
cleanupTasks.delete(taskFn); cleanupTasks.delete(taskFn)
return result; return result
}; }
}; }
signalExit(() => { signalExit(() => {
if (cleanupTasks.size) { if (cleanupTasks.size) {
console.log(`Process exitted in middle of publishing - cleaning up`); console.log(`Process exitted in middle of publishing - cleaning up`)
cleanupTasks.forEach((taskFn) => taskFn()); cleanupTasks.forEach((taskFn) => taskFn())
} }
}); })
@@ -15,7 +15,7 @@ const getDependantPackages = ({
packagesToPublish.add(packageName) packagesToPublish.add(packageName)
const dependants = depTree[packageName] const dependants = depTree[packageName]
if (dependants) { if (dependants) {
dependants.forEach(dependant => dependants.forEach((dependant) =>
getDependantPackages({ getDependantPackages({
packageName: dependant, packageName: dependant,
depTree, depTree,
@@ -5,7 +5,7 @@ const defaultSpawnArgs = {
stdio: `inherit`, stdio: `inherit`,
} }
exports.setDefaultSpawnStdio = stdio => { exports.setDefaultSpawnStdio = (stdio) => {
defaultSpawnArgs.stdio = stdio defaultSpawnArgs.stdio = stdio
} }
@@ -1,4 +1,4 @@
exports.getVersionInfo = () => { exports.getVersionInfo = () => {
const { version: devCliVersion } = require(`../../package.json`); const { version: devCliVersion } = require(`../../package.json`)
return `Medusa Dev CLI version: ${devCliVersion}`; return `Medusa Dev CLI version: ${devCliVersion}`
}; }
@@ -10,13 +10,23 @@ import execa from "execa"
/** /**
* OAS output directory * OAS output directory
* *
* @privateRemarks * @privateRemarks
* This should be the only directory OAS is loaded from for Medusa V2. * This should be the only directory OAS is loaded from for Medusa V2.
* For now, we only use it if the --v2 flag it passed to the CLI tool. * For now, we only use it if the --v2 flag it passed to the CLI tool.
*/ */
const oasOutputPath = path.resolve( const oasOutputPath = path.resolve(
__dirname, "..", "..", "..", "..", "..", "..", "www", "utils", "generated", "oas-output" __dirname,
"..",
"..",
"..",
"..",
"..",
"..",
"www",
"utils",
"generated",
"oas-output"
) )
const basePath = path.resolve(__dirname, `../../`) const basePath = path.resolve(__dirname, `../../`)
@@ -128,7 +138,13 @@ describe("command oas", () => {
beforeAll(async () => { beforeAll(async () => {
const outDir = path.resolve(tmpDir, uid()) const outDir = path.resolve(tmpDir, uid())
await runCLI("oas", ["--type", "combined", "--out-dir", outDir, "--local"]) await runCLI("oas", [
"--type",
"combined",
"--out-dir",
outDir,
"--local",
])
const generatedFilePath = path.resolve(outDir, "combined.oas.json") const generatedFilePath = path.resolve(outDir, "combined.oas.json")
oas = (await readJson(generatedFilePath)) as OpenAPIObject oas = (await readJson(generatedFilePath)) as OpenAPIObject
}) })
@@ -227,7 +243,7 @@ describe("command oas", () => {
outDir, outDir,
"--paths", "--paths",
additionalPath, additionalPath,
"--local" "--local",
]) ])
const generatedFilePath = path.resolve(outDir, "store.oas.json") const generatedFilePath = path.resolve(outDir, "store.oas.json")
oas = (await readJson(generatedFilePath)) as OpenAPIObject oas = (await readJson(generatedFilePath)) as OpenAPIObject
@@ -363,7 +379,7 @@ components:
outDir, outDir,
"--base", "--base",
filePath, filePath,
"--local" "--local",
]) ])
const generatedFilePath = path.resolve(outDir, "store.oas.json") const generatedFilePath = path.resolve(outDir, "store.oas.json")
oas = (await readJson(generatedFilePath)) as OpenAPIObject oas = (await readJson(generatedFilePath)) as OpenAPIObject
@@ -473,7 +489,7 @@ components:
const routes = Object.keys(oas.paths) const routes = Object.keys(oas.paths)
expect(routes.includes("/admin/products")).toBeTruthy() expect(routes.includes("/admin/products")).toBeTruthy()
expect(routes.includes("/store/products")).toBeFalsy() expect(routes.includes("/store/products")).toBeFalsy()
}) })
}) })
describe("public OAS with base", () => { describe("public OAS with base", () => {
@@ -579,7 +595,7 @@ components:
]) ])
const generatedFilePath = path.resolve(outDir, "store.oas.json") const generatedFilePath = path.resolve(outDir, "store.oas.json")
oas = (await readJson(generatedFilePath)) as OpenAPIObject oas = (await readJson(generatedFilePath)) as OpenAPIObject
}) })
it("should add new path to existing paths", async () => { it("should add new path to existing paths", async () => {
const routes = Object.keys(oas.paths) const routes = Object.keys(oas.paths)
@@ -1,4 +1,7 @@
import { PreviewDocsOptions, previewDocs } from "@redocly/cli/lib/commands/preview-docs" import {
previewDocs,
PreviewDocsOptions,
} from "@redocly/cli/lib/commands/preview-docs"
import { commandWrapper } from "@redocly/cli/lib/wrapper" import { commandWrapper } from "@redocly/cli/lib/wrapper"
import { Command, Option, OptionValues } from "commander" import { Command, Option, OptionValues } from "commander"
import execa from "execa" import execa from "execa"
@@ -12,7 +15,12 @@ import {
} from "./utils/circular-patch-utils" } from "./utils/circular-patch-utils"
import { getTmpDirectory, isFile } from "./utils/fs-utils" import { getTmpDirectory, isFile } from "./utils/fs-utils"
import { readJson } from "./utils/json-utils" import { readJson } from "./utils/json-utils"
import { jsonObjectToYamlString, readYaml, writeYaml, writeYamlFromJson } from "./utils/yaml-utils" import {
jsonObjectToYamlString,
readYaml,
writeYaml,
writeYamlFromJson,
} from "./utils/yaml-utils"
import yargs from "yargs" import yargs from "yargs"
/** /**
@@ -64,7 +72,7 @@ export const commandOptions: Option[] = [
new Option( new Option(
"--main-file-name <mainFileName>", "--main-file-name <mainFileName>",
"The name of the main YAML file." "The name of the main YAML file."
).default("openapi.yaml") ).default("openapi.yaml"),
] ]
export function getCommand(): Command { export function getCommand(): Command {
@@ -140,7 +148,10 @@ export async function execute(cliParams: OptionValues): Promise<void> {
if (dryRun) { if (dryRun) {
console.log(`⚫️ Dry run - no files generated`) console.log(`⚫️ Dry run - no files generated`)
// check out possible changes in redocly config // check out possible changes in redocly config
await execa("git", ["checkout", path.join(basePath, "redocly", "redocly-config.yaml")]) await execa("git", [
"checkout",
path.join(basePath, "redocly", "redocly-config.yaml"),
])
return return
} }
if (shouldPreview) { if (shouldPreview) {
@@ -150,7 +161,10 @@ export async function execute(cliParams: OptionValues): Promise<void> {
if (shouldSplit) { if (shouldSplit) {
await generateReference(srcFileSanitized, outDir) await generateReference(srcFileSanitized, outDir)
} else { } else {
await writeYaml(path.join(outDir, finalOASFile), await fs.readFile(srcFileSanitized, "utf8")) await writeYaml(
path.join(outDir, finalOASFile),
await fs.readFile(srcFileSanitized, "utf8")
)
} }
if (shouldBuildHTML) { if (shouldBuildHTML) {
const outHTMLFile = path.resolve(outDir, "index.html") const outHTMLFile = path.resolve(outDir, "index.html")
@@ -236,17 +250,31 @@ const fixCirclularReferences = async (srcFile: string): Promise<void> => {
${hint} ${hint}
### ###
` `
const redoclyConfigPath = path.join(basePath, "redocly", "redocly-config.yaml") const redoclyConfigPath = path.join(
const originalContent = await readYaml(redoclyConfigPath) as CircularReferenceConfig basePath,
"redocly",
"redocly-config.yaml"
)
const originalContent = (await readYaml(
redoclyConfigPath
)) as CircularReferenceConfig
Object.keys(recommendation).forEach((recKey) => { Object.keys(recommendation).forEach((recKey) => {
originalContent.decorators["medusa/circular-patch"].schemas[recKey] = [ originalContent.decorators["medusa/circular-patch"].schemas[recKey] = [
...(originalContent.decorators["medusa/circular-patch"].schemas[recKey] || []), ...(originalContent.decorators["medusa/circular-patch"].schemas[
...recommendation[recKey] recKey
] || []),
...recommendation[recKey],
] ]
}) })
await writeYaml(redoclyConfigPath, jsonObjectToYamlString(originalContent)) await writeYaml(
console.log(`🟡 Added the following unhandled circular references to redocly-config.ts:` + hintMessage) redoclyConfigPath,
jsonObjectToYamlString(originalContent)
)
console.log(
`🟡 Added the following unhandled circular references to redocly-config.ts:` +
hintMessage
)
} }
} }
console.log(`🟢 All circular references are handled`) console.log(`🟢 All circular references are handled`)
@@ -15,9 +15,7 @@ import { isFile } from "./utils/fs-utils"
* Constants * Constants
*/ */
// Medusa core package directory // Medusa core package directory
const medusaPackagePath = path.dirname( const medusaPackagePath = path.dirname(require.resolve("@medusajs/medusa"))
require.resolve("@medusajs/medusa")
)
const basePath = path.resolve(__dirname, "../") const basePath = path.resolve(__dirname, "../")
/** /**
@@ -48,7 +46,7 @@ export const commandOptions: Option[] = [
new Option( new Option(
"--local", "--local",
"Generate OAS from local files rather than public OAS. This is useful for generating references in the Medusa monorepo." "Generate OAS from local files rather than public OAS. This is useful for generating references in the Medusa monorepo."
) ),
] ]
export function getCommand() { export function getCommand() {
@@ -105,11 +103,17 @@ export async function execute(cliParams: OptionValues) {
console.log(`🟣 Generating OAS - ${apiType}`) console.log(`🟣 Generating OAS - ${apiType}`)
if (apiType === "combined") { if (apiType === "combined") {
const adminOAS = !local ? await getPublicOas("admin") : await getOASFromCodebase("admin") const adminOAS = !local
const storeOAS = !local ? await getPublicOas("store") : await getOASFromCodebase("store") ? await getPublicOas("admin")
: await getOASFromCodebase("admin")
const storeOAS = !local
? await getPublicOas("store")
: await getOASFromCodebase("store")
oas = await combineOAS(adminOAS, storeOAS) oas = await combineOAS(adminOAS, storeOAS)
} else { } else {
oas = !local ? await getPublicOas(apiType) : await getOASFromCodebase(apiType) oas = !local
? await getPublicOas(apiType)
: await getOASFromCodebase(apiType)
} }
if (additionalPaths.length || baseFile) { if (additionalPaths.length || baseFile) {
@@ -133,14 +137,21 @@ export async function execute(cliParams: OptionValues) {
/** /**
* Methods * Methods
*/ */
async function getOASFromCodebase( async function getOASFromCodebase(apiType: ApiType): Promise<OpenAPIObject> {
apiType: ApiType
): Promise<OpenAPIObject> {
/** /**
* OAS output directory * OAS output directory
*/ */
const oasOutputPath = path.resolve( const oasOutputPath = path.resolve(
__dirname, "..", "..", "..", "..", "..", "www", "utils", "generated", "oas-output" __dirname,
"..",
"..",
"..",
"..",
"..",
"www",
"utils",
"generated",
"oas-output"
) )
const gen = await swaggerInline( const gen = await swaggerInline(
[ [
@@ -158,11 +169,9 @@ async function getOASFromCodebase(
return (await OpenAPIParser.parse(JSON.parse(gen))) as OpenAPIObject return (await OpenAPIParser.parse(JSON.parse(gen))) as OpenAPIObject
} }
async function getPublicOas( async function getPublicOas(apiType: ApiType) {
apiType: ApiType,
) {
const url = `https://docs.medusajs.com/v2/api/api/download/${apiType}` const url = `https://docs.medusajs.com/v2/api/api/download/${apiType}`
return await OpenAPIParser.parse(url) as OpenAPIObject return (await OpenAPIParser.parse(url)) as OpenAPIObject
} }
async function getOASFromPaths( async function getOASFromPaths(
+1 -1
View File
@@ -8,4 +8,4 @@ type CircularReferenceConfig = {
schemas: CircularReferenceSchema schemas: CircularReferenceSchema
} }
} }
} }
@@ -1,6 +1,5 @@
import { access, lstat, mkdtemp } from "fs/promises" import { access, lstat, mkdtemp } from "fs/promises"
import path from "path" import path, { sep } from "path"
import { sep } from "path"
import { tmpdir } from "os" import { tmpdir } from "os"
export async function isFile(filePath: string): Promise<boolean> { export async function isFile(filePath: string): Promise<boolean> {
@@ -6,11 +6,17 @@ export const readYaml = async (filePath): Promise<unknown> => {
return yaml.load(yamlString) return yaml.load(yamlString)
} }
export const writeYaml = async (filePath: string, yamlContent: string): Promise<void> => { export const writeYaml = async (
filePath: string,
yamlContent: string
): Promise<void> => {
await fs.writeFile(filePath, yamlContent, "utf8") await fs.writeFile(filePath, yamlContent, "utf8")
} }
export const writeYamlFromJson = async (filePath, jsonObject): Promise<void> => { export const writeYamlFromJson = async (
filePath,
jsonObject
): Promise<void> => {
const yamlString = yaml.dump(jsonObject) const yamlString = yaml.dump(jsonObject)
await fs.writeFile(filePath, yamlString, "utf8") await fs.writeFile(filePath, yamlString, "utf8")
} }
@@ -4,4 +4,3 @@ export * from "./link-sales-channels-to-publishable-key"
export * from "./revoke-api-keys" export * from "./revoke-api-keys"
export * from "./update-api-keys" export * from "./update-api-keys"
export * from "./validate-sales-channel-exists" export * from "./validate-sales-channel-exists"
@@ -3,4 +3,3 @@ export * from "./delete-api-keys"
export * from "./link-sales-channels-to-publishable-key" export * from "./link-sales-channels-to-publishable-key"
export * from "./revoke-api-keys" export * from "./revoke-api-keys"
export * from "./update-api-keys" export * from "./update-api-keys"
@@ -1,3 +1,2 @@
export * from "./steps" export * from "./steps"
export * from "./workflows" export * from "./workflows"
@@ -1,3 +1,2 @@
export * from "./steps" export * from "./steps"
export * from "./workflows" export * from "./workflows"
@@ -28,4 +28,3 @@ export * from "./update-line-items"
export * from "./validate-cart-payments" export * from "./validate-cart-payments"
export * from "./validate-cart-shipping-options" export * from "./validate-cart-shipping-options"
export * from "./validate-variant-prices" export * from "./validate-variant-prices"
@@ -83,7 +83,8 @@ export const updateTaxLinesWorkflow = createWorkflow(
transform({ input, cart }, (data) => ({ transform({ input, cart }, (data) => ({
cart: data.cart, cart: data.cart,
items: data.input.items || data.cart.items, items: data.input.items || data.cart.items,
shipping_methods: data.input.shipping_methods || data.cart.shipping_methods, shipping_methods:
data.input.shipping_methods || data.cart.shipping_methods,
force_tax_calculation: data.input.force_tax_calculation, force_tax_calculation: data.input.force_tax_calculation,
})) }))
) )
@@ -6,4 +6,3 @@ export * from "./delete-customers"
export * from "./remove-customer-account" export * from "./remove-customer-account"
export * from "./update-addresses" export * from "./update-addresses"
export * from "./update-customers" export * from "./update-customers"
@@ -15,4 +15,3 @@ export * from "./update-fulfillment"
export * from "./update-shipping-profiles" export * from "./update-shipping-profiles"
export * from "./upsert-shipping-options" export * from "./upsert-shipping-options"
export * from "./validate-shipment" export * from "./validate-shipment"
@@ -1,3 +1,2 @@
export * from "./capture-payment" export * from "./capture-payment"
export * from "./refund-payment" export * from "./refund-payment"
@@ -1,3 +1,2 @@
export * from "./steps" export * from "./steps"
export * from "./workflows" export * from "./workflows"
@@ -1,3 +1,2 @@
export * from "./steps" export * from "./steps"
export * from "./workflows" export * from "./workflows"
@@ -3,4 +3,3 @@ export * from "./create-users"
export * from "./delete-users" export * from "./delete-users"
export * from "./remove-user-account" export * from "./remove-user-account"
export * from "./update-users" export * from "./update-users"
+1 -1
View File
@@ -59,7 +59,6 @@
"@mikro-orm/postgresql": "5.9.7", "@mikro-orm/postgresql": "5.9.7",
"@swc/core": "^1.7.28", "@swc/core": "^1.7.28",
"@swc/jest": "^0.2.36", "@swc/jest": "^0.2.36",
"@types/express": "^4.17.17",
"@types/jsonwebtoken": "^8.5.9", "@types/jsonwebtoken": "^8.5.9",
"awilix": "^8.0.1", "awilix": "^8.0.1",
"ioredis": "^5.4.1", "ioredis": "^5.4.1",
@@ -78,6 +77,7 @@
"@medusajs/utils": "^1.11.9", "@medusajs/utils": "^1.11.9",
"@medusajs/workflows-sdk": "^0.1.6", "@medusajs/workflows-sdk": "^0.1.6",
"@opentelemetry/api": "^1.9.0", "@opentelemetry/api": "^1.9.0",
"@types/express": "^4.17.17",
"connect-redis": "5.2.0", "connect-redis": "5.2.0",
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",
"cors": "^2.8.5", "cors": "^2.8.5",
+3 -8
View File
@@ -1,18 +1,13 @@
import { createMedusaContainer } from "@medusajs/utils" import { createMedusaContainer } from "@medusajs/utils"
import { AwilixContainer, ResolveOptions } from "awilix" import { AwilixContainer, ResolveOptions } from "awilix"
import { TransformObjectMethodToAsync } from "@medusajs/types"; import { ModuleImplementations } from "@medusajs/types"
/**
* The following interface acts as a bucket that other modules or the
* utils package can fill using declaration merging
*/
export interface ModuleImplementations {}
/** /**
* The Medusa Container extends [Awilix](https://github.com/jeffijoe/awilix) to * The Medusa Container extends [Awilix](https://github.com/jeffijoe/awilix) to
* provide dependency injection functionalities. * provide dependency injection functionalities.
*/ */
export type MedusaContainer<Cradle extends object = TransformObjectMethodToAsync<ModuleImplementations>> = // export type MedusaContainer<Cradle extends object = TransformObjectMethodToAsync<ModuleImplementations>> =
export type MedusaContainer<Cradle extends object = ModuleImplementations> =
Omit<AwilixContainer, "resolve"> & { Omit<AwilixContainer, "resolve"> & {
resolve<K extends keyof Cradle>( resolve<K extends keyof Cradle>(
key: K, key: K,
@@ -1,8 +1,14 @@
import zod from "zod" import zod from "zod"
import { MedusaError } from "@medusajs/framework/utils" import { MedusaError } from "@medusajs/utils"
import { createLinkBody } from "../validators" import { validateAndTransformBody } from "../utils/validate-body"
import { validateAndTransformBody } from "../validate-body" import { MedusaRequest, MedusaResponse } from "../types"
import { MedusaRequest, MedusaResponse } from "../../../types/routing"
const createLinkBody = () => {
return zod.object({
add: zod.array(zod.string()).optional(),
remove: zod.array(zod.string()).optional(),
})
}
describe("validateAndTransformBody", () => { describe("validateAndTransformBody", () => {
afterEach(() => { afterEach(() => {
@@ -1,8 +1,57 @@
import { MedusaError } from "@medusajs/framework/utils" import z from "zod"
import { NextFunction, Request, Response } from "express" import { MedusaError } from "@medusajs/utils"
import { validateAndTransformQuery } from "../utils/validate-query"
import { MedusaRequest, MedusaResponse, MedusaNextFunction } from "../types"
import { createFindParams } from "../validators" export const createSelectParams = () => {
import { validateAndTransformQuery } from "../validate-query" return z.object({
fields: z.string().optional(),
})
}
const createFindParams = ({
offset,
limit,
order,
}: {
offset?: number
limit?: number
order?: string
} = {}) => {
const selectParams = createSelectParams()
return selectParams.merge(
z.object({
offset: z.preprocess(
(val) => {
if (val && typeof val === "string") {
return parseInt(val)
}
return val
},
z
.number()
.optional()
.default(offset ?? 0)
),
limit: z.preprocess(
(val) => {
if (val && typeof val === "string") {
return parseInt(val)
}
return val
},
z
.number()
.optional()
.default(limit ?? 20)
),
order: order
? z.string().optional().default(order)
: z.string().optional(),
})
)
}
describe("validateAndTransformQuery", () => { describe("validateAndTransformQuery", () => {
afterEach(() => { afterEach(() => {
@@ -12,9 +61,9 @@ describe("validateAndTransformQuery", () => {
it("should transform the input query", async () => { it("should transform the input query", async () => {
let mockRequest = { let mockRequest = {
query: {}, query: {},
} as Request } as MedusaRequest
const mockResponse = {} as Response const mockResponse = {} as MedusaResponse
const nextFunction: NextFunction = jest.fn() const nextFunction: MedusaNextFunction = jest.fn()
const expectations = ({ const expectations = ({
offset, offset,
@@ -104,15 +153,13 @@ describe("validateAndTransformQuery", () => {
inputOrder: undefined, inputOrder: undefined,
}) })
//////////////////////////////
mockRequest = { mockRequest = {
query: { query: {
limit: "10", limit: "10",
offset: "5", offset: "5",
order: "created_at", order: "created_at",
}, },
} as unknown as Request } as unknown as MedusaRequest
middleware = validateAndTransformQuery(createFindParams(), queryConfig) middleware = validateAndTransformQuery(createFindParams(), queryConfig)
@@ -125,15 +172,13 @@ describe("validateAndTransformQuery", () => {
transformedOrder: { created_at: "ASC" }, transformedOrder: { created_at: "ASC" },
}) })
//////////////////////////////
mockRequest = { mockRequest = {
query: { query: {
limit: "10", limit: "10",
offset: "5", offset: "5",
order: "created_at", order: "created_at",
}, },
} as unknown as Request } as unknown as MedusaRequest
queryConfig = { queryConfig = {
defaults: [ defaults: [
@@ -166,9 +211,9 @@ describe("validateAndTransformQuery", () => {
query: { query: {
fields: "id", fields: "id",
}, },
} as unknown as Request } as unknown as MedusaRequest
const mockResponse = {} as Response const mockResponse = {} as MedusaResponse
const nextFunction: NextFunction = jest.fn() const nextFunction: MedusaNextFunction = jest.fn()
let queryConfig: any = { let queryConfig: any = {
defaultFields: [ defaultFields: [
@@ -200,13 +245,11 @@ describe("validateAndTransformQuery", () => {
}) })
) )
//////////////////////////////
mockRequest = { mockRequest = {
query: { query: {
fields: "+test_prop,-prop-test-something", fields: "+test_prop,-prop-test-something",
}, },
} as unknown as Request } as unknown as MedusaRequest
queryConfig = { queryConfig = {
defaultFields: [ defaultFields: [
@@ -249,13 +292,11 @@ describe("validateAndTransformQuery", () => {
}) })
) )
//////////////////////////////
mockRequest = { mockRequest = {
query: { query: {
fields: "+test_prop,-updated_at", fields: "+test_prop,-updated_at",
}, },
} as unknown as Request } as unknown as MedusaRequest
queryConfig = { queryConfig = {
defaults: [ defaults: [
@@ -296,9 +337,9 @@ describe("validateAndTransformQuery", () => {
query: { query: {
fields: "*product.variants,+product.id", fields: "*product.variants,+product.id",
}, },
} as unknown as Request } as unknown as MedusaRequest
const mockResponse = {} as Response const mockResponse = {} as MedusaResponse
const nextFunction: NextFunction = jest.fn() const nextFunction: MedusaNextFunction = jest.fn()
let queryConfig: any = { let queryConfig: any = {
defaults: [ defaults: [
@@ -367,13 +408,11 @@ describe("validateAndTransformQuery", () => {
}) })
) )
//////////////////////////////
mockRequest = { mockRequest = {
query: { query: {
fields: "store.name", fields: "store.name",
}, },
} as unknown as Request } as unknown as MedusaRequest
queryConfig = { queryConfig = {
defaultFields: [ defaultFields: [
@@ -423,9 +462,9 @@ describe("validateAndTransformQuery", () => {
query: { query: {
fields: "+test_prop", fields: "+test_prop",
}, },
} as unknown as Request } as unknown as MedusaRequest
const mockResponse = {} as Response const mockResponse = {} as MedusaResponse
const nextFunction: NextFunction = jest.fn() const nextFunction: MedusaNextFunction = jest.fn()
let queryConfig: any = { let queryConfig: any = {
defaultFields: [ defaultFields: [
@@ -468,13 +507,11 @@ describe("validateAndTransformQuery", () => {
) )
) )
//////////////////////////////
mockRequest = { mockRequest = {
query: { query: {
fields: "product", fields: "product",
}, },
} as unknown as Request } as unknown as MedusaRequest
queryConfig = { queryConfig = {
defaultFields: [ defaultFields: [
@@ -517,13 +554,11 @@ describe("validateAndTransformQuery", () => {
) )
) )
//////////////////////////////
mockRequest = { mockRequest = {
query: { query: {
fields: "store", fields: "store",
}, },
} as unknown as Request } as unknown as MedusaRequest
queryConfig = { queryConfig = {
defaultFields: [ defaultFields: [
@@ -562,13 +597,11 @@ describe("validateAndTransformQuery", () => {
) )
) )
//////////////////////////////
mockRequest = { mockRequest = {
query: { query: {
fields: "*product", fields: "*product",
}, },
} as unknown as Request } as unknown as MedusaRequest
queryConfig = { queryConfig = {
defaults: [ defaults: [
@@ -605,13 +638,11 @@ describe("validateAndTransformQuery", () => {
) )
) )
//////////////////////////////
mockRequest = { mockRequest = {
query: { query: {
fields: "*product.variants", fields: "*product.variants",
}, },
} as unknown as Request } as unknown as MedusaRequest
queryConfig = { queryConfig = {
defaults: [ defaults: [
@@ -649,13 +680,11 @@ describe("validateAndTransformQuery", () => {
) )
) )
//////////////////////////////
mockRequest = { mockRequest = {
query: { query: {
fields: "*product", fields: "*product",
}, },
} as unknown as Request } as unknown as MedusaRequest
queryConfig = { queryConfig = {
defaults: [ defaults: [
@@ -2,4 +2,11 @@ export * from "./express-loader"
export * from "./router" export * from "./router"
export * from "./types" export * from "./types"
export * from "./middlewares" export * from "./middlewares"
export * from "./utils/http-compression"
export * from "./utils/validate-body"
export * from "./utils/validate-query"
export * from "./utils/get-query-config"
export * from "./utils/define-middlewares" export * from "./utils/define-middlewares"
export * from "./utils/maybe-apply-link-filter"
export * from "./utils/refetch-entities"
export * from "./utils/unless-path"
@@ -1,11 +1,10 @@
import { isObject, isPresent } from "@medusajs/framework/utils" import { isObject, isPresent } from "@medusajs/utils"
import { NextFunction } from "express" import { MedusaNextFunction, MedusaRequest } from "../types"
import { MedusaRequest } from "../../../../types/routing"
export function applyDefaultFilters<TFilter extends object>( export function applyDefaultFilters<TFilter extends object>(
filtersToApply: TFilter filtersToApply: TFilter
) { ) {
return async (req: MedusaRequest, _, next: NextFunction) => { return async (req: MedusaRequest, _, next: MedusaNextFunction) => {
for (const [filter, filterValue] of Object.entries(filtersToApply)) { for (const [filter, filterValue] of Object.entries(filtersToApply)) {
let valueToApply = filterValue let valueToApply = filterValue
@@ -0,0 +1,13 @@
import { MedusaNextFunction, MedusaRequest } from "../types"
export function applyParamsAsFilters(mappings: { [param: string]: string }) {
return async (req: MedusaRequest, _, next: MedusaNextFunction) => {
for (const [param, paramValue] of Object.entries(req.params)) {
if (mappings[param]) {
req.filterableFields[mappings[param]] = paramValue
}
}
return next()
}
}
@@ -0,0 +1,11 @@
import { MedusaNextFunction, MedusaRequest } from "../types"
export function clearFiltersByKey(keys: string[]) {
return async (req: MedusaRequest, _, next: MedusaNextFunction) => {
keys.forEach((key) => {
delete req.filterableFields[key]
})
return next()
}
}
@@ -1,4 +1,3 @@
import { Query } from "@medusajs/types"
import { import {
ApiKeyType, ApiKeyType,
ContainerRegistrationKeys, ContainerRegistrationKeys,
@@ -31,7 +30,7 @@ export async function ensurePublishableApiKeyMiddleware(
} }
let apiKey let apiKey
const query: Query = req.scope.resolve(ContainerRegistrationKeys.QUERY) const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)
try { try {
const { data } = await query.graph( const { data } = await query.graph(
@@ -3,7 +3,6 @@ import { NextFunction, Response } from "express"
import { ContainerRegistrationKeys, MedusaError } from "@medusajs/utils" import { ContainerRegistrationKeys, MedusaError } from "@medusajs/utils"
import { formatException } from "./exception-formatter" import { formatException } from "./exception-formatter"
import { MedusaRequest } from "../types" import { MedusaRequest } from "../types"
import { logger as logger_ } from "../../logger"
const QUERY_RUNNER_RELEASED = "QueryRunnerAlreadyReleasedError" const QUERY_RUNNER_RELEASED = "QueryRunnerAlreadyReleasedError"
const TRANSACTION_STARTED = "TransactionAlreadyStartedError" const TRANSACTION_STARTED = "TransactionAlreadyStartedError"
@@ -20,9 +19,7 @@ export function errorHandler() {
res: Response, res: Response,
next: NextFunction next: NextFunction
) => { ) => {
const logger: typeof logger_ = req.scope.resolve( const logger = req.scope.resolve(ContainerRegistrationKeys.LOGGER)
ContainerRegistrationKeys.LOGGER
)
err = formatException(err) err = formatException(err)
@@ -1,3 +1,7 @@
export * from "./authenticate-middleware" export * from "./authenticate-middleware"
export * from "./error-handler" export * from "./error-handler"
export * from "./exception-formatter" export * from "./exception-formatter"
export * from "./apply-default-filters"
export * from "./apply-params-as-filters"
export * from "./clear-filters-by-key"
export * from "./set-context"
@@ -1,8 +1,7 @@
import { NextFunction } from "express" import { MedusaNextFunction, MedusaRequest } from "../types"
import { MedusaRequest } from "../../../../types/routing"
export function setContext(context: Record<string, any>) { export function setContext(context: Record<string, any>) {
return async (req: MedusaRequest, _, next: NextFunction) => { return async (req: MedusaRequest, _, next: MedusaNextFunction) => {
const ctx: Record<string, any> = { ...(req.context || {}) } const ctx: Record<string, any> = { ...(req.context || {}) }
for (const [contextKey, contextValue] of Object.entries(context || {})) { for (const [contextKey, contextValue] of Object.entries(context || {})) {
+5 -9
View File
@@ -1,17 +1,13 @@
import type { NextFunction, Request, Response } from "express" import type { NextFunction, Request, Response } from "express"
import { ZodObject } from "zod" import { ZodObject } from "zod"
import { MedusaPricingContext, RequestQueryFields } from "@medusajs/types" import {
FindConfig,
MedusaPricingContext,
RequestQueryFields,
} from "@medusajs/types"
import { MedusaContainer } from "../container" import { MedusaContainer } from "../container"
export interface FindConfig<Entity> {
select?: (keyof Entity)[]
skip?: number
take?: number
relations?: string[]
order?: { [K: string]: "ASC" | "DESC" }
}
/** /**
* List of all the supported HTTP methods * List of all the supported HTTP methods
*/ */
@@ -1,13 +1,12 @@
import { RequestQueryFields } from "@medusajs/framework/types" import { pick } from "lodash"
import { RequestQueryFields, FindConfig, QueryConfig } from "@medusajs/types"
import { import {
getSetDifference,
isDefined, isDefined,
isPresent, isPresent,
MedusaError, MedusaError,
getSetDifference,
stringToSelectRelationObject, stringToSelectRelationObject,
} from "@medusajs/framework/utils" } from "@medusajs/utils"
import { pick } from "lodash"
import { FindConfig, QueryConfig } from "../types/common"
export function pickByConfig<TModel>( export function pickByConfig<TModel>(
obj: TModel | TModel[], obj: TModel | TModel[],
@@ -1,12 +1,17 @@
import {
HttpCompressionOptions,
ProjectConfigOptions,
} from "@medusajs/framework/types"
import compression from "compression" import compression from "compression"
import { Request, Response } from "express" import type { ConfigModule } from "@medusajs/types"
import { ContainerRegistrationKeys } from "@medusajs/utils"
export function shouldCompressResponse(req: Request, res: Response) { import { HttpCompressionOptions, ProjectConfigOptions } from "../../config"
const { projectConfig } = req.scope.resolve("configModule") import type { MedusaRequest, MedusaResponse } from "../types"
export function shouldCompressResponse(
req: MedusaRequest,
res: MedusaResponse
) {
const { projectConfig } = req.scope.resolve<ConfigModule>(
ContainerRegistrationKeys.CONFIG_MODULE
)
const { enabled } = compressionOptions(projectConfig) const { enabled } = compressionOptions(projectConfig)
if (!enabled) { if (!enabled) {
@@ -2,9 +2,8 @@ import {
arrayIntersection, arrayIntersection,
ContainerRegistrationKeys, ContainerRegistrationKeys,
remoteQueryObjectFromString, remoteQueryObjectFromString,
} from "@medusajs/framework/utils" } from "@medusajs/utils"
import { NextFunction } from "express" import { MedusaNextFunction, MedusaRequest } from "../types"
import { MedusaRequest } from "../../types/routing"
export function maybeApplyLinkFilter({ export function maybeApplyLinkFilter({
entryPoint, entryPoint,
@@ -12,7 +11,11 @@ export function maybeApplyLinkFilter({
filterableField, filterableField,
filterByField = "id", filterByField = "id",
}) { }) {
return async function linkFilter(req: MedusaRequest, _, next: NextFunction) { return async function linkFilter(
req: MedusaRequest,
_,
next: MedusaNextFunction
) {
const filterableFields = req.filterableFields const filterableFields = req.filterableFields
if (!filterableFields?.[filterableField]) { if (!filterableFields?.[filterableField]) {
@@ -1,10 +1,10 @@
import { MedusaContainer } from "@medusajs/framework/types" import { MedusaContainer } from "@medusajs/types"
import { import {
ContainerRegistrationKeys,
isString, isString,
ContainerRegistrationKeys,
remoteQueryObjectFromString, remoteQueryObjectFromString,
} from "@medusajs/framework/utils" } from "@medusajs/utils"
import { MedusaRequest } from "../../types/routing" import { MedusaRequest } from "../types"
export const refetchEntities = async ( export const refetchEntities = async (
entryPoint: string, entryPoint: string,
@@ -0,0 +1,22 @@
import {
MedusaNextFunction,
MedusaRequest,
MedusaResponse,
MiddlewareFunction,
} from "../types"
/**
* Due to how our route loader works, where we load all middlewares before routes, ambiguous routes * end up having all middlewares on different routes executed before the route handler is.
*/
/**
* This function allows us to skip middlewares for particular routes, so we can temporarily solve * * this without completely breaking the route loader for everyone.
*/
export const unlessPath =
(onPath: RegExp, middleware: MiddlewareFunction) =>
(req: MedusaRequest, res: MedusaResponse, next: MedusaNextFunction) => {
if (onPath.test(req.path)) {
return next()
} else {
return middleware(req, res, next)
}
}
@@ -1,7 +1,7 @@
import { NextFunction } from "express"
import { z } from "zod" import { z } from "zod"
import { MedusaRequest, MedusaResponse } from "../../types/routing" import { NextFunction } from "express"
import { zodValidator } from "./zod-helper" import { MedusaRequest, MedusaResponse } from "../types"
import { zodValidator } from "../../zod/zod-helpers"
export function validateAndTransformBody( export function validateAndTransformBody(
zodSchema: zodSchema:
@@ -1,19 +1,12 @@
import {
BaseEntity,
QueryConfig,
RequestQueryFields,
} from "@medusajs/framework/types"
import { NextFunction } from "express"
import { omit } from "lodash"
import { z } from "zod" import { z } from "zod"
import { MedusaRequest, MedusaResponse } from "../../types/routing" import { omit } from "lodash"
import { removeUndefinedProperties } from "../../utils" import { NextFunction } from "express"
import { import { removeUndefinedProperties, MedusaError } from "@medusajs/utils"
prepareListQuery, import { BaseEntity, QueryConfig, RequestQueryFields } from "@medusajs/types"
prepareRetrieveQuery,
} from "../../utils/get-query-config" import { zodValidator } from "../../zod/zod-helpers"
import { zodValidator } from "./zod-helper" import { MedusaRequest, MedusaResponse } from "../types"
import { MedusaError } from "@medusajs/framework/utils" import { prepareListQuery, prepareRetrieveQuery } from "./get-query-config"
/** /**
* Normalize an input query, especially from array like query params to an array type * Normalize an input query, especially from array like query params to an array type
+1
View File
@@ -10,6 +10,7 @@ export * from "./medusa-app-loader"
export * from "./subscribers" export * from "./subscribers"
export * from "./workflows" export * from "./workflows"
export * from "./telemetry" export * from "./telemetry"
export * from "./zod"
export const MEDUSA_CLI_PATH = require.resolve("@medusajs/medusa-cli") export const MEDUSA_CLI_PATH = require.resolve("@medusajs/medusa-cli")
+1 -1
View File
@@ -1 +1 @@
export * from './job-loader' export * from "./job-loader"
@@ -33,6 +33,7 @@ import {
container as mainContainer, container as mainContainer,
MedusaContainer, MedusaContainer,
} from "./container" } from "./container"
import type { Knex } from "@mikro-orm/knex"
export class MedusaAppLoader { export class MedusaAppLoader {
/** /**
@@ -106,9 +107,9 @@ export class MedusaAppLoader {
protected prepareSharedResourcesAndDeps() { protected prepareSharedResourcesAndDeps() {
const injectedDependencies = { const injectedDependencies = {
[ContainerRegistrationKeys.PG_CONNECTION]: this.#container.resolve( [ContainerRegistrationKeys.PG_CONNECTION]: this.#container.resolve<
ContainerRegistrationKeys.PG_CONNECTION Knex<any>
), >(ContainerRegistrationKeys.PG_CONNECTION),
[ContainerRegistrationKeys.LOGGER]: this.#container.resolve( [ContainerRegistrationKeys.LOGGER]: this.#container.resolve(
ContainerRegistrationKeys.LOGGER ContainerRegistrationKeys.LOGGER
), ),
@@ -1,11 +1,11 @@
/** /**
* Custom wrapper on top of MikroORM CLI to override the issue * Custom wrapper on top of MikroORM CLI to override the issue
* they have when importing TypeScript files. * they have when importing TypeScript files.
* *
* They have hardcoded the module system of TypeScript to CommonJS * They have hardcoded the module system of TypeScript to CommonJS
* and that makes it impossible to use any other module system * and that makes it impossible to use any other module system
* like Node16 or NodeNext and so on. * like Node16 or NodeNext and so on.
* *
* With this wrapper, we monkey patch the code responsible for register * With this wrapper, we monkey patch the code responsible for register
* ts-node and then boot their CLI. Since, the code footprint is * ts-node and then boot their CLI. Since, the code footprint is
* small, we should be okay with managing this wrapper. * small, we should be okay with managing this wrapper.
@@ -51,7 +51,6 @@ require("@jercle/yargonaut")
.style("yellow", "required") .style("yellow", "required")
.helpStyle("green") .helpStyle("green")
.errorsStyle("red") .errorsStyle("red")
;(async () => { ;(async () => {
const argv = await CLIConfigurator.configure() const argv = await CLIConfigurator.configure()
const args = await argv.parse(process.argv.slice(2)) const args = await argv.parse(process.argv.slice(2))
@@ -1 +1 @@
export * from "@medusajs/workflows-sdk/composer" export * from "@medusajs/workflows-sdk/composer"
+1
View File
@@ -0,0 +1 @@
export * from "./zod-helpers"
+4 -1
View File
@@ -1,3 +1,6 @@
{ {
"extends": "../../../_tsconfig.base.json" "extends": "../../../_tsconfig.base.json",
"compilerOptions": {
"rootDir": "./src"
}
} }
+7 -4
View File
@@ -59,9 +59,12 @@ export class Upload {
} }
async delete(id: string, headers?: ClientHeaders) { async delete(id: string, headers?: ClientHeaders) {
return this.client.fetch<HttpTypes.AdminFileDeleteResponse>(`/admin/uploads/${id}`, { return this.client.fetch<HttpTypes.AdminFileDeleteResponse>(
method: "DELETE", `/admin/uploads/${id}`,
headers, {
}) method: "DELETE",
headers,
}
)
} }
} }
+14 -12
View File
@@ -204,12 +204,13 @@ export class Store {
lineItemId: string, lineItemId: string,
headers?: ClientHeaders headers?: ClientHeaders
) => { ) => {
return this.client.fetch< return this.client.fetch<HttpTypes.StoreLineItemDeleteResponse>(
HttpTypes.StoreLineItemDeleteResponse `/store/carts/${cartId}/line-items/${lineItemId}`,
>(`/store/carts/${cartId}/line-items/${lineItemId}`, { {
method: "DELETE", method: "DELETE",
headers, headers,
}) }
)
}, },
addShippingMethod: async ( addShippingMethod: async (
cartId: string, cartId: string,
@@ -432,12 +433,13 @@ export class Store {
) )
}, },
deleteAddress: async (addressId: string, headers?: ClientHeaders) => { deleteAddress: async (addressId: string, headers?: ClientHeaders) => {
return this.client.fetch< return this.client.fetch<HttpTypes.StoreCustomerAddressDeleteResponse>(
HttpTypes.StoreCustomerAddressDeleteResponse `/store/customers/me/addresses/${addressId}`,
>(`/store/customers/me/addresses/${addressId}`, { {
method: "DELETE", method: "DELETE",
headers, headers,
}) }
)
}, },
} }
} }
@@ -1,4 +1,3 @@
export * from "./module-loader" export * from "./module-loader"
export * from "./module-provider-loader" export * from "./module-provider-loader"
export * from "./register-modules" export * from "./register-modules"
+1 -1
View File
@@ -1,7 +1,7 @@
import { import {
AuthIdentityDTO,
AuthenticationInput, AuthenticationInput,
AuthenticationResponse, AuthenticationResponse,
AuthIdentityDTO,
} from "./common" } from "./common"
// This interface currently won't allow for linking multiple providers to a single auth entity. That flow is more complex and not supported yet. // This interface currently won't allow for linking multiple providers to a single auth entity. That flow is more complex and not supported yet.
+1 -1
View File
@@ -2,9 +2,9 @@ import { FindConfig } from "../common"
import { IModuleService } from "../modules-sdk" import { IModuleService } from "../modules-sdk"
import { Context } from "../shared-context" import { Context } from "../shared-context"
import { import {
AuthIdentityDTO,
AuthenticationInput, AuthenticationInput,
AuthenticationResponse, AuthenticationResponse,
AuthIdentityDTO,
CreateAuthIdentityDTO, CreateAuthIdentityDTO,
CreateProviderIdentityDTO, CreateProviderIdentityDTO,
FilterableAuthIdentityProps, FilterableAuthIdentityProps,
+1 -1
View File
@@ -32,8 +32,8 @@ import {
CreateShippingMethodForSingleCartDTO, CreateShippingMethodForSingleCartDTO,
CreateShippingMethodTaxLineDTO, CreateShippingMethodTaxLineDTO,
UpdateAddressDTO, UpdateAddressDTO,
UpdateCartDTO,
UpdateCartDataDTO, UpdateCartDataDTO,
UpdateCartDTO,
UpdateLineItemDTO, UpdateLineItemDTO,
UpdateLineItemTaxLineDTO, UpdateLineItemTaxLineDTO,
UpdateLineItemWithSelectorDTO, UpdateLineItemWithSelectorDTO,
+24 -2
View File
@@ -306,9 +306,31 @@ export type RawRounding = {
/** /**
* @ignore * @ignore
*/ */
export type QueryConfig<TEntity extends BaseEntity> = { export type QueryConfig<TEntity> = {
/**
* Default fields and relations to return
*/
defaults?: (keyof TEntity | string)[] defaults?: (keyof TEntity | string)[]
allowed?: (keyof TEntity | string)[] /**
* @deprecated Use `defaults` instead
*/
defaultFields?: (keyof TEntity | string)[]
/**
* @deprecated Use `defaultFields` instead and the relations will be inferred
*/
defaultRelations?: string[]
/**
* Fields and relations that are allowed to be requested
*/
allowed?: string[]
/**
* @deprecated Use `allowed` instead
*/
allowedFields?: string[]
/**
* @deprecated Use `allowedFields` instead and the relations will be inferred
*/
allowedRelations?: string[]
defaultLimit?: number defaultLimit?: number
isList?: boolean isList?: boolean
} }
+1 -1
View File
@@ -3,4 +3,4 @@ import { MedusaContainer } from "./medusa-container"
export type ExecArgs = { export type ExecArgs = {
container: MedusaContainer container: MedusaContainer
args: string[] args: string[]
} }
@@ -2,7 +2,7 @@ import stream from "stream"
/** /**
* @interface * @interface
* *
* Details of a file upload's result. * Details of a file upload's result.
*/ */
export type FileServiceUploadResult = { export type FileServiceUploadResult = {
@@ -19,7 +19,7 @@ export type FileServiceUploadResult = {
/** /**
* @interface * @interface
* *
* The relevant details to upload a file through a stream. * The relevant details to upload a file through a stream.
*/ */
export type FileServiceGetUploadStreamResult = { export type FileServiceGetUploadStreamResult = {
@@ -44,7 +44,7 @@ export type FileServiceGetUploadStreamResult = {
/** /**
* @interface * @interface
* *
* The details of a file to retrieve. * The details of a file to retrieve.
*/ */
export type GetUploadedFileType = { export type GetUploadedFileType = {
@@ -61,7 +61,7 @@ export type GetUploadedFileType = {
/** /**
* @interface * @interface
* *
* The details of the file to remove. * The details of the file to remove.
*/ */
export type DeleteFileType = { export type DeleteFileType = {
@@ -75,7 +75,7 @@ export type DeleteFileType = {
/** /**
* @interface * @interface
* *
* The details of the file being uploaded through a stream. * The details of the file being uploaded through a stream.
*/ */
export type UploadStreamDescriptorType = { export type UploadStreamDescriptorType = {
@@ -1,7 +1,7 @@
export type FulfillmentOption = { export type FulfillmentOption = {
/** /**
* The option's ID. * The option's ID.
* *
* @example express * @example express
*/ */
id: string id: string
@@ -22,4 +22,4 @@ export type AdminApiKeyListResponse = PaginatedResponse<{
api_keys: AdminApiKey[] api_keys: AdminApiKey[]
}> }>
export type AdminApiKeyDeleteResponse = DeleteResponse<"api_key"> export type AdminApiKeyDeleteResponse = DeleteResponse<"api_key">
@@ -1,4 +1,3 @@
export * from "./payloads" export * from "./payloads"
export * from "./queries" export * from "./queries"
export * from "./responses" export * from "./responses"
@@ -26,4 +26,4 @@ export interface AdminCampaignResponse {
campaign: AdminCampaign campaign: AdminCampaign
} }
export type AdminCampaignDeleteResponse = DeleteResponse<"campaign"> export type AdminCampaignDeleteResponse = DeleteResponse<"campaign">
@@ -20,7 +20,8 @@ export interface StoreCart extends Omit<BaseCart, "items"> {
payment_collection?: StorePaymentCollection payment_collection?: StorePaymentCollection
region?: StoreRegion region?: StoreRegion
} }
export interface StoreCartLineItem extends Omit<BaseCartLineItem, "product" | "variant" | "cart"> { export interface StoreCartLineItem
extends Omit<BaseCartLineItem, "product" | "variant" | "cart"> {
product?: StoreProduct product?: StoreProduct
variant?: StoreProductVariant variant?: StoreProductVariant
cart: StoreCart cart: StoreCart
@@ -39,4 +40,4 @@ export interface StoreCartShippingMethod extends BaseCartShippingMethod {
adjustments?: (BaseShippingMethodAdjustment & { adjustments?: (BaseShippingMethodAdjustment & {
shipping_method: StoreCartShippingMethod shipping_method: StoreCartShippingMethod
})[] })[]
} }
@@ -1,3 +1,3 @@
export * from "./entities" export * from "./entities"
export * from "./payloads" export * from "./payloads"
export * from "./responses" export * from "./responses"
@@ -94,4 +94,4 @@ export interface StoreAddAddress {
* Holds custom data in key-value pairs. * Holds custom data in key-value pairs.
*/ */
metadata?: Record<string, unknown> | null metadata?: Record<string, unknown> | null
} }
@@ -6,17 +6,22 @@ export interface StoreCartResponse {
cart: StoreCart cart: StoreCart
} }
export type StoreCompleteCartResponse = { export type StoreCompleteCartResponse =
type: "cart" | {
cart: StoreCart type: "cart"
error: { cart: StoreCart
message: string error: {
name: string message: string
type: string name: string
} type: string
} | { }
type: "order" }
order: StoreOrder | {
} type: "order"
order: StoreOrder
}
export type StoreLineItemDeleteResponse = DeleteResponseWithParent<"line-item", StoreCart> export type StoreLineItemDeleteResponse = DeleteResponseWithParent<
"line-item",
StoreCart
>
@@ -1,3 +1,3 @@
export * from "./entities" export * from "./entities"
export * from "./queries" export * from "./queries"
export * from "./responses" export * from "./responses"
@@ -1,6 +1,7 @@
import { OperatorMap } from "../../../dal"; import { OperatorMap } from "../../../dal"
import { BaseCollectionListParams } from "../common"; import { BaseCollectionListParams } from "../common"
export interface StoreCollectionFilters extends Omit<BaseCollectionListParams, "id"> { export interface StoreCollectionFilters
extends Omit<BaseCollectionListParams, "id"> {
deleted_at?: OperatorMap<string> deleted_at?: OperatorMap<string>
} }
@@ -15,14 +15,15 @@ export type DeleteResponse<TObject extends string> = {
deleted: boolean deleted: boolean
} }
export type DeleteResponseWithParent<TObject extends string, TParent = {}> = export type DeleteResponseWithParent<
DeleteResponse<TObject> & TObject extends string,
{ TParent = {}
/** > = DeleteResponse<TObject> & {
* The parent resource of the item that was deleted, if applicable. /**
*/ * The parent resource of the item that was deleted, if applicable.
parent?: TParent */
} parent?: TParent
}
export type PaginatedResponse<T> = { export type PaginatedResponse<T> = {
limit: number limit: number
@@ -38,4 +39,4 @@ export type BatchResponse<T> = {
object: string object: string
deleted: boolean deleted: boolean
} }
} }
@@ -1,3 +1,3 @@
export * from "./admin" export * from "./admin"
export * from "./common" export * from "./common"
export * from "./store" export * from "./store"
@@ -1,3 +1,3 @@
import { BaseCurrency } from "../common"; import { BaseCurrency } from "../common"
export interface StoreCurrency extends BaseCurrency {} export interface StoreCurrency extends BaseCurrency {}
@@ -1,3 +1,3 @@
export * from "./entities" export * from "./entities"
export * from "./queries" export * from "./queries"
export * from "./responses" export * from "./responses"
@@ -1,8 +1,9 @@
import { BaseFilterable } from "../../../dal"; import { BaseFilterable } from "../../../dal"
import { FindParams } from "../../common"; import { FindParams } from "../../common"
export interface StoreGetCurrencyListParams extends export interface StoreGetCurrencyListParams
FindParams, BaseFilterable<StoreGetCurrencyListParams> { extends FindParams,
q?: string BaseFilterable<StoreGetCurrencyListParams> {
code?: string | string[] q?: string
} code?: string | string[]
}
@@ -1,5 +1,5 @@
import { PaginatedResponse } from "../../common"; import { PaginatedResponse } from "../../common"
import { StoreCurrency } from "./entities"; import { StoreCurrency } from "./entities"
export interface StoreCurrencyResponse { export interface StoreCurrencyResponse {
currency: StoreCurrency currency: StoreCurrency
@@ -1,4 +1,4 @@
export * from "./entities" export * from "./entities"
export * from "./payloads" export * from "./payloads"
export * from "./queries" export * from "./queries"
export * from "./responses" export * from "./responses"
@@ -1,2 +1 @@
export * from "./admin"; export * from "./admin"
@@ -1,4 +1,4 @@
export * from "./entities" export * from "./entities"
export * from "./payloads" export * from "./payloads"
export * from "./queries" export * from "./queries"
export * from "./responses" export * from "./responses"
@@ -1,4 +1,8 @@
import { DeleteResponse, DeleteResponseWithParent, PaginatedResponse } from "../../common" import {
DeleteResponse,
DeleteResponseWithParent,
PaginatedResponse,
} from "../../common"
import { AdminCustomer, AdminCustomerAddress } from "./entities" import { AdminCustomer, AdminCustomerAddress } from "./entities"
export interface AdminCustomerResponse { export interface AdminCustomerResponse {
@@ -1,9 +1,6 @@
import { import { BaseCustomer, BaseCustomerAddress } from "../common"
BaseCustomer,
BaseCustomerAddress,
} from "../common"
export interface StoreCustomer extends Omit<BaseCustomer, "created_by"> { export interface StoreCustomer extends Omit<BaseCustomer, "created_by"> {
addresses: StoreCustomerAddress[] addresses: StoreCustomerAddress[]
} }
export interface StoreCustomerAddress extends BaseCustomerAddress {} export interface StoreCustomerAddress extends BaseCustomerAddress {}
@@ -1,4 +1,4 @@
export * from "./entities" export * from "./entities"
export * from "./payloads" export * from "./payloads"
export * from "./queries" export * from "./queries"
export * from "./responses" export * from "./responses"
@@ -1,8 +1,5 @@
import { import { BaseCustomerAddressFilters, BaseCustomerFilters } from "../common"
BaseCustomerAddressFilters,
BaseCustomerFilters,
} from "../common"
export interface StoreCustomerFilters extends BaseCustomerFilters {} export interface StoreCustomerFilters extends BaseCustomerFilters {}
export interface StoreCustomerAddressFilters export interface StoreCustomerAddressFilters
extends BaseCustomerAddressFilters {} extends BaseCustomerAddressFilters {}
@@ -1,5 +1,5 @@
import { DeleteResponseWithParent, PaginatedResponse } from "../../common"; import { DeleteResponseWithParent, PaginatedResponse } from "../../common"
import { StoreCustomer, StoreCustomerAddress } from "./entities"; import { StoreCustomer, StoreCustomerAddress } from "./entities"
export interface StoreCustomerResponse { export interface StoreCustomerResponse {
customer: StoreCustomer customer: StoreCustomer
@@ -12,4 +12,7 @@ export interface StoreCustomerAddressResponse {
export interface StoreCustomerAddressListResponse export interface StoreCustomerAddressListResponse
extends PaginatedResponse<{ addresses: StoreCustomerAddress[] }> {} extends PaginatedResponse<{ addresses: StoreCustomerAddress[] }> {}
export type StoreCustomerAddressDeleteResponse = DeleteResponseWithParent<"address", StoreCustomer> export type StoreCustomerAddressDeleteResponse = DeleteResponseWithParent<
"address",
StoreCustomer
>
@@ -1,3 +1,3 @@
import { BaseExchange } from "../common"; import { BaseExchange } from "../common"
export interface AdminExchange extends BaseExchange {} export interface AdminExchange extends BaseExchange {}
@@ -1,6 +1,10 @@
import { OperatorMap } from "../../dal" import { OperatorMap } from "../../dal"
import { FindParams } from "../common" import { FindParams } from "../common"
import { BaseOrder, BaseOrderShippingMethod, BaseOrderTransaction } from "../order/common" import {
BaseOrder,
BaseOrderShippingMethod,
BaseOrderTransaction,
} from "../order/common"
import { AdminReturn, AdminReturnItem } from "../return" import { AdminReturn, AdminReturnItem } from "../return"
export interface BaseExchangeItem { export interface BaseExchangeItem {
@@ -1 +1 @@
export * from "./admin" export * from "./admin"
@@ -1,3 +1,3 @@
import { BaseFile } from "../common" import { BaseFile } from "../common"
export interface AdminFile extends BaseFile {} export interface AdminFile extends BaseFile {}
@@ -1,3 +1,3 @@
export * from "./entities" export * from "./entities"
export * from "./payloads" export * from "./payloads"
export * from "./responses" export * from "./responses"
@@ -1,3 +1,3 @@
import { BaseUploadFile } from "../common"; import { BaseUploadFile } from "../common"
export type AdminUploadFile = BaseUploadFile export type AdminUploadFile = BaseUploadFile
@@ -1,5 +1,5 @@
import { DeleteResponse } from "../../common"; import { DeleteResponse } from "../../common"
import { AdminFile } from "./entities"; import { AdminFile } from "./entities"
export interface AdminFileResponse { export interface AdminFileResponse {
file: AdminFile file: AdminFile
@@ -9,4 +9,4 @@ export interface AdminFileListResponse {
files: AdminFile[] files: AdminFile[]
} }
export type AdminFileDeleteResponse = DeleteResponse<"file"> export type AdminFileDeleteResponse = DeleteResponse<"file">
@@ -1,3 +1,3 @@
import { BaseFulfillmentProvider } from "../common"; import { BaseFulfillmentProvider } from "../common"
export interface AdminFulfillmentProvider extends BaseFulfillmentProvider {} export interface AdminFulfillmentProvider extends BaseFulfillmentProvider {}
@@ -1,4 +1,4 @@
export interface BaseFulfillmentProvider { export interface BaseFulfillmentProvider {
id: string id: string
is_enabled: boolean is_enabled: boolean
} }
Loaded 100 of 557 files, more files were not shown because too many files have changed in this diff. Show more