@dittowords/cli 5.0.0-beta.8 → 5.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/README.md +18 -72
- package/bin/ditto.js +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,30 +1,33 @@
|
|
|
1
|
-
# Ditto CLI
|
|
1
|
+
# Ditto CLI
|
|
2
2
|
|
|
3
|
-
The Ditto CLI enables developers to access the Ditto API directly from the command line.
|
|
3
|
+
The Ditto CLI enables developers to access the Ditto API directly from the command line. You can use the CLI to import Ditto data directly into your own codebase.
|
|
4
|
+
|
|
5
|
+
The CLI is configured to fetch text from the latest version of Ditto by default. However, all legacy features are still fully supported by passing a `--legacy` flag along with the legacy CLI command. See [Legacy Setup](#legacy-setup) for details on using the CLI with older Ditto projects and components.
|
|
4
6
|
|
|
5
7
|
[](https://badge.fury.io/js/@dittowords%2Fcli)
|
|
6
8
|
|
|
7
9
|
## Documentation
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
- [Documentation](https://developer.dittowords.com/cli-reference/authentication)
|
|
12
|
+
- [Changelog](https://developer.dittowords.com/feedback-support/changelog)
|
|
10
13
|
|
|
11
14
|
## Support
|
|
12
15
|
|
|
13
16
|
- [Bug Reports](https://github.com/dittowords/cli/issues/)
|
|
14
17
|
- [Support Chat](https://www.dittowords.com)
|
|
15
|
-
- [What is Ditto?](https://
|
|
18
|
+
- [What is Ditto?](https://developer.dittowords.com/introduction)
|
|
16
19
|
|
|
17
20
|
## Installation
|
|
18
21
|
|
|
19
22
|
```sh
|
|
20
|
-
npm install --save-dev @dittowords/cli
|
|
23
|
+
npm install --save-dev @dittowords/cli
|
|
21
24
|
```
|
|
22
25
|
|
|
23
26
|
It's recommended to install the CLI as a development dependency to ensure your whole team is on the same version.
|
|
24
27
|
|
|
25
28
|
## Authentication
|
|
26
29
|
|
|
27
|
-
The first time you run the CLI, you’ll be asked to provide an API key. You can generate an API key from your [developer integrations settings](https://app.dittowords.com/
|
|
30
|
+
The first time you run the CLI, you’ll be asked to provide an API key. You can generate an API key from your [developer integrations settings](https://app.dittowords.com/developers/api-keys).
|
|
28
31
|
|
|
29
32
|
See the [Authentication](http://developer.dittowords.com/api-reference/authentication) page for more information on API keys.
|
|
30
33
|
|
|
@@ -38,25 +41,28 @@ The default file looks like this:
|
|
|
38
41
|
|
|
39
42
|
```yml
|
|
40
43
|
projects: [],
|
|
44
|
+
components: {
|
|
45
|
+
folders: []
|
|
46
|
+
},
|
|
41
47
|
variants: [],
|
|
42
48
|
outputs:
|
|
43
49
|
- format: json,
|
|
44
50
|
framework: i18next
|
|
45
51
|
```
|
|
46
52
|
|
|
47
|
-
For more information on configuring the CLI, see [this documentation section](https://
|
|
53
|
+
For more information on configuring the CLI, see [this documentation section](https://developer.dittowords.com/cli-reference/configuration).
|
|
48
54
|
|
|
49
55
|
## Usage
|
|
50
56
|
|
|
51
57
|
```bash
|
|
52
|
-
npx @dittowords/cli
|
|
58
|
+
npx @dittowords/cli pull
|
|
53
59
|
```
|
|
54
60
|
|
|
55
61
|
Run the CLI to pull string data from Ditto and write it to disk.
|
|
56
62
|
|
|
57
|
-
String files are written to the
|
|
63
|
+
String files are written to the specified folder in a format that corresponds to your configuration. After integrating these files into development, you can execute the CLI at any time to fetch the latest strings from Ditto and update them in your application.
|
|
58
64
|
|
|
59
|
-
For more information on how files written to disk, see [this documentation section](https://
|
|
65
|
+
For more information on how files are written to disk, see [this documentation section](https://developer.dittowords.com/cli-reference/files).
|
|
60
66
|
|
|
61
67
|
See our demo projects for examples of how to integrate the Ditto CLI in different environments:
|
|
62
68
|
|
|
@@ -64,69 +70,9 @@ See our demo projects for examples of how to integrate the Ditto CLI in differen
|
|
|
64
70
|
- [iOS mobile app](https://github.com/dittowords/ditto-react-demo)
|
|
65
71
|
- [Android mobile app](https://github.com/dittowords/ditto-react-demo)
|
|
66
72
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
v5 of the Ditto CLI points at the new Ditto beta experience by default. To run the CLI compatible with legacy Ditto, append the `--legacy` flag, and the CLI will work as it did in the `4.x` version. All existing legecy commands are depricated, but fully functional at this time.
|
|
70
|
-
|
|
71
|
-
## Documentation
|
|
72
|
-
|
|
73
|
-
The official documentation can be found [here](http://developer.dittowords.com/cli-reference/authentication).
|
|
74
|
-
|
|
75
|
-
## Support
|
|
76
|
-
|
|
77
|
-
- [Bug Reports](https://github.com/dittowords/cli/issues/)
|
|
78
|
-
- [Support Chat](https://www.dittowords.com)
|
|
79
|
-
- [What is Ditto?](https://www.dittowords.com/docs/what-is-ditto)
|
|
73
|
+
## Legacy Setup
|
|
80
74
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
```sh
|
|
84
|
-
npm install --save-dev @dittowords/cli@beta
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
It's recommended to install the CLI as a development dependency to ensure your whole team is on the same version.
|
|
88
|
-
|
|
89
|
-
## Authentication
|
|
90
|
-
|
|
91
|
-
The first time you run the CLI, you’ll be asked to provide an API key. You can generate an API key from your [developer integrations settings](https://app.dittowords.com/account/devtools).
|
|
92
|
-
|
|
93
|
-
See the [Authentication](http://developer.dittowords.com/api-reference/authentication) page for more information on API keys.
|
|
94
|
-
|
|
95
|
-
## Configuration
|
|
96
|
-
|
|
97
|
-
By default, the CLI operates against a `ditto/` folder relative to the current working directory.
|
|
98
|
-
|
|
99
|
-
The first time you run the CLI, a `ditto/` folder will be created if it doesn't already exist. The folder will also be populated with a default `config.yml` file, which is used to control the CLI's behavior.
|
|
100
|
-
|
|
101
|
-
The default file looks like this:
|
|
102
|
-
|
|
103
|
-
```yml
|
|
104
|
-
projects: [],
|
|
105
|
-
variants: [],
|
|
106
|
-
outputs:
|
|
107
|
-
- format: json,
|
|
108
|
-
framework: i18next
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
For more information on configuring the CLI, see [http://developer.dittowords.com/cli-reference/configuration](http://developer.dittowords.com/cli-reference/configuration).
|
|
112
|
-
|
|
113
|
-
## Usage
|
|
114
|
-
|
|
115
|
-
```bash
|
|
116
|
-
npx @dittowords/cli
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
Run the CLI to pull string data from Ditto and write it to disk.
|
|
120
|
-
|
|
121
|
-
String files are written to the `ditto` folder in a format that corresponds to your configuration. After integrating these files into development, you can execute the CLI at any time to fetch the latest strings from Ditto and update them in your application.
|
|
122
|
-
|
|
123
|
-
For more information on how files written to disk, see [http://developer.dittowords.com/cli-reference/files](http://developer.dittowords.com/cli-reference/files).
|
|
124
|
-
|
|
125
|
-
See our demo projects for examples of how to integrate the Ditto CLI in different environments:
|
|
126
|
-
|
|
127
|
-
- [React web app](https://github.com/dittowords/ditto-react-demo)
|
|
128
|
-
- [iOS mobile app](https://github.com/dittowords/ditto-react-demo)
|
|
129
|
-
- [Android mobile app](https://github.com/dittowords/ditto-react-demo)
|
|
75
|
+
Beginning with `v5.0.0`, the Ditto CLI points at the new Ditto experience by default. To run the CLI compatible with legacy Ditto, append the `--legacy` flag to any legacy command, and the CLI will work as it did in the `4.x` version. All existing legacy commands remain fully functional at this time.
|
|
130
76
|
|
|
131
77
|
## Feedback
|
|
132
78
|
|
package/bin/ditto.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
4
|
-
var Jr=Object.create;var se=Object.defineProperty;var Vr=Object.getOwnPropertyDescriptor;var Yr=Object.getOwnPropertyNames;var Br=Object.getPrototypeOf,qr=Object.prototype.hasOwnProperty;var Ze=t=>{throw TypeError(t)};var r=(t,e)=>se(t,"name",{value:e,configurable:!0});var Gr=(t,e,o,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Yr(e))!qr.call(t,s)&&s!==o&&se(t,s,{get:()=>e[s],enumerable:!(n=Vr(e,s))||n.enumerable});return t};var l=(t,e,o)=>(o=t!=null?Jr(Br(t)):{},Gr(e||!t||!t.__esModule?se(o,"default",{value:t,enumerable:!0}):o,t));var He=(t,e,o)=>e.has(t)||Ze("Cannot "+o);var D=(t,e,o)=>(He(t,e,"read from private field"),o?o.call(t):e.get(t)),V=(t,e,o)=>e.has(t)?Ze("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,o),R=(t,e,o,n)=>(He(t,e,"write to private field"),n?n.call(t,o):e.set(t,o),o);var Or=l(require("@sentry/node"));var it="5.0.0
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="f865a369-e1da-5321-ba25-1c81e1859ad2")}catch(e){}}();
|
|
4
|
+
var Jr=Object.create;var se=Object.defineProperty;var Vr=Object.getOwnPropertyDescriptor;var Yr=Object.getOwnPropertyNames;var Br=Object.getPrototypeOf,qr=Object.prototype.hasOwnProperty;var Ze=t=>{throw TypeError(t)};var r=(t,e)=>se(t,"name",{value:e,configurable:!0});var Gr=(t,e,o,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Yr(e))!qr.call(t,s)&&s!==o&&se(t,s,{get:()=>e[s],enumerable:!(n=Vr(e,s))||n.enumerable});return t};var l=(t,e,o)=>(o=t!=null?Jr(Br(t)):{},Gr(e||!t||!t.__esModule?se(o,"default",{value:t,enumerable:!0}):o,t));var He=(t,e,o)=>e.has(t)||Ze("Cannot "+o);var D=(t,e,o)=>(He(t,e,"read from private field"),o?o.call(t):e.get(t)),V=(t,e,o)=>e.has(t)?Ze("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,o),R=(t,e,o,n)=>(He(t,e,"write to private field"),n?n.call(t,o):e.set(t,o),o);var Or=l(require("@sentry/node"));var it="5.0.0";var U=require("commander");var ho=l(require("boxen")),Ut=l(require("chalk"));var fo=l(require("ora"));var so=l(require("axios"));var Y=l(require("fs")),to=l(require("path")),eo=l(require("url")),ct=l(require("js-yaml")),oo=l(require("@sentry/node"));var Xe=require("os"),at=l(require("path")),u=new class{get API_HOST(){return process.env.DITTO_API_HOST||"https://api.dittowords.com"}get CONFIG_FILE(){return process.env.DITTO_CONFIG_FILE||at.default.join((0,Xe.homedir)(),".config","ditto")}get PROJECT_CONFIG_FILE(){return at.default.normalize(at.default.join("ditto","config.yml"))}get TEXT_DIR(){return process.env.DITTO_TEXT_DIR||"ditto"}get TEXT_FILE(){return at.default.normalize(at.default.join(this.TEXT_DIR,"text.json"))}};function Qe(t){if(typeof t!="object")return{};let e={};for(let o in t){let n=o,s=t[n];e[n]=typeof s=="object"||Array.isArray(s)?JSON.stringify(s):s}return e}r(Qe,"createSentryContext");var zr={sources:{components:!0},variants:!0,format:"flat"},ro=ct.default.dump(zr);function vt(t,e){let o=to.default.dirname(t);Y.default.existsSync(o)||Y.default.mkdirSync(o),Y.default.existsSync(t)||Y.default.writeFileSync(t,e||"","utf-8")}r(vt,"createFileIfMissing");function Wr(t){return typeof t=="object"}r(Wr,"jsonIsConfigYAML");function Zr(t){return!!t&&typeof t=="object"&&Object.values(t).every(e=>e.every&&e.every(o=>typeof o=="object"&&Object.keys(o).includes("token")))}r(Zr,"jsonIsGlobalYAML");function ie(t=u.PROJECT_CONFIG_FILE,e={}){vt(t,ro);let o=Y.default.readFileSync(t,"utf8"),n=ct.default.load(o);return Wr(n)?n:e}r(ie,"readProjectConfigData");function jt(t=u.CONFIG_FILE,e={}){vt(t);let o=Y.default.readFileSync(t,"utf8"),n=ct.default.load(o);return Zr(n)?n:e}r(jt,"readGlobalConfigData");function Hr(t,e){vt(t,ro);let o=ie(t),n={...o,...e,sources:{...o.sources,...e.sources}},s=ct.default.dump(n);Y.default.writeFileSync(t,s,"utf8")}r(Hr,"writeProjectConfigData");function ae(t,e){vt(t);let o=jt(t),n=ct.default.dump({...o,...e});Y.default.writeFileSync(t,n,"utf8")}r(ae,"writeGlobalConfigData");function Bt(t){return t.includes("://")?eo.default.parse(t).hostname||"":t}r(Bt,"justTheHost");function Xr(t,e){let o=jt(t),n=Bt(e);o[n]=[],o[n][0]={token:""},ae(t,o)}r(Xr,"deleteToken");function Qr(t,e,o){let n=jt(t),s=Bt(e);n[s]=[],n[s][0]={token:o},ae(t,n)}r(Qr,"saveToken");function no(){return process.env.DITTO_API_KEY}r(no,"getTokenFromEnv");function Kr(t,e){let o=no();if(o)return o;let s=jt(t)[Bt(e)];if(!s)return;let{length:i}=s;return s[i-1].token}r(Kr,"getToken");var Ke=/-(\d+$)/;function tn(t,e){let o=e;if(t.has(o))for(;t.has(o);){let[n,s]=o.match(Ke)||[];s&&!isNaN(parseInt(s))?o=`${o.replace(Ke,"")}-${parseInt(s)+1}`:o=`${o}-1`}return o}r(tn,"dedupeProjectName");function en(t){let{sources:e,variants:o,format:n,status:s,richText:i,iosLocales:a,projects:c,components:m,disableJsDriver:g}=ie(t),f=e?.projects||[],d=new Set,S=[],x=!1;(f||[]).forEach(k=>{if(k.id&&k.name){if(k.id==="ditto_component_library"){x=!0;return}k.fileName=tn(d,k.name),d.add(k.fileName),S.push(k)}});let w=!!e?.components,_=typeof e?.components=="object"?e.components.root:void 0,P=typeof e?.components=="object"?e.components.folders:void 0,I={hasSourceData:!!S.length||w,validProjects:S,shouldFetchComponentLibrary:w,variants:o||!1,format:n,status:s,richText:i,hasTopLevelProjectsField:!!c,hasTopLevelComponentsField:!!m,hasComponentLibraryInProjects:x,componentRoot:_,componentFolders:P,localeByVariantApiId:a?a.reduce((k,nt)=>({...k,...nt}),{}):void 0,disableJsDriver:g};return oo.setContext("config",Qe(I)),I}r(en,"parseSourceInformation");var C={createFileIfMissing:vt,readProjectConfigData:ie,readGlobalConfigData:jt,writeGlobalConfigData:ae,writeProjectConfigData:Hr,justTheHost:Bt,saveToken:Qr,deleteToken:Xr,getToken:Kr,getTokenFromEnv:no,parseSourceInformation:en};function j(t){return so.default.create({baseURL:u.API_HOST,headers:{Authorization:`token ${t||C.getToken(u.CONFIG_FILE,u.API_HOST)}`,"x-ditto-cli":!0}})}r(j,"createApiClient");var q=l(require("chalk"));var on=r(t=>q.default.magenta(t),"errorText"),rn=r(t=>q.default.yellow(t),"warnText"),nn=r(t=>q.default.blueBright(t),"info"),sn=r(t=>q.default.green(t),"success"),an=r(t=>q.default.blueBright.underline(t),"url"),cn=r(t=>q.default.grey(t),"subtle"),pn=r(t=>q.default.white(t),"write"),ln=r(()=>console.log(`
|
|
5
5
|
`),"nl"),p={errorText:on,warnText:rn,info:nn,success:sn,url:an,subtle:cn,write:pn,nl:ln};var ao=l(require("fs")),co=l(require("@sentry/node")),po=l(require("chalk")),lo=require("enquirer");var io=l(require("@sentry/node"));async function b(t,e=2){t&&console.log(`
|
|
6
6
|
${t}
|
|
7
7
|
`),await io.flush(),process.exit(e)}r(b,"quit");var mo=require("axios");var ce=r((t,e=u.API_HOST)=>{if(C.getTokenFromEnv())return!1;let o=t||u.CONFIG_FILE;if(!ao.default.existsSync(o))return!0;let n=C.readGlobalConfigData(o);return!n[C.justTheHost(e)]||n[C.justTheHost(e)][0].token===""},"needsToken");async function mn(t){let e=j(t),o="/token-check",n;try{n=await e.get(o)}catch(s){if(!(s instanceof mo.AxiosError))return{success:!1,output:[p.warnText("Sorry! We're having trouble reaching the Ditto API.")]};if(s.code==="ENOTFOUND")return{success:!1,output:[p.errorText(`Can't connect to API: ${p.url(u.API_HOST)}`)]};if(s.response?.status===401||s.response?.status===404)return{success:!1,output:[p.errorText("This API key isn't valid. Please try another.")]}}return typeof n=="string"?{success:!1,output:[n]}:n?.status===200?{success:!0}:{success:!1,output:[p.errorText("This API key isn't valid. Please try another.")]}}r(mn,"verifyTokenUsingTokenCheck");async function un(t){let e=await mn(t);return e.success?!0:e.output.join(`
|
|
@@ -124,4 +124,4 @@ Error ID: ${T.info(a)}`;return await xt(T.errorText(i)+c,s)}},"executeCommand"),
|
|
|
124
124
|
Ditto CLI is running in legacy mode. This mode is deprecated and will be removed in a future release.
|
|
125
125
|
`)),Ho()):Fr()},"main");Gs();
|
|
126
126
|
|
|
127
|
-
//# debugId=
|
|
127
|
+
//# debugId=f865a369-e1da-5321-ba25-1c81e1859ad2
|