@dittowords/cli 4.0.0-alpha.0 → 4.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 +125 -36
- package/bin/config.js +8 -6
- package/bin/config.js.map +1 -1
- package/bin/ditto.js +1 -1
- package/bin/init/project.js +3 -3
- package/bin/init/project.js.map +1 -1
- package/bin/pull.js +127 -57
- package/bin/pull.js.map +1 -1
- package/bin/types.js +2 -2
- package/bin/types.js.map +1 -1
- package/bin/utils/createSentryContext.js +2 -2
- package/bin/utils/createSentryContext.js.map +1 -1
- package/bin/utils/generateJsDriver.js +29 -5
- package/bin/utils/generateJsDriver.js.map +1 -1
- package/lib/config.ts +19 -6
- package/lib/init/project.ts +1 -1
- package/lib/pull.ts +171 -53
- package/lib/types.ts +24 -7
- package/lib/utils/generateJsDriver.ts +40 -6
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ npm install --save-dev @dittowords/cli
|
|
|
14
14
|
npm install --global @dittowords/cli
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
The installed binary is named `ditto-cli`. You can execute it directly in `node_modules/.bin/ditto-cli` or using [npx](https://www.npmjs.com/package/npx)
|
|
17
|
+
The installed binary is named `ditto-cli`. You can execute it directly in `node_modules/.bin/ditto-cli` or using [npx](https://www.npmjs.com/package/npx) like `npx @dittowords/cli`.
|
|
18
18
|
|
|
19
19
|
The first time you run the CLI, you'll be asked to provide an API key (found at [https://app.dittowords.com/account/user](https://app.dittowords.com/account/user) under **API Keys**):
|
|
20
20
|
|
|
@@ -35,7 +35,7 @@ Thanks for authenticating.
|
|
|
35
35
|
We'll save the key to: /Users/{username}/.config/ditto
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
Once you've successfully authenticated, you'll be asked to choose a source (a project or your component library) to pull data
|
|
38
|
+
Once you've successfully authenticated, you'll be asked to choose a source (a project or your component library) to pull data from:
|
|
39
39
|
|
|
40
40
|
```
|
|
41
41
|
Looks like there are no Ditto sources selected for your current directory: /Users/ditto
|
|
@@ -46,15 +46,15 @@ Looks like there are no Ditto sources selected for your current directory: /User
|
|
|
46
46
|
...
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
After selecting a source, a configuration file will automatically be created at the path `./ditto/config.yml` relative to your current working directory. The CLI will attempt to read from this file every time a command is executed. See the [config.yml documentation](#files)
|
|
49
|
+
After selecting a source, a configuration file will automatically be created at the path `./ditto/config.yml` relative to your current working directory. The CLI will attempt to read from this file every time a command is executed. See the [config.yml documentation](#files) for a full reference of how the CLI can be configured.
|
|
50
50
|
|
|
51
|
-
Once you've successfully authenticated and a config file has been created, you’re ready to start fetching copy! If you need to use the CLI with multiple configurations, simply
|
|
51
|
+
Once you've successfully authenticated and a config file has been created, you’re ready to start fetching copy! If you need to use the CLI with multiple configurations, simply initialize it in multiple directories.
|
|
52
52
|
|
|
53
53
|
## API Keys
|
|
54
54
|
|
|
55
55
|
The CLI will not prompt for an API key if a value is provided in the environment variable `DITTO_API_KEY`.
|
|
56
56
|
|
|
57
|
-
If the `DITTO_API_KEY` environment variable is not set, the CLI will
|
|
57
|
+
If the `DITTO_API_KEY` environment variable is not set, the CLI will look for an API token in [your authentication file](#authentication). If this file does not exist or does not contain a valid API key, the CLI will prompt for one.
|
|
58
58
|
|
|
59
59
|
We don't recommend editing the authentication file by hand; if you need to remove a saved API key or swap one key with another, it's better to fully delete the file and then re-run the CLI.
|
|
60
60
|
|
|
@@ -66,7 +66,7 @@ We don't recommend editing the authentication file by hand; if you need to remov
|
|
|
66
66
|
|
|
67
67
|
**Action:** Pulls data from Ditto according to configured sources.
|
|
68
68
|
|
|
69
|
-
Generate files your local `ditto/` folder
|
|
69
|
+
Generate files your local `ditto/` folder. File extension is determined by the `format` property specified in `config.yml`.
|
|
70
70
|
|
|
71
71
|
If no format is specified, the `flat` format will be used by default. Each time text is pulled from Ditto, the existing files in the `ditto/` directory are removed before new files are created in their place.
|
|
72
72
|
|
|
@@ -88,7 +88,9 @@ For more details on files generated by this command, see [Output Files](#output-
|
|
|
88
88
|
|
|
89
89
|
**Usage:** `ditto-cli component-folders`
|
|
90
90
|
|
|
91
|
-
**Action:** List component folders in your workspace.
|
|
91
|
+
**Action:** List component folders in your workspace.
|
|
92
|
+
|
|
93
|
+
More information about component folders in Ditto can be found [here](https://www.dittowords.com/docs/component-folders).
|
|
92
94
|
|
|
93
95
|
### Import components
|
|
94
96
|
|
|
@@ -129,7 +131,7 @@ variants: true
|
|
|
129
131
|
|
|
130
132
|
A list of places the CLI should pull text data from. For the CLI to function, at least one source type (`projects` or `components`) is required.
|
|
131
133
|
|
|
132
|
-
|
|
134
|
+
##### `sources.projects`
|
|
133
135
|
|
|
134
136
|
A list of projects to pull text from.
|
|
135
137
|
|
|
@@ -144,28 +146,79 @@ sources:
|
|
|
144
146
|
|
|
145
147
|
The `name` property is used for display purposes when referencing a project in the CLI, but does not have to be an exact match with the project name in Ditto.
|
|
146
148
|
|
|
147
|
-
|
|
149
|
+
An `exclude_components` property can be added on a per-project basis to indicate that text items should only be pulled which are not associated with a component:
|
|
150
|
+
|
|
151
|
+
```yml
|
|
152
|
+
sources:
|
|
153
|
+
projects:
|
|
154
|
+
- id: 61b8d26105f8f400e97fdd14
|
|
155
|
+
name: Landing Page Copy
|
|
156
|
+
exclude_components: true
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
##### `sources.components`
|
|
160
|
+
|
|
161
|
+
A boolean or configuration object indicating how component data should be pulled from your component library.
|
|
162
|
+
|
|
163
|
+
The simplest configuration is a boolean, which indicates that all components in your component library should be fetched:
|
|
164
|
+
|
|
165
|
+
```yml
|
|
166
|
+
sources:
|
|
167
|
+
components: true
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
You can also pass an object that supports two complementary properties: `root` and `folders`.
|
|
171
|
+
|
|
172
|
+
- `root` controls behavior for components that are NOT in folders (i.e. that are at the _root_ of the component library)
|
|
173
|
+
- `folders` controls behavior for components that are ARE in folders
|
|
148
174
|
|
|
149
|
-
|
|
175
|
+
If `root` is `true` and `folders` is unspecified, **only components not in folders** will be fetched:
|
|
150
176
|
|
|
151
177
|
```yml
|
|
152
178
|
sources:
|
|
153
179
|
components:
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
#
|
|
157
|
-
# if set to true, enables pulling data from the component
|
|
158
|
-
# library. if set to false, CLI behaves as if `sources.components`
|
|
159
|
-
# is not defined
|
|
160
|
-
enabled: true
|
|
180
|
+
root: true
|
|
181
|
+
```
|
|
161
182
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
183
|
+
If `root` is `false` and `folders` is unspecified, **only components in any folder** will be fetched:
|
|
184
|
+
|
|
185
|
+
```yml
|
|
186
|
+
sources:
|
|
187
|
+
components:
|
|
188
|
+
root: false
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
If `root` is unspecified and `folders` contains a list of component folders, **only components in the specified folders** will be fetched:
|
|
192
|
+
|
|
193
|
+
```yml
|
|
194
|
+
sources:
|
|
195
|
+
components:
|
|
166
196
|
folders:
|
|
167
|
-
- id:
|
|
168
|
-
name:
|
|
197
|
+
- id: folder-api-id-1
|
|
198
|
+
name: Folder 1
|
|
199
|
+
- id: folder-api-id-2
|
|
200
|
+
name: Folder 2
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
If `root` is `true` and `folders` contains a list of component folders, **non-folder components and components in the specified folders** will be fetched:
|
|
204
|
+
|
|
205
|
+
```yml
|
|
206
|
+
sources:
|
|
207
|
+
components:
|
|
208
|
+
folders:
|
|
209
|
+
- id: folder-api-id-1
|
|
210
|
+
name: Folder 1
|
|
211
|
+
- id: folder-api-id-2
|
|
212
|
+
name: Folder 2
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
`root` can also be specified as a configuration object with a `status` property to indicate that non-folder components should be fetched that have the indicated status:
|
|
216
|
+
|
|
217
|
+
```yml
|
|
218
|
+
sources:
|
|
219
|
+
components:
|
|
220
|
+
root:
|
|
221
|
+
status: WIP
|
|
169
222
|
```
|
|
170
223
|
|
|
171
224
|
#### Variants
|
|
@@ -178,7 +231,7 @@ Defaults to `false` if not specified.
|
|
|
178
231
|
variants: true
|
|
179
232
|
```
|
|
180
233
|
|
|
181
|
-
|
|
234
|
+
#### Format
|
|
182
235
|
|
|
183
236
|
The format that text data should be generated in. Accepted values:
|
|
184
237
|
|
|
@@ -202,26 +255,56 @@ format:
|
|
|
202
255
|
- ios-stringsdict
|
|
203
256
|
```
|
|
204
257
|
|
|
258
|
+
You should not specify multiple JSON formats in the same configuration, as they will overwrite one another when writing to disk.
|
|
259
|
+
|
|
205
260
|
#### Status
|
|
206
261
|
|
|
207
|
-
If
|
|
262
|
+
If specified, only source data with the indicated status will be fetched. Accepted values:
|
|
208
263
|
|
|
209
264
|
- `NONE`
|
|
210
265
|
- `WIP`
|
|
211
266
|
- `REVIEW`
|
|
212
267
|
- `FINAL`
|
|
213
268
|
|
|
269
|
+
If `status` is specified at the top level of the configuration, it will apply to all sources:
|
|
270
|
+
|
|
214
271
|
```yml
|
|
215
272
|
status: FINAL
|
|
273
|
+
sources:
|
|
274
|
+
components: true
|
|
275
|
+
projects:
|
|
276
|
+
- id: project-1
|
|
277
|
+
name: Project 1
|
|
216
278
|
```
|
|
217
279
|
|
|
218
|
-
|
|
280
|
+
`status` can also be specified at the level of individual sources:
|
|
219
281
|
|
|
220
|
-
|
|
282
|
+
```yml
|
|
283
|
+
sources:
|
|
284
|
+
components:
|
|
285
|
+
root:
|
|
286
|
+
status: REVIEW
|
|
287
|
+
folders:
|
|
288
|
+
- id: folder-api-id-1
|
|
289
|
+
name: Folder 1
|
|
290
|
+
status: NONE
|
|
291
|
+
projects:
|
|
292
|
+
- id: project-1
|
|
293
|
+
name: Project 1
|
|
294
|
+
status: WIP
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
If both are specified, a source-level `status` overrides a top-level `status`.
|
|
298
|
+
|
|
299
|
+
More information about Ditto statuses can be found [here](https://www.dittowords.com/docs/tips-for-collaborating).
|
|
221
300
|
|
|
222
301
|
#### Rich Text
|
|
223
302
|
|
|
224
|
-
If defined
|
|
303
|
+
If defined with the `flat` format, output values will be HTML strings (rich text) for each piece of source data.
|
|
304
|
+
|
|
305
|
+
If defined with the `structured` format, output data will include a `rich_text` property that is an HTML string (rich text) for each piece of source data.
|
|
306
|
+
|
|
307
|
+
You can read more about Ditto's rich text feature [here](https://www.dittowords.com/docs/rich-text).
|
|
225
308
|
|
|
226
309
|
```yml
|
|
227
310
|
richText: true
|
|
@@ -232,17 +315,21 @@ richText: true
|
|
|
232
315
|
```yml
|
|
233
316
|
sources:
|
|
234
317
|
components:
|
|
235
|
-
|
|
318
|
+
root: true
|
|
236
319
|
folders:
|
|
237
320
|
- id: 61b8d26105f8f400e97fdd14
|
|
238
321
|
name: Onboarding
|
|
322
|
+
- id: 61b8d26105f8f400e97fdd15
|
|
323
|
+
name: Onboarding 2
|
|
324
|
+
status: WIP
|
|
239
325
|
projects:
|
|
240
326
|
- name: Landing Page Copy
|
|
241
327
|
id: 61b8d26105f8f400e97fdd14
|
|
242
328
|
- name: User Settings
|
|
243
329
|
id: 606cb89ac55041013d552f8b
|
|
330
|
+
status: WIP
|
|
244
331
|
variants: true
|
|
245
|
-
format:
|
|
332
|
+
format: structured
|
|
246
333
|
status: FINAL
|
|
247
334
|
richText: false
|
|
248
335
|
```
|
|
@@ -274,19 +361,21 @@ All files created will adhere to the following template:
|
|
|
274
361
|
{source_name}__{variant_name}.{extension}
|
|
275
362
|
```
|
|
276
363
|
|
|
277
|
-
- `source_name`: the name of
|
|
278
|
-
-
|
|
279
|
-
-
|
|
364
|
+
- `source_name`: the name of the source a given file holds data for
|
|
365
|
+
- for projects, this is `{project-name}`
|
|
366
|
+
- for components, this is `components__{folder_name}`
|
|
367
|
+
- `variant_name`: the API ID of a variant or `base` for files generated for non-variant text
|
|
368
|
+
- `extension`: the file extension that corresponds to the configured format(s)
|
|
280
369
|
|
|
281
|
-
To
|
|
370
|
+
To keep cross-platform behavior consistent, file names will be fully lowercase, have whitespace replaced with hyphens, and have non-word characters (with the exception of `-` and `_`) removed.
|
|
282
371
|
|
|
283
372
|
If the configured format(s) result(s) in JSON files being generated, an `index.js` "driver file" is also created to simplify the process of integrating Ditto into web apps:
|
|
284
373
|
|
|
285
374
|
```js
|
|
286
375
|
module.exports = {
|
|
287
376
|
ditto_component_library: {
|
|
288
|
-
base: require("./
|
|
289
|
-
spanish: require("./
|
|
377
|
+
base: require("./components__root__base.json"),
|
|
378
|
+
spanish: require("./components__root__spanish.json"),
|
|
290
379
|
},
|
|
291
380
|
project_xxx: {
|
|
292
381
|
base: require("./example-project__base.json"),
|
package/bin/config.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
!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]="
|
|
2
|
+
!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]="3f451b9b-6016-532a-b399-58b8b273e73c")}catch(e){}}();
|
|
3
3
|
|
|
4
4
|
var __create = Object.create;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
@@ -61,7 +61,7 @@ var import_consts = __toESM(require("./consts"));
|
|
|
61
61
|
var import_createSentryContext = require("./utils/createSentryContext");
|
|
62
62
|
const DEFAULT_CONFIG_JSON = {
|
|
63
63
|
sources: {
|
|
64
|
-
components:
|
|
64
|
+
components: true
|
|
65
65
|
},
|
|
66
66
|
variants: true,
|
|
67
67
|
format: "flat"
|
|
@@ -168,7 +168,6 @@ function dedupeProjectName(projectNames, projectName) {
|
|
|
168
168
|
return dedupedName;
|
|
169
169
|
}
|
|
170
170
|
function parseSourceInformation(file) {
|
|
171
|
-
var _a, _b;
|
|
172
171
|
const {
|
|
173
172
|
sources,
|
|
174
173
|
variants,
|
|
@@ -195,7 +194,9 @@ function parseSourceInformation(file) {
|
|
|
195
194
|
projectNames.add(project.fileName);
|
|
196
195
|
validProjects.push(project);
|
|
197
196
|
});
|
|
198
|
-
const shouldFetchComponentLibrary = Boolean(
|
|
197
|
+
const shouldFetchComponentLibrary = Boolean(sources == null ? void 0 : sources.components);
|
|
198
|
+
const componentRoot = typeof (sources == null ? void 0 : sources.components) === "object" ? sources.components.root : void 0;
|
|
199
|
+
const componentFolders = typeof (sources == null ? void 0 : sources.components) === "object" ? sources.components.folders : void 0;
|
|
199
200
|
const hasSourceData = !!validProjects.length || shouldFetchComponentLibrary;
|
|
200
201
|
const result = {
|
|
201
202
|
hasSourceData,
|
|
@@ -208,7 +209,8 @@ function parseSourceInformation(file) {
|
|
|
208
209
|
hasTopLevelProjectsField: !!projectsRoot,
|
|
209
210
|
hasTopLevelComponentsField: !!componentsRoot,
|
|
210
211
|
hasComponentLibraryInProjects,
|
|
211
|
-
|
|
212
|
+
componentRoot,
|
|
213
|
+
componentFolders
|
|
212
214
|
};
|
|
213
215
|
Sentry.setContext("config", (0, import_createSentryContext.createSentryContext)(result));
|
|
214
216
|
return result;
|
|
@@ -233,4 +235,4 @@ var config_default = {
|
|
|
233
235
|
});
|
|
234
236
|
//# sourceMappingURL=config.js.map
|
|
235
237
|
|
|
236
|
-
//# debugId=
|
|
238
|
+
//# debugId=3f451b9b-6016-532a-b399-58b8b273e73c
|
package/bin/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/config.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport url from \"url\";\nimport yaml from \"js-yaml\";\nimport * as Sentry from \"@sentry/node\";\n\nimport consts from \"./consts\";\nimport { Project, ConfigYAML } from \"./types\";\nimport { createSentryContext } from \"./utils/createSentryContext\";\n\nexport const DEFAULT_CONFIG_JSON: ConfigYAML = {\n sources: {\n components: { enabled: true },\n },\n variants: true,\n format: \"flat\",\n};\n\nexport const DEFAULT_CONFIG = yaml.dump(DEFAULT_CONFIG_JSON);\n\nfunction createFileIfMissing(filename: string, defaultContents?: any) {\n const dir = path.dirname(filename);\n\n // create the directory if it doesn't already exist\n if (!fs.existsSync(dir)) fs.mkdirSync(dir);\n\n // create the file if it doesn't already exist\n if (!fs.existsSync(filename)) {\n // create the file, writing the `defaultContents` if provided\n fs.writeFileSync(filename, defaultContents || \"\", \"utf-8\");\n }\n}\n\nfunction jsonIsConfigYAML(json: unknown): json is ConfigYAML {\n return typeof json === \"object\";\n}\n\nfunction jsonIsGlobalYAML(\n json: unknown\n): json is Record<string, { token: string }[]> {\n return (\n !!json &&\n typeof json === \"object\" &&\n Object.values(json).every(\n (arr) =>\n (arr as any).every &&\n arr.every(\n (val: any) =>\n typeof val === \"object\" && Object.keys(val).includes(\"token\")\n )\n )\n );\n}\n\n/**\n * Read data from a project config file\n * @param {string} file defaults to `PROJECT_CONFIG_FILE` defined in `constants.js`\n * @param {*} defaultData defaults to `{}`\n * @returns { ConfigYAML }\n */\nfunction readProjectConfigData(\n file = consts.PROJECT_CONFIG_FILE,\n defaultData = {}\n): ConfigYAML {\n createFileIfMissing(file, DEFAULT_CONFIG);\n const fileContents = fs.readFileSync(file, \"utf8\");\n const yamlData = yaml.load(fileContents);\n if (jsonIsConfigYAML(yamlData)) {\n return yamlData;\n }\n return defaultData;\n}\n\n/**\n * Read data from a global config file\n * @param {string} file defaults to `CONFIG_FILE` defined in `constants.js`\n * @param {*} defaultData defaults to `{}`\n * @returns { Record<string, { token: string }[]> }\n */\nfunction readGlobalConfigData(\n file = consts.CONFIG_FILE,\n defaultData = {}\n): Record<string, { token: string }[]> {\n createFileIfMissing(file);\n const fileContents = fs.readFileSync(file, \"utf8\");\n const yamlData = yaml.load(fileContents);\n if (jsonIsGlobalYAML(yamlData)) {\n return yamlData;\n }\n return defaultData;\n}\n\nfunction writeProjectConfigData(file: string, data: Partial<ConfigYAML>) {\n createFileIfMissing(file, DEFAULT_CONFIG);\n const existingData = readProjectConfigData(file);\n\n const configData: ConfigYAML = {\n ...existingData,\n ...data,\n sources: {\n ...existingData.sources,\n ...data.sources,\n },\n };\n\n const yamlStr = yaml.dump(configData);\n fs.writeFileSync(file, yamlStr, \"utf8\");\n}\n\nfunction writeGlobalConfigData(file: string, data: object) {\n createFileIfMissing(file);\n const existingData = readGlobalConfigData(file);\n const yamlStr = yaml.dump({ ...existingData, ...data });\n fs.writeFileSync(file, yamlStr, \"utf8\");\n}\n\nfunction justTheHost(host: string) {\n if (!host.includes(\"://\")) return host;\n return url.parse(host).hostname || \"\";\n}\n\nfunction deleteToken(file: string, host: string) {\n const data = readGlobalConfigData(file);\n const hostParsed = justTheHost(host);\n data[hostParsed] = [];\n data[hostParsed][0] = { token: \"\" };\n writeGlobalConfigData(file, data);\n}\n\nfunction saveToken(file: string, host: string, token: string) {\n const data = readGlobalConfigData(file);\n const hostParsed = justTheHost(host);\n data[hostParsed] = []; // only allow one token per host\n data[hostParsed][0] = { token };\n writeGlobalConfigData(file, data);\n}\n\nfunction getTokenFromEnv() {\n return process.env.DITTO_API_KEY;\n}\n\n/**\n *\n * @param {string} file\n * @param {string} host\n * @returns {Token}\n */\nfunction getToken(file: string, host: string) {\n const tokenFromEnv = getTokenFromEnv();\n if (tokenFromEnv) {\n return tokenFromEnv;\n }\n\n const data = readGlobalConfigData(file);\n const hostEntry = data[justTheHost(host)];\n if (!hostEntry) return undefined;\n const { length } = hostEntry;\n\n return hostEntry[length - 1].token;\n}\n\nconst IS_DUPLICATE = /-(\\d+$)/;\n\nfunction dedupeProjectName(projectNames: Set<string>, projectName: string) {\n let dedupedName = projectName;\n\n if (projectNames.has(dedupedName)) {\n while (projectNames.has(dedupedName)) {\n const [_, numberStr] = dedupedName.match(IS_DUPLICATE) || [];\n if (numberStr && !isNaN(parseInt(numberStr))) {\n dedupedName = `${dedupedName.replace(IS_DUPLICATE, \"\")}-${\n parseInt(numberStr) + 1\n }`;\n } else {\n dedupedName = `${dedupedName}-1`;\n }\n }\n }\n\n return dedupedName;\n}\n\n/**\n * Reads from the config file, filters out\n * invalid projects, dedupes those remaining, and returns:\n * - whether or not the data required to `pull` is present\n * - whether or not the component library should be fetched\n * - an array of valid, deduped projects\n * - the `variants` and `format` config options\n */\nfunction parseSourceInformation(file?: string) {\n const {\n sources,\n variants,\n format,\n status,\n richText,\n projects: projectsRoot,\n components: componentsRoot,\n } = readProjectConfigData(file);\n\n const projects = sources?.projects || [];\n\n const projectNames = new Set<string>();\n const validProjects: Project[] = [];\n let hasComponentLibraryInProjects = false;\n\n (projects || []).forEach((project) => {\n const isValid = project.id && project.name;\n if (!isValid) {\n return;\n }\n\n if (project.id === \"ditto_component_library\") {\n hasComponentLibraryInProjects = true;\n return;\n }\n\n project.fileName = dedupeProjectName(projectNames, project.name);\n projectNames.add(project.fileName);\n\n validProjects.push(project);\n });\n\n const shouldFetchComponentLibrary = Boolean(sources?.components?.enabled);\n\n const hasSourceData = !!validProjects.length || shouldFetchComponentLibrary;\n\n const result = {\n hasSourceData,\n validProjects,\n shouldFetchComponentLibrary,\n variants: variants || false,\n format,\n status,\n richText,\n hasTopLevelProjectsField: !!projectsRoot,\n hasTopLevelComponentsField: !!componentsRoot,\n hasComponentLibraryInProjects,\n componentFolders: sources?.components?.folders || null,\n };\n\n Sentry.setContext(\"config\", createSentryContext(result));\n\n return result;\n}\n\nexport default {\n createFileIfMissing,\n readProjectConfigData,\n readGlobalConfigData,\n writeGlobalConfigData,\n writeProjectConfigData,\n justTheHost,\n saveToken,\n deleteToken,\n getToken,\n getTokenFromEnv,\n parseSourceInformation,\n};\n"],"names":["yaml","path","fs","consts","url"],"mappings":"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","debug_id":"ee8aabef-5bac-5c7b-a33a-2a40689fc6dc"}
|
|
1
|
+
{"version":3,"sources":["../lib/config.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport url from \"url\";\nimport yaml from \"js-yaml\";\nimport * as Sentry from \"@sentry/node\";\n\nimport consts from \"./consts\";\nimport { createSentryContext } from \"./utils/createSentryContext\";\nimport { Project, ConfigYAML, SourceInformation } from \"./types\";\n\nexport const DEFAULT_CONFIG_JSON: ConfigYAML = {\n sources: {\n components: true,\n },\n variants: true,\n format: \"flat\",\n};\n\nexport const DEFAULT_CONFIG = yaml.dump(DEFAULT_CONFIG_JSON);\n\nfunction createFileIfMissing(filename: string, defaultContents?: any) {\n const dir = path.dirname(filename);\n\n // create the directory if it doesn't already exist\n if (!fs.existsSync(dir)) fs.mkdirSync(dir);\n\n // create the file if it doesn't already exist\n if (!fs.existsSync(filename)) {\n // create the file, writing the `defaultContents` if provided\n fs.writeFileSync(filename, defaultContents || \"\", \"utf-8\");\n }\n}\n\nfunction jsonIsConfigYAML(json: unknown): json is ConfigYAML {\n return typeof json === \"object\";\n}\n\nfunction jsonIsGlobalYAML(\n json: unknown\n): json is Record<string, { token: string }[]> {\n return (\n !!json &&\n typeof json === \"object\" &&\n Object.values(json).every(\n (arr) =>\n (arr as any).every &&\n arr.every(\n (val: any) =>\n typeof val === \"object\" && Object.keys(val).includes(\"token\")\n )\n )\n );\n}\n\n/**\n * Read data from a project config file\n * @param {string} file defaults to `PROJECT_CONFIG_FILE` defined in `constants.js`\n * @param {*} defaultData defaults to `{}`\n * @returns { ConfigYAML }\n */\nfunction readProjectConfigData(\n file = consts.PROJECT_CONFIG_FILE,\n defaultData = {}\n): ConfigYAML {\n createFileIfMissing(file, DEFAULT_CONFIG);\n const fileContents = fs.readFileSync(file, \"utf8\");\n const yamlData = yaml.load(fileContents);\n if (jsonIsConfigYAML(yamlData)) {\n return yamlData;\n }\n return defaultData;\n}\n\n/**\n * Read data from a global config file\n * @param {string} file defaults to `CONFIG_FILE` defined in `constants.js`\n * @param {*} defaultData defaults to `{}`\n * @returns { Record<string, { token: string }[]> }\n */\nfunction readGlobalConfigData(\n file = consts.CONFIG_FILE,\n defaultData = {}\n): Record<string, { token: string }[]> {\n createFileIfMissing(file);\n const fileContents = fs.readFileSync(file, \"utf8\");\n const yamlData = yaml.load(fileContents);\n if (jsonIsGlobalYAML(yamlData)) {\n return yamlData;\n }\n return defaultData;\n}\n\nfunction writeProjectConfigData(file: string, data: Partial<ConfigYAML>) {\n createFileIfMissing(file, DEFAULT_CONFIG);\n const existingData = readProjectConfigData(file);\n\n const configData: ConfigYAML = {\n ...existingData,\n ...data,\n sources: {\n ...existingData.sources,\n ...data.sources,\n },\n };\n\n const yamlStr = yaml.dump(configData);\n fs.writeFileSync(file, yamlStr, \"utf8\");\n}\n\nfunction writeGlobalConfigData(file: string, data: object) {\n createFileIfMissing(file);\n const existingData = readGlobalConfigData(file);\n const yamlStr = yaml.dump({ ...existingData, ...data });\n fs.writeFileSync(file, yamlStr, \"utf8\");\n}\n\nfunction justTheHost(host: string) {\n if (!host.includes(\"://\")) return host;\n return url.parse(host).hostname || \"\";\n}\n\nfunction deleteToken(file: string, host: string) {\n const data = readGlobalConfigData(file);\n const hostParsed = justTheHost(host);\n data[hostParsed] = [];\n data[hostParsed][0] = { token: \"\" };\n writeGlobalConfigData(file, data);\n}\n\nfunction saveToken(file: string, host: string, token: string) {\n const data = readGlobalConfigData(file);\n const hostParsed = justTheHost(host);\n data[hostParsed] = []; // only allow one token per host\n data[hostParsed][0] = { token };\n writeGlobalConfigData(file, data);\n}\n\nfunction getTokenFromEnv() {\n return process.env.DITTO_API_KEY;\n}\n\n/**\n *\n * @param {string} file\n * @param {string} host\n * @returns {Token}\n */\nfunction getToken(file: string, host: string) {\n const tokenFromEnv = getTokenFromEnv();\n if (tokenFromEnv) {\n return tokenFromEnv;\n }\n\n const data = readGlobalConfigData(file);\n const hostEntry = data[justTheHost(host)];\n if (!hostEntry) return undefined;\n const { length } = hostEntry;\n\n return hostEntry[length - 1].token;\n}\n\nconst IS_DUPLICATE = /-(\\d+$)/;\n\nfunction dedupeProjectName(projectNames: Set<string>, projectName: string) {\n let dedupedName = projectName;\n\n if (projectNames.has(dedupedName)) {\n while (projectNames.has(dedupedName)) {\n const [_, numberStr] = dedupedName.match(IS_DUPLICATE) || [];\n if (numberStr && !isNaN(parseInt(numberStr))) {\n dedupedName = `${dedupedName.replace(IS_DUPLICATE, \"\")}-${\n parseInt(numberStr) + 1\n }`;\n } else {\n dedupedName = `${dedupedName}-1`;\n }\n }\n }\n\n return dedupedName;\n}\n\n/**\n * Reads from the config file, filters out\n * invalid projects, dedupes those remaining, and returns:\n * - whether or not the data required to `pull` is present\n * - whether or not the component library should be fetched\n * - an array of valid, deduped projects\n * - the `variants` and `format` config options\n */\nfunction parseSourceInformation(file?: string): SourceInformation {\n const {\n sources,\n variants,\n format,\n status,\n richText,\n projects: projectsRoot,\n components: componentsRoot,\n } = readProjectConfigData(file);\n\n const projects = sources?.projects || [];\n\n const projectNames = new Set<string>();\n const validProjects: Project[] = [];\n let hasComponentLibraryInProjects = false;\n\n (projects || []).forEach((project) => {\n const isValid = project.id && project.name;\n if (!isValid) {\n return;\n }\n\n if (project.id === \"ditto_component_library\") {\n hasComponentLibraryInProjects = true;\n return;\n }\n\n project.fileName = dedupeProjectName(projectNames, project.name);\n projectNames.add(project.fileName);\n\n validProjects.push(project);\n });\n\n const shouldFetchComponentLibrary = Boolean(sources?.components);\n const componentRoot =\n typeof sources?.components === \"object\"\n ? sources.components.root\n : undefined;\n const componentFolders =\n typeof sources?.components === \"object\"\n ? sources.components.folders\n : undefined;\n\n /**\n * If it's not specified to fetch projects or the component library, then there\n * is no source data to pull.\n */\n const hasSourceData = !!validProjects.length || shouldFetchComponentLibrary;\n\n const result = {\n hasSourceData,\n validProjects,\n shouldFetchComponentLibrary,\n variants: variants || false,\n format,\n status,\n richText,\n hasTopLevelProjectsField: !!projectsRoot,\n hasTopLevelComponentsField: !!componentsRoot,\n hasComponentLibraryInProjects,\n componentRoot,\n componentFolders,\n };\n\n Sentry.setContext(\"config\", createSentryContext(result));\n\n return result;\n}\n\nexport default {\n createFileIfMissing,\n readProjectConfigData,\n readGlobalConfigData,\n writeGlobalConfigData,\n writeProjectConfigData,\n justTheHost,\n saveToken,\n deleteToken,\n getToken,\n getTokenFromEnv,\n parseSourceInformation,\n};\n"],"names":["yaml","path","fs","consts","url"],"mappings":"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","debug_id":"3f451b9b-6016-532a-b399-58b8b273e73c"}
|
package/bin/ditto.js
CHANGED
|
@@ -74,7 +74,7 @@ var import_generate_suggestions = require("./generate-suggestions");
|
|
|
74
74
|
var import_processMetaOption = __toESM(require("./utils/processMetaOption"));
|
|
75
75
|
var import_importComponents = require("./importComponents");
|
|
76
76
|
var import_component_folders = require("./component-folders");
|
|
77
|
-
const environment = "
|
|
77
|
+
const environment = "production";
|
|
78
78
|
Sentry.init({ dsn: "https://9c1d99fa4267f54c6b914f720b4ed3a2@o979374.ingest.sentry.io/4505705213919232", environment, release: import_package.version });
|
|
79
79
|
function getVersion() {
|
|
80
80
|
const packageJsonPath = import_path.default.join(__dirname, "..", "package.json");
|
package/bin/init/project.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
!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]="
|
|
2
|
+
!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]="fe72409f-ce5c-58cd-8ee2-da472d2578a7")}catch(e){}}();
|
|
3
3
|
|
|
4
4
|
var __create = Object.create;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
@@ -68,7 +68,7 @@ var import_quit = require("../utils/quit");
|
|
|
68
68
|
function saveProject(file, name, id) {
|
|
69
69
|
if (id === "components") {
|
|
70
70
|
import_config.default.writeProjectConfigData(file, {
|
|
71
|
-
sources: { components:
|
|
71
|
+
sources: { components: true }
|
|
72
72
|
});
|
|
73
73
|
return;
|
|
74
74
|
}
|
|
@@ -179,4 +179,4 @@ var project_default = { needsSource, collectAndSaveSource };
|
|
|
179
179
|
});
|
|
180
180
|
//# sourceMappingURL=project.js.map
|
|
181
181
|
|
|
182
|
-
//# debugId=
|
|
182
|
+
//# debugId=fe72409f-ce5c-58cd-8ee2-da472d2578a7
|
package/bin/init/project.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../lib/init/project.ts"],"sourcesContent":["import ora from \"ora\";\n\nimport { createApiClient } from \"../api\";\nimport config from \"../config\";\nimport consts from \"../consts\";\nimport output from \"../output\";\nimport { collectAndSaveToken } from \"./token\";\nimport {\n getSelectedProjects,\n getIsUsingComponents,\n} from \"../utils/getSelectedProjects\";\nimport promptForProject from \"../utils/promptForProject\";\nimport { AxiosResponse } from \"axios\";\nimport { Project, Token } from \"../types\";\nimport { quit } from \"../utils/quit\";\n\nfunction saveProject(file: string, name: string, id: string) {\n if (id === \"components\") {\n config.writeProjectConfigData(file, {\n sources: { components:
|
|
1
|
+
{"version":3,"sources":["../../lib/init/project.ts"],"sourcesContent":["import ora from \"ora\";\n\nimport { createApiClient } from \"../api\";\nimport config from \"../config\";\nimport consts from \"../consts\";\nimport output from \"../output\";\nimport { collectAndSaveToken } from \"./token\";\nimport {\n getSelectedProjects,\n getIsUsingComponents,\n} from \"../utils/getSelectedProjects\";\nimport promptForProject from \"../utils/promptForProject\";\nimport { AxiosResponse } from \"axios\";\nimport { Project, Token } from \"../types\";\nimport { quit } from \"../utils/quit\";\n\nfunction saveProject(file: string, name: string, id: string) {\n if (id === \"components\") {\n config.writeProjectConfigData(file, {\n sources: { components: true },\n });\n return;\n }\n\n const projects = [...getSelectedProjects(file), { name, id }];\n config.writeProjectConfigData(file, { sources: { projects } });\n}\n\nexport const needsSource = () => {\n return !config.parseSourceInformation().hasSourceData;\n};\n\nasync function askForAnotherToken() {\n config.deleteToken(consts.CONFIG_FILE, consts.API_HOST);\n const message =\n \"Looks like the API key you have saved no longer works. Please enter another one.\";\n await collectAndSaveToken(message);\n}\n\nasync function listProjects(token: Token, projectsAlreadySelected: Project[]) {\n const api = createApiClient();\n const spinner = ora(\"Fetching sources in your workspace...\");\n spinner.start();\n\n let response: AxiosResponse<{ id: string; name: string }[]>;\n try {\n response = await api.get(\"/project-names\");\n } catch (e) {\n spinner.stop();\n throw e;\n }\n\n const projectsAlreadySelectedSet = projectsAlreadySelected.reduce(\n (set, project) => set.add(project.id.toString()),\n new Set<string>()\n );\n\n const result = response.data.filter(\n ({ id }) =>\n // covers an edge case where v0 of the API includes the component library\n // in the response from the `/project-names` endpoint\n id !== \"ditto_component_library\" &&\n !projectsAlreadySelectedSet.has(id.toString())\n );\n\n spinner.stop();\n\n return result;\n}\n\nasync function collectSource(token: Token, includeComponents: boolean) {\n const projectsAlreadySelected = getSelectedProjects();\n const componentSourceSelected = getIsUsingComponents();\n\n let sources = await listProjects(token, projectsAlreadySelected);\n if (includeComponents && !componentSourceSelected) {\n sources = [\n { id: \"ditto_component_library\", name: \"Ditto Component Library\" },\n ...sources,\n ];\n }\n\n if (!sources?.length) {\n console.log(\"You're currently syncing all projects in your workspace.\");\n console.log(\n output.warnText(\n \"Not seeing a project that you were expecting? Verify that developer mode is enabled on that project. More info: https://www.dittowords.com/docs/ditto-developer-mode\"\n )\n );\n return null;\n }\n\n return promptForProject({\n projects: sources,\n message: \"Choose the source you'd like to sync text from\",\n });\n}\n\nexport const collectAndSaveSource = async (\n { components = false }: { initialize?: boolean; components?: boolean } = {\n components: false,\n }\n) => {\n try {\n const token = config.getToken(consts.CONFIG_FILE, consts.API_HOST);\n const project = await collectSource(token, components);\n if (!project) {\n quit(null, 0);\n return;\n }\n\n console.log(\n \"\\n\" +\n `Thanks for adding ${output.info(\n project.name\n )} to your selected sources.\\n` +\n `We saved your updated configuration to: ${output.info(\n consts.PROJECT_CONFIG_FILE\n )}\\n`\n );\n\n saveProject(consts.PROJECT_CONFIG_FILE, project.name, project.id);\n } catch (e: any) {\n console.log(e);\n if (e.response && e.response.status === 404) {\n await askForAnotherToken();\n await collectAndSaveSource({ components });\n } else {\n quit(null, 2);\n }\n }\n};\n\nexport const _testing = { saveProject, needsSource };\n\nexport default { needsSource, collectAndSaveSource };\n"],"names":["config","consts","ora","output","promptForProject"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAgB;AAEhB,iBAAgC;AAChC,oBAAmB;AACnB,oBAAmB;AACnB,oBAAmB;AACnB,mBAAoC;AACpC,iCAGO;AACP,8BAA6B;AAG7B,kBAAqB;AAErB,SAAS,YAAY,MAAc,MAAc,IAAY;AAC3D,MAAI,OAAO,cAAc;AACvB,kBAAAA,QAAO,uBAAuB,MAAM;AAAA,MAClC,SAAS,EAAE,YAAY,KAAK;AAAA,IAC9B,CAAC;AACD;AAAA,EACF;AAEA,QAAM,WAAW,CAAC,OAAG,gDAAoB,IAAI,GAAG,EAAE,MAAM,GAAG,CAAC;AAC5D,gBAAAA,QAAO,uBAAuB,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AAC/D;AAEO,MAAM,cAAc,MAAM;AAC/B,SAAO,CAAC,cAAAA,QAAO,uBAAuB,EAAE;AAC1C;AAEA,SAAe,qBAAqB;AAAA;AAClC,kBAAAA,QAAO,YAAY,cAAAC,QAAO,aAAa,cAAAA,QAAO,QAAQ;AACtD,UAAM,UACJ;AACF,cAAM,kCAAoB,OAAO;AAAA,EACnC;AAAA;AAEA,SAAe,aAAa,OAAc,yBAAoC;AAAA;AAC5E,UAAM,UAAM,4BAAgB;AAC5B,UAAM,cAAU,WAAAC,SAAI,uCAAuC;AAC3D,YAAQ,MAAM;AAEd,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,IAAI,IAAI,gBAAgB;AAAA,IAC3C,SAAS,GAAG;AACV,cAAQ,KAAK;AACb,YAAM;AAAA,IACR;AAEA,UAAM,6BAA6B,wBAAwB;AAAA,MACzD,CAAC,KAAK,YAAY,IAAI,IAAI,QAAQ,GAAG,SAAS,CAAC;AAAA,MAC/C,oBAAI,IAAY;AAAA,IAClB;AAEA,UAAM,SAAS,SAAS,KAAK;AAAA,MAC3B,CAAC,EAAE,GAAG;AAAA;AAAA;AAAA,QAGJ,OAAO,6BACP,CAAC,2BAA2B,IAAI,GAAG,SAAS,CAAC;AAAA;AAAA,IACjD;AAEA,YAAQ,KAAK;AAEb,WAAO;AAAA,EACT;AAAA;AAEA,SAAe,cAAc,OAAc,mBAA4B;AAAA;AACrE,UAAM,8BAA0B,gDAAoB;AACpD,UAAM,8BAA0B,iDAAqB;AAErD,QAAI,UAAU,MAAM,aAAa,OAAO,uBAAuB;AAC/D,QAAI,qBAAqB,CAAC,yBAAyB;AACjD,gBAAU;AAAA,QACR,EAAE,IAAI,2BAA2B,MAAM,0BAA0B;AAAA,QACjE,GAAG;AAAA,MACL;AAAA,IACF;AAEA,QAAI,EAAC,mCAAS,SAAQ;AACpB,cAAQ,IAAI,0DAA0D;AACtE,cAAQ;AAAA,QACN,cAAAC,QAAO;AAAA,UACL;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,eAAO,wBAAAC,SAAiB;AAAA,MACtB,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA;AAEO,MAAM,uBAAuB,IAI/B,2CAHH,EAAE,aAAa,MAAM,IAAoD;AAAA,EACvE,YAAY;AACd,GACG;AACH,MAAI;AACF,UAAM,QAAQ,cAAAJ,QAAO,SAAS,cAAAC,QAAO,aAAa,cAAAA,QAAO,QAAQ;AACjE,UAAM,UAAU,MAAM,cAAc,OAAO,UAAU;AACrD,QAAI,CAAC,SAAS;AACZ,4BAAK,MAAM,CAAC;AACZ;AAAA,IACF;AAEA,YAAQ;AAAA,MACN;AAAA,oBACuB,cAAAE,QAAO;AAAA,QAC1B,QAAQ;AAAA,MACV,CAAC;AAAA,0CAC0C,cAAAA,QAAO;AAAA,QAChD,cAAAF,QAAO;AAAA,MACT,CAAC;AAAA;AAAA,IACL;AAEA,gBAAY,cAAAA,QAAO,qBAAqB,QAAQ,MAAM,QAAQ,EAAE;AAAA,EAClE,SAAS,GAAQ;AACf,YAAQ,IAAI,CAAC;AACb,QAAI,EAAE,YAAY,EAAE,SAAS,WAAW,KAAK;AAC3C,YAAM,mBAAmB;AACzB,YAAM,qBAAqB,EAAE,WAAW,CAAC;AAAA,IAC3C,OAAO;AACL,4BAAK,MAAM,CAAC;AAAA,IACd;AAAA,EACF;AACF;AAEO,MAAM,WAAW,EAAE,aAAa,YAAY;AAEnD,IAAO,kBAAQ,EAAE,aAAa,qBAAqB","debug_id":"fe72409f-ce5c-58cd-8ee2-da472d2578a7"}
|