UNPKG

@fabrix/spool-cart

Version:

Spool - eCommerce Spool for Fabrix

358 lines (357 loc) 11.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const common_1 = require("@fabrix/fabrix/dist/common"); const spool_sequelize_1 = require("@fabrix/spool-sequelize"); const errors_1 = require("@fabrix/spool-sequelize/dist/errors"); const lodash_1 = require("lodash"); const enums_1 = require("../../enums"); class ShopResolver extends spool_sequelize_1.SequelizeResolver { batch(options, batch) { const self = this; options.limit = options.limit || 100; options.offset = options.offset || 0; options.regressive = options.regressive || false; const recursiveQuery = function (options) { let count = 0; return self.findAndCountAll(options) .then(results => { count = results.count; return batch(results.rows); }) .then(batched => { if (count >= (options.regressive ? options.limit : options.offset + options.limit)) { options.offset = options.regressive ? 0 : options.offset + options.limit; return recursiveQuery(options); } else { return Promise.resolve(); } }); }; return recursiveQuery(options); } resolveByInstance(shop, options = {}) { return Promise.resolve(shop); } resolveById(shop, options = {}) { return this.findById(shop.id, options) .then(resShop => { if (!resShop && options.reject !== false) { throw new errors_1.ModelError('E_NOT_FOUND', `Shop ${shop.id} not found`); } return resShop; }); } resolveByToken(shop, options = {}) { return this.findOne(this.app.services.SequelizeService.mergeOptionDefaults(options, { where: { token: shop.token } })) .then(resShop => { if (!resShop && options.reject !== false) { throw new errors_1.ModelError('E_NOT_FOUND', `Shop token ${shop.token} not found`); } return resShop; }); } resolveByHandle(shop, options = {}) { return this.findOne(this.app.services.SequelizeService.mergeOptionDefaults(options, { where: { handle: shop.handle } })) .then(resShop => { if (!resShop && options.reject !== false) { throw new errors_1.ModelError('E_NOT_FOUND', `Shop handle ${shop.handle} not found`); } return resShop; }); } resolveByNumber(shop, options = {}) { return this.findById(shop, options) .then(resShop => { if (!resShop && options.reject !== false) { throw new errors_1.ModelError('E_NOT_FOUND', `Shop ${shop.token} not found`); } return resShop; }); } resolveByString(shop, options = {}) { return this.findOne(this.app.services.SequelizeService.mergeOptionDefaults(options, { where: { code: shop } })) .then(resShop => { if (!resShop && options.reject !== false) { throw new errors_1.ModelError('E_NOT_FOUND', `Shop ${shop} not found`); } return resShop; }); } resolveDefault(options = {}) { return this.findOne({ transaction: options.transaction || null }) .then(resShop => { if (!resShop && options.reject !== false) { throw new errors_1.ModelError('E_NOT_FOUND', 'Shop not found'); } return resShop; }); } resolve(shop, options = {}) { const resolvers = { 'instance': shop instanceof this.instance, 'id': !!(shop && lodash_1.isObject(shop) && shop.id), 'token': !!(shop && lodash_1.isObject(shop) && shop.token), 'handle': !!(shop && lodash_1.isObject(shop) && shop.handle), 'number': !!(shop && lodash_1.isNumber(shop)), 'string': !!(shop && lodash_1.isString(shop)), 'default': options.default === true }; const type = Object.keys(resolvers).find((key) => resolvers[key]); switch (type) { case 'instance': { return this.resolveByInstance(shop, options); } case 'id': { return this.resolveById(shop, options); } case 'token': { return this.resolveByToken(shop, options); } case 'handle': { return this.resolveByHandle(shop, options); } case 'number': { return this.resolveByNumber(shop, options); } case 'string': { return this.resolveByString(shop, options); } case 'default': { return this.resolveDefault(options); } default: { const err = new Error(`Unable to resolve Shop ${shop}`); return Promise.reject(err); } } } transformShops(shops = [], options = {}) { const ShopModel = this; const Sequelize = ShopModel.sequelize; shops = shops.map(shop => { if (shop && lodash_1.isNumber(shop)) { return { id: shop }; } else if (shop && lodash_1.isString(shop)) { shop = { name: shop }; return shop; } else if (shop && lodash_1.isObject(shop)) { return shop; } }); shops = shops.filter(shop => shop); return Sequelize.Promise.mapSeries(shops, shop => { return ShopModel.findOne({ where: lodash_1.pick(shop, ['id', 'handle']), attributes: ['id', 'name', 'handle'], transaction: options.transaction || null }) .then(foundShop => { if (foundShop) { return lodash_1.extend(foundShop, shop); } else { return ShopModel.create(shop, { transaction: options.transaction || null }); } }); }); } } exports.ShopResolver = ShopResolver; class Shop extends common_1.FabrixModel { static get resolver() { return ShopResolver; } static config(app, Sequelize) { return { options: { underscored: true, enums: { UNITS: enums_1.UNITS }, scopes: { live: { where: { live_mode: true } } }, hooks: { beforeValidate: [ (shop, options) => { if (!shop.handle && shop.name) { shop.handle = shop.name; } } ] } } }; } static schema(app, Sequelize) { return { name: { type: Sequelize.STRING, allowNull: false }, handle: { type: Sequelize.STRING, allowNull: false, unique: true, set: function (val) { this.setDataValue('handle', app.services.ProxyCartService.handle(val)); } }, phone: { type: Sequelize.STRING }, primary_locale: { type: Sequelize.STRING, defaultValue: 'en-us', allowNull: false }, address_id: { type: Sequelize.INTEGER }, currency: { type: Sequelize.STRING, defaultValue: 'USD', allowNull: false }, host: { type: Sequelize.STRING, allowNull: false }, email: { type: Sequelize.STRING, validate: { isEmail: true } }, money_format: { type: Sequelize.STRING, defaultValue: '$', allowNull: false }, money_with_currency_format: { type: Sequelize.STRING, defaultValue: '$ USD', allowNull: false }, tax_shipping: { type: Sequelize.BOOLEAN, defaultValue: false }, taxes_included: { type: Sequelize.BOOLEAN, defaultValue: false }, county_taxes: { type: Sequelize.BOOLEAN }, timezone: { type: Sequelize.STRING, defaultValue: '(GMT-05:00) Eastern Time', allowNull: false }, iana_timezone: { type: Sequelize.STRING, defaultValue: 'America/New_York', allowNull: false }, weight_unit: { type: Sequelize.ENUM, values: Object.values(enums_1.UNITS), defaultValue: enums_1.UNITS.G }, live_mode: { type: Sequelize.BOOLEAN, defaultValue: app.config.get('cart.live_mode') } }; } static associate(models) { models.Shop.belongsTo(models.Address, { as: 'address' }); models.Shop.belongsToMany(models.Address, { as: 'addresses', foreignKey: 'model_id', through: { model: models.ItemAddress, scope: { model: 'shop' }, constraints: false }, constraints: false }); models.Shop.hasMany(models.Cart, { as: 'carts', foreignKey: 'shop_id' }); models.Shop.belongsToMany(models.Order, { as: 'orders', through: { model: models.ShopOrder, unique: true, }, foreignKey: 'shop_id' }); models.Shop.hasMany(models.OrderItem, { as: 'order_items', foreignKey: 'shop_id' }); models.Shop.belongsToMany(models.Product, { as: 'products', through: { model: models.ShopProduct, foreignKey: 'shop_id', unique: false, }, }); models.Shop.belongsToMany(models.ProductVariant, { as: 'variants', through: { model: models.ShopProduct, foreignKey: 'shop_id', unique: false, }, }); models.Shop.belongsToMany(models.User, { as: 'users', through: { model: models.ShopUser, unique: true, }, foreignKey: 'shop_id' }); models.Shop.belongsToMany(models.Customer, { as: 'customers', through: { model: models.ShopCustomer, unique: true, }, foreignKey: 'shop_id' }); } } exports.Shop = Shop;