Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): init cli #488

Merged
merged 1 commit into from
Dec 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
392 changes: 392 additions & 0 deletions cli/package-lock.json

Large diffs are not rendered by default.

41 changes: 41 additions & 0 deletions cli/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "laf-cli",
"version": "1.0.0",
"description": "",
"main": "dist/main.js",
"bin": {
"laf": "dist/main.js"
},
"scripts": {
"dev": "tsc -w",
"watch": "tsc -w",
"build": "tsc",
"prepublishOnly": "npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/labring/laf.git"
},
"keywords": [
"laf"
],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/labring/laf/issues"
},
"devDependencies": {
"@types/cli-table2": "^0.2.3",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@types/cli-table: '^0.3.1' ?

"@types/mime": "^2.0.3",
"@types/node": "^17.0.31"
},
"dependencies": {
"axios": "^1.2.1",
"class-transformer": "^0.5.1",
"cli-table3": "^0.6.3",
"commander": "^9.3.0",
"reflect-metadata": "^0.1.13",
"typescript": "^4.7.4",
"yaml": "^2.1.3"
}
}
45 changes: 45 additions & 0 deletions cli/src/actions/application/application.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { getHomeDir, writeYamlFile, ensureDirectory } from '../../utils/path';
import * as path from 'node:path'
import * as fs from 'node:fs'
import { getApplicationByAppid, listApplication } from '../../apis/application';
import * as Table from 'cli-table3';
import { ApplicationMetadata } from '../../templates/application';
import { APPLICATION_METADATA_FILE_NAME, FUNCTIONS_DIRECTORY_NAME } from '../../utils/constant'


export async function handleInitApplication(appid: string, options: { sync: boolean }) {
const applicationYamlPath = path.join(getHomeDir(), APPLICATION_METADATA_FILE_NAME)
if (fs.existsSync(applicationYamlPath)) {
console.log('The application configuration file already exists in the current directory, unable to initialize the application')
return
}
const res = await getApplicationByAppid(appid);
const applicationMetadata: ApplicationMetadata = {
appid: res.data.appid,
name: res.data.name,
regionName: res.data.regionName,
bundleName: res.data.bundleName,
}
writeYamlFile(applicationYamlPath, applicationMetadata);

// init directory
ensureDirectory(path.join(getHomeDir(), FUNCTIONS_DIRECTORY_NAME))


// if sync is true, load remote data in local
if (options.sync) {

}

}

export async function handleListApplication() {
const table = new Table({
head: ['appid', 'name', 'region', 'bundle', 'runtime'],
})
const res = await listApplication();
for (let app of res.data) {
table.push([app.appid, app.name, app.regionName, app.bundleName, app.runtimeName])
}
console.log(table.toString());
}
28 changes: 28 additions & 0 deletions cli/src/apis/application.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { requestData } from "../utils/request"

/**
* 根据 appid 获取应用
* @param {string} appid
* @returns 返回应用数据
*/
export async function getApplicationByAppid(appid: string) {
const res = await requestData({
url: `/v1/applications/${appid}`,
method: 'get'
})
return res.data
}

/**
* 获取应用列表
* @returns 返回应用数据
*/
export async function listApplication() {
const url = `/v1/applications`
const obj = {
method: "GET",
url
}
const result = await requestData(obj)
return result.data
}
25 changes: 25 additions & 0 deletions cli/src/commands/application/application.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { program, Command } from 'commander'

import {handleInitApplication, handleListApplication} from '../../actions/application/application'

export function applicationCommand(): Command {
const app = program.command('app')

app
.command('init <appid>')
.description('Initialize application')
.option('-s, --sync', 'Sync application', "false")
.action((appid, options) => {
handleInitApplication(appid, options)
})

app.command('list')
.description('List application')
.action(() => {
handleListApplication()
})

return app
}


15 changes: 15 additions & 0 deletions cli/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Command } from 'commander'
import { applicationCommand } from './commands/application/application'


const program = new Command()
program
.option('-v, --version', 'output version')
.action(() => {
const version = require('../package.json').version
console.log(version)
})

program.addCommand(applicationCommand())

program.parse(process.argv)
16 changes: 16 additions & 0 deletions cli/src/templates/application.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

export interface ApplicationMetadata {
maslow marked this conversation as resolved.
Show resolved Hide resolved

name: string;

appid: string;

regionName?: string;

bundleName?: string;

runtimeName?: string;

createdAt?: string;

}
10 changes: 10 additions & 0 deletions cli/src/utils/constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

export const APPLICATION_METADATA_FILE_NAME = 'laf.yaml';

export const FUNCTIONS_DIRECTORY_NAME = 'functions';

export const FUNCTIONS_METADATA_FILE_SUFFIX_NAME = '.meta.yaml';

export const COLLECTIONS_DIRECTORY_NAME = 'collections';

export const COLLECTIONS_METADATA_FILE_SUFFIX_NAME = '.meta.yaml';
29 changes: 29 additions & 0 deletions cli/src/utils/path.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as fs from 'node:fs'
import { stringify, parse } from 'yaml'

export function getHomeDir() {
return "/Users/mac/Work/laf-cli-test/";
}

export function ensureDirectory(dir: string) {
try {
fs.accessSync(dir, fs.constants.R_OK | fs.constants.W_OK)
} catch (err) {
fs.mkdirSync(dir, { recursive: true })
}
}

export function exist(fp: string): boolean {
return fs.existsSync(fp);
}

export function loadYamlFile(filePath: string): any {
const metadataStr = fs.readFileSync(filePath, 'utf-8')
const yamlData = parse(metadataStr);
return yamlData;
}

export function writeYamlFile(filePath: string, data: any) {
const yamlData = stringify(data);
fs.writeFileSync(filePath, yamlData);
}
84 changes: 84 additions & 0 deletions cli/src/utils/request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import axios from 'axios'
import { getRemoteServer } from './token'
import { getAccessToken } from './token'
Comment on lines +2 to +3
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

combine into one line



export const request = axios.create({
// set baseURL
baseURL: getRemoteServer()
})

// http request
request.interceptors.request.use(
async (config) => {
const token = await getAccessToken()
if (token) {
config.headers = {
...config.headers,
Authorization: `Bearer ${token}`
};
} else {
console.error("please login first: `laf login -u username -p password`")
process.exit(1)
}
return config
},
(error) => {
// 错误抛到业务代码
error.data = {}
error.data.msg = '服务器异常,请联系管理员!'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

代码中的中文,还是在写的时候 统一 去除掉

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好的

return Promise.resolve(error)
},
)



request.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/

/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
response => {
return response
},
error => {
const status = error.response.status

if (status === 401) {
console.error(error.response.data)
process.exit(1)

}
if (status === 403) {
console.error(error.response.data)
process.exit(1)
}
if (status === 404) {
console.error(error.response.data)
process.exit(1)
}
if (status === 422) {
console.error(error.response.data)
process.exit(1)
}

// showError(error.message)
return Promise.reject(error)
}
)



/**
* 描述 axios request 请求
* @param {Object} obj
*/
export function requestData(obj: object) {
return request.request(obj)
}
9 changes: 9 additions & 0 deletions cli/src/utils/token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@


export function getAccessToken(): string {
return 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2MzhkZDdhNTBlZTVjMGViNjk2NWU2NzIiLCJpYXQiOjE2NzAzMTE2ODksImV4cCI6MTY3MDkxNjQ4OX0.2UtpV0WC5kvtoPynvhXCSnrh9vadKQ7crLBMSxnI3A8'
}

export function getRemoteServer(): string {
return 'http://localhost:3000'
Comment on lines +4 to +8
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这些是不是应该弄到配置文件?

}
39 changes: 39 additions & 0 deletions cli/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"compileOnSave": true,
"compilerOptions": {
"allowJs": false,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"charset": "utf8",
"declaration": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"importHelpers": false,
"module": "commonjs",
"declarationMap": true,
// "declarationDir": "types",
"noEmitOnError": false,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": false,
"noUnusedLocals": true,
"noUnusedParameters": true,
"outDir": "dist",
"pretty": true,
"removeComments": true,
"stripInternal": true,
"skipDefaultLibCheck": true,
"skipLibCheck": true,
"target": "es2017",
"alwaysStrict": true,
"lib": [
"es2015",
"es6"
]
},
"include": [
"src/**/*",
],
"exclude": [
"tests",
]
}