mirror of
https://github.com/directus/directus.git
synced 2026-01-29 20:18:07 -05:00
Merge branch 'cli' into main
This commit is contained in:
1220
package-lock.json
generated
1220
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
93
package.json
93
package.json
@@ -1,12 +1,16 @@
|
||||
{
|
||||
"name": "api-node",
|
||||
"version": "0.0.1",
|
||||
"version": "9.0.0-alpha.3",
|
||||
"description": "The Directus API in Node.js",
|
||||
"main": "dist/server.js",
|
||||
"bin": {
|
||||
"directus": "dist/cli/index.js"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "NODE_ENV=production node dist/server.js",
|
||||
"build": "rimraf dist && tsc -b && copyfiles \"src/**/*.*\" -e \"src/**/*.ts\" -u 1 dist",
|
||||
"dev": "LOG_LEVEL=trace ts-node-dev src/server.ts --clear --watch \"src/**/*.ts\" --rs --transpile-only | pino-colada"
|
||||
"dev": "LOG_LEVEL=trace ts-node-dev src/server.ts --clear --watch \"src/**/*.ts\" --rs --transpile-only | pino-colada",
|
||||
"cli": "ts-node --script-mode --transpile-only src/cli/index.ts"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -27,14 +31,60 @@
|
||||
"url": "https://github.com/directus/api-node/issues"
|
||||
},
|
||||
"homepage": "https://github.com/directus/api-node#readme",
|
||||
"dependencies": {
|
||||
"@hapi/joi": "^17.1.1",
|
||||
"@slynova/flydrive": "^1.0.2",
|
||||
"@slynova/flydrive-gcs": "^1.0.2",
|
||||
"@slynova/flydrive-s3": "^1.0.2",
|
||||
"argon2": "^0.26.2",
|
||||
"atob": "^2.1.2",
|
||||
"body-parser": "^1.19.0",
|
||||
"busboy": "^0.3.1",
|
||||
"camelcase": "^6.0.0",
|
||||
"chalk": "^4.1.0",
|
||||
"clear": "^0.1.0",
|
||||
"commander": "^5.1.0",
|
||||
"cookie-parser": "^1.4.5",
|
||||
"dotenv": "^8.2.0",
|
||||
"exif-reader": "^1.0.3",
|
||||
"express": "^4.17.1",
|
||||
"express-async-handler": "^1.1.4",
|
||||
"express-pino-logger": "^5.0.0",
|
||||
"express-session": "^1.17.1",
|
||||
"fs-extra": "^9.0.1",
|
||||
"get-port": "^5.1.1",
|
||||
"grant": "^5.2.0",
|
||||
"icc": "^2.0.0",
|
||||
"inquirer": "^7.3.1",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"knex": "^0.21.1",
|
||||
"liquidjs": "^9.14.1",
|
||||
"lodash": "^4.17.19",
|
||||
"ms": "^2.1.2",
|
||||
"mssql": "^6.2.0",
|
||||
"mysql": "^2.18.1",
|
||||
"nanoid": "^3.1.10",
|
||||
"nodemailer": "^6.4.10",
|
||||
"oracledb": "^5.0.0",
|
||||
"pg": "^8.3.0",
|
||||
"pino": "^6.3.2",
|
||||
"resolve-cwd": "^3.0.0",
|
||||
"sharp": "^0.25.4",
|
||||
"sqlite3": "^5.0.0",
|
||||
"uuid": "^8.2.0",
|
||||
"uuid-validate": "0.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/atob": "^2.1.2",
|
||||
"@types/busboy": "^0.2.3",
|
||||
"@types/clear": "^0.1.0",
|
||||
"@types/cookie-parser": "^1.4.2",
|
||||
"@types/express": "^4.17.7",
|
||||
"@types/express-pino-logger": "^4.0.2",
|
||||
"@types/express-session": "^1.17.0",
|
||||
"@types/fs-extra": "^9.0.1",
|
||||
"@types/hapi__joi": "^17.1.3",
|
||||
"@types/inquirer": "^6.5.0",
|
||||
"@types/jsonwebtoken": "^8.5.0",
|
||||
"@types/lodash": "^4.14.157",
|
||||
"@types/ms": "^0.7.31",
|
||||
@@ -52,6 +102,7 @@
|
||||
"prettier": "^2.0.5",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-node": "^8.10.2",
|
||||
"ts-node-dev": "^1.0.0-pre.51",
|
||||
"tslint": "^6.1.2",
|
||||
"typescript": "^3.9.6"
|
||||
},
|
||||
@@ -64,43 +115,5 @@
|
||||
"*.{js,ts}": [
|
||||
"prettier --write"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@hapi/joi": "^17.1.1",
|
||||
"@slynova/flydrive": "^1.0.2",
|
||||
"@slynova/flydrive-gcs": "^1.0.2",
|
||||
"@slynova/flydrive-s3": "^1.0.2",
|
||||
"argon2": "^0.26.2",
|
||||
"atob": "^2.1.2",
|
||||
"body-parser": "^1.19.0",
|
||||
"busboy": "^0.3.1",
|
||||
"camelcase": "^6.0.0",
|
||||
"cookie-parser": "^1.4.5",
|
||||
"dotenv": "^8.2.0",
|
||||
"exif-reader": "^1.0.3",
|
||||
"express": "^4.17.1",
|
||||
"express-async-handler": "^1.1.4",
|
||||
"express-pino-logger": "^5.0.0",
|
||||
"express-session": "^1.17.1",
|
||||
"get-port": "^5.1.1",
|
||||
"grant": "^5.2.0",
|
||||
"icc": "^2.0.0",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"knex": "^0.21.1",
|
||||
"liquidjs": "^9.14.1",
|
||||
"lodash": "^4.17.19",
|
||||
"ms": "^2.1.2",
|
||||
"mssql": "^6.2.0",
|
||||
"mysql": "^2.18.1",
|
||||
"nanoid": "^3.1.10",
|
||||
"nodemailer": "^6.4.10",
|
||||
"oracledb": "^5.0.0",
|
||||
"pg": "^8.3.0",
|
||||
"pino": "^6.3.2",
|
||||
"sharp": "^0.25.4",
|
||||
"sqlite3": "^5.0.0",
|
||||
"ts-node-dev": "^1.0.0-pre.51",
|
||||
"uuid": "^8.2.0",
|
||||
"uuid-validate": "0.0.3"
|
||||
}
|
||||
}
|
||||
|
||||
13
src/cli/create/drivers.ts
Normal file
13
src/cli/create/drivers.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export const drivers = {
|
||||
sqlite3: 'SQLite',
|
||||
mysql: 'MySQL (/ MariaDB / Aurora)',
|
||||
pg: 'PostgreSQL (/ Amazon Redshift)',
|
||||
oracledb: 'Oracle Database',
|
||||
mssql: 'Microsoft SQL Server',
|
||||
};
|
||||
|
||||
export function getDriverForClient(client: string) {
|
||||
for (const [key, value] of Object.entries(drivers)) {
|
||||
if (value === client) return key;
|
||||
}
|
||||
}
|
||||
66
src/cli/create/index.ts
Normal file
66
src/cli/create/index.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import fse from 'fs-extra';
|
||||
import chalk from 'chalk';
|
||||
import inquirer from 'inquirer';
|
||||
import { resolve } from 'path';
|
||||
import { databaseQuestions } from './questions';
|
||||
import { drivers, getDriverForClient } from './drivers';
|
||||
|
||||
export default async function create(directory: string, options: Record<string, any>) {
|
||||
const path = resolve(directory);
|
||||
checkRequirements();
|
||||
|
||||
if (await fse.pathExists(path)) {
|
||||
const stat = await fse.stat(path);
|
||||
|
||||
if (stat.isDirectory() === false) {
|
||||
console.error(
|
||||
`Destination '${chalk.red(directory)}' already exists and is not a directory.`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const files = await fse.readdir(path);
|
||||
|
||||
if (files.length > 0) {
|
||||
console.error(
|
||||
`Destination '${chalk.red(
|
||||
directory
|
||||
)}' already exists and is not an empty directory.`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
let { client } = await inquirer.prompt([
|
||||
{
|
||||
type: 'list',
|
||||
name: 'client',
|
||||
message: 'Choose your database client',
|
||||
choices: Object.values(drivers),
|
||||
},
|
||||
]);
|
||||
|
||||
client = getDriverForClient(client);
|
||||
|
||||
const responses = await inquirer.prompt(
|
||||
databaseQuestions[client].map((question) => question({ client }))
|
||||
);
|
||||
|
||||
/** @todo
|
||||
* - See if you can connect to DB
|
||||
* - Install Directus system stuff into DB
|
||||
* - Start the Node API
|
||||
*/
|
||||
}
|
||||
|
||||
function checkRequirements() {
|
||||
const nodeVersion = process.versions.node;
|
||||
const major = +nodeVersion.split('.')[0];
|
||||
|
||||
if (major < 12) {
|
||||
console.error(`You are running Node ${nodeVersion}.`);
|
||||
console.error('Directus requires Node 12 and up.');
|
||||
console.error('Please update your Node version and try again.');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
50
src/cli/create/questions.ts
Normal file
50
src/cli/create/questions.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
const filename = () => ({
|
||||
type: 'input',
|
||||
name: 'filename',
|
||||
message: 'Filename:',
|
||||
default: './data.db',
|
||||
});
|
||||
|
||||
const host = () => ({
|
||||
type: 'input',
|
||||
name: 'host',
|
||||
message: 'Host:',
|
||||
default: '127.0.0.1',
|
||||
});
|
||||
|
||||
const port = ({ client }) => ({
|
||||
type: 'input',
|
||||
name: 'port',
|
||||
message: 'Port:',
|
||||
default() {
|
||||
const ports = {
|
||||
pg: 5432,
|
||||
mysql: 3306,
|
||||
oracledb: 1521,
|
||||
mssql: 1433,
|
||||
};
|
||||
|
||||
return ports[client];
|
||||
},
|
||||
});
|
||||
|
||||
const username = () => ({
|
||||
type: 'input',
|
||||
name: 'username',
|
||||
message: 'Username:',
|
||||
});
|
||||
|
||||
const password = () => ({
|
||||
type: 'password',
|
||||
name: 'password',
|
||||
message: 'Password:',
|
||||
mask: '*',
|
||||
});
|
||||
|
||||
export const databaseQuestions = {
|
||||
sqlite3: [filename],
|
||||
mysql: [host, port, username, password],
|
||||
pg: [host, port, username, password],
|
||||
oracledb: [host, port, username, password],
|
||||
mssql: [host, port, username, password],
|
||||
};
|
||||
18
src/cli/index.ts
Normal file
18
src/cli/index.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import program from 'commander';
|
||||
|
||||
const pkg = require('../../package.json');
|
||||
|
||||
import start from './start';
|
||||
import create from './create';
|
||||
|
||||
program.version(pkg.version, '-v, --version');
|
||||
|
||||
program.name('directus').usage('[command] [options]');
|
||||
|
||||
program.command('create <directory>').description('Create a new Directus Project').action(create);
|
||||
|
||||
program.command('start').description('Start the Directus API').action(start);
|
||||
|
||||
program.parseAsync(process.argv);
|
||||
14
src/cli/start.ts
Normal file
14
src/cli/start.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import app from '../app';
|
||||
import logger from '../logger';
|
||||
import getPort from 'get-port';
|
||||
import clear from 'clear';
|
||||
|
||||
export default async function start() {
|
||||
clear();
|
||||
|
||||
const port = process.env.PORT || (await getPort({ port: 3000 }));
|
||||
|
||||
app.listen(port, () => {
|
||||
logger.info(`Server started at port ${port}`);
|
||||
});
|
||||
}
|
||||
@@ -39,18 +39,6 @@ if (emailTransport === 'sendmail') {
|
||||
pass: process.env.EMAIL_SMTP_PASSWORD,
|
||||
},
|
||||
} as any);
|
||||
|
||||
logger.trace('[Email] Verifying SMTP connection.');
|
||||
|
||||
transporter
|
||||
.verify()
|
||||
.then(() => {
|
||||
logger.info('[Email] SMTP connected. Ready to send emails.');
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error(`[Email] Couldn't connect to SMTP server:`);
|
||||
logger.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
export type EmailOptions = {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import database, { schemaInspector } from '../database';
|
||||
import { FIELD_SPECIAL_ALIAS_TYPES } from '../constants';
|
||||
import { uniq } from 'lodash';
|
||||
|
||||
export default async function hasFields(fields: { collection: string; field: string }[]) {
|
||||
@@ -28,8 +27,7 @@ export async function collectionHasFields(collection: string, fieldKeys: string[
|
||||
.select('field')
|
||||
.from('directus_fields')
|
||||
.where({ collection })
|
||||
.whereIn('field', fieldKeys)
|
||||
.whereIn('special', FIELD_SPECIAL_ALIAS_TYPES),
|
||||
.whereIn('field', fieldKeys),
|
||||
]);
|
||||
|
||||
const existingFields = uniq([
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
"esModuleInterop": true,
|
||||
"target": "es6",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"outDir": "dist"
|
||||
"sourceMap": false,
|
||||
"outDir": "dist",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"lib": [
|
||||
"es2015"
|
||||
]
|
||||
],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user