Merge branch 'develop' into feat/draft-orders
This commit is contained in:
34 files changed
+879
-7196
No files matched your search
@@ -1,10 +1,6 @@
|
||||
import { spawn, execSync } from "child_process"
|
||||
import mongoose from "mongoose"
|
||||
import chokidar from "chokidar"
|
||||
import express from "express"
|
||||
import path from "path"
|
||||
|
||||
import loaders from "../loaders"
|
||||
import Logger from "../loaders/logger"
|
||||
|
||||
export default async function({ port, directory }) {
|
||||
|
||||
@@ -1,136 +1,18 @@
|
||||
import { createConnection, MigrationExecutor } from "typeorm"
|
||||
import { spawn, execSync } from "child_process"
|
||||
import chokidar from "chokidar"
|
||||
import path from "path"
|
||||
import fs from "fs"
|
||||
import _ from "lodash"
|
||||
import { getConfigFile, createRequireFromPath } from "medusa-core-utils"
|
||||
import { sync as existsSync } from "fs-exists-cached"
|
||||
import { createConnection } from "typeorm"
|
||||
import { getConfigFile } from "medusa-core-utils"
|
||||
|
||||
import loaders from "../loaders"
|
||||
import Logger from "../loaders/logger"
|
||||
|
||||
function createFileContentHash(path, files) {
|
||||
return path + files
|
||||
}
|
||||
import getMigrations from "./utils/get-migrations"
|
||||
|
||||
// TODO: Create unique id for each plugin
|
||||
function createPluginId(name) {
|
||||
return name
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the correct path for the plugin. If it is a local plugin it will be
|
||||
* found in the plugins folder. Otherwise we will look for the plugin in the
|
||||
* installed npm packages.
|
||||
* @param {string} pluginName - the name of the plugin to find. Should match
|
||||
* the name of the folder where the plugin is contained.
|
||||
* @return {object} the plugin details
|
||||
*/
|
||||
function resolvePlugin(pluginName) {
|
||||
// Only find plugins when we're not given an absolute path
|
||||
if (!existsSync(pluginName)) {
|
||||
// Find the plugin in the local plugins folder
|
||||
const resolvedPath = path.resolve(`./plugins/${pluginName}`)
|
||||
|
||||
if (existsSync(resolvedPath)) {
|
||||
if (existsSync(`${resolvedPath}/package.json`)) {
|
||||
const packageJSON = JSON.parse(
|
||||
fs.readFileSync(`${resolvedPath}/package.json`, `utf-8`)
|
||||
)
|
||||
const name = packageJSON.name || pluginName
|
||||
//warnOnIncompatiblePeerDependency(name, packageJSON)
|
||||
|
||||
return {
|
||||
resolve: resolvedPath,
|
||||
name,
|
||||
id: createPluginId(name),
|
||||
options: {},
|
||||
version:
|
||||
packageJSON.version || createFileContentHash(resolvedPath, `**`),
|
||||
}
|
||||
} else {
|
||||
// Make package.json a requirement for local plugins too
|
||||
throw new Error(`Plugin ${pluginName} requires a package.json file`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rootDir = path.resolve(".")
|
||||
|
||||
/**
|
||||
* Here we have an absolute path to an internal plugin, or a name of a module
|
||||
* which should be located in node_modules.
|
||||
*/
|
||||
try {
|
||||
const requireSource =
|
||||
rootDir !== null
|
||||
? createRequireFromPath(`${rootDir}/:internal:`)
|
||||
: require
|
||||
|
||||
// If the path is absolute, resolve the directory of the internal plugin,
|
||||
// otherwise resolve the directory containing the package.json
|
||||
const resolvedPath = path.dirname(
|
||||
requireSource.resolve(`${pluginName}/package.json`)
|
||||
)
|
||||
|
||||
const packageJSON = JSON.parse(
|
||||
fs.readFileSync(`${resolvedPath}/package.json`, `utf-8`)
|
||||
)
|
||||
// warnOnIncompatiblePeerDependency(packageJSON.name, packageJSON)
|
||||
|
||||
return {
|
||||
resolve: resolvedPath,
|
||||
id: createPluginId(packageJSON.name),
|
||||
name: packageJSON.name,
|
||||
version: packageJSON.version,
|
||||
}
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`Unable to find plugin "${pluginName}". Perhaps you need to install its package?`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const t = async function({ port, directory }) {
|
||||
const t = async function({ directory }) {
|
||||
const args = process.argv
|
||||
args.shift()
|
||||
args.shift()
|
||||
args.shift()
|
||||
|
||||
const { configModule } = getConfigFile(directory, `medusa-config`)
|
||||
const { plugins } = configModule
|
||||
|
||||
const resolved = plugins.map(plugin => {
|
||||
if (_.isString(plugin)) {
|
||||
return resolvePlugin(plugin)
|
||||
}
|
||||
|
||||
const details = resolvePlugin(plugin.resolve)
|
||||
details.options = plugin.options
|
||||
|
||||
return details
|
||||
})
|
||||
|
||||
resolved.push({
|
||||
resolve: `${directory}/dist`,
|
||||
name: `project-plugin`,
|
||||
id: createPluginId(`project-plugin`),
|
||||
options: {},
|
||||
version: createFileContentHash(process.cwd(), `**`),
|
||||
})
|
||||
|
||||
const migrationDirs = []
|
||||
const coreMigrations = path.resolve(__dirname, "../migrations")
|
||||
|
||||
migrationDirs.push(`${coreMigrations}/*.js`)
|
||||
|
||||
for (const p of resolved) {
|
||||
const exists = existsSync(`${p.resolve}/migrations`)
|
||||
if (exists) {
|
||||
migrationDirs.push(`${p.resolve}/migrations/*.js`)
|
||||
}
|
||||
}
|
||||
const migrationDirs = getMigrations(directory)
|
||||
|
||||
const connection = await createConnection({
|
||||
type: configModule.projectConfig.database_type,
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
import path from "path"
|
||||
import fs from "fs"
|
||||
import express from "express"
|
||||
import { createConnection } from "typeorm"
|
||||
import { sync as existsSync } from "fs-exists-cached"
|
||||
import { getConfigFile } from "medusa-core-utils"
|
||||
|
||||
import Logger from "../loaders/logger"
|
||||
import loaders from "../loaders"
|
||||
|
||||
import getMigrations from "./utils/get-migrations"
|
||||
|
||||
const t = async function({ directory, migrate, seedFile }) {
|
||||
let resolvedPath = seedFile
|
||||
|
||||
// If we are already given an absolute path we can skip resolution step
|
||||
if (!existsSync(resolvedPath)) {
|
||||
resolvedPath = path.resolve(path.join(directory, seedFile))
|
||||
|
||||
if (!existsSync(resolvedPath)) {
|
||||
console.error(`Could not find a seed file at: ${seedFile}`)
|
||||
console.error(`Resolved path: ${resolvedPath}`)
|
||||
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
if (migrate) {
|
||||
const migrationDirs = getMigrations(directory)
|
||||
const { configModule } = getConfigFile(directory, `medusa-config`)
|
||||
const connection = await createConnection({
|
||||
type: configModule.projectConfig.database_type,
|
||||
url: configModule.projectConfig.database_url,
|
||||
extra: configModule.projectConfig.database_extra || {},
|
||||
migrations: migrationDirs,
|
||||
logging: true,
|
||||
})
|
||||
|
||||
await connection.runMigrations()
|
||||
await connection.close()
|
||||
Logger.info("Migrations completed.")
|
||||
}
|
||||
|
||||
const app = express()
|
||||
const { container } = await loaders({
|
||||
directory,
|
||||
expressApp: app,
|
||||
})
|
||||
|
||||
const manager = container.resolve("manager")
|
||||
|
||||
const storeService = container.resolve("storeService")
|
||||
const userService = container.resolve("userService")
|
||||
const regionService = container.resolve("regionService")
|
||||
const productService = container.resolve("productService")
|
||||
const productVariantService = container.resolve("productVariantService")
|
||||
const shippingOptionService = container.resolve("shippingOptionService")
|
||||
const shippingProfileService = container.resolve("shippingProfileService")
|
||||
|
||||
await manager.transaction(async tx => {
|
||||
const { store, regions, products, shipping_options, users } = JSON.parse(
|
||||
fs.readFileSync(resolvedPath, `utf-8`)
|
||||
)
|
||||
|
||||
const gcProfile = await shippingProfileService.retrieveGiftCardDefault()
|
||||
const defaultProfile = await shippingProfileService.retrieveDefault()
|
||||
|
||||
if (store) {
|
||||
await storeService.withTransaction(tx).update(store)
|
||||
}
|
||||
|
||||
for (const u of users) {
|
||||
let pass = u.password
|
||||
if (pass) {
|
||||
delete u.password
|
||||
}
|
||||
await userService.withTransaction(tx).create(u, pass)
|
||||
}
|
||||
|
||||
let regionIds = {}
|
||||
for (const r of regions) {
|
||||
let dummyId
|
||||
if (!r.id || !r.id.startsWith("reg_")) {
|
||||
dummyId = r.id
|
||||
delete r.id
|
||||
}
|
||||
|
||||
const reg = await regionService.withTransaction(tx).create(r)
|
||||
|
||||
if (dummyId) {
|
||||
regionIds[dummyId] = reg.id
|
||||
}
|
||||
}
|
||||
|
||||
for (const so of shipping_options) {
|
||||
if (regionIds[so.region_id]) {
|
||||
so.region_id = regionIds[so.region_id]
|
||||
}
|
||||
|
||||
so.profile_id = defaultProfile.id
|
||||
if (so.is_giftcard) {
|
||||
so.profile_id = gcProfile.id
|
||||
delete so.is_giftcard
|
||||
}
|
||||
|
||||
await shippingOptionService.withTransaction(tx).create(so)
|
||||
}
|
||||
|
||||
for (const p of products) {
|
||||
const variants = p.variants
|
||||
delete p.variants
|
||||
|
||||
p.profile_id = defaultProfile.id
|
||||
if (p.is_giftcard) {
|
||||
p.profile_id = gcProfile.id
|
||||
}
|
||||
|
||||
const newProd = await productService.withTransaction(tx).create(p)
|
||||
|
||||
if (variants && variants.length) {
|
||||
const optionIds = p.options.map(
|
||||
o => newProd.options.find(newO => newO.title === o.title).id
|
||||
)
|
||||
|
||||
for (const v of variants) {
|
||||
const variant = {
|
||||
...v,
|
||||
options: v.options.map((o, index) => ({
|
||||
...o,
|
||||
option_id: optionIds[index],
|
||||
})),
|
||||
}
|
||||
|
||||
await productVariantService
|
||||
.withTransaction(tx)
|
||||
.create(newProd.id, variant)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default t
|
||||
@@ -1,10 +1,7 @@
|
||||
import "core-js/stable"
|
||||
import "regenerator-runtime/runtime"
|
||||
|
||||
import mongoose from "mongoose"
|
||||
import chokidar from "chokidar"
|
||||
import express from "express"
|
||||
import cwdResolve from "resolve-cwd"
|
||||
|
||||
import loaders from "../loaders"
|
||||
import Logger from "../loaders/logger"
|
||||
|
||||
@@ -1,23 +1,19 @@
|
||||
import "core-js/stable"
|
||||
import "regenerator-runtime/runtime"
|
||||
|
||||
import mongoose from "mongoose"
|
||||
import chokidar from "chokidar"
|
||||
import express from "express"
|
||||
import cwdResolve from "resolve-cwd"
|
||||
|
||||
import loaders from "../loaders"
|
||||
import Logger from "../loaders/logger"
|
||||
|
||||
export default async function({ directory, email, password }) {
|
||||
export default async function({ directory, id, email, password }) {
|
||||
const app = express()
|
||||
const { container, dbConnection } = await loaders({
|
||||
const { container } = await loaders({
|
||||
directory,
|
||||
expressApp: app,
|
||||
})
|
||||
|
||||
const userService = container.resolve("userService")
|
||||
const user = await userService.create({ email }, password)
|
||||
await userService.create({ id, email }, password)
|
||||
|
||||
process.exit()
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
import path from "path"
|
||||
import fs from "fs"
|
||||
import { isString } from "lodash"
|
||||
import { sync as existsSync } from "fs-exists-cached"
|
||||
import { getConfigFile, createRequireFromPath } from "medusa-core-utils"
|
||||
|
||||
function createFileContentHash(path, files) {
|
||||
return path + files
|
||||
}
|
||||
|
||||
// TODO: Create unique id for each plugin
|
||||
function createPluginId(name) {
|
||||
return name
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the correct path for the plugin. If it is a local plugin it will be
|
||||
* found in the plugins folder. Otherwise we will look for the plugin in the
|
||||
* installed npm packages.
|
||||
* @param {string} pluginName - the name of the plugin to find. Should match
|
||||
* the name of the folder where the plugin is contained.
|
||||
* @return {object} the plugin details
|
||||
*/
|
||||
function resolvePlugin(pluginName) {
|
||||
// Only find plugins when we're not given an absolute path
|
||||
if (!existsSync(pluginName)) {
|
||||
// Find the plugin in the local plugins folder
|
||||
const resolvedPath = path.resolve(`./plugins/${pluginName}`)
|
||||
|
||||
if (existsSync(resolvedPath)) {
|
||||
if (existsSync(`${resolvedPath}/package.json`)) {
|
||||
const packageJSON = JSON.parse(
|
||||
fs.readFileSync(`${resolvedPath}/package.json`, `utf-8`)
|
||||
)
|
||||
const name = packageJSON.name || pluginName
|
||||
//warnOnIncompatiblePeerDependency(name, packageJSON)
|
||||
|
||||
return {
|
||||
resolve: resolvedPath,
|
||||
name,
|
||||
id: createPluginId(name),
|
||||
options: {},
|
||||
version:
|
||||
packageJSON.version || createFileContentHash(resolvedPath, `**`),
|
||||
}
|
||||
} else {
|
||||
// Make package.json a requirement for local plugins too
|
||||
throw new Error(`Plugin ${pluginName} requires a package.json file`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rootDir = path.resolve(".")
|
||||
|
||||
/**
|
||||
* Here we have an absolute path to an internal plugin, or a name of a module
|
||||
* which should be located in node_modules.
|
||||
*/
|
||||
try {
|
||||
const requireSource =
|
||||
rootDir !== null
|
||||
? createRequireFromPath(`${rootDir}/:internal:`)
|
||||
: require
|
||||
|
||||
// If the path is absolute, resolve the directory of the internal plugin,
|
||||
// otherwise resolve the directory containing the package.json
|
||||
const resolvedPath = path.dirname(
|
||||
requireSource.resolve(`${pluginName}/package.json`)
|
||||
)
|
||||
|
||||
const packageJSON = JSON.parse(
|
||||
fs.readFileSync(`${resolvedPath}/package.json`, `utf-8`)
|
||||
)
|
||||
// warnOnIncompatiblePeerDependency(packageJSON.name, packageJSON)
|
||||
|
||||
return {
|
||||
resolve: resolvedPath,
|
||||
id: createPluginId(packageJSON.name),
|
||||
name: packageJSON.name,
|
||||
version: packageJSON.version,
|
||||
}
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`Unable to find plugin "${pluginName}". Perhaps you need to install its package?`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default directory => {
|
||||
const { configModule } = getConfigFile(directory, `medusa-config`)
|
||||
const { plugins } = configModule
|
||||
|
||||
const resolved = plugins.map(plugin => {
|
||||
if (isString(plugin)) {
|
||||
return resolvePlugin(plugin)
|
||||
}
|
||||
|
||||
const details = resolvePlugin(plugin.resolve)
|
||||
details.options = plugin.options
|
||||
|
||||
return details
|
||||
})
|
||||
|
||||
resolved.push({
|
||||
resolve: `${directory}/dist`,
|
||||
name: `project-plugin`,
|
||||
id: createPluginId(`project-plugin`),
|
||||
options: {},
|
||||
version: createFileContentHash(process.cwd(), `**`),
|
||||
})
|
||||
|
||||
const migrationDirs = []
|
||||
const coreMigrations = path.resolve(
|
||||
path.join(__dirname, "..", "..", "migrations")
|
||||
)
|
||||
|
||||
migrationDirs.push(path.join(coreMigrations, "*.js"))
|
||||
|
||||
for (const p of resolved) {
|
||||
const exists = existsSync(`${p.resolve}/migrations`)
|
||||
if (exists) {
|
||||
migrationDirs.push(`${p.resolve}/migrations/*.js`)
|
||||
}
|
||||
}
|
||||
|
||||
return migrationDirs
|
||||
}
|
||||
@@ -3,6 +3,8 @@ import path from "path"
|
||||
import { EntitySchema } from "typeorm"
|
||||
import { asClass, asValue } from "awilix"
|
||||
|
||||
import formatRegistrationName from "../utils/format-registration-name"
|
||||
|
||||
/**
|
||||
* Registers all models in the model directory
|
||||
*/
|
||||
@@ -34,23 +36,3 @@ export default ({ container }, config = { register: true }) => {
|
||||
|
||||
return toReturn
|
||||
}
|
||||
|
||||
function formatRegistrationName(fn) {
|
||||
const offset = process.env.NODE_ENV === "test" ? 3 : 2
|
||||
|
||||
const descriptorIndex = fn.split(".").length - 2
|
||||
const descriptor = fn.split(".")[descriptorIndex]
|
||||
const splat = descriptor.split("/")
|
||||
const rawname = splat[splat.length - 1]
|
||||
const namespace = splat[splat.length - offset]
|
||||
const upperNamespace =
|
||||
namespace.charAt(0).toUpperCase() + namespace.slice(1, -1)
|
||||
|
||||
const parts = rawname.split("-").map((n, index) => {
|
||||
if (index !== 0) {
|
||||
return n.charAt(0).toUpperCase() + n.slice(1)
|
||||
}
|
||||
return n
|
||||
})
|
||||
return parts.join("") + upperNamespace
|
||||
}
|
||||
@@ -16,6 +16,8 @@ import fs from "fs"
|
||||
import { asValue, asClass, asFunction, aliasTo } from "awilix"
|
||||
import { sync as existsSync } from "fs-exists-cached"
|
||||
|
||||
import formatRegistrationName from "../utils/format-registration-name"
|
||||
|
||||
/**
|
||||
* Registers all services in the services directory
|
||||
*/
|
||||
@@ -360,29 +362,6 @@ function registerModels(pluginDetails, container) {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a filename into the correct container resolution name.
|
||||
* Names are camelCase formatted and namespaced by the folder i.e:
|
||||
* models/example-person -> examplePersonModel
|
||||
* @param {string} fn - the full path of the file
|
||||
* @return {string} the formatted name
|
||||
*/
|
||||
function formatRegistrationName(fn) {
|
||||
const descriptor = fn.split(".")[0]
|
||||
const splat = descriptor.split("/")
|
||||
const rawname = splat[splat.length - 1]
|
||||
const namespace = splat[splat.length - 2]
|
||||
const upperNamespace =
|
||||
namespace.charAt(0).toUpperCase() + namespace.slice(1, -1)
|
||||
const parts = rawname.split("-").map((n, index) => {
|
||||
if (index !== 0) {
|
||||
return n.charAt(0).toUpperCase() + n.slice(1)
|
||||
}
|
||||
return n
|
||||
})
|
||||
return parts.join("") + upperNamespace
|
||||
}
|
||||
|
||||
// TODO: Create unique id for each plugin
|
||||
function createPluginId(name) {
|
||||
return name
|
||||
|
||||
@@ -2,6 +2,8 @@ import glob from "glob"
|
||||
import path from "path"
|
||||
import { Lifetime, asClass, asValue } from "awilix"
|
||||
|
||||
import formatRegistrationName from "../utils/format-registration-name"
|
||||
|
||||
/**
|
||||
* Registers all models in the model directory
|
||||
*/
|
||||
@@ -23,23 +25,3 @@ export default ({ container }) => {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function formatRegistrationName(fn) {
|
||||
const offset = process.env.NODE_ENV === "test" ? 3 : 2
|
||||
|
||||
const descriptorIndex = fn.split(".").length - 2
|
||||
const descriptor = fn.split(".")[descriptorIndex]
|
||||
const splat = descriptor.split("/")
|
||||
const rawname = splat[splat.length - 1]
|
||||
const namespace = splat[splat.length - offset]
|
||||
const upperNamespace = "Repository"
|
||||
// namespace.charAt(0).toUpperCase() + namespace.slice(1, -1)
|
||||
|
||||
const parts = rawname.split("-").map((n, index) => {
|
||||
if (index !== 0) {
|
||||
return n.charAt(0).toUpperCase() + n.slice(1)
|
||||
}
|
||||
return n
|
||||
})
|
||||
return parts.join("") + upperNamespace
|
||||
}
|
||||
@@ -3,6 +3,8 @@ import glob from "glob"
|
||||
import path from "path"
|
||||
import { Lifetime, asFunction } from "awilix"
|
||||
|
||||
import formatRegistrationName from "../utils/format-registration-name"
|
||||
|
||||
/**
|
||||
* Registers all services in the services directory
|
||||
*/
|
||||
@@ -23,23 +25,3 @@ export default ({ container, configModule }) => {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function formatRegistrationName(fn) {
|
||||
const offset = process.env.NODE_ENV === "test" ? 3 : 2
|
||||
|
||||
const descriptorIndex = fn.split(".").length - 2
|
||||
const descriptor = fn.split(".")[descriptorIndex]
|
||||
const splat = descriptor.split("/")
|
||||
const rawname = splat[splat.length - 1]
|
||||
const namespace = splat[splat.length - offset]
|
||||
const upperNamespace =
|
||||
namespace.charAt(0).toUpperCase() + namespace.slice(1, -1)
|
||||
|
||||
const parts = rawname.split("-").map((n, index) => {
|
||||
if (index !== 0) {
|
||||
return n.charAt(0).toUpperCase() + n.slice(1)
|
||||
}
|
||||
return n
|
||||
})
|
||||
return parts.join("") + upperNamespace
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||
|
||||
export class nullablePassword1619108646647 implements MigrationInterface {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "user" ALTER COLUMN "password_hash" DROP NOT NULL`
|
||||
)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "user" ALTER COLUMN "password_hash" TYPE character varying, ALTER COLUMN "password_hash" NOT NULL`
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ export class User {
|
||||
@Column({ nullable: true })
|
||||
last_name: string
|
||||
|
||||
@Column()
|
||||
@Column({ nullable: true })
|
||||
password_hash: string
|
||||
|
||||
@Column({ nullable: true })
|
||||
|
||||
@@ -45,6 +45,9 @@ describe("RegionService", () => {
|
||||
})
|
||||
|
||||
const storeService = {
|
||||
withTransaction: function() {
|
||||
return this
|
||||
},
|
||||
retrieve: () => {
|
||||
return {
|
||||
id: IdMap.getId("test-store"),
|
||||
@@ -221,6 +224,9 @@ describe("RegionService", () => {
|
||||
})
|
||||
|
||||
const storeService = {
|
||||
withTransaction: function() {
|
||||
return this
|
||||
},
|
||||
retrieve: () => {
|
||||
return {
|
||||
id: IdMap.getId("test-store"),
|
||||
@@ -312,6 +318,9 @@ describe("RegionService", () => {
|
||||
})
|
||||
|
||||
const storeService = {
|
||||
withTransaction: function() {
|
||||
return this
|
||||
},
|
||||
retrieve: () => {
|
||||
return {
|
||||
id: IdMap.getId("test-store"),
|
||||
|
||||
@@ -359,6 +359,9 @@ describe("ShippingOptionService", () => {
|
||||
}
|
||||
|
||||
const regionService = {
|
||||
withTransaction: function() {
|
||||
return this
|
||||
},
|
||||
retrieve: () => {
|
||||
return Promise.resolve({ fulfillment_providers: [{ id: "provider" }] })
|
||||
},
|
||||
|
||||
@@ -40,6 +40,16 @@ class AuthService extends BaseService {
|
||||
* error: a string with the error message
|
||||
*/
|
||||
async authenticateAPIToken(token) {
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
try {
|
||||
const user = await this.userService_.retrieve(token)
|
||||
return {
|
||||
success: true,
|
||||
user,
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
try {
|
||||
const user = await this.userService_.retrieveByApiToken(token)
|
||||
return {
|
||||
|
||||
@@ -57,6 +57,7 @@ class RegionService extends BaseService {
|
||||
const cloned = new RegionService({
|
||||
manager: transactionManager,
|
||||
regionRepository: this.regionRepository_,
|
||||
currencyRepository: this.currencyRepository_,
|
||||
countryRepository: this.countryRepository_,
|
||||
storeService: this.storeService_,
|
||||
paymentProviderRepository: this.paymentProviderRepository_,
|
||||
@@ -114,7 +115,7 @@ class RegionService extends BaseService {
|
||||
regionObject[key] = value
|
||||
}
|
||||
|
||||
const created = await regionRepository.create(regionObject)
|
||||
const created = regionRepository.create(regionObject)
|
||||
const result = await regionRepository.save(created)
|
||||
return result
|
||||
})
|
||||
@@ -253,7 +254,9 @@ class RegionService extends BaseService {
|
||||
* @param {string} currencyCode - an ISO currency code
|
||||
*/
|
||||
async validateCurrency_(currencyCode) {
|
||||
const store = await this.storeService_.retrieve(["currencies"])
|
||||
const store = await this.storeService_
|
||||
.withTransaction(this.transactionManager_)
|
||||
.retrieve(["currencies"])
|
||||
|
||||
const storeCurrencies = store.currencies.map(curr => curr.code)
|
||||
|
||||
|
||||
@@ -323,9 +323,11 @@ class ShippingOptionService extends BaseService {
|
||||
const optionRepo = manager.getCustomRepository(this.optionRepository_)
|
||||
const option = await optionRepo.create(data)
|
||||
|
||||
const region = await this.regionService_.retrieve(option.region_id, {
|
||||
relations: ["fulfillment_providers"],
|
||||
})
|
||||
const region = await this.regionService_
|
||||
.withTransaction(manager)
|
||||
.retrieve(option.region_id, {
|
||||
relations: ["fulfillment_providers"],
|
||||
})
|
||||
|
||||
if (
|
||||
!region.fulfillment_providers.find(
|
||||
|
||||
@@ -153,9 +153,12 @@ class UserService extends BaseService {
|
||||
const userRepo = manager.getCustomRepository(this.userRepository_)
|
||||
|
||||
const validatedEmail = this.validateEmail_(user.email)
|
||||
const hashedPassword = await this.hashPassword_(password)
|
||||
if (password) {
|
||||
const hashedPassword = await this.hashPassword_(password)
|
||||
user.password_hash = hashedPassword
|
||||
}
|
||||
|
||||
user.email = validatedEmail
|
||||
user.password_hash = hashedPassword
|
||||
|
||||
const created = await userRepo.create(user)
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import path from "path"
|
||||
import formatRegistrationName from "../format-registration-name"
|
||||
|
||||
describe("formatRegistrationName", () => {
|
||||
const tests = [
|
||||
[["medusa-test-dir", "dist", "services", "my-test.js"], "myTestService"],
|
||||
[["medusa-test-dir", "dist", "services", "my.js"], "myService"],
|
||||
[["services", "my-quite-long-file.js"], "myQuiteLongFileService"],
|
||||
[
|
||||
["/", "Users", "seb", "com.medusa.js", "services", "dot.js"],
|
||||
"dotService",
|
||||
],
|
||||
[
|
||||
["/", "Users", "seb.rin", "com.medusa.js", "services", "dot.js"],
|
||||
"dotService",
|
||||
],
|
||||
[
|
||||
["/", "Users", "seb.rin", "com.medusa.js", "repositories", "dot.js"],
|
||||
"dotRepository",
|
||||
],
|
||||
[
|
||||
["/", "Users", "seb.rin", "com.medusa.js", "models", "dot.js"],
|
||||
"dotModel",
|
||||
],
|
||||
[["C:", "server", "services", "dot.js"], "dotService"],
|
||||
]
|
||||
|
||||
test.each(
|
||||
tests.map(([pathParts, expected]) => [path.join(...pathParts), expected])
|
||||
)("Service %s -> %s", (fn, expected) => {
|
||||
const res = formatRegistrationName(fn)
|
||||
expect(res).toEqual(expected)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,44 @@
|
||||
import path from "path"
|
||||
|
||||
/**
|
||||
* Formats a filename into the correct container resolution name.
|
||||
* Names are camelCase formatted and namespaced by the folder i.e:
|
||||
* models/example-person -> examplePersonModel
|
||||
* @param {string} fn - the full path of the file
|
||||
* @return {string} the formatted name
|
||||
*/
|
||||
function formatRegistrationName(fn) {
|
||||
const parsed = path.parse(fn)
|
||||
const parsedDir = path.parse(parsed.dir)
|
||||
|
||||
const rawname = parsed.name
|
||||
let namespace = parsedDir.name
|
||||
if (namespace.startsWith("__")) {
|
||||
const parsedCoreDir = path.parse(parsedDir.dir)
|
||||
namespace = parsedCoreDir.name
|
||||
}
|
||||
|
||||
switch (namespace) {
|
||||
// We strip the last character when adding the type of registration
|
||||
// this is a trick for plural "ies"
|
||||
case "repositories":
|
||||
namespace = "repositorys"
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
const upperNamespace =
|
||||
namespace.charAt(0).toUpperCase() + namespace.slice(1, -1)
|
||||
|
||||
const parts = rawname.split("-").map((n, index) => {
|
||||
if (index !== 0) {
|
||||
return n.charAt(0).toUpperCase() + n.slice(1)
|
||||
}
|
||||
return n
|
||||
})
|
||||
|
||||
return parts.join("") + upperNamespace
|
||||
}
|
||||
|
||||
export default formatRegistrationName
|
||||
Reference in new issue
Block a user