mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
feat(cli): init
This commit is contained in:
parent
44d9177161
commit
0c6462dbda
4 changed files with 187 additions and 0 deletions
51
packages/create-logto/package.json
Normal file
51
packages/create-logto/package.json
Normal file
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"name": "create-logto",
|
||||
"version": "1.0.0",
|
||||
"description": "Logto creation to getting started.",
|
||||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"homepage": "https://github.com/logto-io/logto#readme",
|
||||
"license": "MPL-2.0",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/logto-io/logto.git"
|
||||
},
|
||||
"bin": "./lib/index.js",
|
||||
"scripts": {
|
||||
"precommit": "lint-staged",
|
||||
"build": "rimraf lib && tsc",
|
||||
"dev": "tsc --watch --preserveWatchOutput --incremental",
|
||||
"lint": "eslint --ext .ts src",
|
||||
"lint:report": "pnpm lint --format json --output-file report.json",
|
||||
"prepack": "pnpm build"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.0.0"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/logto-io/logto/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.27.2",
|
||||
"decompress": "^4.2.1",
|
||||
"prompts": "^2.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@silverhand/eslint-config": "1.0.0",
|
||||
"@silverhand/ts-config": "1.0.0",
|
||||
"@types/axios": "^0.14.0",
|
||||
"@types/decompress": "^4.2.4",
|
||||
"@types/prompts": "^2.0.14",
|
||||
"eslint": "^8.21.0",
|
||||
"lint-staged": "^13.0.0",
|
||||
"prettier": "^2.7.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "@silverhand"
|
||||
},
|
||||
"prettier": "@silverhand/eslint-config/.prettierrc"
|
||||
}
|
31
packages/create-logto/src/functions.ts
Normal file
31
packages/create-logto/src/functions.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { execSync } from 'child_process';
|
||||
import { createWriteStream } from 'fs';
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
export const isVersionGreaterThan = (version: string, targetMajor: number) =>
|
||||
Number(version.split('.')[0]) >= targetMajor;
|
||||
|
||||
export const trimV = (version: string) => (version.startsWith('v') ? version.slice(1) : version);
|
||||
|
||||
export const safeExecSync = (command: string) => {
|
||||
try {
|
||||
return execSync(command, { encoding: 'utf8', stdio: 'pipe' });
|
||||
} catch {}
|
||||
};
|
||||
|
||||
export const downloadFile = async (url: string, destination: string) => {
|
||||
const file = createWriteStream(destination);
|
||||
const response = await axios.get(url, { responseType: 'stream' });
|
||||
response.data.pipe(file);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
file.on('error', (error) => {
|
||||
reject(error.message);
|
||||
});
|
||||
file.on('finish', () => {
|
||||
file.close();
|
||||
resolve(file);
|
||||
});
|
||||
});
|
||||
};
|
95
packages/create-logto/src/index.ts
Normal file
95
packages/create-logto/src/index.ts
Normal file
|
@ -0,0 +1,95 @@
|
|||
import { execSync } from 'child_process';
|
||||
import { existsSync } from 'fs';
|
||||
import { unlink } from 'fs/promises';
|
||||
import path from 'path';
|
||||
|
||||
import decompress from 'decompress';
|
||||
import prompt from 'prompts';
|
||||
|
||||
import { downloadFile, isVersionGreaterThan, safeExecSync, trimV } from './functions';
|
||||
|
||||
const DIRECTORY = 'logto';
|
||||
const NODE_MAJOR_VERSION = 16;
|
||||
const POSTGRES_MAJOR_VERSION = 14;
|
||||
|
||||
async function main() {
|
||||
const nodeVersion = execSync('node -v', { encoding: 'utf8', stdio: 'pipe' });
|
||||
const pgOutput = safeExecSync('postgres --version') ?? '';
|
||||
const pgArray = pgOutput.split(' ');
|
||||
const pgVersion = pgArray[pgArray.length - 1]!;
|
||||
|
||||
if (!isVersionGreaterThan(trimV(nodeVersion), NODE_MAJOR_VERSION)) {
|
||||
throw new Error(`Logto requires NodeJS >= ${NODE_MAJOR_VERSION}.0.0.`);
|
||||
}
|
||||
|
||||
let response;
|
||||
|
||||
try {
|
||||
response = await prompt(
|
||||
[
|
||||
{
|
||||
name: 'instancePath',
|
||||
message: 'Where should we create your logto instance?',
|
||||
type: 'text',
|
||||
initial: './' + DIRECTORY,
|
||||
format: (value: string) => path.resolve(value.trim()),
|
||||
validate: (value: string) =>
|
||||
existsSync(value) ? 'That path already exists, please try another.' : true,
|
||||
},
|
||||
{
|
||||
name: 'hasPostgresUrl',
|
||||
message: `Logto requires PostgreSQL >= ${POSTGRES_MAJOR_VERSION}.0.0 but cannot find in the current environment. Do you have a remote PostgreSQL instance ready?`,
|
||||
type: !isVersionGreaterThan(trimV(pgVersion), POSTGRES_MAJOR_VERSION) ? 'confirm' : null,
|
||||
initial: true,
|
||||
},
|
||||
{
|
||||
name: 'postgresUrl',
|
||||
message: 'What is the URL of your PostgreSQL instance?',
|
||||
type: (_, data) => (data.hasPostgresUrl ? 'text' : null),
|
||||
format: (value: string) => value.trim(),
|
||||
validate: (value: string) =>
|
||||
(value &&
|
||||
Boolean(
|
||||
/^(?:([^\s#/:?]+):\/{2})?(?:([^\s#/?@]+)@)?([^\s#/?]+)?(?:\/([^\s#?]*))?(?:\?([^\s#]+))?\S*$/.test(
|
||||
value
|
||||
)
|
||||
)) ||
|
||||
'Please enter a valid connection URL.',
|
||||
},
|
||||
{
|
||||
name: 'startInstance',
|
||||
message: 'Would you like to start Logto now?',
|
||||
type: 'confirm',
|
||||
initial: true,
|
||||
},
|
||||
],
|
||||
{
|
||||
onCancel: () => {
|
||||
throw new Error('Operation cancelled');
|
||||
},
|
||||
}
|
||||
);
|
||||
} catch (error: any) {
|
||||
console.log(error.message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const startCommand = `cd ${response.instancePath} && npm start`;
|
||||
const tarFileLocation = path.resolve('./logto.tar.gz');
|
||||
|
||||
await downloadFile(
|
||||
'https://github.com/logto-io/logto/releases/latest/download/logto.tar.gz',
|
||||
tarFileLocation
|
||||
);
|
||||
await decompress(tarFileLocation, response.instancePath);
|
||||
await unlink(tarFileLocation);
|
||||
|
||||
if (response.startInstance) {
|
||||
execSync(startCommand, { stdio: 'inherit' });
|
||||
} else {
|
||||
console.log(`You can use ${startCommand} to start Logto. Happy hacking!`);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
10
packages/create-logto/tsconfig.json
Normal file
10
packages/create-logto/tsconfig.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"extends": "@silverhand/ts-config/tsconfig.base",
|
||||
"compilerOptions": {
|
||||
"outDir": "lib",
|
||||
"declaration": true
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|
Loading…
Reference in a new issue