diff --git a/.prettierrc.js b/.prettierrc.js
deleted file mode 100644
index d98de6c..0000000
--- a/.prettierrc.js
+++ /dev/null
@@ -1,9 +0,0 @@
-module.exports = {
- bracketSpacing: false,
- trailingComma: "all",
- printWidth: 140,
- tabWidth: 2,
- singleQuote: false,
- noSemi: true,
- rcVerbose: true,
-};
diff --git a/README.md b/README.md
index 4a18d5c..038be7d 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,6 @@
[](https://github.com/svbutko)
[](https://twitter.com/svbutko)
-
Generate code-friendly image URI source constants.
To learn about use cases and what issues it solves check [this blog post](https://dev.to/svbutko/react-native-image-resource-generator-m14).
@@ -30,56 +29,56 @@ npm install --save-dev react-native-image-resource-generator
### Usage
1. Create a folder and put all of your images there (_sub-folders are supported too_). Example:
-```
-project
-│ package.json
-│ src
-│
-└───resources
-│ │ fonts
-│ │ settings
-│ │
-│ └───images
-│ │ arrow_down.png
-│ │ arrow_down@2x.png
-│ │ arrow_down@3x.png
-│ │ arrow_up.png
-│ │ ...
-```
+ ```
+ project
+ │ package.json
+ │ src
+ │
+ └───resources
+ │ │ fonts
+ │ │ settings
+ │ │
+ │ └───images
+ │ │ arrow_down.png
+ │ │ arrow_down@2x.png
+ │ │ arrow_down@3x.png
+ │ │ arrow_up.png
+ │ │ ...
+ ```
2. Add script to your `package.json` scripts or type into terminal:
* JavaScript: ```img-res-gen --dir=resources/images --out=src/common/ImageResources.js```
* TypeScript ```img-res-gen --dir=resources/images --out=src/common/ImageResources.g.ts --ts```
3. The result of the previous command will create a file with static image URI sources, which will look something similar to this:
-```typescript
-/* eslint:disable */
-/* tslint:disable */
-import {ImageURISource} from "react-native";
-
-export class ImageResources {
- static readonly account: ImageURISource = require("../../resources/images/account.png");
- static readonly arrow_down: ImageURISource = require("../../resources/images/arrow_down.png");
- static readonly arrow_up: ImageURISource = require("../../resources/images/arrow_up.png");
- static readonly avatar: ImageURISource = require("../../resources/images/avatar.png");
- static readonly back: ImageURISource = require("../../resources/images/back.png");
- static readonly bank: ImageURISource = require("../../resources/images/bank.png");
- static readonly bell: ImageURISource = require("../../resources/images/bell.png");
-}
-```
+ ```typescript
+ /* eslint:disable */
+ /* tslint:disable */
+ import {ImageURISource} from "react-native";
+
+ export class ImageResources {
+ static readonly account: ImageURISource = require("../../resources/images/account.png");
+ static readonly arrow_down: ImageURISource = require("../../resources/images/arrow_down.png");
+ static readonly arrow_up: ImageURISource = require("../../resources/images/arrow_up.png");
+ static readonly avatar: ImageURISource = require("../../resources/images/avatar.png");
+ static readonly back: ImageURISource = require("../../resources/images/back.png");
+ static readonly bank: ImageURISource = require("../../resources/images/bank.png");
+ static readonly bell: ImageURISource = require("../../resources/images/bell.png");
+ }
+ ```
4. After this use it anywhere you need:
-```typescript jsx
-
-```
+ ```typescript jsx
+
+ ```
If you added or removed images, simply re-run the script to regenerate the file.
### Options
-| Option | Description | Required | Example
-|---------------|-----------------------------------------------------------------------------|----------|---------------------------------------
-| dir | Relative directory path with images | `True` | `img-res-gen --dir=resources/images`
-| out | Output file path | `True` | `img-res-gen --out=src/common/ImageResources.g.ts`
-| read | Read directory path, adds additional path to a file's output required path | `False` | `img-res-gen --read=build/src`
-| ts | Should the output file be generated as a TypeScript file | `False` | `img-res-gen --ts`
+| Option | Description | Required | Example |
+|--------|----------------------------------------------------------------------------|----------|----------------------------------------------------|
+| dir | Relative directory path with images | `True` | `img-res-gen --dir=resources/images` |
+| out | Output file path | `True` | `img-res-gen --out=src/common/ImageResources.g.ts` |
+| read | Read directory path, adds additional path to a file's output required path | `False` | `img-res-gen --read=build/src` |
+| ts | Should the output file be generated as a TypeScript file | `False` | `img-res-gen --ts` |
diff --git a/package-lock.json b/package-lock.json
index 63347d5..6d6ba86 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,7 +1,7 @@
{
"name": "react-native-image-resource-generator",
"version": "1.0.2",
- "lockfileVersion": 2,
+ "lockfileVersion": 3,
"requires": true,
"packages": {
"": {
@@ -15,33 +15,8 @@
},
"bin": {
"img-res-gen": "bin/index.js"
- },
- "devDependencies": {
- "@types/command-line-args": "^5.2.0",
- "@types/command-line-usage": "^5.0.2",
- "@types/node": "^17.0.36",
- "prettier": "^2.6.2",
- "typescript": "^4.7.2"
}
},
- "node_modules/@types/command-line-args": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.0.tgz",
- "integrity": "sha512-UuKzKpJJ/Ief6ufIaIzr3A/0XnluX7RvFgwkV89Yzvm77wCh1kFaFmqN8XEnGcN62EuHdedQjEMb8mYxFLGPyA==",
- "dev": true
- },
- "node_modules/@types/command-line-usage": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/@types/command-line-usage/-/command-line-usage-5.0.2.tgz",
- "integrity": "sha512-n7RlEEJ+4x4TS7ZQddTmNSxP+zziEG0TNsMfiRIxcIVXt71ENJ9ojeXmGO3wPoTdn7pJcU2xc3CJYMktNT6DPg==",
- "dev": true
- },
- "node_modules/@types/node": {
- "version": "17.0.36",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.36.tgz",
- "integrity": "sha512-V3orv+ggDsWVHP99K3JlwtH20R7J4IhI1Kksgc+64q5VxgfRkQG8Ws3MFm/FZOKDYGy9feGFlZ70/HpCNe9QaA==",
- "dev": true
- },
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -83,13 +58,16 @@
}
},
"node_modules/cliui": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
- "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dependencies": {
"string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
+ "strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
}
},
"node_modules/color-convert": {
@@ -163,9 +141,9 @@
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"node_modules/escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"engines": {
"node": ">=6"
}
@@ -218,21 +196,6 @@
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
},
- "node_modules/prettier": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
- "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
- "dev": true,
- "bin": {
- "prettier": "bin-prettier.js"
- },
- "engines": {
- "node": ">=10.13.0"
- },
- "funding": {
- "url": "https://github.com/prettier/prettier?sponsor=1"
- }
- },
"node_modules/reduce-flatten": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz",
@@ -244,7 +207,7 @@
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"engines": {
"node": ">=0.10.0"
}
@@ -315,11 +278,11 @@
}
},
"node_modules/transliteration": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/transliteration/-/transliteration-2.2.0.tgz",
- "integrity": "sha512-o29GDWtecNoK4TNfnJQesGluFPiza+U8NoiKrErU8eTNlVgma6w1LV/tTiGo+waFLkhtL9WxrW0lXhZKmm7msQ==",
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/transliteration/-/transliteration-2.3.5.tgz",
+ "integrity": "sha512-HAGI4Lq4Q9dZ3Utu2phaWgtm3vB6PkLUFqWAScg/UW+1eZ/Tg6Exo4oC0/3VUol/w4BlefLhUUSVBr/9/ZGQOw==",
"dependencies": {
- "yargs": "^16.1.0"
+ "yargs": "^17.5.1"
},
"bin": {
"slugify": "dist/bin/slugify",
@@ -329,19 +292,6 @@
"node": ">=6.0.0"
}
},
- "node_modules/typescript": {
- "version": "4.7.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.2.tgz",
- "integrity": "sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==",
- "dev": true,
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=4.2.0"
- }
- },
"node_modules/typical": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
@@ -425,339 +375,29 @@
}
},
"node_modules/yargs": {
- "version": "16.2.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
- "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"dependencies": {
- "cliui": "^7.0.2",
+ "cliui": "^8.0.1",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
- "string-width": "^4.2.0",
+ "string-width": "^4.2.3",
"y18n": "^5.0.5",
- "yargs-parser": "^20.2.2"
+ "yargs-parser": "^21.1.1"
},
"engines": {
- "node": ">=10"
+ "node": ">=12"
}
},
"node_modules/yargs-parser": {
- "version": "20.2.9",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
- "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"engines": {
- "node": ">=10"
+ "node": ">=12"
}
}
- },
- "dependencies": {
- "@types/command-line-args": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.0.tgz",
- "integrity": "sha512-UuKzKpJJ/Ief6ufIaIzr3A/0XnluX7RvFgwkV89Yzvm77wCh1kFaFmqN8XEnGcN62EuHdedQjEMb8mYxFLGPyA==",
- "dev": true
- },
- "@types/command-line-usage": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/@types/command-line-usage/-/command-line-usage-5.0.2.tgz",
- "integrity": "sha512-n7RlEEJ+4x4TS7ZQddTmNSxP+zziEG0TNsMfiRIxcIVXt71ENJ9ojeXmGO3wPoTdn7pJcU2xc3CJYMktNT6DPg==",
- "dev": true
- },
- "@types/node": {
- "version": "17.0.36",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.36.tgz",
- "integrity": "sha512-V3orv+ggDsWVHP99K3JlwtH20R7J4IhI1Kksgc+64q5VxgfRkQG8Ws3MFm/FZOKDYGy9feGFlZ70/HpCNe9QaA==",
- "dev": true
- },
- "ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
- },
- "ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "requires": {
- "color-convert": "^1.9.0"
- }
- },
- "array-back": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
- "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q=="
- },
- "chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- },
- "cliui": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
- "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
- "requires": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^7.0.0"
- }
- },
- "color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "requires": {
- "color-name": "1.1.3"
- }
- },
- "color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
- },
- "command-line-args": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz",
- "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==",
- "requires": {
- "array-back": "^3.1.0",
- "find-replace": "^3.0.0",
- "lodash.camelcase": "^4.3.0",
- "typical": "^4.0.0"
- }
- },
- "command-line-usage": {
- "version": "6.1.3",
- "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz",
- "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==",
- "requires": {
- "array-back": "^4.0.2",
- "chalk": "^2.4.2",
- "table-layout": "^1.0.2",
- "typical": "^5.2.0"
- },
- "dependencies": {
- "array-back": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
- "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg=="
- },
- "typical": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
- "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg=="
- }
- }
- },
- "deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
- },
- "emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
- },
- "escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
- },
- "escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
- },
- "find-replace": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
- "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
- "requires": {
- "array-back": "^3.0.1"
- }
- },
- "get-caller-file": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
- },
- "has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
- },
- "lodash.camelcase": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
- "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
- },
- "prettier": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
- "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
- "dev": true
- },
- "reduce-flatten": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz",
- "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w=="
- },
- "require-directory": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
- },
- "string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- }
- },
- "strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "requires": {
- "ansi-regex": "^5.0.1"
- }
- },
- "supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "requires": {
- "has-flag": "^3.0.0"
- }
- },
- "table-layout": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz",
- "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==",
- "requires": {
- "array-back": "^4.0.1",
- "deep-extend": "~0.6.0",
- "typical": "^5.2.0",
- "wordwrapjs": "^4.0.0"
- },
- "dependencies": {
- "array-back": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
- "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg=="
- },
- "typical": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
- "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg=="
- }
- }
- },
- "transliteration": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/transliteration/-/transliteration-2.2.0.tgz",
- "integrity": "sha512-o29GDWtecNoK4TNfnJQesGluFPiza+U8NoiKrErU8eTNlVgma6w1LV/tTiGo+waFLkhtL9WxrW0lXhZKmm7msQ==",
- "requires": {
- "yargs": "^16.1.0"
- }
- },
- "typescript": {
- "version": "4.7.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.2.tgz",
- "integrity": "sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==",
- "dev": true
- },
- "typical": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
- "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw=="
- },
- "wordwrapjs": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz",
- "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==",
- "requires": {
- "reduce-flatten": "^2.0.0",
- "typical": "^5.2.0"
- },
- "dependencies": {
- "typical": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
- "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg=="
- }
- }
- },
- "wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "requires": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- }
- }
- },
- "y18n": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
- "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="
- },
- "yargs": {
- "version": "16.2.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
- "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
- "requires": {
- "cliui": "^7.0.2",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.0",
- "y18n": "^5.0.5",
- "yargs-parser": "^20.2.2"
- }
- },
- "yargs-parser": {
- "version": "20.2.9",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
- "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="
- }
}
}
diff --git a/package.json b/package.json
index e7443cd..70f7ba5 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,6 @@
"description": "React Native image resource generator CLI tool",
"main": "bin/index.js",
"scripts": {
- "build": "tsc",
"test": "echo \"Error: no test specified\" && exit 1"
},
"bin": {
@@ -24,7 +23,7 @@
"generator",
"cli-tool"
],
- "author": "Sergei Butko (https://twitter.com/@svbutko)",
+ "author": "Sergei Butko (https://github.com/svbutko)",
"license": "MIT",
"bugs": {
"url": "https://github.com/svbutko/react-native-image-resource-generator/issues"
@@ -33,7 +32,7 @@
"contributors": [
{
"name": "Sergei Butko",
- "url": "https://twitter.com/@svbutko"
+ "url": "https://github.com/svbutko"
},
{
"name": "Igor Antsiferov",
@@ -44,12 +43,5 @@
"command-line-args": "^5.2.1",
"command-line-usage": "^6.1.3",
"transliteration": "^2.2.0"
- },
- "devDependencies": {
- "@types/command-line-args": "^5.2.0",
- "@types/command-line-usage": "^5.0.2",
- "@types/node": "^17.0.36",
- "prettier": "^2.6.2",
- "typescript": "^4.7.2"
}
}
diff --git a/src/FileEntry.ts b/src/FileEntry.ts
deleted file mode 100644
index 982e81b..0000000
--- a/src/FileEntry.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import path from "path";
-
-export class FileEntry {
- constructor(dir: string, out: string, fileName: string) {
- this.relativeResourcePath = path.relative(path.dirname(out), path.join(dir, fileName)).replace(/\\/g, "/");
- this.variableName = fileName
- .toLowerCase()
- .replace(/(.*)(.(png|jpg|jpeg|gif|bmp|svg))$/, "$1")
- .replace(/^\d+/, ($0) => new Array($0.length + 1).join("_"))
- .replace(/\W+/g, "_");
- }
-
- readonly relativeResourcePath: string;
- readonly variableName: string;
-}
diff --git a/src/index.js b/src/index.js
new file mode 100644
index 0000000..4868d90
--- /dev/null
+++ b/src/index.js
@@ -0,0 +1,209 @@
+#!/usr/bin/env node
+
+const transliteration = require("transliteration");
+const fs = require("fs");
+const path = require("path");
+const commandLineArgs = require("command-line-args");
+const commandLineUsage = require("command-line-usage");
+
+
+run()
+ .then(() => console.log("Done"))
+ .catch((error) => console.error(`Error happened while generating resources:\n${error}`));
+
+const optionDefinitions = [
+ {name: "dir", alias: "d", type: String, description: "Relative directory path with images"},
+ {name: "out", alias: "o", type: String, description: "Output file path"},
+ {name: "read", alias: "r", type: String, description: "Read directory path (optional)"},
+ {
+ name: "ts",
+ alias: "t",
+ type: Boolean,
+ description: "Should the output file be generated as a TypeScript file (optional)",
+ },
+];
+
+const cmdOptions = commandLineArgs(optionDefinitions);
+const cmdUsage = commandLineUsage([{header: "Options", optionList: optionDefinitions}]);
+
+/**
+ * @param {string} dir
+ * @param {string} out
+ * @param {string} fileName
+ * @returns {FileEntry}
+ */
+function assembleFileEntry(dir, out, fileName) {
+ return {
+ relativeResourcePath: path.relative(path.dirname(out), path.join(dir, fileName)).replace(/\\/g, "/"),
+ variableName: fileName
+ .toLowerCase()
+ .replace(/(.*)(.(png|jpg|jpeg|gif|bmp|svg))$/, "$1")
+ .replace(/^\d+/, ($0) => new Array($0.length + 1).join("_"))
+ .replace(/\W+/g, "_"),
+ };
+}
+
+async function run() {
+ checkOptions(cmdOptions);
+ console.log(`Started searching resources in ${cmdOptions.dir}`);
+
+ const resources = [];
+
+ let content =
+ `/* eslint-disable */` +
+ `\n/* tslint:disable */` +
+ `${cmdOptions.ts ? '\nimport {ImageURISource} from "react-native";' : ""}` +
+ `\n\n/**` +
+ `\n * This file is auto-generated by react-native-image-resource-generator` +
+ `\n * !!! DO NOT EDIT !!!` +
+ `\n * For more information check the documentation:` +
+ `\n * https://github.com/svbutko/react-native-image-resource-generator` +
+ `\n*/`;
+
+ await prepareFiles(cmdOptions.dir);
+ await collectEntries(cmdOptions.dir, path.join("root", path.dirname(cmdOptions.out), cmdOptions.read || ""), true, resources);
+
+ for (const resourceEntry of resources) {
+ content += generateClassExport(resourceEntry.name, resourceEntry.entries);
+ }
+
+ fs.writeFileSync(cmdOptions.out, content);
+}
+
+/**
+ * @param {string} dir
+ * @param {string} out
+ * @param {boolean} isRoot
+ * @param {ResultEntries[]} result
+ * @returns {Promise}
+ */
+async function collectEntries(dir, out, isRoot, result) {
+ const files = await readDir(dir);
+
+ /** @type {ResultEntries} */
+ const item = {
+ name: isRoot ? "ImageResources" : toCamelCase(dir.split(path.sep).pop()) + "Resources",
+ entries: [],
+ };
+
+ const regex = new RegExp("^((?!@).)*$");
+
+ for (const file of files) {
+ const joinedPath = path.join(dir, file);
+
+ if (fs.lstatSync(joinedPath).isDirectory()) {
+ await collectEntries(joinedPath, out, false, result);
+ } else if (regex.exec(file)) {
+ item.entries.push(assembleFileEntry(dir, out, file));
+ }
+ }
+
+ result.push(item);
+}
+
+/**
+ * @param {string} className
+ * @param {FileEntry[]} entries
+ * @returns {string}
+ */
+function generateClassExport(className, entries) {
+ return `\n\nexport class ${className} {\n${entries.map((entry) => getEntryDeclaration(entry)).join("\n")}\n}`;
+}
+
+/**
+ * @param {FileEntry} entry
+ * @returns {string}
+ */
+function getEntryDeclaration(entry) {
+ if (cmdOptions.ts) {
+ return ` static readonly ${entry.variableName}: ImageURISource = require("${entry.relativeResourcePath}");`;
+ }
+
+ return ` static ${entry.variableName} = require("${entry.relativeResourcePath}");`;
+}
+
+/**
+ * @param {string} dir
+ * @returns {Promise}
+ */
+function readDir(dir) {
+ return new Promise((resolve, reject) => {
+ fs.readdir(dir, (err, files) => {
+ if (err) {
+ reject(err);
+ }
+ resolve(files);
+ });
+ });
+}
+
+/**
+ * @param {string} str
+ * @returns {string}
+ */
+function toCamelCase(str) {
+ return str.substring(0, 1).toUpperCase() + str.substring(1);
+}
+
+/**
+ * @param {Options} options
+ * @returns {void}
+ */
+function checkOptions(options) {
+ if (options.dir == null || options.out == null) {
+ throw new Error(`Missing non-optional options.\nList of options:\n ${cmdUsage}`);
+ }
+}
+
+/** @type {OptionsTransliterate} */
+const transliterationOptions = {
+ trim: true,
+};
+
+/**
+ * @param {string} dir
+ * @returns {void}
+ */
+async function prepareFiles(dir) {
+ const files = await readDir(dir);
+
+ for (const file of files) {
+ const joinedPath = path.join(dir, file);
+
+ if (fs.lstatSync(joinedPath).isDirectory()) {
+ await prepareFiles(joinedPath);
+ } else {
+ const escapedFile = transliteration.transliterate(file, transliterationOptions)
+ .replace(/[,]/g, ".")
+ .replace(/[^A-Za-z0-9_@.]/g, "_");
+
+ if (escapedFile !== file) {
+ fs.renameSync(joinedPath, path.join(dir, escapedFile));
+ }
+ }
+ }
+}
+
+/**
+ * @typedef Options
+ * @prop {string} dir
+ * @prop {string} out
+ * @prop {string} read
+ * @prop {string} ts
+ */
+
+/**
+ * @typedef FileEntry
+ * @prop {string} relativeResourcePath
+ * @prop {string} variableName
+ */
+
+/**
+ * @typedef ResultEntries
+ * @prop {string} name
+ * @prop {FileEntry[]} entries
+ */
+
+/**
+ * @typedef {import('transliteration/dist/node/src/types').OptionsTransliterate} OptionsTransliterate
+ */
diff --git a/src/index.ts b/src/index.ts
deleted file mode 100644
index a347041..0000000
--- a/src/index.ts
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/usr/bin/env node
-
-import fs from "fs";
-import {FileEntry} from "./FileEntry";
-import path from "path";
-import {cmdOptions, cmdUsage} from "./options";
-import {IResourceEntries, Options} from "./types";
-import {transliterate} from "transliteration";
-import {OptionsTransliterate} from "transliteration/dist/node/src/types";
-
-run()
- .then(() => console.log("Done"))
- .catch((error) => console.error(`Error happened while generating resources:\n${error}`));
-
-async function run(): Promise {
- checkOptions(cmdOptions);
- console.log(`Started searching resources in ${cmdOptions.dir}`);
-
- const resources: IResourceEntries[] = [];
-
- let content =
- `/* eslint-disable */` +
- `\n/* tslint:disable */` +
- `${cmdOptions.ts ? '\nimport {ImageURISource} from "react-native";' : ""}` +
- `\n\n/**` +
- `\n * This file is auto-generated by react-native-image-resource-generator` +
- `\n * !!! DO NOT EDIT !!!` +
- `\n * For more information check the documentation:` +
- `\n * https://github.com/svbutko/react-native-image-resource-generator` +
- `\n*/`;
-
- await prepareFiles(cmdOptions.dir);
- await collectEntries(cmdOptions.dir, path.join("root", path.dirname(cmdOptions.out), cmdOptions.read || ""), true, resources);
-
- for (const resourceEntry of resources) {
- content += generateClassExport(resourceEntry.name, resourceEntry.entries);
- }
-
- fs.writeFileSync(cmdOptions.out, content);
-}
-
-async function collectEntries(dir: string, out: string, isRoot: boolean, result: IResourceEntries[]): Promise {
- const files = await readDir(dir);
- const item: IResourceEntries = {
- name: isRoot ? "ImageResources" : toCamelCase(dir.split(path.sep).pop()!) + "Resources",
- entries: [],
- };
-
- const regex = new RegExp("^((?!@).)*$");
-
- for (const file of files) {
- if (fs.lstatSync(path.join(dir, file)).isDirectory()) {
- await collectEntries(path.join(dir, file), out, false, result);
- } else if (regex.exec(file)) {
- const entry = new FileEntry(dir, out, file);
- item.entries.push(entry);
- }
- }
-
- result.push(item);
-}
-
-function generateClassExport(className: string, entries: FileEntry[]): string {
- return `\n\nexport class ${className} {\n${entries.map((entry) => getEntryDeclaration(entry)).join("\n")}\n}`;
-}
-
-function getEntryDeclaration(entry: FileEntry): string {
- if (cmdOptions.ts) {
- return ` static readonly ${entry.variableName}: ImageURISource = require("${entry.relativeResourcePath}");`;
- } else {
- return ` static ${entry.variableName} = require("${entry.relativeResourcePath}");`;
- }
-}
-
-function readDir(dir: string): Promise {
- return new Promise((resolve, reject): void => {
- fs.readdir(dir, (err, files) => {
- if (err) {
- reject(err);
- }
- resolve(files);
- });
- });
-}
-
-function toCamelCase(str: string): string {
- return str.substr(0, 1).toUpperCase() + str.substr(1);
-}
-
-function checkOptions(options: Options) {
- if (options.dir == null || options.out == null) {
- throw new Error(`Missing non-optional options.\nList of options:\n ${cmdUsage}`);
- }
-}
-
-const transliterationOptions: OptionsTransliterate = {
- trim: true,
-};
-
-async function prepareFiles(dir: string): Promise {
- const files = await readDir(dir);
- for (const file of files) {
- if (fs.lstatSync(path.join(dir, file)).isDirectory()) {
- await prepareFiles(path.join(dir, file));
- } else {
- const escapedFile = transliterate(file, transliterationOptions)
- .replace(/[,]/g, ".")
- .replace(/[^A-Za-z0-9_@.]/g, "_");
-
- if (escapedFile != file) {
- fs.renameSync(path.join(dir, file), path.join(dir, escapedFile));
- }
- }
- }
-}
diff --git a/src/options.ts b/src/options.ts
deleted file mode 100644
index 984ae33..0000000
--- a/src/options.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import commandLineArgs from "command-line-args";
-import commandLineUsage from "command-line-usage";
-import {IOptionDefinition, Options, OptionsEnum} from "./types";
-
-const optionDefinitions: IOptionDefinition[] = [
- {name: OptionsEnum.dir, alias: "d", type: String, description: "Relative directory path with images"},
- {name: OptionsEnum.out, alias: "o", type: String, description: "Output file path"},
- {name: OptionsEnum.read, alias: "r", type: String, description: "Read directory path (optional)"},
- {
- name: OptionsEnum.ts,
- alias: "t",
- type: Boolean,
- description: "Should the output file be generated as a TypeScript file (optional)",
- },
-];
-
-export const cmdOptions = commandLineArgs(optionDefinitions) as Options;
-export const cmdUsage = commandLineUsage([{header: "Options", optionList: optionDefinitions}]);
diff --git a/src/types/index.ts b/src/types/index.ts
deleted file mode 100644
index df7ea82..0000000
--- a/src/types/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import {FileEntry} from "../FileEntry";
-import {OptionDefinition} from "command-line-usage";
-
-export interface IResourceEntries {
- name: string;
- entries: FileEntry[];
-}
-
-export enum OptionsEnum {
- dir = "dir",
- out = "out",
- ts = "ts",
- read = "read",
-}
-
-export type Options = {[key in keyof typeof OptionsEnum]: string};
-
-export interface IOptionDefinition extends OptionDefinition {
- name: OptionsEnum;
-}
diff --git a/tsconfig.json b/tsconfig.json
deleted file mode 100644
index 11ba06e..0000000
--- a/tsconfig.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "compilerOptions": {
- "allowJs": false,
- "allowSyntheticDefaultImports": true,
- "esModuleInterop": true,
- "isolatedModules": true,
- "module": "commonjs",
- "target": "esnext",
- "lib": [
- "es6",
- "es2015",
- "es2015.iterable"
- ],
- "strict": true,
- "sourceMap": false,
- "moduleResolution": "node",
- "noImplicitAny": true,
- "noUnusedLocals": true,
- "noImplicitReturns": true,
- "preserveConstEnums": true,
- "alwaysStrict": true,
- "strictNullChecks": true,
- "skipLibCheck": true,
- "resolveJsonModule": true,
- "outDir": "./bin"
- },
- "include": [
- "src/**/*",
- ],
- "exclude": [
- "node_modules",
- "bin",
- ]
-}