diff --git a/API.md b/API.md index af05dd5..c1bcfe3 100644 --- a/API.md +++ b/API.md @@ -242,6 +242,7 @@ The store is exposed as a `LibDashStore` instance (see `src/index.js`). Each met - `setSelectedCompany(googleAuthId: number, companyId: number): Promise` - [pic](API.pic.md) - `getImageByHash(googleAuthId: number, fullHash: string, tx?: object): Promise<{buffer: Buffer, w: number, h: number, size: number, contentType: string}>` + - `getSmallThumbByHash(googleAuthId: number, fullHash: string, tx?: object): Promise<{buffer: Buffer, w: number, h: number, contentType: string}>` - `getThumbByHash(googleAuthId: number, fullHash: string, tx?: object): Promise<{buffer: Buffer, w: number, h: number, contentType: string}>` - [numbers](API.numbers.md) - `list(googleAuthId: number, tx?: object): Promise>` diff --git a/API.pic.md b/API.pic.md index f4c0d35..919d294 100644 --- a/API.pic.md +++ b/API.pic.md @@ -31,6 +31,35 @@ const image = await store.pic.getImageByHash(42, 'abc123'); // => { buffer, w, h, size, contentType: 'image/avif' } ``` +## `pic.getSmallThumbByHash` + +*Source: `src/store/pic/getSmallThumbByHash.js`* + +Returns the small thumbnail image (AVIF, 40px max edge) for a given hash. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `googleAuthId` | `number` | The id of the Google auth user. | +| `fullHash` | `string` | The full image hash. | +| `[tx]` | `object` | Optional transaction to run within. | + +**Returns** + +`Promise<{buffer: Buffer, w: number, h: number, contentType: string}>` — The small thumbnail image. + +**Throws** + +`Error` — If the image is not found. + +**Example** + +```js +const thumb = await store.pic.getSmallThumbByHash(42, 'abc123'); +// => { buffer, w, h, contentType: 'image/avif' } +``` + ## `pic.getThumbByHash` *Source: `src/store/pic/getThumbByHash.js`* diff --git a/src/index.js b/src/index.js index b39e3ab..bb3d42d 100644 --- a/src/index.js +++ b/src/index.js @@ -138,6 +138,7 @@ import googleAuthSetSelectedCompany from './store/google_auth/setSelectedCompany import googleAuthSetProfile from './store/google_auth/setProfile.js'; import picGetImageByHash from './store/pic/getImageByHash.js'; import picGetThumbByHash from './store/pic/getThumbByHash.js'; +import picGetSmallThumbByHash from './store/pic/getSmallThumbByHash.js'; import numbersList from './store/numbers/list.js'; import numbersUpdate from './store/numbers/update.js'; import storePurge from './store/purge.js'; @@ -471,6 +472,7 @@ export default class LibDashStore { this.pic = { getImageByHash: picGetImageByHash(provider), getThumbByHash: picGetThumbByHash(provider), + getSmallThumbByHash: picGetSmallThumbByHash(provider), }; this.numbers = { diff --git a/src/providers/mssql/queries/pic.js b/src/providers/mssql/queries/pic.js index f1824fd..66e4c64 100644 --- a/src/providers/mssql/queries/pic.js +++ b/src/providers/mssql/queries/pic.js @@ -61,6 +61,12 @@ FROM pic WHERE hash = @hash `; +export const GET_SMALLTHUMB_BY_HASH = ` +SELECT smallthumbw AS w, smallthumbh AS h, smallthumbbinary AS buffer +FROM pic +WHERE hash = @hash +`; + export const DELETE_BY_ARTICLE_AND_HASH = ` DELETE p FROM pic p diff --git a/src/providers/sqlite3/queries/pic.js b/src/providers/sqlite3/queries/pic.js index 3810687..9070f43 100644 --- a/src/providers/sqlite3/queries/pic.js +++ b/src/providers/sqlite3/queries/pic.js @@ -30,6 +30,12 @@ FROM pic WHERE hash = @hash `; +export const GET_SMALLTHUMB_BY_HASH = ` +SELECT smallthumbw AS w, smallthumbh AS h, smallthumbbinary AS buffer +FROM pic +WHERE hash = @hash +`; + export const DELETE_BY_ARTICLE_AND_HASH = ` DELETE FROM pic WHERE hash = @fullHash diff --git a/src/store/pic/getSmallThumbByHash.js b/src/store/pic/getSmallThumbByHash.js new file mode 100644 index 0000000..7529a8f --- /dev/null +++ b/src/store/pic/getSmallThumbByHash.js @@ -0,0 +1,46 @@ +import { GET_SMALLTHUMB_BY_HASH as MSSQL_GET } from '../../providers/mssql/queries/pic.js'; +import { GET_SMALLTHUMB_BY_HASH as SQLITE_GET } from '../../providers/sqlite3/queries/pic.js'; +import resolvePicAccess from './resolvePicAccess.js'; +import makeRunner from '../runner.js'; + +export default function getSmallThumbByHash(provider) { + const authorize = resolvePicAccess(provider); + const sql = provider?.dialect === 'sqlite3' ? SQLITE_GET : MSSQL_GET; + + /** + * Returns the small thumbnail image (AVIF, 40px max edge) for a given hash. + * + * @param {number} googleAuthId - The id of the Google auth user. + * @param {string} fullHash - The full image hash. + * @param {object} [tx] - Optional transaction to run within. + * @returns {Promise<{buffer: Buffer, w: number, h: number, contentType: string}>} The small thumbnail image. + * @throws {Error} If the image is not found. + * + * @example + * const thumb = await store.pic.getSmallThumbByHash(42, 'abc123'); + * // => { buffer, w, h, contentType: 'image/avif' } + */ + return async (googleAuthId, fullHash, tx) => { + await authorize(googleAuthId, fullHash, tx); + + const runner = makeRunner(provider, tx); + const result = await runner.query(sql, { hash: fullHash }); + + const row = result.rows[0]; + if (!row) { + throw new Error('Image not found'); + } + + const buffer = row.buffer ?? row.smallthumbbinary; + if (!buffer) { + throw new Error('Image not found'); + } + + return { + buffer, + w: row.w, + h: row.h, + contentType: 'image/avif', + }; + }; +}