misc: convert all internal scripts to ESM (#6286)

* misc: convert all internal scripts to ESM

* fixes

* fix

* fixes

* fix!

* complete eslint

* more move

* fix!

* This looks better?

* Final ones
This commit is contained in:
Joshua Chen 2022-01-08 12:59:28 +08:00 committed by GitHub
parent bcc05e243f
commit 4fad1ce0cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
66 changed files with 412 additions and 374 deletions

View file

@ -12,9 +12,7 @@ packages/lqip-loader/lib/
packages/docusaurus/lib/ packages/docusaurus/lib/
packages/docusaurus-*/lib/* packages/docusaurus-*/lib/*
packages/docusaurus-*/lib-next/ packages/docusaurus-*/lib-next/
packages/docusaurus-plugin-pwa/copyUntypedFiles.js copyUntypedFiles.mjs
packages/docusaurus-plugin-ideal-image/copyUntypedFiles.js
packages/docusaurus-theme-search-algolia/copyUntypedFiles.js
packages/create-docusaurus/lib/* packages/create-docusaurus/lib/*
packages/create-docusaurus/templates/facebook/.eslintrc.js packages/create-docusaurus/templates/facebook/.eslintrc.js

View file

@ -39,6 +39,7 @@ module.exports = {
}, },
}, },
}, },
reportUnusedDisableDirectives: true,
plugins: ['react-hooks', 'header'], plugins: ['react-hooks', 'header'],
rules: { rules: {
'react-hooks/rules-of-hooks': ERROR, 'react-hooks/rules-of-hooks': ERROR,
@ -208,7 +209,7 @@ module.exports = {
}, },
}, },
{ {
files: ['*.js'], files: ['*.js', '*.mjs', '.cjs'],
rules: { rules: {
// Make JS code directly runnable in Node. // Make JS code directly runnable in Node.
'@typescript-eslint/no-var-requires': OFF, '@typescript-eslint/no-var-requires': OFF,

View file

@ -5,10 +5,10 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
// eslint-disable-next-line import/no-extraneous-dependencies /* eslint-disable import/no-extraneous-dependencies */
const rimraf = require('rimraf');
const {readFileSync, writeFileSync, readdirSync} = require('fs'); import fs from 'fs-extra';
const {execSync} = require('child_process'); import shell from 'shelljs';
const NODE_MAJOR_VERSION = parseInt(process.versions.node.split('.')[0], 10); const NODE_MAJOR_VERSION = parseInt(process.versions.node.split('.')[0], 10);
if (NODE_MAJOR_VERSION < 16) { if (NODE_MAJOR_VERSION < 16) {
@ -20,7 +20,7 @@ if (NODE_MAJOR_VERSION < 16) {
// Generate one example per init template // Generate one example per init template
// We use those generated examples as CodeSandbox projects // We use those generated examples as CodeSandbox projects
// See https://github.com/facebook/docusaurus/issues/1699 // See https://github.com/facebook/docusaurus/issues/1699
function generateTemplateExample(template) { async function generateTemplateExample(template) {
try { try {
console.log( console.log(
`generating ${template} template for codesandbox in the examples folder...`, `generating ${template} template for codesandbox in the examples folder...`,
@ -30,20 +30,17 @@ function generateTemplateExample(template) {
const command = template.endsWith('-typescript') const command = template.endsWith('-typescript')
? template.replace('-typescript', ' -- --typescript') ? template.replace('-typescript', ' -- --typescript')
: template; : template;
execSync( shell.exec(
// /!\ we use the published init script on purpose, // /!\ we use the published init script on purpose,
// because using the local init script is too early and could generate upcoming/unavailable config options // because using the local init script is too early and could generate upcoming/unavailable config options
// remember CodeSandbox templates will use the published version, not the repo version // remember CodeSandbox templates will use the published version, not the repo version
`npm init docusaurus@latest examples/${template} ${command}`, `npm init docusaurus@latest examples/${template} ${command}`,
// `node ./packages/docusaurus-init/bin/index.js init examples/${template} ${template}`, // `node ./packages/docusaurus-init/bin/index.js init examples/${template} ${template}`,
{
stdio: 'inherit',
},
); );
// read the content of the package.json // read the content of the package.json
const templatePackageJson = JSON.parse( const templatePackageJson = JSON.parse(
readFileSync(`examples/${template}/package.json`, 'utf8'), await fs.readFile(`examples/${template}/package.json`, 'utf8'),
); );
// attach the dev script which would be used in code sandbox by default // attach the dev script which would be used in code sandbox by default
@ -64,7 +61,7 @@ function generateTemplateExample(template) {
: `Docusaurus example project (${template} template)`; : `Docusaurus example project (${template} template)`;
// rewrite the package.json file with the new edit // rewrite the package.json file with the new edit
writeFileSync( await fs.writeFile(
`./examples/${template}/package.json`, `./examples/${template}/package.json`,
`${JSON.stringify(templatePackageJson, null, 2)}\n`, `${JSON.stringify(templatePackageJson, null, 2)}\n`,
); );
@ -80,7 +77,7 @@ function generateTemplateExample(template) {
node: '14', node: '14',
}, },
}; };
writeFileSync( await fs.writeFile(
`./examples/${template}/sandbox.config.json`, `./examples/${template}/sandbox.config.json`,
`${JSON.stringify(codeSanboxConfig, null, 2)}\n`, `${JSON.stringify(codeSanboxConfig, null, 2)}\n`,
); );
@ -89,7 +86,7 @@ function generateTemplateExample(template) {
installDependencies: true, installDependencies: true,
startCommand: 'npm start', startCommand: 'npm start',
}; };
writeFileSync( await fs.writeFile(
`./examples/${template}/.stackblitzrc`, `./examples/${template}/.stackblitzrc`,
`${JSON.stringify(stackBlitzConfig, null, 2)}\n`, `${JSON.stringify(stackBlitzConfig, null, 2)}\n`,
); );
@ -115,7 +112,7 @@ function updateStarters() {
const command = `git push ${remote} \`git subtree split --prefix ${subfolder}\`:${remoteBranch} --force`; const command = `git push ${remote} \`git subtree split --prefix ${subfolder}\`:${remoteBranch} --force`;
try { try {
console.log(`forcePushGitSubtree command: ${command}`); console.log(`forcePushGitSubtree command: ${command}`);
execSync(command); shell.exec(command);
console.log('forcePushGitSubtree success!'); console.log('forcePushGitSubtree success!');
} catch (e) { } catch (e) {
console.error( console.error(
@ -150,60 +147,58 @@ function updateStarters() {
console.log(''); console.log('');
} }
function run() { const branch = shell.exec('git rev-parse --abbrev-ref HEAD').stdout;
const branch = execSync('git rev-parse --abbrev-ref HEAD').toString(); if (branch === 'main') {
if (branch === 'main') { throw new Error(
throw new Error( "Please don't generate Docusaurus examples from the main branch!\nWe are going to commit during this process!",
"Please don't generate Docusaurus examples from the main branch!\nWe are going to commit during this process!", );
); }
} if (shell.exec('git diff --exit-code').code !== 0) {
try { throw new Error(
execSync('git diff --exit-code'); 'Please run the generate examples command with a clean Git state and no uncommitted local changes. git diff should display nothing!',
} catch (e) { );
throw new Error(
'Please run the generate examples command with a clean Git state and no uncommited local changes. git diff should display nothing!',
);
}
console.log('');
console.log('# Generate examples start!');
console.log('');
// delete the examples directories if they exists
console.log('-------');
console.log('## Removing example folders...');
rimraf.sync('./examples/classic');
rimraf.sync('./examples/classic-typescript');
rimraf.sync('./examples/facebook');
console.log('');
// get the list of all available templates
console.log('-------');
console.log('## Generate example folders...');
console.log('');
const excludes = ['README.md', 'shared'];
const templates = readdirSync(
'./packages/create-docusaurus/templates',
).filter((name) => !excludes.includes(name));
console.log(`Will generate examples for templates: ${templates}`);
templates.forEach(generateTemplateExample);
console.log('Commiting changes');
execSync('git add examples');
execSync("git commit -am 'update examples' --allow-empty");
console.log('');
// update starters
console.log('-------');
console.log('# Updating starter repos and branches ...');
console.log('It can take some time... please wait until done...');
updateStarters();
console.log('');
console.log('-------');
console.log('');
console.log('Generate examples end!');
console.log("Don't forget to push and merge your pull-request!");
console.log('');
} }
run(); console.log(`
# Generate examples start!
`);
// delete the examples directories if they exists
console.log(`-------
## Removing example folders...
`);
await fs.rm('./examples/classic', {recursive: true, force: true});
await fs.rm('./examples/classic-typescript', {recursive: true, force: true});
await fs.rm('./examples/facebook', {recursive: true, force: true});
// get the list of all available templates
console.log(`
-------
## Generate example folders...
`);
const excludes = ['README.md', 'shared'];
const templates = (
await fs.readdir('./packages/create-docusaurus/templates')
).filter((name) => !excludes.includes(name));
console.log(`Will generate examples for templates: ${templates.join(',')}`);
// eslint-disable-next-line no-restricted-syntax
for (const template of templates) {
await generateTemplateExample(template);
}
console.log('Commiting changes');
shell.exec('git add examples');
shell.exec("git commit -am 'update examples' --allow-empty");
// update starters
console.log(`
-------
# Updating starter repos and branches ...
It can take some time... please wait until done...
`);
updateStarters();
console.log(`
-------
Generate examples end!
Don't forget to push and merge your pull request!
`);

View file

@ -5,26 +5,26 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
// eslint-disable-next-line import/no-extraneous-dependencies /* eslint-disable import/no-extraneous-dependencies */
import sharp from 'sharp'; import sharp from 'sharp';
import fs from 'fs/promises'; import fs from 'fs-extra';
import path from 'path'; import path from 'path';
// eslint-disable-next-line import/no-extraneous-dependencies
import imageSize from 'image-size'; import imageSize from 'image-size';
import {fileURLToPath} from 'url';
const allImages = ( const allImages = (
await fs.readdir(new URL('../../website/src/data/showcase', import.meta.url)) await fs.readdir(new URL('../../website/src/data/showcase', import.meta.url))
).filter((file) => ['.png', 'jpg', '.jpeg'].includes(path.extname(file))); ).filter((file) => ['.png', 'jpg', '.jpeg'].includes(path.extname(file)));
const [,,...selectedImages] = process.argv; const [, , ...selectedImages] = process.argv;
const images = selectedImages.length > 0 ? selectedImages : allImages; const images = selectedImages.length > 0 ? selectedImages : allImages;
await Promise.all( await Promise.all(
images.map(async (img) => { images.map(async (img) => {
const imgPath = new URL( const imgPath = fileURLToPath(
`../../website/src/data/showcase/${img}`, new URL(`../../website/src/data/showcase/${img}`, import.meta.url),
import.meta.url, );
).pathname;
const {width, height} = imageSize(imgPath); const {width, height} = imageSize(imgPath);
if (width === 640 && height === 320) { if (width === 640 && height === 320) {
// Do not emit if no resized. Important because we // Do not emit if no resized. Important because we

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
const path = require('path'); import {fileURLToPath} from 'url';
const ignorePatterns = [ const ignorePatterns = [
'/node_modules/', '/node_modules/',
@ -21,8 +21,8 @@ const ignorePatterns = [
'/packages/docusaurus-migrate/lib', '/packages/docusaurus-migrate/lib',
]; ];
module.exports = { export default {
rootDir: path.resolve(__dirname), rootDir: fileURLToPath(new URL('.', import.meta.url)),
verbose: true, verbose: true,
testURL: 'http://localhost/', testURL: 'http://localhost/',
testEnvironment: 'node', testEnvironment: 'node',

View file

@ -15,7 +15,7 @@
"start:website:baseUrl": "yarn workspace website start:baseUrl", "start:website:baseUrl": "yarn workspace website start:baseUrl",
"start:website:blogOnly": "yarn workspace website start:blogOnly", "start:website:blogOnly": "yarn workspace website start:blogOnly",
"start:website:deployPreview": "cross-env NETLIFY=true CONTEXT='deploy-preview' yarn workspace website start", "start:website:deployPreview": "cross-env NETLIFY=true CONTEXT='deploy-preview' yarn workspace website start",
"examples:generate": "node generateExamples", "examples:generate": "node admin/scripts/generateExamples.mjs",
"build": "yarn build:packages && yarn build:website", "build": "yarn build:packages && yarn build:website",
"build:packages": "lerna run build --no-private", "build:packages": "lerna run build --no-private",
"build:website": "yarn workspace website build", "build:website": "yarn workspace website build",
@ -41,13 +41,13 @@
"postinstall": "run-p postinstall:**", "postinstall": "run-p postinstall:**",
"postinstall:main": "yarn lock:update && yarn build:packages", "postinstall:main": "yarn lock:update && yarn build:packages",
"postinstall:dev": "is-ci || husky install", "postinstall:dev": "is-ci || husky install",
"format": "prettier --config .prettierrc --write \"**/*.{js,jsx,ts,tsx,json}\"", "format": "prettier --config .prettierrc --write \"**/*.{js,jsx,ts,tsx,json,mjs}\"",
"format:diff": "prettier --config .prettierrc --list-different \"**/*.{js,jsx,ts,tsx,json}\"", "format:diff": "prettier --config .prettierrc --list-different \"**/*.{js,jsx,ts,tsx,json,mjs}\"",
"format-docs": "prettier --config .prettierrc --write \"**/*.{md,mdx}\"", "format-docs": "prettier --config .prettierrc --write \"**/*.{md,mdx}\"",
"format-docs:diff": "prettier --config .prettierrc --list-different \"**/*.{md,mdx}\"", "format-docs:diff": "prettier --config .prettierrc --list-different \"**/*.{md,mdx}\"",
"lint": "yarn lint:js && yarn lint:style", "lint": "yarn lint:js && yarn lint:style",
"lint:ci": "yarn lint:js --quiet --report-unused-disable-directives && yarn lint:style", "lint:ci": "yarn lint:js --quiet && yarn lint:style",
"lint:js": "eslint --cache \"**/*.{js,jsx,ts,tsx}\"", "lint:js": "eslint --cache --report-unused-disable-directives \"**/*.{js,jsx,ts,tsx,mjs}\"",
"lint:style": "stylelint \"**/*.css\"", "lint:style": "stylelint \"**/*.css\"",
"lerna": "lerna", "lerna": "lerna",
"test": "cross-env TZ=UTC jest", "test": "cross-env TZ=UTC jest",
@ -116,7 +116,7 @@
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"serve": "^12.0.1", "serve": "^12.0.1",
"sharp": "^0.29.1", "sharp": "^0.29.1",
"stylelint": "^13.10.0", "stylelint": "^14.2.0",
"tslib": "^2.3.1", "tslib": "^2.3.1",
"typescript": "^4.5.2" "typescript": "^4.5.2"
}, },

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -5,15 +5,15 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
const path = require('path'); import fs from 'fs-extra';
const fs = require('fs-extra'); import {fileURLToPath} from 'url';
/** /**
* Copy all untyped and static assets files to lib. * Copy all untyped and static assets files to lib.
*/ */
const srcDir = path.resolve(__dirname, 'src'); const srcDir = fileURLToPath(new URL('src', import.meta.url));
const libDir = path.resolve(__dirname, 'lib'); const libDir = fileURLToPath(new URL('lib', import.meta.url));
fs.copySync(srcDir, libDir, { await fs.copy(srcDir, libDir, {
filter(filepath) { filter(filepath) {
return !/__tests__/.test(filepath) && !/\.tsx?$/.test(filepath); return !/__tests__/.test(filepath) && !/\.tsx?$/.test(filepath);
}, },

View file

@ -5,8 +5,8 @@
"main": "lib/index.js", "main": "lib/index.js",
"types": "src/plugin-debug.d.ts", "types": "src/plugin-debug.d.ts",
"scripts": { "scripts": {
"build": "tsc && node copyUntypedFiles.js", "build": "tsc && node copyUntypedFiles.mjs",
"watch": "node copyUntypedFiles.js && tsc --watch" "watch": "node copyUntypedFiles.mjs && tsc --watch"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -5,15 +5,15 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
const path = require('path'); import fs from 'fs-extra';
const fs = require('fs-extra'); import {fileURLToPath} from 'url';
/** /**
* Copy all untyped and static assets files to lib. * Copy all untyped and static assets files to lib.
*/ */
const srcDir = path.resolve(__dirname, 'src'); const srcDir = fileURLToPath(new URL('src', import.meta.url));
const libDir = path.resolve(__dirname, 'lib'); const libDir = fileURLToPath(new URL('lib', import.meta.url));
fs.copySync(srcDir, libDir, { await fs.copy(srcDir, libDir, {
filter(filepath) { filter(filepath) {
return !/__tests__/.test(filepath) && !/\.tsx?$/.test(filepath); return !/__tests__/.test(filepath) && !/\.tsx?$/.test(filepath);
}, },

View file

@ -8,7 +8,7 @@
"build": "yarn build:server && yarn build:browser && yarn build:copy && yarn build:format", "build": "yarn build:server && yarn build:browser && yarn build:copy && yarn build:format",
"build:server": "tsc --project tsconfig.server.json", "build:server": "tsc --project tsconfig.server.json",
"build:browser": "tsc --project tsconfig.browser.json", "build:browser": "tsc --project tsconfig.browser.json",
"build:copy": "node copyUntypedFiles.js", "build:copy": "node copyUntypedFiles.mjs",
"build:format": "prettier --config ../../.prettierrc --write \"lib/**/*.js\"" "build:format": "prettier --config ../../.prettierrc --write \"lib/**/*.js\""
}, },
"publishConfig": { "publishConfig": {

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -5,15 +5,15 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
const path = require('path'); import fs from 'fs-extra';
const fs = require('fs-extra'); import {fileURLToPath} from 'url';
/** /**
* Copy all untyped and static assets files to lib. * Copy all untyped and static assets files to lib.
*/ */
const srcDir = path.resolve(__dirname, 'src'); const srcDir = fileURLToPath(new URL('src', import.meta.url));
const libDir = path.resolve(__dirname, 'lib'); const libDir = fileURLToPath(new URL('lib', import.meta.url));
fs.copySync(srcDir, libDir, { await fs.copy(srcDir, libDir, {
filter(filepath) { filter(filepath) {
return !/__tests__/.test(filepath) && !/\.tsx?$/.test(filepath); return !/__tests__/.test(filepath) && !/\.tsx?$/.test(filepath);
}, },

View file

@ -8,7 +8,7 @@
"build": "yarn build:server && yarn build:browser && yarn build:copy", "build": "yarn build:server && yarn build:browser && yarn build:copy",
"build:server": "tsc --project tsconfig.server.json", "build:server": "tsc --project tsconfig.server.json",
"build:browser": "tsc --project tsconfig.browser.json", "build:browser": "tsc --project tsconfig.browser.json",
"build:copy": "node copyUntypedFiles.js" "build:copy": "node copyUntypedFiles.mjs"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -6,21 +6,20 @@
*/ */
import {merge} from 'lodash'; import {merge} from 'lodash';
import {ThemeConfigSchema, DEFAULT_CONFIG} from '../validateThemeConfig';
const {ThemeConfigSchema, DEFAULT_CONFIG} = require('../validateThemeConfig'); import {normalizeThemeConfig} from '@docusaurus/utils-validation';
import theme from 'prism-react-renderer/themes/github';
import darkTheme from 'prism-react-renderer/themes/dracula';
const {normalizeThemeConfig} = require('@docusaurus/utils-validation'); function testValidateThemeConfig(partialThemeConfig: Record<string, unknown>) {
const theme = require('prism-react-renderer/themes/github');
const darkTheme = require('prism-react-renderer/themes/dracula');
function testValidateThemeConfig(partialThemeConfig) {
return normalizeThemeConfig(ThemeConfigSchema, { return normalizeThemeConfig(ThemeConfigSchema, {
...DEFAULT_CONFIG, ...DEFAULT_CONFIG,
...partialThemeConfig, ...partialThemeConfig,
}); });
} }
function testOk(partialThemeConfig) { function testOk(partialThemeConfig: Record<string, unknown>) {
expect( expect(
testValidateThemeConfig({...DEFAULT_CONFIG, ...partialThemeConfig}), testValidateThemeConfig({...DEFAULT_CONFIG, ...partialThemeConfig}),
).toEqual({ ).toEqual({

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -5,15 +5,15 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
const path = require('path'); import fs from 'fs-extra';
const fs = require('fs-extra'); import {fileURLToPath} from 'url';
/** /**
* Copy all untyped and static assets files to lib. * Copy all untyped and static assets files to lib.
*/ */
const srcDir = path.resolve(__dirname, 'src'); const srcDir = fileURLToPath(new URL('src', import.meta.url));
const libDir = path.resolve(__dirname, 'lib'); const libDir = fileURLToPath(new URL('lib', import.meta.url));
fs.copySync(srcDir, libDir, { await fs.copy(srcDir, libDir, {
filter(filepath) { filter(filepath) {
return !/__tests__/.test(filepath) && !/\.tsx?$/.test(filepath); return !/__tests__/.test(filepath) && !/\.tsx?$/.test(filepath);
}, },

View file

@ -5,8 +5,8 @@
"main": "./lib/index.js", "main": "./lib/index.js",
"types": "./lib/index.d.ts", "types": "./lib/index.d.ts",
"scripts": { "scripts": {
"build": "node copyUntypedFiles.js && tsc", "build": "node copyUntypedFiles.mjs && tsc",
"watch": "node copyUntypedFiles.js && tsc --watch" "watch": "node copyUntypedFiles.mjs && tsc --watch"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,20 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const path = require('path');
const fs = require('fs-extra');
/**
* Copy all untyped and static assets files to lib.
*/
const srcDir = path.resolve(__dirname, 'src');
const libDir = path.resolve(__dirname, 'lib');
fs.copySync(srcDir, libDir, {
filter(filepath) {
return !/__tests__/.test(filepath) && !/\.tsx?$/.test(filepath);
},
});

View file

@ -0,0 +1,20 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import fs from 'fs-extra';
import {fileURLToPath} from 'url';
/**
* Copy all untyped and static assets files to lib.
*/
const srcDir = fileURLToPath(new URL('src', import.meta.url));
const libDir = fileURLToPath(new URL('lib', import.meta.url));
await fs.copy(srcDir, libDir, {
filter(filepath) {
return !/__tests__/.test(filepath) && !/\.tsx?$/.test(filepath);
},
});

View file

@ -7,8 +7,8 @@
"access": "public" "access": "public"
}, },
"scripts": { "scripts": {
"build": "tsc && node copyUntypedFiles.js", "build": "tsc && node copyUntypedFiles.mjs",
"watch": "node copyUntypedFiles.js && tsc --watch" "watch": "node copyUntypedFiles.mjs && tsc --watch"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,20 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const path = require('path');
const fs = require('fs-extra');
/**
* Copy all untyped and static assets files to lib.
*/
const srcDir = path.resolve(__dirname, 'src');
const libDir = path.resolve(__dirname, 'lib');
fs.copySync(srcDir, libDir, {
filter(filepath) {
return !/__tests__/.test(filepath) && !/\.tsx?$/.test(filepath);
},
});

View file

@ -0,0 +1,20 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import fs from 'fs-extra';
import {fileURLToPath} from 'url';
/**
* Copy all untyped and static assets files to lib.
*/
const srcDir = fileURLToPath(new URL('src', import.meta.url));
const libDir = fileURLToPath(new URL('lib', import.meta.url));
await fs.copy(srcDir, libDir, {
filter(filepath) {
return !/__tests__/.test(filepath) && !/\.tsx?$/.test(filepath);
},
});

View file

@ -21,7 +21,7 @@
"build": "yarn build:server && yarn build:browser && yarn build:copy", "build": "yarn build:server && yarn build:browser && yarn build:copy",
"build:server": "tsc --project tsconfig.server.json", "build:server": "tsc --project tsconfig.server.json",
"build:browser": "tsc --project tsconfig.browser.json", "build:browser": "tsc --project tsconfig.browser.json",
"build:copy": "node copyUntypedFiles.js" "build:copy": "node copyUntypedFiles.mjs"
}, },
"dependencies": { "dependencies": {
"@docsearch/react": "^3.0.0-alpha.39", "@docsearch/react": "^3.0.0-alpha.39",

View file

@ -5,10 +5,11 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
const {validateThemeConfig, DEFAULT_CONFIG} = require('../validateThemeConfig'); import type {Joi} from '@docusaurus/utils-validation';
import {validateThemeConfig, DEFAULT_CONFIG} from '../validateThemeConfig';
function testValidateThemeConfig(themeConfig) { function testValidateThemeConfig(themeConfig: Record<string, unknown>) {
function validate(schema, cfg) { function validate(schema: Joi.Schema, cfg: Record<string, unknown>) {
const {value, error} = schema.validate(cfg, { const {value, error} = schema.validate(cfg, {
convert: false, convert: false,
}); });

View file

@ -8,7 +8,7 @@
import {Joi} from '@docusaurus/utils-validation'; import {Joi} from '@docusaurus/utils-validation';
import type {ThemeConfig, Validate, ValidationResult} from '@docusaurus/types'; import type {ThemeConfig, Validate, ValidationResult} from '@docusaurus/types';
const DEFAULT_CONFIG = { export const DEFAULT_CONFIG = {
contextualSearch: false, // future: maybe we want to enable this by default contextualSearch: false, // future: maybe we want to enable this by default
// By default, all Docusaurus sites are using the same AppId // By default, all Docusaurus sites are using the same AppId
@ -17,7 +17,6 @@ const DEFAULT_CONFIG = {
searchParameters: {}, searchParameters: {},
}; };
exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
export const Schema = Joi.object({ export const Schema = Joi.object({
algolia: Joi.object({ algolia: Joi.object({

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -0,0 +1,47 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {extractThemeCodeMessages} from '../update';
import path from 'path';
import fs from 'fs-extra';
import {mapValues} from 'lodash';
// Seems the 5s default timeout fails sometimes
jest.setTimeout(15000);
describe('theme-translations package', () => {
test(`to have base messages files contain EXACTLY all the translations extracted from the theme. Please run "yarn workspace @docusaurus/theme-translations update" to keep base messages files up-to-date.`, async () => {
const baseMessagesDirPath = path.join(__dirname, '../locales/base');
const baseMessages = Object.fromEntries(
(
await Promise.all(
(
await fs.readdir(baseMessagesDirPath)
).map(async (baseMessagesFile) =>
Object.entries(
JSON.parse(
(
await fs.readFile(
path.join(baseMessagesDirPath, baseMessagesFile),
)
).toString(),
) as Record<string, string>,
),
),
)
)
.flat()
.filter(([key]) => !key.endsWith('___DESCRIPTION')),
);
const codeMessages = mapValues(
await extractThemeCodeMessages(),
(translation) => translation.message,
);
expect(codeMessages).toEqual(baseMessages);
});
});

View file

@ -0,0 +1,12 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import type {TranslationFileContent} from '@docusaurus/types';
export function extractThemeCodeMessages(
targetDirs?: string[],
): Promise<TranslationFileContent>;

View file

@ -1,42 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const {extractThemeCodeMessages} = require('./update');
const path = require('path');
const fs = require('fs-extra');
const {mapValues, pickBy} = require('lodash');
// Seems the 5s default timeout fails sometimes
jest.setTimeout(15000);
describe('theme-translations package', () => {
test(`to have base messages files contain EXACTLY all the translations extracted from the theme. Please run "yarn workspace @docusaurus/theme-translations update" to keep base messages files up-to-date.`, async () => {
const baseMessagesDirPath = path.join(__dirname, 'locales/base');
const baseMessages = pickBy(
await fs
.readdirSync(baseMessagesDirPath)
.reduce(async (messages, baseMessagesFile) => {
const newMessages = {
...(await messages),
...JSON.parse(
await fs.readFile(
path.join(baseMessagesDirPath, baseMessagesFile),
),
),
};
return newMessages;
}, {}),
(_, key) => !key.endsWith('___DESCRIPTION'),
);
const codeMessages = mapValues(
await extractThemeCodeMessages(),
(translation) => translation.message,
);
expect(codeMessages).toEqual(baseMessages);
});
});

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -1,20 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const path = require('path');
const fs = require('fs-extra');
/**
* Copy all untyped and static assets files to lib.
*/
const srcDir = path.resolve(__dirname, 'src');
const libDir = path.resolve(__dirname, 'lib');
fs.copySync(srcDir, libDir, {
filter(filepath) {
return !/__tests__/.test(filepath) && !/\.tsx?$/.test(filepath);
},
});

View file

@ -0,0 +1,20 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import fs from 'fs-extra';
import {fileURLToPath} from 'url';
/**
* Copy all untyped and static assets files to lib.
*/
const srcDir = fileURLToPath(new URL('src', import.meta.url));
const libDir = fileURLToPath(new URL('lib', import.meta.url));
await fs.copy(srcDir, libDir, {
filter(filepath) {
return !/__tests__/.test(filepath) && !/\.tsx?$/.test(filepath);
},
});

View file

@ -24,8 +24,8 @@
"docusaurus": "bin/docusaurus.js" "docusaurus": "bin/docusaurus.js"
}, },
"scripts": { "scripts": {
"build": "tsc && tsc -p tsconfig.client.json && node copyUntypedFiles.js", "build": "tsc && tsc -p tsconfig.client.json && node copyUntypedFiles.mjs",
"watch": "node copyUntypedFiles.js && concurrently -n \"server,client\" --kill-others \"tsc --watch\" \"tsc -p tsconfig.client.json --watch\"" "watch": "node copyUntypedFiles.mjs && concurrently -n \"server,client\" --kill-others \"tsc --watch\" \"tsc -p tsconfig.client.json --watch\""
}, },
"bugs": { "bugs": {
"url": "https://github.com/facebook/docusaurus/issues" "url": "https://github.com/facebook/docusaurus/issues"

View file

@ -1,4 +1,4 @@
copyUntypedFiles.js copyUntypedFiles.mjs
.tsbuildinfo .tsbuildinfo
tsconfig* tsconfig*
__tests__ __tests__

View file

@ -19,25 +19,12 @@ async function delay(ms) {
}); });
} }
async function run() { if (
if ( process.env.NETLIFY === 'true' &&
process.env.NETLIFY === 'true' && process.env.SITE_NAME === 'docusaurus-i18n-staging'
process.env.SITE_NAME === 'docusaurus-i18n-staging' ) {
) { console.log(
console.log( '[Crowdin] Delaying the docusaurus-i18n-staging deployment to avoid 409 errors',
'[Crowdin] Delaying the docusaurus-i18n-staging deployment to avoid 409 errors', );
); await delay(30000);
await delay(30000);
}
} }
run().then(
() => {
process.exit(0);
},
(e) => {
console.error(e.message);
console.error(e.stack);
process.exit(1);
},
);

View file

@ -12,11 +12,7 @@ const math = require('remark-math');
const katex = require('rehype-katex'); const katex = require('rehype-katex');
const VersionsArchived = require('./versionsArchived.json'); const VersionsArchived = require('./versionsArchived.json');
const {dogfoodingPluginInstances} = require('./_dogfooding/dogfooding.config'); const {dogfoodingPluginInstances} = require('./_dogfooding/dogfooding.config');
const FeatureRequestsPlugin = require('./src/featureRequests/FeatureRequestsPlugin');
const npm2yarn = require('@docusaurus/remark-plugin-npm2yarn'); const npm2yarn = require('@docusaurus/remark-plugin-npm2yarn');
const configTabs = require('./src/remark/configTabs');
const lightTheme = require('./src/utils/prismLight');
const darkTheme = require('./src/utils/prismDark');
const ArchivedVersionsDropdownItems = Object.entries(VersionsArchived).splice( const ArchivedVersionsDropdownItems = Object.entries(VersionsArchived).splice(
0, 0,
@ -120,7 +116,6 @@ const config = {
], ],
themes: ['live-codeblock'], themes: ['live-codeblock'],
plugins: [ plugins: [
FeatureRequestsPlugin,
[ [
'content-docs', 'content-docs',
/** @type {import('@docusaurus/plugin-content-docs').Options} */ /** @type {import('@docusaurus/plugin-content-docs').Options} */
@ -265,7 +260,7 @@ const config = {
}, },
showLastUpdateAuthor: true, showLastUpdateAuthor: true,
showLastUpdateTime: true, showLastUpdateTime: true,
remarkPlugins: [math, [npm2yarn, {sync: true}], configTabs], remarkPlugins: [math, [npm2yarn, {sync: true}]],
rehypePlugins: [katex], rehypePlugins: [katex],
disableVersioning: isVersioningDisabled, disableVersioning: isVersioningDisabled,
lastVersion: isDev || isDeployPreview ? 'current' : undefined, lastVersion: isDev || isDeployPreview ? 'current' : undefined,
@ -332,8 +327,6 @@ const config = {
content: `⭐️ If you like Docusaurus, give it a star on <a target="_blank" rel="noopener noreferrer" href="https://github.com/facebook/docusaurus">GitHub</a> and follow us on <a target="_blank" rel="noopener noreferrer" href="https://twitter.com/docusaurus" >Twitter</a> ${TwitterSvg}`, content: `⭐️ If you like Docusaurus, give it a star on <a target="_blank" rel="noopener noreferrer" href="https://github.com/facebook/docusaurus">GitHub</a> and follow us on <a target="_blank" rel="noopener noreferrer" href="https://twitter.com/docusaurus" >Twitter</a> ${TwitterSvg}`,
}, },
prism: { prism: {
theme: lightTheme,
darkTheme,
// We need to load markdown again so that YAML is loaded before MD // We need to load markdown again so that YAML is loaded before MD
// and the YAML front matter is highlighted correctly. // and the YAML front matter is highlighted correctly.
// TODO after we have forked prism-react-renderer, we should tweak the // TODO after we have forked prism-react-renderer, we should tweak the
@ -519,11 +512,18 @@ const config = {
}), }),
}; };
// TODO temporary dogfood async config, remove soon
async function createConfig() { async function createConfig() {
await new Promise((resolve) => { const FeatureRequestsPlugin = (await import('./src/featureRequests/FeatureRequestsPlugin.mjs')).default;
setTimeout(resolve, 0); const configTabs = (await import('./src/remark/configTabs.mjs')).default;
}); const lightTheme = (await import('./src/utils/prismLight.mjs')).default;
const darkTheme = (await import('./src/utils/prismDark.mjs')).default;
config.plugins?.push(FeatureRequestsPlugin);
// @ts-expect-error: we know it exists, right
config.presets[0][1].docs.remarkPlugins.push(configTabs);
// @ts-expect-error: we know it exists, right
config.themeConfig.prism.theme = lightTheme;
// @ts-expect-error: we know it exists, right
config.themeConfig.prism.darkTheme = darkTheme;
return config; return config;
} }

View file

@ -10,7 +10,7 @@
"deploy": "docusaurus deploy", "deploy": "docusaurus deploy",
"clear": "docusaurus clear", "clear": "docusaurus clear",
"serve": "docusaurus serve", "serve": "docusaurus serve",
"test:css-order": "node testCSSOrder.js", "test:css-order": "node testCSSOrder.mjs",
"write-translations": "docusaurus write-translations", "write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids", "write-heading-ids": "docusaurus write-heading-ids",
"start:baseUrl": "cross-env BASE_URL='/build/' yarn start", "start:baseUrl": "cross-env BASE_URL='/build/' yarn start",
@ -20,8 +20,8 @@
"build:fast": "cross-env BUILD_FAST=true yarn build --locale en", "build:fast": "cross-env BUILD_FAST=true yarn build --locale en",
"netlify:build:production": "yarn docusaurus write-translations && yarn netlify:crowdin:delay && yarn netlify:crowdin:uploadSources && yarn netlify:crowdin:downloadTranslations && yarn build && yarn test:css-order", "netlify:build:production": "yarn docusaurus write-translations && yarn netlify:crowdin:delay && yarn netlify:crowdin:uploadSources && yarn netlify:crowdin:downloadTranslations && yarn build && yarn test:css-order",
"netlify:build:deployPreview": "yarn docusaurus write-translations --locale fr --messagePrefix '(fr) ' && yarn build && yarn test:css-order", "netlify:build:deployPreview": "yarn docusaurus write-translations --locale fr --messagePrefix '(fr) ' && yarn build && yarn test:css-order",
"netlify:crowdin:delay": "node delayCrowdin.js", "netlify:crowdin:delay": "node delayCrowdin.mjs",
"netlify:crowdin:wait": "node waitForCrowdin.js", "netlify:crowdin:wait": "node waitForCrowdin.mjs",
"netlify:crowdin:downloadTranslations": "yarn netlify:crowdin:wait && yarn --cwd .. crowdin:download:website", "netlify:crowdin:downloadTranslations": "yarn netlify:crowdin:wait && yarn --cwd .. crowdin:download:website",
"netlify:crowdin:downloadTranslationsFailSafe": "yarn netlify:crowdin:wait && (yarn --cwd .. crowdin:download:website || echo 'Crowdin translation download failure (only internal PRs have access to the Crowdin env token)')", "netlify:crowdin:downloadTranslationsFailSafe": "yarn netlify:crowdin:wait && (yarn --cwd .. crowdin:download:website || echo 'Crowdin translation download failure (only internal PRs have access to the Crowdin env token)')",
"netlify:crowdin:uploadSources": "yarn --cwd .. crowdin:upload:website", "netlify:crowdin:uploadSources": "yarn --cwd .. crowdin:upload:website",

View file

@ -5,17 +5,20 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
const {normalizeUrl} = require('@docusaurus/utils'); import utils from '@docusaurus/utils';
/** /**
* @param {import('@docusaurus/types').LoadContext} context * @param {import('@docusaurus/types').LoadContext} context
* @returns {import('@docusaurus/types').Plugin} * @returns {import('@docusaurus/types').Plugin}
*/ */
function FeatureRequestsPlugin(context) { export default function FeatureRequestsPlugin(context) {
return { return {
name: 'feature-requests-plugin', name: 'feature-requests-plugin',
async contentLoaded({actions}) { async contentLoaded({actions}) {
const basePath = normalizeUrl([context.baseUrl, '/feature-requests']); const basePath = utils.normalizeUrl([
context.baseUrl,
'/feature-requests',
]);
await actions.createData('paths.json', JSON.stringify(basePath)); await actions.createData('paths.json', JSON.stringify(basePath));
actions.addRoute({ actions.addRoute({
path: basePath, path: basePath,
@ -28,5 +31,3 @@ function FeatureRequestsPlugin(context) {
}, },
}; };
} }
module.exports = FeatureRequestsPlugin;

View file

@ -5,12 +5,12 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
const visit = require('unist-util-visit'); import visit from 'unist-util-visit';
/** /**
* Turns a "```js config-tabs" code block into a "plugin options" and a "preset options" tab * Turns a "```js config-tabs" code block into a "plugin options" and a "preset options" tab
*/ */
const plugin = () => { export default function plugin() {
const transformer = (root) => { const transformer = (root) => {
let tabsImported = false; let tabsImported = false;
let codeBlockImported = false; let codeBlockImported = false;
@ -165,6 +165,4 @@ const plugin = () => {
} }
}; };
return transformer; return transformer;
}; }
module.exports = plugin;

View file

@ -6,9 +6,9 @@
*/ */
// eslint-disable-next-line import/no-extraneous-dependencies // eslint-disable-next-line import/no-extraneous-dependencies
const darkTheme = require('prism-react-renderer/themes/vsDark'); import darkTheme from 'prism-react-renderer/themes/vsDark/index.cjs.js';
module.exports = { export default {
plain: { plain: {
color: '#D4D4D4', color: '#D4D4D4',
backgroundColor: '#1E1E1E', backgroundColor: '#1E1E1E',

View file

@ -6,9 +6,9 @@
*/ */
// eslint-disable-next-line import/no-extraneous-dependencies // eslint-disable-next-line import/no-extraneous-dependencies
const lightTheme = require('prism-react-renderer/themes/github'); import lightTheme from 'prism-react-renderer/themes/github/index.cjs.js';
module.exports = { export default {
...lightTheme, ...lightTheme,
styles: [ styles: [
...lightTheme.styles, ...lightTheme.styles,

View file

@ -5,8 +5,10 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
const path = require('path'); import path from 'path';
const fs = require('fs'); import {fileURLToPath} from 'url';
// eslint-disable-next-line import/no-extraneous-dependencies
import fs from 'fs-extra';
/* /*
This verifies CSS ordering on the Docusaurus site itself, This verifies CSS ordering on the Docusaurus site itself,
@ -51,11 +53,11 @@ const EXPECTED_CSS_MARKERS = [
'.DocSearch-Modal', '.DocSearch-Modal',
]; ];
const cssDirName = path.join(__dirname, 'build', 'assets', 'css'); const cssDirName = fileURLToPath(new URL('build/assets/css', import.meta.url));
const cssFileNames = fs const cssFileNames = (await fs.readdir(cssDirName)).filter((file) =>
.readdirSync(cssDirName) file.endsWith('.css'),
.filter((file) => file.endsWith('.css')); );
if (cssFileNames.length !== 1) { if (cssFileNames.length !== 1) {
throw new Error('unexpected: more than 1 css file'); throw new Error('unexpected: more than 1 css file');
@ -64,7 +66,7 @@ const cssFile = path.join(cssDirName, cssFileNames[0]);
console.log('Inspecting CSS file for test CSS markers', cssFile); console.log('Inspecting CSS file for test CSS markers', cssFile);
const cssFileContent = fs.readFileSync(cssFile, 'utf8'); const cssFileContent = await fs.readFile(cssFile, 'utf8');
const cssMarkersWithPositions = EXPECTED_CSS_MARKERS.map((marker) => { const cssMarkersWithPositions = EXPECTED_CSS_MARKERS.map((marker) => {
const position = cssFileContent.indexOf(marker); const position = cssFileContent.indexOf(marker);
@ -88,8 +90,7 @@ const sortBy = (key) => (a, b) =>
// eslint-disable-next-line no-nested-ternary // eslint-disable-next-line no-nested-ternary
a[key] > b[key] ? 1 : b[key] > a[key] ? -1 : 0; a[key] > b[key] ? 1 : b[key] > a[key] ? -1 : 0;
const sortedCSSMarkers = cssMarkersWithPositions const sortedCSSMarkers = [...cssMarkersWithPositions]
.concat()
.sort(sortBy('position')) .sort(sortBy('position'))
.map(({marker}) => marker); .map(({marker}) => marker);

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
const {Translations} = require('@crowdin/crowdin-api-client'); import {Translations} from '@crowdin/crowdin-api-client';
/* /*
Crowdin does not support concurrent "project builds" (downloads of translations). Crowdin does not support concurrent "project builds" (downloads of translations).
@ -24,9 +24,7 @@ const timeout = 5 * 60 * 1000;
const projectId = 428890; const projectId = 428890;
const token = process.env.CROWDIN_PERSONAL_TOKEN; // set on Netlify const token = process.env.CROWDIN_PERSONAL_TOKEN; // set on Netlify
const translations = new Translations({ const translations = new Translations({token});
token,
});
async function delay(ms) { async function delay(ms) {
return new Promise((resolve) => { return new Promise((resolve) => {
@ -39,35 +37,23 @@ async function hasBuildInProgress() {
return projectBuilds.data.some((build) => build.data.status === 'inProgress'); return projectBuilds.data.some((build) => build.data.status === 'inProgress');
} }
async function run() { const timeBefore = Date.now();
const timeBefore = Date.now();
// eslint-disable-next-line no-constant-condition
while (true) {
if (Date.now() - timeBefore > timeout) {
console.warn(
'[Crowdin] Timeout of wait script reached => will try to proceed but download translations is likely to fail...',
);
break;
}
const inProgress = await hasBuildInProgress(); // eslint-disable-next-line no-constant-condition
if (inProgress) { while (true) {
console.log('[Crowdin] A build is still in progress => waiting...'); if (Date.now() - timeBefore > timeout) {
await delay(pollInterval); console.warn(
} else { '[Crowdin] Timeout of wait script reached => will try to proceed but download translations is likely to fail...',
console.warn('[Crowdin] No build in progress => lets continue'); );
break; break;
} }
const inProgress = await hasBuildInProgress();
if (inProgress) {
console.log('[Crowdin] A build is still in progress => waiting...');
await delay(pollInterval);
} else {
console.warn("[Crowdin] No build in progress => let's continue");
break;
} }
} }
run().then(
() => {
process.exit(0);
},
(e) => {
console.error(e.message);
console.error(e.stack);
process.exit(1);
},
);

View file

@ -6561,10 +6561,10 @@ color@^4.0.1:
color-convert "^2.0.1" color-convert "^2.0.1"
color-string "^1.6.0" color-string "^1.6.0"
colord@^2.9.1: colord@^2.9.1, colord@^2.9.2:
version "2.9.1" version "2.9.2"
resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.1.tgz#c961ea0efeb57c9f0f4834458f26cb9cc4a3f90e" resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.2.tgz#25e2bacbbaa65991422c07ea209e2089428effb1"
integrity sha512-4LBMSt09vR0uLnPVkOUBnmxgoaeN4ewRbx801wY/bXcltXfpR/G46OdWn96XpYmCWuYvO46aBZP4NgX8HpNAcw== integrity sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==
colorette@^2.0.10, colorette@^2.0.16: colorette@^2.0.10, colorette@^2.0.16:
version "2.0.16" version "2.0.16"
@ -7415,10 +7415,10 @@ debug@3.1.0:
dependencies: dependencies:
ms "2.0.0" ms "2.0.0"
debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2: debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3:
version "4.3.2" version "4.3.3"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
dependencies: dependencies:
ms "2.1.2" ms "2.1.2"
@ -10642,10 +10642,10 @@ ignore@^4.0.3, ignore@^4.0.6:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8: ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8, ignore@^5.2.0:
version "5.1.9" version "5.2.0"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.9.tgz#9ec1a5cbe8e1446ec60d4420060d43aa6e7382fb" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
integrity sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ== integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
image-q@^1.1.1: image-q@^1.1.1:
version "1.1.1" version "1.1.1"
@ -12194,6 +12194,11 @@ known-css-properties@^0.21.0:
resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.21.0.tgz#15fbd0bbb83447f3ce09d8af247ed47c68ede80d" resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.21.0.tgz#15fbd0bbb83447f3ce09d8af247ed47c68ede80d"
integrity sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw== integrity sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw==
known-css-properties@^0.24.0:
version "0.24.0"
resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.24.0.tgz#19aefd85003ae5698a5560d2b55135bf5432155c"
integrity sha512-RTSoaUAfLvpR357vWzAz/50Q/BmHfmE6ETSWfutT0AJiw10e6CmcdYRQJlLRd95B53D0Y2aD1jSxD3V3ySF+PA==
kuler@^2.0.0: kuler@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3"
@ -15360,6 +15365,11 @@ postcss-safe-parser@^4.0.2:
dependencies: dependencies:
postcss "^7.0.26" postcss "^7.0.26"
postcss-safe-parser@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz#bb4c29894171a94bc5c996b9a30317ef402adaa1"
integrity sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==
postcss-sass@^0.4.4: postcss-sass@^0.4.4:
version "0.4.4" version "0.4.4"
resolved "https://registry.yarnpkg.com/postcss-sass/-/postcss-sass-0.4.4.tgz#91f0f3447b45ce373227a98b61f8d8f0785285a3" resolved "https://registry.yarnpkg.com/postcss-sass/-/postcss-sass-0.4.4.tgz#91f0f3447b45ce373227a98b61f8d8f0785285a3"
@ -15375,10 +15385,10 @@ postcss-scss@^2.1.1:
dependencies: dependencies:
postcss "^7.0.6" postcss "^7.0.6"
postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5: postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.7:
version "6.0.6" version "6.0.8"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz#f023ed7a9ea736cd7ef70342996e8e78645a7914"
integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== integrity sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ==
dependencies: dependencies:
cssesc "^3.0.0" cssesc "^3.0.0"
util-deprecate "^1.0.2" util-deprecate "^1.0.2"
@ -18001,7 +18011,7 @@ stylehacks@^5.0.1:
browserslist "^4.16.0" browserslist "^4.16.0"
postcss-selector-parser "^6.0.4" postcss-selector-parser "^6.0.4"
stylelint@^13.10.0, stylelint@^13.2.1: stylelint@^13.2.1:
version "13.13.1" version "13.13.1"
resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-13.13.1.tgz#fca9c9f5de7990ab26a00f167b8978f083a18f3c" resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-13.13.1.tgz#fca9c9f5de7990ab26a00f167b8978f083a18f3c"
integrity sha512-Mv+BQr5XTUrKqAXmpqm6Ddli6Ief+AiPZkRsIrAoUKFuq/ElkUh9ZMYxXD0iQNZ5ADghZKLOWz1h7hTClB7zgQ== integrity sha512-Mv+BQr5XTUrKqAXmpqm6Ddli6Ief+AiPZkRsIrAoUKFuq/ElkUh9ZMYxXD0iQNZ5ADghZKLOWz1h7hTClB7zgQ==
@ -18055,6 +18065,51 @@ stylelint@^13.10.0, stylelint@^13.2.1:
v8-compile-cache "^2.3.0" v8-compile-cache "^2.3.0"
write-file-atomic "^3.0.3" write-file-atomic "^3.0.3"
stylelint@^14.2.0:
version "14.2.0"
resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-14.2.0.tgz#da4f0f4580e66911c38c376ed82447b78e32b0fb"
integrity sha512-i0DrmDXFNpDsWiwx6SPRs4/pyw4kvZgqpDGvsTslQMY7hpUl6r33aQvNSn6cnTg2wtZ9rreFElI7XAKpOWi1vQ==
dependencies:
balanced-match "^2.0.0"
colord "^2.9.2"
cosmiconfig "^7.0.1"
debug "^4.3.3"
execall "^2.0.0"
fast-glob "^3.2.7"
fastest-levenshtein "^1.0.12"
file-entry-cache "^6.0.1"
get-stdin "^8.0.0"
global-modules "^2.0.0"
globby "^11.0.4"
globjoin "^0.1.4"
html-tags "^3.1.0"
ignore "^5.2.0"
import-lazy "^4.0.0"
imurmurhash "^0.1.4"
is-plain-object "^5.0.0"
known-css-properties "^0.24.0"
mathml-tag-names "^2.1.3"
meow "^9.0.0"
micromatch "^4.0.4"
normalize-path "^3.0.0"
normalize-selector "^0.2.0"
picocolors "^1.0.0"
postcss "^8.3.11"
postcss-media-query-parser "^0.2.3"
postcss-resolve-nested-selector "^0.1.1"
postcss-safe-parser "^6.0.0"
postcss-selector-parser "^6.0.7"
postcss-value-parser "^4.1.0"
resolve-from "^5.0.0"
specificity "^0.4.1"
string-width "^4.2.3"
strip-ansi "^6.0.1"
style-search "^0.1.0"
svg-tags "^1.0.0"
table "^6.7.5"
v8-compile-cache "^2.3.0"
write-file-atomic "^3.0.3"
sugarss@^2.0.0: sugarss@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-2.0.0.tgz#ddd76e0124b297d40bf3cca31c8b22ecb43bc61d" resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-2.0.0.tgz#ddd76e0124b297d40bf3cca31c8b22ecb43bc61d"
@ -18142,10 +18197,10 @@ symbol-tree@^3.2.4:
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
table@^6.6.0: table@^6.6.0, table@^6.7.5:
version "6.7.3" version "6.8.0"
resolved "https://registry.yarnpkg.com/table/-/table-6.7.3.tgz#255388439715a738391bd2ee4cbca89a4d05a9b7" resolved "https://registry.yarnpkg.com/table/-/table-6.8.0.tgz#87e28f14fa4321c3377ba286f07b79b281a3b3ca"
integrity sha512-5DkIxeA7XERBqMwJq0aHZOdMadBx4e6eDoFRuyT5VR82J0Ycg2DwM6GfA/EQAhJ+toRTaS1lIdSQCqgrmhPnlw== integrity sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==
dependencies: dependencies:
ajv "^8.0.1" ajv "^8.0.1"
lodash.truncate "^4.4.2" lodash.truncate "^4.4.2"