fix(medusa-plugin-contentful): add type and collection entity synchronisation (#1191)

* fix: adds optional type and collection entries on products

* fix: type upsert in product

* fix: type upsert in product

* Update packages/medusa-plugin-contentful/src/services/contentful.js

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>

* Update packages/medusa-plugin-contentful/src/services/contentful.js

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
Sebastian Rindom
2022-03-17 23:29:26 +01:00
committed by GitHub
parent e3655b53f7
commit 36bfdfe6e1

View File

@@ -32,6 +32,8 @@ class ContentfulService extends BaseService {
}) })
this.redis_ = redisClient this.redis_ = redisClient
this.capab_ = {}
} }
async addIgnore_(id, side) { async addIgnore_(id, side) {
@@ -78,14 +80,18 @@ class ContentfulService extends BaseService {
} }
} }
getVariantLinks_(variantEntries) { getLink_(fromEntry) {
return variantEntries.map((v) => ({ return {
sys: { sys: {
type: "Link", type: "Link",
linkType: "Entry", linkType: "Entry",
id: v.sys.id, id: fromEntry.sys.id,
}, },
})) }
}
getVariantLinks_(variantEntries) {
return variantEntries.map((v) => this.getLink_(v))
} }
async createImageAssets(product) { async createImageAssets(product) {
@@ -224,37 +230,7 @@ class ContentfulService extends BaseService {
} }
} }
if (p.type) { await this.createSpecialProductFields(fields, p)
const type = {
"en-US": p.type.value,
}
fields[this.getCustomField("type", "product")] = type
}
if (p.collection) {
const collection = {
"en-US": p.collection.title,
}
fields[this.getCustomField("collection", "product")] = collection
}
if (p.tags) {
const tags = {
"en-US": p.tags,
}
fields[this.getCustomField("tags", "product")] = tags
}
if (p.handle) {
const handle = {
"en-US": p.handle,
}
fields[this.getCustomField("handle", "product")] = handle
}
const result = await environment.createEntryWithId("product", p.id, { const result = await environment.createEntryWithId("product", p.id, {
fields, fields,
@@ -415,6 +391,125 @@ class ContentfulService extends BaseService {
} }
} }
async createCollectionInContentful(collection) {
const hasType = await this.getType("collection")
.then(() => true)
.catch(() => false)
if (!hasType) {
return Promise.resolve()
}
const environment = await this.getContentfulEnvironment_()
const fields = {
[this.getCustomField("medusaId", "collection")]: {
"en-US": collection.id,
},
[this.getCustomField("title", "collection")]: {
"en-US": collection.title,
},
}
const result = await environment.createEntryWithId(
"collection",
collection.id,
{
fields,
}
)
return result
}
async createTypeInContentful(type) {
const hasType = await this.getType("productType")
.then(() => true)
.catch(() => false)
if (!hasType) {
return Promise.resolve()
}
const environment = await this.getContentfulEnvironment_()
const fields = {
[this.getCustomField("medusaId", "type")]: {
"en-US": type.id,
},
[this.getCustomField("name", "type")]: {
"en-US": type.value,
},
}
const result = await environment.createEntryWithId("productType", type.id, {
fields,
})
return result
}
async upsertTypeEntry(type) {
const hasType = await this.getType("productType")
.then(() => true)
.catch(() => false)
if (!hasType) {
return Promise.resolve()
}
const environment = await this.getContentfulEnvironment_()
// check if type exists
let typeEntry = undefined
try {
typeEntry = await environment.getEntry(type.id)
} catch (error) {
return this.createTypeInContentful(type)
}
const typeEntryFields = {
...typeEntry.fields,
[this.getCustomField("name", "type")]: {
"en-US": type.value,
},
}
typeEntry.fields = typeEntryFields
return await typeEntry.update()
}
async upsertCollectionEntry(collection) {
const hasType = await this.getType("collection")
.then(() => true)
.catch(() => false)
if (!hasType) {
return Promise.resolve()
}
const environment = await this.getContentfulEnvironment_()
// check if collection exists
let collectionEntry = undefined
try {
collectionEntry = await environment.getEntry(collection.id)
} catch (error) {
return this.createCollectionInContentful(collection)
}
const collectionEntryFields = {
...collectionEntry.fields,
[this.getCustomField("title", "collection")]: {
"en-US": collection.title,
},
}
collectionEntry.fields = collectionEntryFields
return await collectionEntry.update()
}
async updateProductInContentful(data) { async updateProductInContentful(data) {
const updateFields = [ const updateFields = [
"variants", "variants",
@@ -453,6 +548,7 @@ class ContentfulService extends BaseService {
}) })
const environment = await this.getContentfulEnvironment_() const environment = await this.getContentfulEnvironment_()
// check if product exists // check if product exists
let productEntry = undefined let productEntry = undefined
try { try {
@@ -525,38 +621,7 @@ class ContentfulService extends BaseService {
} }
} }
if (p.type) { await this.createSpecialProductFields(productEntryFields, p)
const type = {
"en-US": p.type.value,
}
productEntryFields[this.getCustomField("type", "product")] = type
}
if (p.collection) {
const collection = {
"en-US": p.collection.title,
}
productEntryFields[this.getCustomField("collection", "product")] =
collection
}
if (p.tags) {
const tags = {
"en-US": p.tags,
}
productEntryFields[this.getCustomField("tags", "product")] = tags
}
if (p.handle) {
const handle = {
"en-US": p.handle,
}
productEntryFields[this.getCustomField("handle", "product")] = handle
}
productEntry.fields = productEntryFields productEntry.fields = productEntryFields
@@ -571,6 +636,59 @@ class ContentfulService extends BaseService {
} }
} }
async createSpecialProductFields(fields, p) {
const capabilities = await this.checkCapabilities("product")
if (p.type) {
if (capabilities.type) {
const val = {
"en-US": this.getLink_(await this.upsertTypeEntry(p.type)),
}
fields[this.getCustomField("type", "product")] = val
} else {
const type = {
"en-US": p.type.value,
}
fields[this.getCustomField("type", "product")] = type
}
}
if (p.collection) {
if (capabilities.collection) {
const val = {
"en-US": this.getLink_(
await this.upsertCollectionEntry(p.collection)
),
}
fields[this.getCustomField("collection", "product")] = val
} else {
const collection = {
"en-US": p.collection.title,
}
fields[this.getCustomField("collection", "product")] = collection
}
}
if (p.tags) {
const tags = {
"en-US": p.tags,
}
fields[this.getCustomField("tags", "product")] = tags
}
if (p.handle) {
const handle = {
"en-US": p.handle,
}
fields[this.getCustomField("handle", "product")] = handle
}
}
async updateProductVariantInContentful(variant) { async updateProductVariantInContentful(variant) {
const updateFields = [ const updateFields = [
"title", "title",
@@ -863,6 +981,43 @@ class ContentfulService extends BaseService {
const environment = await this.getContentfulEnvironment_() const environment = await this.getContentfulEnvironment_()
return environment.getContentType(type) return environment.getContentType(type)
} }
async checkCapabilities(type) {
switch (type) {
case "product":
return this.checkProductCapabilities()
default:
return {}
}
}
async checkProductCapabilities() {
if (this.capab_["product"]) {
return this.capab_["product"]
}
const product = await this.getType("product")
const capabilities = {
collection: false,
type: false,
}
if (product.fields) {
const typeField = product.fields.find((f) => f.id === "type")
if (typeField) {
capabilities.type = typeField.linkType === "Entry"
}
const collectionField = product.fields.find((f) => f.id === "collection")
if (collectionField) {
capabilities.collection = collectionField.linkType === "Entry"
}
}
this.capab_["product"] = capabilities
return capabilities
}
} }
export default ContentfulService export default ContentfulService