yata-fetch 1.3.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +16 -0
- package/.github/workflows/publish.yaml +23 -0
- package/.github/workflows/test.yaml +143 -0
- package/.prettierignore +15 -0
- package/.prettierrc +9 -0
- package/.tool-versions +1 -1
- package/README.md +35 -33
- package/bin/yata-fetch.js +2 -2
- package/dist/cli.cjs +2 -0
- package/package.json +22 -20
- package/src/cli.ts +48 -0
- package/src/log.ts +22 -0
- package/src/vite-env.d.ts +1 -0
- package/src/yata.ts +153 -0
- package/test/fixtures/yata.json +2 -4
- package/test/unit/yata.spec.js +111 -0
- package/tsconfig.json +20 -0
- package/vite.config.js +15 -0
- package/.circleci/config.yml +0 -17
- package/.eslintrc.js +0 -141
- package/dist/cli.js +0 -112
- package/dist/cli.js.map +0 -1
- package/dist/log.js +0 -26
- package/dist/log.js.map +0 -1
- package/dist/yata.js +0 -133
- package/dist/yata.js.map +0 -1
- package/gulpfile.js +0 -66
- package/src/cli.js +0 -42
- package/src/log.js +0 -20
- package/src/yata.js +0 -144
- package/test/unit/.eslintrc.js +0 -20
- package/test/unit/yata-spec.js +0 -103
package/.eslintrc.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"env": {
|
|
3
|
+
"browser": true,
|
|
4
|
+
"es2021": true
|
|
5
|
+
},
|
|
6
|
+
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
|
7
|
+
"parser": "@typescript-eslint/parser",
|
|
8
|
+
"parserOptions": {
|
|
9
|
+
"ecmaVersion": "latest",
|
|
10
|
+
"sourceType": "module"
|
|
11
|
+
},
|
|
12
|
+
"plugins": ["@typescript-eslint"],
|
|
13
|
+
"rules": {
|
|
14
|
+
"@typescript-eslint/no-var-requires": 0
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: Publish to NPM
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches:
|
|
5
|
+
- master
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
release:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- name: Checkout
|
|
12
|
+
uses: actions/checkout@v2
|
|
13
|
+
- name: Setup Node
|
|
14
|
+
uses: actions/setup-node@v2
|
|
15
|
+
with:
|
|
16
|
+
node-version: '16.16.0'
|
|
17
|
+
registry-url: 'https://registry.npmjs.org'
|
|
18
|
+
- name: Install dependencies and build 🔧
|
|
19
|
+
run: npm install && npm run build
|
|
20
|
+
- name: Publish package on NPM 📦
|
|
21
|
+
run: npm publish
|
|
22
|
+
env:
|
|
23
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
cache_version: v1
|
|
10
|
+
node-version: 16.16.0
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
dependencies:
|
|
14
|
+
name: Install dependencies
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v2
|
|
18
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
19
|
+
uses: actions/setup-node@v2
|
|
20
|
+
with:
|
|
21
|
+
node-version: ${{ env.node-version }}
|
|
22
|
+
- name: Set lockfile_hash
|
|
23
|
+
run: echo "lockfile_hash=${{ hashFiles('**/package-lock.json') }}" >> $GITHUB_ENV
|
|
24
|
+
- name: Restore node_modules cache
|
|
25
|
+
uses: actions/cache@v2
|
|
26
|
+
id: node-modules-cache
|
|
27
|
+
with:
|
|
28
|
+
path: ./node_modules
|
|
29
|
+
key: ${{ runner.os }}-node-modules-${{ env.cache_version }}-${{ env.lockfile_hash }}
|
|
30
|
+
- name: Get npm cache directory path
|
|
31
|
+
if: steps.node-modules-cache.outputs.cache-hit != 'true'
|
|
32
|
+
id: npm-cache-dir-path
|
|
33
|
+
run: echo "::set-output name=dir::~/.npm/_cacache"
|
|
34
|
+
- name: Restore npm cache
|
|
35
|
+
if: steps.node-modules-cache.outputs.cache-hit != 'true'
|
|
36
|
+
uses: actions/cache@v2
|
|
37
|
+
id: npm-cache
|
|
38
|
+
with:
|
|
39
|
+
path: ${{ steps.npm-cache-dir-path.outputs.dir }}
|
|
40
|
+
key: ${{ runner.os }}-npm-${{ env.cache_version }}-${{ env.lockfile_hash }}
|
|
41
|
+
restore-keys: ${{ runner.os }}-npm-${{ env.cache_version }}-
|
|
42
|
+
- name: Install dependencies
|
|
43
|
+
if: steps.node-modules-cache.outputs.cache-hit != 'true'
|
|
44
|
+
run: npm ci
|
|
45
|
+
lint_scripts:
|
|
46
|
+
name: Lint JavaScript
|
|
47
|
+
needs: dependencies
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
steps:
|
|
50
|
+
- uses: actions/checkout@v2
|
|
51
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
52
|
+
uses: actions/setup-node@v2
|
|
53
|
+
with:
|
|
54
|
+
node-version: ${{ env.node-version }}
|
|
55
|
+
- name: Restore node_modules cache
|
|
56
|
+
uses: actions/cache@v2
|
|
57
|
+
id: node-modules-cache
|
|
58
|
+
with:
|
|
59
|
+
path: ./node_modules
|
|
60
|
+
key: ${{ runner.os }}-node-modules-${{ env.cache_version }}-${{ hashFiles('**/package-lock.json') }}
|
|
61
|
+
- name: Lint
|
|
62
|
+
run: npm run lint:eslint
|
|
63
|
+
lint_format:
|
|
64
|
+
name: Lint Formatting
|
|
65
|
+
needs: dependencies
|
|
66
|
+
runs-on: ubuntu-latest
|
|
67
|
+
steps:
|
|
68
|
+
- uses: actions/checkout@v2
|
|
69
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
70
|
+
uses: actions/setup-node@v2
|
|
71
|
+
with:
|
|
72
|
+
node-version: ${{ env.node-version }}
|
|
73
|
+
- name: Restore node_modules cache
|
|
74
|
+
uses: actions/cache@v2
|
|
75
|
+
id: node-modules-cache
|
|
76
|
+
with:
|
|
77
|
+
path: ./node_modules
|
|
78
|
+
key: ${{ runner.os }}-node-modules-${{ env.cache_version }}-${{ hashFiles('**/package-lock.json') }}
|
|
79
|
+
- name: Lint format
|
|
80
|
+
run: npm run lint:fmt
|
|
81
|
+
lint_types:
|
|
82
|
+
name: Lint Typings
|
|
83
|
+
needs: dependencies
|
|
84
|
+
runs-on: ubuntu-latest
|
|
85
|
+
steps:
|
|
86
|
+
- uses: actions/checkout@v2
|
|
87
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
88
|
+
uses: actions/setup-node@v2
|
|
89
|
+
with:
|
|
90
|
+
node-version: ${{ env.node-version }}
|
|
91
|
+
- name: Restore node_modules cache
|
|
92
|
+
uses: actions/cache@v2
|
|
93
|
+
id: node-modules-cache
|
|
94
|
+
with:
|
|
95
|
+
path: ./node_modules
|
|
96
|
+
key: ${{ runner.os }}-node-modules-${{ env.cache_version }}-${{ hashFiles('**/package-lock.json') }}
|
|
97
|
+
- name: Lint
|
|
98
|
+
run: npm run lint:ts
|
|
99
|
+
build:
|
|
100
|
+
name: Build application
|
|
101
|
+
needs:
|
|
102
|
+
- dependencies
|
|
103
|
+
- lint_types
|
|
104
|
+
runs-on: ubuntu-latest
|
|
105
|
+
steps:
|
|
106
|
+
- uses: actions/checkout@v2
|
|
107
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
108
|
+
uses: actions/setup-node@v2
|
|
109
|
+
with:
|
|
110
|
+
node-version: ${{ env.node-version }}
|
|
111
|
+
- name: Restore node_modules cache
|
|
112
|
+
uses: actions/cache@v2
|
|
113
|
+
id: node-modules-cache
|
|
114
|
+
with:
|
|
115
|
+
path: ./node_modules
|
|
116
|
+
key: ${{ runner.os }}-node-modules-${{ env.cache_version }}-${{ hashFiles('**/package-lock.json') }}
|
|
117
|
+
- name: Build app
|
|
118
|
+
run: npm run build
|
|
119
|
+
test_unit:
|
|
120
|
+
name: Unit Tests
|
|
121
|
+
needs:
|
|
122
|
+
- build
|
|
123
|
+
- lint_scripts
|
|
124
|
+
- lint_format
|
|
125
|
+
- lint_types
|
|
126
|
+
runs-on: ubuntu-latest
|
|
127
|
+
continue-on-error: false
|
|
128
|
+
outputs:
|
|
129
|
+
test-results: ${{ steps.status.outputs.test-results }}
|
|
130
|
+
steps:
|
|
131
|
+
- uses: actions/checkout@v2
|
|
132
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
133
|
+
uses: actions/setup-node@v2
|
|
134
|
+
with:
|
|
135
|
+
node-version: ${{ env.node-version }}
|
|
136
|
+
- name: Restore node_modules cache
|
|
137
|
+
uses: actions/cache@v2
|
|
138
|
+
id: node-modules-cache
|
|
139
|
+
with:
|
|
140
|
+
path: ./node_modules
|
|
141
|
+
key: ${{ runner.os }}-node-modules-${{ env.cache_version }}-${{ hashFiles('**/package-lock.json') }}
|
|
142
|
+
- name: Run tests
|
|
143
|
+
run: npm run test
|
package/.prettierignore
ADDED
package/.prettierrc
ADDED
package/.tool-versions
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
nodejs
|
|
1
|
+
nodejs 16.16.0
|
package/README.md
CHANGED
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
# yata-fetch
|
|
2
2
|
|
|
3
|
-
[](https://circleci.com/gh/dzbo/yata-fetch/tree/master)
|
|
4
|
-
|
|
5
3
|
Welcome to Yata integration package, this package will allow you to easy get your translations from http://yatapp.net service.
|
|
6
4
|
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
`yarn add yata-fetch -D`
|
|
7
|
+
`npm install yata-fetch -D`
|
|
12
8
|
|
|
13
9
|
## Usage
|
|
14
10
|
|
|
15
11
|
### Setup
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
- Create config file in project folder (see details below).
|
|
14
|
+
- Add `MY_YATA_API_TOKEN` key to env variables in `.zshrc/.bashrc`:
|
|
19
15
|
|
|
20
16
|
```
|
|
21
17
|
export MY_YATA_API_TOKEN=XXXX
|
|
@@ -23,15 +19,14 @@ export MY_YATA_API_TOKEN=XXXX
|
|
|
23
19
|
|
|
24
20
|
You can check token in your organization settings.
|
|
25
21
|
|
|
26
|
-
|
|
27
22
|
### Configuration file
|
|
28
23
|
|
|
29
|
-
Example
|
|
24
|
+
Example `.yata.json` file:
|
|
30
25
|
|
|
31
26
|
```
|
|
32
27
|
{
|
|
33
28
|
"token": "MY_YATA_API_TOKEN",
|
|
34
|
-
"project": "
|
|
29
|
+
"project": "XXX",
|
|
35
30
|
"locales": [
|
|
36
31
|
"en_US", "de_DE"
|
|
37
32
|
],
|
|
@@ -42,38 +37,49 @@ Example `yata.json` file:
|
|
|
42
37
|
}
|
|
43
38
|
```
|
|
44
39
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
- `token` (string, required) - name of ENV variable containing API token
|
|
41
|
+
- `project` (string, required) - ID of the project, you can get it from your organization settings in Yata
|
|
42
|
+
- `locales` (array, required) - locales to generate
|
|
43
|
+
- `format` (string, optional, default: yml) - output file format
|
|
44
|
+
- `root` (boolean, optional, default: false) - if set to `true` locale file
|
|
50
45
|
will contain locale as root element
|
|
51
|
-
|
|
46
|
+
- `outputPath` (string, optional, default: './translations') - path where
|
|
52
47
|
files will be generated
|
|
53
|
-
|
|
48
|
+
- `strip_empty` (boolean, optional, default: false) - if set to `true` parser will omnit empty keys from generation and export only those that have text
|
|
54
49
|
|
|
55
50
|
### Fetching translations
|
|
56
51
|
|
|
57
52
|
```
|
|
58
|
-
$
|
|
53
|
+
$ yata-fetch [options]
|
|
59
54
|
```
|
|
60
55
|
|
|
61
56
|
Options:
|
|
62
57
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
stack from config file
|
|
66
|
-
|
|
58
|
+
- `config` (string, optional, default: yata.json) - path to json config file.
|
|
59
|
+
- `locale` - if you like you can generate only one locale instead whole stack from config file
|
|
67
60
|
|
|
68
61
|
Example:
|
|
69
62
|
|
|
70
63
|
```
|
|
71
|
-
|
|
64
|
+
$ yata-fetch --config .yata.json --locale en_US
|
|
72
65
|
```
|
|
73
66
|
|
|
67
|
+
Hint:
|
|
68
|
+
|
|
69
|
+
It's best to create scripts for generating translations in `package.json` file. For example:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
"scripts": {
|
|
73
|
+
"yata-fetch": "yata-fetch --config .yata.json"
|
|
74
|
+
"yata-fetch:en": "yata-fetch --config .yata.json --locale en_US"
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
and simply call with `npm run yata-fetch`
|
|
79
|
+
|
|
74
80
|
## Problems?
|
|
75
81
|
|
|
76
|
-
|
|
82
|
+
- Open an Issue
|
|
77
83
|
|
|
78
84
|
## Contributing
|
|
79
85
|
|
|
@@ -83,19 +89,15 @@ This project uses `yarn` as a package manager and `gulp` as task runner.
|
|
|
83
89
|
|
|
84
90
|
### Installation
|
|
85
91
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
### Running
|
|
90
|
-
|
|
91
|
-
* `yarn s`
|
|
92
|
+
- `git clone` this repository
|
|
93
|
+
- `npm install`
|
|
92
94
|
|
|
93
95
|
#### Running Tests
|
|
94
96
|
|
|
95
|
-
|
|
97
|
+
- `npm run test`
|
|
96
98
|
|
|
97
99
|
### Building
|
|
98
100
|
|
|
99
|
-
|
|
101
|
+
- `npm run build`
|
|
100
102
|
|
|
101
|
-
Build files are
|
|
103
|
+
Build files are stored in `dist` folder.
|
package/bin/yata-fetch.js
CHANGED
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";function c(t,i){let e;switch(t){case"red":e="\x1B[31m";break;case"green":e="\x1B[32m";break;case"yellow":e="\x1B[33m";break;default:e="\x1B[37m"}return console.log(`${e}%s\x1B[0m`,i)}const y=require("https"),m=require("path"),l=require("fs"),f={config:null,defaultConfigPath:"./yata.json",configPath:"",token:"",project:"",locales:[],format:"yml",root:!1,outputPath:"translations",stripEmpty:!1,apiHost:"",getConfigPath(t){return t?this.configPath=t:this.configPath=this.defaultConfigPath,this.configPath},validateConfig(t,i,e,n,h,s,a){if(t)this.token=t;else throw new Error("No `token` in ENV");if(i)this.project=i;else throw new Error("No `project` in config file");if(!Array.isArray(e)||e.length===0)throw new Error("No `locales` in config file");return this.locales=e,n&&typeof n=="string"&&(this.format=n),h&&typeof h=="boolean"&&(this.root=h),s&&typeof s=="string"&&(this.outputPath=s),a&&typeof a=="boolean"&&(this.stripEmpty=a),!0},normalizeLocale(t){if(!t)return;const i=t.replace("-","_").split("_"),e=[];return e.push(i[0].toLowerCase()),i[1]&&e.push(i[1].toUpperCase()),e.join("_")},downloadTranslation(t){const i=this.normalizeLocale(t);if(!i)throw new Error("No locale passed to download function");l.existsSync(this.outputPath)||l.mkdirSync(this.outputPath);const e=`${i}.${this.format}`,n=m.join(process.cwd(),`${this.outputPath}/${e}`),h=`${this.apiHost}/api/v1/project/${this.project}/${t}/${this.format}?apiToken=${this.token}&root=${this.root}&strip_empty=${this.stripEmpty}`;let s;l.existsSync(n)&&(s=l.readFileSync(n));const a=l.createWriteStream(n);return new Promise((g,u)=>{y.get(h,r=>{const{statusCode:p}=r;if(p!==200)return u(`Request Failed.
|
|
2
|
+
Status Code: ${p}`);r.pipe(a),a.on("finish",()=>{const d=l.readFileSync(n);s&&s.equals(d)?c("yellow",`Generating "${t}" translation. Skipped.`):c("green",`Generating "${t}" translation. Done.`),g(!0)})}).on("error",r=>{r instanceof Error?c("red",r.message):typeof r=="string"&&c("red",r)})})}},o=require("nconf");async function w(){o.argv(),o.env(),o.file({file:f.getConfigPath(o.get("config"))}),f.apiHost=o.get("YATA_API_HOST")||"https://api.yatapp.net";try{if(f.validateConfig(o.get(o.get("token")),o.get("project"),o.get("locales"),o.get("format"),o.get("root"),o.get("outputPath"),o.get("strip_empty")))if(o.get("locale"))await f.downloadTranslation(o.get("locale"));else for(const t of f.locales)await f.downloadTranslation(t)}catch(t){t instanceof Error?c("red",t.message):typeof t=="string"&&c("red",t)}}module.exports=w;
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yata-fetch",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"description": "Adds CLI interface for importing translation files from Yata",
|
|
5
6
|
"license": "MIT",
|
|
6
7
|
"main": "./dist/yata",
|
|
@@ -20,28 +21,29 @@
|
|
|
20
21
|
"yata-fetch": "./bin/yata-fetch.js"
|
|
21
22
|
},
|
|
22
23
|
"scripts": {
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
24
|
+
"build": "vite build",
|
|
25
|
+
"generate": "node bin/yata-fetch.js --config test/fixtures/yata.json",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"coverage": "vitest run --coverage",
|
|
28
|
+
"lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:*\"",
|
|
29
|
+
"lint:eslint": "eslint src --ext .js,.ts,.vue",
|
|
30
|
+
"lint:ts": "tsc --noEmit",
|
|
31
|
+
"lint:fmt": "prettier --check --loglevel=warn --write ."
|
|
28
32
|
},
|
|
29
33
|
"dependencies": {
|
|
30
|
-
"
|
|
31
|
-
"nconf": "^0.11.2"
|
|
34
|
+
"nconf": "0.12.0"
|
|
32
35
|
},
|
|
33
36
|
"devDependencies": {
|
|
34
|
-
"@
|
|
35
|
-
"@
|
|
36
|
-
"@
|
|
37
|
-
"@
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"mock-fs": "^4.13.0"
|
|
37
|
+
"@types/nconf": "0.10.3",
|
|
38
|
+
"@types/node": "18.6.4",
|
|
39
|
+
"@typescript-eslint/eslint-plugin": "5.32.0",
|
|
40
|
+
"@typescript-eslint/parser": "5.32.0",
|
|
41
|
+
"c8": "7.12.0",
|
|
42
|
+
"eslint": "8.21.0",
|
|
43
|
+
"npm-run-all": "4.1.5",
|
|
44
|
+
"prettier": "2.7.1",
|
|
45
|
+
"typescript": "^4.6.4",
|
|
46
|
+
"vite": "^3.0.0",
|
|
47
|
+
"vitest": "0.21.0"
|
|
46
48
|
}
|
|
47
49
|
}
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { IFileOptions } from 'nconf'
|
|
2
|
+
import yata from './yata'
|
|
3
|
+
import log from './log'
|
|
4
|
+
|
|
5
|
+
const nconf = require('nconf')
|
|
6
|
+
|
|
7
|
+
export default async function () {
|
|
8
|
+
// read argv for potential custom config path
|
|
9
|
+
nconf.argv()
|
|
10
|
+
|
|
11
|
+
// read ENV for token
|
|
12
|
+
nconf.env()
|
|
13
|
+
|
|
14
|
+
// load config path
|
|
15
|
+
nconf.file({ file: yata.getConfigPath(nconf.get('config')) } as IFileOptions)
|
|
16
|
+
|
|
17
|
+
// setup API host
|
|
18
|
+
yata.apiHost = nconf.get('YATA_API_HOST') || 'https://api.yatapp.net'
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
if (
|
|
22
|
+
yata.validateConfig(
|
|
23
|
+
nconf.get(nconf.get('token')),
|
|
24
|
+
nconf.get('project'),
|
|
25
|
+
nconf.get('locales'),
|
|
26
|
+
nconf.get('format'),
|
|
27
|
+
nconf.get('root'),
|
|
28
|
+
nconf.get('outputPath'),
|
|
29
|
+
nconf.get('strip_empty')
|
|
30
|
+
)
|
|
31
|
+
) {
|
|
32
|
+
// if passed locale explicit download just one
|
|
33
|
+
if (nconf.get('locale')) {
|
|
34
|
+
await yata.downloadTranslation(nconf.get('locale'))
|
|
35
|
+
} else {
|
|
36
|
+
for (const locale of yata.locales) {
|
|
37
|
+
await yata.downloadTranslation(locale)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
} catch (error) {
|
|
42
|
+
if (error instanceof Error) {
|
|
43
|
+
log('red', error.message)
|
|
44
|
+
} else if (typeof error === 'string') {
|
|
45
|
+
log('red', error)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
package/src/log.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
type Color = 'red' | 'green' | 'yellow'
|
|
2
|
+
|
|
3
|
+
export default function (color: Color, message: string) {
|
|
4
|
+
let code
|
|
5
|
+
|
|
6
|
+
switch (color) {
|
|
7
|
+
case 'red':
|
|
8
|
+
code = '\x1b[31m'
|
|
9
|
+
break
|
|
10
|
+
case 'green':
|
|
11
|
+
code = '\x1b[32m'
|
|
12
|
+
break
|
|
13
|
+
case 'yellow':
|
|
14
|
+
code = '\x1b[33m'
|
|
15
|
+
break
|
|
16
|
+
|
|
17
|
+
default:
|
|
18
|
+
code = '\x1b[37m' // white
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return console.log(`${code}%s\x1b[0m`, message)
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
package/src/yata.ts
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import log from './log'
|
|
2
|
+
|
|
3
|
+
import { IncomingMessage } from 'http'
|
|
4
|
+
const https = require('https')
|
|
5
|
+
const path = require('path')
|
|
6
|
+
const fs = require('fs')
|
|
7
|
+
|
|
8
|
+
type Locale = string
|
|
9
|
+
type Format = 'yml' | 'json'
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
config: null,
|
|
13
|
+
defaultConfigPath: './yata.json',
|
|
14
|
+
configPath: '',
|
|
15
|
+
token: '',
|
|
16
|
+
project: '',
|
|
17
|
+
locales: [] as string[],
|
|
18
|
+
format: 'yml',
|
|
19
|
+
root: false,
|
|
20
|
+
outputPath: 'translations',
|
|
21
|
+
stripEmpty: false,
|
|
22
|
+
apiHost: '',
|
|
23
|
+
|
|
24
|
+
getConfigPath(configPath: string) {
|
|
25
|
+
if (configPath) {
|
|
26
|
+
this.configPath = configPath
|
|
27
|
+
} else {
|
|
28
|
+
this.configPath = this.defaultConfigPath
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return this.configPath
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
validateConfig(
|
|
35
|
+
token?: string,
|
|
36
|
+
project?: string,
|
|
37
|
+
locales?: Locale[],
|
|
38
|
+
format?: Format,
|
|
39
|
+
root?: boolean,
|
|
40
|
+
outputPath?: string,
|
|
41
|
+
stripEmpty?: boolean
|
|
42
|
+
) {
|
|
43
|
+
if (!token) {
|
|
44
|
+
throw new Error('No `token` in ENV')
|
|
45
|
+
} else {
|
|
46
|
+
this.token = token
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!project) {
|
|
50
|
+
throw new Error('No `project` in config file')
|
|
51
|
+
} else {
|
|
52
|
+
this.project = project
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!Array.isArray(locales) || locales.length === 0) {
|
|
56
|
+
throw new Error('No `locales` in config file')
|
|
57
|
+
} else {
|
|
58
|
+
this.locales = locales
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (format && typeof format === 'string') {
|
|
62
|
+
this.format = format
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (root && typeof root === 'boolean') {
|
|
66
|
+
this.root = root
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (outputPath && typeof outputPath === 'string') {
|
|
70
|
+
this.outputPath = outputPath
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (stripEmpty && typeof stripEmpty === 'boolean') {
|
|
74
|
+
this.stripEmpty = stripEmpty
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return true
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
normalizeLocale(locale: Locale) {
|
|
81
|
+
if (!locale) {
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const localeSegments = locale.replace('-', '_').split('_')
|
|
86
|
+
const newLocale = []
|
|
87
|
+
newLocale.push(localeSegments[0].toLowerCase())
|
|
88
|
+
|
|
89
|
+
// two segment locale
|
|
90
|
+
if (localeSegments[1]) {
|
|
91
|
+
newLocale.push(localeSegments[1].toUpperCase())
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return newLocale.join('_')
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
downloadTranslation(locale: Locale) {
|
|
98
|
+
const normalizedLocale = this.normalizeLocale(locale)
|
|
99
|
+
|
|
100
|
+
if (!normalizedLocale) {
|
|
101
|
+
throw new Error('No locale passed to download function')
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// if output folder doesn't exist we create it
|
|
105
|
+
if (!fs.existsSync(this.outputPath)) {
|
|
106
|
+
fs.mkdirSync(this.outputPath)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const fileName = `${normalizedLocale}.${this.format}`
|
|
110
|
+
const filePath = path.join(process.cwd(), `${this.outputPath}/${fileName}`)
|
|
111
|
+
const url = `${this.apiHost}/api/v1/project/${this.project}/${locale}/${this.format}?apiToken=${this.token}&root=${this.root}&strip_empty=${this.stripEmpty}`
|
|
112
|
+
|
|
113
|
+
let bufferFile: Buffer
|
|
114
|
+
|
|
115
|
+
// if file exist we grab it's size
|
|
116
|
+
if (fs.existsSync(filePath)) {
|
|
117
|
+
bufferFile = fs.readFileSync(filePath)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// we start stream
|
|
121
|
+
const file = fs.createWriteStream(filePath)
|
|
122
|
+
|
|
123
|
+
return new Promise((resolve, reject) => {
|
|
124
|
+
https
|
|
125
|
+
.get(url, (response: IncomingMessage) => {
|
|
126
|
+
const { statusCode } = response
|
|
127
|
+
|
|
128
|
+
if (statusCode !== 200) {
|
|
129
|
+
return reject(`Request Failed.\nStatus Code: ${statusCode}`)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
response.pipe(file)
|
|
133
|
+
file.on('finish', () => {
|
|
134
|
+
const newBufferFile = fs.readFileSync(filePath)
|
|
135
|
+
|
|
136
|
+
if (bufferFile && bufferFile.equals(newBufferFile)) {
|
|
137
|
+
log('yellow', `Generating "${locale}" translation. Skipped.`)
|
|
138
|
+
} else {
|
|
139
|
+
log('green', `Generating "${locale}" translation. Done.`)
|
|
140
|
+
}
|
|
141
|
+
resolve(true)
|
|
142
|
+
})
|
|
143
|
+
})
|
|
144
|
+
.on('error', (error: Error) => {
|
|
145
|
+
if (error instanceof Error) {
|
|
146
|
+
log('red', error.message)
|
|
147
|
+
} else if (typeof error === 'string') {
|
|
148
|
+
log('red', error)
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
},
|
|
153
|
+
}
|
package/test/fixtures/yata.json
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"token": "YATA_DEV_TOKEN",
|
|
3
|
-
"project": "
|
|
4
|
-
"locales": [
|
|
5
|
-
"pl_PL", "de_DE"
|
|
6
|
-
],
|
|
3
|
+
"project": "UVV6Rm1yc2JZbS9NcVBUWW96U2RjTldSREFtbDNKQVhHc2JlT0J3T2ZGVT0=",
|
|
4
|
+
"locales": ["pl_PL", "en_US"],
|
|
7
5
|
"format": "yml",
|
|
8
6
|
"root": false,
|
|
9
7
|
"outputPath": "./translations",
|