浏览代码

Merge branch 'feat/v1-8' of github.com:medusajs/medusa-starter-default into feat/v1-8

olivermrbl 2 年之前
父节点
当前提交
da9b5062ac

+ 3 - 3
.babelrc.js

@@ -1,12 +1,12 @@
-let ignore = [`**/dist`];
+let ignore = [`**/dist`]
 
 // Jest needs to compile this code, but generally we don't want this copied
 // to output folders
 if (process.env.NODE_ENV !== `test`) {
-  ignore.push(`**/__tests__`);
+  ignore.push(`**/__tests__`)
 }
 
 module.exports = {
   presets: [["babel-preset-medusa-package"], ["@babel/preset-typescript"]],
   ignore,
-};
+}

+ 12 - 3
.gitignore

@@ -4,6 +4,15 @@
 /uploads
 /node_modules
 yarn-error.log
-/.idea
-/build
-medusa-db.sql
+
+.idea
+
+coverage
+
+!src/**
+
+./tsconfig.tsbuildinfo
+package-lock.json
+yarn.lock
+medusa-db.sql
+build

+ 1 - 1
README.md

@@ -32,7 +32,7 @@
   </a>
 </p>
 
-## Getting Started
+## Compatibility
 
 This starter is compatible with versions >= 1.8.0 of `@medusajs/medusa`. 
 

+ 19 - 1
medusa-config.js

@@ -30,7 +30,7 @@ const STORE_CORS = process.env.STORE_CORS || "http://localhost:8000";
 
 const DATABASE_TYPE = process.env.DATABASE_TYPE;
 const DATABASE_URL = process.env.DATABASE_URL;
-const REDIS_URL = process.env.REDIS_URL;
+const REDIS_URL = process.env.REDIS_URL || "redis://localhost:6379";
 
 const plugins = [
   `medusa-fulfillment-manual`,
@@ -44,8 +44,25 @@ const plugins = [
   },
 ];
 
+const modules = {
+  /*eventBus: {
+    resolve: "@medusajs/event-bus-redis",
+    options: {
+      redisUrl: REDIS_URL
+    }
+  },
+  cacheService: {
+    resolve: "@medusajs/cache-redis",
+    options: {
+      redisUrl: REDIS_URL
+    }
+  },*/
+}
+
 /** @type {import('@medusajs/medusa').ConfigModule["projectConfig"]} */
 const projectConfig = {
+  jwtSecret: process.env.JWT_SECRET,
+  cookieSecret: process.env.COOKIE_SECRET,
   database_database: "./medusa-db.sql",
   database_type: DATABASE_TYPE || "sqlite",
   store_cors: STORE_CORS,
@@ -65,4 +82,5 @@ if (DATABASE_URL) {
 module.exports = {
   projectConfig,
   plugins,
+	modules,
 };

+ 64 - 15
package.json

@@ -4,36 +4,85 @@
   "description": "A starter for Medusa projects.",
   "author": "Sebastian Rindom <skrindom@gmail.com>",
   "license": "MIT",
+  "keywords": [
+    "sqlite",
+    "postgres",
+    "typescript",
+    "ecommerce",
+    "headless",
+    "medusa"
+  ],
   "scripts": {
+    "clean": "./node_modules/.bin/rimraf dist",
+    "build": "yarn run clean && tsc -p tsconfig.json",
+    "watch": "tsc --watch",
+    "test": "jest",
     "seed": "medusa seed -f ./data/seed.json",
-    "build": "babel src -d dist --extensions \".ts,.js\"",
-    "start": "medusa develop",
+    "start": "yarn build && medusa start",
     "build:admin": "medusa-admin build"
   },
   "dependencies": {
+    "@babel/preset-typescript": "^7.21.4",
     "@medusajs/admin": "rc",
-    "@medusajs/cache-inmemory": "rc",
-    "@medusajs/event-bus-local": "rc",
+    "@medusajs/cache-inmemory": "^1.1.0-ci-issue-20230322190222",
+    "@medusajs/cache-redis": "rc",
+    "@medusajs/event-bus-local": "^1.8.0-rc.1",
+    "@medusajs/event-bus-redis": "rc",
     "@medusajs/medusa": "rc",
     "@medusajs/medusa-cli": "rc",
     "@medusajs/modules-sdk": "rc",
+    "@medusajs/types": "^0.0.2-rc.0",
+    "@medusajs/utils": "^0.0.2-rc.0",
+    "babel-preset-medusa-package": "^1.1.13",
+    "body-parser": "^1.19.0",
+    "cors": "^2.8.5",
+    "express": "^4.17.2",
     "medusa-fulfillment-manual": "rc",
     "medusa-interfaces": "rc",
     "medusa-payment-manual": "rc",
     "medusa-payment-stripe": "rc",
     "typeorm": "^0.3.11"
   },
-  "repository": "https://github.com/medusajs/medusa-starter-default.git",
-  "keywords": [
-    "sqlite",
-    "ecommerce",
-    "headless",
-    "medusa"
-  ],
   "devDependencies": {
-    "@babel/cli": "^7.18.10",
-    "@babel/core": "^7.18.10",
-    "@babel/preset-typescript": "^7.14.5",
-    "babel-preset-medusa-package": "^1.1.19"
+    "@babel/cli": "^7.14.3",
+    "@babel/core": "^7.14.3",
+    "@types/express": "^4.17.13",
+    "@types/jest": "^27.4.0",
+    "@types/node": "^17.0.8",
+    "babel-preset-medusa-package": "^1.1.13",
+    "cross-env": "^5.2.1",
+    "eslint": "^6.8.0",
+    "jest": "^27.3.1",
+    "mongoose": "^5.13.14",
+    "rimraf": "^3.0.2",
+    "ts-jest": "^27.0.7",
+    "ts-loader": "^9.2.6",
+    "typescript": "^4.5.2"
+  },
+  "jest": {
+    "globals": {
+      "ts-jest": {
+        "tsconfig": "tsconfig.spec.json"
+      }
+    },
+    "moduleFileExtensions": [
+      "js",
+      "json",
+      "ts"
+    ],
+    "testPathIgnorePatterns": [
+      "/node_modules/",
+      "<rootDir>/node_modules/"
+    ],
+    "rootDir": "src",
+    "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|js)$",
+    "transform": {
+      ".ts": "ts-jest"
+    },
+    "collectCoverageFrom": [
+      "**/*.(t|j)s"
+    ],
+    "coverageDirectory": "./coverage",
+    "testEnvironment": "node"
   }
 }

+ 18 - 10
src/api/README.md

@@ -1,19 +1,27 @@
 # Custom endpoints
 
-You may define custom endpoints by putting files in the `/api` directory that export functions returning an express router.
-```js
+You may define custom endpoints by putting files in the `/api` directory that export functions returning an express router or a collection of express routers.
+
+```ts
 import { Router } from "express"
+import { getConfigFile } from "medusa-core-utils"
+import { getStoreRouter } from "./routes/store"
+import { ConfigModule } from "@medusajs/medusa/dist/types/global";
 
-export default () => {
-  const router = Router()
+export default (rootDirectory) => {
+  const { configModule: { projectConfig } } = getConfigFile(
+    rootDirectory,
+    "medusa-config"
+  ) as { configModule: ConfigModule }
 
-  router.get("/hello-world", (req, res) => {
-    res.json({
-      message: "Welcome to Medusa!"
-    })
-  })
+  const storeCorsOptions = {
+    origin: projectConfig.store_cors.split(","),
+    credentials: true,
+  }
 
-  return router;
+  const storeRouter = getStoreRouter(storeCorsOptions)
+
+  return [storeRouter]
 }
 ```
 

+ 6 - 0
src/api/index.ts

@@ -0,0 +1,6 @@
+import { Router } from "express"
+
+export default (rootDirectory: string): Router | Router[] => {
+  // add your custom routes here
+  return []
+}

+ 5 - 0
src/api/routes/store/custom-route-handler.ts

@@ -0,0 +1,5 @@
+import { Request, Response } from 'express'
+
+export default async (req: Request, res: Response): Promise<void> => {
+  res.sendStatus(200)
+}

+ 17 - 0
src/api/routes/store/index.ts

@@ -0,0 +1,17 @@
+import * as cors from "cors"
+import { Router } from "express"
+import * as bodyParser from "body-parser"
+import customRouteHandler from "./custom-route-handler"
+import { wrapHandler } from "@medusajs/medusa";
+
+const storeRouter = Router()
+export function getStoreRouter(storeCorsOptions): Router {
+  storeRouter.use(cors(storeCorsOptions), bodyParser.json())
+
+  storeRouter.post(
+    "/store/my-custom-path",
+    wrapHandler(customRouteHandler)
+  )
+
+  return storeRouter
+}

+ 19 - 0
src/loaders/README.md

@@ -0,0 +1,19 @@
+# Custom loader
+
+The loader allows you have access to the Medusa service container. This allows you to access the database and the services registered on the container.
+you can register custom registrations in the container or run custom code on startup.
+
+```ts
+// src/loaders/my-loader.ts
+
+import { AwilixContainer } from 'awilix'
+
+/**
+ * 
+ * @param container The container in which the registrations are made
+ * @param config The options of the plugin or the entire config object
+ */
+export default (container: AwilixContainer, config: Record<string, unknown>): void | Promise<void> => {
+  /* Implement your own loader. */
+}
+```

+ 29 - 0
src/migrations/README.md

@@ -0,0 +1,29 @@
+# Custom migrations
+
+You may define custom models (entities) that will be registered on the global container by creating files in the `src/models` directory that export an instance of `BaseEntity`.
+In that case you also need to provide a migration in order to create the table in the database.
+
+## Example
+
+### 1. Create the migration
+
+See [How to Create Migrations](https://docs.medusajs.com/advanced/backend/migrations/) in the documentation.
+
+```ts
+// src/migration/my-migration.ts
+
+import { MigrationInterface, QueryRunner } from "typeorm"
+
+export class MyMigration1617703530229 implements MigrationInterface {
+  name = "myMigration1617703530229"
+
+  public async up(queryRunner: QueryRunner): Promise<void> {
+    // write you migration here
+  }
+
+  public async down(queryRunner: QueryRunner): Promise<void> {
+    // write you migration here
+  }
+}
+
+```

+ 1 - 2
src/models/README.md

@@ -10,8 +10,7 @@ You may define custom models (entities) that will be registered on the global co
 // src/models/post.ts
 
 import { BeforeInsert, Column, Entity, PrimaryColumn } from "typeorm";
-import { BaseEntity} from "@medusajs/medusa";
-import { generateEntityId } from "@medusajs/medusa/dist/utils"
+import { BaseEntity, generateEntityId } from "@medusajs/utils";
 
 @Entity()
 export class Post extends BaseEntity {

+ 17 - 15
src/services/README.md

@@ -2,29 +2,31 @@
 
 You may define custom services that will be registered on the global container by creating files in the `/services` directory that export an instance of `BaseService`.
 
-```js
-// my.js
-
-import { BaseService } from "medusa-interfaces";
+```ts
+// src/services/my-custom.ts
 
-class MyService extends BaseService {
-  constructor({ productService }) {
-    super();
+import { Lifetime } from "awilix"
+import { TransactionBaseService } from "@medusajs/utils";
+import { IEventBusService } from "@medusajs/types";
 
-    this.productService_ = productService
-  }
+export default class MyCustomService extends TransactionBaseService {
+  static LIFE_TIME = Lifetime.SCOPED
+  protected readonly eventBusService_: IEventBusService
 
-  async getProductMessage() {
-    const [product] = await this.productService_.list({}, { take: 1 })
+  constructor(
+      { eventBusService }: { eventBusService: IEventBusService },
+      options: Record<string, unknown>
+  ) {
+    // @ts-ignore
+    super(...arguments)
 
-    return `Welcome to ${product.title}!`
+    this.eventBusService_ = eventBusService
   }
 }
 
-export default MyService;
 ```
 
-The first argument to the `constructor` is the global giving you access to easy dependency injection. The container holds all registered services from the core, installed plugins and from other files in the `/services` directory. The registration name is a camelCased version of the file name with the type appended i.e.: `my.js` is registered as `myService`, `custom-thing.js` is registered as `customThingService`.
+The first argument to the `constructor` is the global giving you access to easy dependency injection. The container holds all registered services from the core, installed plugins and from other files in the `/services` directory. The registration name is a camelCased version of the file name with the type appended i.e.: `my-custom.js` is registered as `myCustomService`, `custom-thing.js` is registered as `customThingService`.
 
 You may use the services you define here in custom endpoints by resolving the services defined.
 
@@ -35,7 +37,7 @@ export default () => {
   const router = Router()
 
   router.get("/hello-product", async (req, res) => {
-    const myService = req.scope.resolve("myService")
+    const myService = req.scope.resolve("myCustomService")
 
     res.json({
       message: await myService.getProductMessage()

+ 5 - 0
src/services/__tests__/test-service.spec.ts

@@ -0,0 +1,5 @@
+describe('MyService', () => {
+    it('should do this', async () => {
+        expect(true).toBe(true)
+    })
+})

+ 28 - 10
src/subscribers/README.md

@@ -2,20 +2,38 @@
 
 You may define custom eventhandlers, `subscribers` by creating files in the `/subscribers` directory.
 
-```js
-class WelcomeSubscriber {
-  constructor({ welcomeService, eventBusService }) {
-    this.welcomeService_ = welcomeService;
-
-    eventBusService.subscribe("order.placed", this.handleWelcome);
+```ts
+import MyCustomService from "../services/my-custom";
+import { EntityManager } from "typeorm";
+import { OrderService } from "@medusajs/medusa";
+import { IEventBusService } from "@medusajs/types";
+
+export default class MySubscriber {
+  protected readonly manager_: EntityManager;
+  protected readonly myCustomService_: MyCustomService
+
+  constructor(
+    {
+      manager,
+      eventBusService,
+      myCustomService,
+    }: {
+      manager: EntityManager;
+      eventBusService: IEventBusService;
+      myCustomService: MyCustomService;
+    }
+  ) {
+    this.manager_ = manager;
+    this.myCustomService_ = myCustomService;
+
+    eventBusService.subscribe(OrderService.Events.PLACED, this.handleOrderPlaced);
   }
 
-  handleWelcome = async (data) => {
-    return await this.welcomeService_.sendWelcome(data.id);
-  };
+  handleOrderPlaced = async (data): Promise<any> => {
+    return true;
+  }
 }
 
-export default WelcomeSubscriber;
 ```
 
 A subscriber is defined as a `class` which is registered as a subscriber by invoking `eventBusService.subscribe` in the `constructor` of the class.

+ 22 - 2
tsconfig.json

@@ -1,5 +1,25 @@
 {
   "compilerOptions": {
-    "experimentalDecorators": true
-  }
+    "lib": ["es5", "es6"],
+    "target": "esnext",
+    "allowJs": true,
+    "esModuleInterop": false,
+    "module": "commonjs",
+    "moduleResolution": "node",
+    "emitDecoratorMetadata": true,
+    "experimentalDecorators": true,
+    "skipLibCheck": true,
+    "skipDefaultLibCheck": true,
+    "declaration": false,
+    "sourceMap": false,
+    "outDir": "./dist",
+    "rootDir": "src",
+    "baseUrl": "src"
+  },
+  "include": ["src"],
+  "exclude": [
+    "**/__tests__",
+    "**/__fixtures__",
+    "node_modules"
+  ]
 }

+ 5 - 0
tsconfig.spec.json

@@ -0,0 +1,5 @@
+{
+  "extends": "./tsconfig.json",
+  "include": ["src"],
+  "exclude": ["dist", "node_modules"]
+}

文件差异内容过多而无法显示
+ 628 - 40
yarn.lock


部分文件因为文件数量过多而无法显示