Skip to content

Commit 7e0bd86

Browse files
authored
feat: compile api (#2)
1 parent 8570710 commit 7e0bd86

File tree

20 files changed

+631
-59
lines changed

20 files changed

+631
-59
lines changed

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
lib
22
coverage
33
tsconfig.json
4+
__generated__

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ TODO:
2424

2525
## :handshake: API
2626

27-
TODO:
27+
About details, See the [API References](https://github.com/intlify/cli/blob/master/api.md)
2828

2929

3030
## :scroll: Changelog

api.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# @intlify/cli API References
2+
3+
## Table Of Contents
4+
5+
- [Function](#function)
6+
- [compile](#compile)
7+
- [Enum](#enum)
8+
- [CompileErrorCodes](#compileerrorcodes)
9+
- [Interface](#interface)
10+
- [CompileOptions](#compileoptions)
11+
12+
## Function
13+
14+
### compile
15+
16+
Compile i18n resources
17+
18+
**Signature:**
19+
```typescript
20+
export declare function compile(source: string, output: string, options?: CompileOptions): Promise<boolean>;
21+
```
22+
23+
#### Parameters
24+
25+
| Parameter | Type | Description |
26+
| --- | --- | --- |
27+
| source | string | the i18n resource source path, you can use glob pattern |
28+
| output | string | the compiled i18n resource output path |
29+
| options | CompileOptions | [CompileOptions](#compileoptions) |
30+
31+
#### Returns
32+
33+
`true` when all i18n resource successfuly compile, not `false`
34+
35+
#### Remarks
36+
37+
This functoin is **asyncronous** function. If you want to get about error details, use the handler of [CompileOptions](#compileoptions) and [CompileErrorCodes](#compileerrorcodes)
38+
39+
40+
## Enum
41+
42+
### CompileErrorCodes
43+
44+
Compile Error Codes
45+
46+
**Signature:**
47+
```typescript
48+
export declare const enum CompileErrorCodes
49+
```
50+
51+
#### Members
52+
53+
| Member | Value| Description |
54+
| --- | --- | --- |
55+
| INTERNAL_COMPILE_ERROR | 3 | Internal compile error |
56+
| INTERNAL_COMPILE_WARNING | 2 | Internal compile warning |
57+
| NOT_SUPPORTED_FORMAT | 1 | Not supported format |
58+
59+
#### Remarks
60+
61+
The error codes of [compile](#compile) function
62+
63+
64+
## Interface
65+
66+
### CompileOptions
67+
68+
Compile Options
69+
70+
**Signature:**
71+
```typescript
72+
export interface CompileOptions
73+
```
74+
75+
#### Remarks
76+
77+
This optioins is used at [compile](#compile) function
78+
79+
80+
#### Methods
81+
82+
83+
#### Properties
84+
85+
##### onCompile
86+
87+
Compile handler
88+
89+
**Signature:**
90+
```typescript
91+
onCompile?: (source: string, output: string) => void;
92+
```
93+
94+
##### onError
95+
96+
Compile Error handler
97+
98+
**Signature:**
99+
```typescript
100+
onError?: (code: number, source: string, output: string, msg?: string) => void;
101+
```
102+
103+
104+

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
},
7272
"files": [
7373
"bin/*.js",
74+
"dist/*.d.ts",
7475
"lib/**/*.js"
7576
],
7677
"homepage": "https://github.com/intlify/cli#readme",
@@ -88,7 +89,7 @@
8889
},
8990
"scripts": {
9091
"build": "yarn build:transpile && yarn build:extract",
91-
"build:docs": "api-docs-gen ./temp/cli.api.json -c ./docsgen.config.js -o ./",
92+
"build:docs": "api-docs-gen ./temp/cli.api.json -c ./docsgen.config.js -o ./ -g noprefix",
9293
"build:extract": "api-extractor run -l -c ./api-extractor.json",
9394
"build:transpile": "tsc -p .",
9495
"clean": "npm-run-all clean:*",
@@ -108,5 +109,6 @@
108109
"test:unit": "jest --env node",
109110
"test:watch": "jest --env node --watch",
110111
"watch": "tsc -p . --watch"
111-
}
112+
},
113+
"types": "dist/cli.d.ts"
112114
}

src/api.ts

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import path from 'path'
2+
import { promises as fs } from 'fs'
3+
import { debug as Debug } from 'debug'
4+
import { generateJSON, generateYAML } from './generator/index'
5+
import { globAsync } from './utils'
6+
7+
const SUPPORTED_FORMAT = ['.json', '.json5', '.yaml', '.yml']
8+
const debug = Debug('@intlify/cli:api')
9+
10+
/**
11+
* Compile Error Codes
12+
*
13+
* @remarks
14+
* The error codes of {@link compile} function
15+
*
16+
* @public
17+
*/
18+
export const enum CompileErrorCodes {
19+
/**
20+
* Not supported format
21+
*/
22+
NOT_SUPPORTED_FORMAT = 1,
23+
/**
24+
* Internal compile warning
25+
*/
26+
INTERNAL_COMPILE_WARNING,
27+
/**
28+
* Internal compile error
29+
*/
30+
INTERNAL_COMPILE_ERROR
31+
}
32+
33+
/**
34+
* Compile Options
35+
*
36+
* @remarks
37+
* This optioins is used at {@link compile} function
38+
*
39+
* @public
40+
*/
41+
export interface CompileOptions {
42+
/**
43+
* Compile Error handler
44+
*/
45+
onError?: (code: number, source: string, output: string, msg?: string) => void
46+
/**
47+
* Compile handler
48+
*/
49+
onCompile?: (source: string, output: string) => void
50+
}
51+
52+
/**
53+
* Compile i18n resources
54+
*
55+
* @param source - the i18n resource source path, you can use glob pattern
56+
* @param output - the compiled i18n resource output path
57+
* @param options - {@link CompileOptions}
58+
*
59+
* @remarks
60+
* This functoin is **asyncronous** function. If you want to get about error details, use the handler of {@link CompileOptions} and {@link CompileErrorCodes}
61+
*
62+
* @returns `true` when all i18n resource successfuly compile, not `false`
63+
*
64+
* @public
65+
*/
66+
export async function compile(
67+
source: string,
68+
output: string,
69+
options: CompileOptions = {}
70+
): Promise<boolean> {
71+
let ret = true
72+
73+
const targets = await globAsync(source)
74+
debug('compile: targets', targets)
75+
76+
for (const target of targets) {
77+
const parsed = path.parse(target)
78+
debug('parsed', parsed)
79+
if (!parsed.ext) {
80+
continue
81+
}
82+
const filename = `${parsed.name}.js`
83+
const generatePath = path.resolve(output, filename)
84+
if (!SUPPORTED_FORMAT.includes(parsed.ext)) {
85+
options.onError &&
86+
options.onError(
87+
CompileErrorCodes.NOT_SUPPORTED_FORMAT,
88+
target,
89+
generatePath
90+
)
91+
ret = false
92+
continue
93+
}
94+
const source = await fs.readFile(target, { encoding: 'utf-8' })
95+
const generate = /\.json?5/.test(parsed.ext) ? generateJSON : generateYAML
96+
let occuredError = false
97+
const { code } = generate(source, {
98+
type: 'plain',
99+
filename: target,
100+
env: 'production',
101+
onError: (msg: string): void => {
102+
occuredError = true
103+
options.onError &&
104+
options.onError(
105+
CompileErrorCodes.INTERNAL_COMPILE_ERROR,
106+
target,
107+
generatePath,
108+
msg
109+
)
110+
ret = false
111+
},
112+
onWarn: (msg: string): void => {
113+
options.onError &&
114+
options.onError(
115+
CompileErrorCodes.INTERNAL_COMPILE_WARNING,
116+
target,
117+
generatePath,
118+
msg
119+
)
120+
ret = false
121+
}
122+
})
123+
if (!occuredError) {
124+
await writeGenerateCode(output, filename, code)
125+
options.onCompile && options.onCompile(target, generatePath)
126+
}
127+
}
128+
129+
return ret
130+
}
131+
132+
export async function writeGenerateCode(
133+
target: string,
134+
filename: string,
135+
code: string
136+
): Promise<string> {
137+
await fs.mkdir(target, { recursive: true })
138+
const generatePath = path.resolve(target, filename)
139+
await fs.writeFile(generatePath, code)
140+
return generatePath
141+
}

src/commands/compile.ts

Lines changed: 34 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import path from 'path'
2-
import { promises as fs } from 'fs'
32
import chalk from 'chalk'
43
import { Arguments, Argv } from 'yargs'
5-
import { generateJSON, generateYAML } from '../generator/index'
6-
import { globAsync } from '../utils'
4+
import { debug as Debug } from 'debug'
5+
import { CompileErrorCodes, compile } from '../api'
76

8-
const SUPPORTED_FORMAT = ['.json', '.json5', '.yaml', '.yml']
7+
const debug = Debug('@intlify/cli:compile')
98

109
type CompileOptions = {
1110
source: string
@@ -36,59 +35,41 @@ export const handler = async (
3635
): Promise<void> => {
3736
const output =
3837
args.output != null ? path.resolve(__dirname, args.output) : process.cwd()
39-
const targets = await globAsync(args.source)
40-
targets.forEach(async (target: string) => {
41-
const parsed = path.parse(target)
42-
if (!SUPPORTED_FORMAT.includes(parsed.ext)) {
43-
console.warn(
44-
chalk.yellow(
45-
`${target}: Ignore compilation due to not supported '${parsed.ext}'`
46-
)
47-
)
48-
return
49-
}
50-
const source = await fs.readFile(target, { encoding: 'utf-8' })
51-
const generate = /\.json?5/.test(parsed.ext) ? generateJSON : generateYAML
52-
const filename = `${parsed.name}.js`
53-
const generatePath = path.resolve(output, filename)
54-
let occuredError = false
55-
const { code } = generate(source, {
56-
type: 'plain',
57-
filename: target,
58-
env: 'production',
59-
onError: (msg: string): void => {
60-
occuredError = true
61-
console.log(
62-
chalk.green(`error compilation: ${target} -> ${generatePath}, ${msg}`)
63-
)
64-
},
65-
onWarn: (msg: string): void => {
66-
console.log(
67-
chalk.yellow(
68-
`warning compilation: ${target} -> ${generatePath}, ${msg}`
38+
const ret = await compile(args.source, output, {
39+
onCompile: (source: string, output: string): void => {
40+
console.log(chalk.green(`success compilation: ${source} -> ${output}`))
41+
},
42+
onError: (
43+
code: number,
44+
source: string,
45+
output: string,
46+
msg?: string
47+
): void => {
48+
switch (code) {
49+
case CompileErrorCodes.NOT_SUPPORTED_FORMAT:
50+
const parsed = path.parse(source)
51+
console.warn(
52+
chalk.yellow(
53+
`${source}: Ignore compilation due to not supported '${parsed.ext}'`
54+
)
55+
)
56+
break
57+
case CompileErrorCodes.INTERNAL_COMPILE_WARNING:
58+
console.log(
59+
chalk.yellow(`warning compilation: ${source} -> ${output}, ${msg}`)
60+
)
61+
break
62+
case CompileErrorCodes.INTERNAL_COMPILE_ERROR:
63+
console.log(
64+
chalk.green(`error compilation: ${source} -> ${output}, ${msg}`)
6965
)
70-
)
66+
break
67+
default:
68+
break
7169
}
72-
})
73-
if (!occuredError) {
74-
const filename = `${parsed.name}.js`
75-
await writeGenerateCode(output, filename, code)
76-
console.log(
77-
chalk.green(`success compilation: ${target} -> ${generatePath}`)
78-
)
7970
}
8071
})
81-
}
82-
83-
async function writeGenerateCode(
84-
target: string,
85-
filename: string,
86-
code: string
87-
): Promise<string> {
88-
await fs.mkdir(target, { recursive: true })
89-
const generatePath = path.resolve(target, filename)
90-
await fs.writeFile(generatePath, code)
91-
return generatePath
72+
debug('compile: ', ret)
9273
}
9374

9475
export default {

0 commit comments

Comments
 (0)