Skip to content
This repository was archived by the owner on Nov 16, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add new apis and new get items
  • Loading branch information
yiyione committed May 31, 2021
commit 501b7f9a16ed9d36b9ab3505f4e853b5b6d14275
141 changes: 141 additions & 0 deletions rest_server/src/controllers/item_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,152 @@ const del = asyncHandler(async (req, res, next) => {
}
});

const listTags = asyncHandler(async (req, res, next) => {
try {
let result = await MarketplaceItem.get(req.params.itemId);
if (checkReadPermission(req.userInfo, result)) {
result = await MarketplaceItem.getTags(result);
if (isNil(result)) {
return next(error.createNotFound());
} else {
res.status(200).json(result);
}
} else {
return next(
error.createForbidden(
`The access to the item ${req.params.itemId} is forbidden`,
),
);
}
} catch (e) {
return next(error.createInternalServerError(e));
}
});

const addTag = asyncHandler(async (req, res, next) => {
try {
let result = await MarketplaceItem.get(req.params.itemId);
if (checkReadPermission(req.userInfo, result)) {
result = await MarketplaceItem.addTag(result, req.params.tagId);
if (isNil(result)) {
return next(error.createNotFound());
} else {
res.status(200).send('added');
}
} else {
return next(
error.createForbidden(
`The access to the item ${req.params.itemId} is forbidden`,
),
);
}
} catch (e) {
return next(error.createInternalServerError(e));
}
});

const deleteTag = asyncHandler(async (req, res, next) => {
try {
let result = await MarketplaceItem.get(req.params.itemId);
if (checkReadPermission(req.userInfo, result)) {
result = await MarketplaceItem.deleteTag(result, req.params.tagId);
if (isNil(result)) {
return next(error.createNotFound());
} else {
res.status(200).json('deleted');
}
} else {
return next(
error.createForbidden(
`The access to the item ${req.params.itemId} is forbidden`,
),
);
}
} catch (e) {
return next(error.createInternalServerError(e));
}
});

const listCategories = asyncHandler(async (req, res, next) => {
try {
let result = await MarketplaceItem.get(req.params.itemId);
if (checkReadPermission(req.userInfo, result)) {
result = await MarketplaceItem.getCategories(result);
if (isNil(result)) {
return next(error.createNotFound());
} else {
res.status(200).json(result);
}
} else {
return next(
error.createForbidden(
`The access to the item ${req.params.itemId} is forbidden`,
),
);
}
} catch (e) {
return next(error.createInternalServerError(e));
}
});

const addCategory = asyncHandler(async (req, res, next) => {
try {
let result = await MarketplaceItem.get(req.params.itemId);
if (checkReadPermission(req.userInfo, result)) {
result = await MarketplaceItem.addCategory(result, req.params.categoryId);
if (isNil(result)) {
return next(error.createNotFound());
} else {
res.status(200).send('added');
}
} else {
return next(
error.createForbidden(
`The access to the item ${req.params.itemId} is forbidden`,
),
);
}
} catch (e) {
return next(error.createInternalServerError(e));
}
});

const deleteCategory = asyncHandler(async (req, res, next) => {
try {
let result = await MarketplaceItem.get(req.params.itemId);
if (checkReadPermission(req.userInfo, result)) {
result = await MarketplaceItem.deleteCategory(
result,
req.params.categoryId,
);
if (isNil(result)) {
return next(error.createNotFound());
} else {
res.status(200).json('deleted');
}
} else {
return next(
error.createForbidden(
`The access to the item ${req.params.itemId} is forbidden`,
),
);
}
} catch (e) {
return next(error.createInternalServerError(e));
}
});

// module exports
module.exports = {
list,
create,
get,
update,
del,
listTags,
addTag,
deleteTag,
listCategories,
addCategory,
deleteCategory,
};
112 changes: 98 additions & 14 deletions rest_server/src/models/marketplace_item.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
const { isNil, toLower } = require('lodash');
const { Op, fn, col, where } = require('sequelize');
const { Op, fn, col, where, cast } = require('sequelize');
const modelSyncHandler = require('./model_init_handler');

class MarketplaceItem {
Expand Down Expand Up @@ -97,16 +97,6 @@ class MarketplaceItem {
if (source) {
filterStatement.source = source;
}
if (tags) {
filterStatement.tags = {
[Op.contains]: tags,
};
}
if (categories) {
filterStatement.categories = {
[Op.contains]: categories,
};
}
if (keyword) {
const lowerKeyword = toLower(keyword);
filterStatement[Op.or] = [
Expand All @@ -128,7 +118,7 @@ class MarketplaceItem {
summary: where(
fn('LOWER', col('summary')),
Op.substring,
`%${lowerKeyword}%`,
```%${lowerKeyword}%`,
),
},
];
Expand Down Expand Up @@ -171,11 +161,57 @@ class MarketplaceItem {
},
];
}
const items = await this.orm.findAll({ where: filterStatement });
const havings = [];
if (tags) {
havings.push({
where: where(
fn('array_agg', col('ItemTags.name')),
Op.contains,
cast(tags, 'varchar[]'),
),
});
}
if (categories) {
havings.push({
where: where(
fn('array_agg', col('ItemCategories.name')),
Op.contains,
cast(categories, 'varchar[]'),
),
});
}
const items = await this.orm.findAll({
where: filterStatement,
having: havings,
group: [
'MarketplaceItem.id',
'ItemTags.id',
'ItemTags->ItemTagRelation.createdAt',
'ItemTags->ItemTagRelation.updatedAt',
'ItemTags->ItemTagRelation.MarketplaceItemId',
'ItemTags->ItemTagRelation.ItemTagId',
'ItemCategories.id',
'ItemCategories->ItemCategoryRelation.createdAt',
'ItemCategories->ItemCategoryRelation.updatedAt',
'ItemCategories->ItemCategoryRelation.MarketplaceItemId',
'ItemCategories->ItemCategoryRelation.ItemCategoryId',
],
include: [
{
attributes: ['id', 'name', 'color'],
model: this.models.ItemTag.orm,
through: { attributes: [] },
},
{
attributes: ['id', 'name'],
model: this.models.ItemCategory.orm,
through: { attributes: [] },
},
],
});
return items;
},
);

return await handler(
name,
author,
Expand Down Expand Up @@ -306,6 +342,54 @@ class MarketplaceItem {

return await handler(itemId, this.models);
}

async getTags(item) {
const handler = modelSyncHandler(async item => {
return await item.getItemTags();
});

return await handler(item, this.models);
}

async addTag(item, tagId) {
const handler = modelSyncHandler(async itemId => {
return await item.addItemTag(tagId);
});

return await handler(item, this.models);
}

async deleteTag(item, tagId) {
const handler = modelSyncHandler(async item => {
return await item.removeItemTag(tagId);
});

return await handler(item, this.models);
}

async getCategories(item) {
const handler = modelSyncHandler(async item => {
return await item.getItemCategories();
});

return await handler(item, this.models);
}

async addCategory(item, tagId) {
const handler = modelSyncHandler(async item => {
return await item.addItemCategory(tagId);
});

return await handler(item, this.models);
}

async deleteCategory(item, tagId) {
const handler = modelSyncHandler(async item => {
return await item.removeItemCategory(tagId);
});

return await handler(item, this.models);
}
}

module.exports = MarketplaceItem;
12 changes: 6 additions & 6 deletions rest_server/src/models/model_init_handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ const createTemplates = async models => {
const marketplaceItem = await models.MarketplaceItem.orm.create(
newItem,
);
if (Array.isArray(item.categories)) {
for (const categoryName of item.categories) {
itemTags.push([categoryName, marketplaceItem.id]);
if (Array.isArray(newItem.categories)) {
for (const categoryName of newItem.categories) {
itemCategories.push([categoryName, marketplaceItem.id]);
}
}
if (Array.isArray(item.tags)) {
for (const tagName of item.tags) {
itemCategories.push([tagName, marketplaceItem.id]);
if (Array.isArray(newItem.tags)) {
for (const tagName of newItem.tags) {
itemTags.push([tagName, marketplaceItem.id]);
}
}
} catch (err) {
Expand Down
18 changes: 18 additions & 0 deletions rest_server/src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,24 @@ router
.put(token.checkAuthAndGetTokenInfo, itemController.update)
.delete(token.checkAuthAndGetTokenInfo, itemController.del);

router
.route('/items/:itemId/tag')
.get(token.checkAuthAndGetUserInfo, itemController.listTags);

router
.route('/items/:itemId/tag/:tagId')
.post(token.checkAuthAndGetUserInfo, itemController.addTag)
.delete(token.checkAuthAndGetUserInfo, itemController.deleteTag);

router
.route('/items/:itemId/category')
.get(token.checkAuthAndGetUserInfo, itemController.listCategories);

router
.route('/items/:itemId/category/:categoryId')
.post(token.checkAuthAndGetUserInfo, itemController.addCategory)
.delete(token.checkAuthAndGetUserInfo, itemController.deleteCategory);

router
.route('/tags')
.get(token.checkAuthAndGetUserInfo, tagController.list)
Expand Down