@paralect/hive 0.0.3 → 0.0.4
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/cli/helpers/axiosAuth.js +12 -0
- package/cli/helpers/downloadDirectory.js +46 -0
- package/cli/helpers/execCommand.js +48 -0
- package/cli/helpers/isAuthorized.js +41 -0
- package/cli/helpers/isProjectInit.js +71 -0
- package/cli/helpers/mergeDirs.js +71 -0
- package/cli/hive.js +158 -43
- package/package.json +4 -2
- package/starter/.dockerignore +1 -0
- package/starter/Dockerfile +1 -1
- package/starter/deploy/api/templates/deployment.yaml +4 -3
- package/starter/deploy/script/Dockerfile +1 -1
- package/starter/deploy/script/src/index.js +4 -3
- package/starter/package.json +1 -1
- package/starter/src/helpers/getResourceEndpoints.js +0 -1
- package/starter/src/middlewares/shouldExist.js +24 -4
- package/starter/src/resources/health/endpoints/get.js +1 -1
- package/starter/src/resources/users/methods/ensureUserCreated.js +7 -7
- package/starter/src/resources/users/users.schema.js +1 -1
- /package/starter/src/emails/{dist → compiled}/MyEmailComponent.js +0 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
|
|
3
|
+
module.exports = (options) => {
|
|
4
|
+
return axios({
|
|
5
|
+
...options,
|
|
6
|
+
// url: options.url.startsWith('http') ? options.url : `https://hive-api-test.paralect.co/${options.url}`,
|
|
7
|
+
url: options.url.startsWith('http') ? options.url : `http://localhost:3001/${options.url}`,
|
|
8
|
+
headers: {
|
|
9
|
+
...(options?.headers || {}),
|
|
10
|
+
...(process.env.HIVE_TOKEN ? { Authorization: `Bearer ${process.env.HIVE_TOKEN}` } : {})}
|
|
11
|
+
})
|
|
12
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const axios = require('axios');
|
|
4
|
+
|
|
5
|
+
const GITHUB_API_URL = 'https://api.github.com/repos';
|
|
6
|
+
|
|
7
|
+
async function fetchDirectoryTree(owner, repo, dirPath) {
|
|
8
|
+
const url = `${GITHUB_API_URL}/${owner}/${repo}/contents/${dirPath}`;
|
|
9
|
+
const response = await axios.get(url);
|
|
10
|
+
return response.data;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function downloadFile(fileUrl, filePath) {
|
|
14
|
+
const response = await axios({
|
|
15
|
+
url: fileUrl,
|
|
16
|
+
method: 'GET',
|
|
17
|
+
responseType: 'stream'
|
|
18
|
+
});
|
|
19
|
+
await fs.ensureDir(path.dirname(filePath));
|
|
20
|
+
response.data.pipe(fs.createWriteStream(filePath));
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
response.data.on('end', resolve);
|
|
23
|
+
response.data.on('error', reject);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function downloadDirectory(pluginName, baseDir = '') {
|
|
28
|
+
const owner = 'paralect';
|
|
29
|
+
const repo = 'hive-plugins';
|
|
30
|
+
|
|
31
|
+
const destDir = path.join(process.cwd(), baseDir);
|
|
32
|
+
|
|
33
|
+
const tree = await fetchDirectoryTree(owner, repo, pluginName);
|
|
34
|
+
for (const item of tree) {
|
|
35
|
+
const relativePath = path.relative(pluginName, item.path);
|
|
36
|
+
const filePath = path.join(destDir, relativePath);
|
|
37
|
+
if (item.type === 'file') {
|
|
38
|
+
console.log(`Downloading ${item.path}...`);
|
|
39
|
+
await downloadFile(item.download_url, filePath);
|
|
40
|
+
} else if (item.type === 'dir') {
|
|
41
|
+
await downloadDirectory(item.path, path.join(baseDir, relativePath));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = downloadDirectory;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const execa = require('execa');
|
|
5
|
+
const mkdirp = require('mkdirp');
|
|
6
|
+
|
|
7
|
+
const execCommand = async (command, options = {}, outputFileSrc = null) => {
|
|
8
|
+
let commandParts = command;
|
|
9
|
+
|
|
10
|
+
if (typeof command === 'string') {
|
|
11
|
+
commandParts = command
|
|
12
|
+
.split(/ +(?=(?:(?:[^"]*"){2})*[^"]*$)/g)
|
|
13
|
+
.map((commandPart) => {
|
|
14
|
+
if (
|
|
15
|
+
commandPart[0] === '"' &&
|
|
16
|
+
commandPart[commandPart.length - 1] === '"'
|
|
17
|
+
) {
|
|
18
|
+
return commandPart.replace(/["]+/g, '', '');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return commandPart;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// commandParts = command.split(' ').filter((part) => !!part.trim());
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const commandName = commandParts.shift();
|
|
28
|
+
const commandArguments = commandParts;
|
|
29
|
+
|
|
30
|
+
const process = execa(commandName, commandArguments, {
|
|
31
|
+
stdio: outputFileSrc ? 'pipe' : 'inherit',
|
|
32
|
+
...options,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (outputFileSrc) {
|
|
36
|
+
console.log('writing to outputFileSrc', outputFileSrc);
|
|
37
|
+
const dir = path.dirname(outputFileSrc);
|
|
38
|
+
|
|
39
|
+
await mkdirp(dir);
|
|
40
|
+
console.log(dir, fs.existsSync(dir));
|
|
41
|
+
|
|
42
|
+
process.stdout.pipe(fs.createWriteStream(outputFileSrc, { flags: 'a+' }));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return process;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
module.exports = execCommand;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const inquirer = require('inquirer');
|
|
3
|
+
|
|
4
|
+
module.exports = async () => {
|
|
5
|
+
if (!process.env.HIVE_TOKEN) {
|
|
6
|
+
const { email } = await inquirer.prompt([
|
|
7
|
+
{
|
|
8
|
+
type: 'input',
|
|
9
|
+
name: 'email',
|
|
10
|
+
message: 'Please enter your email:'
|
|
11
|
+
}
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
await axios({ url: `https://hive-api-test.paralect.co/auth/login-code`, method: 'post', data: { email } });
|
|
16
|
+
|
|
17
|
+
const { code } = await inquirer.prompt([
|
|
18
|
+
{
|
|
19
|
+
type: 'input',
|
|
20
|
+
name: 'code',
|
|
21
|
+
message: `One time code (sent to ${email})`,
|
|
22
|
+
}
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
const { token, user } = (await axios({ url: `https://hive-api-test.paralect.co/auth/verify-login`, method: 'post', data: { email, code } })).data;
|
|
26
|
+
|
|
27
|
+
console.log(`
|
|
28
|
+
You're now logged into Hive! Welcome 🐝
|
|
29
|
+
|
|
30
|
+
Important: to save access add HIVE_TOKEN to your env variables and your ~/.zshrc file
|
|
31
|
+
|
|
32
|
+
export HIVE_TOKEN=${token}`);
|
|
33
|
+
|
|
34
|
+
return { token, user };
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.error('An error occurred:', error.message);
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
return { token: process.env.HIVE_TOKEN };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const axios = require('./axiosAuth');
|
|
4
|
+
const inquirer = require('inquirer');
|
|
5
|
+
|
|
6
|
+
module.exports = async () => {
|
|
7
|
+
if (!process.env.PROJECT_ID) {
|
|
8
|
+
let projectConfigPath = path.resolve(process.env.HIVE_SRC, './hive.config.js');
|
|
9
|
+
|
|
10
|
+
if (fs.existsSync(projectConfigPath)) {
|
|
11
|
+
const config = require(projectConfigPath);
|
|
12
|
+
if (config.projectId) {
|
|
13
|
+
process.env.PROJECT_ID = config.projectId;
|
|
14
|
+
}
|
|
15
|
+
} else {
|
|
16
|
+
const projectPackageJsonPath = path.resolve(process.env.HIVE_SRC, './package.json');
|
|
17
|
+
|
|
18
|
+
let projectName;
|
|
19
|
+
|
|
20
|
+
if (fs.existsSync(projectPackageJsonPath)) {
|
|
21
|
+
const { name } = require(projectPackageJsonPath);
|
|
22
|
+
projectName = name;
|
|
23
|
+
} else {
|
|
24
|
+
const { name } = await inquirer.prompt([
|
|
25
|
+
{
|
|
26
|
+
type: 'input',
|
|
27
|
+
name: 'name',
|
|
28
|
+
message: 'Project Name'
|
|
29
|
+
}
|
|
30
|
+
]);
|
|
31
|
+
|
|
32
|
+
projectName = name;
|
|
33
|
+
|
|
34
|
+
fs.writeFileSync(projectPackageJsonPath, `${JSON.stringify({
|
|
35
|
+
name: name,
|
|
36
|
+
|
|
37
|
+
scripts: {
|
|
38
|
+
"dev": "nodemon --watch . --exec hive run .",
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
dependencies: {
|
|
42
|
+
"@paralect/hive": "^0.0.4"
|
|
43
|
+
},
|
|
44
|
+
devDependencies: {
|
|
45
|
+
"nodemon": "^3.1.4"
|
|
46
|
+
}
|
|
47
|
+
}, null, 2)}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const project = (await axios({ url: `projects`, method: 'post', data: { name: projectName } })).data;
|
|
51
|
+
|
|
52
|
+
fs.writeFileSync(projectConfigPath, `module.exports = { projectId: '${project._id}' } `);
|
|
53
|
+
|
|
54
|
+
const projectEnvPath = path.resolve(process.env.HIVE_SRC, './config/.env');
|
|
55
|
+
|
|
56
|
+
if (project?.envs?.staging) {
|
|
57
|
+
if (!fs.existsSync(path.resolve(process.env.HIVE_SRC, './config'))) {
|
|
58
|
+
fs.mkdirSync(path.resolve(process.env.HIVE_SRC, './config'));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
fs.writeFileSync(projectEnvPath, Object.keys(project.envs.staging).map(key => `${key}=${project.envs.staging[key]}`).join('\n'));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
console.log(`Successfully initialised project ${projectName}!`);
|
|
65
|
+
|
|
66
|
+
process.env.PROJECT_ID = project._id;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return { projectId: process.env.PROJECT_ID };
|
|
71
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
function shouldIgnore(filePath) {
|
|
6
|
+
const ignoredDirs = ['node_modules', 'dist', '.git'];
|
|
7
|
+
return ignoredDirs.some(dir => filePath.includes(path.sep + dir + path.sep));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async function copyDir(src, dest) {
|
|
11
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
12
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
13
|
+
|
|
14
|
+
for (let entry of entries) {
|
|
15
|
+
const srcPath = path.join(src, entry.name);
|
|
16
|
+
const destPath = path.join(dest, entry.name);
|
|
17
|
+
|
|
18
|
+
if (shouldIgnore(srcPath)) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (entry.isDirectory()) {
|
|
23
|
+
await copyDir(srcPath, destPath);
|
|
24
|
+
} else {
|
|
25
|
+
console.log('copy', srcPath, destPath)
|
|
26
|
+
await fs.copyFileSync(srcPath, destPath);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function copyRootFiles(sourceDir, destDir) {
|
|
32
|
+
try {
|
|
33
|
+
// Read all items in the source directory
|
|
34
|
+
const items = await fs.promises.readdir(sourceDir, { withFileTypes: true });
|
|
35
|
+
|
|
36
|
+
// Ensure the destination directory exists
|
|
37
|
+
await fs.promises.mkdir(destDir, { recursive: true });
|
|
38
|
+
|
|
39
|
+
// Iterate over each item
|
|
40
|
+
for (const item of items) {
|
|
41
|
+
const sourcePath = path.join(sourceDir, item.name);
|
|
42
|
+
const destPath = path.join(destDir, item.name);
|
|
43
|
+
|
|
44
|
+
// Check if the item is a file and not package.json
|
|
45
|
+
if (item.isFile() && item.name !== 'package.json') {
|
|
46
|
+
// Copy the file to the destination directory
|
|
47
|
+
await fs.promises.copyFile(sourcePath, destPath);
|
|
48
|
+
console.log(`Copied: ${sourcePath} -> ${destPath}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
console.log('Files copied successfully.');
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error('An error occurred:', error.message);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function mergeDirectories(sourceDir1, sourceDir2, targetDir) {
|
|
59
|
+
// First, copy all contents from sourceDir1 to targetDir
|
|
60
|
+
await copyDir(sourceDir1, targetDir);
|
|
61
|
+
|
|
62
|
+
// Then, copy and extend/overwrite with contents from sourceDir2
|
|
63
|
+
await copyDir(sourceDir2, `${targetDir}/src`);
|
|
64
|
+
await copyRootFiles(sourceDir2, targetDir);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = async ({ hiveSrc, outDir }) => {
|
|
68
|
+
await mergeDirectories(path.resolve(__dirname, './../../starter'), hiveSrc, outDir);
|
|
69
|
+
|
|
70
|
+
console.log('Merged resources');
|
|
71
|
+
}
|
package/cli/hive.js
CHANGED
|
@@ -1,50 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const { program } = require('commander');
|
|
4
|
-
const axios = require('axios');
|
|
5
|
-
const fs = require('fs-extra');
|
|
6
|
-
const path = require('path');
|
|
7
|
-
|
|
8
|
-
const GITHUB_API_URL = 'https://api.github.com/repos';
|
|
9
4
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const response = await axios({
|
|
18
|
-
url: fileUrl,
|
|
19
|
-
method: 'GET',
|
|
20
|
-
responseType: 'stream'
|
|
21
|
-
});
|
|
22
|
-
await fs.ensureDir(path.dirname(filePath));
|
|
23
|
-
response.data.pipe(fs.createWriteStream(filePath));
|
|
24
|
-
return new Promise((resolve, reject) => {
|
|
25
|
-
response.data.on('end', resolve);
|
|
26
|
-
response.data.on('error', reject);
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async function downloadDirectory(pluginName, baseDir = '') {
|
|
31
|
-
const owner = 'paralect';
|
|
32
|
-
const repo = 'hive-plugins';
|
|
33
|
-
|
|
34
|
-
const destDir = path.join(process.cwd(), baseDir);
|
|
35
|
-
|
|
36
|
-
const tree = await fetchDirectoryTree(owner, repo, pluginName);
|
|
37
|
-
for (const item of tree) {
|
|
38
|
-
const relativePath = path.relative(pluginName, item.path);
|
|
39
|
-
const filePath = path.join(destDir, relativePath);
|
|
40
|
-
if (item.type === 'file') {
|
|
41
|
-
console.log(`Downloading ${item.path}...`);
|
|
42
|
-
await downloadFile(item.download_url, filePath);
|
|
43
|
-
} else if (item.type === 'dir') {
|
|
44
|
-
await downloadDirectory(item.path, path.join(baseDir, relativePath));
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const isAuthorized = require('./helpers/isAuthorized');
|
|
7
|
+
const mergeDirs = require('./helpers/mergeDirs');
|
|
8
|
+
const execCommand = require('./helpers/execCommand');
|
|
9
|
+
const downloadDirectory = require('./helpers/downloadDirectory');
|
|
10
|
+
const axios = require('./helpers/axiosAuth');
|
|
11
|
+
const isProjectInit = require('./helpers/isProjectInit.js');
|
|
48
12
|
|
|
49
13
|
program
|
|
50
14
|
.command('run [dirPath]')
|
|
@@ -58,6 +22,66 @@ program
|
|
|
58
22
|
}
|
|
59
23
|
});
|
|
60
24
|
|
|
25
|
+
program
|
|
26
|
+
.command('deploy [imageTag]')
|
|
27
|
+
.description('Build and deploy Hive project from local machine docker + helm')
|
|
28
|
+
.action(async (imageTag) => {
|
|
29
|
+
process.env.HIVE_SRC = path.resolve(process.cwd());
|
|
30
|
+
|
|
31
|
+
if (!imageTag) {
|
|
32
|
+
const { stdout: branch } = await execCommand(
|
|
33
|
+
"git rev-parse --abbrev-ref HEAD",
|
|
34
|
+
{ stdio: "pipe" }
|
|
35
|
+
);
|
|
36
|
+
const { stdout: commitSHA } = await execCommand("git rev-parse HEAD", {
|
|
37
|
+
stdio: "pipe",
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
imageTag = `${branch}.${commitSHA}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
console.log("Deploying Image Tag ", imageTag);
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
await isAuthorized();
|
|
47
|
+
const { projectId } = await isProjectInit();
|
|
48
|
+
console.log('project id', projectId)
|
|
49
|
+
const { isOk } = (
|
|
50
|
+
await axios({
|
|
51
|
+
// url: `http://localhost:3001/projects/${projectId}/deploy`,
|
|
52
|
+
url: `projects/${projectId}/deploy`,
|
|
53
|
+
method: 'post',
|
|
54
|
+
data: {
|
|
55
|
+
imageTag
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
).data;
|
|
59
|
+
|
|
60
|
+
console.log('Deployed');
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.error('An error occurred:', error.message);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
program
|
|
67
|
+
.command('deploy-local')
|
|
68
|
+
.description('Build and deploy Hive project from local machine docker + helm')
|
|
69
|
+
.action(async () => {
|
|
70
|
+
try {
|
|
71
|
+
let outDir = path.resolve(process.cwd(), './dist');
|
|
72
|
+
await mergeDirs({ hiveSrc: path.resolve(process.cwd()), outDir });
|
|
73
|
+
|
|
74
|
+
console.log('outDir', path.resolve(outDir, `./deploy/script`))
|
|
75
|
+
await execCommand(`npm install --prefix ${path.resolve(outDir, `./deploy/script`)}`);
|
|
76
|
+
|
|
77
|
+
await execCommand('node ./index.js', {
|
|
78
|
+
cwd: path.resolve(outDir, `./deploy/script/src`)
|
|
79
|
+
});
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error('An error occurred:', error.message);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
61
85
|
program
|
|
62
86
|
.command('install <plugin>')
|
|
63
87
|
.description('Installs Hive plugin')
|
|
@@ -71,4 +95,95 @@ program
|
|
|
71
95
|
}
|
|
72
96
|
});
|
|
73
97
|
|
|
98
|
+
program
|
|
99
|
+
.command('login')
|
|
100
|
+
.description('Login into Hive Cloud')
|
|
101
|
+
.action(async () => {
|
|
102
|
+
if (process.env.HIVE_TOKEN) {
|
|
103
|
+
const user = (await axios({ url: `users/me`, method: 'get' })).data;
|
|
104
|
+
|
|
105
|
+
console.log(`Already logged in!`, user);
|
|
106
|
+
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
program
|
|
113
|
+
.command('init')
|
|
114
|
+
.description('Init Hive Project')
|
|
115
|
+
.action(async () => {
|
|
116
|
+
try {
|
|
117
|
+
process.env.HIVE_SRC = path.resolve(process.cwd());
|
|
118
|
+
|
|
119
|
+
await isAuthorized();
|
|
120
|
+
await isProjectInit();
|
|
121
|
+
} catch (error) {
|
|
122
|
+
console.error('An error occurred:', error.message);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
program
|
|
127
|
+
.command('env-get <envName>')
|
|
128
|
+
.description('Get env variable')
|
|
129
|
+
.action(async (envName) => {
|
|
130
|
+
try {
|
|
131
|
+
process.env.HIVE_SRC = path.resolve(process.cwd());
|
|
132
|
+
|
|
133
|
+
await isAuthorized();
|
|
134
|
+
const { projectId } = await isProjectInit();
|
|
135
|
+
|
|
136
|
+
const { value } = (await axios({
|
|
137
|
+
method: 'post',
|
|
138
|
+
url: `projects/${projectId}/get-env`,
|
|
139
|
+
data: {
|
|
140
|
+
name: envName
|
|
141
|
+
}
|
|
142
|
+
})).data;
|
|
143
|
+
|
|
144
|
+
console.log(`${envName} value is ${value || '<empty>'}`)
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.error('An error occurred:', error.message);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
program
|
|
151
|
+
.command('env-set <envName> <envValue>')
|
|
152
|
+
.description('Set env variable')
|
|
153
|
+
.action(async (envName, envValue) => {
|
|
154
|
+
try {
|
|
155
|
+
process.env.HIVE_SRC = path.resolve(process.cwd());
|
|
156
|
+
|
|
157
|
+
await isAuthorized();
|
|
158
|
+
const { projectId } = await isProjectInit();
|
|
159
|
+
|
|
160
|
+
const { value } = (await axios({
|
|
161
|
+
method: 'post',
|
|
162
|
+
url: `projects/${projectId}/env`,
|
|
163
|
+
data: {
|
|
164
|
+
name: envName,
|
|
165
|
+
value: envValue,
|
|
166
|
+
}
|
|
167
|
+
})).data;
|
|
168
|
+
|
|
169
|
+
console.log(`Updated ${envName}`)
|
|
170
|
+
} catch (error) {
|
|
171
|
+
console.error('An error occurred:', error.message);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
// program
|
|
177
|
+
// .command('init [name]')
|
|
178
|
+
// .description('Installs Hive plugin')
|
|
179
|
+
// .action(async (plugin) => {
|
|
180
|
+
// try {
|
|
181
|
+
// const destDir = process.cwd();
|
|
182
|
+
|
|
183
|
+
// await downloadDirectory(plugin);
|
|
184
|
+
// } catch (error) {
|
|
185
|
+
// console.error('An error occurred:', error.message);
|
|
186
|
+
// }
|
|
187
|
+
// });
|
|
188
|
+
|
|
74
189
|
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paralect/hive",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -26,8 +26,10 @@
|
|
|
26
26
|
"commander": "^12.1.0",
|
|
27
27
|
"dotenv": "16.0.0",
|
|
28
28
|
"eslint-config-prettier": "8.5.0",
|
|
29
|
+
"execa": "^4.1.0",
|
|
29
30
|
"fs-extra": "^11.2.0",
|
|
30
31
|
"handlebars": "4.7.7",
|
|
32
|
+
"inquirer": "^8.2.6",
|
|
31
33
|
"joi": "^17.13.3",
|
|
32
34
|
"koa": "2.13.4",
|
|
33
35
|
"koa-bodyparser": "4.3.0",
|
|
@@ -37,7 +39,7 @@
|
|
|
37
39
|
"koa-qs": "3.0.0",
|
|
38
40
|
"lodash": "4.17.21",
|
|
39
41
|
"mjml": "4.12.0",
|
|
40
|
-
"mkdirp": "1.0.4",
|
|
42
|
+
"mkdirp": "^1.0.4",
|
|
41
43
|
"moment": "2.29.1",
|
|
42
44
|
"moment-duration-format": "2.3.2",
|
|
43
45
|
"multer": "1.4.4",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
node_modules
|
package/starter/Dockerfile
CHANGED
|
@@ -21,9 +21,10 @@ spec:
|
|
|
21
21
|
env:
|
|
22
22
|
- name: PROJECT_ID
|
|
23
23
|
value: {{ .Values.projectId }}
|
|
24
|
-
|
|
25
|
-
- name:
|
|
26
|
-
value: {{ .
|
|
24
|
+
{{- range .Values.env }}
|
|
25
|
+
- name: {{ .name }}
|
|
26
|
+
value: {{ .value }}
|
|
27
|
+
{{- end }}
|
|
27
28
|
imagePullPolicy: Always
|
|
28
29
|
livenessProbe:
|
|
29
30
|
httpGet:
|
|
@@ -31,7 +31,7 @@ const pushToKubernetes = async ({ imageTag, appName, deployConfig }) => {
|
|
|
31
31
|
fs.writeFileSync(`${config.home}/.kube/config`, config.kubeConfig);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
let projectId = '
|
|
34
|
+
let projectId = process.env.PROJECT_ID || 'core';
|
|
35
35
|
let attachedDomains;
|
|
36
36
|
|
|
37
37
|
await execCommand(
|
|
@@ -42,10 +42,11 @@ const pushToKubernetes = async ({ imageTag, appName, deployConfig }) => {
|
|
|
42
42
|
--set imagesVersion=${imageTag} \
|
|
43
43
|
--set domain={hive-api-${projectId}.paralect.co} \
|
|
44
44
|
--set projectId=${projectId} \
|
|
45
|
-
--set
|
|
45
|
+
--set env\[0\].name=MONGODB_URI \
|
|
46
|
+
--set env\[0\].value='${process.env.MONGODB_URI}' \
|
|
46
47
|
-f ${deployDir}/staging.yaml --timeout 35m`,
|
|
47
48
|
{
|
|
48
|
-
cwd: `/app`,
|
|
49
|
+
// cwd: `/app`,
|
|
49
50
|
}
|
|
50
51
|
);
|
|
51
52
|
};
|
package/starter/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build-assets": "mjml ./src/assets/emails/*.mjml -o ./src/assets/emails/dist/",
|
|
20
|
-
"build-emails": "babel src/emails --out-dir src/emails/
|
|
20
|
+
"build-emails": "babel src/emails --out-dir src/emails/compiled",
|
|
21
21
|
"dev": "nodemon --watch src src/app.js",
|
|
22
22
|
"init-project": "./bin/init-project.sh",
|
|
23
23
|
"start": "node src/app.js",
|
|
@@ -20,7 +20,6 @@ module.exports = async (resourceName) => {
|
|
|
20
20
|
)).map( f => ({ name: f }))];
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
console.log('endpointFiles', resourceName, endpointFiles);
|
|
24
23
|
return endpointFiles.map(({ name, isHiveEndpoint }) => ({
|
|
25
24
|
file: isHiveEndpoint ? `${process.env.HIVE_SRC}/resources/${resourceName}/endpoints/${name}`: `${__dirname}/../resources/${resourceName}/endpoints/${name}`,
|
|
26
25
|
name: _.last(name.split("/")).replace(".js", ""),
|
|
@@ -1,12 +1,32 @@
|
|
|
1
|
-
const db = require(
|
|
1
|
+
const db = require('db');
|
|
2
|
+
|
|
3
|
+
function singularize(word) {
|
|
4
|
+
const endings = {
|
|
5
|
+
ves: 'fe',
|
|
6
|
+
ies: 'y',
|
|
7
|
+
i: 'us',
|
|
8
|
+
zes: 'ze',
|
|
9
|
+
ses: 's',
|
|
10
|
+
es: 'e',
|
|
11
|
+
s: '',
|
|
12
|
+
};
|
|
13
|
+
return word.replace(
|
|
14
|
+
new RegExp(`(${Object.keys(endings).join('|')})$`),
|
|
15
|
+
(r) => endings[r]
|
|
16
|
+
);
|
|
17
|
+
}
|
|
2
18
|
|
|
3
19
|
module.exports = (
|
|
4
20
|
resourceName,
|
|
5
|
-
{
|
|
21
|
+
{
|
|
22
|
+
criteria = (ctx) => ({ _id: ctx.params[`${singularize(resourceName)}Id`] }),
|
|
23
|
+
ctxName = resourceName,
|
|
24
|
+
} = {}
|
|
6
25
|
) => {
|
|
7
26
|
return async (ctx, next) => {
|
|
8
27
|
const doc = await db.services[resourceName].findOne(criteria(ctx));
|
|
9
|
-
ctx.state[
|
|
28
|
+
ctx.state[ctxName] = doc;
|
|
29
|
+
ctx.state[singularize(resourceName)] = doc;
|
|
10
30
|
|
|
11
31
|
if (!doc) {
|
|
12
32
|
ctx.throw(404, { message: `${resourceName} not found` });
|
|
@@ -14,4 +34,4 @@ module.exports = (
|
|
|
14
34
|
await next();
|
|
15
35
|
}
|
|
16
36
|
};
|
|
17
|
-
};
|
|
37
|
+
};
|
|
@@ -3,15 +3,15 @@ const slug = require('slug');
|
|
|
3
3
|
|
|
4
4
|
const userService = require('db').services.users;
|
|
5
5
|
|
|
6
|
-
const formatUsername = ({ username, fullName }) => {
|
|
6
|
+
const formatUsername = ({ username, fullName, email }) => {
|
|
7
7
|
return (
|
|
8
8
|
username ||
|
|
9
|
-
slug(`${fullName.split(' ')[0]} ${fullName.split(' ')[1] || ''}`, '.')
|
|
9
|
+
fullName ? slug(`${fullName.split(' ')[0]} ${fullName.split(' ')[1] || ''}`, '.') : email?.split('@')[0]
|
|
10
10
|
);
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
const createUserAccount = async (userData) => {
|
|
14
|
-
let username = formatUsername({ fullName: userData.fullName });
|
|
14
|
+
let username = formatUsername({ fullName: userData.fullName, email: userData.email });
|
|
15
15
|
|
|
16
16
|
if (await userService.exists({ username })) {
|
|
17
17
|
username += _.random(1000, 9999);
|
|
@@ -49,9 +49,9 @@ const ensureUserCreated = async (userData) => {
|
|
|
49
49
|
}
|
|
50
50
|
);
|
|
51
51
|
|
|
52
|
-
return { user: changedUser, isNew:
|
|
52
|
+
return { user: changedUser, isNew: false };
|
|
53
53
|
} else {
|
|
54
|
-
|
|
54
|
+
return { user, isNew: false };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -62,6 +62,6 @@ const ensureUserCreated = async (userData) => {
|
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
module.exports = async (userData) => {
|
|
65
|
-
const {
|
|
66
|
-
return
|
|
65
|
+
const { user, isNew } = await ensureUserCreated(userData);
|
|
66
|
+
return user;
|
|
67
67
|
};
|
|
File without changes
|