medusajs / medusa

Building blocks for digital commerce
https://medusajs.com
MIT License
25.03k stars 2.5k forks source link

Invalid linkable passed for the first argument / Key X is not linkable on service X #8044

Closed Nik0di3m closed 3 months ago

Nik0di3m commented 3 months ago

Describe the bug

When attempting to link the review module to the product module using the defineLink function, an error occurs: "Key review_model_id is not linkable on service reviewModuleService". Additionally, TypeScript errors appear: "Default export of the module has or is using private name 'DefineLinkSymbol'.ts(4082)".

If isList is used in the link configuration, the error "Invalid linkable passed for the first argument" occurs.

System information

Medusa v2.x.x (with relevant plugins)
Node.js version: v20.x.x
Database: PostgreSQL
Operating system: Windows 11
Browser (if relevant): N/A

Steps to reproduce the behavior

Create a review module with the following files:
    index.ts
    models.ts
    service.ts
Attempt to link the review module to the product module using defineLink.
Execute the code and observe the error.

Expected behavior

The defineLink function should successfully link the review module to the product module, allowing access to product reviews.

Screenshots

obraz

Code snippets

Review Module

index.ts:

import { Module } from "@medusajs/utils";
import ReviewModuleService from "./service";

export default Module("reviewModuleService", {
  service: ReviewModuleService,
});

models.ts:

import { model } from "@medusajs/utils";

const ReviewModel = model.define("review_model", {
  id: model.id().primaryKey(),
  rating: model.number().default(0),
  comment: model.text(),
});
export default ReviewModel;

service.ts:

import { MedusaService } from "@medusajs/utils";
import { Logger } from "@medusajs/medusa";
import { EntityManager } from "@mikro-orm/postgresql";
import ReviewModel from "./models/review-model";

type InjectedDependencies = {
  logger: Logger;
  manager: EntityManager;
};

class ReviewModuleService extends MedusaService({
  ReviewModel,
}) {
  protected logger_: Logger;
  protected manager_: EntityManager;

  constructor({ logger, manager }: InjectedDependencies) {
    super(...arguments);
    this.logger_ = logger;
    this.manager_ = manager;
    this.logger_.info("[Review Module Service]: Initialized");
  }
}

export default ReviewModuleService;

Linking Code isList: src/links/review-product.ts

import ReviewModule from "../modules/review";
import ProductModule from "@medusajs/product";
import { defineLink } from "@medusajs/utils";

export default defineLink(
  {
    linkable: ReviewModule.linkable.reviewModel,
    isList: true,
  },
  ProductModule.linkable.product
);

Linking Code isList: src/links/review-product.ts

import ReviewModule from "../modules/review";
import ProductModule from "@medusajs/product";
import { defineLink } from "@medusajs/utils";

export default defineLink(
  ReviewModule.linkable.reviewModel,
  ProductModule.linkable.product
);

Additional context

The error suggests that the key review_model_id is not recognized as linkable. Ensure that the review_model_id is correctly configured as linkable in the review module. If there are additional configurations required to make the review_model_id linkable, please provide guidance on how to achieve this.

olivermrbl commented 3 months ago

@Nik0di3m, can I get you to try to update your project to use the latest preview versions? This issue was resolved in #8014

Feel free to reopen the issue if the error persists.

lexvz14 commented 3 months ago

Hi there,

I'm running into the exact same issue. I believe I have the latest preview versions installed (I got started yesterday).

Any thoughts? I used the exact same code as listed in this issue.

Thanks and best, Lex

olivermrbl commented 3 months ago

@lexvz14, can you share more about your setup? Module, link, etc.

lexvz14 commented 3 months ago

Surely @olivermrbl!

This is the exact error: Error starting server. Error: Key combined_product_id is not linkable on service productCombinationsModuleService

// medusa-config.js 
const modules = {
    ...
    [PRODUCT_COMBINATIONS_MODULE]: {
      resolve: "./modules/product-combinations",
      definition: {
        isQueryable: true
      }
    },
    ...
}

// index.ts
import ProductCombinationsModuleService from "./service"
import { Module } from "@medusajs/utils"

export const PRODUCT_COMBINATIONS_MODULE = "productCombinationsModuleService"

export default Module(PRODUCT_COMBINATIONS_MODULE, {
  service: ProductCombinationsModuleService,
})

// service.ts
import { MedusaService } from "@medusajs/utils";
import { Logger } from "@medusajs/medusa";
import { EntityManager } from "@mikro-orm/postgresql";
import ProductCombinationsModule from "./models";

type InjectedDependencies = {
  logger: Logger;
  manager: EntityManager;
};

class ProductCombinationsModuleService extends MedusaService({
    ProductCombinationsModule,
}) {
  protected logger_: Logger;
  protected manager_: EntityManager;

  constructor({ logger, manager }: InjectedDependencies) {
    super(...arguments);
    this.logger_ = logger;
    this.manager_ = manager;
    this.logger_.info("[Product Combinations Module]: Initialized");
  }
}

export default ProductCombinationsModuleService;

// models.ts
import { model } from "@medusajs/utils";

const CombinedProduct = model.define("combined_product", {
  id: model.id().primaryKey(),
});

export default CombinedProduct;

// migrations-config.ts
import { defineMikroOrmCliConfig } from "@medusajs/utils"
import path from "path"
import CombinedProduct from "./models"
import { PRODUCT_COMBINATIONS_MODULE } from "."

export default defineMikroOrmCliConfig(PRODUCT_COMBINATIONS_MODULE, {
  entities: [CombinedProduct] as any[],
  migrations: {
    path: path.join(__dirname, "migrations"),
  },
})

// links/product-combination.ts
import ProductCombinationsModule from "../modules/product-combinations"
import ProductModule from "@medusajs/product"
import { defineLink } from "@medusajs/utils"

export default defineLink(
    {
        linkable: ProductCombinationsModule.linkable.combinedProduct,
        isList: true,
    },
    ProductModule.linkable.product
);

// package.json
{
  "name": "medusa-starter-default",
  "version": "0.0.1",
  "description": "A starter for Medusa projects.",
  "author": "Medusa (https://medusajs.com)",
  "license": "MIT",
  "keywords": [
    "sqlite",
    "postgres",
    "typescript",
    "ecommerce",
    "headless",
    "medusa"
  ],
  "scripts": {
    "build": "medusa build",
    "seed": "medusa exec ./src/scripts/seed.ts",
    "start": "medusa start",
    "dev": "medusa develop"
  },
  "dependencies": {
    "@medusajs/api-key": "preview",
    "@medusajs/auth": "preview",
    "@medusajs/cache-inmemory": "preview",
    "@medusajs/cache-redis": "^1.9.2-preview-20240712210456",
    "@medusajs/cart": "preview",
    "@medusajs/currency": "preview",
    "@medusajs/customer": "preview",
    "@medusajs/event-bus-local": "preview",
    "@medusajs/event-bus-redis": "^1.8.14-preview-20240712210456",
    "@medusajs/file": "preview",
    "@medusajs/file-local-next": "preview",
    "@medusajs/fulfillment": "preview",
    "@medusajs/fulfillment-manual": "preview",
    "@medusajs/inventory-next": "preview",
    "@medusajs/medusa": "preview",
    "@medusajs/notification": "preview",
    "@medusajs/notification-local": "preview",
    "@medusajs/order": "preview",
    "@medusajs/payment": "preview",
    "@medusajs/payment-stripe": "^0.0.3-preview-20240712210456",
    "@medusajs/pricing": "preview",
    "@medusajs/product": "preview",
    "@medusajs/promotion": "preview",
    "@medusajs/region": "preview",
    "@medusajs/sales-channel": "preview",
    "@medusajs/stock-location-next": "preview",
    "@medusajs/store": "preview",
    "@medusajs/tax": "preview",
    "@medusajs/user": "preview",
    "@medusajs/workflow-engine-inmemory": "preview",
    "express": "^4.17.2",
    "medusa-plugin-meilisearch": "preview"
  },
  "devDependencies": {
    "@medusajs/medusa-cli": "preview",
    "@mikro-orm/cli": "5.9.7",
    "@mikro-orm/core": "5.9.7",
    "@mikro-orm/migrations": "5.9.7",
    "@mikro-orm/postgresql": "5.9.7",
    "@stdlib/number-float64-base-normalize": "0.0.8",
    "@swc/core": "1.5.7",
    "@types/express": "^4.17.13",
    "@types/mime": "1.3.5",
    "@types/node": "^17.0.8",
    "@types/react": "^18.3.2",
    "ts-node": "^10.9.2",
    "typescript": "^4.5.2"
  },
  "resolutions": {
    "**/@medusajs/medusa-cli": "link:./node_modules/@medusajs/medusa-cli"
  },
  "engines": {
    "node": ">=20"
  }
}

I also tried to link like so:

import ProductCombinationsModule from "../modules/product-combinations"
import ProductModule from "@medusajs/product"
import { defineLink } from "@medusajs/utils"

export default defineLink(
    ProductCombinationsModule.linkable.combinedProduct,
    ProductModule.linkable.product
);
Nik0di3m commented 3 months ago

Hi, I just got back from vacation and checked to see if anything had moved with the problem.

Overall it is much better than last time but there is still a problem with linking modules after the medusa update.

I tried with the hello module from the documentation. Migrations are created without problems, unfortunately with linking modules it still displays an error.

I tried with different databases (local, NeonDB) and the same problem occurs on everything.

Error: Key my_custom_id is not linkable on service helloModuleService

obraz

Below I am sending the link to the public repository to keep as every line of code.

https://github.com/Nik0di3m/meduas-not-linkable

@lexvz14 let us know if you have dealt with the problem

imash96 commented 3 months ago

In the snapshot version issue is resolved https://github.com/medusajs/medusa/pull/8194

The pull request is not yet merged till then you can use the snapshot version

Replace preview with snapshot in your package.json or wait till PR is merged