replace index.js entry point (#8058)

* replace index.js entry point

* add types.d.ts

* Update documentation

* Add Typescript usage example

* Drop template file

* Readd test

* Minor change

Co-authored-by: Álvaro Mondéjar Rubio <mondejar1994@gmail.com>
This commit is contained in:
Sachin Raja 2022-11-28 03:32:57 -08:00 committed by GitHub
parent 89dc12cb35
commit fcec7adc8b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 67 additions and 123 deletions

View file

@ -4,6 +4,5 @@ npm-debug.log
# Build files # Build files
/index.js /index.js
/icons.js /index.mjs
/icons.mjs /index.d.ts
/icons.d.ts

5
.gitignore vendored
View file

@ -1,8 +1,7 @@
# Files generated by build script # Files generated by build script
/index.js /index.js
/icons.js /index.mjs
/icons.mjs /index.d.ts
/icons.d.ts
# Ignore all files in the icons folder # Ignore all files in the icons folder
icons/* icons/*

View file

@ -9,7 +9,6 @@
!LICENSE.md !LICENSE.md
!VERSIONING.md !VERSIONING.md
!index.js !index.js
!index.mjs
!index.d.ts !index.d.ts
!icons.js !types.d.ts
!icons.mjs
!icons.d.ts

View file

@ -11,6 +11,5 @@ scripts/build/templates/*.js
# Generated JavaScript files don't need to be formatted # Generated JavaScript files don't need to be formatted
index.js index.js
icons.js index.mjs
icons.mjs index.d.ts
icons.d.ts

View file

@ -73,13 +73,13 @@ npm install simple-icons
All icons are imported from a single file, where `[ICON SLUG]` is replaced by a capitalized [slug]. We highly recommend using a bundler that can tree shake such as [webpack](https://webpack.js.org/) to remove the unused icon code: All icons are imported from a single file, where `[ICON SLUG]` is replaced by a capitalized [slug]. We highly recommend using a bundler that can tree shake such as [webpack](https://webpack.js.org/) to remove the unused icon code:
```javascript ```javascript
// Import a specific icon by its slug as: // Import a specific icon by its slug as:
// import { si[ICON SLUG] } from 'simple-icons/icons' // import { si[ICON SLUG] } from 'simple-icons'
// For example: // For example:
// use import/esm to allow tree shaking // use import/esm to allow tree shaking
import { siSimpleicons } from 'simple-icons/icons'; import { siSimpleicons } from 'simple-icons';
// or with require/cjs // or with require/cjs
const { siSimpleicons } = require('simple-icons/icons'); const { siSimpleicons } = require('simple-icons');
``` ```
It will return an icon object: It will return an icon object:
@ -107,10 +107,20 @@ NOTE: the `license` entry will be `undefined` if we do not yet have license data
*/ */
``` ```
If you need to iterate over all icons, use:
```javascript
import * as icons from 'simple-icons';
```
#### TypeScript Usage <picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/simple-icons/simple-icons/develop/assets/readme/typescript-white.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/typescript.svg"><img src="https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/typescript.svg" alt="Typescript" align=left width=19 height=19></picture> #### TypeScript Usage <picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/simple-icons/simple-icons/develop/assets/readme/typescript-white.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/typescript.svg"><img src="https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/typescript.svg" alt="Typescript" align=left width=19 height=19></picture>
Type definitions are bundled with the package. Type definitions are bundled with the package.
```typescript
import type { SimpleIcon } from 'simple-icons';
```
### PHP Usage <picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/simple-icons/simple-icons/develop/assets/readme/php-white.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/php.svg"><img src="https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/php.svg" alt="Php" align=left width=24 height=24></picture> ### PHP Usage <picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/simple-icons/simple-icons/develop/assets/readme/php-white.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/php.svg"><img src="https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/php.svg" alt="Php" align=left width=24 height=24></picture>
The icons are also available through our Packagist package. To install, simply run: The icons are also available through our Packagist package. To install, simply run:

24
index.d.ts vendored
View file

@ -1,24 +0,0 @@
export interface SimpleIcon {
title: string;
slug: string;
svg: string;
path: string;
source: string;
hex: string;
guidelines?: string | undefined;
license?:
| {
type: string;
url: string;
}
| undefined;
}
/**
* @deprecated The `simple-icons` entrypoint will be removed in the next major. Please switch to using `import * as icons from "simple-icons/icons"` if you need an object with all the icons.
*/
declare const icons: Record<string, SimpleIcon> & {
Get(name: string): SimpleIcon;
};
export default icons;

View file

@ -59,7 +59,7 @@
}, },
"scripts": { "scripts": {
"build": "node scripts/build/package.js", "build": "node scripts/build/package.js",
"clean": "rimraf index.js icons.js icons.mjs icons.d.ts", "clean": "rimraf index.js index.mjs index.d.ts",
"format": "prettier --write .", "format": "prettier --write .",
"lint": "run-s our-lint jslint jsonlint svglint wslint", "lint": "run-s our-lint jslint jsonlint svglint wslint",
"our-lint": "node scripts/lint/ourlint.js", "our-lint": "node scripts/lint/ourlint.js",

View file

@ -26,19 +26,16 @@ const __dirname = getDirnameFromImportMeta(import.meta.url);
const UTF8 = 'utf8'; const UTF8 = 'utf8';
const rootDir = path.resolve(__dirname, '..', '..'); const rootDir = path.resolve(__dirname, '..', '..');
const indexFile = path.resolve(rootDir, 'index.js');
const iconsDir = path.resolve(rootDir, 'icons'); const iconsDir = path.resolve(rootDir, 'icons');
const iconsJsFile = path.resolve(rootDir, 'icons.js'); const indexJsFile = path.resolve(rootDir, 'index.js');
const iconsMjsFile = path.resolve(rootDir, 'icons.mjs'); const indexMjsFile = path.resolve(rootDir, 'index.mjs');
const iconsDtsFile = path.resolve(rootDir, 'icons.d.ts'); const indexDtsFile = path.resolve(rootDir, 'index.d.ts');
const templatesDir = path.resolve(__dirname, 'templates'); const templatesDir = path.resolve(__dirname, 'templates');
const indexTemplateFile = path.resolve(templatesDir, 'index.js');
const iconObjectTemplateFile = path.resolve(templatesDir, 'icon-object.js'); const iconObjectTemplateFile = path.resolve(templatesDir, 'icon-object.js');
const build = async () => { const build = async () => {
const icons = await getIconsData(); const icons = await getIconsData();
const indexTemplate = await fs.readFile(indexTemplateFile, UTF8);
const iconObjectTemplate = await fs.readFile(iconObjectTemplateFile, UTF8); const iconObjectTemplate = await fs.readFile(iconObjectTemplateFile, UTF8);
// Local helper functions // Local helper functions
@ -109,27 +106,19 @@ const build = async () => {
// constants used in templates to reduce package size // constants used in templates to reduce package size
const constantsString = `const a='<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>',b='</title><path d="',c='"/></svg>';`; const constantsString = `const a='<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>',b='</title><path d="',c='"/></svg>';`;
// write our generic index.js
const rawIndexJs = util.format(
indexTemplate,
constantsString,
buildIcons.map(({ icon }) => iconToKeyValue(icon)).join(','),
);
await writeJs(indexFile, rawIndexJs);
// write our file containing the exports of all icons in CommonJS ... // write our file containing the exports of all icons in CommonJS ...
const rawIconsJs = `${constantsString}module.exports={${iconsBarrelJs.join( const rawIndexJs = `${constantsString}module.exports={${iconsBarrelJs.join(
'', '',
)}};`; )}};`;
await writeJs(iconsJsFile, rawIconsJs); await writeJs(indexJsFile, rawIndexJs);
// and ESM // and ESM
const rawIconsMjs = constantsString + iconsBarrelMjs.join(''); const rawIndexMjs = constantsString + iconsBarrelMjs.join('');
await writeJs(iconsMjsFile, rawIconsMjs); await writeJs(indexMjsFile, rawIndexMjs);
// and create a type declaration file // and create a type declaration file
const rawIconsDts = `import {SimpleIcon} from ".";type I = SimpleIcon;${iconsBarrelDts.join( const rawIndexDts = `import {SimpleIcon} from "./types";export {SimpleIcon};type I=SimpleIcon;${iconsBarrelDts.join(
'', '',
)}`; )}`;
await writeTs(iconsDtsFile, rawIconsDts); await writeTs(indexDtsFile, rawIndexDts);
}; };
build(); build();

View file

@ -1,14 +0,0 @@
console.warn('Deprecation warning: The `simple-icons` entrypoint will be removed in the next major. Please switch to using `import * as icons from "simple-icons/icons"` if you need an object with all the icons.')
%s
var icons = {%s};
Object.defineProperty(icons, "Get", {
enumerable: false,
value: function(targetName) {
return icons[targetName];
}
});
module.exports = icons;

View file

@ -1,19 +0,0 @@
import {
getIconsData,
getIconSlug,
slugToVariableName,
} from '../scripts/utils.js';
import * as simpleIcons from '../icons.mjs';
import { testIcon } from './test-icon.js';
(async () => {
const icons = await getIconsData();
icons.map((icon) => {
const slug = getIconSlug(icon);
const variableName = slugToVariableName(slug);
const subject = simpleIcons[variableName];
testIcon(icon, subject, slug);
});
})();

View file

@ -1,37 +1,19 @@
import simpleIcons from '../index.js'; import {
import { getIconSlug, getIconsData, titleToSlug } from '../scripts/utils.js'; getIconsData,
import { test } from 'mocha'; getIconSlug,
import { strict as assert } from 'node:assert'; slugToVariableName,
} from '../scripts/utils.js';
import * as simpleIcons from '../index.mjs';
import { testIcon } from './test-icon.js';
(async () => { (async () => {
const icons = await getIconsData(); const icons = await getIconsData();
icons.forEach((icon) => { icons.map((icon) => {
const slug = getIconSlug(icon); const slug = getIconSlug(icon);
const variableName = slugToVariableName(slug);
const subject = simpleIcons[variableName];
test(`'Get' ${icon.title} by its slug`, () => { testIcon(icon, subject, slug);
const found = simpleIcons.Get(slug);
assert.ok(found);
assert.equal(found.title, icon.title);
assert.equal(found.hex, icon.hex);
assert.equal(found.source, icon.source);
});
if (icon.slug) {
// if an icon data has a slug, it must be different to the
// slug inferred from the title, which prevents adding
// unnecessary slugs to icons data
test(`'${icon.title}' slug must be necessary`, () => {
assert.notEqual(titleToSlug(icon.title), icon.slug);
});
}
});
test(`Iterating over simpleIcons only exposes icons`, () => {
const iconArray = Object.values(simpleIcons);
for (let icon of iconArray) {
assert.ok(icon);
assert.equal(typeof icon, 'object');
}
}); });
})(); })();

View file

@ -2,7 +2,7 @@ import fs from 'node:fs';
import path from 'node:path'; import path from 'node:path';
import { strict as assert } from 'node:assert'; import { strict as assert } from 'node:assert';
import { describe, it } from 'mocha'; import { describe, it } from 'mocha';
import { URL_REGEX } from '../scripts/utils.js'; import { URL_REGEX, titleToSlug } from '../scripts/utils.js';
const iconsDir = path.resolve(process.cwd(), 'icons'); const iconsDir = path.resolve(process.cwd(), 'icons');
@ -66,5 +66,14 @@ export const testIcon = (icon, subject, slug) => {
const svgFileContents = fs.readFileSync(svgPath, 'utf8'); const svgFileContents = fs.readFileSync(svgPath, 'utf8');
assert.equal(subject.svg, svgFileContents); assert.equal(subject.svg, svgFileContents);
}); });
if (icon.slug) {
// if an icon data has a slug, it must be different to the
// slug inferred from the title, which prevents adding
// unnecessary slugs to icons data
it(`'${icon.title}' slug must be necessary`, () => {
assert.notEqual(titleToSlug(icon.title), icon.slug);
});
}
}); });
}; };

15
types.d.ts vendored Normal file
View file

@ -0,0 +1,15 @@
export interface SimpleIcon {
title: string;
slug: string;
svg: string;
path: string;
source: string;
hex: string;
guidelines?: string | undefined;
license?:
| {
type: string;
url: string;
}
| undefined;
}