@paralect/hive 0.1.49 → 0.1.50-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.hive/.babelrc +3 -0
- package/.hive/.cursor/commands/add-endpoint.md +262 -0
- package/.hive/.cursor/commands/add-handler.md +137 -0
- package/.hive/.cursor/commands/add-middleware.md +95 -0
- package/.hive/.cursor/commands/add-resource.md +71 -0
- package/.hive/.cursor/commands/add-scheduler.md +138 -0
- package/.hive/.cursor/commands/add-service.md +188 -0
- package/.hive/.cursor/skills/hive-auth/SKILL.md +134 -0
- package/.hive/.cursor/skills/hive-database/SKILL.md +103 -0
- package/.hive/.cursor/skills/hive-endpoint/SKILL.md +103 -0
- package/.hive/.cursor/skills/hive-handler/SKILL.md +88 -0
- package/.hive/.cursor/skills/hive-mapping/SKILL.md +85 -0
- package/.hive/.cursor/skills/hive-middleware/SKILL.md +104 -0
- package/.hive/.cursor/skills/hive-overview/SKILL.md +50 -0
- package/.hive/.cursor/skills/hive-scheduler/SKILL.md +94 -0
- package/.hive/.cursor/skills/hive-schema/SKILL.md +73 -0
- package/.hive/.cursor/skills/hive-service/SKILL.md +90 -0
- package/.hive/.dockerignore +1 -0
- package/.hive/Dockerfile +22 -0
- package/.hive/Dockerfile.dev +33 -0
- package/.hive/Dockerfile.prod +29 -0
- package/.hive/README.md +11 -0
- package/.hive/bin/deploy.sh +5 -0
- package/.hive/bin/start.sh +2 -0
- package/.hive/bootstrap-hive.js +118 -0
- package/.hive/deploy/api/Chart.yaml +6 -0
- package/.hive/deploy/api/staging.yaml +3 -0
- package/.hive/deploy/api/templates/deployment.yaml +44 -0
- package/.hive/deploy/api/templates/ingress.yaml +26 -0
- package/.hive/deploy/api/templates/service.yaml +14 -0
- package/.hive/deploy/script/Dockerfile +39 -0
- package/.hive/deploy/script/package-lock.json +1499 -0
- package/.hive/deploy/script/package.json +12 -0
- package/.hive/deploy/script/src/config.js +48 -0
- package/.hive/deploy/script/src/index.js +108 -0
- package/.hive/deploy/script/src/util.js +19 -0
- package/.hive/initial-data.json +176 -0
- package/.hive/package-lock.json +10242 -0
- package/.hive/package.json +98 -0
- package/.hive/ship_logo.png +0 -0
- package/.hive/src/app-config/app.js +3 -0
- package/.hive/src/app-config/assertEnv.js +15 -0
- package/.hive/src/app-config/index.js +62 -0
- package/.hive/src/app.js +69 -0
- package/.hive/src/assets/emails/components/header.mjml +13 -0
- package/.hive/src/assets/emails/dist/.gitkeep +0 -0
- package/.hive/src/assets/emails/signup-welcome.mjml +34 -0
- package/.hive/src/assets/emails/styles/index.mjml +77 -0
- package/.hive/src/autoMap/addHandlers.js +142 -0
- package/.hive/src/autoMap/getDependentFields.js +37 -0
- package/.hive/src/autoMap/mapSchema.js +99 -0
- package/.hive/src/autoMap/schemaMappings.js +13 -0
- package/.hive/src/autoMap/schemaMappings.json +3 -0
- package/.hive/src/bullMqBus.js +21 -0
- package/.hive/src/bullMqWrapper.js +23 -0
- package/.hive/src/db.js +52 -0
- package/.hive/src/emails/MyEmailComponent.jsx +14 -0
- package/.hive/src/emails/compiled/MyEmailComponent.js +18 -0
- package/.hive/src/emails/compiled/compiled/MyEmailComponent.js +18 -0
- package/.hive/src/helpers/db/ifUpdated.js +22 -0
- package/.hive/src/helpers/getMiddlewares.js +38 -0
- package/.hive/src/helpers/getResourceEndpoints.js +28 -0
- package/.hive/src/helpers/getResources.js +32 -0
- package/.hive/src/helpers/getSchemas.js +50 -0
- package/.hive/src/helpers/importHandlers.js +29 -0
- package/.hive/src/helpers/isZodArray.js +13 -0
- package/.hive/src/helpers/prettierFormat.js +8 -0
- package/.hive/src/helpers/schema/db.schema.js +9 -0
- package/.hive/src/helpers/schema/pagination.schema.js +14 -0
- package/.hive/src/ioEmitter.js +9 -0
- package/.hive/src/jsconfig.json +5 -0
- package/.hive/src/lib/node-mongo/.github/workflows/npm-publish.yml +32 -0
- package/.hive/src/lib/node-mongo/API.md +654 -0
- package/.hive/src/lib/node-mongo/CHANGELOG.md +98 -0
- package/.hive/src/lib/node-mongo/README.md +97 -0
- package/.hive/src/lib/node-mongo/package-lock.json +3682 -0
- package/.hive/src/lib/node-mongo/package.json +74 -0
- package/.hive/src/lib/node-mongo/src/index.js +64 -0
- package/.hive/src/lib/node-mongo/src/mongo-query-service.js +78 -0
- package/.hive/src/lib/node-mongo/src/mongo-service-error.js +15 -0
- package/.hive/src/lib/node-mongo/src/mongo-service.js +303 -0
- package/.hive/src/logger.js +43 -0
- package/.hive/src/middlewares/allowNoAuth.js +9 -0
- package/.hive/src/middlewares/attachUser.js +41 -0
- package/.hive/src/middlewares/global/extractUserTokens.js +15 -0
- package/.hive/src/middlewares/global/tryToAttachUser.js +33 -0
- package/.hive/src/middlewares/isAuthorized.js +18 -0
- package/.hive/src/middlewares/shouldExist.js +37 -0
- package/.hive/src/middlewares/shouldNotExist.js +19 -0
- package/.hive/src/middlewares/uploadFile.js +5 -0
- package/.hive/src/middlewares/validate.js +32 -0
- package/.hive/src/migrations/migration.js +8 -0
- package/.hive/src/migrations/migration.service.js +73 -0
- package/.hive/src/migrations/migrations/1.js +22 -0
- package/.hive/src/migrations/migrations-log/migration-log.schema.js +13 -0
- package/.hive/src/migrations/migrations-log/migration-log.service.js +50 -0
- package/.hive/src/migrations/migrations.schema.js +6 -0
- package/.hive/src/migrations/migrator.js +75 -0
- package/.hive/src/migrator.js +4 -0
- package/.hive/src/resources/_dev/endpoints/triggerSchedulerHandler.js +32 -0
- package/.hive/src/resources/health/endpoints/get.js +19 -0
- package/.hive/src/resources/schemaMappings/schemaMappings.schema.js +6 -0
- package/.hive/src/resources/tokens/methods/generateSecureToken.js +9 -0
- package/.hive/src/resources/tokens/methods/setToken.js +8 -0
- package/.hive/src/resources/tokens/methods/storeToken.js +35 -0
- package/.hive/src/resources/tokens/tokens.schema.js +11 -0
- package/.hive/src/resources/users/endpoints/getCurrentUser.js +14 -0
- package/.hive/src/resources/users/endpoints/getUserProfile.js +19 -0
- package/.hive/src/resources/users/handlers/test.js +1 -0
- package/.hive/src/resources/users/methods/ensureUserCreated.js +68 -0
- package/.hive/src/resources/users/users.schema.js +16 -0
- package/.hive/src/routes/index.js +172 -0
- package/.hive/src/routes/middlewares/attachCustomErrors.js +28 -0
- package/.hive/src/routes/middlewares/routeErrorHandler.js +27 -0
- package/.hive/src/scheduler/handlers/sendDailyReport.example.js +7 -0
- package/.hive/src/scheduler.js +32 -0
- package/.hive/src/security.util.js +38 -0
- package/.hive/src/services/emailService.js +15 -0
- package/.hive/src/services/globalTest.js +0 -0
- package/.hive/src/services/setCookie.js +21 -0
- package/.hive/src/socketIo.js +99 -0
- package/.hive/tsconfig.json +31 -0
- package/cli/helpers/docker.js +59 -0
- package/cli/helpers/envCheck.js +127 -0
- package/cli/helpers/findPort.js +32 -0
- package/cli/hive.js +91 -17
- package/package.json +1 -1
- package/starter/loader.mjs +40 -0
- package/starter/package-lock.json +3512 -262
- package/starter/package.json +7 -2
- package/starter/register.mjs +6 -0
- package/starter/src/app-config/index.js +3 -0
- package/starter/src/app.js +10 -14
- package/starter/src/autoMap/addHandlers.js +3 -3
- package/starter/src/autoMap/getDependentFields.js +1 -1
- package/starter/src/autoMap/mapSchema.js +2 -2
- package/starter/src/bullMqBus.js +1 -1
- package/starter/src/bullMqWrapper.js +1 -1
- package/starter/src/db.js +12 -11
- package/starter/src/helpers/esm.js +56 -0
- package/starter/src/helpers/getMiddlewares.js +3 -0
- package/starter/src/helpers/getResourceEndpoints.js +3 -0
- package/starter/src/helpers/getResources.js +3 -0
- package/starter/src/helpers/getSchemas.js +3 -0
- package/starter/src/helpers/importHandlers.js +11 -20
- package/starter/src/ioEmitter.js +1 -1
- package/starter/src/logger.js +1 -1
- package/starter/src/middlewares/attachUser.js +2 -2
- package/starter/src/middlewares/global/tryToAttachUser.js +1 -1
- package/starter/src/middlewares/shouldExist.js +1 -1
- package/starter/src/middlewares/shouldNotExist.js +1 -1
- package/starter/src/migrations/migration.service.js +4 -1
- package/starter/src/migrations/migrations-log/migration-log.schema.js +1 -1
- package/starter/src/migrations/migrations-log/migration-log.service.js +1 -1
- package/starter/src/migrations/migrations.schema.js +1 -1
- package/starter/src/migrations/migrator.js +1 -1
- package/starter/src/migrator.js +2 -3
- package/starter/src/resources/schemaMappings/schemaMappings.schema.js +1 -1
- package/starter/src/resources/tokens/methods/setToken.js +1 -1
- package/starter/src/resources/tokens/methods/storeToken.js +2 -2
- package/starter/src/resources/tokens/tokens.schema.js +1 -1
- package/starter/src/resources/users/endpoints/getCurrentUser.js +1 -1
- package/starter/src/resources/users/endpoints/getUserProfile.js +1 -1
- package/starter/src/resources/users/methods/ensureUserCreated.js +1 -1
- package/starter/src/resources/users/users.schema.js +1 -1
- package/starter/src/routes/index.js +8 -8
- package/starter/src/routes/middlewares/routeErrorHandler.js +1 -1
- package/starter/src/scheduler.js +10 -7
- package/starter/src/services/emailService.js +1 -1
- package/starter/src/services/setCookie.js +2 -2
- package/starter/src/socketIo.js +3 -3
- package/test-app/.cursor/commands/add-endpoint.md +262 -0
- package/test-app/.cursor/commands/add-handler.md +137 -0
- package/test-app/.cursor/commands/add-middleware.md +95 -0
- package/test-app/.cursor/commands/add-resource.md +71 -0
- package/test-app/.cursor/commands/add-scheduler.md +138 -0
- package/test-app/.cursor/commands/add-service.md +188 -0
- package/test-app/.cursor/skills/hive-auth/SKILL.md +134 -0
- package/test-app/.cursor/skills/hive-database/SKILL.md +103 -0
- package/test-app/.cursor/skills/hive-endpoint/SKILL.md +103 -0
- package/test-app/.cursor/skills/hive-handler/SKILL.md +88 -0
- package/test-app/.cursor/skills/hive-mapping/SKILL.md +85 -0
- package/test-app/.cursor/skills/hive-middleware/SKILL.md +104 -0
- package/test-app/.cursor/skills/hive-overview/SKILL.md +50 -0
- package/test-app/.cursor/skills/hive-scheduler/SKILL.md +94 -0
- package/test-app/.cursor/skills/hive-schema/SKILL.md +73 -0
- package/test-app/.cursor/skills/hive-service/SKILL.md +90 -0
- package/test-app/package-lock.json +462 -0
- package/test-app/package.json +21 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const rootDir = path.resolve(__dirname, "./../../../");
|
|
3
|
+
|
|
4
|
+
const ENV = process.env;
|
|
5
|
+
|
|
6
|
+
const config = {
|
|
7
|
+
rootDir,
|
|
8
|
+
|
|
9
|
+
environment: ENV.ENVIRONMENT || "staging",
|
|
10
|
+
|
|
11
|
+
namespace: ENV.NAMESPACE || "staging",
|
|
12
|
+
|
|
13
|
+
kubeConfig: ENV.KUBE_CONFIG,
|
|
14
|
+
|
|
15
|
+
home: ENV.HOME,
|
|
16
|
+
|
|
17
|
+
dockerRegistry: {
|
|
18
|
+
name: "paralect/hive-api",
|
|
19
|
+
username: ENV.DOCKER_AUTH_USERNAME,
|
|
20
|
+
password: ENV.DOCKER_AUTH_PASSWORD,
|
|
21
|
+
|
|
22
|
+
imageTag: ENV.IMAGE_TAG,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const deployConfig = {
|
|
27
|
+
dockerRepo: `${config.dockerRegistry.name}`,
|
|
28
|
+
dir: `${rootDir}`,
|
|
29
|
+
folder: "",
|
|
30
|
+
dockerFilePath: `${rootDir}/Dockerfile`,
|
|
31
|
+
dockerContextDir: rootDir
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Object.keys(deployConfig).forEach((serviceName) => {
|
|
35
|
+
// if (!deployConfig[serviceName].dockerFilePath) {
|
|
36
|
+
// deployConfig[
|
|
37
|
+
// serviceName
|
|
38
|
+
// ].dockerFilePath = `${deployConfig[serviceName].dir}/Dockerfile`;
|
|
39
|
+
// }
|
|
40
|
+
|
|
41
|
+
// if (!deployConfig[serviceName].dockerContextDir) {
|
|
42
|
+
// deployConfig[serviceName].dockerContextDir = deployConfig[serviceName].dir;
|
|
43
|
+
// }
|
|
44
|
+
// });
|
|
45
|
+
|
|
46
|
+
config.deploy = deployConfig;
|
|
47
|
+
|
|
48
|
+
module.exports = config;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const List = require("prompt-list");
|
|
3
|
+
|
|
4
|
+
const config = require("./config");
|
|
5
|
+
const { execCommand } = require("./util");
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
const buildAndPushImage = async ({
|
|
9
|
+
dockerFilePath,
|
|
10
|
+
dockerRepo,
|
|
11
|
+
dockerContextDir,
|
|
12
|
+
imageTag,
|
|
13
|
+
environment,
|
|
14
|
+
}) => {
|
|
15
|
+
await execCommand(`docker build \
|
|
16
|
+
--build-arg APP_ENV=${environment} \
|
|
17
|
+
-f ${dockerFilePath} \
|
|
18
|
+
-t ${dockerRepo} \
|
|
19
|
+
${dockerContextDir}`);
|
|
20
|
+
await execCommand(`docker tag ${dockerRepo} ${imageTag}`);
|
|
21
|
+
await execCommand(`docker push ${imageTag}`);
|
|
22
|
+
await execCommand(`docker push ${dockerRepo}:latest`);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const pushToKubernetes = async ({ imageTag, appName, deployConfig }) => {
|
|
26
|
+
const deployDir = `${config.rootDir}/deploy/api`;
|
|
27
|
+
|
|
28
|
+
if (config.kubeConfig && !fs.existsSync(`${config.home}/.kube/config`)) {
|
|
29
|
+
console.log("Creating kubeconfig");
|
|
30
|
+
fs.mkdirSync(`${config.home}/.kube`);
|
|
31
|
+
fs.writeFileSync(`${config.home}/.kube/config`, config.kubeConfig);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let projectId = process.env.PROJECT_ID || 'core';
|
|
35
|
+
let attachedDomains;
|
|
36
|
+
|
|
37
|
+
await execCommand(
|
|
38
|
+
`helm upgrade --force --install projects-${projectId} ${deployDir} \
|
|
39
|
+
--namespace apps --create-namespace \
|
|
40
|
+
--set containerRegistry=paralect/hive-api \
|
|
41
|
+
--set service=hive-api-${projectId} \
|
|
42
|
+
--set imagesVersion=${imageTag} \
|
|
43
|
+
--set domain={hive-api-${projectId}.paralect.co} \
|
|
44
|
+
--set projectId=${projectId} \
|
|
45
|
+
--set env\[0\].name=MONGODB_URI \
|
|
46
|
+
--set env\[0\].value='${process.env.MONGODB_URI}' \
|
|
47
|
+
-f ${deployDir}/staging.yaml --timeout 35m`,
|
|
48
|
+
{
|
|
49
|
+
// cwd: `/app`,
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const deploy = async () => {
|
|
55
|
+
if (config.dockerRegistry.password) {
|
|
56
|
+
await execCommand(
|
|
57
|
+
`docker login --username ${config.dockerRegistry.username} --password ${config.dockerRegistry.password} registry.digitalocean.com`
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
const deployConfig = config.deploy;
|
|
61
|
+
|
|
62
|
+
let imageTag = config.dockerRegistry.imageTag;
|
|
63
|
+
|
|
64
|
+
if (!imageTag) {
|
|
65
|
+
const { stdout: branch } = await execCommand(
|
|
66
|
+
"git rev-parse --abbrev-ref HEAD",
|
|
67
|
+
{ stdio: "pipe" }
|
|
68
|
+
);
|
|
69
|
+
const { stdout: commitSHA } = await execCommand("git rev-parse HEAD", {
|
|
70
|
+
stdio: "pipe",
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
imageTag = `${branch}.${commitSHA}`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
await execCommand(
|
|
78
|
+
"kubectl delete secrets sh.helm.release.v1.apps-staging-api.v1"
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
await execCommand(
|
|
82
|
+
"kubectl delete secrets sh.helm.release.v1.apps-staging-api.v2"
|
|
83
|
+
);
|
|
84
|
+
} catch (err) {}
|
|
85
|
+
|
|
86
|
+
// push api image to registry
|
|
87
|
+
await buildAndPushImage({
|
|
88
|
+
...deployConfig,
|
|
89
|
+
imageTag: `${deployConfig.dockerRepo}:${imageTag}`,
|
|
90
|
+
environment: config.environment,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
if (!process.env.SKIP_KUBERNETES) {
|
|
94
|
+
// deploy api to kubernetes and deploy migrator through helm hooks
|
|
95
|
+
await pushToKubernetes({
|
|
96
|
+
imageTag,
|
|
97
|
+
appName: "api",
|
|
98
|
+
deployConfig,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
deploy();
|
|
104
|
+
|
|
105
|
+
process.on("unhandledRejection", (error) => {
|
|
106
|
+
console.error(error);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const execa = require('execa');
|
|
2
|
+
|
|
3
|
+
const execCommand = async (command, options = {}) => {
|
|
4
|
+
let commandParts = command;
|
|
5
|
+
|
|
6
|
+
if (typeof command === 'string') {
|
|
7
|
+
commandParts = command.split(' ').filter(part => !!part.trim());
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const commandName = commandParts.shift();
|
|
11
|
+
const commandArguments = commandParts;
|
|
12
|
+
console.log('command', command);
|
|
13
|
+
|
|
14
|
+
return execa(commandName, commandArguments, { stdio: 'inherit', ...options });
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
module.exports = {
|
|
18
|
+
execCommand,
|
|
19
|
+
};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
{
|
|
2
|
+
"resources": [
|
|
3
|
+
{
|
|
4
|
+
"name": "users",
|
|
5
|
+
"endpoints": [
|
|
6
|
+
{
|
|
7
|
+
"name": "getCurrentUser",
|
|
8
|
+
"endpoint": { "method": "GET", "url": "/me" },
|
|
9
|
+
"requestSchema": {},
|
|
10
|
+
"handler": "module.exports.handler = async (ctx) => { const user = await userService.findOne({ _id: ctx.state.user._id }); ctx.body = user; }"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "getUserProfile",
|
|
14
|
+
"endpoint": { "method": "GET", "url": "/profile/:userId" },
|
|
15
|
+
"requestSchema": {
|
|
16
|
+
"userId": "Joi.string().required()"
|
|
17
|
+
},
|
|
18
|
+
"handler": "module.exports.handler = async (ctx) => { const { userId } = ctx.params; const user = await userService.findOne({ _id: userId }); ctx.body = user; }"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"handlers": [],
|
|
22
|
+
"methods": [],
|
|
23
|
+
"schemas": [
|
|
24
|
+
{
|
|
25
|
+
"name": "users",
|
|
26
|
+
"schema": {
|
|
27
|
+
"username": "Joi.string().required()",
|
|
28
|
+
"email": "Joi.string().email().required()",
|
|
29
|
+
"password": "Joi.string().required()",
|
|
30
|
+
"bio": "Joi.string()",
|
|
31
|
+
"avatarUrl": "Joi.string().uri()",
|
|
32
|
+
"_id": "Joi.string()",
|
|
33
|
+
"createdOn": "Joi.date()",
|
|
34
|
+
"updatedOn": "Joi.date()"
|
|
35
|
+
},
|
|
36
|
+
"_schemaMappings": {}
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "follows",
|
|
42
|
+
"endpoints": [
|
|
43
|
+
{
|
|
44
|
+
"name": "followUser",
|
|
45
|
+
"endpoint": { "method": "POST", "url": "/" },
|
|
46
|
+
"requestSchema": {
|
|
47
|
+
"followingId": "Joi.string().required()"
|
|
48
|
+
},
|
|
49
|
+
"handler": "module.exports.handler = async (ctx) => { const { followingId } = ctx.validatedData; const followerId = ctx.state.user._id; const newFollow = await followService.create({ follower: { _id: followerId }, following: { _id: followingId } }); ctx.body = newFollow; }"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "unfollowUser",
|
|
53
|
+
"endpoint": { "method": "DELETE", "url": "/" },
|
|
54
|
+
"requestSchema": {
|
|
55
|
+
"followingId": "Joi.string().required()"
|
|
56
|
+
},
|
|
57
|
+
"handler": "module.exports.handler = async (ctx) => { const { followingId } = ctx.validatedData; const followerId = ctx.state.user._id; await followService.remove({ follower: { _id: followerId }, following: { _id: followingId } }); ctx.body = { message: 'Unfollowed successfully' }; }"
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
"handlers": [
|
|
61
|
+
{
|
|
62
|
+
"name": "updateFollowersCount",
|
|
63
|
+
"handler": "const userService = require('../../../db').services.users; const followService = require('../../../db').services.follows; followService.on('created', async ({ doc: follow }) => { const { followingId } = follow; await userService.atomic.update({ _id: followingId }, { $inc: { followersCount: 1 } }); }); followService.on('removed', async ({ doc: follow }) => { const { followingId } = follow; await userService.atomic.update({ _id: followingId }, { $inc: { followersCount: -1 } }); });"
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"methods": [],
|
|
67
|
+
"schemas": [
|
|
68
|
+
{
|
|
69
|
+
"name": "follows",
|
|
70
|
+
"schema": {
|
|
71
|
+
"follower": { "_id": "Joi.string().required()" },
|
|
72
|
+
"following": { "_id": "Joi.string().required()" },
|
|
73
|
+
"_id": "Joi.string()",
|
|
74
|
+
"createdOn": "Joi.date()",
|
|
75
|
+
"updatedOn": "Joi.date()"
|
|
76
|
+
},
|
|
77
|
+
"_schemaMappings": {}
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"name": "posts",
|
|
83
|
+
"endpoints": [
|
|
84
|
+
{
|
|
85
|
+
"name": "createPost",
|
|
86
|
+
"endpoint": { "method": "POST", "url": "/" },
|
|
87
|
+
"requestSchema": {
|
|
88
|
+
"content": "Joi.string().max(280).required()",
|
|
89
|
+
"fileUrl": "Joi.string().allow(null, '')"
|
|
90
|
+
},
|
|
91
|
+
"handler": "module.exports.handler = async (ctx) => { const { content, fileUrl } = ctx.validatedData; const userId = ctx.state.user._id; const username = ctx.state.user.username; const newPost = await postService.create({ content, fileUrl, creator: { _id: userId, username: username } }); ctx.body = newPost; }"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"name": "getFeed",
|
|
95
|
+
"endpoint": { "method": "GET", "url": "/feed" },
|
|
96
|
+
"requestSchema": {},
|
|
97
|
+
"handler": "module.exports.handler = async (ctx) => { const posts = await postService.find({}, { sort: { createdOn: -1 } }); ctx.body = posts; }"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "likePost",
|
|
101
|
+
"endpoint": { "method": "POST", "url": "/:postId/like" },
|
|
102
|
+
"requestSchema": {},
|
|
103
|
+
"handler": "module.exports.handler = async (ctx) => { const { postId } = ctx.params; const userId = ctx.state.user._id; await likeService.create({ post: { _id: postId }, user: { _id: userId } }); await postService.atomic.update({ _id: postId }, { $inc: { likesCount: 1 } }); ctx.body = { message: 'Post liked' }; }"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"name": "commentOnPost",
|
|
107
|
+
"endpoint": { "method": "POST", "url": "/:postId/comment" },
|
|
108
|
+
"requestSchema": {
|
|
109
|
+
"content": "Joi.string().required()"
|
|
110
|
+
},
|
|
111
|
+
"handler": "module.exports.handler = async (ctx) => { const { postId } = ctx.params; const { content } = ctx.validatedData; const userId = ctx.state.user._id; const username = ctx.state.user.username; const newComment = await commentService.create({ post: { _id: postId }, content, creator: { _id: userId, username: username }, createdOn: new Date() }); await postService.atomic.update({ _id: postId }, { $inc: { commentsCount: 1 } }); ctx.body = newComment; }"
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
"handlers": [
|
|
115
|
+
{
|
|
116
|
+
"name": "updateCommentsCount",
|
|
117
|
+
"handler": "const postService = require('../../../db').services.posts; const commentService = require('../../../db').services.comments; commentService.on('created', async ({ doc: comment }) => { const { post } = comment; await postService.atomic.update({ _id: post._id }, { $inc: { commentsCount: 1 } }); }); commentService.on('removed', async ({ doc: comment }) => { const { post } = comment; await postService.atomic.update({ _id: post._id }, { $inc: { commentsCount: -1 } }); });"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"name": "updateLikesCount",
|
|
121
|
+
"handler": "const postService = require('../../../db').services.posts; const likeService = require('../../../db').services.likes; likeService.on('created', async ({ doc: like }) => { const { postId } = like; await postService.atomic.update({ _id: postId }, { $inc: { likesCount: 1 } }); }); likeService.on('removed', async ({ doc: like }) => { const { postId } = like; await postService.atomic.update({ _id: postId }, { $inc: { likesCount: -1 } }); });"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"name": "notifyUserOnComment",
|
|
125
|
+
"handler": ""
|
|
126
|
+
}
|
|
127
|
+
],
|
|
128
|
+
"methods": [],
|
|
129
|
+
"schemas": [
|
|
130
|
+
{
|
|
131
|
+
"name": "posts",
|
|
132
|
+
"schema": {
|
|
133
|
+
"content": "Joi.string().max(280).required()",
|
|
134
|
+
"fileUrl": "Joi.string().allow(null, '')",
|
|
135
|
+
"creator": {
|
|
136
|
+
"_id": "Joi.string().required()",
|
|
137
|
+
"username": "Joi.string()"
|
|
138
|
+
},
|
|
139
|
+
"likesCount": "Joi.number().default(0)",
|
|
140
|
+
"commentsCount": "Joi.number().default(0)",
|
|
141
|
+
"parentPost": {
|
|
142
|
+
"_id": "Joi.string()",
|
|
143
|
+
"content": "Joi.string()",
|
|
144
|
+
"creator": "Joi.object()",
|
|
145
|
+
"likesCount": "Joi.number().default(0)",
|
|
146
|
+
"commentsCount": "Joi.number().default(0)"
|
|
147
|
+
},
|
|
148
|
+
"_id": "Joi.string()",
|
|
149
|
+
"createdOn": "Joi.date()",
|
|
150
|
+
"updatedOn": "Joi.date()"
|
|
151
|
+
},
|
|
152
|
+
"_schemaMappings": {}
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"name": "likes",
|
|
158
|
+
"endpoints": [],
|
|
159
|
+
"handlers": [],
|
|
160
|
+
"methods": [],
|
|
161
|
+
"schemas": [
|
|
162
|
+
{
|
|
163
|
+
"name": "likes",
|
|
164
|
+
"schema": {
|
|
165
|
+
"post": { "_id": "Joi.string().required()" },
|
|
166
|
+
"user": { "_id": "Joi.string().required()" },
|
|
167
|
+
"_id": "Joi.string()",
|
|
168
|
+
"createdOn": "Joi.date()",
|
|
169
|
+
"updatedOn": "Joi.date()"
|
|
170
|
+
},
|
|
171
|
+
"_schemaMappings": {}
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
}
|