Fix ESLint config (#38)
* Add support for Azure DevOps and BitBucket * Remove `console.log` * Fix ESLint config - Fix the ESLint config - Fix all lint errors that cropped up as a result - Add scripts to lint - Add prettier format script - Add `husky` / `lint-staged` to lint/format files when they're pushed * Move provider configs to new file as requested * Fixes to meet maintainers specs * Fix remaining lint warns/errs * eslint fix * Update eslint/prettier packges Remove unused `@types/node-fetch` package * Add `eslint-plugin-jsdoc` * Add eslint rule for allowing providers to reassign params in their `replaceIcon` functions * Add sensible defaults for prettier to override any local editor settings * Some final cleanup * Loosen the required engines to allow for easier installing Co-authored-by: Claudio Santos <Claudiohbsantos@users.noreply.github.com>
This commit is contained in:
parent
b626e990aa
commit
05f9f8c057
2
.eslintignore
Normal file
2
.eslintignore
Normal file
@ -0,0 +1,2 @@
|
||||
dist
|
||||
node_modules
|
@ -1,11 +1,38 @@
|
||||
{
|
||||
"extends": ["airbnb", "prettier"],
|
||||
"plugins": ["prettier"],
|
||||
"rules": {
|
||||
"prettier/prettier": ["error"]
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true,
|
||||
"node": true
|
||||
},
|
||||
"globals": {
|
||||
"window": true,
|
||||
"document": true
|
||||
"chrome": "readonly"
|
||||
},
|
||||
"extends": ["airbnb-base", "plugin:jsdoc/recommended", "prettier"],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 12,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"no-use-before-define": ["error", { "functions": false }],
|
||||
"jsdoc/require-jsdoc": "off"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["scripts/*.js", "svgo.config.js"],
|
||||
"parserOptions": {
|
||||
"sourceType": "script"
|
||||
},
|
||||
"rules": {
|
||||
"import/no-extraneous-dependencies": "off",
|
||||
"import/no-dynamic-require": "off",
|
||||
"no-console": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["src/providers/*.js"],
|
||||
"rules": {
|
||||
"no-param-reassign": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
3
.github/workflows/update-from-upstream.yml
vendored
3
.github/workflows/update-from-upstream.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16.13.0"
|
||||
node-version: '16.13.0'
|
||||
|
||||
- name: Fetch release version
|
||||
id: upstream
|
||||
@ -64,4 +64,3 @@ jobs:
|
||||
if: steps.upstream.outputs.release_tag != steps.upstream.outputs.current_tag
|
||||
continue-on-error: true
|
||||
run: npx web-ext sign -s ./dist/firefox/ --channel=listed --api-key=${{ secrets.FIREFOX_API_JWT_ISSUER }} --api-secret=${{ secrets.FIREFOX_API_JWT_SECRET }}
|
||||
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,4 +17,5 @@ node_modules
|
||||
.cache/
|
||||
.vscode/
|
||||
.DS_Store
|
||||
.eslintcache
|
||||
Thumbs.db
|
||||
|
1
.husky/.gitignore
vendored
Normal file
1
.husky/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
_
|
4
.husky/pre-commit
Executable file
4
.husky/pre-commit
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
4
.prettierignore
Normal file
4
.prettierignore
Normal file
@ -0,0 +1,4 @@
|
||||
.cache
|
||||
dist
|
||||
src/*.json
|
||||
!src/manifest.json
|
@ -1,4 +1,13 @@
|
||||
{
|
||||
"printWidth": 100,
|
||||
"singleQuote": true
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"quoteProps": "as-needed",
|
||||
"trailingComma": "es5",
|
||||
"bracketSpacing": true,
|
||||
"arrowParens": "always",
|
||||
"proseWrap": "preserve",
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
|
5838
package-lock.json
generated
5838
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
30
package.json
30
package.json
@ -14,27 +14,29 @@
|
||||
"url": "https://github.com/Claudiohbsantos/github-material-icons-extension/issues"
|
||||
},
|
||||
"engines": {
|
||||
"node": "16.13.0",
|
||||
"npm": "8.1.0"
|
||||
"node": "^16.0.0",
|
||||
"npm": "^8.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"selector-observer": "2.1.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@octokit/core": "3.5.1",
|
||||
"@types/node-fetch": "2.5.11",
|
||||
"compare-versions": "3.6.0",
|
||||
"eslint": "7.29.0",
|
||||
"eslint-config": "0.3.0",
|
||||
"eslint-config-airbnb": "18.2.1",
|
||||
"eslint-config-prettier": "8.3.0",
|
||||
"eslint-plugin-prettier": "3.4.0",
|
||||
"eslint": "8.18.0",
|
||||
"eslint-config-airbnb-base": "15.0.0",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"eslint-plugin-import": "2.26.0",
|
||||
"eslint-plugin-jsdoc": "39.3.3",
|
||||
"follow-redirects": "1.14.1",
|
||||
"fs-extra": "10.0.0",
|
||||
"husky": "8.0.1",
|
||||
"json-stable-stringify": "1.0.1",
|
||||
"lint-staged": "13.0.3",
|
||||
"node-fetch": "2.6.1",
|
||||
"npm-run-all": "4.1.5",
|
||||
"parcel-bundler": "1.12.5",
|
||||
"prettier": "2.3.1",
|
||||
"prettier": "2.7.1",
|
||||
"rimraf": "3.0.2",
|
||||
"sharp": "0.28.3",
|
||||
"simple-git": "2.40.0",
|
||||
@ -59,6 +61,14 @@
|
||||
"update-upstream-version": "node ./scripts/update-upstream-version",
|
||||
"update-package-version": "npm version --no-git-tag-version",
|
||||
"update": "run-s update-upstream-version \"update-package-version patch\" update-manifest-version build",
|
||||
"release": "run-s \"update-package-version {1}\" update-manifest-version build --"
|
||||
"release": "run-s \"update-package-version {1}\" update-manifest-version build --",
|
||||
"lint": "eslint .",
|
||||
"lint-fix": "eslint --fix .",
|
||||
"format": "prettier --write --ignore-unknown .",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": "eslint --fix",
|
||||
"*": "prettier --write --ignore-unknown"
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,16 @@
|
||||
{
|
||||
"extends": [
|
||||
"config:base"
|
||||
],
|
||||
"extends": ["config:base"],
|
||||
"lockFileMaintenance": {
|
||||
"enabled": false
|
||||
},
|
||||
"packageRules": [
|
||||
{
|
||||
"packageNames": [
|
||||
"npm"
|
||||
],
|
||||
"packageNames": ["npm"],
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"matchManagers": [
|
||||
"npm"
|
||||
],
|
||||
"matchDepTypes": [
|
||||
"devDependencies"
|
||||
],
|
||||
"matchManagers": ["npm"],
|
||||
"matchDepTypes": ["devDependencies"],
|
||||
"enabled": false
|
||||
}
|
||||
]
|
||||
|
@ -5,7 +5,7 @@ const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
const rimraf = require('rimraf');
|
||||
const simpleGit = require('simple-git');
|
||||
const child_process = require('child_process');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
/**
|
||||
* Internal depedencies
|
||||
@ -13,7 +13,7 @@ const child_process = require('child_process');
|
||||
const srcPath = path.resolve(__dirname, '..', 'src');
|
||||
const vsExtPath = path.resolve(__dirname, '..', 'temp');
|
||||
const destSVGPath = path.resolve(__dirname, '..', 'svg');
|
||||
const commitLockPath = path.resolve(__dirname, '..', 'upstream.commit')
|
||||
const commitLockPath = path.resolve(__dirname, '..', 'upstream.commit');
|
||||
|
||||
const vsExtExecOptions = {
|
||||
cwd: vsExtPath,
|
||||
@ -27,7 +27,7 @@ const distIconsExecOptions = {
|
||||
async function main() {
|
||||
rimraf.sync(vsExtPath);
|
||||
rimraf.sync(destSVGPath);
|
||||
await fs.ensureDir(destSVGPath)
|
||||
await fs.ensureDir(destSVGPath);
|
||||
|
||||
console.log('[1/7] Cloning PKief/vscode-material-icon-theme into temporary cache.');
|
||||
const git = simpleGit();
|
||||
@ -36,25 +36,25 @@ async function main() {
|
||||
'100', // fetch only last 100 commits. Guesswork, could be too shallow if upstream doesnt release often
|
||||
]);
|
||||
|
||||
const commit = fs.readFileSync(commitLockPath, {encoding: 'utf8'})?.trim()
|
||||
console.log('Checking out to upstream commit:', commit)
|
||||
const upstreamGit = simpleGit(vsExtPath)
|
||||
await upstreamGit.checkout(commit, ['--force'])
|
||||
const commit = fs.readFileSync(commitLockPath, { encoding: 'utf8' })?.trim();
|
||||
console.log('Checking out to upstream commit:', commit);
|
||||
const upstreamGit = simpleGit(vsExtPath);
|
||||
await upstreamGit.checkout(commit, ['--force']);
|
||||
|
||||
console.log('[2/7] Terminate Git repository in temporary cache.');
|
||||
rimraf.sync(path.resolve(vsExtPath, '.git'));
|
||||
|
||||
console.log('[3/7] Install NPM dependencies for VSC extension.');
|
||||
child_process.execSync(`npm install --ignore-scripts`, vsExtExecOptions);
|
||||
execSync(`npm install --ignore-scripts`, vsExtExecOptions);
|
||||
|
||||
console.log('[4/7] Terminate Git tracking in temporary cache.');
|
||||
await fs.copy(path.resolve(vsExtPath, 'icons'), path.resolve(destSVGPath));
|
||||
|
||||
console.log('[5/7] Optimise extension icons using SVGO.');
|
||||
child_process.execSync(`npx svgo -r .`, distIconsExecOptions);
|
||||
execSync(`npx svgo -r .`, distIconsExecOptions);
|
||||
|
||||
console.log('[6/7] Run build tasks for VSC extension.');
|
||||
child_process.execSync(`npm run build`, vsExtExecOptions);
|
||||
execSync(`npm run build`, vsExtExecOptions);
|
||||
|
||||
console.log('[7/7] Copy file icon configuration to source code directory.');
|
||||
await fs.copy(
|
||||
@ -65,4 +65,4 @@ async function main() {
|
||||
rimraf.sync(vsExtPath);
|
||||
}
|
||||
|
||||
main()
|
||||
main();
|
||||
|
@ -21,13 +21,11 @@ fs.ensureDir(iconsPath).then(generateIcons);
|
||||
* @since 1.4.0
|
||||
*/
|
||||
function generateIcons() {
|
||||
targetSizes.map((size) => {
|
||||
targetSizes.forEach((size) => {
|
||||
sharp(svgPath)
|
||||
.png()
|
||||
.resize({ width: size, height: size })
|
||||
.toFile(`${iconsPath}/icon-${size}.png`)
|
||||
.catch(function (err) {
|
||||
console.log(err);
|
||||
});
|
||||
.catch(console.error);
|
||||
});
|
||||
}
|
||||
|
@ -4,9 +4,9 @@ const api = require('@octokit/core');
|
||||
const fs = require('fs-extra');
|
||||
const fr = require('follow-redirects');
|
||||
const glob = require('glob');
|
||||
const stringify = require('json-stable-stringify');
|
||||
const remap = require('./remap.json');
|
||||
const iconMap = require('../src/icon-map.json');
|
||||
const stringify = require('json-stable-stringify');
|
||||
|
||||
const vsDataPath = path.resolve(__dirname, '..', 'data');
|
||||
const srcPath = path.resolve(__dirname, '..', 'src');
|
||||
@ -20,7 +20,7 @@ const resultsPerPage = 100; // max 100
|
||||
let index = 0;
|
||||
let total;
|
||||
let items = [];
|
||||
let languages = [];
|
||||
const languages = [];
|
||||
|
||||
console.log('[1/7] Querying Github API for official VSC language contributions.');
|
||||
|
||||
@ -42,7 +42,8 @@ const GITHUB_RATELIMIT = 6000;
|
||||
octokit.request('GET /search/code', query).then(
|
||||
(res) => {
|
||||
if (!res.data) throw new Error();
|
||||
query.page = index++;
|
||||
query.page = index;
|
||||
index += 1;
|
||||
total = total || res.data.total_count;
|
||||
items = items.concat(res.data.items);
|
||||
if (resultsPerPage * index >= total) {
|
||||
@ -69,7 +70,7 @@ function fetchLanguageContribution(item) {
|
||||
const extPath = path.join(item.repository.name, resPath);
|
||||
const extDir = path.dirname(extPath);
|
||||
if (/sample|template/.test(extDir)) {
|
||||
total--;
|
||||
total -= 1;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@ -79,7 +80,7 @@ function fetchLanguageContribution(item) {
|
||||
.get(urlPath, (res) => {
|
||||
res.pipe(extFile);
|
||||
res.on('end', () => {
|
||||
index++;
|
||||
index += 1;
|
||||
if (index === total) {
|
||||
console.log('[3/7] Loading VSC language contributions into Node.');
|
||||
glob(path.join(vsDataPath, '**', 'extension.json'), (err, matches) => {
|
||||
@ -92,7 +93,7 @@ function fetchLanguageContribution(item) {
|
||||
})
|
||||
.on('error', (err) => {
|
||||
fs.unlink(extPath);
|
||||
throw new Error(err);
|
||||
throw err;
|
||||
});
|
||||
});
|
||||
} catch (reason) {
|
||||
@ -100,13 +101,13 @@ function fetchLanguageContribution(item) {
|
||||
}
|
||||
}
|
||||
|
||||
function loadLanguageContribution(path) {
|
||||
function loadLanguageContribution(filePath) {
|
||||
try {
|
||||
const data = JSON.parse(fs.readFileSync(path));
|
||||
const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
||||
data.contributes = data.contributes || {};
|
||||
data.contributes.languages = data.contributes.languages || [];
|
||||
languages.push(...data.contributes.languages);
|
||||
index++;
|
||||
index += 1;
|
||||
if (index === total) {
|
||||
console.log('[4/7] Processing language contributions for VSC File Icon API compatibility.');
|
||||
index = 0;
|
||||
@ -114,22 +115,21 @@ function loadLanguageContribution(path) {
|
||||
languages.forEach(processLanguageContribution);
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`${error} (${path})`);
|
||||
throw new Error(`${error} (${filePath})`);
|
||||
}
|
||||
}
|
||||
|
||||
function processLanguageContribution(lang) {
|
||||
delete lang.aliases;
|
||||
delete lang.configuration;
|
||||
delete lang.firstLine;
|
||||
function processLanguageContribution(language) {
|
||||
const { aliases, configuration, firstLine, ...lang } = language;
|
||||
|
||||
lang.extensions = lang.extensions || [];
|
||||
lang.filenames = lang.filenames || [];
|
||||
if (lang.filenamePatterns) {
|
||||
lang.filenamePatterns.forEach((ptn) => {
|
||||
if (/^\*\.[^*\/\?]+$/.test(ptn)) {
|
||||
if (/^\*\.[^*/?]+$/.test(ptn)) {
|
||||
lang.extensions.push(ptn.substring(1));
|
||||
}
|
||||
if (/^[^*\/\?]+$/.test(ptn)) {
|
||||
if (/^[^*/?]+$/.test(ptn)) {
|
||||
lang.filenames.push(ptn);
|
||||
}
|
||||
});
|
||||
@ -146,7 +146,7 @@ function processLanguageContribution(lang) {
|
||||
.map((ext) => ext.substring(1))
|
||||
.filter((ext) => !/\*|\/|\?/.test(ext));
|
||||
lang.filenames = lang.filenames.filter((name) => !/\*|\/|\?/.test(name));
|
||||
index++;
|
||||
index += 1;
|
||||
if (index === total) {
|
||||
console.log('[5/7] Mapping language contributions into file icon configuration.');
|
||||
index = 0;
|
||||
@ -162,55 +162,55 @@ const languageMap = {
|
||||
function mapLanguageContribution(lang) {
|
||||
lang.extensions.forEach((ext) => {
|
||||
let extIconName = lang.id;
|
||||
if (remap.extensions.hasOwnProperty(extIconName)) {
|
||||
let overrideIcon = remap.extensions[extIconName];
|
||||
if (remap.extensions[extIconName]) {
|
||||
const overrideIcon = remap.extensions[extIconName];
|
||||
if (typeof overrideIcon === 'object') {
|
||||
for (const [ptn, override] in Object.entries(overrideIcon)) {
|
||||
Object.entries(overrideIcon).forEach(([ptn, override]) => {
|
||||
if (ptn.startsWith('^') && ext.startsWith(ptn.substring(1))) {
|
||||
extIconName = override;
|
||||
}
|
||||
if (ptn.length && ext === ptn) {
|
||||
extIconName = override;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
extIconName = iconMap.languageIds[extIconName] || extIconName;
|
||||
}
|
||||
if (
|
||||
!remap.deletions[`extensions:${extIconName}`] &&
|
||||
!iconMap.fileExtensions.hasOwnProperty(extIconName) &&
|
||||
iconMap.iconDefinitions.hasOwnProperty(extIconName)
|
||||
!iconMap.fileExtensions[extIconName] &&
|
||||
iconMap.iconDefinitions[extIconName]
|
||||
) {
|
||||
languageMap.fileExtensions[ext] = extIconName;
|
||||
}
|
||||
});
|
||||
lang.filenames.forEach((name) => {
|
||||
let fileIconName = lang.id;
|
||||
if (remap.filenames.hasOwnProperty(fileIconName)) {
|
||||
let overrideIcon = remap.filenames[fileIconName];
|
||||
if (remap.filenames[fileIconName]) {
|
||||
const overrideIcon = remap.filenames[fileIconName];
|
||||
if (typeof overrideIcon === 'object') {
|
||||
for (const [ptn, override] in Object.entries(overrideIcon)) {
|
||||
Object.entries(overrideIcon).forEach(([ptn, override]) => {
|
||||
if (ptn.startsWith('^') && name.startsWith(ptn.substring(1))) {
|
||||
fileIconName = override;
|
||||
}
|
||||
if (ptn.length && name === ptn) {
|
||||
fileIconName = override;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
fileIconName = iconMap.languageIds[fileIconName] || fileIconName;
|
||||
}
|
||||
if (
|
||||
!remap.deletions[`filenames:${fileIconName}`] &&
|
||||
!iconMap.fileNames.hasOwnProperty(fileIconName) &&
|
||||
iconMap.iconDefinitions.hasOwnProperty(fileIconName)
|
||||
!iconMap.fileNames[fileIconName] &&
|
||||
iconMap.iconDefinitions[fileIconName]
|
||||
) {
|
||||
languageMap.fileNames[name] = fileIconName;
|
||||
}
|
||||
});
|
||||
index++;
|
||||
index += 1;
|
||||
if (index === total) {
|
||||
index = 0;
|
||||
generateLanguageMap();
|
||||
|
@ -1,14 +1,15 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
const Parcel = require('parcel-bundler');
|
||||
|
||||
const destSVGPath = path.resolve(__dirname, '..', 'svg');
|
||||
const distBasePath = path.resolve(__dirname, '..', 'dist');
|
||||
const srcPath = path.resolve(__dirname, '..', 'src');
|
||||
|
||||
/** Create icons cache. */
|
||||
function consolidateSVGFiles() {
|
||||
async function consolidateSVGFiles() {
|
||||
console.log('[1/2] Generate icon cache for extension.');
|
||||
return fs
|
||||
await fs
|
||||
.copy(path.resolve(srcPath, 'custom'), destSVGPath)
|
||||
.then(() => fs.readdir(destSVGPath))
|
||||
.then((files) => Object.fromEntries(files.map((filename) => [filename, filename])))
|
||||
@ -49,7 +50,8 @@ function buildManifest(distPath, manifestName) {
|
||||
function buildDist(name, manifestName) {
|
||||
const distPath = path.resolve(distBasePath, name);
|
||||
|
||||
return fs.ensureDir(distPath)
|
||||
return fs
|
||||
.ensureDir(distPath)
|
||||
.then(consolidateSVGFiles)
|
||||
.then(() => src(distPath))
|
||||
.then(() => buildManifest(distPath, manifestName))
|
||||
|
@ -11,10 +11,10 @@ const manifestPath = path.resolve(__dirname, '..', 'src', 'manifests', 'base.jso
|
||||
const manifest = require(manifestPath);
|
||||
|
||||
const updatedManifest = { ...manifest, version: package.version };
|
||||
const updatedManifestStr = JSON.stringify(updatedManifest, null, 2) + '\n';
|
||||
const updatedManifestStr = `${JSON.stringify(updatedManifest, null, 2)}\n`;
|
||||
|
||||
fs.writeFile(manifestPath, updatedManifestStr)
|
||||
.then(() => {
|
||||
console.log(`Updated manifest.json version to ${package.version}`);
|
||||
})
|
||||
.catch((err) => console.error(err));
|
||||
.catch(console.error);
|
||||
|
@ -2,7 +2,7 @@ const fetch = require('node-fetch');
|
||||
const path = require('path');
|
||||
const api = require('@octokit/core');
|
||||
const compareVersions = require('compare-versions');
|
||||
const fs = require('fs').promises;
|
||||
const fs = require('fs/promises');
|
||||
|
||||
const upstreamVersionFilePath = path.resolve(__dirname, '..', 'upstream.version');
|
||||
const upstreamCommitFilePath = path.resolve(__dirname, '..', 'upstream.commit');
|
||||
@ -11,6 +11,8 @@ const upstreamCommitFilePath = path.resolve(__dirname, '..', 'upstream.commit');
|
||||
* Gets latest VSCode Extension release version by parsing it's most recent 100 commit msgs
|
||||
*
|
||||
* returns version string or undefined
|
||||
*
|
||||
* @returns {Promise<string>} The current version of the upstream repository.
|
||||
*/
|
||||
const getUpstreamVersion = () =>
|
||||
fetch('https://raw.githubusercontent.com/PKief/vscode-material-icon-theme/main/package.json')
|
||||
@ -19,9 +21,12 @@ const getUpstreamVersion = () =>
|
||||
|
||||
const octokit = new api.Octokit();
|
||||
const getUpstreamCommit = () =>
|
||||
octokit.request('GET /repos/PKief/vscode-material-icon-theme/commits', {per_page: 1}).then(res => res.data?.[0].sha)
|
||||
octokit
|
||||
.request('GET /repos/PKief/vscode-material-icon-theme/commits', { per_page: 1 })
|
||||
.then((res) => res.data?.[0].sha);
|
||||
|
||||
const getLastUpstreamVersion = () => fs.readFile(upstreamVersionFilePath, { encoding: 'utf8' }).then(data => data.trim());
|
||||
const getLastUpstreamVersion = () =>
|
||||
fs.readFile(upstreamVersionFilePath, { encoding: 'utf8' }).then((data) => data.trim());
|
||||
|
||||
const updateReadmeBadge = async (version) => {
|
||||
const readmeFilePath = path.resolve(__dirname, '..', 'README.md');
|
||||
|
96
src/main.js
96
src/main.js
@ -6,19 +6,16 @@ import { observe } from 'selector-observer';
|
||||
/**
|
||||
* Internal depedencies.
|
||||
*/
|
||||
import iconsList from './icon-list';
|
||||
import iconMap from './icon-map';
|
||||
import languageMap from './language-map';
|
||||
|
||||
import iconsList from './icon-list.json';
|
||||
import iconMap from './icon-map.json';
|
||||
import languageMap from './language-map.json';
|
||||
import providerConfig from './providers';
|
||||
|
||||
// Expected configuration.
|
||||
iconMap.options = {
|
||||
...iconMap.options,
|
||||
...{
|
||||
activeIconPack: 'react_redux',
|
||||
// activeIconPack: 'nest', // TODO: implement interface to choose pack
|
||||
},
|
||||
};
|
||||
|
||||
// replacing all icons synchronously prevents visual "blinks" but can
|
||||
@ -32,7 +29,7 @@ const rushFirst = (rushBatch, callback) => {
|
||||
if (executions <= rushBatch) {
|
||||
callback(); // immediately run to prevent visual "blink"
|
||||
setTimeout(callback, 20); // run again later to catch any icons that are missed in large repositories
|
||||
executions++;
|
||||
executions += 1;
|
||||
} else {
|
||||
setTimeout(callback, 0); // run without blocking to prevent delayed rendering of large folders too much
|
||||
clearTimeout(timerID);
|
||||
@ -74,7 +71,7 @@ const gitProvider = getGitProvider();
|
||||
if (gitProvider) {
|
||||
observe(gitProvider.selectors.row, {
|
||||
add(row) {
|
||||
const callback = () => replaceIcon(row, iconMap, languageMap, gitProvider);
|
||||
const callback = () => replaceIcon(row, gitProvider);
|
||||
|
||||
rushFirst(90, callback);
|
||||
|
||||
@ -86,13 +83,11 @@ if (gitProvider) {
|
||||
/**
|
||||
* Replace file/folder icons.
|
||||
*
|
||||
* @param {String} itemRow Item Row.
|
||||
* @param {Object} iconMap Icon Map.
|
||||
* @param {Object} languageMap Language Map.
|
||||
* @param {Object} provider Git Provider specs.
|
||||
* @return {undefined}
|
||||
* @param {HTMLElement} itemRow Item Row.
|
||||
* @param {object} provider Git Provider specs.
|
||||
* @returns {undefined}
|
||||
*/
|
||||
function replaceIcon(itemRow, iconMap, languageMap, provider) {
|
||||
function replaceIcon(itemRow, provider) {
|
||||
const isLightTheme = provider.getIsLightTheme();
|
||||
|
||||
// Get file/folder name.
|
||||
@ -119,18 +114,16 @@ function replaceIcon(itemRow, iconMap, languageMap, provider) {
|
||||
fileExtension,
|
||||
isDir,
|
||||
isSubmodule,
|
||||
isSymlink,
|
||||
iconMap,
|
||||
languageMap
|
||||
isSymlink
|
||||
); // returns icon name if found or undefined.
|
||||
if (isLightTheme) {
|
||||
iconName = lookForLightMatch(iconName, fileName, fileExtension, isDir, iconMap); // returns icon name if found for light mode or undefined.
|
||||
iconName = lookForLightMatch(iconName, fileName, fileExtension, isDir); // returns icon name if found for light mode or undefined.
|
||||
}
|
||||
|
||||
// Get folder icon from active icon pack.
|
||||
|
||||
if (iconMap.options.activeIconPack) {
|
||||
iconName = lookForIconPackMatch(lowerFileName, iconMap) ?? iconName;
|
||||
iconName = lookForIconPackMatch(lowerFileName) ?? iconName;
|
||||
}
|
||||
|
||||
if (!iconName) return;
|
||||
@ -145,26 +138,15 @@ function replaceIcon(itemRow, iconMap, languageMap, provider) {
|
||||
* Lookup for matched file/folder icon name.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param {String} fileName File name.
|
||||
* @param {String} lowerFileName Lowercase file name.
|
||||
* @param {String} fileExtension File extension.
|
||||
* @param {Boolean} isDir Check if directory type.
|
||||
* @param {Boolean} isSubmodule Check if submodule type.
|
||||
* @param {Boolean} isSymlink Check if symlink
|
||||
* @param {Object} iconMap Icon map.
|
||||
* @returns {String} The matched icon name.
|
||||
* @param {string} fileName File name.
|
||||
* @param {string} lowerFileName Lowercase file name.
|
||||
* @param {string} fileExtension File extension.
|
||||
* @param {boolean} isDir Check if directory type.
|
||||
* @param {boolean} isSubmodule Check if submodule type.
|
||||
* @param {boolean} isSymlink Check if symlink
|
||||
* @returns {string} The matched icon name.
|
||||
*/
|
||||
function lookForMatch(
|
||||
fileName,
|
||||
lowerFileName,
|
||||
fileExtension,
|
||||
isDir,
|
||||
isSubmodule,
|
||||
isSymlink,
|
||||
iconMap,
|
||||
languageMap
|
||||
) {
|
||||
function lookForMatch(fileName, lowerFileName, fileExtension, isDir, isSubmodule, isSymlink) {
|
||||
if (isSubmodule) return 'folder-git';
|
||||
if (isSymlink) return 'folder-symlink';
|
||||
|
||||
@ -201,15 +183,13 @@ function lookForMatch(
|
||||
* Lookup for matched light file/folder icon name.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*
|
||||
* @param {String} iconName Icon name.
|
||||
* @param {String} fileName File name.
|
||||
* @param {String} fileExtension File extension.
|
||||
* @param {Boolean} isDir Check if directory or file type.
|
||||
* @param {Object} iconMap Icon map.
|
||||
* @returns {String} The matched icon name.
|
||||
* @param {string} iconName Icon name.
|
||||
* @param {string} fileName File name.
|
||||
* @param {string} fileExtension File extension.
|
||||
* @param {boolean} isDir Check if directory or file type.
|
||||
* @returns {string} The matched icon name.
|
||||
*/
|
||||
function lookForLightMatch(iconName, fileName, fileExtension, isDir, iconMap) {
|
||||
function lookForLightMatch(iconName, fileName, fileExtension, isDir) {
|
||||
// First look in fileNames and folderNames.
|
||||
if (iconMap.light.fileNames[fileName] && !isDir) return iconMap.light.fileNames[fileName];
|
||||
if (iconMap.light.folderNames[fileName] && isDir) return iconMap.light.folderNames[fileName];
|
||||
@ -225,12 +205,10 @@ function lookForLightMatch(iconName, fileName, fileExtension, isDir, iconMap) {
|
||||
* Lookup for matched icon from active icon pack.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*
|
||||
* @param {String} lowerFileName Lowercase file name.
|
||||
* @param {Object} iconMap Icon map.
|
||||
* @returns {String} The matched icon name.
|
||||
* @param {string} lowerFileName Lowercase file name.
|
||||
* @returns {string} The matched icon name.
|
||||
*/
|
||||
function lookForIconPackMatch(lowerFileName, iconMap) {
|
||||
function lookForIconPackMatch(lowerFileName) {
|
||||
if (iconMap.options.activeIconPack) {
|
||||
switch (iconMap.options.activeIconPack) {
|
||||
case 'angular':
|
||||
@ -241,7 +219,8 @@ function lookForIconPackMatch(lowerFileName, iconMap) {
|
||||
case 'react_redux':
|
||||
if (iconsList[`folder-react-${lowerFileName}.svg`]) {
|
||||
return `folder-react-${lowerFileName}`;
|
||||
} else if (iconsList[`folder-redux-${lowerFileName}.svg`]) {
|
||||
}
|
||||
if (iconsList[`folder-redux-${lowerFileName}.svg`]) {
|
||||
return `folder-redux-${lowerFileName}`;
|
||||
}
|
||||
break;
|
||||
@ -249,9 +228,11 @@ function lookForIconPackMatch(lowerFileName, iconMap) {
|
||||
case 'vue_vuex':
|
||||
if (iconsList[`folder-vuex-${lowerFileName}.svg`]) {
|
||||
return `folder-vuex-${lowerFileName}`;
|
||||
} else if (iconsList[`folder-vue-${lowerFileName}.svg`]) {
|
||||
}
|
||||
if (iconsList[`folder-vue-${lowerFileName}.svg`]) {
|
||||
return `folder-vue-${lowerFileName}`;
|
||||
} else if ('nuxt' === lowerFileName) {
|
||||
}
|
||||
if (lowerFileName === 'nuxt') {
|
||||
return `folder-nuxt`;
|
||||
}
|
||||
break;
|
||||
@ -277,7 +258,12 @@ function lookForIconPackMatch(lowerFileName, iconMap) {
|
||||
return 'nest-guard';
|
||||
case /\.resolver\.(t|j)s$/.test(lowerFileName):
|
||||
return 'nest-resolver';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ const azureConfig = {
|
||||
document.defaultView.getComputedStyle(document.body).getPropertyValue('color') ===
|
||||
'rgba(0, 0, 0, 0.9)', // TODO: There is probably a better way to determine whether Azure is in light mode
|
||||
getIsDirectory: (svgEl) => svgEl.classList.contains('repos-folder-icon'),
|
||||
getIsSubmodule: (svgEl) => false, // There appears to be no way to tell if a folder is a submodule
|
||||
getIsSubmodule: () => false, // There appears to be no way to tell if a folder is a submodule
|
||||
getIsSymlink: (svgEl) => svgEl.classList.contains('ms-Icon--PageArrowRight'),
|
||||
replaceIcon: (svgEl, newSVG) => {
|
||||
newSVG.style.display = 'inline-flex';
|
||||
|
@ -9,7 +9,7 @@ const bitbucketConfig = {
|
||||
getIsLightTheme: () => true, // No dark mode available for bitbucket currently
|
||||
getIsDirectory: (svgEl) => svgEl.parentNode?.getAttribute('aria-label') === 'Directory,',
|
||||
getIsSubmodule: (svgEl) => svgEl.parentNode?.getAttribute('aria-label') === 'Submodule,',
|
||||
getIsSymlink: (svgEl) => false, // There appears to be no way to determine this for bitbucket
|
||||
getIsSymlink: () => false, // There appears to be no way to determine this for bitbucket
|
||||
replaceIcon: (svgEl, newSVG) => {
|
||||
newSVG.style.overflow = 'hidden';
|
||||
newSVG.style.pointerEvents = 'none';
|
||||
|
@ -2,7 +2,8 @@ const githubConfig = {
|
||||
name: 'github',
|
||||
selectors: {
|
||||
row: '.js-navigation-container[role=grid] > .js-navigation-item, file-tree .ActionList-content, a.tree-browser-result',
|
||||
filename: 'div[role="rowheader"] > span, .ActionList-item-label, a.tree-browser-result > marked-text',
|
||||
filename:
|
||||
'div[role="rowheader"] > span, .ActionList-item-label, a.tree-browser-result > marked-text',
|
||||
icon: '.octicon-file, .octicon-file-directory-fill, a.tree-browser-result > svg.octicon.octicon-file',
|
||||
},
|
||||
getIsLightTheme: () => document.querySelector('html').getAttribute('data-color-mode') === 'light',
|
||||
|
Loading…
x
Reference in New Issue
Block a user