@examplary/cli 1.14.0 → 1.15.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 CHANGED
@@ -25,6 +25,10 @@ You'll be required to pass a `--key` argument with your API key, which you can
25
25
  obtain from your Examplary account settings. You can also set the `EXAMPLARY_API_KEY`
26
26
  environment variable to avoid passing the key every time.
27
27
 
28
+ A `README.md` and `preview.png` in the same directory are uploaded as the question type's
29
+ documentation and preview image, along with any translations named by language code, like
30
+ `README.nl.md` or `preview.nl.png`.
31
+
28
32
  ## Validating
29
33
 
30
34
  To run all of the pre-upload checks without uploading anything, use:
@@ -1,10 +1,29 @@
1
1
  #! /usr/bin/env node
2
- import { readFile } from "fs/promises";
2
+ import { readdir, readFile } from "fs/promises";
3
3
  import { join } from "path";
4
4
  import { cwd, exit } from "process";
5
5
  import { setApiHost, setApiKey, uploadFile } from "../lib/api.js";
6
6
  import { readJsonOrYamlFile, readMetaFile } from "../lib/read-meta.js";
7
7
  import { isValid, printValidationResult, validateDefinition, } from "../lib/validate.js";
8
+ /**
9
+ * Uploads e.g. `README.md` (English) and its translations like `README.nl.md`,
10
+ * returning their URLs keyed by language code.
11
+ */
12
+ const uploadLocalizedFiles = async (dir, baseName, extension, contentType) => {
13
+ const pattern = new RegExp(`^${baseName}(?:\\.([a-z]{2}))?\\.${extension}$`);
14
+ const urls = {};
15
+ for (const file of await readdir(dir)) {
16
+ const match = file.match(pattern);
17
+ if (!match)
18
+ continue;
19
+ const contents = await readFile(join(dir, file));
20
+ if (!contents.length)
21
+ continue;
22
+ urls[match[1] || "en"] = await uploadFile(file, contents, contentType);
23
+ console.log(`• Uploaded ${file}`);
24
+ }
25
+ return Object.keys(urls).length ? urls : undefined;
26
+ };
8
27
  export const uploadCommand = async (argv) => {
9
28
  setApiHost(argv.host);
10
29
  setApiKey(argv.key);
@@ -62,18 +81,10 @@ export const uploadCommand = async (argv) => {
62
81
  definition.icon = await uploadFile("icon.svg", result.iconContents, "image/svg+xml");
63
82
  console.log(`• Uploaded icon`);
64
83
  }
65
- // Upload the README if present
66
- const readme = await readFile(join(dir, "README.md"), "utf-8").catch(() => null);
67
- if (readme) {
68
- definition.readme = await uploadFile("README.md", readme, "text/markdown");
69
- console.log(`• Uploaded README`);
70
- }
71
- // Upload the preview image if present
72
- const previewImage = await readFile(join(dir, "preview.png")).catch(() => null);
73
- if (previewImage) {
74
- definition.previewImage = await uploadFile("preview.png", previewImage, "image/png");
75
- console.log(`• Uploaded preview image`);
76
- }
84
+ definition.readmeUrls = await uploadLocalizedFiles(dir, "README", "md", "text/markdown");
85
+ definition.readme = definition.readmeUrls?.en;
86
+ definition.previewImageUrls = await uploadLocalizedFiles(dir, "preview", "png", "image/png");
87
+ definition.previewImage = definition.previewImageUrls?.en;
77
88
  // Upload the preview data if present, always converted to JSON
78
89
  try {
79
90
  const preview = await readJsonOrYamlFile(dir, "preview");