feat: add size, created, and modified columns to file table and manifestattachment APIs
This commit is contained in:
@@ -776,6 +776,9 @@ BEGIN
|
||||
hash NVARCHAR(64) NOT NULL,
|
||||
mimetype NVARCHAR(255) NOT NULL,
|
||||
name NVARCHAR(255) NOT NULL,
|
||||
size BIGINT NOT NULL,
|
||||
created DATETIME2 NOT NULL CONSTRAINT DF_file_created DEFAULT SYSUTCDATETIME(),
|
||||
modified DATETIME2 NOT NULL CONSTRAINT DF_file_modified DEFAULT SYSUTCDATETIME(),
|
||||
content VARBINARY(MAX) NOT NULL,
|
||||
thumbavif VARBINARY(MAX) NULL,
|
||||
thumbx INT NULL,
|
||||
|
||||
@@ -5,9 +5,9 @@ WHERE id = @manifestId AND company_id = @companyId
|
||||
`;
|
||||
|
||||
export const CREATE_FILE = `
|
||||
INSERT INTO [file] (hash, mimetype, name, content, thumbavif, thumbx, thumby)
|
||||
INSERT INTO [file] (hash, mimetype, name, size, created, modified, content, thumbavif, thumbx, thumby)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@hash, @mimetype, @name, @content, CONVERT(VARBINARY(MAX), @thumbavif), @thumbx, @thumby)
|
||||
VALUES (@hash, @mimetype, @name, @size, @created, @modified, @content, CONVERT(VARBINARY(MAX), @thumbavif), @thumbx, @thumby)
|
||||
`;
|
||||
|
||||
export const GET_NEXT_SORT = `
|
||||
@@ -31,7 +31,9 @@ SELECT
|
||||
f.hash,
|
||||
f.mimetype,
|
||||
f.name,
|
||||
DATALENGTH(f.content) AS size,
|
||||
f.size,
|
||||
f.created,
|
||||
f.modified,
|
||||
f.thumbavif,
|
||||
f.thumbx,
|
||||
f.thumby
|
||||
@@ -50,6 +52,9 @@ SELECT
|
||||
f.hash,
|
||||
f.mimetype,
|
||||
f.name,
|
||||
f.size,
|
||||
f.created,
|
||||
f.modified,
|
||||
f.content,
|
||||
f.thumbavif,
|
||||
f.thumbx,
|
||||
|
||||
@@ -23,11 +23,14 @@ export default function add(pool) {
|
||||
* @param {string} input.name - The file name.
|
||||
* @param {Buffer} input.content - The file content.
|
||||
* @param {number} [input.sort] - Optional display sort order.
|
||||
* @param {number} [input.size] - Optional file size in bytes (defaults to content length).
|
||||
* @param {Date|string} [input.created] - Optional creation timestamp (defaults to current date).
|
||||
* @param {Date|string} [input.modified] - Optional modified timestamp (defaults to created date).
|
||||
* @param {string} [input.hash] - The file hash (auto-computed SHA-256 if omitted).
|
||||
* @param {Buffer} [input.thumbavif] - Optional AVIF thumbnail buffer.
|
||||
* @param {number} [input.thumbx] - Optional thumbnail width.
|
||||
* @param {number} [input.thumby] - Optional thumbnail height.
|
||||
* @returns {Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>} The created attachment record.
|
||||
* @returns {Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, created: Date, modified: Date, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>} The created attachment record.
|
||||
* @throws {Error} If the manifest is not found or file input is invalid.
|
||||
*
|
||||
* @example
|
||||
@@ -36,10 +39,10 @@ export default function add(pool) {
|
||||
* name: 'invoice.pdf',
|
||||
* content: fileBuffer,
|
||||
* });
|
||||
* // => { id, manifestId, fileId, sort, hash, mimetype, name, thumbavif, thumbx, thumby }
|
||||
* // => { id, manifestId, fileId, sort, hash, mimetype, name, size, created, modified, thumbavif, thumbx, thumby }
|
||||
*/
|
||||
return async (googleAuthId, manifestId, input, ...rest) => {
|
||||
let rawMimetype, rawName, rawContent, rawHash, rawThumbavif, rawThumbx, rawThumby, rawSort;
|
||||
let rawMimetype, rawName, rawContent, rawHash, rawThumbavif, rawThumbx, rawThumby, rawSort, rawSize, rawCreated, rawModified;
|
||||
if (typeof input === 'object' && input !== null && !Buffer.isBuffer(input)) {
|
||||
rawMimetype = input.mimetype;
|
||||
rawName = input.name;
|
||||
@@ -49,6 +52,9 @@ export default function add(pool) {
|
||||
rawThumbx = input.thumbx ?? input.thumbw;
|
||||
rawThumby = input.thumby ?? input.thumbh;
|
||||
rawSort = input.sort;
|
||||
rawSize = input.size;
|
||||
rawCreated = input.created ?? input.createdAt;
|
||||
rawModified = input.modified ?? input.modifiedAt ?? input.lastModified;
|
||||
} else {
|
||||
rawMimetype = input;
|
||||
rawName = rest[0];
|
||||
@@ -78,6 +84,27 @@ export default function add(pool) {
|
||||
}
|
||||
}
|
||||
|
||||
const size =
|
||||
Number.isFinite(rawSize) && rawSize >= 0
|
||||
? Number(rawSize)
|
||||
: content.length;
|
||||
|
||||
const parsedCreated =
|
||||
rawCreated instanceof Date && !isNaN(rawCreated)
|
||||
? rawCreated
|
||||
: typeof rawCreated === 'string' || typeof rawCreated === 'number'
|
||||
? new Date(rawCreated)
|
||||
: null;
|
||||
const created = parsedCreated && !isNaN(parsedCreated) ? parsedCreated : new Date();
|
||||
|
||||
const parsedModified =
|
||||
rawModified instanceof Date && !isNaN(rawModified)
|
||||
? rawModified
|
||||
: typeof rawModified === 'string' || typeof rawModified === 'number'
|
||||
? new Date(rawModified)
|
||||
: null;
|
||||
const modified = parsedModified && !isNaN(parsedModified) ? parsedModified : created;
|
||||
|
||||
const hash =
|
||||
typeof rawHash === 'string' && rawHash.trim()
|
||||
? rawHash.trim()
|
||||
@@ -134,6 +161,9 @@ export default function add(pool) {
|
||||
.input('hash', hash)
|
||||
.input('mimetype', mimetype)
|
||||
.input('name', name)
|
||||
.input('size', size)
|
||||
.input('created', created)
|
||||
.input('modified', modified)
|
||||
.input('content', content)
|
||||
.input('thumbavif', thumbavif)
|
||||
.input('thumbx', thumbx)
|
||||
@@ -160,6 +190,9 @@ export default function add(pool) {
|
||||
hash,
|
||||
mimetype,
|
||||
name,
|
||||
size,
|
||||
created,
|
||||
modified,
|
||||
thumbavif,
|
||||
thumbx,
|
||||
thumby,
|
||||
|
||||
@@ -13,12 +13,12 @@ export default function getById(pool) {
|
||||
* @param {number} googleAuthId - The id of the Google auth user.
|
||||
* @param {number} manifestId - The manifest ID.
|
||||
* @param {number} id - The attachment ID or file ID.
|
||||
* @returns {Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, content: Buffer, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>} The attachment record with binary content.
|
||||
* @returns {Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, created: Date, modified: Date, content: Buffer, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>} The attachment record with binary content.
|
||||
* @throws {Error} If the manifest or attachment is not found, or user is not authorized.
|
||||
*
|
||||
* @example
|
||||
* const attachment = await store.manifestattachment.getById(42, 1, 5);
|
||||
* // => { id, manifestId, fileId, sort, hash, mimetype, name, content, thumbavif, thumbx, thumby }
|
||||
* // => { id, manifestId, fileId, sort, hash, mimetype, name, size, created, modified, content, thumbavif, thumbx, thumby }
|
||||
*/
|
||||
return async (googleAuthId, manifestId, id) => {
|
||||
if (!Number.isFinite(id)) {
|
||||
@@ -46,6 +46,9 @@ export default function getById(pool) {
|
||||
hash: row.hash,
|
||||
mimetype: row.mimetype,
|
||||
name: row.name,
|
||||
size: Number(row.size),
|
||||
created: row.created,
|
||||
modified: row.modified,
|
||||
content: row.content,
|
||||
thumbavif: row.thumbavif ?? null,
|
||||
thumbx: row.thumbx ?? null,
|
||||
|
||||
@@ -12,7 +12,9 @@ function shape(row) {
|
||||
hash: row.hash,
|
||||
mimetype: row.mimetype,
|
||||
name: row.name,
|
||||
size: row.size,
|
||||
size: Number(row.size),
|
||||
created: row.created,
|
||||
modified: row.modified,
|
||||
thumbavif: row.thumbavif ?? null,
|
||||
thumbx: row.thumbx ?? null,
|
||||
thumby: row.thumby ?? null,
|
||||
@@ -28,12 +30,12 @@ export default function listByManifestId(pool) {
|
||||
*
|
||||
* @param {number} googleAuthId - The id of the Google auth user.
|
||||
* @param {number} manifestId - The manifest ID.
|
||||
* @returns {Promise<Array<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>>} A list of attachment metadata objects.
|
||||
* @returns {Promise<Array<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, created: Date, modified: Date, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>>} A list of attachment metadata objects.
|
||||
* @throws {Error} If the manifest is not found or the user is not authorized.
|
||||
*
|
||||
* @example
|
||||
* const attachments = await store.manifestattachment.listByManifestId(42, 1);
|
||||
* // => [{ id, manifestId, fileId, sort, hash, mimetype, name, size, thumbavif, thumbx, thumby }]
|
||||
* // => [{ id, manifestId, fileId, sort, hash, mimetype, name, size, created, modified, thumbavif, thumbx, thumby }]
|
||||
*/
|
||||
return async (googleAuthId, manifestId) => {
|
||||
const { companyId } = await access(googleAuthId);
|
||||
|
||||
Reference in New Issue
Block a user