diff options
Diffstat (limited to 'packages/integrations/image/src')
-rw-r--r-- | packages/integrations/image/src/shorthash.ts | 67 | ||||
-rw-r--r-- | packages/integrations/image/src/utils.ts | 6 |
2 files changed, 73 insertions, 0 deletions
diff --git a/packages/integrations/image/src/shorthash.ts b/packages/integrations/image/src/shorthash.ts new file mode 100644 index 000000000..99a691ac4 --- /dev/null +++ b/packages/integrations/image/src/shorthash.ts @@ -0,0 +1,67 @@ +/** + * shortdash - https://github.com/bibig/node-shorthash + * + * @license + * + * (The MIT License) + * + * Copyright (c) 2013 Bibig <bibig@me.com> + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +const dictionary = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY'; +const binary = dictionary.length; + +// refer to: http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/ +function bitwise(str: string) { + let hash = 0; + if (str.length === 0) return hash; + for (let i = 0; i < str.length; i++) { + const ch = str.charCodeAt(i); + hash = (hash << 5) - hash + ch; + hash = hash & hash; // Convert to 32bit integer + } + return hash; +} + +export function shorthash(text: string) { + let num: number; + let result = ''; + + let integer = bitwise(text); + const sign = integer < 0 ? 'Z' : ''; // It it's negative, start with Z, which isn't in the dictionary + + integer = Math.abs(integer); + + while (integer >= binary) { + num = integer % binary; + integer = Math.floor(integer / binary); + result = dictionary[num] + result; + } + + if (integer > 0) { + result = dictionary[integer] + result; + } + + return sign + result; +} diff --git a/packages/integrations/image/src/utils.ts b/packages/integrations/image/src/utils.ts index 44c338cf4..80dff1b6e 100644 --- a/packages/integrations/image/src/utils.ts +++ b/packages/integrations/image/src/utils.ts @@ -1,5 +1,6 @@ import fs from 'fs'; import path from 'path'; +import { shorthash } from './shorthash.js'; import type { OutputFormat, TransformOptions } from './types'; export function isOutputFormat(value: string): value is OutputFormat { @@ -48,6 +49,11 @@ export function propsToFilename({ src, width, height, format }: TransformOptions const ext = path.extname(src); let filename = src.replace(ext, ''); + // for remote images, add a hash of the full URL to dedupe images with the same filename + if (isRemoteImage(src)) { + filename += `-${shorthash(src)}`; + } + if (width && height) { return `${filename}_${width}x${height}.${format}`; } else if (width) { |