feat: add Filesystem util and load env util (#7487)
This commit is contained in:
2
.github/workflows/action.yml
vendored
2
.github/workflows/action.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16.10.0"
|
||||
node-version: 20
|
||||
cache: "yarn"
|
||||
|
||||
- name: Assert changed
|
||||
|
||||
2
.github/workflows/docs-freshness-check.yml
vendored
2
.github/workflows/docs-freshness-check.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16.10.0"
|
||||
node-version: 20
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
|
||||
40
.github/workflows/docs-test.yml
vendored
40
.github/workflows/docs-test.yml
vendored
@@ -1,5 +1,5 @@
|
||||
name: Documentation Tests
|
||||
on:
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- www/**
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "18"
|
||||
node-version: 20
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
# TODO change once we have actual URLs
|
||||
NEXT_PUBLIC_RESOURCES_URL: "http://example.com"
|
||||
NEXT_PUBLIC_USER_GUIDE_URL: "http://example.com"
|
||||
|
||||
|
||||
vale-book:
|
||||
if: ${{ startsWith(github.head_ref, 'docs/') }}
|
||||
runs-on: ubuntu-latest
|
||||
@@ -75,7 +75,7 @@ jobs:
|
||||
# an error state
|
||||
- name: Get PR files number
|
||||
working-directory: www/utils/packages/scripts
|
||||
run: 'yarn check:pr-files-count ${{ github.ref_name }}'
|
||||
run: "yarn check:pr-files-count ${{ github.ref_name }}"
|
||||
id: pr-files
|
||||
|
||||
- name: Get Directories to Scan
|
||||
@@ -90,13 +90,13 @@ jobs:
|
||||
with:
|
||||
files: ${{ steps.directories.outputs.LIST }}
|
||||
fail_on_error: true
|
||||
vale_flags: '--minAlertLevel=error'
|
||||
vale_flags: "--minAlertLevel=error"
|
||||
reporter: github-pr-check
|
||||
token: ${{ github.token }}
|
||||
filter_mode: nofilter
|
||||
env:
|
||||
REVIEWDOG_GITHUB_API_TOKEN: ${{ github.token }}
|
||||
|
||||
|
||||
vale-resources:
|
||||
if: ${{ startsWith(github.head_ref, 'docs/') }}
|
||||
runs-on: ubuntu-latest
|
||||
@@ -127,7 +127,7 @@ jobs:
|
||||
# an error state
|
||||
- name: Get PR files number
|
||||
working-directory: www/utils/packages/scripts
|
||||
run: 'yarn check:pr-files-count ${{ github.ref_name }}'
|
||||
run: "yarn check:pr-files-count ${{ github.ref_name }}"
|
||||
id: pr-files
|
||||
|
||||
- name: Get Directories to Scan
|
||||
@@ -141,13 +141,13 @@ jobs:
|
||||
with:
|
||||
files: ${{ steps.directories.outputs.LIST }}
|
||||
fail_on_error: true
|
||||
vale_flags: '--minAlertLevel=error'
|
||||
vale_flags: "--minAlertLevel=error"
|
||||
reporter: github-pr-check
|
||||
token: ${{ github.token }}
|
||||
filter_mode: nofilter
|
||||
env:
|
||||
REVIEWDOG_GITHUB_API_TOKEN: ${{ github.token }}
|
||||
|
||||
|
||||
vale-user-guide:
|
||||
if: ${{ startsWith(github.head_ref, 'docs/') }}
|
||||
runs-on: ubuntu-latest
|
||||
@@ -178,7 +178,7 @@ jobs:
|
||||
# an error state
|
||||
- name: Get PR files number
|
||||
working-directory: www/utils/packages/scripts
|
||||
run: 'yarn check:pr-files-count ${{ github.ref_name }}'
|
||||
run: "yarn check:pr-files-count ${{ github.ref_name }}"
|
||||
id: pr-files
|
||||
|
||||
- name: Get Directories to Scan
|
||||
@@ -192,13 +192,13 @@ jobs:
|
||||
with:
|
||||
files: ${{ steps.directories.outputs.LIST }}
|
||||
fail_on_error: true
|
||||
vale_flags: '--minAlertLevel=error'
|
||||
vale_flags: "--minAlertLevel=error"
|
||||
reporter: github-pr-check
|
||||
token: ${{ github.token }}
|
||||
filter_mode: nofilter
|
||||
env:
|
||||
REVIEWDOG_GITHUB_API_TOKEN: ${{ github.token }}
|
||||
|
||||
|
||||
vale-ui:
|
||||
if: ${{ startsWith(github.head_ref, 'docs/') }}
|
||||
runs-on: ubuntu-latest
|
||||
@@ -229,7 +229,7 @@ jobs:
|
||||
# an error state
|
||||
- name: Get PR files number
|
||||
working-directory: www/utils/packages/scripts
|
||||
run: 'yarn check:pr-files-count ${{ github.ref_name }}'
|
||||
run: "yarn check:pr-files-count ${{ github.ref_name }}"
|
||||
id: pr-files
|
||||
|
||||
- name: Get Directories to Scan
|
||||
@@ -244,13 +244,13 @@ jobs:
|
||||
with:
|
||||
files: ${{ steps.directories.outputs.LIST }}
|
||||
fail_on_error: true
|
||||
vale_flags: '--minAlertLevel=error'
|
||||
vale_flags: "--minAlertLevel=error"
|
||||
reporter: github-pr-check
|
||||
token: ${{ github.token }}
|
||||
filter_mode: nofilter
|
||||
env:
|
||||
REVIEWDOG_GITHUB_API_TOKEN: ${{ github.token }}
|
||||
|
||||
|
||||
vale-api:
|
||||
if: ${{ startsWith(github.head_ref, 'docs/') }}
|
||||
runs-on: ubuntu-latest
|
||||
@@ -281,7 +281,7 @@ jobs:
|
||||
# an error state
|
||||
- name: Get PR files number
|
||||
working-directory: www/utils/packages/scripts
|
||||
run: 'yarn check:pr-files-count ${{ github.ref_name }}'
|
||||
run: "yarn check:pr-files-count ${{ github.ref_name }}"
|
||||
id: pr-files
|
||||
|
||||
- name: Get Directories to Scan
|
||||
@@ -296,13 +296,13 @@ jobs:
|
||||
with:
|
||||
files: ${{ steps.directories.outputs.LIST }}
|
||||
fail_on_error: true
|
||||
vale_flags: '--minAlertLevel=error'
|
||||
vale_flags: "--minAlertLevel=error"
|
||||
reporter: github-pr-check
|
||||
token: ${{ github.token }}
|
||||
filter_mode: diff_context
|
||||
env:
|
||||
REVIEWDOG_GITHUB_API_TOKEN: ${{ github.token }}
|
||||
|
||||
|
||||
content-eslint:
|
||||
if: ${{ startsWith(github.head_ref, 'docs/') }}
|
||||
runs-on: ubuntu-latest
|
||||
@@ -324,7 +324,7 @@ jobs:
|
||||
- name: Run Eslint
|
||||
working-directory: www
|
||||
run: yarn lint:content
|
||||
|
||||
|
||||
code-docs-eslint:
|
||||
if: ${{ startsWith(github.head_ref, 'docs/') }}
|
||||
runs-on: ubuntu-latest
|
||||
@@ -352,4 +352,4 @@ jobs:
|
||||
|
||||
- name: Run Eslint
|
||||
working-directory: www
|
||||
run: yarn lint
|
||||
run: yarn lint
|
||||
|
||||
@@ -9,9 +9,9 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
referenceName:
|
||||
description: 'Reference to Generate. Use either `all` or a name of a config file in `www/utils/packages/typedoc-config` such as `product`.'
|
||||
description: "Reference to Generate. Use either `all` or a name of a config file in `www/utils/packages/typedoc-config` such as `product`."
|
||||
required: false
|
||||
default: 'all'
|
||||
default: "all"
|
||||
|
||||
jobs:
|
||||
references:
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16.10.0"
|
||||
node-version: 20
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
@@ -83,4 +83,4 @@ jobs:
|
||||
add-paths: www/apps/resources/references/**
|
||||
branch: "docs/generate-reference"
|
||||
branch-suffix: "timestamp"
|
||||
body: ${{ steps.pr-message.outputs.body }}
|
||||
body: ${{ steps.pr-message.outputs.body }}
|
||||
|
||||
8
.github/workflows/generate-docblocks.yml
vendored
8
.github/workflows/generate-docblocks.yml
vendored
@@ -14,10 +14,10 @@ jobs:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js 18
|
||||
- name: Setup Node.js 20
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 20
|
||||
|
||||
- name: Install Dependencies
|
||||
run: yarn
|
||||
@@ -70,10 +70,10 @@ jobs:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js 18
|
||||
- name: Setup Node.js 20
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 20
|
||||
|
||||
- name: Install Dependencies
|
||||
run: yarn
|
||||
|
||||
10
.github/workflows/generate-public-references.yml
vendored
10
.github/workflows/generate-public-references.yml
vendored
@@ -3,9 +3,9 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
referenceName:
|
||||
description: 'Reference to Generate. Use either `all` to generate all references, `api` to generate the API reference, or `ui` to generate UI reference.'
|
||||
description: "Reference to Generate. Use either `all` to generate all references, `api` to generate the API reference, or `ui` to generate UI reference."
|
||||
required: false
|
||||
default: 'all'
|
||||
default: "all"
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16.10.0"
|
||||
node-version: 20
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
@@ -78,7 +78,7 @@ jobs:
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16.10.0"
|
||||
node-version: 20
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
@@ -114,4 +114,4 @@ jobs:
|
||||
labels: "type: chore"
|
||||
add-paths: www/apps/ui/src/specs
|
||||
branch: "docs/generate-ui-ref"
|
||||
branch-suffix: "timestamp"
|
||||
branch-suffix: "timestamp"
|
||||
|
||||
2
.github/workflows/release-notifications.yml
vendored
2
.github/workflows/release-notifications.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16.10.0"
|
||||
node-version: 20
|
||||
cache: "yarn"
|
||||
|
||||
- name: Post to Slack channel
|
||||
|
||||
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -15,10 +15,10 @@ jobs:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js 16
|
||||
- name: Setup Node.js 20
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
|
||||
- name: Creating .npmrc
|
||||
run: |
|
||||
@@ -37,4 +37,4 @@ jobs:
|
||||
- name: Create Release Pull Request
|
||||
uses: changesets/action@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
6
.github/workflows/snapshot-this.yml
vendored
6
.github/workflows/snapshot-this.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
snapshot:
|
||||
name: Snapshot Release
|
||||
if: |
|
||||
github.event.issue.pull_request &&
|
||||
github.event.issue.pull_request &&
|
||||
github.event.comment.body == '/snapshot-this'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -79,7 +79,7 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
node-version: 20
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
@@ -120,7 +120,7 @@ jobs:
|
||||
'```sh\n' +
|
||||
`yarn add ${tag}\n` +
|
||||
'```'
|
||||
)).join('\n') +
|
||||
)).join('\n') +
|
||||
`\n\n> Latest commit: ${context.sha}`
|
||||
|
||||
)
|
||||
|
||||
132
.github/workflows/test-cli-with-database.yml
vendored
132
.github/workflows/test-cli-with-database.yml
vendored
@@ -1,82 +1,82 @@
|
||||
name: CLI Pipeline
|
||||
on:
|
||||
pull_request:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test-cli-with-database:
|
||||
env:
|
||||
NODE_ENV: CI
|
||||
REDIS_URL: redis://localhost:6379
|
||||
DATABASE_URL: "postgres://postgres:postgres@localhost/cli-test"
|
||||
POSTGRES_URL: "postgres://postgres:postgres@localhost/cli-test"
|
||||
services:
|
||||
redis:
|
||||
image: redis
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 6379:6379
|
||||
test-cli-with-database:
|
||||
env:
|
||||
NODE_ENV: CI
|
||||
REDIS_URL: redis://localhost:6379
|
||||
DATABASE_URL: "postgres://postgres:postgres@localhost/cli-test"
|
||||
POSTGRES_URL: "postgres://postgres:postgres@localhost/cli-test"
|
||||
services:
|
||||
redis:
|
||||
image: redis
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
postgres:
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_DB: cli-test
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
postgres:
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_DB: cli-test
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup development server
|
||||
uses: ./.github/actions/setup-server
|
||||
with:
|
||||
cache-extension: "cli-test"
|
||||
node-version: 18
|
||||
- name: Setup development server
|
||||
uses: ./.github/actions/setup-server
|
||||
with:
|
||||
cache-extension: "cli-test"
|
||||
node-version: 20
|
||||
|
||||
- name: Install Medusa cli
|
||||
run: npm i -g @medusajs/medusa-cli@preview
|
||||
- name: Install Medusa cli
|
||||
run: npm i -g @medusajs/medusa-cli@preview
|
||||
|
||||
- name: Create Medusa project
|
||||
run: |
|
||||
medusa new cli-test --skip-db --v2 --branch feat/v2-ci
|
||||
working-directory: ..
|
||||
- name: Create Medusa project
|
||||
run: |
|
||||
medusa new cli-test --skip-db --v2 --branch feat/v2-ci
|
||||
working-directory: ..
|
||||
|
||||
- name: run medusa dev
|
||||
run: medusa-dev --force-install
|
||||
working-directory: ../cli-test
|
||||
- name: run medusa dev
|
||||
run: medusa-dev --force-install
|
||||
working-directory: ../cli-test
|
||||
|
||||
- name: Run migrations
|
||||
run: medusa migrations run
|
||||
working-directory: ../cli-test
|
||||
- name: Run migrations
|
||||
run: medusa migrations run
|
||||
working-directory: ../cli-test
|
||||
|
||||
- name: Create admin user
|
||||
run: medusa user -e test@test.com -p password -i admin_123
|
||||
working-directory: ../cli-test
|
||||
- name: Create admin user
|
||||
run: medusa user -e test@test.com -p password -i admin_123
|
||||
working-directory: ../cli-test
|
||||
|
||||
- name: Run development server
|
||||
run: medusa develop &
|
||||
working-directory: ../cli-test
|
||||
- name: Run development server
|
||||
run: medusa develop &
|
||||
working-directory: ../cli-test
|
||||
|
||||
- name: Testing development server
|
||||
uses: ./.github/actions/test-server
|
||||
- name: Testing development server
|
||||
uses: ./.github/actions/test-server
|
||||
|
||||
- name: Starting medusa
|
||||
run: medusa start &
|
||||
working-directory: ../cli-test
|
||||
- name: Starting medusa
|
||||
run: medusa start &
|
||||
working-directory: ../cli-test
|
||||
|
||||
- name: Testing server
|
||||
uses: ./.github/actions/test-server
|
||||
- name: Testing server
|
||||
uses: ./.github/actions/test-server
|
||||
|
||||
22
.github/workflows/trigger-release.yml
vendored
22
.github/workflows/trigger-release.yml
vendored
@@ -5,14 +5,14 @@ on:
|
||||
inputs:
|
||||
version:
|
||||
type: choice
|
||||
default: 'preview'
|
||||
default: "preview"
|
||||
description: What tag do you want to release?
|
||||
required: true
|
||||
options:
|
||||
- preview
|
||||
- next
|
||||
- snapshot
|
||||
- canary
|
||||
options:
|
||||
- preview
|
||||
- next
|
||||
- snapshot
|
||||
- canary
|
||||
branches:
|
||||
- develop
|
||||
paths-ignore:
|
||||
@@ -32,10 +32,10 @@ jobs:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js 16.x
|
||||
- name: Setup Node.js 20
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
node-version: 20
|
||||
|
||||
- name: Creating .npmrc
|
||||
run: |
|
||||
@@ -44,8 +44,8 @@ jobs:
|
||||
EOF
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Configure npm node prepend
|
||||
|
||||
- name: Configure npm node prepend
|
||||
run: npm config set scripts-prepend-node-path auto
|
||||
|
||||
- name: Install Dependencies
|
||||
@@ -61,6 +61,6 @@ jobs:
|
||||
|
||||
- name: Build all packages
|
||||
run: yarn build
|
||||
|
||||
|
||||
- name: Publish packages under next tag
|
||||
run: yarn changeset publish --no-git-tags --snapshot --tag ${{ github.event.inputs.version || 'preview' }}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import express from "express"
|
||||
import getPort from "get-port"
|
||||
import { resolve } from "path"
|
||||
import { isObject, promiseAll } from "@medusajs/utils"
|
||||
import { isObject, promiseAll, GracefulShutdownServer } from "@medusajs/utils"
|
||||
import { MedusaContainer } from "@medusajs/types"
|
||||
|
||||
async function bootstrapApp({
|
||||
@@ -52,7 +52,7 @@ export async function startApp({
|
||||
let expressServer
|
||||
|
||||
const shutdown = async () => {
|
||||
await promiseAll([expressServer.shutdown(), medusaShutdown()])
|
||||
await promiseAll([expressServer?.shutdown(), medusaShutdown()])
|
||||
|
||||
if (typeof global !== "undefined" && global?.gc) {
|
||||
global.gc()
|
||||
@@ -77,10 +77,6 @@ export async function startApp({
|
||||
})
|
||||
|
||||
// TODO: fix that once we find the appropriate place to put this util
|
||||
const {
|
||||
GracefulShutdownServer,
|
||||
} = require("@medusajs/medusa/dist/utils/graceful-shutdown-server")
|
||||
|
||||
expressServer = GracefulShutdownServer.create(server)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"@mikro-orm/postgresql": "5.9.7",
|
||||
"awilix": "^8.0.1",
|
||||
"bignumber.js": "^9.1.2",
|
||||
"dotenv": "^16.4.5",
|
||||
"knex": "2.4.2",
|
||||
"ulid": "^2.3.0"
|
||||
},
|
||||
|
||||
40
packages/core/utils/src/common/__tests__/load-env.spec.ts
Normal file
40
packages/core/utils/src/common/__tests__/load-env.spec.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { join } from "path"
|
||||
import { FileSystem } from "../file-system"
|
||||
import { loadEnv } from "../load-env"
|
||||
|
||||
const filesystem = new FileSystem(join(__dirname, "tmp"))
|
||||
|
||||
describe("loadEnv", function () {
|
||||
afterEach(async () => {
|
||||
await filesystem.cleanup()
|
||||
delete process.env.MEDUSA_VERSION
|
||||
delete process.env.MEDUSA_DEV_VERSION
|
||||
delete process.env.MEDUSA_TEST_VERSION
|
||||
delete process.env.MEDUSA_STAGING_VERSION
|
||||
delete process.env.MEDUSA_PRODUCTION_VERSION
|
||||
})
|
||||
|
||||
it("should load .env file when in unknown environment", async function () {
|
||||
await filesystem.create(".env", "MEDUSA_VERSION=1.0")
|
||||
loadEnv("", filesystem.basePath)
|
||||
|
||||
expect(process.env.MEDUSA_VERSION).toEqual("1.0")
|
||||
})
|
||||
|
||||
it("should load .env file for known environments", async function () {
|
||||
await filesystem.create(".env", "MEDUSA_DEV_VERSION=1.0")
|
||||
await filesystem.create(".env.test", "MEDUSA_TEST_VERSION=1.0")
|
||||
await filesystem.create(".env.staging", "MEDUSA_STAGING_VERSION=1.0")
|
||||
await filesystem.create(".env.production", "MEDUSA_PRODUCTION_VERSION=1.0")
|
||||
|
||||
loadEnv("development", filesystem.basePath)
|
||||
loadEnv("test", filesystem.basePath)
|
||||
loadEnv("staging", filesystem.basePath)
|
||||
loadEnv("production", filesystem.basePath)
|
||||
|
||||
expect(process.env.MEDUSA_DEV_VERSION).toEqual("1.0")
|
||||
expect(process.env.MEDUSA_TEST_VERSION).toEqual("1.0")
|
||||
expect(process.env.MEDUSA_STAGING_VERSION).toEqual("1.0")
|
||||
expect(process.env.MEDUSA_PRODUCTION_VERSION).toEqual("1.0")
|
||||
})
|
||||
})
|
||||
159
packages/core/utils/src/common/file-system.ts
Normal file
159
packages/core/utils/src/common/file-system.ts
Normal file
@@ -0,0 +1,159 @@
|
||||
import { dirname, join } from "path"
|
||||
import {
|
||||
promises,
|
||||
constants,
|
||||
type Dirent,
|
||||
type RmOptions,
|
||||
type StatOptions,
|
||||
type WriteFileOptions,
|
||||
type MakeDirectoryOptions,
|
||||
} from "fs"
|
||||
|
||||
const { rm, stat, mkdir, access, readdir, readFile, writeFile } = promises
|
||||
|
||||
export type JSONFileOptions = WriteFileOptions & {
|
||||
spaces?: number | string
|
||||
replacer?: (this: any, key: string, value: any) => any
|
||||
}
|
||||
|
||||
/**
|
||||
* File system abstraction to create and cleanup files during
|
||||
* tests
|
||||
*/
|
||||
export class FileSystem {
|
||||
constructor(public basePath: string) {}
|
||||
|
||||
private makePath(filePath: string) {
|
||||
return join(this.basePath, filePath)
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup directory
|
||||
*/
|
||||
async cleanup(options?: RmOptions) {
|
||||
return rm(this.basePath, {
|
||||
recursive: true,
|
||||
maxRetries: 10,
|
||||
force: true,
|
||||
...options,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a directory inside the root of the filesystem
|
||||
* path. You may use this method to create nested
|
||||
* directories as well.
|
||||
*/
|
||||
mkdir(dirPath: string, options?: MakeDirectoryOptions) {
|
||||
return mkdir(this.makePath(dirPath), { recursive: true, ...options })
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new file
|
||||
*/
|
||||
async create(filePath: string, contents: string, options?: WriteFileOptions) {
|
||||
const absolutePath = this.makePath(filePath)
|
||||
await mkdir(dirname(absolutePath), { recursive: true })
|
||||
return writeFile(this.makePath(filePath), contents, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a file
|
||||
*/
|
||||
async remove(filePath: string, options?: RmOptions) {
|
||||
return rm(this.makePath(filePath), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
maxRetries: 2,
|
||||
...options,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the root of the filesystem exists
|
||||
*/
|
||||
async rootExists() {
|
||||
try {
|
||||
await access(this.basePath, constants.F_OK)
|
||||
return true
|
||||
} catch (error) {
|
||||
if (error.code === "ENOENT") {
|
||||
return false
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file exists
|
||||
*/
|
||||
async exists(filePath: string) {
|
||||
try {
|
||||
await access(this.makePath(filePath), constants.F_OK)
|
||||
return true
|
||||
} catch (error) {
|
||||
if (error.code === "ENOENT") {
|
||||
return false
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns file contents
|
||||
*/
|
||||
async contents(filePath: string) {
|
||||
return readFile(this.makePath(filePath), "utf-8")
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps file contents to the stdout
|
||||
*/
|
||||
async dump(filePath: string) {
|
||||
console.log("------------------------------------------------------------")
|
||||
console.log(`file path => "${filePath}"`)
|
||||
console.log(`contents => "${await this.contents(filePath)}"`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns stats for a file
|
||||
*/
|
||||
async stats(filePath: string, options?: StatOptions) {
|
||||
return stat(this.makePath(filePath), options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively reads files from a given directory
|
||||
*/
|
||||
readDir(dirPath?: string): Promise<Dirent[]> {
|
||||
const location = dirPath ? this.makePath(dirPath) : this.basePath
|
||||
return readdir(location, {
|
||||
recursive: true,
|
||||
withFileTypes: true,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a json file
|
||||
*/
|
||||
async createJson(filePath: string, contents: any, options?: JSONFileOptions) {
|
||||
if (options && typeof options === "object") {
|
||||
const { replacer, spaces, ...rest } = options
|
||||
return this.create(
|
||||
filePath,
|
||||
JSON.stringify(contents, replacer, spaces),
|
||||
rest
|
||||
)
|
||||
}
|
||||
|
||||
return this.create(filePath, JSON.stringify(contents), options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and parse a json file
|
||||
*/
|
||||
async contentsJson(filePath: string) {
|
||||
const contents = await readFile(this.makePath(filePath), "utf-8")
|
||||
return JSON.parse(contents)
|
||||
}
|
||||
}
|
||||
@@ -61,3 +61,6 @@ export * from "./to-handle"
|
||||
export * from "./validate-handle"
|
||||
export * from "./parse-cors-origins"
|
||||
export * from "./build-regexp-if-valid"
|
||||
export * from "./load-env"
|
||||
export * from "./file-system"
|
||||
export * from "./graceful-shutdown-server"
|
||||
|
||||
24
packages/core/utils/src/common/load-env.ts
Normal file
24
packages/core/utils/src/common/load-env.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import dotenv from "dotenv"
|
||||
import { join } from "path"
|
||||
const KNOWN_ENVIRONMENTS = ["staging", "production", "test"]
|
||||
|
||||
/**
|
||||
* Loads ".env" file based upon the environment in which the
|
||||
* app is running.
|
||||
*
|
||||
* - Loads ".env" file by default.
|
||||
* - Loads ".env.staging" when "environment=staging".
|
||||
* - Loads ".env.production" when "environment=production".
|
||||
* - Loads ".env.test" when "environment=test".
|
||||
*
|
||||
* This method does not return any value and updates the "process.env"
|
||||
* object instead.
|
||||
*/
|
||||
export function loadEnv(environment: string, envDir: string) {
|
||||
const fileToLoad = KNOWN_ENVIRONMENTS.includes(environment)
|
||||
? `.env.${environment}`
|
||||
: ".env"
|
||||
try {
|
||||
dotenv.config({ path: join(envDir, fileToLoad) })
|
||||
} catch {}
|
||||
}
|
||||
@@ -3,14 +3,13 @@ import "regenerator-runtime/runtime"
|
||||
|
||||
import cluster from "cluster"
|
||||
import express from "express"
|
||||
import { GracefulShutdownServer } from "../utils"
|
||||
import { track } from "medusa-telemetry"
|
||||
import { scheduleJob } from "node-schedule"
|
||||
import os from "os"
|
||||
|
||||
import loaders from "../loaders"
|
||||
import Logger from "../loaders/logger"
|
||||
import { isPresent } from "@medusajs/utils"
|
||||
import { isPresent, GracefulShutdownServer } from "@medusajs/utils"
|
||||
|
||||
const EVERY_SIXTH_HOUR = "0 */6 * * *"
|
||||
const CRON_SCHEDULE = EVERY_SIXTH_HOUR
|
||||
|
||||
@@ -2,12 +2,12 @@ import "core-js/stable"
|
||||
import "regenerator-runtime/runtime"
|
||||
|
||||
import express from "express"
|
||||
import { GracefulShutdownServer } from "../utils"
|
||||
import { track } from "medusa-telemetry"
|
||||
import { scheduleJob } from "node-schedule"
|
||||
|
||||
import loaders from "../loaders"
|
||||
import Logger from "../loaders/logger"
|
||||
import { GracefulShutdownServer } from "@medusajs/utils"
|
||||
|
||||
const EVERY_SIXTH_HOUR = "0 */6 * * *"
|
||||
const CRON_SCHEDULE = EVERY_SIXTH_HOUR
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import { mkdirSync, rmSync, writeFileSync } from "fs"
|
||||
import { resolve } from "path"
|
||||
import { join } from "path"
|
||||
import { FileSystem } from "@medusajs/utils"
|
||||
|
||||
import loadFeatureFlags from "../feature-flags"
|
||||
|
||||
const distTestTargetDirectorPath = resolve(__dirname, "__ff-test__")
|
||||
|
||||
const getFolderTestTargetDirectoryPath = (folderName: string): string => {
|
||||
return resolve(distTestTargetDirectorPath, folderName)
|
||||
}
|
||||
const filesystem = new FileSystem(join(__dirname, "__ff-test__"))
|
||||
|
||||
const buildFeatureFlag = (
|
||||
key: string,
|
||||
@@ -28,60 +23,42 @@ const buildFeatureFlag = (
|
||||
describe("feature flags", () => {
|
||||
const OLD_ENV = { ...process.env }
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach(async () => {
|
||||
jest.resetModules()
|
||||
jest.clearAllMocks()
|
||||
|
||||
process.env = { ...OLD_ENV }
|
||||
|
||||
rmSync(distTestTargetDirectorPath, { recursive: true, force: true })
|
||||
|
||||
mkdirSync(getFolderTestTargetDirectoryPath("project"), {
|
||||
mode: "777",
|
||||
recursive: true,
|
||||
})
|
||||
|
||||
mkdirSync(getFolderTestTargetDirectoryPath("flags"), {
|
||||
mode: "777",
|
||||
recursive: true,
|
||||
})
|
||||
await filesystem.cleanup()
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
afterAll(async () => {
|
||||
process.env = OLD_ENV
|
||||
rmSync(distTestTargetDirectorPath, { recursive: true, force: true })
|
||||
await filesystem.cleanup()
|
||||
})
|
||||
|
||||
it("should load the flag from project", async () => {
|
||||
writeFileSync(
|
||||
resolve(getFolderTestTargetDirectoryPath("flags"), "flag-1.js"),
|
||||
buildFeatureFlag("flag-1", true)
|
||||
)
|
||||
await filesystem.create("flags/flag-1.js", buildFeatureFlag("flag-1", true))
|
||||
|
||||
const flags = await loadFeatureFlags(
|
||||
const flags = loadFeatureFlags(
|
||||
{ featureFlags: { flag_1: false } },
|
||||
undefined,
|
||||
getFolderTestTargetDirectoryPath("flags")
|
||||
join(filesystem.basePath, "flags")
|
||||
)
|
||||
|
||||
expect(flags.isFeatureEnabled("flag_1")).toEqual(false)
|
||||
})
|
||||
|
||||
it("should load a nested + simple flag from project", async () => {
|
||||
writeFileSync(
|
||||
resolve(getFolderTestTargetDirectoryPath("flags"), "test.js"),
|
||||
buildFeatureFlag("test", false)
|
||||
)
|
||||
|
||||
writeFileSync(
|
||||
resolve(getFolderTestTargetDirectoryPath("flags"), "simpletest.js"),
|
||||
await filesystem.create("flags/test.js", buildFeatureFlag("test", false))
|
||||
await filesystem.create(
|
||||
"flags/simpletest.js",
|
||||
buildFeatureFlag("simpletest", false)
|
||||
)
|
||||
|
||||
const flags = await loadFeatureFlags(
|
||||
const flags = loadFeatureFlags(
|
||||
{ featureFlags: { test: { nested: true }, simpletest: true } },
|
||||
undefined,
|
||||
getFolderTestTargetDirectoryPath("flags")
|
||||
join(filesystem.basePath, "flags")
|
||||
)
|
||||
|
||||
expect(flags.isFeatureEnabled({ test: "nested" })).toEqual(true)
|
||||
@@ -89,15 +66,15 @@ describe("feature flags", () => {
|
||||
})
|
||||
|
||||
it("should load the default feature flags", async () => {
|
||||
writeFileSync(
|
||||
resolve(getFolderTestTargetDirectoryPath("flags"), "flag-1.js"),
|
||||
buildFeatureFlag("flag-1", true)
|
||||
await filesystem.create(
|
||||
"flags/flag-1.js",
|
||||
buildFeatureFlag("flag-1", false)
|
||||
)
|
||||
|
||||
const flags = await loadFeatureFlags(
|
||||
const flags = loadFeatureFlags(
|
||||
{},
|
||||
undefined,
|
||||
getFolderTestTargetDirectoryPath("flags")
|
||||
join(filesystem.basePath, "flags")
|
||||
)
|
||||
|
||||
expect(flags.isFeatureEnabled("flag_1")).toEqual(true)
|
||||
@@ -106,15 +83,14 @@ describe("feature flags", () => {
|
||||
it("should load the flag from env", async () => {
|
||||
process.env.MEDUSA_FF_FLAG_1 = "false"
|
||||
|
||||
writeFileSync(
|
||||
resolve(getFolderTestTargetDirectoryPath("flags"), "flag-1.js"),
|
||||
buildFeatureFlag("flag-1", true)
|
||||
await filesystem.create(
|
||||
"flags/flag-1.js",
|
||||
buildFeatureFlag("flag-1", false)
|
||||
)
|
||||
|
||||
const flags = await loadFeatureFlags(
|
||||
const flags = loadFeatureFlags(
|
||||
{},
|
||||
undefined,
|
||||
getFolderTestTargetDirectoryPath("flags")
|
||||
join(filesystem.basePath, "flags")
|
||||
)
|
||||
|
||||
expect(flags.isFeatureEnabled("flag_1")).toEqual(false)
|
||||
@@ -122,26 +98,23 @@ describe("feature flags", () => {
|
||||
|
||||
it("should load mix of flags", async () => {
|
||||
process.env.MEDUSA_FF_FLAG_3 = "false"
|
||||
|
||||
writeFileSync(
|
||||
resolve(getFolderTestTargetDirectoryPath("flags"), "flag-1.js"),
|
||||
buildFeatureFlag("flag-1", true)
|
||||
await filesystem.create(
|
||||
"flags/flag-1.js",
|
||||
buildFeatureFlag("flag-1", false)
|
||||
)
|
||||
await filesystem.create(
|
||||
"flags/flag-2.js",
|
||||
buildFeatureFlag("flag-2", false)
|
||||
)
|
||||
await filesystem.create(
|
||||
"flags/flag-3.js",
|
||||
buildFeatureFlag("flag-3", false)
|
||||
)
|
||||
|
||||
writeFileSync(
|
||||
resolve(getFolderTestTargetDirectoryPath("flags"), "flag-2.js"),
|
||||
buildFeatureFlag("flag-2", true)
|
||||
)
|
||||
|
||||
writeFileSync(
|
||||
resolve(getFolderTestTargetDirectoryPath("flags"), "flag-3.js"),
|
||||
buildFeatureFlag("flag-3", true)
|
||||
)
|
||||
|
||||
const flags = await loadFeatureFlags(
|
||||
const flags = loadFeatureFlags(
|
||||
{ featureFlags: { flag_2: false } },
|
||||
undefined,
|
||||
getFolderTestTargetDirectoryPath("flags")
|
||||
join(filesystem.basePath, "flags")
|
||||
)
|
||||
|
||||
expect(flags.isFeatureEnabled("flag_1")).toEqual(true)
|
||||
|
||||
@@ -3,4 +3,3 @@ export * from "./exception-formatter"
|
||||
export * from "./middlewares"
|
||||
export * from "./omit-deep"
|
||||
export * from "./remove-undefined-properties"
|
||||
export * from "./graceful-shutdown-server"
|
||||
|
||||
Reference in New Issue
Block a user