Merge branch 'medusajs:develop' into develop

This commit is contained in:
Ronaldo Caetano authored and GitHub committed 2021-10-25 22:07:36 -03:00
commit 662b1ee670
76 files changed
+246 -484

No files matched your search

-20
View File
@@ -6,12 +6,10 @@
/packages/medusa/src/services/middleware.js
/packages/medusa/src/services/payment-provider.js
/packages/medusa/src/services/product-variant.js
/packages/medusa/src/services/product.js
/packages/medusa/src/services/shipping-profile.js
/packages/medusa/src/subscribers/notification.js
/packages/medusa/src/subscribers/order.js
/packages/medusa/src/subscribers/product.js
/packages/medusa/src/loaders/api.js
/packages/medusa/src/loaders/database.js
/packages/medusa/src/loaders/defaults.js
@@ -25,37 +23,20 @@
/packages/medusa/src/loaders/repositories.js
/packages/medusa/src/loaders/services.js
/packages/medusa/src/loaders/subscribers.js
/packages/medusa/src/api/routes/admin/apps
/packages/medusa/src/api/routes/admin/auth
/packages/medusa/src/api/routes/admin/collections
/packages/medusa/src/api/routes/admin/customers
/packages/medusa/src/api/routes/admin/draft-orders
/packages/medusa/src/api/routes/admin/gift-cards
/packages/medusa/src/api/routes/admin/notes
/packages/medusa/src/api/routes/admin/notifications
/packages/medusa/src/api/routes/admin/orders
/packages/medusa/src/api/routes/admin/products
/packages/medusa/src/api/routes/admin/regions
/packages/medusa/src/api/routes/admin/return-reasons
/packages/medusa/src/api/routes/admin/returns
/packages/medusa/src/api/routes/admin/shipping-options
/packages/medusa/src/api/routes/admin/shipping-profiles
/packages/medusa/src/api/routes/admin/store
/packages/medusa/src/api/routes/admin/swaps
/packages/medusa/src/api/routes/admin/users
/packages/medusa/src/api/routes/store/auth
/packages/medusa/src/api/routes/store/carts
/packages/medusa/src/api/routes/store/customers
/packages/medusa/src/api/routes/store/gift-cards
/packages/medusa/src/api/routes/store/orders
/packages/medusa/src/api/routes/store/products
/packages/medusa/src/api/routes/store/regions
/packages/medusa/src/api/routes/store/return-reasons
/packages/medusa/src/api/routes/store/returns
/packages/medusa/src/api/routes/store/shipping-options
/packages/medusa/src/api/routes/store/swaps
# END OF FILES TODO
@@ -66,7 +47,6 @@
/packages/medusa/src/helpers
/packages/medusa/src/migrations
/packages/medusa/src/utils
/integration-tests
/docs
/docs-util
@@ -0,0 +1,33 @@
name: cache-bootstrap
description: Creates a cache with the given extension for lerna packages
inputs:
extension:
description: Extension for cache name
partial:
description: Boolean flag to describe whether or not to run a partial bootstrap when finding cache
default: false
runs:
using: composite
steps:
# for always overriding cache, use: pat-s/always-upload-cache@v2.1.5
- uses: actions/cache@v2
id: cache
with:
path: |
node_modules
*/*/node_modules
key: ${{ runner.os }}-yarn-${{inputs.extension}}-v8-${{ hashFiles('**/yarn.lock') }}
# We want to only bootstrap and install if no cache is found.
# Futhermore, we might want to do a partial, hoisted, bootstrap towards
# the base branch if it exists, otherwise we choose develop for this.
# yarn install --frozen-lockfile
- run: |
if [[ "${{steps.cache.outputs.cache-hit}}" != "true" || "${{inputs.partial}}" != "true" ]]; then
yarn install --frozen-lockfile
yarn bootstrap --concurrency=2
elif [[ "${{inputs.partial}}" = "true" ]]; then
[[ ! -z "${GITHUB_BASE_REF}" ]] && ref="${GITHUB_BASE_REF#refs/heads/}" || ref="develop"
yarn bootstrap --npm-client=npm --hoist --since "origin/${ref}...HEAD" --concurrency=2
fi
shell: bash
+82
View File
@@ -0,0 +1,82 @@
name: Medusa Pipeline
on: [push, pull_request]
jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2.3.5
with:
fetch-depth: 0
- name: Setup Node.js environment
uses: actions/setup-node@v2.4.1
with:
node-version: '14'
cache: 'yarn'
- name: Assert changed
run: ./scripts/assert-changed-files-actions.sh "packages"
- name: Bootstrap packages
uses: ./.github/actions/cache-bootstrap
with:
extension: unit-tests
- name: Run unit tests
run: node --max-old-space-size=2048 ./node_modules/.bin/jest -w 1
integration-tests:
runs-on: ubuntu-latest
services:
postgres:
image: postgres
env:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Checkout
uses: actions/checkout@v2.3.5
with:
fetch-depth: 0
- name: Setup Node.js environment
uses: actions/setup-node@v2.4.1
with:
node-version: '14'
cache: 'yarn'
- name: Bootstrap packages
uses: ./.github/actions/cache-bootstrap
with:
extension: integration-tests
- name: Install dev cli
run: sudo npm i -g medusa-dev-cli
- name: Set path to medusa repo
run: medusa-dev --set-path-to-repo `pwd`
- name: Force install
run: medusa-dev --force-install
working-directory: integration-tests/api
- name: Build integration tests
run: yarn build
working-directory: integration-tests/api
- name: Run integration tests
run: yarn test
working-directory: integration-tests/api
env:
DB_PASSWORD: postgres
+1 -1
View File
@@ -1,5 +1,5 @@
{
"endOfLine": "lf",
"endOfLine": "auto",
"semi": false,
"singleQuote": false,
"tabWidth": 2,
@@ -43,9 +43,7 @@ import { defaultFields, defaultRelations } from "./"
*/
export default async (req, res) => {
const schema = Validator.object().keys({
value: Validator.number()
.integer()
.optional(),
value: Validator.number().integer().optional(),
ends_at: Validator.date().optional(),
is_disabled: Validator.boolean().optional(),
region_id: Validator.string().optional(),
@@ -57,7 +55,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const giftCardService = req.scope.resolve("giftCardService")
const newly = await giftCardService.create({
@@ -71,7 +68,4 @@ export default async (req, res) => {
})
res.status(200).json({ gift_card: giftCard })
} catch (err) {
throw err
}
}
@@ -26,7 +26,6 @@
export default async (req, res) => {
const { id } = req.params
try {
const giftCardService = req.scope.resolve("giftCardService")
await giftCardService.delete(id)
@@ -35,7 +34,4 @@ export default async (req, res) => {
object: "gift-card",
deleted: true,
})
} catch (err) {
throw err
}
}
@@ -22,7 +22,6 @@ import { defaultFields, defaultRelations } from "./"
export default async (req, res) => {
const { id } = req.params
try {
const giftCardService = req.scope.resolve("giftCardService")
const giftCard = await giftCardService.retrieve(id, {
select: defaultFields,
@@ -30,7 +29,4 @@ export default async (req, res) => {
})
res.status(200).json({ gift_card: giftCard })
} catch (err) {
throw err
}
}
@@ -3,7 +3,7 @@ import middlewares from "../../../middlewares"
const route = Router()
export default app => {
export default (app) => {
app.use("/gift-cards", route)
route.get("/", middlewares.wrap(require("./list-gift-cards").default))
@@ -33,10 +33,7 @@ export const defaultFields = [
"metadata",
]
export const defaultRelations = [
"region",
"order",
]
export const defaultRelations = ["region", "order"]
export const allowedFields = [
"id",
@@ -1,4 +1,3 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultFields, defaultRelations } from "./"
/**
@@ -21,7 +20,6 @@ import { defaultFields, defaultRelations } from "./"
* $ref: "#/components/schemas/gift_card"
*/
export default async (req, res) => {
try {
const limit = parseInt(req.query.limit) || 50
const offset = parseInt(req.query.offset) || 0
@@ -42,7 +40,4 @@ export default async (req, res) => {
})
res.status(200).json({ gift_cards: giftCards })
} catch (err) {
throw err
}
}
@@ -47,9 +47,7 @@ export default async (req, res) => {
const { id } = req.params
const schema = Validator.object().keys({
balance: Validator.number()
.precision(0)
.optional(),
balance: Validator.number().precision(0).optional(),
ends_at: Validator.date().optional(),
is_disabled: Validator.boolean().optional(),
region_id: Validator.string().optional(),
@@ -61,7 +59,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const giftCardService = req.scope.resolve("giftCardService")
await giftCardService.update(id, value)
@@ -72,7 +69,4 @@ export default async (req, res) => {
})
res.status(200).json({ gift_card: giftCard })
} catch (err) {
throw err
}
}
@@ -3,7 +3,7 @@ import middlewares from "../../../middlewares"
const route = Router()
export default app => {
export default (app) => {
app.use("/notifications", route)
/**
@@ -21,13 +21,12 @@ import { defaultRelations, defaultFields } from "./"
* $ref: "#/components/schemas/notification"
*/
export default async (req, res) => {
try {
const notificationService = req.scope.resolve("notificationService")
const limit = parseInt(req.query.limit) || 50
const offset = parseInt(req.query.offset) || 0
let selector = {}
const selector = {}
let includeFields = []
if ("fields" in req.query) {
@@ -74,10 +73,7 @@ export default async (req, res) => {
const notifications = await notificationService.list(selector, listConfig)
const fields = [...listConfig.select, ...listConfig.relations]
const data = notifications.map(o => _.pick(o, fields))
const data = notifications.map((o) => _.pick(o, fields))
res.json({ notifications: data, offset, limit })
} catch (error) {
throw error
}
}
@@ -32,7 +32,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const notificationService = req.scope.resolve("notificationService")
const config = {}
@@ -49,7 +48,4 @@ export default async (req, res) => {
})
res.json({ notification })
} catch (error) {
throw error
}
}
@@ -39,7 +39,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const productService = req.scope.resolve("productService")
await productService.addOption(id, value.title)
@@ -49,7 +48,4 @@ export default async (req, res) => {
})
res.json({ product })
} catch (err) {
throw err
}
}
@@ -188,9 +188,7 @@ export default async (req, res) => {
description: Validator.string().allow(""),
is_giftcard: Validator.boolean().default(false),
discountable: Validator.boolean().default(true),
images: Validator.array()
.items(Validator.string())
.optional(),
images: Validator.array().items(Validator.string()).optional(),
thumbnail: Validator.string().optional(),
handle: Validator.string().optional(),
status: Validator.string()
@@ -203,9 +201,7 @@ export default async (req, res) => {
})
.allow(null)
.optional(),
collection_id: Validator.string()
.allow(null)
.optional(),
collection_id: Validator.string().allow(null).optional(),
tags: Validator.array()
.items({
id: Validator.string().optional(),
@@ -225,30 +221,13 @@ export default async (req, res) => {
inventory_quantity: Validator.number().default(0),
allow_backorder: Validator.boolean().optional(),
manage_inventory: Validator.boolean().optional(),
weight: Validator.number()
.allow(null)
.optional(),
length: Validator.number()
.allow(null)
.optional(),
height: Validator.number()
.allow(null)
.optional(),
width: Validator.number()
.allow(null)
.optional(),
origin_country: Validator.string()
.optional()
.allow("")
.allow(null),
mid_code: Validator.string()
.optional()
.allow("")
.allow(null),
material: Validator.string()
.optional()
.allow("")
.allow(null),
weight: Validator.number().allow(null).optional(),
length: Validator.number().allow(null).optional(),
height: Validator.number().allow(null).optional(),
width: Validator.number().allow(null).optional(),
origin_country: Validator.string().optional().allow("").allow(null),
mid_code: Validator.string().optional().allow("").allow(null),
material: Validator.string().optional().allow("").allow(null),
metadata: Validator.object().optional(),
prices: Validator.array()
.items(
@@ -256,9 +235,7 @@ export default async (req, res) => {
.keys({
region_id: Validator.string(),
currency_code: Validator.string(),
amount: Validator.number()
.integer()
.required(),
amount: Validator.number().integer().required(),
sale_amount: Validator.number().optional(),
})
.xor("region_id", "currency_code")
@@ -270,30 +247,14 @@ export default async (req, res) => {
})
.default([]),
}),
weight: Validator.number()
.allow(null)
.optional(),
length: Validator.number()
.allow(null)
.optional(),
height: Validator.number()
.allow(null)
.optional(),
width: Validator.number()
.allow(null)
.optional(),
hs_code: Validator.string()
.optional()
.allow(""),
origin_country: Validator.string()
.optional()
.allow(""),
mid_code: Validator.string()
.optional()
.allow(""),
material: Validator.string()
.optional()
.allow(""),
weight: Validator.number().allow(null).optional(),
length: Validator.number().allow(null).optional(),
height: Validator.number().allow(null).optional(),
width: Validator.number().allow(null).optional(),
hs_code: Validator.string().optional().allow(""),
origin_country: Validator.string().optional().allow(""),
mid_code: Validator.string().optional().allow(""),
material: Validator.string().optional().allow(""),
metadata: Validator.object().optional(),
})
@@ -302,7 +263,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const productService = req.scope.resolve("productService")
const productVariantService = req.scope.resolve("productVariantService")
const shippingProfileService = req.scope.resolve("shippingProfileService")
@@ -310,7 +270,7 @@ export default async (req, res) => {
const entityManager = req.scope.resolve("manager")
let newProduct
await entityManager.transaction(async manager => {
await entityManager.transaction(async (manager) => {
const { variants } = value
delete value.variants
@@ -331,14 +291,16 @@ export default async (req, res) => {
.create({ ...value, profile_id: shippingProfile.id })
if (variants) {
for (const [i, variant] of variants.entries()) variant.variant_rank = i
for (const [i, variant] of variants.entries()) {
variant.variant_rank = i
}
const optionIds = value.options.map(
o => newProduct.options.find(newO => newO.title === o.title).id
(o) => newProduct.options.find((newO) => newO.title === o.title).id
)
await Promise.all(
variants.map(async v => {
variants.map(async (v) => {
const variant = {
...v,
options: v.options.map((o, index) => ({
@@ -361,7 +323,4 @@ export default async (req, res) => {
})
res.json({ product })
} catch (err) {
throw err
}
}
@@ -115,18 +115,10 @@ export default async (req, res) => {
inventory_quantity: Validator.number().default(0),
allow_backorder: Validator.boolean().optional(),
manage_inventory: Validator.boolean().optional(),
weight: Validator.number()
.allow(null)
.optional(),
length: Validator.number()
.allow(null)
.optional(),
height: Validator.number()
.allow(null)
.optional(),
width: Validator.number()
.allow(null)
.optional(),
weight: Validator.number().allow(null).optional(),
length: Validator.number().allow(null).optional(),
height: Validator.number().allow(null).optional(),
width: Validator.number().allow(null).optional(),
origin_country: Validator.string().allow(""),
mid_code: Validator.string().allow(""),
material: Validator.string().allow(""),
@@ -137,9 +129,7 @@ export default async (req, res) => {
.keys({
region_id: Validator.string().empty(null),
currency_code: Validator.string().required(),
amount: Validator.number()
.integer()
.required(),
amount: Validator.number().integer().required(),
sale_amount: Validator.number().optional(),
})
.xor("region_id", "currency_code")
@@ -158,7 +148,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const productVariantService = req.scope.resolve("productVariantService")
const productService = req.scope.resolve("productService")
@@ -170,7 +159,4 @@ export default async (req, res) => {
})
res.json({ product })
} catch (err) {
throw err
}
}
@@ -31,7 +31,6 @@ import { defaultRelations, defaultFields } from "."
export default async (req, res) => {
const { id, option_id } = req.params
try {
const productService = req.scope.resolve("productService")
await productService.deleteOption(id, option_id)
const data = await productService.retrieve(id, {
@@ -45,7 +44,4 @@ export default async (req, res) => {
deleted: true,
product: data,
})
} catch (err) {
throw err
}
}
@@ -26,7 +26,6 @@
export default async (req, res) => {
const { id } = req.params
try {
const productService = req.scope.resolve("productService")
await productService.delete(id)
res.json({
@@ -34,7 +33,4 @@ export default async (req, res) => {
object: "product",
deleted: true,
})
} catch (err) {
throw err
}
}
@@ -29,7 +29,6 @@ import { defaultRelations, defaultFields } from "."
export default async (req, res) => {
const { id, variant_id } = req.params
try {
const productVariantService = req.scope.resolve("productVariantService")
const productService = req.scope.resolve("productService")
@@ -46,7 +45,4 @@ export default async (req, res) => {
deleted: true,
product: data,
})
} catch (err) {
throw err
}
}
@@ -3,7 +3,7 @@ import middlewares from "../../../middlewares"
const route = Router()
export default app => {
export default (app) => {
app.use("/products", route)
route.post("/", middlewares.wrap(require("./create-product").default))
@@ -1,4 +1,3 @@
import _ from "lodash"
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultFields, defaultRelations, filterableFields } from "./"
@@ -42,7 +41,6 @@ export default async (req, res) => {
)
}
try {
const productService = req.scope.resolve("productService")
const limit = parseInt(req.query.limit) || 50
@@ -84,10 +82,7 @@ export default async (req, res) => {
take: limit,
}
let products = await productService.list(selector, listConfig)
const products = await productService.list(selector, listConfig)
res.json({ products, count: products.length, offset, limit })
} catch (error) {
throw error
}
}
@@ -1,11 +1,7 @@
export default async (req, res) => {
try {
const productService = req.scope.resolve("productService")
const tags = await productService.listTagsByUsage()
res.json({ tags })
} catch (error) {
throw error
}
}
@@ -18,13 +18,9 @@
* $ref: "#/components/schemas/product_type"
*/
export default async (req, res) => {
try {
const productService = req.scope.resolve("productService")
const types = await productService.listTypes()
res.json({ types })
} catch (error) {
throw error
}
}
@@ -14,7 +14,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const productService = req.scope.resolve("productService")
await productService.update(id, {
metadata: { [value.key]: value.value },
@@ -26,7 +25,4 @@ export default async (req, res) => {
})
res.status(200).json({ product })
} catch (err) {
throw err
}
}
@@ -41,7 +41,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const productService = req.scope.resolve("productService")
await productService.updateOption(id, option_id, value)
@@ -52,7 +51,4 @@ export default async (req, res) => {
})
res.json({ product })
} catch (err) {
throw err
}
}
@@ -188,9 +188,7 @@ export default async (req, res) => {
const schema = Validator.object().keys({
title: Validator.string().optional(),
subtitle: Validator.string()
.optional()
.allow(null, ""),
subtitle: Validator.string().optional().allow(null, ""),
description: Validator.string().optional(),
discountable: Validator.boolean().optional(),
status: Validator.string().valid(
@@ -206,9 +204,7 @@ export default async (req, res) => {
})
.allow(null)
.optional(),
collection_id: Validator.string()
.allow(null)
.optional(),
collection_id: Validator.string().allow(null).optional(),
tags: Validator.array()
.items({
id: Validator.string().optional(),
@@ -216,26 +212,15 @@ export default async (req, res) => {
})
.optional(),
handle: Validator.string().optional(),
weight: Validator.number()
.allow(null)
.optional(),
length: Validator.number()
.allow(null)
.optional(),
height: Validator.number()
.allow(null)
.optional(),
width: Validator.number()
.allow(null)
.optional(),
weight: Validator.number().allow(null).optional(),
length: Validator.number().allow(null).optional(),
height: Validator.number().allow(null).optional(),
width: Validator.number().allow(null).optional(),
origin_country: Validator.string().allow(null, ""),
hs_code: Validator.string().allow(null, ""),
mid_code: Validator.string().allow(null, ""),
material: Validator.string().allow(null, ""),
images: Validator.array()
.items(Validator.string())
.optional()
.optional(),
images: Validator.array().items(Validator.string()).optional().optional(),
thumbnail: Validator.string().optional(),
variants: Validator.array()
.items({
@@ -249,9 +234,7 @@ export default async (req, res) => {
.keys({
region_id: Validator.string(),
currency_code: Validator.string(),
amount: Validator.number()
.integer()
.required(),
amount: Validator.number().integer().required(),
sale_amount: Validator.number().optional(),
})
.xor("region_id", "currency_code")
@@ -266,21 +249,11 @@ export default async (req, res) => {
inventory_quantity: Validator.number().allow(null),
allow_backorder: Validator.boolean().allow(null),
manage_inventory: Validator.boolean().allow(null),
weight: Validator.number()
.allow(null)
.optional(),
length: Validator.number()
.allow(null)
.optional(),
height: Validator.number()
.allow(null)
.optional(),
width: Validator.number()
.allow(null)
.optional(),
hs_code: Validator.string()
.optional()
.allow(null, ""),
weight: Validator.number().allow(null).optional(),
length: Validator.number().allow(null).optional(),
height: Validator.number().allow(null).optional(),
width: Validator.number().allow(null).optional(),
hs_code: Validator.string().optional().allow(null, ""),
origin_country: Validator.string().allow(null, ""),
mid_code: Validator.string().allow(null, ""),
material: Validator.string().allow(null, ""),
@@ -295,11 +268,10 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const productService = req.scope.resolve("productService")
const entityManager = req.scope.resolve("manager")
await entityManager.transaction(async manager => {
await entityManager.transaction(async (manager) => {
await productService.withTransaction(manager).update(id, value)
})
@@ -309,7 +281,4 @@ export default async (req, res) => {
})
res.json({ product })
} catch (err) {
throw err
}
}
@@ -1,4 +1,3 @@
import _ from "lodash"
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultFields, defaultRelations } from "./"
@@ -116,9 +115,7 @@ export default async (req, res) => {
.keys({
region_id: Validator.string().empty(null),
currency_code: Validator.string(),
amount: Validator.number()
.integer()
.required(),
amount: Validator.number().integer().required(),
sale_amount: Validator.number().optional(),
})
.xor("region_id", "currency_code")
@@ -133,30 +130,14 @@ export default async (req, res) => {
inventory_quantity: Validator.number().optional(),
allow_backorder: Validator.boolean().optional(),
manage_inventory: Validator.boolean().optional(),
weight: Validator.number()
.allow(null)
.optional(),
length: Validator.number()
.allow(null)
.optional(),
height: Validator.number()
.allow(null)
.optional(),
width: Validator.number()
.allow(null)
.optional(),
hs_code: Validator.string()
.optional()
.allow(null, ""),
origin_country: Validator.string()
.optional()
.allow(null, ""),
mid_code: Validator.string()
.optional()
.allow(null, ""),
material: Validator.string()
.optional()
.allow(null, ""),
weight: Validator.number().allow(null).optional(),
length: Validator.number().allow(null).optional(),
height: Validator.number().allow(null).optional(),
width: Validator.number().allow(null).optional(),
hs_code: Validator.string().optional().allow(null, ""),
origin_country: Validator.string().optional().allow(null, ""),
mid_code: Validator.string().optional().allow(null, ""),
material: Validator.string().optional().allow(null, ""),
metadata: Validator.object().optional(),
})
@@ -165,7 +146,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const productService = req.scope.resolve("productService")
const productVariantService = req.scope.resolve("productVariantService")
@@ -175,8 +155,6 @@ export default async (req, res) => {
select: defaultFields,
relations: defaultRelations,
})
res.json({ product })
} catch (err) {
throw err
}
}
@@ -39,7 +39,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const regionService = req.scope.resolve("regionService")
await regionService.addCountry(region_id, value.country_code)
@@ -49,7 +48,4 @@ export default async (req, res) => {
})
res.status(200).json({ region })
} catch (err) {
throw err
}
}
@@ -39,7 +39,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const regionService = req.scope.resolve("regionService")
await regionService.addFulfillmentProvider(region_id, value.provider_id)
@@ -48,7 +47,4 @@ export default async (req, res) => {
relations: defaultRelations,
})
res.status(200).json({ region: data })
} catch (err) {
throw err
}
}
@@ -39,7 +39,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const regionService = req.scope.resolve("regionService")
await regionService.addPaymentProvider(region_id, value.provider_id)
@@ -48,7 +47,4 @@ export default async (req, res) => {
relations: defaultRelations,
})
res.status(200).json({ region: data })
} catch (err) {
throw err
}
}
@@ -66,7 +66,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const regionService = req.scope.resolve("regionService")
const result = await regionService.create(value)
@@ -76,7 +75,4 @@ export default async (req, res) => {
})
res.status(200).json({ region })
} catch (err) {
throw err
}
}
@@ -23,7 +23,6 @@ import { defaultRelations, defaultFields } from "./"
export default async (req, res) => {
const { id, key } = req.params
try {
const regionService = req.scope.resolve("regionService")
await regionService.deleteMetadata(id, key)
@@ -33,7 +32,4 @@ export default async (req, res) => {
})
res.status(200).json({ region })
} catch (err) {
throw err
}
}
@@ -1,5 +1,3 @@
import { MedusaError, Validator } from "medusa-core-utils"
/**
* @oas [delete] /regions/{id}
* operationId: "DeleteRegionsRegion"
@@ -27,7 +25,6 @@ import { MedusaError, Validator } from "medusa-core-utils"
*/
export default async (req, res) => {
const { region_id } = req.params
try {
const regionService = req.scope.resolve("regionService")
await regionService.delete(region_id)
@@ -36,7 +33,4 @@ export default async (req, res) => {
object: "region",
deleted: true,
})
} catch (err) {
throw err
}
}
@@ -22,7 +22,6 @@
export default async (req, res) => {
const { region_id } = req.params
try {
const fulfillmentProviderService = req.scope.resolve(
"fulfillmentProviderService"
)
@@ -31,7 +30,7 @@ export default async (req, res) => {
relations: ["fulfillment_providers"],
})
const fpsIds = region.fulfillment_providers.map(fp => fp.id) || []
const fpsIds = region.fulfillment_providers.map((fp) => fp.id) || []
const options = await fulfillmentProviderService.listFulfillmentOptions(
fpsIds
@@ -40,7 +39,4 @@ export default async (req, res) => {
res.status(200).json({
fulfillment_options: options,
})
} catch (err) {
throw err
}
}
@@ -1,4 +1,3 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
/**
@@ -22,7 +21,6 @@ import { defaultRelations, defaultFields } from "./"
*/
export default async (req, res) => {
const { region_id } = req.params
try {
const regionService = req.scope.resolve("regionService")
const data = await regionService.retrieve(region_id, {
select: defaultFields,
@@ -30,7 +28,4 @@ export default async (req, res) => {
})
res.status(200).json({ region: data })
} catch (err) {
throw err
}
}
@@ -3,7 +3,7 @@ import middlewares from "../../../middlewares"
const route = Router()
export default app => {
export default (app) => {
app.use("/regions", route)
route.get("/", middlewares.wrap(require("./list-regions").default))
@@ -20,7 +20,6 @@ import { defaultFields, defaultRelations } from "./"
* $ref: "#/components/schemas/region"
*/
export default async (req, res) => {
try {
const regionService = req.scope.resolve("regionService")
const limit = parseInt(req.query.limit) || 50
@@ -35,10 +34,7 @@ export default async (req, res) => {
take: limit,
}
let regions = await regionService.list(selector, listConfig)
const regions = await regionService.list(selector, listConfig)
res.json({ regions, count: regions.length, offset, limit })
} catch (err) {
throw err
}
}
@@ -1,4 +1,3 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
/**
@@ -23,7 +22,6 @@ import { defaultRelations, defaultFields } from "./"
*/
export default async (req, res) => {
const { region_id, country_code } = req.params
try {
const regionService = req.scope.resolve("regionService")
await regionService.removeCountry(region_id, country_code)
@@ -33,7 +31,4 @@ export default async (req, res) => {
})
res.json({ region })
} catch (err) {
throw err
}
}
@@ -1,4 +1,3 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
/**
@@ -23,7 +22,6 @@ import { defaultRelations, defaultFields } from "./"
*/
export default async (req, res) => {
const { region_id, provider_id } = req.params
try {
const regionService = req.scope.resolve("regionService")
await regionService.removeFulfillmentProvider(region_id, provider_id)
@@ -34,7 +32,4 @@ export default async (req, res) => {
})
res.json({ region })
} catch (err) {
throw err
}
}
@@ -1,4 +1,3 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
/**
@@ -23,7 +22,6 @@ import { defaultRelations, defaultFields } from "./"
*/
export default async (req, res) => {
const { region_id, provider_id } = req.params
try {
const regionService = req.scope.resolve("regionService")
await regionService.removePaymentProvider(region_id, provider_id)
@@ -33,7 +31,4 @@ export default async (req, res) => {
})
res.json({ region })
} catch (err) {
throw err
}
}
@@ -1,4 +1,5 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultFields, defaultRelations } from "."
export default async (req, res) => {
const { id } = req.params
@@ -13,17 +14,13 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const regionService = req.scope.resolve("regionService")
await regionService.setMetadata(id, value.key, value.value)
const region = await regionService.retrieve(region_id, {
const region = await regionService.retrieve(id, {
select: defaultFields,
relations: defaultRelations,
})
res.status(200).json({ region })
} catch (err) {
throw err
}
}
@@ -70,7 +70,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const regionService = req.scope.resolve("regionService")
await regionService.update(region_id, value)
const region = await regionService.retrieve(region_id, {
@@ -79,7 +78,4 @@ export default async (req, res) => {
})
res.status(200).json({ region })
} catch (err) {
throw err
}
}
@@ -72,16 +72,12 @@ export default async (req, res) => {
profile_id: Validator.string(),
data: Validator.object().required(),
price_type: Validator.string().required(),
amount: Validator.number()
.integer()
.optional(),
amount: Validator.number().integer().optional(),
requirements: Validator.array()
.items(
Validator.object({
type: Validator.string().required(),
amount: Validator.number()
.integer()
.required(),
amount: Validator.number().integer().required(),
})
)
.optional(),
@@ -94,7 +90,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const optionService = req.scope.resolve("shippingOptionService")
const shippingProfileService = req.scope.resolve("shippingProfileService")
@@ -111,7 +106,4 @@ export default async (req, res) => {
})
res.status(200).json({ shipping_option: data })
} catch (err) {
throw err
}
}
@@ -25,7 +25,6 @@
*/
export default async (req, res) => {
const { option_id } = req.params
try {
const optionService = req.scope.resolve("shippingOptionService")
await optionService.delete(option_id)
@@ -35,7 +34,4 @@ export default async (req, res) => {
object: "shipping-option",
deleted: true,
})
} catch (err) {
throw err
}
}
@@ -19,12 +19,8 @@
*/
export default async (req, res) => {
const { option_id } = req.params
try {
const optionService = req.scope.resolve("shippingOptionService")
const data = await optionService.retrieve(option_id)
res.status(200).json({ shipping_option: data })
} catch (err) {
throw err
}
}
@@ -3,7 +3,7 @@ import middlewares from "../../../middlewares"
const route = Router()
export default app => {
export default (app) => {
app.use("/shipping-options", route)
route.get("/", middlewares.wrap(require("./list-shipping-options").default))
@@ -21,7 +21,6 @@ import { defaultFields, defaultRelations } from "./"
* $ref: "#/components/schemas/shipping_option"
*/
export default async (req, res) => {
try {
const query = _.pick(req.query, ["region_id", "is_return", "admin_only"])
const optionService = req.scope.resolve("shippingOptionService")
@@ -31,7 +30,4 @@ export default async (req, res) => {
})
res.status(200).json({ shipping_options: data })
} catch (err) {
throw err
}
}
@@ -1,4 +1,3 @@
import _ from "lodash"
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultFields, defaultRelations } from "./"
@@ -50,17 +49,13 @@ export default async (req, res) => {
const { option_id } = req.params
const schema = Validator.object().keys({
name: Validator.string().optional(),
amount: Validator.number()
.integer()
.optional(),
amount: Validator.number().integer().optional(),
requirements: Validator.array()
.items(
Validator.object({
id: Validator.string().optional(),
type: Validator.string().required(),
amount: Validator.number()
.integer()
.required(),
amount: Validator.number().integer().required(),
})
)
.optional(),
@@ -73,7 +68,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const optionService = req.scope.resolve("shippingOptionService")
await optionService.update(option_id, value)
@@ -84,7 +78,4 @@ export default async (req, res) => {
})
res.status(200).json({ shipping_option: data })
} catch (err) {
throw err
}
}
@@ -22,7 +22,6 @@ import { defaultFields, defaultRelations } from "./"
export default async (req, res) => {
const { id } = req.params
try {
const swapService = req.scope.resolve("swapService")
const swap = await swapService.retrieve(id, {
@@ -31,7 +30,4 @@ export default async (req, res) => {
})
res.json({ swap })
} catch (error) {
throw error
}
}
@@ -3,7 +3,7 @@ import middlewares from "../../../middlewares"
const route = Router()
export default app => {
export default (app) => {
app.use("/swaps", route)
/**
@@ -1,5 +1,3 @@
import _ from "lodash"
/**
* @oas [get] /swaps
* operationId: "GetSwaps"
@@ -20,7 +18,6 @@ import _ from "lodash"
* $ref: "#/components/schemas/swap"
*/
export default async (req, res) => {
try {
const swapService = req.scope.resolve("swapService")
const limit = parseInt(req.query.limit) || 50
@@ -37,7 +34,4 @@ export default async (req, res) => {
const swaps = await swapService.list(selector, { ...listConfig })
res.json({ swaps, count: swaps.length, offset, limit })
} catch (error) {
throw error
}
}
@@ -13,14 +13,10 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const userService = req.scope.resolve("userService")
const data = _.pick(value, ["email", "name"])
const user = await userService.create(data, value.password)
res.status(200).json({ user })
} catch (err) {
throw err
}
}
@@ -1,12 +1,8 @@
export default async (req, res) => {
const { user_id } = req.params
try {
const userService = req.scope.resolve("userService")
const user = await userService.retrieve(user_id)
res.json({ user })
} catch (error) {
throw error
}
}
@@ -1,10 +1,6 @@
export default async (req, res) => {
try {
const userService = req.scope.resolve("userService")
const users = await userService.list({})
res.status(200).json({ users })
} catch (err) {
throw err
}
}
@@ -9,8 +9,6 @@ export default async (req, res) => {
if (error) {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const userService = req.scope.resolve("userService")
const user = await userService.retrieveByEmail(value.email)
@@ -18,7 +16,4 @@ export default async (req, res) => {
await userService.generateResetPasswordToken(user.id)
res.sendStatus(204)
} catch (error) {
throw error
}
}
@@ -12,8 +12,6 @@ export default async (req, res) => {
if (error) {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const userService = req.scope.resolve("userService")
const user = await userService.retrieveByEmail(value.email)
@@ -26,7 +24,4 @@ export default async (req, res) => {
const data = await userService.setPassword(user.id, value.password)
res.status(200).json({ user: data })
} catch (error) {
throw error
}
}
@@ -12,11 +12,7 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const userService = req.scope.resolve("userService")
const data = await userService.update(user_id, value)
res.status(200).json({ user: data })
} catch (err) {
throw err
}
}
@@ -1,5 +1,3 @@
import { Validator, MedusaError } from "medusa-core-utils"
/**
* @oas [get] /auth/{email}
* operationId: "GetAuthEmail"
@@ -16,7 +16,6 @@
* $ref: "#/components/schemas/customer"
*/
export default async (req, res) => {
try {
if (req.user && req.user.customer_id) {
const customerService = req.scope.resolve("customerService")
const customer = await customerService.retrieve(req.user.customer_id, {
@@ -26,7 +25,4 @@ export default async (req, res) => {
} else {
res.sendStatus(401)
}
} catch (err) {
throw err
}
}
@@ -41,7 +41,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const customerService = req.scope.resolve("customerService")
let customer = await customerService.addAddress(id, value.address)
@@ -51,7 +50,4 @@ export default async (req, res) => {
})
res.status(200).json({ customer })
} catch (err) {
throw err
}
}
@@ -40,7 +40,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const customerService = req.scope.resolve("customerService")
let customer = await customerService.create(value)
@@ -55,7 +54,4 @@ export default async (req, res) => {
})
res.status(200).json({ customer })
} catch (err) {
throw err
}
}
@@ -25,15 +25,11 @@ export default async (req, res) => {
const { address_id } = req.params
const customerService = req.scope.resolve("customerService")
try {
await customerService.removeAddress(id, address_id)
customer = await customerService.retrieve(id, {
const customer = await customerService.retrieve(id, {
relations: defaultRelations,
select: defaultFields,
})
res.json({ customer })
} catch (err) {
throw err
}
}
@@ -19,14 +19,10 @@ import { defaultRelations, defaultFields } from "./"
*/
export default async (req, res) => {
const id = req.user.customer_id
try {
const customerService = req.scope.resolve("customerService")
const customer = await customerService.retrieve(id, {
relations: defaultRelations,
select: defaultFields,
})
res.json({ customer })
} catch (err) {
throw err
}
}
@@ -27,7 +27,6 @@
*/
export default async (req, res) => {
const id = req.user.customer_id
try {
const storeService = req.scope.resolve("storeService")
const paymentProviderService = req.scope.resolve("paymentProviderService")
const customerService = req.scope.resolve("customerService")
@@ -49,7 +48,4 @@ export default async (req, res) => {
)
res.json({ payment_methods: methods.flat() })
} catch (err) {
throw err
}
}
@@ -1,4 +1,3 @@
import _ from "lodash"
import {
defaultRelations,
defaultFields,
@@ -29,7 +28,7 @@ import {
*/
export default async (req, res) => {
const id = req.user.customer_id
try {
const orderService = req.scope.resolve("orderService")
const selector = {
@@ -59,13 +58,7 @@ export default async (req, res) => {
order: { created_at: "DESC" },
}
const [orders, count] = await orderService.listAndCount(
selector,
listConfig
)
const [orders, count] = await orderService.listAndCount(selector, listConfig)
res.json({ orders, count, offset, limit })
} catch (error) {
throw error
}
}
@@ -21,7 +21,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const customerService = req.scope.resolve("customerService")
const customer = await customerService.retrieveByEmail(value.email)
@@ -29,7 +28,4 @@ export default async (req, res) => {
await customerService.generateResetPasswordToken(customer.id)
res.sendStatus(204)
} catch (error) {
throw error
}
}
@@ -43,7 +43,7 @@ export default async (req, res) => {
}
const customerService = req.scope.resolve("customerService")
try {
let customer = await customerService.updateAddress(
id,
address_id,
@@ -56,7 +56,4 @@ export default async (req, res) => {
})
res.json({ customer })
} catch (err) {
throw err
}
}
@@ -1,4 +1,3 @@
import { optional } from "joi"
import { Validator, MedusaError } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
@@ -64,7 +63,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const customerService = req.scope.resolve("customerService")
await customerService.update(id, value)
@@ -74,7 +72,4 @@ export default async (req, res) => {
})
res.status(200).json({ customer })
} catch (err) {
throw err
}
}
@@ -22,7 +22,6 @@ import { defaultFields, defaultRelations } from "."
export default async (req, res) => {
const { cart_id } = req.params
try {
const orderService = req.scope.resolve("orderService")
const order = await orderService.retrieveByCartId(cart_id, {
select: defaultFields,
@@ -30,7 +29,4 @@ export default async (req, res) => {
})
res.json({ order })
} catch (error) {
throw error
}
}
@@ -1,4 +1,3 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations } from "."
/**
@@ -30,7 +29,6 @@ import { defaultRelations } from "."
* $ref: "#/components/schemas/product"
*/
export default async (req, res) => {
try {
const productService = req.scope.resolve("productService")
const limit = parseInt(req.query.limit) || 100
@@ -53,7 +51,4 @@ export default async (req, res) => {
const products = await productService.list(selector, listConfig)
res.json({ products, count: products.length, offset, limit })
} catch (error) {
throw error
}
}
@@ -16,7 +16,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const { q, offset, limit, filter, ...options } = value
const paginationOptions = { offset, limit }
@@ -29,7 +28,4 @@ export default async (req, res) => {
})
res.status(200).send(results)
} catch (error) {
throw error
}
}
@@ -25,8 +25,6 @@ export default async (req, res) => {
const productIds =
(req.query.product_ids && req.query.product_ids.split(",")) || []
const regionId = req.query.region_id
try {
const productService = req.scope.resolve("productService")
const shippingOptionService = req.scope.resolve("shippingOptionService")
@@ -52,7 +50,4 @@ export default async (req, res) => {
})
res.status(200).json({ shipping_options: options })
} catch (err) {
throw err
}
}
@@ -31,7 +31,6 @@ export default async (req, res) => {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const cartService = req.scope.resolve("cartService")
const shippingProfileService = req.scope.resolve("shippingProfileService")
@@ -43,7 +42,4 @@ export default async (req, res) => {
const options = await shippingProfileService.fetchCartOptions(cart)
res.status(200).json({ shipping_options: options })
} catch (err) {
throw err
}
}
@@ -1,4 +1,3 @@
import { IdMap } from "../../../../../../../medusa-test-utils/dist"
import { request } from "../../../../../helpers/test-request"
import { ProductVariantServiceMock } from "../../../../../services/__mocks__/product-variant"
+13 -11
View File
@@ -1,11 +1,10 @@
import _ from "lodash"
import { MedusaError } from "medusa-core-utils"
import { BaseService } from "medusa-interfaces"
import { Brackets } from "typeorm"
/**
* Provides layer to manipulate products.
* @implements BaseService
* @extends BaseService
*/
class ProductService extends BaseService {
static IndexName = `products`
@@ -88,7 +87,8 @@ class ProductService extends BaseService {
}
/**
* @param {Object} listOptions - the query object for find
* @param {object} selector - selector for query
* @param {Object} config - config for query object for find
* @return {Promise} the result of the find operation
*/
async list(selector = {}, config = { relations: [], skip: 0, take: 20 }) {
@@ -112,7 +112,7 @@ class ProductService extends BaseService {
query.select = config.select
}
let rels = query.relations
const rels = query.relations
delete query.relations
if (q) {
@@ -162,6 +162,7 @@ class ProductService extends BaseService {
* Gets a product by id.
* Throws in case of DB Error and if product was not found.
* @param {string} productId - id of the product to get.
* @param {object} config - config of the product to get.
* @return {Promise<Product>} the result of the find one operation.
*/
async retrieve(productId, config = {}) {
@@ -258,7 +259,7 @@ class ProductService extends BaseService {
this.productTagRepository_
)
let newTags = []
const newTags = []
for (const tag of tags) {
const existing = await productTagRepository.findOne({
where: { value: tag.value },
@@ -339,7 +340,7 @@ class ProductService extends BaseService {
this.imageRepository_
)
let productImages = []
const productImages = []
for (const img of images) {
const existing = await imageRepository.findOne({
where: { url: img },
@@ -376,8 +377,7 @@ class ProductService extends BaseService {
relations: ["variants", "tags", "images"],
})
const { variants, metadata, options, images, tags, type, ...rest } =
update
const { variants, metadata, images, tags, type, ...rest } = update
if (!product.thumbnail && !update.thumbnail && images?.length) {
product.thumbnail = images[0]
@@ -473,7 +473,9 @@ class ProductService extends BaseService {
{ relations: ["variants"] }
)
if (!product) return Promise.resolve()
if (!product) {
return Promise.resolve()
}
await productRepo.softRemove(product)
@@ -574,7 +576,7 @@ class ProductService extends BaseService {
* optionOrder and the length of the product's options are different. Will
* throw optionOrder contains an id not associated with the product.
* @param {string} productId - the product whose options we are reordering
* @param {[ObjectId]} optionId - the ids of the product's options in the
* @param {string[]} optionOrder - the ids of the product's options in the
* new order
* @return {Promise} the result of the update operation
*/
@@ -727,7 +729,7 @@ class ProductService extends BaseService {
/**
* Decorates a product with product variants.
* @param {Product} product - the product to decorate.
* @param {string} productId - the productId to decorate.
* @param {string[]} fields - the fields to include.
* @param {string[]} expandFields - fields to expand.
* @return {Product} return the decorated product.
+40
View File
@@ -0,0 +1,40 @@
#!/bin/bash
IS_CI="${CI:-false}"
GREP_PATTERN=$1
if [ "$IS_CI" = true ]; then
git config --local url."https://github.com/".insteadOf git@github.com:
git config --local user.name "Medusajs Bot"
git config --local user.email "core@medusa-commerce.com"
git fetch origin
git merge --no-edit origin/master
if [ $? -ne 0 ]; then
echo "Branch has conflicts with master, rolling back test."
git merge --abort
fi
git config --local --unset user.name
git config --local --unset user.email
git config --local --unset url."https://github.com/".insteadOf
fi
# Make sure that we are diffing towards the right branch, in github actions this is different
# depending on whether or not we are creating a pull request or not.
[ ! -z ${GITHUB_BASE_REF} ] && HAS_BASE=true || HAS_BASE=false
[ HAS_BASE = true ] && COMPARE="${GITHUB_BASE_REF#refs/heads/}" || COMPARE="develop"
FILES_COUNT="$(git diff-tree --no-commit-id --name-only -r origin/"$COMPARE" | grep -E "$GREP_PATTERN" -c)"
if [ "$IS_CI" = true ]; then
# reset to previous state
git reset --hard $GITHUB_SHA
fi
if [ "$FILES_COUNT" -eq 0 ]; then
echo "0 files matching '$GREP_PATTERN'; exiting and marking successful."
exit 0
else
echo "$FILES_COUNT file(s) matching '$GREP_PATTERN'; continuing."
fi