Browse Source

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

olivermrbl 2 years ago
parent
commit
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
 // Jest needs to compile this code, but generally we don't want this copied
 // to output folders
 // to output folders
 if (process.env.NODE_ENV !== `test`) {
 if (process.env.NODE_ENV !== `test`) {
-  ignore.push(`**/__tests__`);
+  ignore.push(`**/__tests__`)
 }
 }
 
 
 module.exports = {
 module.exports = {
   presets: [["babel-preset-medusa-package"], ["@babel/preset-typescript"]],
   presets: [["babel-preset-medusa-package"], ["@babel/preset-typescript"]],
   ignore,
   ignore,
-};
+}

+ 12 - 3
.gitignore

@@ -4,6 +4,15 @@
 /uploads
 /uploads
 /node_modules
 /node_modules
 yarn-error.log
 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>
   </a>
 </p>
 </p>
 
 
-## Getting Started
+## Compatibility
 
 
 This starter is compatible with versions >= 1.8.0 of `@medusajs/medusa`. 
 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_TYPE = process.env.DATABASE_TYPE;
 const DATABASE_URL = process.env.DATABASE_URL;
 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 = [
 const plugins = [
   `medusa-fulfillment-manual`,
   `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"]} */
 /** @type {import('@medusajs/medusa').ConfigModule["projectConfig"]} */
 const projectConfig = {
 const projectConfig = {
+  jwtSecret: process.env.JWT_SECRET,
+  cookieSecret: process.env.COOKIE_SECRET,
   database_database: "./medusa-db.sql",
   database_database: "./medusa-db.sql",
   database_type: DATABASE_TYPE || "sqlite",
   database_type: DATABASE_TYPE || "sqlite",
   store_cors: STORE_CORS,
   store_cors: STORE_CORS,
@@ -65,4 +82,5 @@ if (DATABASE_URL) {
 module.exports = {
 module.exports = {
   projectConfig,
   projectConfig,
   plugins,
   plugins,
+	modules,
 };
 };

+ 64 - 15
package.json

@@ -4,36 +4,85 @@
   "description": "A starter for Medusa projects.",
   "description": "A starter for Medusa projects.",
   "author": "Sebastian Rindom <skrindom@gmail.com>",
   "author": "Sebastian Rindom <skrindom@gmail.com>",
   "license": "MIT",
   "license": "MIT",
+  "keywords": [
+    "sqlite",
+    "postgres",
+    "typescript",
+    "ecommerce",
+    "headless",
+    "medusa"
+  ],
   "scripts": {
   "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",
     "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"
     "build:admin": "medusa-admin build"
   },
   },
   "dependencies": {
   "dependencies": {
+    "@babel/preset-typescript": "^7.21.4",
     "@medusajs/admin": "rc",
     "@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": "rc",
     "@medusajs/medusa-cli": "rc",
     "@medusajs/medusa-cli": "rc",
     "@medusajs/modules-sdk": "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-fulfillment-manual": "rc",
     "medusa-interfaces": "rc",
     "medusa-interfaces": "rc",
     "medusa-payment-manual": "rc",
     "medusa-payment-manual": "rc",
     "medusa-payment-stripe": "rc",
     "medusa-payment-stripe": "rc",
     "typeorm": "^0.3.11"
     "typeorm": "^0.3.11"
   },
   },
-  "repository": "https://github.com/medusajs/medusa-starter-default.git",
-  "keywords": [
-    "sqlite",
-    "ecommerce",
-    "headless",
-    "medusa"
-  ],
   "devDependencies": {
   "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
 # 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 { 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
 // src/models/post.ts
 
 
 import { BeforeInsert, Column, Entity, PrimaryColumn } from "typeorm";
 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()
 @Entity()
 export class Post extends BaseEntity {
 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`.
 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.
 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()
   const router = Router()
 
 
   router.get("/hello-product", async (req, res) => {
   router.get("/hello-product", async (req, res) => {
-    const myService = req.scope.resolve("myService")
+    const myService = req.scope.resolve("myCustomService")
 
 
     res.json({
     res.json({
       message: await myService.getProductMessage()
       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.
 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.
 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": {
   "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"]
+}

File diff suppressed because it is too large
+ 628 - 40
yarn.lock


Some files were not shown because too many files changed in this diff