Setup favicon generation (#178)
Co-authored-by: Konrad Szwarc <konrad.szwarc.dev@gmail.com>
13
.prettierignore
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Dependencies
|
||||
node_modules
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
|
||||
# Build output
|
||||
dist
|
||||
stats.html
|
||||
|
||||
# Favicon generation output
|
||||
**/favicons/**
|
||||
*.auto-generated*
|
||||
|
|
@ -15,5 +15,10 @@ export default defineConfig({
|
|||
],
|
||||
vite: {
|
||||
plugins: [visualizer()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'date-fns/locale': 'date-fns/locale/index.js',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
351
package-lock.json
generated
|
|
@ -23,6 +23,7 @@
|
|||
"astro-compress": "1.1.28",
|
||||
"concurrently": "7.6.0",
|
||||
"date-fns": "2.29.3",
|
||||
"favicons": "7.0.2",
|
||||
"iconify-icon-names": "1.1.0",
|
||||
"immer": "9.0.18",
|
||||
"locales-ts": "1.0.0",
|
||||
|
|
@ -35,6 +36,7 @@
|
|||
"puppeteer-report": "3.1.0",
|
||||
"rollup-plugin-visualizer": "5.9.0",
|
||||
"tailwindcss": "3.2.4",
|
||||
"ts-node": "10.9.1",
|
||||
"type-fest": "3.5.3",
|
||||
"typescript": "4.9.4"
|
||||
},
|
||||
|
|
@ -610,6 +612,28 @@
|
|||
"partytown": "bin/partytown.cjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "0.3.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@emmetio/abbreviation": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.2.3.tgz",
|
||||
|
|
@ -1109,6 +1133,30 @@
|
|||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tsconfig/node10": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
|
||||
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tsconfig/node12": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tsconfig/node14": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tsconfig/node16": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
|
||||
"integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/acorn": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz",
|
||||
|
|
@ -2605,6 +2653,12 @@
|
|||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/create-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cross-fetch": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
|
||||
|
|
@ -3445,6 +3499,12 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
|
|
@ -3634,6 +3694,20 @@
|
|||
"reusify": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/favicons": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/favicons/-/favicons-7.0.2.tgz",
|
||||
"integrity": "sha512-M/qE3ERHOBu0+Op+61jx8CdvOnSKrrl2zxUPpoGgsNyfjuGqRsK80zYoA5Uwdxl8QM4egfhBWZp1j7KK3YnOMg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"escape-html": "^1.0.3",
|
||||
"sharp": "^0.31.1",
|
||||
"xml2js": "^0.4.23"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fd-slicer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||
|
|
@ -4660,9 +4734,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"json5": "lib/cli.js"
|
||||
|
|
@ -4864,6 +4938,12 @@
|
|||
"sourcemap-codec": "^1.4.8"
|
||||
}
|
||||
},
|
||||
"node_modules/make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/markdown-table": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.2.tgz",
|
||||
|
|
@ -7511,6 +7591,12 @@
|
|||
"suf-log": "^2.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/sax": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/scheduler": {
|
||||
"version": "0.23.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
|
||||
|
|
@ -8238,6 +8324,73 @@
|
|||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-node": {
|
||||
"version": "10.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
|
||||
"integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@cspotcode/source-map-support": "^0.8.0",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
"@tsconfig/node12": "^1.0.7",
|
||||
"@tsconfig/node14": "^1.0.0",
|
||||
"@tsconfig/node16": "^1.0.2",
|
||||
"acorn": "^8.4.1",
|
||||
"acorn-walk": "^8.1.1",
|
||||
"arg": "^4.1.0",
|
||||
"create-require": "^1.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"v8-compile-cache-lib": "^3.0.1",
|
||||
"yn": "3.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"ts-node": "dist/bin.js",
|
||||
"ts-node-cwd": "dist/bin-cwd.js",
|
||||
"ts-node-esm": "dist/bin-esm.js",
|
||||
"ts-node-script": "dist/bin-script.js",
|
||||
"ts-node-transpile-only": "dist/bin-transpile.js",
|
||||
"ts-script": "dist/bin-script-deprecated.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@swc/core": ">=1.2.50",
|
||||
"@swc/wasm": ">=1.2.50",
|
||||
"@types/node": "*",
|
||||
"typescript": ">=2.7"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@swc/core": {
|
||||
"optional": true
|
||||
},
|
||||
"@swc/wasm": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/ts-node/node_modules/acorn-walk": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
|
||||
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-node/node_modules/arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ts-node/node_modules/diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/tsconfig-resolver": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/tsconfig-resolver/-/tsconfig-resolver-3.0.1.tgz",
|
||||
|
|
@ -8613,6 +8766,12 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/vfile": {
|
||||
"version": "5.3.4",
|
||||
"resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.4.tgz",
|
||||
|
|
@ -9336,6 +9495,28 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/xml2js": {
|
||||
"version": "0.4.23",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
|
||||
"integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"sax": ">=0.6.0",
|
||||
"xmlbuilder": "~11.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xmlbuilder": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
|
||||
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
|
|
@ -9447,6 +9628,15 @@
|
|||
"fd-slicer": "~1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
|
|
@ -9918,6 +10108,27 @@
|
|||
"integrity": "sha512-Zbr2Eo0AQ4yzmQr/36/h+6LKjmdVBB3Q5cGzO6rtlIKB/IOpbQVUZW+XAnhpJmJr9sIF97OZjgbhG9k7Sjn4yw==",
|
||||
"dev": true
|
||||
},
|
||||
"@cspotcode/source-map-support": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/trace-mapping": "0.3.9"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@emmetio/abbreviation": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.2.3.tgz",
|
||||
|
|
@ -10316,6 +10527,30 @@
|
|||
"integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
|
||||
"dev": true
|
||||
},
|
||||
"@tsconfig/node10": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
|
||||
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
|
||||
"dev": true
|
||||
},
|
||||
"@tsconfig/node12": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||
"dev": true
|
||||
},
|
||||
"@tsconfig/node14": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||
"dev": true
|
||||
},
|
||||
"@tsconfig/node16": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
|
||||
"integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/acorn": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz",
|
||||
|
|
@ -11473,6 +11708,12 @@
|
|||
"path-type": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"create-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"cross-fetch": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
|
||||
|
|
@ -12002,6 +12243,12 @@
|
|||
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
|
||||
"dev": true
|
||||
},
|
||||
"escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
||||
"dev": true
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
|
|
@ -12142,6 +12389,17 @@
|
|||
"reusify": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"favicons": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/favicons/-/favicons-7.0.2.tgz",
|
||||
"integrity": "sha512-M/qE3ERHOBu0+Op+61jx8CdvOnSKrrl2zxUPpoGgsNyfjuGqRsK80zYoA5Uwdxl8QM4egfhBWZp1j7KK3YnOMg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"escape-html": "^1.0.3",
|
||||
"sharp": "^0.31.1",
|
||||
"xml2js": "^0.4.23"
|
||||
}
|
||||
},
|
||||
"fd-slicer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||
|
|
@ -12872,9 +13130,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"dev": true
|
||||
},
|
||||
"jsonc-parser": {
|
||||
|
|
@ -13028,6 +13286,12 @@
|
|||
"sourcemap-codec": "^1.4.8"
|
||||
}
|
||||
},
|
||||
"make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"dev": true
|
||||
},
|
||||
"markdown-table": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.2.tgz",
|
||||
|
|
@ -14847,6 +15111,12 @@
|
|||
"suf-log": "^2.5.3"
|
||||
}
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
|
||||
"dev": true
|
||||
},
|
||||
"scheduler": {
|
||||
"version": "0.23.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
|
||||
|
|
@ -15379,6 +15649,47 @@
|
|||
"integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==",
|
||||
"dev": true
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "10.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
|
||||
"integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@cspotcode/source-map-support": "^0.8.0",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
"@tsconfig/node12": "^1.0.7",
|
||||
"@tsconfig/node14": "^1.0.0",
|
||||
"@tsconfig/node16": "^1.0.2",
|
||||
"acorn": "^8.4.1",
|
||||
"acorn-walk": "^8.1.1",
|
||||
"arg": "^4.1.0",
|
||||
"create-require": "^1.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"v8-compile-cache-lib": "^3.0.1",
|
||||
"yn": "3.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn-walk": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
|
||||
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
|
||||
"dev": true
|
||||
},
|
||||
"arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"dev": true
|
||||
},
|
||||
"diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tsconfig-resolver": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/tsconfig-resolver/-/tsconfig-resolver-3.0.1.tgz",
|
||||
|
|
@ -15632,6 +15943,12 @@
|
|||
"sade": "^1.7.3"
|
||||
}
|
||||
},
|
||||
"v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||
"dev": true
|
||||
},
|
||||
"vfile": {
|
||||
"version": "5.3.4",
|
||||
"resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.4.tgz",
|
||||
|
|
@ -16051,6 +16368,22 @@
|
|||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"xml2js": {
|
||||
"version": "0.4.23",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
|
||||
"integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"sax": ">=0.6.0",
|
||||
"xmlbuilder": "~11.0.0"
|
||||
}
|
||||
},
|
||||
"xmlbuilder": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
|
||||
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
|
||||
"dev": true
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
|
|
@ -16140,6 +16473,12 @@
|
|||
"fd-slicer": "~1.1.0"
|
||||
}
|
||||
},
|
||||
"yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"dev": true
|
||||
},
|
||||
"yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
|
|
|
|||
|
|
@ -13,9 +13,10 @@
|
|||
"dev": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"generate-cv": "node scripts/generate-cv.cjs",
|
||||
"prettier:check": "prettier --check --ignore-path .gitignore .",
|
||||
"prettier:write": "prettier --write --ignore-path .gitignore .",
|
||||
"generate-cv": "ts-node scripts/generate-cv.ts",
|
||||
"generate-favicons": "ts-node scripts/generate-favicons.ts",
|
||||
"prettier:check": "prettier --check .",
|
||||
"prettier:write": "prettier --write .",
|
||||
"astro:check": "astro check",
|
||||
"ts:check": "tsc --jsx preserve --skipLibCheck",
|
||||
"check": "concurrently npm:*:check"
|
||||
|
|
@ -36,6 +37,7 @@
|
|||
"astro-compress": "1.1.28",
|
||||
"concurrently": "7.6.0",
|
||||
"date-fns": "2.29.3",
|
||||
"favicons": "7.0.2",
|
||||
"iconify-icon-names": "1.1.0",
|
||||
"immer": "9.0.18",
|
||||
"locales-ts": "1.0.0",
|
||||
|
|
@ -48,6 +50,7 @@
|
|||
"puppeteer-report": "3.1.0",
|
||||
"rollup-plugin-visualizer": "5.9.0",
|
||||
"tailwindcss": "3.2.4",
|
||||
"ts-node": "10.9.1",
|
||||
"type-fest": "3.5.3",
|
||||
"typescript": "4.9.4"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 36 36">
|
||||
<path fill="#000" d="M22.25 4h-8.5a1 1 0 0 0-.96.73l-5.54 19.4a.5.5 0 0 0 .62.62l5.05-1.44a2 2 0 0 0 1.38-1.4l3.22-11.66a.5.5 0 0 1 .96 0l3.22 11.67a2 2 0 0 0 1.38 1.39l5.05 1.44a.5.5 0 0 0 .62-.62l-5.54-19.4a1 1 0 0 0-.96-.73Z"/>
|
||||
<path fill="url(#gradient)" d="M18 28a7.63 7.63 0 0 1-5-2c-1.4 2.1-.35 4.35.6 5.55.14.17.41.07.47-.15.44-1.8 2.93-1.22 2.93.6 0 2.28.87 3.4 1.72 3.81.34.16.59-.2.49-.56-.31-1.05-.29-2.46 1.29-3.25 3-1.5 3.17-4.83 2.5-6-.67.67-2.6 2-5 2Z"/>
|
||||
<defs>
|
||||
<linearGradient id="gradient" x1="16" x2="16" y1="32" y2="24" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#000"/>
|
||||
<stop offset="1" stop-color="#000" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<style>
|
||||
@media (prefers-color-scheme:dark){:root{filter:invert(100%)}}
|
||||
</style>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 873 B |
BIN
public/favicons/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
public/favicons/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 230 KiB |
BIN
public/favicons/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
public/favicons/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 975 B |
BIN
public/favicons/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
public/favicons/favicon.ico
Normal file
|
After Width: | Height: | Size: 32 KiB |
26
public/favicons/manifest.webmanifest
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "Mark Freeman - Senior React Developer",
|
||||
"short_name": "Mark Freeman - Senior React Developer",
|
||||
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sodales ac dui at vestibulum. In condimentum metus id dui tincidunt, in blandit mi vehicula.",
|
||||
"dir": "auto",
|
||||
"lang": "en-US",
|
||||
"display": "standalone",
|
||||
"orientation": "any",
|
||||
"start_url": ".",
|
||||
"background_color": "#fff",
|
||||
"theme_color": "#fff",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/favicons/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/favicons/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
const { exec } = require('node:child_process');
|
||||
const path = require('node:path');
|
||||
const fs = require('node:fs');
|
||||
const puppeteer = require('puppeteer');
|
||||
const report = require('puppeteer-report');
|
||||
|
||||
const waitFor = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
const retry = async ({ promise, retries, retryTime }) => {
|
||||
try {
|
||||
return await promise();
|
||||
} catch (error) {
|
||||
if (retries <= 0) throw error;
|
||||
|
||||
await waitFor(retryTime);
|
||||
|
||||
return await retry({ promise, retries: retries - 1, retryTime });
|
||||
}
|
||||
};
|
||||
|
||||
const config = {
|
||||
path: path.join(__dirname, '..', 'public', 'cv.pdf'),
|
||||
format: 'A4',
|
||||
printBackground: true,
|
||||
margin: { top: '10mm', right: '10mm', bottom: '10mm', left: '10mm' },
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
const child = exec('npm run dev');
|
||||
|
||||
const browser = await puppeteer.launch({ headless: true });
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
await page.setViewport({ width: 794, height: 1122, deviceScaleFactor: 2 });
|
||||
|
||||
await retry({
|
||||
promise: () => page.goto('http://localhost:3000/pdf', { waitUntil: 'networkidle0' }),
|
||||
retries: 5,
|
||||
retryTime: 1000,
|
||||
});
|
||||
|
||||
await report.pdfPage(page, config);
|
||||
|
||||
await browser.close();
|
||||
|
||||
child.kill();
|
||||
};
|
||||
|
||||
main();
|
||||
59
scripts/generate-cv.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import { exec } from 'node:child_process';
|
||||
import * as path from 'node:path';
|
||||
import * as puppeteer from 'puppeteer';
|
||||
import { pdfPage } from 'puppeteer-report';
|
||||
|
||||
const waitFor = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
const goTo = async (page: puppeteer.Page, url: string) => {
|
||||
await page.goto(url, { waitUntil: 'networkidle0' });
|
||||
};
|
||||
|
||||
type GoToReturn = ReturnType<typeof goTo>;
|
||||
|
||||
interface RetryOptions {
|
||||
promise: () => GoToReturn;
|
||||
retries: number;
|
||||
retryTime: number;
|
||||
}
|
||||
|
||||
const retry = async ({ promise, retries, retryTime }: RetryOptions): GoToReturn => {
|
||||
try {
|
||||
return await promise();
|
||||
} catch (error) {
|
||||
if (retries <= 0) throw error;
|
||||
|
||||
await waitFor(retryTime);
|
||||
|
||||
return await retry({ promise, retries: retries - 1, retryTime });
|
||||
}
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
const child = exec('npm run dev');
|
||||
|
||||
const browser = await puppeteer.launch({ headless: true });
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
await page.setViewport({ width: 794, height: 1122, deviceScaleFactor: 2 });
|
||||
|
||||
await retry({
|
||||
promise: () => goTo(page, 'http://localhost:3000/pdf'),
|
||||
retries: 5,
|
||||
retryTime: 1000,
|
||||
});
|
||||
|
||||
await pdfPage(page, {
|
||||
path: path.join(__dirname, '..', 'public', 'cv.pdf'),
|
||||
format: 'A4',
|
||||
printBackground: true,
|
||||
margin: { top: '10mm', right: '10mm', bottom: '10mm', left: '10mm' },
|
||||
});
|
||||
|
||||
await browser.close();
|
||||
|
||||
child.kill();
|
||||
};
|
||||
|
||||
main();
|
||||
53
scripts/generate-favicons.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import { favicons, config as faviconsConfig, FaviconFile, FaviconImage } from 'favicons';
|
||||
import config from '../src/data/config';
|
||||
import { mkdir, writeFile, rm } from 'fs/promises';
|
||||
import { existsSync } from 'fs';
|
||||
|
||||
const faviconsDirectory = './public/favicons';
|
||||
|
||||
const saveFile = async (file: FaviconFile | FaviconImage) => {
|
||||
await writeFile(`${faviconsDirectory}/${file.name}`, file.contents);
|
||||
console.log(`${file.name} has been created successfully`);
|
||||
};
|
||||
|
||||
(async () => {
|
||||
const { faviconPath } = config.meta;
|
||||
|
||||
const response = await favicons(`.${faviconPath}`, {
|
||||
...faviconsConfig.defaults,
|
||||
path: '/favicons',
|
||||
appName: config.meta.title,
|
||||
appDescription: config.meta.description,
|
||||
appShortName: config.meta.title,
|
||||
lang: config.i18n.locale.code,
|
||||
start_url: '.',
|
||||
icons: {
|
||||
android: ['android-chrome-192x192.png', 'android-chrome-512x512.png'],
|
||||
windows: false,
|
||||
yandex: false,
|
||||
appleStartup: false,
|
||||
appleIcon: ['apple-touch-icon.png'],
|
||||
favicons: ['favicon-16x16.png', 'favicon-32x32.png', 'favicon.ico'],
|
||||
},
|
||||
});
|
||||
|
||||
if (existsSync(faviconsDirectory)) {
|
||||
await rm(faviconsDirectory, { recursive: true });
|
||||
}
|
||||
|
||||
await mkdir(faviconsDirectory);
|
||||
|
||||
await Promise.all([...response.images, ...response.files].map(saveFile));
|
||||
|
||||
const comments = [
|
||||
'<!-- This file is auto-generated. Do not edit it manually. -->\n',
|
||||
'<!-- In order to apply changes to it, adjust configuration object in generate-favicons.ts script and run it -->\n',
|
||||
];
|
||||
|
||||
const formattedHtml = response.html.map((line) => line.replace('>', '/>')).join('\n');
|
||||
|
||||
const pathToFaviconsFile = './src/web/head/favicons.auto-generated.astro';
|
||||
|
||||
await writeFile(pathToFaviconsFile, [...comments, formattedHtml, '\n']);
|
||||
console.log(`${pathToFaviconsFile} has been updated successfully`);
|
||||
})();
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import type { Config } from '@/types/data';
|
||||
import enUS from 'date-fns/locale/en-US/index.js';
|
||||
import { enUS } from 'date-fns/locale';
|
||||
import type { ReadonlyDeep } from 'type-fest';
|
||||
|
||||
const config = {
|
||||
|
|
@ -14,7 +14,7 @@ const config = {
|
|||
title: 'Mark Freeman - Senior React Developer',
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sodales ac dui at vestibulum. In condimentum metus id dui tincidunt, in blandit mi vehicula.',
|
||||
favicon: '/favicon.svg',
|
||||
faviconPath: '/src/assets/my-image.jpeg',
|
||||
},
|
||||
pdf: {
|
||||
footer:
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@ export interface MetaConfig {
|
|||
description: string;
|
||||
|
||||
/**
|
||||
* [WEB] URL or path to the page's favicon.
|
||||
* [WEB] Absolute path to the image used for favicons generation.
|
||||
*
|
||||
* Specified icon will be displayed next to the page title in browser tab.
|
||||
*/
|
||||
favicon: string;
|
||||
faviconPath: string;
|
||||
|
||||
/**
|
||||
* [WEB] Title used in open graph links.
|
||||
|
|
|
|||
19
src/web/components/head.astro
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
import Favicons from '@/web/head/favicons.auto-generated.astro';
|
||||
import InitialTheme from '@/web/head/initial-theme.astro';
|
||||
import Meta from '@/web/head/meta.astro';
|
||||
|
||||
import type { MetaConfig } from '@/types/config/meta-config.types';
|
||||
|
||||
interface Props {
|
||||
meta: MetaConfig;
|
||||
}
|
||||
|
||||
const { meta } = Astro.props;
|
||||
---
|
||||
|
||||
<head>
|
||||
<Meta meta={meta} />
|
||||
<Favicons />
|
||||
<InitialTheme />
|
||||
</head>
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
import type { Data } from '@/types/data';
|
||||
import Analytics from '@/web/analytics/analytics.astro';
|
||||
import Head from './head.astro';
|
||||
|
||||
export interface Props extends Pick<Data['config'], 'meta' | 'i18n'> {}
|
||||
|
||||
|
|
@ -9,33 +10,7 @@ const { meta, i18n } = Astro.props;
|
|||
|
||||
<!DOCTYPE html>
|
||||
<html lang={i18n.locale.code} class="scroll-smooth">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>{meta.title}</title>
|
||||
<meta name="description" content={meta.description} />
|
||||
<link rel="icon" type="image/svg+xml" href={meta.favicon} />
|
||||
<meta property="og:title" content={meta.ogTitle ?? meta.title} />
|
||||
<meta property="og:description" content={meta.ogDescription ?? meta.description} />
|
||||
{meta.ogImage && <meta property="og:image" content={meta.ogImage} />}
|
||||
<script is:inline>
|
||||
const theme = (() => {
|
||||
if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) {
|
||||
return localStorage.getItem('theme');
|
||||
}
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
})();
|
||||
|
||||
if (theme === 'light') {
|
||||
document.documentElement.classList.remove('dark');
|
||||
} else {
|
||||
document.documentElement.classList.add('dark');
|
||||
}
|
||||
|
||||
window.localStorage.setItem('theme', theme);
|
||||
</script>
|
||||
</head>
|
||||
<Head meta={meta} />
|
||||
<body class="flex justify-center overflow-x-hidden bg-gray-50 dark:bg-gray-900 xl:relative xl:left-7">
|
||||
<Analytics />
|
||||
<slot />
|
||||
|
|
|
|||
12
src/web/head/favicons.auto-generated.astro
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<!-- This file is auto-generated. Do not edit it manually. -->
|
||||
<!-- In order to apply changes to it, adjust configuration object in generate-favicons.ts script and run it -->
|
||||
<link rel="icon" type="image/x-icon" href="/favicons/favicon.ico"/>
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png"/>
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png"/>
|
||||
<link rel="manifest" href="/favicons/manifest.webmanifest"/>
|
||||
<meta name="mobile-web-app-capable" content="yes"/>
|
||||
<meta name="theme-color" content="#fff"/>
|
||||
<meta name="application-name" content="Mark Freeman - Senior React Developer"/>
|
||||
<meta name="apple-mobile-web-app-capable" content="yes"/>
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
|
||||
<meta name="apple-mobile-web-app-title" content="Mark Freeman - Senior React Developer"/>
|
||||
16
src/web/head/initial-theme.astro
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<script is:inline>
|
||||
const theme = (() => {
|
||||
if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) {
|
||||
return localStorage.getItem('theme');
|
||||
}
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
})();
|
||||
|
||||
if (theme === 'light') {
|
||||
document.documentElement.classList.remove('dark');
|
||||
} else {
|
||||
document.documentElement.classList.add('dark');
|
||||
}
|
||||
|
||||
window.localStorage.setItem('theme', theme);
|
||||
</script>
|
||||
18
src/web/head/meta.astro
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
import type { MetaConfig } from '@/types/config/meta-config.types';
|
||||
|
||||
interface Props {
|
||||
meta: MetaConfig;
|
||||
}
|
||||
|
||||
const { meta } = Astro.props;
|
||||
---
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>{meta.title}</title>
|
||||
<meta name="description" content={meta.description} />
|
||||
<meta property="og:title" content={meta.ogTitle ?? meta.title} />
|
||||
<meta property="og:description" content={meta.ogDescription ?? meta.description} />
|
||||
{meta.ogImage && <meta property="og:image" content={meta.ogImage} />}
|
||||
|
|
@ -35,5 +35,11 @@
|
|||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["**/*.ts", "**/*.tsx", "**/*.cjs", "**/*.astro"]
|
||||
"include": ["**/*.ts", "**/*.tsx", "**/*.cjs", "**/*.astro"],
|
||||
"ts-node": {
|
||||
"transpileOnly": true,
|
||||
"compilerOptions": {
|
||||
"module": "CommonJS"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||