Skip to content

Commit 57d6c69

Browse files
authored
Merge branch 'main' into feat/print-stylesheet
2 parents 0b24b1d + 30fd5f4 commit 57d6c69

38 files changed

+3018
-38
lines changed

.changeset/config.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
"access": "public",
1010
"baseBranch": "main",
1111
"updateInternalDependencies": "patch",
12-
"ignore": ["starlight-docs"]
12+
"ignore": ["starlight-docs", "@example/*", "docs-i18n-tracker"]
1313
}

.github/labeler.yml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# See https://github.com/actions/labeler
2+
3+
'🚨 action':
4+
- .github/workflows/**
5+
6+
i18n:
7+
- src/content/docs/de/**/*
8+
- src/content/docs/es/**/*
9+
- src/content/docs/fr/**/*
10+
- src/content/docs/it/**/*
11+
- src/content/docs/ja/**/*

.github/workflows/pr-labeler.yml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: "Pull Request Labeler"
2+
on:
3+
- pull_request_target
4+
5+
jobs:
6+
triage:
7+
permissions:
8+
contents: read
9+
pull-requests: write
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/labeler@v4
13+
with:
14+
repo-token: "${{ secrets.GITHUB_TOKEN }}"
15+

.github/workflows/release.yml

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ jobs:
3232
- name: Create Release Pull Request
3333
uses: changesets/action@v1
3434
with:
35+
version: pnpm run version
3536
publish: pnpm changeset publish
3637
commit: '[ci] release'
3738
title: '[ci] release'

.npmrc

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
prefer-workspace-packages=true
2+
link-workspace-packages=true

docs-i18n-tracker/.gitignore

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# build output
2+
dist/
3+
# generated types
4+
.astro/
5+
6+
# dependencies
7+
node_modules/
8+
9+
# logs
10+
npm-debug.log*
11+
yarn-debug.log*
12+
yarn-error.log*
13+
pnpm-debug.log*
14+
15+
16+
# environment variables
17+
.env
18+
.env.production
19+
20+
# macOS-specific files
21+
.DS_Store

docs-i18n-tracker/README.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# docs-i18n-tracker
2+
3+
This folder contains scripts for generating a single-page dashboard tracking translation progress of pages in the Starlight docs site.
4+
5+
You can build the page locally by moving to this directory and running `pnpm build`.
6+
7+
The page will be built to `dist/index.html` in this directory.
8+
9+
The live version of this tracker is available at **<https://i18n.starlight.astro.build>**.

docs-i18n-tracker/build.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { TranslationStatusBuilder } from './lib/translation-status/builder';
2+
import { locales } from '../docs/astro.config.mjs';
3+
4+
const translationStatusBuilder = new TranslationStatusBuilder({
5+
pageSourceDir: '../docs/src/content/docs',
6+
htmlOutputFilePath: './dist/index.html',
7+
sourceLanguage: 'en',
8+
targetLanguages: Object.values(locales)
9+
.map((el) => el.lang)
10+
.filter((lang) => lang !== 'en')
11+
.sort(),
12+
languageLabels: Object.values(locales)
13+
.filter((loc) => loc.lang !== 'en')
14+
.reduce((acc, curr) => ({ [curr.lang]: curr.label, ...acc }), {}),
15+
githubRepo: process.env.GITHUB_REPOSITORY || 'withastro/starlight',
16+
githubToken: process.env.GITHUB_TOKEN,
17+
});
18+
19+
await translationStatusBuilder.run();
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* When using custom loaders like `tsm` to add TypeScript & module support to scripts,
3+
* Node.js outputs a known set of warnings, which distract from the actual script output.
4+
*
5+
* By adding `--require=./scripts/lib/filter-warnings.cjs` to the `node` or `tsm` args,
6+
* this script filters those known warnings (but not any others) from the output.
7+
*/
8+
9+
// Remove Node's built-in `warning` listener which outputs all warnings to stderr
10+
process.removeAllListeners('warning');
11+
12+
// Add our own version that skips known warnings
13+
process.on('warning', (warning) => {
14+
let { name, message } = warning;
15+
if (
16+
name === 'ExperimentalWarning' &&
17+
(message.indexOf('--experimental-loader') > -1 || message.indexOf('Custom ESM Loaders') > -1)
18+
)
19+
return;
20+
if (name === 'DeprecationWarning' && message.indexOf('Obsolete loader hook') > -1) return;
21+
22+
console.warn(warning);
23+
});

docs-i18n-tracker/lib/github-get.mjs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import fetch from 'node-fetch';
2+
import pRetry, { AbortError } from 'p-retry';
3+
4+
/**
5+
* Fetch a URL from the GitHub API and resolve its JSON response.
6+
* @param {{ url: string; githubToken?: string }} options
7+
* @returns {Promise<any>}
8+
*/
9+
export async function githubGet({ url, githubToken = undefined }) {
10+
return await pRetry(
11+
async () => {
12+
const headers = {
13+
Accept: 'application/vnd.github.v3+json',
14+
};
15+
if (githubToken) {
16+
headers.Authorization = `token ${githubToken}`;
17+
}
18+
const response = await fetch(url, { headers });
19+
const json = await response.json();
20+
21+
if (!response.ok) {
22+
throw new AbortError(
23+
`GitHub API call failed: GET "${url}" returned status ${
24+
response.status
25+
}: ${JSON.stringify(json)}`
26+
);
27+
}
28+
29+
return json;
30+
},
31+
{ retries: 5 }
32+
);
33+
}

docs-i18n-tracker/lib/output.mjs

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import dedent from 'dedent-js';
2+
import kleur from 'kleur';
3+
4+
export const isCi = process.env.CI;
5+
6+
/**
7+
* @param {any} [message]
8+
* @param {...any} params
9+
*/
10+
export function debug(message, ...params) {
11+
console.log(message, ...params);
12+
}
13+
14+
/**
15+
* @param {any} [message]
16+
* @param {...any} params
17+
*/
18+
export function warning(message, ...params) {
19+
console.warn(kleur.yellow().bold(`*** WARNING: ${message}`), ...params);
20+
}
21+
22+
/**
23+
* @param {any} [message]
24+
* @param {...any} params
25+
*/
26+
export function error(message, ...params) {
27+
console.error(kleur.red().bold(`*** ERROR: ${message}`), ...params);
28+
}
29+
30+
/**
31+
* Dedents the given markdown and replaces single newlines with spaces,
32+
* while leaving new paragraphs intact.
33+
*/
34+
export function dedentMd(...markdown) {
35+
return dedent(...markdown).replace(/(\S)\n(?!\n)/g, '$1 ');
36+
}
37+
38+
/**
39+
* Formats the given `template` based on `count`, picking the correct plural
40+
* or singular form from the template.
41+
*
42+
* - If `count` is defined, it also prepends the template with `count`.
43+
* - Example: "broken link(s)" --> "1 broken link" / "2 broken links"
44+
* - If `count` is undefined, it capitalizes the first letter.
45+
* - Example: "broken link(s)" --> "Broken link"
46+
*
47+
* Supported template syntax:
48+
* - Use `(s)` to add a plural-only "s", e.g. "broken link(s)"
49+
* - Use `|` to provide separate templates, e.g. "issue was|issues were"
50+
*
51+
* @param {number} count
52+
* @param {string} template
53+
*/
54+
export function formatCount(count, template) {
55+
/** @param {string} text */
56+
const wrapWithCount = (text) => {
57+
// If no count was given, we're outputting a single issue in annotations,
58+
// so omit count and capitalize the first letter of the issue type description
59+
if (count === undefined) return text[0].toUpperCase() + text.slice(1);
60+
61+
// Otherwise, prefix the issue type description with count
62+
return `${count} ${text}`;
63+
};
64+
65+
const usePlural = count !== undefined && count !== 1;
66+
const templateParts = template.split('|');
67+
const usedTemplate =
68+
templateParts.length === 2 ? templateParts[usePlural ? 1 : 0] : template;
69+
return wrapWithCount(usedTemplate.replace(/\(s\)/g, usePlural ? 's' : ''));
70+
}
71+
72+
export default {
73+
debug,
74+
warning,
75+
error,
76+
dedentMd,
77+
formatCount,
78+
isCi,
79+
};

0 commit comments

Comments
 (0)