@huolala-tech/nad-cli
Advanced tools
Comparing version 0.0.1 to 0.0.2
@@ -0,1 +1,9 @@ | ||
## 0.0.2 | ||
- Support more URL format | ||
- Update i18n test cases | ||
- Fix url path automatically | ||
- Add utils tests | ||
- Update error message | ||
- Add test cases | ||
- Create repository |
@@ -8,1 +8,2 @@ export * from './FileIsNotJson'; | ||
export * from './UnknownOption'; | ||
export * from './ContentTypeIsNotJson'; |
@@ -1,14 +0,22 @@ | ||
export declare const I100: () => string; | ||
export declare const I101: (args_0: string | number | null | undefined) => string; | ||
export declare const I102: (args_0: string | number | null | undefined) => string; | ||
export declare const I103: (args_0: string | number | null | undefined) => string; | ||
export declare const I104: (args_0: string | number | null | undefined) => string; | ||
export declare const I105: (args_0: string | number | null | undefined) => string; | ||
export declare const I107: (args_0: string | number | null | undefined) => string; | ||
export declare const I108: () => string; | ||
export declare const I109: (args_0: string | number | null | undefined) => string; | ||
export declare const I110: (args_0: string | number | null | undefined) => string; | ||
export declare const I111: (args_0: string | number | null | undefined) => string; | ||
export declare const I112: (args_0: string | number | null | undefined) => string; | ||
export declare const I113: (args_0: string | number | null | undefined) => string; | ||
export declare const I114: (args_0: string | number | null | undefined) => string; | ||
interface Desc { | ||
zh: string; | ||
en: string; | ||
} | ||
export declare const getTemplateByType: (desc: Desc, key?: string) => string; | ||
export declare const i18n: <T extends number>(desc: Desc) => ((...args: 0 extends T ? [] : 1 extends T ? [string | number | null | undefined] : 2 extends T ? [string | number | null | undefined, string | number | null | undefined] : 3 extends T ? [string | number | null | undefined, string | number | null | undefined, string | number | null | undefined] : 4 extends T ? [string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined] : 5 extends T ? [string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined] : 6 extends T ? [string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined] : 7 extends T ? [string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined] : 8 extends T ? [string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined] : 9 extends T ? [string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined] : 10 extends T ? [string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined, string | number | null | undefined] : any) => string) & Desc; | ||
export declare const I100: (() => string) & Desc; | ||
export declare const I101: ((args_0: string | number | null | undefined) => string) & Desc; | ||
export declare const I102: ((args_0: string | number | null | undefined) => string) & Desc; | ||
export declare const I103: ((args_0: string | number | null | undefined) => string) & Desc; | ||
export declare const I104: ((args_0: string | number | null | undefined) => string) & Desc; | ||
export declare const I105: ((args_0: string | number | null | undefined) => string) & Desc; | ||
export declare const I107: ((args_0: string | number | null | undefined) => string) & Desc; | ||
export declare const I108: (() => string) & Desc; | ||
export declare const I109: ((args_0: string | number | null | undefined) => string) & Desc; | ||
export declare const I110: ((args_0: string | number | null | undefined) => string) & Desc; | ||
export declare const I111: ((args_0: string | number | null | undefined) => string) & Desc; | ||
export declare const I112: ((args_0: string | number | null | undefined) => string) & Desc; | ||
export declare const I113: ((args_0: string | number | null | undefined) => string) & Desc; | ||
export declare const I114: ((args_0: string | number | null | undefined) => string) & Desc; | ||
export declare const I115: ((args_0: string | number | null | undefined, args_1: string | number | null | undefined, args_2: string | number | null | undefined) => string) & Desc; | ||
export {}; |
@@ -54,6 +54,20 @@ 'use strict'; | ||
const lang = (env.LC_ALL || env.LC_MESSAGES || env.LANG || env.LANGUAGE || 'en-US').replace(/_/g, '-').replace(/\..*/, ''); | ||
const findVariablePosition = line => { | ||
let pos = 0; | ||
for (let i = 0; i < line.length; i++) { | ||
const v = line.charCodeAt(i); | ||
if (v === 0x1b) return pos; // break on ANSI start | ||
// 1: ASCII | ||
// 2: Other wider character | ||
pos += v > 0xff ? 2 : 1; | ||
} | ||
return 0; | ||
}; | ||
const type = lang.replace(/-.*/g, ''); | ||
const getTemplateByType = (desc, key = type) => { | ||
return key in desc ? desc[key] : desc.en; | ||
}; | ||
const i18n = desc => { | ||
return (...args) => { | ||
const template = type in desc ? desc[type] : desc.en; | ||
const fn = (...args) => { | ||
const template = getTemplateByType(desc); | ||
return template.replace(/\$(\d+)(<(.*?),(.*?)>)?/g, (_, number, isChoice, singular, plural) => { | ||
@@ -69,2 +83,3 @@ const variable = String(args[number - 1]); | ||
}; | ||
return Object.assign(fn, desc); | ||
}; | ||
@@ -94,5 +109,5 @@ const I100 = i18n({ | ||
Options: | ||
-t, --target <target> The output file format, one of ("ts", "oc", "raw"), defaults "ts" | ||
-c, --confit <path> A config file path (if it's specified, other arguments are no loger revent) | ||
-h, --help Show this help information | ||
-t, --target <target> Specify the output file format ("ts", "oc", "raw"), defaults to "ts". | ||
-c, --config <path> Path to configuration file. If specified, all other arguments will be ignored. | ||
-h, --help Display this help message. | ||
` | ||
@@ -102,3 +117,3 @@ }); | ||
zh: `成功生成 $1 个模块,其中包含:`, | ||
en: `There $1<is,are> $1 $1<module,modules> have been successfully generated, containing the following:` | ||
en: `A total of $1 $1<module,modules> $1<was,were> generated, containing the following:` | ||
}); | ||
@@ -127,28 +142,32 @@ const I102 = i18n({ | ||
zh: `你指定了一个配置文件,因此其它参数将会被忽略`, | ||
en: `Since you specified a configuration file, arguments are no longer relevant` | ||
en: `Since a configuration file was specified, all other arguments will be ignored` | ||
}); | ||
const I109 = i18n({ | ||
zh: `配置文件中缺少 $1 字段`, | ||
en: `The '$1' field is missing from your configuration file` | ||
en: `The configuration file is missing the '$1' field` | ||
}); | ||
const I110 = i18n({ | ||
zh: `提供的 $1 不是一个有效的 URI`, | ||
en: `The $1 is not a valid URI` | ||
en: `The '$1' is not a valid URI` | ||
}); | ||
const I111 = i18n({ | ||
zh: `提供的 $1 是一个目录不是文件`, | ||
en: `The $1 is a directory not a file` | ||
zh: `提供的 $1 是一个目录而不是文件`, | ||
en: `The '$1' is a directory, not a file` | ||
}); | ||
const I112 = i18n({ | ||
zh: `无效的输出格式 $1`, | ||
en: `Invalid output formats ($1)` | ||
zh: `无效的输出格式 '$1',只支持 ts、oc、raw`, | ||
en: `The output format '$1' is not valid. Only 'ts', 'oc', and 'raw' are supported` | ||
}); | ||
const I113 = i18n({ | ||
zh: `配置文件 $1 不是一个有效的 JSON`, | ||
en: `The config file $1 is not a valid JSON.` | ||
en: `The configuration file '$1' is not a valid JSON` | ||
}); | ||
const I114 = i18n({ | ||
zh: `配置文件 $1 不存在`, | ||
en: `The config file $1 is not found.` | ||
en: `The configuration file '$1' not found` | ||
}); | ||
const I115 = i18n({ | ||
zh: `接口响应了一个 $1 内容类型,期望是 $2(来自 $3)`, | ||
en: `Response Content-Type $1 while expected $2 (from $3)` | ||
}); | ||
class Option { | ||
@@ -215,2 +234,14 @@ constructor(read) { | ||
} | ||
class UnexpectedContentType extends customError.CustomError { | ||
constructor(actual, expect, url) { | ||
super(I115(actual, expect, url)); | ||
this.name = 'UnexpectedContentType'; | ||
} | ||
static assertJson(res, url) { | ||
const type = res.headers['content-type']; | ||
if (!type || !/^application\/json\s*(;|$)/i.test(type)) { | ||
throw new UnexpectedContentType(type, 'application/json', url); | ||
} | ||
} | ||
} | ||
class Program { | ||
@@ -357,13 +388,2 @@ constructor(options) { | ||
}; | ||
const findVariablePosition = line => { | ||
let pos = 0; | ||
for (let i = 0; i < line.length; i++) { | ||
const v = line.charCodeAt(i); | ||
if (v === 0x1b) break; // break on ANSI start | ||
// 1: ASCII | ||
// 2: Other wider character | ||
pos += v > 0xff ? 2 : 1; | ||
} | ||
return pos; | ||
}; | ||
const printBuilderInfo = (root, io) => { | ||
@@ -393,11 +413,35 @@ const gen = new nadBuilder.CodeGen(); | ||
const request = url => __awaiter(void 0, void 0, void 0, function* () { | ||
const headers = {}; | ||
headers['Accept-Language'] = [lang, '*'].join(', '); | ||
const res = yield axios(url, { | ||
headers, | ||
const config = { | ||
headers: {}, | ||
timeout: 10000 | ||
}); | ||
const defs = res.data; | ||
return defs; | ||
}; | ||
config.headers['Accept-Language'] = [lang, '*'].join(', '); | ||
config.headers['Accept'] = 'application/json'; | ||
const res = yield axios(url, config); | ||
UnexpectedContentType.assertJson(res, url); | ||
return res.data; | ||
}); | ||
const DEFS_PATH = '/nad/api/defs'; | ||
function fixUrl(url) { | ||
const u = new URL(url); | ||
u.pathname = u.pathname.replace(/((\/nad(\/api(\/defs)?)?)?|\/*)$/, DEFS_PATH); | ||
return u.toString(); | ||
} | ||
const getDefsFromRemote = url => __awaiter(void 0, void 0, void 0, function* () { | ||
const fixedUrl = fixUrl(url); | ||
try { | ||
return yield request(fixedUrl); | ||
} catch (error) { | ||
// Retry with original url, if some errors are received from the fixed url. | ||
if (fixedUrl !== url) { | ||
switch (true) { | ||
case error instanceof axios.AxiosError && !!error.response: | ||
case error instanceof UnexpectedContentType: | ||
return yield request(url); | ||
} | ||
} | ||
/* istanbul ignore next */ | ||
throw error; | ||
} | ||
}); | ||
const processByConfig = (config, io = process) => __awaiter(void 0, void 0, void 0, function* () { | ||
@@ -410,3 +454,3 @@ const { | ||
} = config; | ||
const defs = yield request(url); | ||
const defs = yield getDefsFromRemote(url); | ||
const { | ||
@@ -413,0 +457,0 @@ root, |
@@ -5,2 +5,3 @@ import type { Writable } from 'stream'; | ||
export declare const getWritable: (file: string | undefined, io: IO) => Writable; | ||
export declare function fixUrl(url: string): string; | ||
export declare const processByConfig: (config: Config, io?: IO) => Promise<void>; |
@@ -8,1 +8,2 @@ /// <reference types="node" /> | ||
} | ||
export declare const findVariablePosition: (line: string) => number; |
{ | ||
"name": "@huolala-tech/nad-cli", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"description": "The CLI Tools of Nad Project", | ||
@@ -17,3 +17,3 @@ "main": "./dist/index.js", | ||
"scripts": { | ||
"test": "jest src", | ||
"test": "jest --coverage", | ||
"fix": "yarn lint && yarn prettier", | ||
@@ -38,13 +38,13 @@ "lint": "eslint src --fix", | ||
"@rollup/plugin-babel": "^6.0.3", | ||
"@rollup/plugin-commonjs": "^24.0.1", | ||
"@rollup/plugin-commonjs": "^24.1.0", | ||
"@rollup/plugin-json": "^6.0.0", | ||
"@rollup/plugin-node-resolve": "^15.0.2", | ||
"@types/jest": "^29.5.0", | ||
"@typescript-eslint/eslint-plugin": "^5.57.1", | ||
"@typescript-eslint/parser": "^5.57.1", | ||
"eslint": "^8.37.0", | ||
"@typescript-eslint/eslint-plugin": "^5.58.0", | ||
"@typescript-eslint/parser": "^5.58.0", | ||
"eslint": "^8.38.0", | ||
"husky": "^8.0.3", | ||
"jest": "^29.5.0", | ||
"prettier": "^2.8.7", | ||
"rollup": "^3.20.2", | ||
"rollup": "^3.20.4", | ||
"rollup-plugin-delete": "^2.0.0", | ||
@@ -51,0 +51,0 @@ "rollup-plugin-typescript2": "^0.34.1", |
Sorry, the diff of this file is not supported yet
55334
32
592