chore: fix yarn.lock conflicts

This commit is contained in:
olivermrbl committed 2022-07-05 10:17:09 +02:00
commit 915359d84b
400 files changed
+16918 -15217

No files matched your search

+11
View File
@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.3.1](https://github.com/medusajs/medusa/compare/@medusajs/medusa-cli@1.3.0...@medusajs/medusa-cli@1.3.1) (2022-07-05)
### Features
* **medusa-cli:** Allow to revert migrations from the CLI ([#1353](https://github.com/medusajs/medusa/issues/1353)) ([012513b](https://github.com/medusajs/medusa/commit/012513b6a1e90169e9e0e53f7a59841a34fbaeb3))
# [1.3.0](https://github.com/medusajs/medusa/compare/@medusajs/medusa-cli@1.2.1...@medusajs/medusa-cli@1.3.0) (2022-05-01)
**Note:** Version bump only for package @medusajs/medusa-cli
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@medusajs/medusa-cli",
"version": "1.3.0",
"version": "1.3.1",
"description": "Command Line interface for Medusa Commerce",
"main": "dist/index.js",
"bin": {
+2 -2
View File
@@ -166,11 +166,11 @@ function buildLocalCommands(cli, isLocalProject) {
})
.command({
command: `migrations [action]`,
desc: `Migrate the database to the most recent version.`,
desc: `Manage migrations from the core and your own project`,
builder: {
action: {
demand: true,
choices: ["run", "show"],
choices: ["run", "revert", "show"],
},
},
handler: handlerP(
+16
View File
@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.0.26](https://github.com/medusajs/medusa/compare/medusa-dev-cli@0.0.24...medusa-dev-cli@0.0.26) (2022-07-05)
**Note:** Version bump only for package medusa-dev-cli
## [0.0.25](https://github.com/medusajs/medusa/compare/medusa-dev-cli@0.0.24...medusa-dev-cli@0.0.25) (2022-07-05)
**Note:** Version bump only for package medusa-dev-cli
## [0.0.24](https://github.com/medusajs/medusa/compare/medusa-dev-cli@0.0.23...medusa-dev-cli@0.0.24) (2021-12-08)
**Note:** Version bump only for package medusa-dev-cli
+5 -4
View File
@@ -1,7 +1,7 @@
{
"name": "medusa-dev-cli",
"description": "CLI helpers for contributors working on Medusa",
"version": "0.0.24",
"version": "0.0.26",
"author": "Sebastian Rindom <skrindom@gmail.com>",
"bin": {
"medusa-dev": "./dist/index.js"
@@ -16,6 +16,7 @@
"fs-extra": "^9.0.1",
"got": "^11.8.5",
"is-absolute": "^1.0.0",
"jest": "^25.5.2",
"lodash": "^4.17.21",
"signal-exit": "^3.0.3",
"verdaccio": "^4.10.0",
@@ -39,10 +40,10 @@
"directory": "packages/medusa-dev-cli"
},
"scripts": {
"build": "babel src --out-dir dist --ignore \"**/__tests__\"",
"prepare": "cross-env NODE_ENV=production npm run build",
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "babel -w src --out-dir dist --ignore \"**/__tests__\""
"build": "babel src --out-dir dist",
"test": "jest",
"watch": "babel -w src --out-dir dist"
},
"engines": {
"node": ">=12.13.0"
+64 -43
View File
@@ -1,12 +1,12 @@
#!/usr/bin/env node
const Configstore = require(`configstore`);
const pkg = require(`../package.json`);
const _ = require(`lodash`);
const path = require(`path`);
const os = require(`os`);
const watch = require(`./watch`);
const { getVersionInfo } = require(`./utils/version`);
const Configstore = require(`configstore`)
const pkg = require(`../package.json`)
const _ = require(`lodash`)
const path = require(`path`)
const os = require(`os`)
const watch = require(`./watch`)
const { getVersionInfo } = require(`./utils/version`)
const argv = require(`yargs`)
.usage(`Usage: medusa-dev [options]`)
.alias(`q`, `quiet`)
@@ -19,7 +19,7 @@ const argv = require(`yargs`)
.nargs(`p`, 1)
.describe(
`p`,
`Set path to Medusa repository.
`Set path to medusa repository.
You typically only need to configure this once.`
)
.nargs(`force-install`, 0)
@@ -27,6 +27,11 @@ You typically only need to configure this once.`
`force-install`,
`Disables copying files into node_modules and forces usage of local npm repository.`
)
.nargs(`external-registry`, 0)
.describe(
`external-registry`,
`Run 'yarn add' commands without the --registry flag.`
)
.alias(`C`, `copy-all`)
.nargs(`C`, 0)
.describe(
@@ -39,87 +44,101 @@ You typically only need to configure this once.`
.alias(`h`, `help`)
.nargs(`v`, 0)
.alias(`v`, `version`)
.describe(`v`, `Print the currently installed version of Medusa Dev CLI`)
.argv;
.describe(`v`, `Print the currently installed version of Medusa Dev CLI`).argv
if (argv.version) {
console.log(getVersionInfo());
process.exit();
console.log(getVersionInfo())
process.exit()
}
const conf = new Configstore(pkg.name);
const conf = new Configstore(pkg.name)
const fs = require(`fs-extra`);
const fs = require(`fs-extra`)
let pathToRepo = argv.setPathToRepo;
let pathToRepo = argv.setPathToRepo
if (pathToRepo) {
if (pathToRepo.includes(`~`)) {
pathToRepo = path.join(os.homedir(), pathToRepo.split(`~`).pop());
pathToRepo = path.join(os.homedir(), pathToRepo.split(`~`).pop())
}
conf.set(`medusa-location`, path.resolve(pathToRepo));
process.exit();
conf.set(`medusa-location`, path.resolve(pathToRepo))
process.exit()
}
const havePackageJsonFile = fs.existsSync(`package.json`);
const havePackageJsonFile = fs.existsSync(`package.json`)
if (!havePackageJsonFile) {
console.error(`Current folder must have a package.json file!`);
process.exit();
console.error(`Current folder must have a package.json file!`)
process.exit()
}
const medusaLocation = conf.get(`medusa-location`);
const medusaLocation = conf.get(`medusa-location`)
if (!medusaLocation) {
console.error(
`
You haven't set the path yet to your cloned
version of medusa. Do so now by running:
medusa-dev --set-path-to-repo /path/to/my/cloned/version/medusa
`
);
process.exit();
)
process.exit()
}
// get list of packages from monorepo
const monoRepoPackages = [];
const packageNameToPath = new Map()
const monoRepoPackages = fs
.readdirSync(path.join(medusaLocation, `packages`))
.map((dirName) => {
try {
const localPkg = JSON.parse(
fs.readFileSync(
path.join(medusaLocation, `packages`, dirName, `package.json`)
)
)
const pkgsDirs = fs.readdirSync(path.join(medusaLocation, `packages`));
for (const dir of pkgsDirs) {
const pack = JSON.parse(
fs.readFileSync(path.join(medusaLocation, `packages`, dir, `package.json`))
);
monoRepoPackages.push(pack.name);
}
if (localPkg?.name) {
packageNameToPath.set(
localPkg.name,
path.join(medusaLocation, `packages`, dirName)
)
return localPkg.name
}
} catch (error) {
// fallback to generic one
}
const localPkg = JSON.parse(fs.readFileSync(`package.json`));
packageNameToPath.set(
dirName,
path.join(medusaLocation, `packages`, dirName)
)
return dirName
})
const localPkg = JSON.parse(fs.readFileSync(`package.json`))
// intersect dependencies with monoRepoPackages to get list of packages that are used
const localPackages = _.intersection(
monoRepoPackages,
Object.keys(_.merge({}, localPkg.dependencies, localPkg.devDependencies))
);
)
if (!argv.packages && _.isEmpty(localPackages)) {
console.error(
`
You haven't got any medusa dependencies into your current package.json
You probably want to pass in a list of packages to start
developing on! For example:
medusa-dev --packages @medusajs/medusa
medusa-dev --packages medusa medusa-js
If you prefer to place them in your package.json dependencies instead,
medusa-dev will pick them up.
`
);
)
if (!argv.forceInstall) {
process.exit();
process.exit()
} else {
console.log(
`Continuing other dependencies installation due to "--forceInstall" flag`
);
)
}
}
@@ -129,4 +148,6 @@ watch(medusaLocation, argv.packages, {
scanOnce: argv.scanOnce,
forceInstall: argv.forceInstall,
monoRepoPackages,
});
packageNameToPath,
externalRegistry: argv.externalRegistry,
})
@@ -1,23 +1,23 @@
const startVerdaccio = require(`verdaccio`).default;
const startVerdaccio = require(`verdaccio`).default
const fs = require(`fs-extra`);
const _ = require(`lodash`);
const fs = require(`fs-extra`)
const _ = require(`lodash`)
let VerdaccioInitPromise = null;
let VerdaccioInitPromise = null
const { verdaccioConfig } = require(`./verdaccio-config`);
const { publishPackage } = require(`./publish-package`);
const { installPackages } = require(`./install-packages`);
const { verdaccioConfig } = require(`./verdaccio-config`)
const { publishPackage } = require(`./publish-package`)
const { installPackages } = require(`./install-packages`)
const startServer = () => {
if (VerdaccioInitPromise) {
return VerdaccioInitPromise;
return VerdaccioInitPromise
}
console.log(`Starting local verdaccio server`);
console.log(`Starting local verdaccio server`)
// clear storage
fs.removeSync(verdaccioConfig.storage);
fs.removeSync(verdaccioConfig.storage)
VerdaccioInitPromise = new Promise((resolve) => {
startVerdaccio(
@@ -29,47 +29,49 @@ const startServer = () => {
(webServer, addr, pkgName, pkgVersion) => {
// console.log(webServer)
webServer.listen(addr.port || addr.path, addr.host, () => {
console.log(`Started local verdaccio server`);
console.log(`Started local verdaccio server`)
resolve();
});
resolve()
})
}
);
});
)
})
return VerdaccioInitPromise;
};
return VerdaccioInitPromise
}
exports.startVerdaccio = startServer;
exports.startVerdaccio = startServer
exports.publishPackagesLocallyAndInstall = async ({
packagesToPublish,
localPackages,
root,
packageNameToPath,
ignorePackageJSONChanges,
yarnWorkspaceRoot,
externalRegistry,
}) => {
await startServer();
await startServer()
const versionPostFix = Date.now();
const versionPostFix = Date.now()
const newlyPublishedPackageVersions = {};
const newlyPublishedPackageVersions = {}
for (const packageName of packagesToPublish) {
newlyPublishedPackageVersions[packageName] = await publishPackage({
packageName,
packagesToPublish,
root,
packageNameToPath,
versionPostFix,
ignorePackageJSONChanges,
});
})
}
const packagesToInstall = _.intersection(packagesToPublish, localPackages);
const packagesToInstall = _.intersection(packagesToPublish, localPackages)
await installPackages({
packagesToInstall,
yarnWorkspaceRoot,
newlyPublishedPackageVersions,
});
};
externalRegistry,
})
}
@@ -8,10 +8,11 @@ const installPackages = async ({
packagesToInstall,
yarnWorkspaceRoot,
newlyPublishedPackageVersions,
externalRegistry,
}) => {
console.log(
`Installing packages from local registry:\n${packagesToInstall
.map(packageAndVersion => ` - ${packageAndVersion}`)
.map((packageAndVersion) => ` - ${packageAndVersion}`)
.join(`\n`)}`
)
let installCmd
@@ -80,22 +81,22 @@ const installPackages = async ({
process.exit(1)
}
const handleDeps = deps => {
const handleDeps = (deps) => {
if (!deps) {
return false
}
let changed = false
Object.keys(deps).forEach(depName => {
Object.keys(deps).forEach((depName) => {
if (packagesToInstall.includes(depName)) {
deps[depName] = `gatsby-dev`
deps[depName] = `medusa-dev`
changed = true
}
})
return changed
}
Object.keys(workspacesLayout).forEach(workspaceName => {
Object.keys(workspacesLayout).forEach((workspaceName) => {
const { location } = workspacesLayout[workspaceName]
const pkgJsonPath = path.join(yarnWorkspaceRoot, location, `package.json`)
if (!fs.existsSync(pkgJsonPath)) {
@@ -109,7 +110,7 @@ const installPackages = async ({
changed |= handleDeps(pkg.peerDependencies)
if (changed) {
console.log(`Changing deps in ${pkgJsonPath} to use @gatsby-dev`)
console.log(`Changing deps in ${pkgJsonPath} to use @medusa-dev`)
fs.outputJSONSync(pkgJsonPath, pkg, {
spaces: 2,
})
@@ -118,24 +119,28 @@ const installPackages = async ({
// package.json files are changed - so we just want to install
// using verdaccio registry
installCmd = [
`yarn`,
[`install`, `--registry=${registryUrl}`, `--ignore-engines`],
]
const yarnCommands = [`install`]
if (!externalRegistry) {
yarnCommands.push(`--registry=${registryUrl}`)
}
installCmd = [`yarn`, yarnCommands]
} else {
installCmd = [
`yarn`,
[
`add`,
...packagesToInstall.map(packageName => {
const packageVersion = newlyPublishedPackageVersions[packageName]
return `${packageName}@${packageVersion}`
}),
`--registry=${registryUrl}`,
`--exact`,
`--ignore-engines`,
],
const yarnCommands = [
`add`,
...packagesToInstall.map((packageName) => {
const packageVersion = newlyPublishedPackageVersions[packageName]
return `${packageName}@${packageVersion}`
}),
`--exact`,
]
if (!externalRegistry) {
yarnCommands.push(`--registry=${registryUrl}`)
}
installCmd = [`yarn`, yarnCommands]
}
try {
@@ -1,18 +1,18 @@
const fs = require(`fs-extra`);
const path = require(`path`);
const fs = require(`fs-extra`)
const path = require(`path`)
const { promisifiedSpawn } = require(`../utils/promisified-spawn`);
const { registryUrl } = require(`./verdaccio-config`);
const { promisifiedSpawn } = require(`../utils/promisified-spawn`)
const { registryUrl } = require(`./verdaccio-config`)
const NPMRCContent = `${registryUrl.replace(
/https?:/g,
``
)}/:_authToken="medusa-dev"`;
)}/:_authToken="medusa-dev"`
const {
getMonorepoPackageJsonPath,
} = require(`../utils/get-monorepo-package-json-path`);
const { registerCleanupTask } = require(`./cleanup-tasks`);
} = require(`../utils/get-monorepo-package-json-path`)
const { registerCleanupTask } = require(`./cleanup-tasks`)
/**
* Edit package.json to:
@@ -27,7 +27,7 @@ const adjustPackageJson = ({
versionPostFix,
packagesToPublish,
ignorePackageJSONChanges,
root,
packageNameToPath,
}) => {
// we need to check if package depend on any other package to will be published and
// adjust version selector to point to dev version of package so local registry is used
@@ -36,10 +36,10 @@ const adjustPackageJson = ({
const monorepoPKGjsonString = fs.readFileSync(
monoRepoPackageJsonPath,
`utf-8`
);
const monorepoPKGjson = JSON.parse(monorepoPKGjsonString);
)
const monorepoPKGjson = JSON.parse(monorepoPKGjsonString)
monorepoPKGjson.version = `${monorepoPKGjson.version}-dev-${versionPostFix}`;
monorepoPKGjson.version = `${monorepoPKGjson.version}-dev-${versionPostFix}`
packagesToPublish.forEach((packageThatWillBePublished) => {
if (
monorepoPKGjson.dependencies &&
@@ -49,37 +49,37 @@ const adjustPackageJson = ({
fs.readFileSync(
getMonorepoPackageJsonPath({
packageName: packageThatWillBePublished,
root,
packageNameToPath,
}),
`utf-8`
)
).version;
).version
monorepoPKGjson.dependencies[
packageThatWillBePublished
] = `${currentVersion}-dev-${versionPostFix}`;
] = `${currentVersion}-dev-${versionPostFix}`
}
});
})
const temporaryMonorepoPKGjsonString = JSON.stringify(monorepoPKGjson);
const temporaryMonorepoPKGjsonString = JSON.stringify(monorepoPKGjson)
const unignorePackageJSONChanges = ignorePackageJSONChanges(packageName, [
monorepoPKGjsonString,
temporaryMonorepoPKGjsonString,
]);
])
// change version and dependency versions
fs.outputFileSync(monoRepoPackageJsonPath, temporaryMonorepoPKGjsonString);
fs.outputFileSync(monoRepoPackageJsonPath, temporaryMonorepoPKGjsonString)
return {
newPackageVersion: monorepoPKGjson.version,
unadjustPackageJson: registerCleanupTask(() => {
// restore original package.json
fs.outputFileSync(monoRepoPackageJsonPath, monorepoPKGjsonString);
unignorePackageJSONChanges();
fs.outputFileSync(monoRepoPackageJsonPath, monorepoPKGjsonString)
unignorePackageJSONChanges()
}),
};
};
}
}
/**
* Anonymous publishing require dummy .npmrc
@@ -88,38 +88,38 @@ const adjustPackageJson = ({
* This is not verdaccio restriction.
*/
const createTemporaryNPMRC = ({ pathToPackage }) => {
const NPMRCPath = path.join(pathToPackage, `.npmrc`);
fs.outputFileSync(NPMRCPath, NPMRCContent);
const NPMRCPath = path.join(pathToPackage, `.npmrc`)
fs.outputFileSync(NPMRCPath, NPMRCContent)
return registerCleanupTask(() => {
fs.removeSync(NPMRCPath);
});
};
fs.removeSync(NPMRCPath)
})
}
const publishPackage = async ({
packageName,
packagesToPublish,
root,
versionPostFix,
ignorePackageJSONChanges,
packageNameToPath,
}) => {
const monoRepoPackageJsonPath = getMonorepoPackageJsonPath({
packageName,
root,
});
packageNameToPath,
})
const { unadjustPackageJson, newPackageVersion } = adjustPackageJson({
monoRepoPackageJsonPath,
packageName,
root,
packageNameToPath,
versionPostFix,
packagesToPublish,
ignorePackageJSONChanges,
});
})
const pathToPackage = path.dirname(monoRepoPackageJsonPath);
const pathToPackage = path.dirname(monoRepoPackageJsonPath)
const uncreateTemporaryNPMRC = createTemporaryNPMRC({ pathToPackage });
const uncreateTemporaryNPMRC = createTemporaryNPMRC({ pathToPackage })
// npm publish
const publishCmd = [
@@ -128,26 +128,26 @@ const publishPackage = async ({
{
cwd: pathToPackage,
},
];
]
console.log(
`Publishing ${packageName}@${newPackageVersion} to local registry`
);
)
try {
await promisifiedSpawn(publishCmd);
await promisifiedSpawn(publishCmd)
console.log(
`Published ${packageName}@${newPackageVersion} to local registry`
);
)
} catch (e) {
console.error(`Failed to publish ${packageName}@${newPackageVersion}`, e);
process.exit(1);
console.error(`Failed to publish ${packageName}@${newPackageVersion}`, e)
process.exit(1)
}
uncreateTemporaryNPMRC();
unadjustPackageJson();
uncreateTemporaryNPMRC()
unadjustPackageJson()
return newPackageVersion;
};
return newPackageVersion
}
exports.publishPackage = publishPackage;
exports.publishPackage = publishPackage
@@ -1,5 +1,15 @@
const { getDependantPackages } = require(`../get-dependant-packages`)
function createMockPackageNameToPath(packageNames) {
const packageNameToPath = new Map()
for (const packageName of packageNames) {
packageNameToPath.set(packageName, `/test/${packageName}`)
}
return packageNameToPath
}
describe(`getDependantPackages`, () => {
it(`handles deep dependency chains`, () => {
const packagesToPublish = getDependantPackages({
@@ -9,6 +19,13 @@ describe(`getDependantPackages`, () => {
"package-a-dep1-dep1": new Set([`package-a-dep1`]),
"not-related": new Set([`also-not-related`]),
},
packageNameToPath: createMockPackageNameToPath([
`package-a`,
`package-a-dep1`,
`package-a-dep1-dep1`,
`not-related`,
`also-not-related`,
]),
})
expect(packagesToPublish).toEqual(
@@ -23,6 +40,10 @@ describe(`getDependantPackages`, () => {
"package-a": new Set([`package-b`]),
"package-b": new Set([`package-a`]),
},
packageNameToPath: createMockPackageNameToPath([
`package-a`,
`package-b`,
]),
})
expect(packagesToPublish).toEqual(new Set([`package-a`, `package-b`]))
})
@@ -43,15 +43,25 @@ jest.doMock(
describe(`traversePackageDeps`, () => {
it(`handles deep dependency chains`, () => {
const monoRepoPackages = [
`package-a`,
`package-a-dep1`,
`package-a-dep1-dep1`,
`package-not-used`,
]
const packageNameToPath = new Map()
for (const packageName of monoRepoPackages) {
packageNameToPath.set(
packageName,
path.join(...`<monorepo-path>/packages/${packageName}`.split(`/`))
)
}
const { seenPackages, depTree } = traversePackagesDeps({
root: `<monorepo-path>`,
packages: [`package-a`, `doesnt-exist`],
monoRepoPackages: [
`package-a`,
`package-a-dep1`,
`package-a-dep1-dep1`,
`package-not-used`,
],
monoRepoPackages,
packageNameToPath,
})
expect(seenPackages).toEqual([
@@ -1,9 +1,9 @@
const fs = require(`fs-extra`);
const _ = require(`lodash`);
const fs = require(`fs-extra`)
const _ = require(`lodash`)
const {
getMonorepoPackageJsonPath,
} = require(`./get-monorepo-package-json-path`);
const got = require(`got`);
} = require(`./get-monorepo-package-json-path`)
const got = require(`got`)
function difference(object, base) {
function changes(object, base) {
@@ -12,11 +12,11 @@ function difference(object, base) {
result[key] =
_.isObject(value) && _.isObject(base[key])
? changes(value, base[key])
: value;
: value
}
});
})
}
return changes(object, base);
return changes(object, base)
}
/**
@@ -24,33 +24,33 @@ function difference(object, base) {
* It will skip dependencies that are removed in monorepo package.
*
* If local package is not installed, it will check unpkg.com.
* This allow medusa-dev to skip publishing unnecesairly and
* This allow gatsby-dev to skip publishing unnecesairly and
* let install packages from public npm repository if nothing changed.
*/
exports.checkDepsChanges = async ({
newPath,
packageName,
monoRepoPackages,
root,
isInitialScan,
ignoredPackageJSON,
packageNameToPath,
}) => {
let localPKGjson;
let packageNotInstalled = false;
let localPKGjson
let packageNotInstalled = false
try {
localPKGjson = JSON.parse(fs.readFileSync(newPath, `utf-8`));
localPKGjson = JSON.parse(fs.readFileSync(newPath, `utf-8`))
} catch {
packageNotInstalled = true;
packageNotInstalled = true
// there is no local package - so we still need to install deps
// this is nice because devs won't need to do initial package installation - we can handle this.
if (!isInitialScan) {
console.log(
`'${packageName}' doesn't seem to be installed. Restart medusa-dev to publish it`
);
`'${packageName}' doesn't seem to be installed. Restart gatsby-dev to publish it`
)
return {
didDepsChanged: false,
packageNotInstalled,
};
}
}
// if package is not installed, we will do http GET request to
@@ -60,37 +60,33 @@ exports.checkDepsChanges = async ({
// this allow us to not publish to local repository
// and save some time/work
try {
const response = await got(
`https://unpkg.com/${packageName}/package.json`
);
const version = getPackageVersion(packageName)
const url = `https://unpkg.com/${packageName}@${version}/package.json`
const response = await got(url)
if (response?.statusCode !== 200) {
throw new Error(`No response or non 200 code`);
throw new Error(`No response or non 200 code for ${url}`)
}
localPKGjson = JSON.parse(response.body);
} catch {
localPKGjson = JSON.parse(response.body)
} catch (e) {
console.log(
`'${packageName}' doesn't seem to be installed and is not published on NPM.`
);
`'${packageName}' doesn't seem to be installed and is not published on NPM. Error: ${e.message}`
)
return {
didDepsChanged: true,
packageNotInstalled,
};
}
}
}
const monoDir = packageName.startsWith("@medusajs")
? packageName.split("/")[1]
: packageName;
const monoRepoPackageJsonPath = getMonorepoPackageJsonPath({
packageName: monoDir,
root,
});
packageName,
packageNameToPath,
})
const monorepoPKGjsonString = fs.readFileSync(
monoRepoPackageJsonPath,
`utf-8`
);
const monorepoPKGjson = JSON.parse(monorepoPKGjsonString);
)
const monorepoPKGjson = JSON.parse(monorepoPKGjsonString)
if (ignoredPackageJSON.has(packageName)) {
if (ignoredPackageJSON.get(packageName).includes(monorepoPKGjsonString)) {
// we are in middle of publishing and content of package.json is one set during publish process,
@@ -98,44 +94,44 @@ exports.checkDepsChanges = async ({
return {
didDepsChanged: false,
packageNotInstalled,
};
}
}
}
if (!monorepoPKGjson.dependencies) monorepoPKGjson.dependencies = {};
if (!localPKGjson.dependencies) localPKGjson.dependencies = {};
if (!monorepoPKGjson.dependencies) monorepoPKGjson.dependencies = {}
if (!localPKGjson.dependencies) localPKGjson.dependencies = {}
const areDepsEqual = _.isEqual(
monorepoPKGjson.dependencies,
localPKGjson.dependencies
);
)
if (!areDepsEqual) {
const diff = difference(
monorepoPKGjson.dependencies,
localPKGjson.dependencies
);
)
const diff2 = difference(
localPKGjson.dependencies,
monorepoPKGjson.dependencies
);
)
let needPublishing = false;
let isPublishing = false;
let needPublishing = false
let isPublishing = false
const depChangeLog = _.uniq(Object.keys({ ...diff, ...diff2 }))
.reduce((acc, key) => {
if (monorepoPKGjson.dependencies[key] === `medusa-dev`) {
if (monorepoPKGjson.dependencies[key] === `gatsby-dev`) {
// if we are in middle of publishing to local repository - ignore
isPublishing = true;
return acc;
isPublishing = true
return acc
}
if (localPKGjson.dependencies[key] === `medusa-dev`) {
if (localPKGjson.dependencies[key] === `gatsby-dev`) {
// monorepo packages will restore version, but after installation
// in local site - it will use `medusa-dev` dist tag - we need
// in local site - it will use `gatsby-dev` dist tag - we need
// to ignore changes that
return acc;
return acc
}
if (
@@ -143,48 +139,55 @@ exports.checkDepsChanges = async ({
monorepoPKGjson.dependencies[key]
) {
// Check only for version changes in packages
// that are not from medusa repo.
// Changes in medusa packages will be copied over
// that are not from gatsby repo.
// Changes in gatsby packages will be copied over
// from monorepo - and if those contain other dependency
// changes - they will be covered
if (!monoRepoPackages.includes(key)) {
acc.push(
` - '${key}' changed version from ${localPKGjson.dependencies[key]} to ${monorepoPKGjson.dependencies[key]}`
);
needPublishing = true;
)
needPublishing = true
}
} else if (monorepoPKGjson.dependencies[key]) {
acc.push(
` - '${key}@${monorepoPKGjson.dependencies[key]}' was added`
);
needPublishing = true;
acc.push(` - '${key}@${monorepoPKGjson.dependencies[key]}' was added`)
needPublishing = true
} else {
acc.push(` - '${key}@${localPKGjson.dependencies[key]}' was removed`);
acc.push(` - '${key}@${localPKGjson.dependencies[key]}' was removed`)
// this doesn't need publishing really, so will skip this
}
return acc;
return acc
}, [])
.join(`\n`);
.join(`\n`)
if (!isPublishing && depChangeLog.length > 0) {
console.log(`Dependencies of '${packageName}' changed:\n${depChangeLog}`);
console.log(`Dependencies of '${packageName}' changed:\n${depChangeLog}`)
if (isInitialScan) {
console.log(
`Will ${!needPublishing ? `not ` : ``}publish to local npm registry.`
);
)
} else {
console.warn(
`Installation of dependencies after initial scan is not implemented`
);
)
}
return {
didDepsChanged: needPublishing,
packageNotInstalled,
};
}
}
}
return {
didDepsChanged: false,
packageNotInstalled,
};
};
}
}
function getPackageVersion(packageName) {
const projectPackageJson = JSON.parse(
fs.readFileSync(`./package.json`, `utf-8`)
)
const { dependencies = {}, devDependencies = {} } = projectPackageJson
const version = dependencies[packageName] || devDependencies[packageName]
return version || `latest`
}
@@ -1,11 +1,4 @@
const path = require(`path`);
const path = require(`path`)
exports.getMonorepoPackageJsonPath = ({ packageName, root }) => {
let dirName = packageName;
if (packageName.startsWith("@medusajs")) {
const [, directory] = packageName.split("/");
dirName = directory;
}
return path.join(root, `packages`, dirName, `package.json`);
};
exports.getMonorepoPackageJsonPath = ({ packageName, packageNameToPath }) =>
path.join(packageNameToPath.get(packageName), `package.json`)
@@ -1,10 +1,17 @@
const _ = require(`lodash`);
const path = require(`path`);
const _ = require(`lodash`)
const path = require(`path`)
/**
* @typedef {Object} TraversePackagesDepsReturn
* @property {Object} depTree Lookup table to check dependants for given package.
* Used to determine which packages need to be published.
* @example
* ```
* {
* "medusa-cli": Set(["medusa"]),
* "medusa-telemetry": Set(["medusa", "medusa-cli"]),
* }
* ```
*/
/**
@@ -24,53 +31,58 @@ const path = require(`path`);
* @return {TraversePackagesDepsReturn}
*/
const traversePackagesDeps = ({
root,
packages,
monoRepoPackages,
seenPackages = [...packages],
depTree = {},
packageNameToPath,
}) => {
packages.forEach((p) => {
if (p.startsWith("@medusajs")) {
p = p.split("/")[1];
}
let pkgJson;
let pkgJson
try {
pkgJson = require(path.join(root, `packages`, p, `package.json`));
} catch {
console.error(`"${p}" package doesn't exist in monorepo.`);
const packageRoot = packageNameToPath.get(p)
if (packageRoot) {
pkgJson = require(path.join(packageRoot, `package.json`))
} else {
console.error(`"${p}" package doesn't exist in monorepo.`)
// remove from seenPackages
seenPackages = seenPackages.filter((seenPkg) => seenPkg !== p)
return
}
} catch (e) {
console.error(`"${p}" package doesn't exist in monorepo.`, e)
// remove from seenPackages
seenPackages = seenPackages.filter((seenPkg) => seenPkg !== p);
return;
seenPackages = seenPackages.filter((seenPkg) => seenPkg !== p)
return
}
const fromMonoRepo = _.intersection(
Object.keys({ ...pkgJson.dependencies }),
monoRepoPackages
);
)
fromMonoRepo.forEach((pkgName) => {
depTree[pkgName] = (depTree[pkgName] || new Set()).add(p);
});
depTree[pkgName] = (depTree[pkgName] || new Set()).add(p)
})
// only traverse not yet seen packages to avoid infinite loops
const newPackages = _.difference(fromMonoRepo, seenPackages);
const newPackages = _.difference(fromMonoRepo, seenPackages)
if (newPackages.length) {
newPackages.forEach((depFromMonorepo) => {
seenPackages.push(depFromMonorepo);
});
seenPackages.push(depFromMonorepo)
})
traversePackagesDeps({
root,
packages: fromMonoRepo,
monoRepoPackages,
seenPackages,
depTree,
});
packageNameToPath,
})
}
});
return { seenPackages, depTree };
};
})
return { seenPackages, depTree }
}
exports.traversePackagesDeps = traversePackagesDeps;
exports.traversePackagesDeps = traversePackagesDeps
+151 -133
View File
@@ -1,27 +1,27 @@
const chokidar = require(`chokidar`);
const _ = require(`lodash`);
const del = require(`del`);
const fs = require(`fs-extra`);
const path = require(`path`);
const findWorkspaceRoot = require(`find-yarn-workspace-root`);
const chokidar = require(`chokidar`)
const _ = require(`lodash`)
const del = require(`del`)
const fs = require(`fs-extra`)
const path = require(`path`)
const findWorkspaceRoot = require(`find-yarn-workspace-root`)
const { publishPackagesLocallyAndInstall } = require(`./local-npm-registry`);
const { checkDepsChanges } = require(`./utils/check-deps-changes`);
const { getDependantPackages } = require(`./utils/get-dependant-packages`);
const { publishPackagesLocallyAndInstall } = require(`./local-npm-registry`)
const { checkDepsChanges } = require(`./utils/check-deps-changes`)
const { getDependantPackages } = require(`./utils/get-dependant-packages`)
const {
setDefaultSpawnStdio,
promisifiedSpawn,
} = require(`./utils/promisified-spawn`);
const { traversePackagesDeps } = require(`./utils/traverse-package-deps`);
} = require(`./utils/promisified-spawn`)
const { traversePackagesDeps } = require(`./utils/traverse-package-deps`)
let numCopied = 0;
let numCopied = 0
const quit = () => {
console.log(`Copied ${numCopied} files`);
process.exit();
};
console.log(`Copied ${numCopied} files`)
process.exit()
}
const MAX_COPY_RETRIES = 3;
const MAX_COPY_RETRIES = 3
/*
* non-existent packages break on('ready')
@@ -30,76 +30,89 @@ const MAX_COPY_RETRIES = 3;
async function watch(
root,
packages,
{ scanOnce, quiet, forceInstall, monoRepoPackages, localPackages }
{
scanOnce,
quiet,
forceInstall,
monoRepoPackages,
localPackages,
packageNameToPath,
externalRegistry,
}
) {
setDefaultSpawnStdio(quiet ? `ignore` : `inherit`);
setDefaultSpawnStdio(quiet ? `ignore` : `inherit`)
// determine if in yarn workspace - if in workspace, force using verdaccio
// as current logic of copying files will not work correctly.
const yarnWorkspaceRoot = findWorkspaceRoot();
const yarnWorkspaceRoot = findWorkspaceRoot()
if (yarnWorkspaceRoot && process.env.NODE_ENV !== `test`) {
console.log(`Yarn workspace found.`);
forceInstall = true;
console.log(`Yarn workspace found.`)
forceInstall = true
}
let afterPackageInstallation = false;
let queuedCopies = [];
let afterPackageInstallation = false
let queuedCopies = []
const realCopyPath = (arg) => {
const { oldPath, newPath, quiet, resolve, reject, retry = 0 } = arg;
const { oldPath, newPath, quiet, resolve, reject, retry = 0 } = arg
fs.copy(oldPath, newPath, (err) => {
if (err) {
if (retry >= MAX_COPY_RETRIES) {
console.error(err);
reject(err);
return;
console.error(err)
reject(err)
return
} else {
setTimeout(
() => realCopyPath({ ...arg, retry: retry + 1 }),
500 * Math.pow(2, retry)
);
return;
)
return
}
}
// When the medusa binary is copied over, it is not setup with the executable
// permissions that it is given when installed via yarn.
// This fixes the issue where after running meduas-dev, running `yarn medusa develop`
// This fixes the issue where after running medusa-dev, running `yarn medusa develop`
// fails with a permission issue.
if (/(bin\/meduas.js|medusa(-cli)?\/cli.js)$/.test(newPath)) {
fs.chmodSync(newPath, `0755`);
// @fixes https://github.com/medusajs/medusa/issues/18809
// Binary files we target:
// - medusa/bin/medusa.js
// -medusa/cli.js
// -medusa-cli/cli.js
if (/(bin\/medusa.js|medusa(-cli)?\/cli.js)$/.test(newPath)) {
fs.chmodSync(newPath, `0755`)
}
numCopied += 1;
numCopied += 1
if (!quiet) {
console.log(`Copied ${oldPath} to ${newPath}`);
console.log(`Copied ${oldPath} to ${newPath}`)
}
resolve();
});
};
resolve()
})
}
const copyPath = (oldPath, newPath, quiet, packageName) =>
new Promise((resolve, reject) => {
const argObj = { oldPath, newPath, quiet, packageName, resolve, reject };
const argObj = { oldPath, newPath, quiet, packageName, resolve, reject }
if (afterPackageInstallation) {
realCopyPath(argObj);
realCopyPath(argObj)
} else {
queuedCopies.push(argObj);
queuedCopies.push(argObj)
}
});
})
const runQueuedCopies = () => {
afterPackageInstallation = true;
queuedCopies.forEach((argObj) => realCopyPath(argObj));
queuedCopies = [];
};
afterPackageInstallation = true
queuedCopies.forEach((argObj) => realCopyPath(argObj))
queuedCopies = []
}
const clearJSFilesFromNodeModules = async () => {
const packagesToClear = queuedCopies.reduce((acc, { packageName }) => {
if (packageName) {
acc.add(packageName);
acc.add(packageName)
}
return acc;
}, new Set());
return acc
}, new Set())
await Promise.all(
[...packagesToClear].map(
@@ -110,65 +123,64 @@ async function watch(
`!node_modules/${packageToClear}/src/**/*.{js,js.map}`,
])
)
);
};
)
}
// check packages deps and if they depend on other packages from monorepo
// add them to packages list
const { seenPackages, depTree } = traversePackagesDeps({
root,
packages: _.uniq(localPackages),
monoRepoPackages,
});
packageNameToPath,
})
const allPackagesToWatch = packages
? _.intersection(packages, seenPackages)
: seenPackages;
: seenPackages
const ignoredPackageJSON = new Map();
const ignoredPackageJSON = new Map()
const ignorePackageJSONChanges = (packageName, contentArray) => {
ignoredPackageJSON.set(packageName, contentArray);
ignoredPackageJSON.set(packageName, contentArray)
return () => {
ignoredPackageJSON.delete(packageName);
};
};
ignoredPackageJSON.delete(packageName)
}
}
if (forceInstall) {
try {
if (allPackagesToWatch.length > 0) {
await publishPackagesLocallyAndInstall({
packagesToPublish: allPackagesToWatch,
root,
packageNameToPath,
localPackages,
ignorePackageJSONChanges,
yarnWorkspaceRoot,
});
externalRegistry,
})
} else {
// run `yarn`
const yarnInstallCmd = [`yarn`];
const yarnInstallCmd = [`yarn`]
console.log(`Installing packages from public NPM registry`);
await promisifiedSpawn(yarnInstallCmd);
console.log(`Installation complete`);
console.log(`Installing packages from public NPM registry`)
await promisifiedSpawn(yarnInstallCmd)
console.log(`Installation complete`)
}
} catch (e) {
console.log(e);
console.log(e)
}
process.exit();
process.exit()
}
if (allPackagesToWatch.length === 0) {
console.error(`There are no packages to watch.`);
return;
console.error(`There are no packages to watch.`)
return
}
const cleanToWatch = allPackagesToWatch.map((pkgName) => {
if (pkgName.startsWith(`@medusajs`)) {
return pkgName.split("/")[1];
}
return pkgName;
});
const allPackagesIgnoringThemesToWatch = allPackagesToWatch.filter(
(pkgName) => !pkgName.startsWith(`medusa-theme`)
)
const ignored = [
/[/\\]node_modules[/\\]/i,
@@ -178,63 +190,70 @@ async function watch(
/[/\\]__mocks__[/\\]/i,
/\.npmrc/i,
].concat(
cleanToWatch.map((p) => new RegExp(`${p}[\\/\\\\]src[\\/\\\\]`, `i`))
);
allPackagesIgnoringThemesToWatch.map(
(p) => new RegExp(`${p}[\\/\\\\]src[\\/\\\\]`, `i`)
)
)
const watchers = _.uniq(
cleanToWatch
.map((p) => path.join(root, `/packages/`, p))
allPackagesToWatch
.map((p) => path.join(packageNameToPath.get(p)))
.filter((p) => fs.existsSync(p))
);
)
let allCopies = [];
const packagesToPublish = new Set();
let isInitialScan = true;
let isPublishing = false;
let allCopies = []
const packagesToPublish = new Set()
let isInitialScan = true
let isPublishing = false
const waitFor = new Set();
let anyPackageNotInstalled = false;
const watchEvents = [`change`, `add`];
const waitFor = new Set()
let anyPackageNotInstalled = false
const watchEvents = [`change`, `add`]
const packagePathMatchingEntries = Array.from(packageNameToPath.entries())
chokidar
.watch(watchers, {
ignored: [(filePath) => _.some(ignored, (reg) => reg.test(filePath))],
})
.on(`all`, async (event, filePath) => {
if (!watchEvents.includes(event)) {
return;
return
}
const [pack] = filePath
.split(/packages[/\\]/)
.pop()
.split(/[/\\]/);
// match against paths
let packageName
const sourcePkg = JSON.parse(
fs.readFileSync(path.join(root, `/packages/`, pack, `package.json`))
);
const packageName = sourcePkg.name;
for (const [_packageName, packagePath] of packagePathMatchingEntries) {
const relativeToThisPackage = path.relative(packagePath, filePath)
if (!relativeToThisPackage.startsWith(`..`)) {
packageName = _packageName
break
}
}
const prefix = path.join(root, `/packages/`, pack);
if (!packageName) {
return
}
const prefix = packageNameToPath.get(packageName)
// Copy it over local version.
// Don't copy over the medusa bin file as that breaks the NPM symlink.
if (_.includes(filePath, `dist/medusa-cli.js`)) {
return;
return
}
const relativePackageFile = path.relative(prefix, filePath);
const relativePackageFile = path.relative(prefix, filePath)
const newPath = path.join(
`./node_modules/${packageName}`,
relativePackageFile
);
)
if (relativePackageFile === `package.json`) {
// package.json files will change during publish to adjust version of package (and dependencies), so ignore
// changes during this process
if (isPublishing) {
return;
return
}
// Compare dependencies with local version
@@ -243,10 +262,10 @@ async function watch(
newPath,
packageName,
monoRepoPackages,
root,
packageNameToPath,
isInitialScan,
ignoredPackageJSON,
});
})
if (isInitialScan) {
// normally checkDepsChanges would be sync,
@@ -255,21 +274,19 @@ async function watch(
// keep track of it to make sure all of it
// finish before installing
waitFor.add(didDepsChangedPromise);
waitFor.add(didDepsChangedPromise)
}
const {
didDepsChanged,
packageNotInstalled,
} = await didDepsChangedPromise;
const { didDepsChanged, packageNotInstalled } =
await didDepsChangedPromise
if (packageNotInstalled) {
anyPackageNotInstalled = true;
anyPackageNotInstalled = true
}
if (didDepsChanged) {
if (isInitialScan) {
waitFor.delete(didDepsChangedPromise);
waitFor.delete(didDepsChangedPromise)
// handle dependency change only in initial scan - this is for sure doable to
// handle this in watching mode correctly - but for the sake of shipping
// this I limit more work/time consuming edge cases.
@@ -287,66 +304,67 @@ async function watch(
}).forEach((packageToPublish) => {
// scheduling publish - we will publish when `ready` is emitted
// as we can do single publish then
packagesToPublish.add(packageToPublish);
});
packagesToPublish.add(packageToPublish)
})
}
}
// don't ever copy package.json as this will mess up any future dependency
// changes checks
return;
return
}
const localCopies = [copyPath(filePath, newPath, quiet, packageName)];
const localCopies = [copyPath(filePath, newPath, quiet, packageName)]
// If this is from "cache-dir" also copy it into the site's .cache
if (_.includes(filePath, `cache-dir`)) {
const newCachePath = path.join(
`.cache/`,
path.relative(path.join(prefix, `cache-dir`), filePath)
);
localCopies.push(copyPath(filePath, newCachePath, quiet));
)
localCopies.push(copyPath(filePath, newCachePath, quiet))
}
allCopies = allCopies.concat(localCopies);
allCopies = allCopies.concat(localCopies)
})
.on(`ready`, async () => {
// wait for all async work needed to be done
// before publishing / installing
await Promise.all(Array.from(waitFor));
await Promise.all(Array.from(waitFor))
if (isInitialScan) {
isInitialScan = false;
isInitialScan = false
if (packagesToPublish.size > 0) {
isPublishing = true;
isPublishing = true
await publishPackagesLocallyAndInstall({
packagesToPublish: Array.from(packagesToPublish),
root,
packageNameToPath,
localPackages,
ignorePackageJSONChanges,
});
packagesToPublish.clear();
isPublishing = false;
externalRegistry,
})
packagesToPublish.clear()
isPublishing = false
} else if (anyPackageNotInstalled) {
// run `yarn`
const yarnInstallCmd = [`yarn`];
const yarnInstallCmd = [`yarn`]
console.log(`Installing packages from public NPM registry`);
await promisifiedSpawn(yarnInstallCmd);
console.log(`Installation complete`);
console.log(`Installing packages from public NPM registry`)
await promisifiedSpawn(yarnInstallCmd)
console.log(`Installation complete`)
}
await clearJSFilesFromNodeModules();
runQueuedCopies();
await clearJSFilesFromNodeModules()
runQueuedCopies()
}
// all files watched, quit once all files are copied if necessary
Promise.all(allCopies).then(() => {
if (scanOnce) {
quit();
quit()
}
});
});
})
})
}
module.exports = watch;
module.exports = watch
+17
View File
@@ -3,6 +3,23 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.0.7](https://github.com/medusajs/medusa/compare/medusa-file-minio@1.0.6...medusa-file-minio@1.0.7) (2022-07-05)
### Bug Fixes
* **medusa-file-spaces,medusa-file-s3,medusa-file-minio:** Add options to super call in file plugins ([#1714](https://github.com/medusajs/medusa/issues/1714)) ([a5f717b](https://github.com/medusajs/medusa/commit/a5f717be5ae1954f3dbf1e7b2edb35d11088a8c8))
### Features
* **medusa:** Delete and download url endpoints ([#1705](https://github.com/medusajs/medusa/issues/1705)) ([cc29b64](https://github.com/medusajs/medusa/commit/cc29b641c9358415b46179371988e7ddc11d2664))
* **medusa:** Extend file-service interface + move to core ([#1577](https://github.com/medusajs/medusa/issues/1577)) ([8e42d37](https://github.com/medusajs/medusa/commit/8e42d37e84e80c003b9c0311117ab8a8871aa61b))
## [1.0.6](https://github.com/medusajs/medusa/compare/medusa-file-minio@1.0.4...medusa-file-minio@1.0.6) (2022-06-19)
**Note:** Version bump only for package medusa-file-minio
+1 -1
View File
@@ -13,4 +13,4 @@ Learn more about how you can use this plugin in the [documentation](https://docs
access_key_id: "YOUR-ACCESS-KEY",
secret_access_key: "YOUR-SECRET-KEY",
}
```
```
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "medusa-file-minio",
"version": "1.0.6",
"version": "1.0.7",
"description": "MinIO server file connector for Medusa",
"main": "index.js",
"repository": {
@@ -1,10 +1,11 @@
import fs from "fs"
import { AbstractFileService } from '@medusajs/medusa'
import aws from "aws-sdk"
import { FileService } from "medusa-interfaces"
import fs from "fs"
class MinioService extends FileService {
class MinioService extends AbstractFileService {
constructor({}, options) {
super()
super({}, options)
this.bucket_ = options.bucket
this.accessKeyId_ = options.access_key_id
@@ -15,14 +16,14 @@ class MinioService extends FileService {
}
upload(file) {
aws.config.setPromisesDependency()
aws.config.setPromisesDependency(null)
aws.config.update({
accessKeyId: this.accessKeyId_,
secretAccessKey: this.secretAccessKey_,
endpoint: this.endpoint_,
s3ForcePathStyle: this.s3ForcePathStyle_,
signatureVersion: this.signatureVersion_,
})
}, true)
const s3 = new aws.S3()
const params = {
@@ -46,14 +47,14 @@ class MinioService extends FileService {
}
delete(file) {
aws.config.setPromisesDependency()
aws.config.setPromisesDependency(null)
aws.config.update({
accessKeyId: this.accessKeyId_,
secretAccessKey: this.secretAccessKey_,
endpoint: this.endpoint_,
s3ForcePathStyle: this.s3ForcePathStyle_,
signatureVersion: this.signatureVersion_,
})
}, true)
const s3 = new aws.S3()
const params = {
@@ -71,6 +72,18 @@ class MinioService extends FileService {
})
})
}
async getUploadStreamDescriptor(fileData) {
throw new Error("Method not implemented.")
}
async getDownloadStream(fileData) {
throw new Error("Method not implemented.")
}
async getPresignedDownloadUrl(fileData) {
throw new Error("Method not implemented.")
}
}
export default MinioService
+16
View File
@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.3](https://github.com/medusajs/medusa/compare/medusa-file-s3@1.1.2...medusa-file-s3@1.1.3) (2022-07-05)
### Bug Fixes
* **medusa-file-spaces,medusa-file-s3,medusa-file-minio:** Add options to super call in file plugins ([#1714](https://github.com/medusajs/medusa/issues/1714)) ([a5f717b](https://github.com/medusajs/medusa/commit/a5f717be5ae1954f3dbf1e7b2edb35d11088a8c8))
### Features
* **medusa:** Extend file-service interface + move to core ([#1577](https://github.com/medusajs/medusa/issues/1577)) ([8e42d37](https://github.com/medusajs/medusa/commit/8e42d37e84e80c003b9c0311117ab8a8871aa61b))
## [1.1.2](https://github.com/medusajs/medusa/compare/medusa-file-s3@1.1.0...medusa-file-s3@1.1.2) (2022-06-19)
**Note:** Version bump only for package medusa-file-s3
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "medusa-file-s3",
"version": "1.1.2",
"version": "1.1.3",
"description": "AWS s3 file connector for Medusa",
"main": "index.js",
"repository": {
+19 -7
View File
@@ -1,10 +1,10 @@
import fs from "fs"
import aws from "aws-sdk"
import { FileService } from "medusa-interfaces"
import { AbstractFileService } from '@medusajs/medusa'
class S3Service extends FileService {
class S3Service extends AbstractFileService {
constructor({}, options) {
super()
super({}, options)
this.bucket_ = options.bucket
this.s3Url_ = options.s3_url
@@ -15,13 +15,13 @@ class S3Service extends FileService {
}
upload(file) {
aws.config.setPromisesDependency()
aws.config.setPromisesDependency(null)
aws.config.update({
accessKeyId: this.accessKeyId_,
secretAccessKey: this.secretAccessKey_,
region: this.region_,
endpoint: this.endpoint_,
})
}, true)
const s3 = new aws.S3()
var params = {
@@ -44,13 +44,13 @@ class S3Service extends FileService {
}
delete(file) {
aws.config.setPromisesDependency()
aws.config.setPromisesDependency(null)
aws.config.update({
accessKeyId: this.accessKeyId_,
secretAccessKey: this.secretAccessKey_,
region: this.region_,
endpoint: this.endpoint_,
})
}, true)
const s3 = new aws.S3()
var params = {
@@ -68,6 +68,18 @@ class S3Service extends FileService {
})
})
}
async getUploadStreamDescriptor(fileData) {
throw new Error("Method not implemented.")
}
async getDownloadStream(fileData) {
throw new Error("Method not implemented.")
}
async getPresignedDownloadUrl(fileData) {
throw new Error("Method not implemented.")
}
}
export default S3Service
+18
View File
@@ -3,6 +3,24 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.2.3](https://github.com/medusajs/medusa/compare/medusa-file-spaces@1.2.2...medusa-file-spaces@1.2.3) (2022-07-05)
### Bug Fixes
* **medusa-file-spaces,medusa-file-s3,medusa-file-minio:** Add options to super call in file plugins ([#1714](https://github.com/medusajs/medusa/issues/1714)) ([a5f717b](https://github.com/medusajs/medusa/commit/a5f717be5ae1954f3dbf1e7b2edb35d11088a8c8))
### Features
* **medusa:** Add batch strategy for order exports ([#1603](https://github.com/medusajs/medusa/issues/1603)) ([bf47d1a](https://github.com/medusajs/medusa/commit/bf47d1aecd74f4489667609444a8b09393e894d3))
* **medusa:** Extend file-service interface + move to core ([#1577](https://github.com/medusajs/medusa/issues/1577)) ([8e42d37](https://github.com/medusajs/medusa/commit/8e42d37e84e80c003b9c0311117ab8a8871aa61b))
* **medusa-file-spaces:** DigitalOcean fileservice streaming ([#1585](https://github.com/medusajs/medusa/issues/1585)) ([abaf10b](https://github.com/medusajs/medusa/commit/abaf10b31d1e9a60710da87cac5c9c869195660d)), closes [#1583](https://github.com/medusajs/medusa/issues/1583) [#1580](https://github.com/medusajs/medusa/issues/1580) [#1582](https://github.com/medusajs/medusa/issues/1582) [#1583](https://github.com/medusajs/medusa/issues/1583) [#1580](https://github.com/medusajs/medusa/issues/1580) [#1582](https://github.com/medusajs/medusa/issues/1582)
## [1.2.2](https://github.com/medusajs/medusa/compare/medusa-file-spaces@1.2.0...medusa-file-spaces@1.2.2) (2022-06-19)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "medusa-file-spaces",
"version": "1.2.2",
"version": "1.2.3",
"description": "Digital Ocean Spaces file connector for Medusa",
"main": "index.js",
"repository": {
@@ -1,11 +1,12 @@
import fs from "fs"
import { AbstractFileService } from "@medusajs/medusa"
import aws from "aws-sdk"
import fs from "fs"
import { parse } from "path"
import { FileService } from "medusa-interfaces"
import stream from "stream"
class DigitalOceanService extends FileService {
class DigitalOceanService extends AbstractFileService {
constructor({}, options) {
super()
super({}, options)
this.bucket_ = options.bucket
this.spacesUrl_ = options.spaces_url?.replace(/\/$/, "")
@@ -16,18 +17,12 @@ class DigitalOceanService extends FileService {
}
upload(file) {
aws.config.setPromisesDependency()
aws.config.update({
accessKeyId: this.accessKeyId_,
secretAccessKey: this.secretAccessKey_,
region: this.region_,
endpoint: this.endpoint_,
})
this.updateAwsConfig()
const parsedFilename = parse(file.originalname)
const fileKey = `${parsedFilename.name}-${Date.now()}${parsedFilename.ext}`
const s3 = new aws.S3()
var params = {
const params = {
ACL: "public-read",
Bucket: this.bucket_,
Body: fs.createReadStream(file.path),
@@ -51,16 +46,10 @@ class DigitalOceanService extends FileService {
}
delete(file) {
aws.config.setPromisesDependency()
aws.config.update({
accessKeyId: this.accessKeyId_,
secretAccessKey: this.secretAccessKey_,
region: this.region_,
endpoint: this.endpoint_,
})
this.updateAwsConfig()
const s3 = new aws.S3()
var params = {
const params = {
Bucket: this.bucket_,
Key: `${file}`,
}
@@ -75,6 +64,71 @@ class DigitalOceanService extends FileService {
})
})
}
async getUploadStreamDescriptor(fileData) {
this.updateAwsConfig()
const pass = new stream.PassThrough()
const fileKey = `${fileData.name}.${fileData.ext}`
const params = {
ACL: fileData.acl ?? "private",
Bucket: this.bucket_,
Body: pass,
Key: fileKey,
}
const s3 = new aws.S3()
return {
writeStream: pass,
promise: s3.upload(params).promise(),
url: `${this.spacesUrl_}/${fileKey}`,
fileKey,
}
}
async getDownloadStream(fileData) {
this.updateAwsConfig()
const s3 = new aws.S3()
const params = {
Bucket: this.bucket_,
Key: `${fileData.fileKey}`,
}
return s3.getObject(params).createReadStream()
}
async getPresignedDownloadUrl(fileData) {
this.updateAwsConfig({
signatureVersion: "v4",
})
const s3 = new aws.S3()
const params = {
Bucket: this.bucket_,
Key: `${fileData.fileKey}`,
Expires: 60, // 60 seconds
}
return await s3.getSignedUrlPromise("getObject", params)
}
updateAwsConfig(additionalConfiguration = {}) {
aws.config.setPromisesDependency(null)
aws.config.update(
{
accessKeyId: this.accessKeyId_,
secretAccessKey: this.secretAccessKey_,
region: this.region_,
endpoint: this.endpoint_,
...additionalConfiguration,
},
true
)
}
}
export default DigitalOceanService
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.3.3](https://github.com/medusajs/medusa/compare/medusa-fulfillment-webshipper@1.3.2...medusa-fulfillment-webshipper@1.3.3) (2022-07-05)
### Bug Fixes
* **webshipper:** allow cancelling WS orders with error status ([#1755](https://github.com/medusajs/medusa/issues/1755)) ([1d3032d](https://github.com/medusajs/medusa/commit/1d3032dc671b477654afd13a218caa772454bde0))
* **webshipper:** only add invoices if invoice generator produces a file ([#1749](https://github.com/medusajs/medusa/issues/1749)) ([c0e18d4](https://github.com/medusajs/medusa/commit/c0e18d473c050d143f67ed2c76fa9ec9414daf1a))
## [1.3.2](https://github.com/medusajs/medusa/compare/medusa-fulfillment-webshipper@1.3.0...medusa-fulfillment-webshipper@1.3.2) (2022-06-19)
**Note:** Version bump only for package medusa-fulfillment-webshipper
@@ -1,6 +1,6 @@
# medusa-fulfillment-webshipper
Adds Webshipper as a fulfilment provider in Medusa Commerce.
Adds Webshipper as a fulfilment provider in Medusa Commerce.
On each new fulfillment an order is created in Webshipper. The plugin listens for shipment events and updated the shipment accordingly.
A webhook listener is exposed at `/webshipper/shipments` to listen for shipment creations. You must create this webhook in Webshipper to have Medusa listen for shipment events.
@@ -13,4 +13,5 @@ A webhook listener is exposed at `/webshipper/shipments` to listen for shipment
order_channel_id: [the channel id to register orders on] (required)
webhook_secret: [the webhook secret used to listen for shipments] (required)
coo_countries: [an array of countries in which a Certificate of Origin will be attached] (default: "all")
delete_on_cancel [determines whether Webshipper orders are deleted when a Medusa fulfillment is canceled] (default: false)
```
@@ -1,6 +1,6 @@
{
"name": "medusa-fulfillment-webshipper",
"version": "1.3.2",
"version": "1.3.3",
"description": "Webshipper Fulfillment provider for Medusa",
"main": "index.js",
"repository": {
@@ -18,7 +18,7 @@
"@babel/plugin-transform-runtime": "^7.7.6",
"@babel/preset-env": "^7.7.5",
"@babel/runtime": "^7.9.6",
"@medusajs/medusa": "^1.3.2",
"@medusajs/medusa": "^1.3.3",
"client-sessions": "^0.8.0",
"cross-env": "^5.2.1",
"eslint": "^6.8.0",
@@ -287,19 +287,21 @@ class WebshipperFulfillmentService extends FulfillmentService {
fulfillmentItems
)
invoice = await this.client_.documents
.create({
type: "documents",
attributes: {
document_size: this.options_.document_size || "A4",
document_format: "PDF",
base64: base64Invoice,
document_type: "invoice",
},
})
.catch((err) => {
throw err
})
if (base64Invoice) {
invoice = await this.client_.documents
.create({
type: "documents",
attributes: {
document_size: this.options_.document_size || "A4",
document_format: "PDF",
base64: base64Invoice,
document_type: "invoice",
},
})
.catch((err) => {
throw err
})
}
const cooCountries = this.options_.coo_countries
if (
@@ -621,19 +623,17 @@ class WebshipperFulfillmentService extends FulfillmentService {
return Promise.resolve()
}
if (order) {
if (
order.data.attributes.status !== "pending" &&
order.data.attributes.status !== "missing_rate"
) {
if (order.data.attributes.status === "cancelled") {
return Promise.resolve(order)
}
throw new Error("Cannot cancel order")
}
if (this.options_.delete_on_cancel) {
return await this.client_.orders.delete(data.id)
}
return this.client_.orders.delete(data.id)
return await this.client_.orders.update(data.id, {
id: data.id,
type: "orders",
attributes: {
status: "cancelled",
},
})
}
}
@@ -83,6 +83,16 @@ class Webshipper {
},
}).then(({ data }) => data)
},
update: async (id, data) => {
const path = `/v2/orders/${id}`
return this.client_({
method: "PATCH",
url: path,
data: {
data,
},
}).then(({ data }) => data)
},
delete: async (id) => {
const path = `/v2/orders/${id}`
return this.client_({
+11
View File
@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.3.1](https://github.com/medusajs/medusa/compare/medusa-interfaces@1.3.0...medusa-interfaces@1.3.1) (2022-07-05)
### Bug Fixes
* **medusa:** Remove deps `mongoose` + `mongodb` ([#1218](https://github.com/medusajs/medusa/issues/1218)) ([c76e23e](https://github.com/medusajs/medusa/commit/c76e23e84dd8cb08c3c709f9f95c4c17b9685439))
# [1.3.0](https://github.com/medusajs/medusa/compare/medusa-interfaces@1.2.1...medusa-interfaces@1.3.0) (2022-05-01)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "medusa-interfaces",
"version": "1.3.0",
"version": "1.3.1",
"description": "Core interfaces for Medusa",
"main": "dist/index.js",
"repository": {
@@ -1,153 +0,0 @@
import mongoose from "mongoose"
/**
* Interface for data models. The default data layer uses an internal mongoose
* model and is as such compatible with MongoDB.
* @interface
*/
class BaseModel {
constructor() {
/** @const the underlying mongoose model used for queries */
this.mongooseModel_ = this.createMongooseModel_()
}
/**
* Returns the model schema. The child class must implement the static schema
* property.
* @return {string} the models schema
*/
getSchema() {
if (!this.constructor.schema) {
throw new Error("Schema not defined")
}
return this.constructor.schema
}
/**
* Returns the model name. The child class must implement the static modelName
* property.
* @return {string} the name of the model
*/
getModelName() {
if (!this.constructor.modelName) {
throw new Error("Every model must have a static modelName property")
}
return this.constructor.modelName
}
/**
* Returns the schema options defined in child class.
* @return {object} the schema options
*/
getSchemaOptions() {
if (!this.constructor.schemaOptions) {
return {}
}
return this.constructor.schemaOptions
}
/**
* @private
* Creates a mongoose model based on schema, schema options and model name.
* @return {Mongooose.Model} the mongoose model
*/
createMongooseModel_() {
const schema = this.getSchema()
const options = this.getSchemaOptions()
const mongooseSchema = new mongoose.Schema(schema, options)
return mongoose.model(this.getModelName(), mongooseSchema)
}
/**
*/
startSession() {
return this.mongooseModel_.startSession()
}
/**
* Queries the mongoose model via the mongoose's findOne.
* @param query {object} a mongoose selector query
* @param options {?object=} mongoose options
* @return {?mongoose.Document} the retreived mongoose document or null.
*/
findOne(query, options = {}) {
return this.mongooseModel_.findOne(query, options).lean()
}
/**
* Queries the mongoose model via the mongoose's find.
* @param query {object} a mongoose selector query
* @param options {?object=} mongoose options
* @return {Array<mongoose.Document>} the retreived mongoose documents or
* an empty array
*/
find(query, options, offset, limit) {
return this.mongooseModel_
.find(query, options)
.skip(offset)
.limit(limit)
.lean()
}
count() {
return this.mongooseModel_.count({})
}
/**
* Update a model via the mongoose model's updateOne.
* @param query {object} a mongoose selector query
* @param update {object} mongoose update object
* @param options {?object=} mongoose options
* @return {object} mongoose result
*/
updateOne(query, update, options = {}) {
options.new = true
return this.mongooseModel_.findOneAndUpdate(query, update, options).lean()
}
/**
* Update a model via the mongoose model's update.
* @param query {object} a mongoose selector query
* @param update {object} mongoose update object
* @param options {?object=} mongoose options
* @return {object} mongoose result
*/
update(query, update, options) {
return this.mongooseModel_.update(query, update, options)
}
/**
* Creates a document in the mongoose model's collection via create.
* @param object {object} the value of the document to be created
* @param options {?object=} mongoose options
* @return {object} mongoose result
*/
create(object, options) {
return this.mongooseModel_.create(object, options)
}
/**
* Deletes a document in the mongoose model's collection
* @param query {object} the value of the document to be created
* @param options {?object=} mongoose options
* @return {object} mongoose result
*/
deleteOne(query, options) {
return this.mongooseModel_.deleteOne(query, options)
}
/**
* Deletes many document in the mongoose model's collection
* @param query {object} the value of the document to be created
* @param options {?object=} mongoose options
* @return {object} mongoose result
*/
delete(query, options) {
return this.mongooseModel_.deleteMany(query, options)
}
}
export default BaseModel
+2 -3
View File
@@ -1,8 +1,7 @@
export { default as BaseService } from "./base-service"
export { default as BaseModel } from "./base-model"
export { default as PaymentService } from "./payment-service"
export { default as FulfillmentService } from "./fulfillment-service"
export { default as FileService } from "./file-service"
export { default as FulfillmentService } from "./fulfillment-service"
export { default as NotificationService } from "./notification-service"
export { default as OauthService } from "./oauth-service"
export { default as PaymentService } from "./payment-service"
export { default as SearchService } from "./search-service"
+17
View File
@@ -3,6 +3,23 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.2.3](https://github.com/medusajs/medusa/compare/@medusajs/medusa-js@1.2.2...@medusajs/medusa-js@1.2.3) (2022-07-05)
### Bug Fixes
* **medusa-js:** Fix `stringifyNullProperties` util ([#1766](https://github.com/medusajs/medusa/issues/1766)) ([7bee57f](https://github.com/medusajs/medusa/commit/7bee57f7c55e15b6a6c847dfda433e67f258ef8e))
### Features
* **medusa-js:** Create utils to stringify null values and respect object types ([#1748](https://github.com/medusajs/medusa/issues/1748)) ([fc1cbe7](https://github.com/medusajs/medusa/commit/fc1cbe72c7b0cd2879a8b112a6f63fa94c728a19))
* **medusa,medusa-js,medusa-react:** Add BatchJob API support in `medusa-js` + `medusa-react` ([#1704](https://github.com/medusajs/medusa/issues/1704)) ([7302d76](https://github.com/medusajs/medusa/commit/7302d76e12683c989f340d2fcfaf4338dca6554a))
## [1.2.2](https://github.com/medusajs/medusa/compare/@medusajs/medusa-js@1.2.0...@medusajs/medusa-js@1.2.2) (2022-06-19)
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@medusajs/medusa-js",
"version": "1.2.2",
"version": "1.2.3",
"description": "Client for Medusa Commerce Rest API",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -15,7 +15,7 @@
"author": "Oliver Juhl",
"license": "MIT",
"dependencies": {
"@medusajs/medusa": "^1.3.2",
"@medusajs/medusa": "^1.3.3",
"axios": "^0.24.0",
"form-data": "^4.0.0",
"qs": "^6.10.3",
@@ -0,0 +1,60 @@
import {
AdminBatchJobListRes,
AdminBatchJobRes,
AdminGetBatchParams,
AdminPostBatchesReq,
} from "@medusajs/medusa"
import qs from "qs"
import { ResponsePromise } from "../../typings"
import BaseResource from "../base"
import { stringifyNullProperties } from "../../utils"
class AdminBatchJobsResource extends BaseResource {
create(
payload: AdminPostBatchesReq,
customHeaders: Record<string, any> = {}
): ResponsePromise<AdminBatchJobRes> {
const path = `/admin/batch-jobs`
return this.client.request("POST", path, payload, {}, customHeaders)
}
list(
query?: AdminGetBatchParams,
customHeaders: Record<string, any> = {}
): ResponsePromise<AdminBatchJobListRes> {
let path = `/admin/batch-jobs`
if (query) {
const queryString = qs.stringify(stringifyNullProperties(query))
path = `/admin/batch-jobs?${queryString}`
}
return this.client.request("GET", path, {}, {}, customHeaders)
}
cancel(
batchJobId: string,
customHeaders: Record<string, any> = {}
): ResponsePromise<AdminBatchJobRes> {
const path = `/admin/batch-jobs/${batchJobId}/cancel`
return this.client.request("POST", path, {}, {}, customHeaders)
}
confirm(
batchJobId: string,
customHeaders: Record<string, any> = {}
): ResponsePromise<AdminBatchJobRes> {
const path = `/admin/batch-jobs/${batchJobId}/confirm`
return this.client.request("POST", path, {}, {}, customHeaders)
}
retrieve(
batchJobId: string,
customHeaders: Record<string, any> = {}
): ResponsePromise<AdminBatchJobRes> {
const path = `/admin/batch-jobs/${batchJobId}`
return this.client.request("GET", path, {}, {}, customHeaders)
}
}
export default AdminBatchJobsResource
+17 -15
View File
@@ -1,33 +1,35 @@
import BaseResource from "../base"
import AdminAuthResource from "./auth"
import AdminCustomersResource from "./customers"
import AdminCustomerGroupsResource from "./customer-groups"
import AdminDiscountsResource from "./discounts"
import AdminBatchJobsResource from "./batch-jobs"
import CollectionsResource from "./collections"
import AdminCustomerGroupsResource from "./customer-groups"
import AdminCustomersResource from "./customers"
import AdminDiscountsResource from "./discounts"
import AdminDraftOrdersResource from "./draft-orders"
import AdminGiftCardsResource from "./gift-cards"
import AdminInvitesResource from "./invites"
import AdminNotesResource from "./notes"
import AdminProductsResource from "./products"
import AdminProductTypesResource from "./product-types"
import AdminUsersResource from "./users"
import AdminReturnsResource from "./returns"
import AdminNotificationsResource from "./notifications"
import AdminOrdersResource from "./orders"
import AdminPriceListResource from "./price-lists"
import AdminProductTagsResource from "./product-tags"
import AdminProductTypesResource from "./product-types"
import AdminProductsResource from "./products"
import AdminRegionsResource from "./regions"
import AdminReturnReasonsResource from "./return-reasons"
import AdminVariantsResource from "./variants"
import AdminSwapsResource from "./swaps"
import AdminTaxRatesResource from "./tax-rates"
import AdminReturnsResource from "./returns"
import AdminShippingOptionsResource from "./shipping-options"
import AdminShippingProfilesResource from "./shipping-profiles"
import AdminStoresResource from "./store"
import AdminShippingOptionsResource from "./shipping-options"
import AdminRegionsResource from "./regions"
import AdminNotificationsResource from "./notifications"
import AdminSwapsResource from "./swaps"
import AdminTaxRatesResource from "./tax-rates"
import AdminUploadsResource from "./uploads"
import AdminProductTagsResource from "./product-tags"
import AdminPriceListResource from "./price-lists"
import AdminUsersResource from "./users"
import AdminVariantsResource from "./variants"
class Admin extends BaseResource {
public auth = new AdminAuthResource(this.client)
public batchJobs = new AdminBatchJobsResource(this.client)
public customers = new AdminCustomersResource(this.client)
public customerGroups = new AdminCustomerGroupsResource(this.client)
public discounts = new AdminDiscountsResource(this.client)
@@ -1,14 +1,21 @@
import { AdminUploadRes, IAdminPostUploadsFile } from "@medusajs/medusa"
import {
AdminDeleteUploadsReq,
IAdminPostUploadsFileReq,
AdminDeleteUploadsRes,
AdminPostUploadsDownloadUrlReq,
AdminUploadsDownloadUrlRes,
AdminUploadsRes,
} from "@medusajs/medusa"
import FormData from "form-data"
import { ResponsePromise } from "../../typings"
import BaseResource from "../base"
import FormData from "form-data"
class AdminUploadsResource extends BaseResource {
private headers = {
"Content-Type": "multipart/form-data",
}
create(file: IAdminPostUploadsFile): ResponsePromise<AdminUploadRes> {
create(file: IAdminPostUploadsFileReq): ResponsePromise<AdminUploadsRes> {
const path = `/admin/uploads`
const payload = new FormData()
@@ -16,6 +23,24 @@ class AdminUploadsResource extends BaseResource {
return this.client.request("POST", path, payload, {}, this.headers)
}
delete(
payload: AdminDeleteUploadsReq,
customHeaders: Record<string, any> = {}
): ResponsePromise<AdminDeleteUploadsRes> {
const path = `/admin/uploads`
return this.client.request("DELETE", path, payload, {}, customHeaders)
}
getPresignedDownloadUrl(
payload: AdminPostUploadsDownloadUrlReq,
customHeaders: Record<string, any> = {}
): ResponsePromise<AdminUploadsDownloadUrlRes> {
const path = `/admin/uploads/download-url`
return this.client.request("POST", path, payload, {}, customHeaders)
}
}
export default AdminUploadsResource
+21
View File
@@ -0,0 +1,21 @@
export function stringifyNullProperties<T extends object>(input: T): T {
const convertProperties = (obj: T) => {
const res = {} as T
Object.keys(obj).reduce((acc: T, key: string) => {
if (obj[key] === null) {
acc[key] = "null"
} else if (typeof obj[key] === "object") {
acc[key] = convertProperties(obj[key])
} else {
acc[key] = obj[key]
}
return acc
}, res)
return res
}
return convertProperties(input)
}
@@ -0,0 +1,31 @@
import { stringifyNullProperties } from "../../src/utils"
describe("stringifyNullProperties", () => {
test("returns empty object on no props", () => {
const result = stringifyNullProperties({})
expect(result).toEqual({})
})
test("successfully stringifies null property", () => {
const result = stringifyNullProperties({ test: null })
expect(result).toEqual({ test: "null" })
})
test("successfully stringifies nested null property", () => {
const result = stringifyNullProperties({
test: { test_2: { test_3: null } },
another_test: "test",
})
expect(result).toEqual({
test: { test_2: { test_3: "null" } },
another_test: "test",
})
})
test("successfully stringifies string property", () => {
const result = stringifyNullProperties({
test: "test",
})
expect(result).toEqual({ test: "test" })
})
})
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.2.3](https://github.com/medusajs/medusa/compare/medusa-payment-paypal@1.2.2...medusa-payment-paypal@1.2.3) (2022-07-05)
**Note:** Version bump only for package medusa-payment-paypal
## [1.2.2](https://github.com/medusajs/medusa/compare/medusa-payment-paypal@1.2.0...medusa-payment-paypal@1.2.2) (2022-06-19)
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "medusa-payment-paypal",
"version": "1.2.2",
"version": "1.2.3",
"description": "Paypal Payment provider for Meduas Commerce",
"main": "index.js",
"repository": {
@@ -26,7 +26,7 @@
"cross-env": "^5.2.1",
"eslint": "^6.8.0",
"jest": "^25.5.2",
"medusa-interfaces": "^1.3.0",
"medusa-interfaces": "^1.3.1",
"medusa-test-utils": "^1.1.37"
},
"scripts": {
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.41](https://github.com/medusajs/medusa/compare/medusa-payment-stripe@1.1.40...medusa-payment-stripe@1.1.41) (2022-07-05)
**Note:** Version bump only for package medusa-payment-stripe
## [1.1.40](https://github.com/medusajs/medusa/compare/medusa-payment-stripe@1.1.38...medusa-payment-stripe@1.1.40) (2022-06-19)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "medusa-payment-stripe",
"version": "1.1.40",
"version": "1.1.41",
"description": "Stripe Payment provider for Meduas Commerce",
"main": "index.js",
"repository": {
-13
View File
@@ -1,13 +0,0 @@
{
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/plugin-transform-instanceof",
"@babel/plugin-transform-classes"
],
"presets": ["@babel/preset-env"],
"env": {
"test": {
"plugins": ["@babel/plugin-transform-runtime"]
}
}
}
-15
View File
@@ -1,15 +0,0 @@
/lib
node_modules
.DS_store
.env*
/*.js
!index.js
/dist
/api
/services
/models
/subscribers
/loaders
@@ -1,8 +0,0 @@
/lib
node_modules
.DS_store
.env*
/*.js
!index.js
yarn.lock
/src
-222
View File
@@ -1,222 +0,0 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.2.0](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.37...medusa-plugin-add-ons@1.2.0) (2022-05-01)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.37](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.36...medusa-plugin-add-ons@1.1.37) (2022-01-11)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.36](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.35...medusa-plugin-add-ons@1.1.36) (2021-12-29)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.35](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.34...medusa-plugin-add-ons@1.1.35) (2021-12-17)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.34](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.33...medusa-plugin-add-ons@1.1.34) (2021-12-08)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.33](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.32...medusa-plugin-add-ons@1.1.33) (2021-11-23)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.32](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.31...medusa-plugin-add-ons@1.1.32) (2021-11-22)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.31](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.30...medusa-plugin-add-ons@1.1.31) (2021-11-19)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.30](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.29...medusa-plugin-add-ons@1.1.30) (2021-11-19)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.29](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.28...medusa-plugin-add-ons@1.1.29) (2021-10-18)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.28](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.27...medusa-plugin-add-ons@1.1.28) (2021-10-18)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.27](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.25...medusa-plugin-add-ons@1.1.27) (2021-10-18)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.26](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.25...medusa-plugin-add-ons@1.1.26) (2021-10-18)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.25](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.24...medusa-plugin-add-ons@1.1.25) (2021-09-15)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.24](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.23...medusa-plugin-add-ons@1.1.24) (2021-09-14)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.23](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.22...medusa-plugin-add-ons@1.1.23) (2021-08-05)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.22](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.21...medusa-plugin-add-ons@1.1.22) (2021-07-26)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.21](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.19...medusa-plugin-add-ons@1.1.21) (2021-07-15)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.20](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.19...medusa-plugin-add-ons@1.1.20) (2021-07-15)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.19](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.18...medusa-plugin-add-ons@1.1.19) (2021-07-02)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.18](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.17...medusa-plugin-add-ons@1.1.18) (2021-06-22)
### Bug Fixes
- release assist ([668e8a7](https://github.com/medusajs/medusa/commit/668e8a740200847fc2a41c91d2979097f1392532))
## [1.1.17](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.16...medusa-plugin-add-ons@1.1.17) (2021-06-09)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.16](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.15...medusa-plugin-add-ons@1.1.16) (2021-06-09)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.15](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.14...medusa-plugin-add-ons@1.1.15) (2021-06-09)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.14](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.13...medusa-plugin-add-ons@1.1.14) (2021-06-09)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.13](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.12...medusa-plugin-add-ons@1.1.13) (2021-06-08)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.12](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.9...medusa-plugin-add-ons@1.1.12) (2021-04-28)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.11](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.10...medusa-plugin-add-ons@1.1.11) (2021-04-20)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.10](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.9...medusa-plugin-add-ons@1.1.10) (2021-04-20)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.9](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.8...medusa-plugin-add-ons@1.1.9) (2021-04-13)
### Bug Fixes
- merge develop ([2982a8e](https://github.com/medusajs/medusa/commit/2982a8e682e90beb4549d969d9d3b04d78a46a2d))
- merge develop ([a468c45](https://github.com/medusajs/medusa/commit/a468c451e82c68f41b5005a2e480057f6124aaa6))
## [1.1.8](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.7...medusa-plugin-add-ons@1.1.8) (2021-04-13)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.7](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.6...medusa-plugin-add-ons@1.1.7) (2021-03-30)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.6](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.5...medusa-plugin-add-ons@1.1.6) (2021-03-17)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.5](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.3...medusa-plugin-add-ons@1.1.5) (2021-03-17)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.4](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.3...medusa-plugin-add-ons@1.1.4) (2021-03-17)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.3](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.2...medusa-plugin-add-ons@1.1.3) (2021-02-17)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.2](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.1...medusa-plugin-add-ons@1.1.2) (2021-02-03)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.1.1](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.1.0...medusa-plugin-add-ons@1.1.1) (2021-01-27)
**Note:** Version bump only for package medusa-plugin-add-ons
# [1.1.0](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.0.8...medusa-plugin-add-ons@1.1.0) (2021-01-26)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.0.8](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.0.7...medusa-plugin-add-ons@1.0.8) (2020-12-17)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.0.7](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.0.6...medusa-plugin-add-ons@1.0.7) (2020-11-24)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.0.6](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.0.5...medusa-plugin-add-ons@1.0.6) (2020-10-19)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.0.5](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.0.4...medusa-plugin-add-ons@1.0.5) (2020-10-12)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.0.4](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.0.3...medusa-plugin-add-ons@1.0.4) (2020-10-09)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.0.3](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.0.2...medusa-plugin-add-ons@1.0.3) (2020-10-05)
### Bug Fixes
- **medusa-plugin-add-ons:** fixes add-on decorator ([5071f36](https://github.com/medusajs/medusa/commit/5071f362e4e140d11a1342a5058e8ad2efaa1ed4))
- **medusa-plugin-addon:** Fixes admin endpoints, Adds flag to avoid merging add-on line-items ([d8483cd](https://github.com/medusajs/medusa/commit/d8483cd1352ecc587112723786b7c31882f9416e))
## [1.0.2](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.0.1...medusa-plugin-add-ons@1.0.2) (2020-09-09)
**Note:** Version bump only for package medusa-plugin-add-ons
## [1.0.1](https://github.com/medusajs/medusa/compare/medusa-plugin-add-ons@1.0.0...medusa-plugin-add-ons@1.0.1) (2020-09-09)
**Note:** Version bump only for package medusa-plugin-add-ons
# 1.0.0 (2020-09-09)
### Features
- **plugins:** Adds add-on plugin ([3de1e6d](https://github.com/medusajs/medusa/commit/3de1e6dd4ad4a2a48d4d8116ebdd011efce2b22a))
-1
View File
@@ -1 +0,0 @@
// noop
@@ -1,44 +0,0 @@
{
"name": "medusa-plugin-add-ons",
"version": "1.2.0",
"description": "Add-on plugin for Medusa Commerce",
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/medusajs/medusa",
"directory": "packages/medusa-plugin-add-ons"
},
"author": "Oliver Juhl",
"license": "AGPL-3.0-or-later",
"devDependencies": {
"@babel/cli": "^7.7.5",
"@babel/core": "^7.7.5",
"@babel/node": "^7.7.4",
"@babel/plugin-proposal-class-properties": "^7.7.4",
"@babel/plugin-transform-classes": "^7.9.5",
"@babel/plugin-transform-instanceof": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.7.6",
"@babel/preset-env": "^7.7.5",
"@babel/register": "^7.7.4",
"@babel/runtime": "^7.9.6",
"client-sessions": "^0.8.0",
"cross-env": "^7.0.2",
"eslint": "^6.8.0",
"jest": "^25.5.2",
"medusa-test-utils": "^1.1.37"
},
"scripts": {
"build": "babel src -d . --ignore **/__tests__",
"prepare": "cross-env NODE_ENV=production npm run build",
"watch": "babel -w src --out-dir . --ignore **/__tests__",
"test": "jest"
},
"dependencies": {
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"medusa-core-utils": "^1.1.31",
"redis": "^3.0.2"
},
"gitHead": "81a7ff73d012fda722f6e9ef0bd9ba0232d37808"
}
@@ -1,12 +0,0 @@
import { Router } from "express"
import admin from "./routes/admin"
import store from "./routes/store"
export default (rootDirectory) => {
const app = Router()
store(app, rootDirectory)
admin(app, rootDirectory)
return app
}
@@ -1 +0,0 @@
export default (fn) => (...args) => fn(...args).catch(args[2])
@@ -1,5 +0,0 @@
import { default as wrap } from "./await-middleware"
export default {
wrap,
}
@@ -1,29 +0,0 @@
import { Validator, MedusaError } from "medusa-core-utils"
export default async (req, res) => {
const schema = Validator.object().keys({
name: Validator.string().required(),
prices: Validator.array()
.items({
currency_code: Validator.string(),
amount: Validator.number(),
})
.required(),
valid_for: Validator.array().items(),
metadata: Validator.object().optional(),
})
const { value, error } = schema.validate(req.body)
if (error) {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const addOnService = req.scope.resolve("addOnService")
const addOn = await addOnService.create(value)
res.status(200).json({ addOn })
} catch (err) {
throw err
}
}
@@ -1,16 +0,0 @@
export default async (req, res) => {
const { id } = req.params
const addOnService = req.scope.resolve("addOnService")
try {
await addOnService.delete(id)
res.status(200).send({
id,
object: "addOn",
deleted: true,
})
} catch (err) {
throw err
}
}
@@ -1,17 +0,0 @@
export default async (req, res) => {
const { id } = req.params
try {
const addOnService = req.scope.resolve("addOnService")
let addOn = await addOnService.retrieve(id)
addOn = await addOnService.decorate(
addOn,
["name", "valid_for", "prices"],
["valid_for"]
)
res.json({ add_on: addOn })
} catch (err) {
throw err
}
}
@@ -1,55 +0,0 @@
import { Router } from "express"
import bodyParser from "body-parser"
import cors from "cors"
import middlewares from "../../middlewares"
import { getConfigFile } from "medusa-core-utils"
const route = Router()
export default (app, rootDirectory) => {
const { configModule } = getConfigFile(rootDirectory, `medusa-config`)
const config = (configModule && configModule.projectConfig) || {}
const adminCors = config.admin_cors || ""
route.use(
cors({
origin: adminCors.split(","),
credentials: true,
})
)
app.use("/admin", route)
route.post(
"/add-ons",
bodyParser.json(),
middlewares.wrap(require("./create-add-on").default)
)
route.post(
"/add-ons/:id",
bodyParser.json(),
middlewares.wrap(require("./update-add-on").default)
)
route.get(
"/add-ons",
bodyParser.json(),
middlewares.wrap(require("./list-add-ons").default)
)
route.get(
"/add-ons/:id",
bodyParser.json(),
middlewares.wrap(require("./get-add-on").default)
)
route.delete(
"/add-ons/:id",
bodyParser.json(),
middlewares.wrap(require("./delete-add-on").default)
)
return app
}
@@ -1,20 +0,0 @@
export default async (req, res) => {
try {
const addOnService = req.scope.resolve("addOnService")
let addOns = await addOnService.list({})
addOns = await Promise.all(
addOns.map((ao) =>
addOnService.decorate(
ao,
["name", "valid_for", "prices"],
["valid_for"]
)
)
)
res.status(200).json({ add_ons: addOns })
} catch (err) {
console.log(err)
throw err
}
}
@@ -1,39 +0,0 @@
import { Validator, MedusaError } from "medusa-core-utils"
export default async (req, res) => {
const { id } = req.params
const schema = Validator.object().keys({
name: Validator.string().optional(),
prices: Validator.array()
.items({
currency_code: Validator.string().required(),
amount: Validator.number().required(),
})
.optional(),
valid_for: Validator.array().optional(),
metadata: Validator.object().optional(),
})
const { value, error } = schema.validate(req.body)
if (error) {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const addOnService = req.scope.resolve("addOnService")
if (value.metadata) {
Object.entries(value.metadata).map(([key, value]) => {
addOnService.setMetadata(id, key, value)
})
delete value.metadata
}
const addOn = await addOnService.update(id, value)
res.status(200).json({ addOn })
} catch (err) {
throw err
}
}
@@ -1,39 +0,0 @@
import { Validator, MedusaError } from "medusa-core-utils"
export default async (req, res) => {
const { id } = req.params
const schema = Validator.object().keys({
variant_id: Validator.string().required(),
quantity: Validator.number().required(),
add_ons: Validator.array().items(Validator.string()).optional(),
metadata: Validator.object().optional(),
})
const { value, error } = schema.validate(req.body)
if (error) {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const lineItemService = req.scope.resolve("addOnLineItemService")
const cartService = req.scope.resolve("cartService")
let cart = await cartService.retrieve(id)
const lineItem = await lineItemService.generate(
value.variant_id,
cart.region_id,
value.quantity,
value.add_ons,
value.metadata
)
cart = await cartService.addLineItem(cart._id, lineItem)
cart = await cartService.decorate(cart, [], ["region"])
res.status(200).json({ cart })
} catch (err) {
throw err
}
}
@@ -1,27 +0,0 @@
import { Validator } from "medusa-core-utils"
export default async (req, res) => {
const schema = Validator.object({
product_id: Validator.string().required(),
})
const { value, error } = schema.validate(region_id)
if (error) {
throw error
}
try {
const addOnService = req.scope.resolve("addOnService")
let addOn = await addOnService.retrieveByProduct(value.product_id)
addOn = await addOnService.decorate(
addOn,
["name", "valid_for", "prices"],
["valid_for"]
)
res.json({ add_on: addOn })
} catch (err) {
throw err
}
}
@@ -1,37 +0,0 @@
import { Router } from "express"
import bodyParser from "body-parser"
import cors from "cors"
import middlewares from "../../middlewares"
import { getConfigFile } from "medusa-core-utils"
const route = Router()
export default (app, rootDirectory) => {
const { configModule } = getConfigFile(rootDirectory, `medusa-config`)
const config = (configModule && configModule.projectConfig) || {}
const storeCors = config.store_cors || ""
route.use(
cors({
origin: storeCors.split(","),
credentials: true,
})
)
app.use("/store", route)
route.post(
"/carts/:id/line-items/add-on",
bodyParser.json(),
middlewares.wrap(require("./create-line-item").default)
)
route.post(
"/carts/:id/line-items/:line_id/add-on",
bodyParser.json(),
middlewares.wrap(require("./update-line-item").default)
)
return app
}
@@ -1,52 +0,0 @@
import { Validator, MedusaError } from "medusa-core-utils"
export default async (req, res) => {
const { id, line_id } = req.params
const schema = Validator.object().keys({
add_ons: Validator.array().items(Validator.string()).optional(),
quantity: Validator.number().optional(),
metadata: Validator.object().optional(),
})
const { value, error } = schema.validate(req.body)
if (error) {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const lineItemService = req.scope.resolve("addOnLineItemService")
const cartService = req.scope.resolve("cartService")
let cart
if (value.quantity === 0) {
cart = await cartService.removeLineItem(id, line_id)
} else {
cart = await cartService.retrieve(id)
const existing = cart.items.find((i) => i._id.equals(line_id))
if (!existing) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"Could not find the line item"
)
}
const lineItem = await lineItemService.generate(
existing.content.variant._id,
cart.region_id,
value.quantity,
value.add_ons,
value.metadata
)
cart = await cartService.updateLineItem(cart._id, line_id, lineItem)
}
cart = await cartService.decorate(cart, [], ["region"])
res.status(200).json({ cart })
} catch (err) {
throw err
}
}
@@ -1,26 +0,0 @@
export default (container, config) => {
const cartService = container.resolve("cartService")
const addOnLineItemService = container.resolve("addOnLineItemService")
cartService.addDecorator(async (cart) => {
try {
cart.items = await Promise.all(
cart.items.map((item) => {
if (item.metadata && item.metadata.add_ons) {
return addOnLineItemService.decorate(
item,
["title", "quantity", "thumbnail", "content", "should_merge"],
["add_ons"]
)
} else {
return item
}
})
)
return cart
} catch (error) {
return cart
}
})
}
@@ -1,46 +0,0 @@
import { IdMap } from "medusa-test-utils"
export const addOns = {
testAddOn: {
_id: IdMap.getId("test-add-on"),
name: "Chili",
prices: [
{
currency_code: "DKK",
amount: 20,
},
],
valid_for: [IdMap.getId("test-product")],
},
testAddOn2: {
_id: IdMap.getId("test-add-on-2"),
name: "Chili",
prices: [
{
currency_code: "DKK",
amount: 20,
},
],
valid_for: [IdMap.getId("test-product")],
},
}
export const AddOnModelMock = {
create: jest.fn().mockReturnValue(Promise.resolve()),
find: jest.fn().mockImplementation((query) => {
return Promise.resolve([addOns.testAddOn, addOns.testAddOn2])
}),
updateOne: jest.fn().mockImplementation((query, update) => {
return Promise.resolve()
}),
deleteOne: jest.fn().mockReturnValue(Promise.resolve()),
findOne: jest.fn().mockImplementation((query) => {
if (query._id === IdMap.getId("test-add-on")) {
return Promise.resolve(addOns.testAddOn)
}
if (query._id === IdMap.getId("test-add-on-2")) {
return Promise.resolve(addOns.testAddOn2)
}
return Promise.resolve(undefined)
}),
}
@@ -1,15 +0,0 @@
import mongoose from "mongoose"
import { BaseModel } from "medusa-interfaces"
class AddOnModel extends BaseModel {
static modelName = "AddOn"
static schema = {
name: { type: String, required: true },
prices: { type: [], required: true },
// Valid products
valid_for: { type: [String], required: true },
metadata: { type: mongoose.Schema.Types.Mixed, default: {} },
}
}
export default AddOnModel
@@ -1,70 +0,0 @@
import { IdMap } from "medusa-test-utils"
export const addOns = {
testAddOn: {
_id: IdMap.getId("test-add-on"),
name: "Chili",
prices: [
{
currency_code: "DKK",
amount: 20,
},
],
valid_for: [IdMap.getId("test-product")],
},
testAddOn2: {
_id: IdMap.getId("test-add-on-2"),
name: "Chili",
prices: [
{
currency_code: "DKK",
amount: 20,
},
],
valid_for: [IdMap.getId("test-product")],
},
testAddOn3: {
_id: IdMap.getId("test-add-on-3"),
name: "Herbs",
prices: [
{
currency_code: "DKK",
amount: 20,
},
],
valid_for: [],
},
}
export const AddOnServiceMock = {
retrieve: jest.fn().mockImplementation((addOnId) => {
if (addOnId === IdMap.getId("test-add-on")) {
return Promise.resolve(addOns.testAddOn)
}
if (addOnId === IdMap.getId("test-add-on-2")) {
return Promise.resolve(addOns.testAddOn2)
}
if (addOnId === IdMap.getId("test-add-on-3")) {
return Promise.resolve(addOns.testAddOn3)
}
return Promise.resolve(undefined)
}),
getRegionPrice: jest.fn().mockImplementation((addOnId, regionId) => {
if (addOnId === IdMap.getId("test-add-on")) {
return Promise.resolve(20)
}
if (addOnId === IdMap.getId("test-add-on-2")) {
return Promise.resolve(20)
}
if (addOnId === IdMap.getId("test-add-on-3")) {
return Promise.resolve(20)
}
return Promise.resolve(undefined)
}),
}
const mock = jest.fn().mockImplementation(() => {
return AddOnServiceMock
})
export default mock
@@ -1,10 +0,0 @@
export const EventBusServiceMock = {
emit: jest.fn(),
subscribe: jest.fn(),
}
const mock = jest.fn().mockImplementation(() => {
return EventBusServiceMock
})
export default mock
@@ -1,94 +0,0 @@
import { IdMap } from "medusa-test-utils"
const variant1 = {
_id: IdMap.getId("test-variant-1"),
title: "variant1",
options: [],
}
const variant2 = {
_id: IdMap.getId("test-variant-2"),
title: "variant2",
options: [
{
option_id: IdMap.getId("color_id"),
value: "black",
},
{
option_id: IdMap.getId("size_id"),
value: "160",
},
],
}
const variant3 = {
_id: IdMap.getId("test-variant-3"),
title: "variant3",
options: [
{
option_id: IdMap.getId("color_id"),
value: "blue",
},
{
option_id: IdMap.getId("size_id"),
value: "150",
},
],
}
const variant4 = {
_id: IdMap.getId("test-variant-4"),
title: "variant4",
options: [
{
option_id: IdMap.getId("color_id"),
value: "blue",
},
{
option_id: IdMap.getId("size_id"),
value: "50",
},
],
}
export const variants = {
one: variant1,
two: variant2,
three: variant3,
four: variant4,
}
export const ProductVariantServiceMock = {
retrieve: jest.fn().mockImplementation((variantId) => {
if (variantId === IdMap.getId("test-variant-1")) {
return Promise.resolve(variant1)
}
if (variantId === IdMap.getId("test-variant-2")) {
return Promise.resolve(variant2)
}
if (variantId === IdMap.getId("test-variant-3")) {
return Promise.resolve(variant3)
}
if (variantId === IdMap.getId("test-variant-4")) {
return Promise.resolve(variant4)
}
return Promise.resolve(undefined)
}),
getRegionPrice: jest.fn().mockImplementation((variantId, context) => {
if (variantId === IdMap.getId("test-variant-1")) {
if (context.regionId === IdMap.getId("world")) {
return Promise.resolve(10)
} else {
return Promise.resolve(20)
}
}
return Promise.reject(new Error("Not found"))
}),
}
const mock = jest.fn().mockImplementation(() => {
return ProductVariantServiceMock
})
export default mock
@@ -1,39 +0,0 @@
import { IdMap } from "medusa-test-utils"
export const products = {
product1: {
_id: IdMap.getId("test-product"),
description: "Test description",
title: "Product 1",
variants: [IdMap.getId("test-variant-1")],
// metadata: {
// add_ons: [IdMap.getId("test-add-on"), IdMap.getId("test-add-on-2")],
// },
},
product2: {
_id: IdMap.getId("test-product-2"),
title: "Product 2",
metadata: {},
},
}
export const ProductServiceMock = {
retrieve: jest.fn().mockImplementation((productId) => {
if (productId === IdMap.getId("test-product")) {
return Promise.resolve(products.product1)
}
if (productId === IdMap.getId("test-product-2")) {
return Promise.resolve(products.product2)
}
return Promise.resolve(undefined)
}),
list: jest.fn().mockImplementation((query) => {
return Promise.resolve([products.product1])
}),
}
const mock = jest.fn().mockImplementation(() => {
return ProductServiceMock
})
export default mock
@@ -1,28 +0,0 @@
import { IdMap } from "medusa-test-utils"
export const regions = {
testRegion: {
_id: IdMap.getId("world"),
name: "Test Region",
countries: ["DK", "US", "DE"],
tax_rate: 0.25,
payment_providers: ["default_provider", "unregistered"],
fulfillment_providers: ["test_shipper"],
currency_code: "DKK",
},
}
export const RegionServiceMock = {
retrieve: jest.fn().mockImplementation((regionId) => {
if (regionId === IdMap.getId("world")) {
return Promise.resolve(regions.testRegion)
}
throw Error(regionId + "not found")
}),
}
const mock = jest.fn().mockImplementation(() => {
return RegionServiceMock
})
export default mock
@@ -1,106 +0,0 @@
import { IdMap } from "medusa-test-utils"
import AddOnLineItemService from "../add-on-line-item"
import { ProductVariantServiceMock } from "../__mocks__/product-variant"
import { ProductServiceMock } from "../__mocks__/product"
import { RegionServiceMock } from "../__mocks__/region"
import { AddOnServiceMock } from "../__mocks__/add-on"
describe("LineItemService", () => {
describe("generate", () => {
let result
const lineItemService = new AddOnLineItemService({
addOnService: AddOnServiceMock,
productVariantService: ProductVariantServiceMock,
productService: ProductServiceMock,
regionService: RegionServiceMock,
})
beforeAll(async () => {
jest.clearAllMocks()
})
it("generates line item and successfully calculates full unit_price", async () => {
result = await lineItemService.generate(
IdMap.getId("test-variant-1"),
IdMap.getId("world"),
1,
[IdMap.getId("test-add-on"), IdMap.getId("test-add-on-2")]
)
expect(result).toEqual({
title: "Product 1",
thumbnail: undefined,
should_merge: false,
content: {
unit_price: 50,
variant: {
_id: IdMap.getId("test-variant-1"),
title: "variant1",
options: [],
},
product: {
_id: IdMap.getId("test-product"),
description: "Test description",
title: "Product 1",
variants: [IdMap.getId("test-variant-1")],
},
quantity: 1,
},
metadata: {
add_ons: [IdMap.getId("test-add-on"), IdMap.getId("test-add-on-2")],
},
quantity: 1,
})
})
it("generates line item and successfully calculates full unit_price for large quantity", async () => {
result = await lineItemService.generate(
IdMap.getId("test-variant-1"),
IdMap.getId("world"),
3,
[IdMap.getId("test-add-on"), IdMap.getId("test-add-on-2")]
)
expect(result).toEqual({
title: "Product 1",
thumbnail: undefined,
should_merge: false,
content: {
unit_price: 150,
variant: {
_id: IdMap.getId("test-variant-1"),
title: "variant1",
options: [],
},
product: {
_id: IdMap.getId("test-product"),
description: "Test description",
title: "Product 1",
variants: [IdMap.getId("test-variant-1")],
},
quantity: 1,
},
metadata: {
add_ons: [IdMap.getId("test-add-on"), IdMap.getId("test-add-on-2")],
},
quantity: 3,
})
})
it("fails if variant has no associated product", async () => {
try {
await lineItemService.generate(
IdMap.getId("test-variant-1"),
IdMap.getId("world"),
1,
[
IdMap.getId("test-add-on"),
IdMap.getId("test-add-on-2"),
IdMap.getId("test-add-on-3"),
]
)
} catch (err) {
expect(err.message).toBe(`Herbs can not be added to Product 1`)
}
})
})
})
@@ -1,134 +0,0 @@
import { IdMap } from "medusa-test-utils"
import { AddOnModelMock, addOns } from "../../models/__mocks__/add-on"
import AddOnService from "../add-on"
import { EventBusServiceMock } from "../__mocks__/event-bus"
import { ProductServiceMock } from "../__mocks__/product"
describe("AddOnService", () => {
describe("create", () => {
const addOnService = new AddOnService({
addOnModel: AddOnModelMock,
productService: ProductServiceMock,
eventBusService: EventBusServiceMock,
})
beforeEach(async () => {
jest.clearAllMocks()
})
it("calls model layer create", async () => {
await addOnService.create({
name: "Chili",
prices: [
{
currency_code: "DKK",
amount: 20,
},
],
valid_for: [IdMap.getId("test-product")],
})
expect(AddOnModelMock.create).toBeCalledTimes(1)
expect(AddOnModelMock.create).toBeCalledWith({
name: "Chili",
prices: [
{
currency_code: "DKK",
amount: 20,
},
],
valid_for: [IdMap.getId("test-product")],
})
})
})
describe("retrieve", () => {
let result
beforeAll(async () => {
jest.clearAllMocks()
const addOnService = new AddOnService({
addOnModel: AddOnModelMock,
})
result = await addOnService.retrieve(IdMap.getId("test-add-on"))
})
it("calls model layer retrieve", async () => {
expect(AddOnModelMock.findOne).toBeCalledTimes(1)
expect(AddOnModelMock.findOne).toBeCalledWith({
_id: IdMap.getId("test-add-on"),
})
})
it("returns the add-on", () => {
expect(result).toEqual(addOns.testAddOn)
})
})
describe("update", () => {
const addOnService = new AddOnService({
addOnModel: AddOnModelMock,
productService: ProductServiceMock,
eventBusService: EventBusServiceMock,
})
beforeEach(async () => {
jest.clearAllMocks()
})
it("calls model layer create", async () => {
await addOnService.update(IdMap.getId("test-add-on"), {
name: "Chili Spice",
valid_for: [IdMap.getId("test-product"), IdMap.getId("test-product-2")],
})
expect(AddOnModelMock.updateOne).toBeCalledTimes(1)
expect(AddOnModelMock.updateOne).toBeCalledWith(
{ _id: IdMap.getId("test-add-on") },
{
$set: {
name: "Chili Spice",
valid_for: [
IdMap.getId("test-product"),
IdMap.getId("test-product-2"),
],
},
},
{ runValidators: true }
)
})
})
describe("retrieveByProduct", () => {
describe("successful retrieval", () => {
let result
beforeAll(async () => {
jest.clearAllMocks()
const addOnService = new AddOnService({
addOnModel: AddOnModelMock,
productService: ProductServiceMock,
})
result = await addOnService.retrieveByProduct(
IdMap.getId("test-product")
)
})
it("calls ProductService retrieve", async () => {
expect(ProductServiceMock.retrieve).toBeCalledTimes(1)
expect(ProductServiceMock.retrieve).toBeCalledWith(
IdMap.getId("test-product")
)
})
it("calls model layer", () => {
expect(AddOnModelMock.find).toBeCalledTimes(1)
expect(AddOnModelMock.find).toBeCalledWith({
valid_for: IdMap.getId("test-product"),
})
})
it("returns the add-ons", () => {
expect(result).toEqual([addOns.testAddOn, addOns.testAddOn2])
})
})
})
})
@@ -1,120 +0,0 @@
import _ from "lodash"
import { BaseService } from "medusa-interfaces"
import { Validator, MedusaError } from "medusa-core-utils"
class AddOnLineItemService extends BaseService {
static Events = {
UPDATED: "add_on.updated",
CREATED: "add_on.created",
}
constructor(
{
addOnService,
productService,
productVariantService,
regionService,
eventBusService,
},
options
) {
super()
this.addOnService_ = addOnService
this.productService_ = productService
this.productVariantService_ = productVariantService
this.regionService_ = regionService
this.eventBus_ = eventBusService
this.options_ = options
}
/**
* Generates a line item.
* @param {string} variantId - id of the line item variant
* @param {*} regionId - id of the cart region
* @param {*} quantity - number of items
* @param {[string]} addOnIds - id of add-ons
*/
async generate(variantId, regionId, quantity, addOnIds, metadata = {}) {
const variant = await this.productVariantService_.retrieve(variantId)
const region = await this.regionService_.retrieve(regionId)
const products = await this.productService_.list({ variants: variantId })
// this should never fail, since a variant must have a product associated
// with it to exists, but better safe than sorry
if (!products.length) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`Could not find product for variant with id: ${variantId}`
)
}
const product = products[0]
let unitPrice = await this.productVariantService_.getRegionPrice(
variant._id,
{regionId: region._id}
)
const addOnPrices = await Promise.all(
addOnIds.map(async (id) => {
const addOn = await this.addOnService_.retrieve(id)
// Check if any of the add-ons can't be added to the product
if (!addOn.valid_for.includes(`${product._id}`)) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`${addOn.name} can not be added to ${product.title}`
)
} else {
return await this.addOnService_.getRegionPrice(id, region._id)
}
})
)
unitPrice += _.sum(addOnPrices)
const line = {
title: product.title,
quantity,
thumbnail: product.thumbnail,
should_merge: false,
content: {
unit_price: unitPrice * quantity,
variant,
product,
quantity: 1,
},
should_merge: false,
metadata: {
...metadata,
add_ons: addOnIds,
},
}
return line
}
async decorate(lineItem, fields, expandFields = []) {
const requiredFields = ["_id", "metadata"]
const decorated = _.pick(lineItem, fields.concat(requiredFields))
if (
expandFields.includes("add_ons") &&
decorated.metadata &&
decorated.metadata.add_ons
) {
decorated.metadata.add_ons = await Promise.all(
decorated.metadata.add_ons.map(
async (ao) => await this.addOnService_.retrieve(ao)
)
)
}
return decorated
}
}
export default AddOnLineItemService
@@ -1,244 +0,0 @@
import _ from "lodash"
import { BaseService } from "medusa-interfaces"
import { Validator, MedusaError } from "medusa-core-utils"
class AddOnService extends BaseService {
static Events = {
UPDATED: "add_on.updated",
CREATED: "add_on.created",
}
constructor(
{
addOnModel,
productService,
productVariantService,
regionService,
eventBusService,
},
options
) {
super()
this.addOnModel_ = addOnModel
this.productService_ = productService
this.productVariantService_ = productVariantService
this.regionService_ = regionService
this.eventBus_ = eventBusService
this.options_ = options
}
/**
* Used to validate add-on ids. Throws an error if the cast fails
* @param {string} rawId - the raw add-on id to validate.
* @return {string} the validated id
*/
validateId_(rawId) {
return rawId
}
/**
* @param {Object} selector - the query object for find
* @return {Promise} the result of the find operation
*/
list(selector, offset, limit) {
return this.addOnModel_.find(selector, {}, offset, limit)
}
/**
* Gets an add-on by id.
* @param {string} addOnId - the id of the add-on to get.
* @return {Promise<AddOn>} the add-on document.
*/
async retrieve(addOnId) {
const validatedId = this.validateId_(addOnId)
const addOn = await this.addOnModel_
.findOne({ _id: validatedId })
.catch((err) => {
throw new MedusaError(MedusaError.Types.DB_ERROR, err.message)
})
if (!addOn) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`Add-on with ${addOnId} was not found`
)
}
return addOn
}
/**
* Creates an add-on.
* @param {object} addOn - the add-on to create
* @return {Promise} resolves to the creation result.
*/
async create(addOn) {
await Promise.all(
addOn.valid_for.map((prodId) => {
this.productService_.retrieve(prodId)
})
)
return this.addOnModel_
.create(addOn)
.then((result) => {
this.eventBus_.emit(AddOnService.Events.CREATED, result)
return result
})
.catch((err) => {
throw new MedusaError(MedusaError.Types.DB_ERROR, err.message)
})
}
/**
* Deletes an add-on.
* @param {object} addOnId - the add-on to delete
* @return {Promise} resolves to the deletion result.
*/
async delete(addOnId) {
const addOn = await this.retrieve(addOnId)
return this.addOnModel_.deleteOne({ _id: addOn._id })
}
/**
* Retrieves all valid add-ons for a given product.
* @param {object} productId - the product id to find add-ons for
* @return {Promise} returns a promise containing all add-ons for the product
*/
async retrieveByProduct(productId) {
const product = await this.productService_.retrieve(productId)
return this.addOnModel_.find({ valid_for: product._id })
}
/**
* Updates an add-on. Metadata updates should use dedicated methods, e.g.
* `setMetadata`, etc. The function will throw errors if metadata updates
* are attempted.
* @param {string} addOnId - the id of the add-on. Must be a string that
* can be casted to an ObjectId
* @param {object} update - an object with the update values.
* @return {Promise} resolves to the update result.
*/
async update(addOnId, update) {
const validatedId = this.validateId_(addOnId)
await Promise.all(
update.valid_for.map((prodId) => {
this.productService_.retrieve(prodId)
})
)
if (update.metadata) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"Use setMetadata to update metadata fields"
)
}
return this.addOnModel_
.updateOne(
{ _id: validatedId },
{ $set: update },
{ runValidators: true }
)
.catch((err) => {
throw new MedusaError(MedusaError.Types.DB_ERROR, err.message)
})
}
/**
* Gets the price specific to a region. If no region specific money amount
* exists the function will try to use a currency price. If no default
* currency price exists the function will throw an error.
* @param {string} addOnId - the id of the add-on to get price from
* @param {string} regionId - the id of the region to get price for
* @return {number} the price specific to the region
*/
async getRegionPrice(addOnId, regionId) {
const addOn = await this.retrieve(addOnId)
const region = await this.regionService_.retrieve(regionId)
let price
addOn.prices.forEach(({ amount, currency_code }) => {
if (!price && currency_code === region.currency_code) {
// If we haven't yet found a price and the current money amount is
// the default money amount for the currency of the region we have found
// a possible price match
price = amount
} else if (region_id === region._id) {
// If the region matches directly with the money amount this is the best
// price
price = amount
}
})
// Return the price if we found a suitable match
if (price !== undefined) {
return price
}
// If we got this far no price could be found for the region
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`A price for region: ${region.name} could not be found`
)
}
/**
* Decorates a add-on with add-on variants.
* @param {AddOn} addOn - the add-on to decorate.
* @param {string[]} fields - the fields to include.
* @param {string[]} expandFields - fields to expand.
* @return {AddOn} return the decorated add-on.
*/
async decorate(addOn, fields, expandFields = []) {
const requiredFields = ["_id", "metadata"]
const decorated = _.pick(addOn, fields.concat(requiredFields))
if (expandFields.includes("valid_for")) {
decorated.valid_for = await Promise.all(
decorated.valid_for.map(
async (p) => await this.productService_.retrieve(p)
)
)
}
return decorated
}
/**
* Dedicated method to set metadata for an add-on.
* To ensure that plugins does not overwrite each
* others metadata fields, setMetadata is provided.
* @param {string} addOnId - the add-on to decorate.
* @param {string} key - key for metadata field
* @param {string} value - value for metadata field.
* @return {Promise} resolves to the updated result.
*/
async setMetadata(addOnId, key, value) {
const validatedId = this.validateId_(addOnId)
if (typeof key !== "string") {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
"Key type is invalid. Metadata keys must be strings"
)
}
const keyPath = `metadata.${key}`
return this.addOnModel_
.updateOne({ _id: validatedId }, { $set: { [keyPath]: value } })
.then((result) => {
this.eventBus_.emit(AddOnService.Events.UPDATED, result)
return result
})
.catch((err) => {
throw new MedusaError(MedusaError.Types.DB_ERROR, err.message)
})
}
}
export default AddOnService
File diff suppressed because it is too large. Load diff
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.2.3](https://github.com/medusajs/medusa/compare/medusa-plugin-algolia@0.2.2...medusa-plugin-algolia@0.2.3) (2022-07-05)
**Note:** Version bump only for package medusa-plugin-algolia
## [0.2.2](https://github.com/medusajs/medusa/compare/medusa-plugin-algolia@0.2.0...medusa-plugin-algolia@0.2.2) (2022-06-19)
**Note:** Version bump only for package medusa-plugin-algolia
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "medusa-plugin-algolia",
"version": "0.2.2",
"version": "0.2.3",
"description": "Search support for algolia",
"main": "index.js",
"repository": {
@@ -25,7 +25,7 @@
"body-parser": "^1.19.0",
"lodash": "^4.17.21",
"medusa-core-utils": "^1.1.31",
"medusa-interfaces": "^1.3.0"
"medusa-interfaces": "^1.3.1"
},
"devDependencies": {
"@babel/cli": "^7.7.5",
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.3.1](https://github.com/medusajs/medusa/compare/medusa-plugin-brightpearl@1.3.0...medusa-plugin-brightpearl@1.3.1) (2022-07-05)
**Note:** Version bump only for package medusa-plugin-brightpearl
# [1.3.0](https://github.com/medusajs/medusa/compare/medusa-plugin-brightpearl@1.2.1...medusa-plugin-brightpearl@1.3.0) (2022-05-01)
**Note:** Version bump only for package medusa-plugin-brightpearl
@@ -1,6 +1,6 @@
{
"name": "medusa-plugin-brightpearl",
"version": "1.3.0",
"version": "1.3.1",
"description": "Brightpearl plugin for Medusa Commerce",
"main": "index.js",
"repository": {
@@ -27,7 +27,7 @@
"cross-env": "^7.0.2",
"eslint": "^6.8.0",
"jest": "^25.5.2",
"medusa-interfaces": "^1.3.0",
"medusa-interfaces": "^1.3.1",
"medusa-test-utils": "^1.1.37",
"prettier": "^2.0.5"
},
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.2.3](https://github.com/medusajs/medusa/compare/medusa-plugin-contentful@1.2.2...medusa-plugin-contentful@1.2.3) (2022-07-05)
**Note:** Version bump only for package medusa-plugin-contentful
## [1.2.2](https://github.com/medusajs/medusa/compare/medusa-plugin-contentful@1.2.0...medusa-plugin-contentful@1.2.2) (2022-06-19)
**Note:** Version bump only for package medusa-plugin-contentful
@@ -1,6 +1,6 @@
{
"name": "medusa-plugin-contentful",
"version": "1.2.2",
"version": "1.2.3",
"description": "Contentful plugin for Medusa Commerce",
"main": "index.js",
"repository": {
@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.2.1](https://github.com/medusajs/medusa/compare/medusa-plugin-ip-lookup@1.2.0...medusa-plugin-ip-lookup@1.2.1) (2022-07-05)
### Bug Fixes
* **medusa:** Remove deps `mongoose` + `mongodb` ([#1218](https://github.com/medusajs/medusa/issues/1218)) ([c76e23e](https://github.com/medusajs/medusa/commit/c76e23e84dd8cb08c3c709f9f95c4c17b9685439))
# [1.2.0](https://github.com/medusajs/medusa/compare/medusa-plugin-ip-lookup@1.1.19...medusa-plugin-ip-lookup@1.2.0) (2022-05-01)
**Note:** Version bump only for package medusa-plugin-ip-lookup
@@ -1,6 +1,6 @@
{
"name": "medusa-plugin-ip-lookup",
"version": "1.2.0",
"version": "1.2.1",
"description": "IP lookup middleware for Medusa core",
"main": "dist/index.js",
"repository": {
@@ -32,8 +32,7 @@
"medusa-interfaces": "1.x"
},
"dependencies": {
"axios": "^0.20.0",
"mongoose": "^5.8.0"
"axios": "^0.20.0"
},
"gitHead": "41a5425405aea5045a26def95c0dc00cf4a5a44d"
}
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.42](https://github.com/medusajs/medusa/compare/medusa-plugin-mailchimp@1.1.41...medusa-plugin-mailchimp@1.1.42) (2022-07-05)
**Note:** Version bump only for package medusa-plugin-mailchimp
## [1.1.41](https://github.com/medusajs/medusa/compare/medusa-plugin-mailchimp@1.1.39...medusa-plugin-mailchimp@1.1.41) (2022-06-19)
**Note:** Version bump only for package medusa-plugin-mailchimp
@@ -1,6 +1,6 @@
{
"name": "medusa-plugin-mailchimp",
"version": "1.1.41",
"version": "1.1.42",
"description": "Mailchimp newsletter subscriptions",
"main": "index.js",
"repository": {
@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.2.3](https://github.com/medusajs/medusa/compare/medusa-plugin-meilisearch@0.2.2...medusa-plugin-meilisearch@0.2.3) (2022-07-05)
### Bug Fixes
* **meilisearch:** remove medusa-interfaces dependency ([#1751](https://github.com/medusajs/medusa/issues/1751)) ([f7e300e](https://github.com/medusajs/medusa/commit/f7e300e8cec082cab23626907333682e9a643238))
## [0.2.2](https://github.com/medusajs/medusa/compare/medusa-plugin-meilisearch@0.2.0...medusa-plugin-meilisearch@0.2.2) (2022-06-19)
**Note:** Version bump only for package medusa-plugin-meilisearch
@@ -1,6 +1,6 @@
{
"name": "medusa-plugin-meilisearch",
"version": "0.2.2",
"version": "0.2.3",
"description": "A starter for Medusa projects.",
"main": "index.js",
"repository": {
@@ -23,7 +23,6 @@
"body-parser": "^1.19.0",
"lodash": "^4.17.21",
"medusa-core-utils": "^1.1.31",
"medusa-interfaces": "^1.3.0",
"meilisearch": "^0.24.0"
},
"devDependencies": {
@@ -1,13 +0,0 @@
{
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/plugin-transform-classes",
"@babel/plugin-transform-instanceof"
],
"presets": ["@babel/preset-env"],
"env": {
"test": {
"plugins": ["@babel/plugin-transform-runtime"]
}
}
}
@@ -1,14 +0,0 @@
dist/
node_modules/
.DS_store
.env*
/*.js
!index.js
yarn.lock
yarn-error.log
/api
/services
/models
/subscribers
@@ -1,225 +0,0 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.37](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.36...medusa-plugin-permissions@1.1.37) (2022-01-11)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.36](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.35...medusa-plugin-permissions@1.1.36) (2021-12-29)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.35](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.34...medusa-plugin-permissions@1.1.35) (2021-12-17)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.34](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.33...medusa-plugin-permissions@1.1.34) (2021-12-08)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.33](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.32...medusa-plugin-permissions@1.1.33) (2021-11-23)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.32](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.31...medusa-plugin-permissions@1.1.32) (2021-11-22)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.31](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.30...medusa-plugin-permissions@1.1.31) (2021-11-19)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.30](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.29...medusa-plugin-permissions@1.1.30) (2021-11-19)
### Features
- Typescript for API layer ([#817](https://github.com/medusajs/medusa/issues/817)) ([373532e](https://github.com/medusajs/medusa/commit/373532ecbc8196f47e71af95a8cf82a14a4b1f9e))
## [1.1.29](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.28...medusa-plugin-permissions@1.1.29) (2021-10-18)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.28](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.27...medusa-plugin-permissions@1.1.28) (2021-10-18)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.27](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.25...medusa-plugin-permissions@1.1.27) (2021-10-18)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.26](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.25...medusa-plugin-permissions@1.1.26) (2021-10-18)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.25](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.24...medusa-plugin-permissions@1.1.25) (2021-09-15)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.24](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.23...medusa-plugin-permissions@1.1.24) (2021-09-14)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.23](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.22...medusa-plugin-permissions@1.1.23) (2021-08-05)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.22](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.21...medusa-plugin-permissions@1.1.22) (2021-07-26)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.21](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.19...medusa-plugin-permissions@1.1.21) (2021-07-15)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.20](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.19...medusa-plugin-permissions@1.1.20) (2021-07-15)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.19](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.18...medusa-plugin-permissions@1.1.19) (2021-07-02)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.18](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.17...medusa-plugin-permissions@1.1.18) (2021-06-22)
### Bug Fixes
- release assist ([668e8a7](https://github.com/medusajs/medusa/commit/668e8a740200847fc2a41c91d2979097f1392532))
## [1.1.17](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.16...medusa-plugin-permissions@1.1.17) (2021-06-09)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.16](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.15...medusa-plugin-permissions@1.1.16) (2021-06-09)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.15](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.14...medusa-plugin-permissions@1.1.15) (2021-06-09)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.14](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.13...medusa-plugin-permissions@1.1.14) (2021-06-09)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.13](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.12...medusa-plugin-permissions@1.1.13) (2021-06-08)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.12](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.9...medusa-plugin-permissions@1.1.12) (2021-04-28)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.11](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.10...medusa-plugin-permissions@1.1.11) (2021-04-20)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.10](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.9...medusa-plugin-permissions@1.1.10) (2021-04-20)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.9](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.8...medusa-plugin-permissions@1.1.9) (2021-04-13)
### Bug Fixes
- merge develop ([2982a8e](https://github.com/medusajs/medusa/commit/2982a8e682e90beb4549d969d9d3b04d78a46a2d))
- merge develop ([a468c45](https://github.com/medusajs/medusa/commit/a468c451e82c68f41b5005a2e480057f6124aaa6))
## [1.1.8](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.7...medusa-plugin-permissions@1.1.8) (2021-04-13)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.7](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.6...medusa-plugin-permissions@1.1.7) (2021-03-30)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.6](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.5...medusa-plugin-permissions@1.1.6) (2021-03-17)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.5](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.3...medusa-plugin-permissions@1.1.5) (2021-03-17)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.4](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.3...medusa-plugin-permissions@1.1.4) (2021-03-17)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.3](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.2...medusa-plugin-permissions@1.1.3) (2021-02-17)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.2](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.1...medusa-plugin-permissions@1.1.2) (2021-02-03)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.1.1](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.1.0...medusa-plugin-permissions@1.1.1) (2021-01-27)
**Note:** Version bump only for package medusa-plugin-permissions
# [1.1.0](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.0.13...medusa-plugin-permissions@1.1.0) (2021-01-26)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.0.13](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.0.12...medusa-plugin-permissions@1.0.13) (2020-12-17)
**Note:** Version bump only for package medusa-plugin-permissions
## [1.0.12](https://github.com/medusajs/medusa/compare/medusa-plugin-permissions@1.0.11...medusa-plugin-permissions@1.0.12) (2020-11-24)
**Note:** Version bump only for package medusa-plugin-permissions
## 1.0.11 (2020-10-19)
## 1.0.10 (2020-09-09)
### Bug Fixes
- updates license ([db519fb](https://github.com/medusajs/medusa/commit/db519fbaa6f8ad02c19cbecba5d4f28ba1ee81aa))
## 1.0.7 (2020-09-07)
## 1.0.1 (2020-09-05)
## 1.0.1-beta.0 (2020-09-04)
# 1.0.0 (2020-09-03)
# 1.0.0-alpha.30 (2020-08-28)
# 1.0.0-alpha.27 (2020-08-27)
# 1.0.0-alpha.26 (2020-08-27)
# 1.0.0-alpha.24 (2020-08-27)
# 1.0.0-alpha.3 (2020-08-20)
# 1.0.0-alpha.2 (2020-08-20)
# 1.0.0-alpha.1 (2020-08-20)
# 1.0.0-alpha.0 (2020-08-20)
### Reverts
- Revert "[medusa-interfaces] : Adds decorator functionality to BaseService (#39)" (#41) ([2273cc5](https://github.com/medusajs/medusa/commit/2273cc519ad4d6ae16157173aba3955d16745e1d)), closes [#39](https://github.com/medusajs/medusa/issues/39) [#41](https://github.com/medusajs/medusa/issues/41)
## [1.0.10](https://github.com/medusajs/medusa/compare/v1.0.9...v1.0.10) (2020-09-09)
### Bug Fixes
- updates license ([db519fb](https://github.com/medusajs/medusa/commit/db519fbaa6f8ad02c19cbecba5d4f28ba1ee81aa))
@@ -1,40 +0,0 @@
{
"name": "medusa-plugin-permissions",
"version": "1.1.37",
"description": "Role permission for Medusa core",
"main": "dist/index.js",
"repository": {
"type": "git",
"url": "https://github.com/medusajs/medusa",
"directory": "packages/medusa-plugin-permissions"
},
"scripts": {
"build": "babel src --out-dir . --ignore **/__tests__",
"prepare": "cross-env NODE_ENV=production npm run build",
"watch": "babel -w src --out-dir . --ignore **/__tests__",
"test": "jest"
},
"author": "Oliver Juhl",
"license": "MIT",
"devDependencies": {
"@babel/cli": "^7.7.5",
"@babel/core": "^7.7.5",
"@babel/plugin-proposal-class-properties": "^7.7.4",
"@babel/plugin-transform-classes": "^7.9.5",
"@babel/plugin-transform-instanceof": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.7.6",
"@babel/preset-env": "^7.7.5",
"@babel/runtime": "^7.7.6",
"cross-env": "^5.2.1",
"jest": "^25.5.2"
},
"peerDependencies": {
"medusa-interfaces": "1.x"
},
"dependencies": {
"medusa-core-utils": "^1.1.31",
"medusa-test-utils": "^1.1.37",
"mongoose": "^5.8.0"
},
"gitHead": "c46300d58fbfd0b2dc2c02745ae143e6247e885b"
}
@@ -1,16 +0,0 @@
// This middleware is injected to ensure authorization of requests
// Since this middleware uses the user object on the request, this should be
// injected after authentication in the core middleware, hence we name
// the middleware postAuth.
export default {
postAuthentication: () => {
return (err, req, res, next) => {
const permissionService = req.scope.resolve("permissionService")
if (permissionService.hasPermission(req.user, req.method, req.path)) {
next()
} else {
res.status(422)
}
}
}
}
@@ -1,36 +0,0 @@
import { IdMap } from "medusa-test-utils"
export const permissions = {
productEditorPermission: {
_id: IdMap.getId("product_editor"),
name: "product_editor",
permissions: [
{
method: "POST",
endpoint: "/products",
},
{
method: "GET",
endpoint: "/products",
},
{
method: "PUT",
endpoint: "/products",
},
],
},
}
export const RoleModelMock = {
create: jest.fn().mockReturnValue(Promise.resolve()),
deleteOne: jest.fn().mockReturnValue(Promise.resolve()),
findOne: jest.fn().mockImplementation(query => {
if (query.name === "product_editor") {
return Promise.resolve(permissions.productEditorPermission)
}
return Promise.resolve(undefined)
}),
updateOne: jest.fn().mockImplementation((query, update) => {
return Promise.resolve()
}),
}
@@ -1,13 +0,0 @@
import { BaseModel } from "medusa-interfaces"
import PermissionSchema from "./schemas/permission"
class RoleModel extends BaseModel {
static modelName = "Role"
static schema = {
name: { type: String, required: true, unique: true },
permissions: { type: [PermissionSchema], required: true, default: [] },
}
}
export default RoleModel
@@ -1,6 +0,0 @@
import mongoose from "mongoose"
export default new mongoose.Schema({
method: { type: String },
endpoint: { type: String },
})
@@ -1,162 +0,0 @@
import { BaseService } from "medusa-interfaces"
import { Validator, MedusaError } from "medusa-core-utils"
class PermissionService extends BaseService {
constructor({ userService, roleModel }) {
super()
/** @private @const {UserService} */
this.userService_ = userService
/** @private @const {RoleModel} */
this.roleModel_ = roleModel
}
validatePermission_(permission) {
const schema = Validator.object({
method: Validator.string().valid(
"POST",
"GET",
"PUT",
"PATCH",
"DELETE",
"CONNECT",
"OPTIONS",
"HEAD",
"TRACE"
),
endpoint: Validator.string(),
})
const { value, error } = schema.validate(permission)
if (error) {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
"Permission is not valid"
)
}
return value
}
async retrieveRole(name) {
const role = await this.roleModel_.findOne({ name }).catch((err) => {
throw new MedusaError(MedusaError.Types.DB_ERROR, err.message)
})
if (!role) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`${name} does not exist. Use method createRole to create it.`
)
}
return role
}
async hasPermission(user, method, endpoint) {
if (!user) return false
for (let i = 0; i < user.metadata.roles.length; i++) {
const role = user.metadata.roles[i]
const permissions = await this.retrieveRole(role)
return permissions.permissions.some((action) => {
return action.method === method && action.endpoint === endpoint
})
}
return false
}
async createRole(roleName, permissions) {
const validatedPermissions = permissions.map((permission) =>
this.validatePermission_(permission)
)
return this.retrieveRole(roleName)
.then((role) => {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
`${role.name} already exists`
)
})
.catch((error) => {
if (error.name === MedusaError.Types.NOT_FOUND) {
return this.roleModel_.create({
name: roleName,
permissions: validatedPermissions,
})
} else {
throw error
}
})
}
async deleteRole(roleName) {
const role = await this.retrieve(roleName)
// Delete is idempotent, but we return a promise to allow then-chaining
if (!role) {
return Promise.resolve()
}
return this.roleModel_
.deleteOne({
_id: role._id,
})
.catch((err) => {
throw new MedusaError(MedusaError.Types.DB_ERROR, err.message)
})
}
async addPermission(roleName, permission) {
const role = await this.retrieveRole(roleName)
const validatedPermission = this.validatePermission_(permission)
return this.roleModel_.updateOne(
{ _id: role._id },
{ $push: { permissions: validatedPermission } }
)
}
async removePermission(roleName, permission) {
const role = await this.retrieveRole(roleName)
const validatedPermission = this.validatePermission_(permission)
return this.roleModel_.updateOne(
{ _id: role._id },
{ $pull: { permissions: validatedPermission } }
)
}
async grantRole(userId, roleName) {
const role = await this.retrieveRole(roleName)
const user = await this.userService_.retrieve(userId)
if (!user.metadata.roles) {
return this.userService_.setMetadata(userId, "roles", [roleName])
}
if (user.metadata.roles.includes(role.name)) {
throw new MedusaError(
MedusaError.Types.DB_ERROR,
`User already has role: ${role.name}`
)
}
user.metadata.roles.push(roleName)
return this.userService_.setMetadata(userId, "roles", user.metadata.roles)
}
async revokeRole(userId, roleName) {
const user = await this.userService_.retrieve(userId)
if (!user.metadata.roles || !user.metadata.roles.includes(roleName)) {
// revokeRole is idempotent, we return a promise to allow then-chaining
return Promise.resolve()
}
// remove role from metadata.roles
const newRoles = user.metadata.roles.filter((r) => r !== roleName)
return this.userService_.setMetadata(userId, "roles", newRoles)
}
}
export default PermissionService
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.3.3](https://github.com/medusajs/medusa/compare/medusa-plugin-sendgrid@1.3.2...medusa-plugin-sendgrid@1.3.3) (2022-07-05)
**Note:** Version bump only for package medusa-plugin-sendgrid
## [1.3.2](https://github.com/medusajs/medusa/compare/medusa-plugin-sendgrid@1.3.0...medusa-plugin-sendgrid@1.3.2) (2022-06-19)
**Note:** Version bump only for package medusa-plugin-sendgrid
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "medusa-plugin-sendgrid",
"version": "1.3.2",
"version": "1.3.3",
"description": "SendGrid transactional emails",
"main": "index.js",
"repository": {
Loaded 100 of 400 files, more files were not shown because too many files have changed in this diff. Show more