@rpcbase/server 0.600.0 → 0.602.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{email-Co1GNjlT.js → email-CK8NNDQY.js} +48 -24
- package/dist/email-CK8NNDQY.js.map +1 -0
- package/dist/email.d.ts +9 -0
- package/dist/email.d.ts.map +1 -1
- package/dist/fileReferences-Ca0tivFd.js +101 -0
- package/dist/fileReferences-Ca0tivFd.js.map +1 -0
- package/dist/{handler-Fk-5fOSm.js → handler-BUTqP40B.js} +2 -2
- package/dist/{handler-Fk-5fOSm.js.map → handler-BUTqP40B.js.map} +1 -1
- package/dist/{handler-C92_gJkX.js → handler-BgcIWWMc.js} +2 -2
- package/dist/{handler-C92_gJkX.js.map → handler-BgcIWWMc.js.map} +1 -1
- package/dist/{handler-CapJTGzc.js → handler-CqSlSCdd.js} +215 -57
- package/dist/handler-CqSlSCdd.js.map +1 -0
- package/dist/{handler-BqlcQ9sE.js → handler-LRLmxrsg.js} +69 -24
- package/dist/handler-LRLmxrsg.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +148 -4
- package/dist/index.js.map +1 -1
- package/dist/initServer.d.ts.map +1 -1
- package/dist/notifications.js +2 -2
- package/dist/postProcessors-iffHvje4.js.map +1 -1
- package/dist/rts/index.js +1 -1
- package/dist/{schemas-B2fUvgYo.js → schemas-POKnVn0c.js} +58 -2
- package/dist/schemas-POKnVn0c.js.map +1 -0
- package/dist/serviceWorker.d.ts +7 -0
- package/dist/serviceWorker.d.ts.map +1 -0
- package/dist/{shared-DfrVDSp0.js → shared-Zt17vuAT.js} +54 -2
- package/dist/shared-Zt17vuAT.js.map +1 -0
- package/dist/uploads/api/file-uploads/fileReferences.d.ts +42 -0
- package/dist/uploads/api/file-uploads/fileReferences.d.ts.map +1 -0
- package/dist/uploads/api/file-uploads/handlers/completeUpload.d.ts.map +1 -1
- package/dist/uploads/api/file-uploads/handlers/initUpload.d.ts.map +1 -1
- package/dist/uploads/api/file-uploads/imageVariantsPostProcessor.d.ts.map +1 -1
- package/dist/uploads/api/file-uploads/index.d.ts +23 -0
- package/dist/uploads/api/file-uploads/index.d.ts.map +1 -1
- package/dist/uploads/api/file-uploads/postProcessors.d.ts +2 -0
- package/dist/uploads/api/file-uploads/postProcessors.d.ts.map +1 -1
- package/dist/uploads/api/file-uploads/shared.d.ts +21 -0
- package/dist/uploads/api/file-uploads/shared.d.ts.map +1 -1
- package/dist/uploads/api/files/handlers/deleteFile.d.ts.map +1 -1
- package/dist/uploads/api/files/handlers/getFile.d.ts.map +1 -1
- package/dist/uploads/worker.js +3 -2
- package/dist/uploads/worker.js.map +1 -1
- package/dist/uploads.js +2 -2
- package/package.json +1 -1
- package/dist/email-Co1GNjlT.js.map +0 -1
- package/dist/handler-BqlcQ9sE.js.map +0 -1
- package/dist/handler-CapJTGzc.js.map +0 -1
- package/dist/schemas-B2fUvgYo.js.map +0 -1
- package/dist/shared-DfrVDSp0.js.map +0 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Application, RequestHandler } from 'express';
|
|
2
|
+
export declare const RPCBASE_SERVICE_WORKER_PATH = "/rpcbase-service-worker.js";
|
|
3
|
+
export declare const RPCBASE_SERVICE_WORKER_MESSAGE_SOURCE = "@rpcbase/service-worker";
|
|
4
|
+
export declare const rpcbaseServiceWorkerSource: string;
|
|
5
|
+
export declare const rpcbaseServiceWorkerRequestHandler: RequestHandler;
|
|
6
|
+
export declare const registerRpcbaseServiceWorkerRoute: (app: Application) => void;
|
|
7
|
+
//# sourceMappingURL=serviceWorker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceWorker.d.ts","sourceRoot":"","sources":["../src/serviceWorker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAG1D,eAAO,MAAM,2BAA2B,+BAA+B,CAAA;AACvE,eAAO,MAAM,qCAAqC,4BAA4B,CAAA;AAE9E,eAAO,MAAM,0BAA0B,QA8H1B,CAAA;AAEb,eAAO,MAAM,kCAAkC,EAAE,cAQhD,CAAA;AAED,eAAO,MAAM,iCAAiC,GAAI,KAAK,WAAW,KAAG,IAEpE,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { extname } from "node:path";
|
|
1
2
|
import { createHash } from "node:crypto";
|
|
2
3
|
import { buildAbilityFromSession, getAccessibleByQuery } from "@rpcbase/db/acl";
|
|
3
4
|
//#region src/uploads/api/file-uploads/shared.ts
|
|
@@ -6,6 +7,7 @@ var MAX_CHUNK_SIZE_BYTES = 15 * 1024 * 1024;
|
|
|
6
7
|
var DEFAULT_MAX_CLIENT_BYTES_PER_SECOND = 10 * 1024 * 1024;
|
|
7
8
|
var DEFAULT_SESSION_TTL_S = 3600 * 24;
|
|
8
9
|
var ensuredIndexDbNames = /* @__PURE__ */ new Set();
|
|
10
|
+
var UPLOAD_DEDUPLICATION_PIPELINE_VERSION = 1;
|
|
9
11
|
var parseOptionalPositiveInt = (rawValue) => {
|
|
10
12
|
if (typeof rawValue !== "string") return null;
|
|
11
13
|
const normalized = rawValue.trim();
|
|
@@ -26,6 +28,7 @@ var getSessionTtlMs = () => {
|
|
|
26
28
|
};
|
|
27
29
|
var getRawBodyLimitBytes = (chunkSizeBytes) => chunkSizeBytes + 1024 * 1024;
|
|
28
30
|
var getBucketName = () => (process.env.RB_FILESYSTEM_BUCKET_NAME ?? "").trim() || "fs";
|
|
31
|
+
var getFileReferencesCollectionName = (bucketName) => `${bucketName}.references`;
|
|
29
32
|
var getUserId = (ctx) => {
|
|
30
33
|
const raw = ctx.req.session?.user?.id;
|
|
31
34
|
if (typeof raw !== "string") return null;
|
|
@@ -53,6 +56,55 @@ var ensureUploadIndexes = async (UploadSession, UploadChunk) => {
|
|
|
53
56
|
await Promise.all([UploadSession.createIndexes(), UploadChunk.createIndexes()]);
|
|
54
57
|
if (dbName) ensuredIndexDbNames.add(dbName);
|
|
55
58
|
};
|
|
59
|
+
var ensureFilesystemUploadIndexes = async (db, bucketName) => {
|
|
60
|
+
await Promise.all([db.collection(`${bucketName}.files`).createIndex({ "metadata.deduplication.key": 1 }, {
|
|
61
|
+
name: "rb_upload_deduplication_key_unique",
|
|
62
|
+
unique: true,
|
|
63
|
+
partialFilterExpression: { "metadata.deduplication.key": { $type: "string" } }
|
|
64
|
+
}), db.collection(getFileReferencesCollectionName(bucketName)).createIndex({ blobId: 1 }, { name: "rb_upload_file_reference_blob" })]);
|
|
65
|
+
};
|
|
66
|
+
var resolveUploadAccessScope = ({ accessScope, isPublic }) => accessScope ?? (isPublic ? "public" : "owner");
|
|
67
|
+
var resolveStoredUploadAccessScope = (metadata) => {
|
|
68
|
+
const accessScope = metadata.accessScope;
|
|
69
|
+
if (accessScope === "owner" || accessScope === "tenant" || accessScope === "public") return accessScope;
|
|
70
|
+
return metadata.isPublic === true || String(metadata.isPublic).trim().toLowerCase() === "true" ? "public" : "owner";
|
|
71
|
+
};
|
|
72
|
+
var buildUploadDeduplication = ({ namespace, hash, filename, mimeType, totalSize, accessScope, userId, ownerKeyHash }) => {
|
|
73
|
+
const ownerPartition = accessScope === "owner" ? userId ? `user:${userId}` : ownerKeyHash ? `key:${ownerKeyHash}` : null : accessScope;
|
|
74
|
+
if (!ownerPartition) return null;
|
|
75
|
+
const normalizedNamespace = namespace.trim();
|
|
76
|
+
const normalizedHash = normalizeSha256Hex(hash);
|
|
77
|
+
const normalizedMimeType = mimeType.trim().toLowerCase();
|
|
78
|
+
const normalizedExtension = extname(filename.trim()).toLowerCase();
|
|
79
|
+
return {
|
|
80
|
+
namespace: normalizedNamespace,
|
|
81
|
+
algorithm: "sha256",
|
|
82
|
+
hash: normalizedHash,
|
|
83
|
+
key: computeSha256Hex(Buffer.from(JSON.stringify([
|
|
84
|
+
UPLOAD_DEDUPLICATION_PIPELINE_VERSION,
|
|
85
|
+
normalizedNamespace,
|
|
86
|
+
normalizedHash,
|
|
87
|
+
totalSize,
|
|
88
|
+
normalizedMimeType,
|
|
89
|
+
normalizedExtension,
|
|
90
|
+
accessScope,
|
|
91
|
+
ownerPartition
|
|
92
|
+
]))),
|
|
93
|
+
pipelineVersion: UPLOAD_DEDUPLICATION_PIPELINE_VERSION
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
var buildUploadAccessMetadata = (session) => {
|
|
97
|
+
const accessScope = resolveUploadAccessScope({
|
|
98
|
+
accessScope: session.accessScope,
|
|
99
|
+
isPublic: session.isPublic
|
|
100
|
+
});
|
|
101
|
+
return {
|
|
102
|
+
accessScope,
|
|
103
|
+
isPublic: accessScope === "public",
|
|
104
|
+
...typeof session.ownerKeyHash === "string" ? { ownerKeyHash: session.ownerKeyHash } : {},
|
|
105
|
+
...typeof session.userId === "string" ? { userId: session.userId } : {}
|
|
106
|
+
};
|
|
107
|
+
};
|
|
56
108
|
var normalizeUploadKey = (raw) => {
|
|
57
109
|
if (typeof raw !== "string") return null;
|
|
58
110
|
const normalized = raw.trim();
|
|
@@ -74,6 +126,6 @@ var buildUploadsAbility = (ctx, tenantId) => {
|
|
|
74
126
|
};
|
|
75
127
|
var getUploadSessionAccessQuery = (ability, action) => getAccessibleByQuery(ability, action, "RBUploadSession");
|
|
76
128
|
//#endregion
|
|
77
|
-
export {
|
|
129
|
+
export { getUserId as _, ensureFilesystemUploadIndexes as a, resolveUploadAccessScope as b, getChunkSizeBytes as c, getModelCtx as d, getRawBodyLimitBytes as f, getUploadSessionAccessQuery as g, getUploadKeyHash as h, computeSha256Hex as i, getFileReferencesCollectionName as l, getTenantId as m, buildUploadDeduplication as n, ensureUploadIndexes as o, getSessionTtlMs as p, buildUploadsAbility as r, getBucketName as s, buildUploadAccessMetadata as t, getMaxClientUploadBytesPerSecond as u, normalizeSha256Hex as v, toBufferPayload as x, resolveStoredUploadAccessScope as y };
|
|
78
130
|
|
|
79
|
-
//# sourceMappingURL=shared-
|
|
131
|
+
//# sourceMappingURL=shared-Zt17vuAT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-Zt17vuAT.js","names":["createHash","timingSafeEqual","extname","Ctx","IRBUploadChunk","IRBUploadSession","LoadModelCtx","buildAbilityFromSession","getAccessibleByQuery","AppAbility","Db","Model","SessionUser","id","currentTenantId","UploadSessionDoc","UploadChunkDoc","Omit","data","Buffer","DEFAULT_CHUNK_SIZE_BYTES","MAX_CHUNK_SIZE_BYTES","DEFAULT_MAX_CLIENT_BYTES_PER_SECOND","DEFAULT_SESSION_TTL_S","ensuredIndexDbNames","Set","UploadAccessScope","UploadDeduplication","NonNullable","UPLOAD_DEDUPLICATION_PIPELINE_VERSION","parseOptionalPositiveInt","rawValue","normalized","trim","parsed","Number","isFinite","Math","floor","getChunkSizeBytes","configured","process","env","RB_UPLOAD_CHUNK_SIZE_BYTES","resolved","min","getMaxClientUploadBytesPerSecond","RB_UPLOAD_MAX_CLIENT_BYTES_PER_SECOND","getSessionTtlMs","ttlSeconds","RB_UPLOAD_SESSION_TTL_S","getRawBodyLimitBytes","chunkSizeBytes","getBucketName","RB_FILESYSTEM_BUCKET_NAME","getFileReferencesCollectionName","bucketName","getUserId","ctx","raw","req","session","user","getTenantId","rawSession","sessionTenantId","computeSha256Hex","update","digest","normalizeSha256Hex","value","toLowerCase","getModelCtx","_ctx","tenantId","ability","toBufferPayload","payload","isBuffer","Uint8Array","from","ensureUploadIndexes","UploadSession","UploadChunk","Promise","dbName","String","db","name","has","all","createIndexes","add","ensureFilesystemUploadIndexes","collection","createIndex","unique","partialFilterExpression","$type","blobId","resolveUploadAccessScope","accessScope","isPublic","resolveStoredUploadAccessScope","metadata","Record","buildUploadDeduplication","namespace","hash","filename","mimeType","totalSize","userId","ownerKeyHash","ownerPartition","normalizedNamespace","normalizedHash","normalizedMimeType","normalizedExtension","key","JSON","stringify","algorithm","pipelineVersion","buildUploadAccessMetadata","Pick","normalizeUploadKey","getUploadKeyHash","uploadKey","get","buildUploadsAbility","uploadKeyHash","claims","undefined","getUploadSessionAccessQuery","action","timingSafeEqualHex","left","right","length","getOwnershipSelector"],"sources":["../src/uploads/api/file-uploads/shared.ts"],"sourcesContent":["import { createHash, timingSafeEqual } from \"node:crypto\"\nimport { extname } from \"node:path\"\n\nimport { Ctx } from \"@rpcbase/api\"\nimport {\n type IRBUploadChunk,\n type IRBUploadSession,\n type LoadModelCtx,\n} from \"@rpcbase/db\"\nimport { buildAbilityFromSession, getAccessibleByQuery, type AppAbility } from \"@rpcbase/db/acl\"\nimport type { Db } from \"mongodb\"\nimport type { Model } from \"mongoose\"\n\n\nexport type SessionUser = {\n id?: string\n currentTenantId?: string\n}\n\nexport type UploadSessionDoc = IRBUploadSession\nexport type UploadChunkDoc = Omit<IRBUploadChunk, \"data\"> & { data: Buffer }\n\nconst DEFAULT_CHUNK_SIZE_BYTES = 5 * 1024 * 1024\nconst MAX_CHUNK_SIZE_BYTES = 15 * 1024 * 1024\n\nconst DEFAULT_MAX_CLIENT_BYTES_PER_SECOND = 10 * 1024 * 1024\n\nconst DEFAULT_SESSION_TTL_S = 60 * 60 * 24\n\nconst ensuredIndexDbNames = new Set<string>()\n\nexport type UploadAccessScope = \"owner\" | \"tenant\" | \"public\"\nexport type UploadDeduplication = NonNullable<IRBUploadSession[\"deduplication\"]>\n\nconst UPLOAD_DEDUPLICATION_PIPELINE_VERSION = 1\n\nconst parseOptionalPositiveInt = (rawValue: unknown): number | null => {\n if (typeof rawValue !== \"string\") return null\n const normalized = rawValue.trim()\n if (!normalized) return null\n const parsed = Number(normalized)\n if (!Number.isFinite(parsed) || parsed <= 0) return null\n return Math.floor(parsed)\n}\n\nexport const getChunkSizeBytes = (): number => {\n const configured = parseOptionalPositiveInt(process.env.RB_UPLOAD_CHUNK_SIZE_BYTES)\n const resolved = configured ?? DEFAULT_CHUNK_SIZE_BYTES\n return Math.min(MAX_CHUNK_SIZE_BYTES, resolved)\n}\n\nexport const getMaxClientUploadBytesPerSecond = (): number | null => {\n const configured = parseOptionalPositiveInt(process.env.RB_UPLOAD_MAX_CLIENT_BYTES_PER_SECOND)\n return configured ?? DEFAULT_MAX_CLIENT_BYTES_PER_SECOND\n}\n\nexport const getSessionTtlMs = (): number => {\n const ttlSeconds = parseOptionalPositiveInt(process.env.RB_UPLOAD_SESSION_TTL_S) ?? DEFAULT_SESSION_TTL_S\n return ttlSeconds * 1000\n}\n\nexport const getRawBodyLimitBytes = (chunkSizeBytes: number): number => chunkSizeBytes + 1024 * 1024\n\nexport const getBucketName = (): string => (process.env.RB_FILESYSTEM_BUCKET_NAME ?? \"\").trim() || \"fs\"\n\nexport const getFileReferencesCollectionName = (bucketName: string): string => `${bucketName}.references`\n\nexport const getUserId = (ctx: Ctx<SessionUser>): string | null => {\n const raw = ctx.req.session?.user?.id\n if (typeof raw !== \"string\") return null\n const normalized = raw.trim()\n return normalized ? normalized : null\n}\n\nexport const getTenantId = (ctx: Ctx<SessionUser>): string | null => {\n const rawSession = ctx.req.session?.user?.currentTenantId\n const sessionTenantId = typeof rawSession === \"string\" ? rawSession.trim() : \"\"\n return sessionTenantId || null\n}\n\nexport const computeSha256Hex = (data: Buffer): string => createHash(\"sha256\").update(data).digest(\"hex\")\n\nexport const normalizeSha256Hex = (value: string): string => value.trim().toLowerCase()\n\nexport const getModelCtx = (_ctx: Ctx<SessionUser>, tenantId: string, ability?: AppAbility): LoadModelCtx => ({\n req: {\n session: {\n user: {\n currentTenantId: tenantId,\n },\n },\n },\n ability,\n})\n\nexport const toBufferPayload = (payload: unknown): Buffer | null => {\n if (Buffer.isBuffer(payload)) return payload\n if (payload instanceof Uint8Array) return Buffer.from(payload)\n return null\n}\n\nexport const ensureUploadIndexes = async (\n UploadSession: Model<UploadSessionDoc>,\n UploadChunk: Model<UploadChunkDoc>,\n): Promise<void> => {\n const dbName = String((UploadSession as unknown as { db?: { name?: unknown } })?.db?.name ?? \"\")\n if (dbName && ensuredIndexDbNames.has(dbName)) return\n\n await Promise.all([\n UploadSession.createIndexes(),\n UploadChunk.createIndexes(),\n ])\n\n if (dbName) ensuredIndexDbNames.add(dbName)\n}\n\nexport const ensureFilesystemUploadIndexes = async (db: Db, bucketName: string): Promise<void> => {\n await Promise.all([\n db.collection(`${bucketName}.files`).createIndex(\n { \"metadata.deduplication.key\": 1 },\n {\n name: \"rb_upload_deduplication_key_unique\",\n unique: true,\n partialFilterExpression: { \"metadata.deduplication.key\": { $type: \"string\" } },\n },\n ),\n db.collection(getFileReferencesCollectionName(bucketName)).createIndex(\n { blobId: 1 },\n { name: \"rb_upload_file_reference_blob\" },\n ),\n ])\n}\n\nexport const resolveUploadAccessScope = ({\n accessScope,\n isPublic,\n}: {\n accessScope?: UploadAccessScope\n isPublic?: boolean\n}): UploadAccessScope => accessScope ?? (isPublic ? \"public\" : \"owner\")\n\nexport const resolveStoredUploadAccessScope = (metadata: Record<string, unknown>): UploadAccessScope => {\n const accessScope = metadata.accessScope\n if (accessScope === \"owner\" || accessScope === \"tenant\" || accessScope === \"public\") {\n return accessScope\n }\n return metadata.isPublic === true || String(metadata.isPublic).trim().toLowerCase() === \"true\" ? \"public\" : \"owner\"\n}\n\nexport const buildUploadDeduplication = ({\n namespace,\n hash,\n filename,\n mimeType,\n totalSize,\n accessScope,\n userId,\n ownerKeyHash,\n}: {\n namespace: string\n hash: string\n filename: string\n mimeType: string\n totalSize: number\n accessScope: UploadAccessScope\n userId?: string\n ownerKeyHash?: string\n}): UploadDeduplication | null => {\n const ownerPartition = accessScope === \"owner\"\n ? userId\n ? `user:${userId}`\n : ownerKeyHash\n ? `key:${ownerKeyHash}`\n : null\n : accessScope\n if (!ownerPartition) return null\n\n const normalizedNamespace = namespace.trim()\n const normalizedHash = normalizeSha256Hex(hash)\n const normalizedMimeType = mimeType.trim().toLowerCase()\n const normalizedExtension = extname(filename.trim()).toLowerCase()\n const key = computeSha256Hex(Buffer.from(JSON.stringify([\n UPLOAD_DEDUPLICATION_PIPELINE_VERSION,\n normalizedNamespace,\n normalizedHash,\n totalSize,\n normalizedMimeType,\n normalizedExtension,\n accessScope,\n ownerPartition,\n ])))\n\n return {\n namespace: normalizedNamespace,\n algorithm: \"sha256\",\n hash: normalizedHash,\n key,\n pipelineVersion: UPLOAD_DEDUPLICATION_PIPELINE_VERSION,\n }\n}\n\nexport const buildUploadAccessMetadata = (\n session: Pick<UploadSessionDoc, \"accessScope\" | \"isPublic\" | \"userId\" | \"ownerKeyHash\">,\n): Record<string, unknown> => {\n const accessScope = resolveUploadAccessScope({\n accessScope: session.accessScope,\n isPublic: session.isPublic,\n })\n\n return {\n accessScope,\n isPublic: accessScope === \"public\",\n ...(typeof session.ownerKeyHash === \"string\" ? { ownerKeyHash: session.ownerKeyHash } : {}),\n ...(typeof session.userId === \"string\" ? { userId: session.userId } : {}),\n }\n}\n\nconst normalizeUploadKey = (raw: unknown): string | null => {\n if (typeof raw !== \"string\") return null\n const normalized = raw.trim()\n return normalized ? normalized : null\n}\n\nexport const getUploadKeyHash = (ctx: Ctx<SessionUser>): string | null => {\n const uploadKey = normalizeUploadKey(ctx.req.get(\"X-Upload-Key\"))\n if (!uploadKey) return null\n return computeSha256Hex(Buffer.from(uploadKey))\n}\n\nexport const buildUploadsAbility = (ctx: Ctx<SessionUser>, tenantId: string): AppAbility => {\n const uploadKeyHash = getUploadKeyHash(ctx)\n const claims = uploadKeyHash ? { uploadKeyHash } : undefined\n return buildAbilityFromSession({ tenantId, session: ctx.req.session, claims })\n}\n\nexport const getUploadSessionAccessQuery = (\n ability: AppAbility,\n action: \"read\" | \"update\" | \"delete\",\n): Record<string, unknown> => getAccessibleByQuery(ability, action, \"RBUploadSession\")\n\nconst timingSafeEqualHex = (left: string, right: string): boolean => {\n if (left.length !== right.length) return false\n try {\n return timingSafeEqual(Buffer.from(left, \"hex\"), Buffer.from(right, \"hex\"))\n } catch {\n return false\n }\n}\n\nexport const getOwnershipSelector = (\n ctx: Ctx<SessionUser>,\n session: Pick<UploadSessionDoc, \"userId\" | \"ownerKeyHash\">,\n): { userId?: string; ownerKeyHash?: string } | null => {\n if (session.userId) {\n const userId = getUserId(ctx)\n if (!userId || userId !== session.userId) return null\n return { userId: session.userId }\n }\n\n if (session.ownerKeyHash) {\n const uploadKeyHash = getUploadKeyHash(ctx)\n if (!uploadKeyHash) return null\n if (!timingSafeEqualHex(session.ownerKeyHash, uploadKeyHash)) return null\n return { ownerKeyHash: session.ownerKeyHash }\n }\n\n return null\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ObjectId, Db } from 'mongodb';
|
|
2
|
+
import { UploadAccessScope, UploadDeduplication } from './shared';
|
|
3
|
+
export type UploadFileReference = {
|
|
4
|
+
_id: ObjectId;
|
|
5
|
+
blobId: ObjectId;
|
|
6
|
+
filename: string;
|
|
7
|
+
mimeType: string;
|
|
8
|
+
totalSize: number;
|
|
9
|
+
accessScope: UploadAccessScope;
|
|
10
|
+
isPublic: boolean;
|
|
11
|
+
userId?: string;
|
|
12
|
+
ownerKeyHash?: string;
|
|
13
|
+
deduplicationKey: string;
|
|
14
|
+
createdAt: Date;
|
|
15
|
+
};
|
|
16
|
+
type CreateUploadFileReferenceOptions = {
|
|
17
|
+
tenantId: string;
|
|
18
|
+
bucketName: string;
|
|
19
|
+
blobId: ObjectId;
|
|
20
|
+
filename: string;
|
|
21
|
+
mimeType: string;
|
|
22
|
+
totalSize: number;
|
|
23
|
+
accessScope: UploadAccessScope;
|
|
24
|
+
userId?: string;
|
|
25
|
+
ownerKeyHash?: string;
|
|
26
|
+
deduplicationKey: string;
|
|
27
|
+
};
|
|
28
|
+
export declare const findUploadFileReference: (db: Db, bucketName: string, referenceId: ObjectId) => Promise<UploadFileReference | null>;
|
|
29
|
+
export declare const createUploadFileReference: ({ tenantId, bucketName, blobId, filename, mimeType, totalSize, accessScope, userId, ownerKeyHash, deduplicationKey, }: CreateUploadFileReferenceOptions) => Promise<string | null>;
|
|
30
|
+
export declare const claimUploadFileReference: ({ tenantId, bucketName, blobId, filename, mimeType, totalSize, accessScope, userId, ownerKeyHash, deduplication, }: Omit<CreateUploadFileReferenceOptions, "deduplicationKey"> & {
|
|
31
|
+
deduplication: UploadDeduplication;
|
|
32
|
+
}) => Promise<string | null>;
|
|
33
|
+
export declare const deleteUploadFileReference: ({ tenantId, bucketName, referenceId, }: {
|
|
34
|
+
tenantId: string;
|
|
35
|
+
bucketName: string;
|
|
36
|
+
referenceId: ObjectId;
|
|
37
|
+
}) => Promise<{
|
|
38
|
+
deleted: boolean;
|
|
39
|
+
blobDeleted: boolean;
|
|
40
|
+
}>;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=fileReferences.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileReferences.d.ts","sourceRoot":"","sources":["../../../../src/uploads/api/file-uploads/fileReferences.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,MAAM,SAAS,CAAA;AAE3C,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACzB,MAAM,UAAU,CAAA;AAGjB,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,EAAE,QAAQ,CAAA;IACb,MAAM,EAAE,QAAQ,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,iBAAiB,CAAA;IAC9B,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,IAAI,CAAA;CAChB,CAAA;AAED,KAAK,gCAAgC,GAAG;IACtC,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,QAAQ,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,iBAAiB,CAAA;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,eAAO,MAAM,uBAAuB,GAClC,IAAI,EAAE,EACN,YAAY,MAAM,EAClB,aAAa,QAAQ,KACpB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAIpC,CAAA;AAED,eAAO,MAAM,yBAAyB,GAAU,uHAW7C,gCAAgC,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAyC1D,CAAA;AAED,eAAO,MAAM,wBAAwB,GAAU,oHAW5C,IAAI,CAAC,gCAAgC,EAAE,kBAAkB,CAAC,GAAG;IAC9D,aAAa,EAAE,mBAAmB,CAAA;CACnC,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CA4CxB,CAAA;AAED,eAAO,MAAM,yBAAyB,GAAU,wCAI7C;IACD,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,QAAQ,CAAA;CACtB,KAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAoDrD,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completeUpload.d.ts","sourceRoot":"","sources":["../../../../../src/uploads/api/file-uploads/handlers/completeUpload.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"completeUpload.d.ts","sourceRoot":"","sources":["../../../../../src/uploads/api/file-uploads/handlers/completeUpload.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAKzC,OAAO,KAAK,OAAO,MAAM,UAAU,CAAA;AAOnC,OAAO,EACL,KAAK,WAAW,EAYjB,MAAM,WAAW,CAAA;AAwDlB,eAAO,MAAM,cAAc,EAAE,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,uBAAuB,EAAE,WAAW,CAkc1G,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initUpload.d.ts","sourceRoot":"","sources":["../../../../../src/uploads/api/file-uploads/handlers/initUpload.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAKzC,OAAO,KAAK,OAAO,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"initUpload.d.ts","sourceRoot":"","sources":["../../../../../src/uploads/api/file-uploads/handlers/initUpload.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAKzC,OAAO,KAAK,OAAO,MAAM,UAAU,CAAA;AAEnC,OAAO,EACL,KAAK,WAAW,EAejB,MAAM,WAAW,CAAA;AAGlB,eAAO,MAAM,UAAU,EAAE,UAAU,CAAC,OAAO,CAAC,kBAAkB,EAAE,OAAO,CAAC,mBAAmB,EAAE,WAAW,CAqIvG,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"imageVariantsPostProcessor.d.ts","sourceRoot":"","sources":["../../../../src/uploads/api/file-uploads/imageVariantsPostProcessor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"imageVariantsPostProcessor.d.ts","sourceRoot":"","sources":["../../../../src/uploads/api/file-uploads/imageVariantsPostProcessor.ts"],"names":[],"mappings":"AAkMA,eAAO,MAAM,kCAAkC,QAAO,IAKrD,CAAA"}
|
|
@@ -3,10 +3,30 @@ export declare const InitRoute = "/api/rb/file-uploads";
|
|
|
3
3
|
export declare const ChunkRoute = "/api/rb/file-uploads/:uploadId/chunks/:index";
|
|
4
4
|
export declare const StatusRoute = "/api/rb/file-uploads/:uploadId/status";
|
|
5
5
|
export declare const CompleteRoute = "/api/rb/file-uploads/:uploadId/complete";
|
|
6
|
+
export declare const uploadAccessScopeSchema: z.ZodEnum<{
|
|
7
|
+
owner: "owner";
|
|
8
|
+
tenant: "tenant";
|
|
9
|
+
public: "public";
|
|
10
|
+
}>;
|
|
11
|
+
export declare const uploadDeduplicationSchema: z.ZodObject<{
|
|
12
|
+
namespace: z.ZodString;
|
|
13
|
+
algorithm: z.ZodLiteral<"sha256">;
|
|
14
|
+
hash: z.ZodString;
|
|
15
|
+
}, z.core.$strip>;
|
|
6
16
|
export declare const initRequestSchema: z.ZodObject<{
|
|
7
17
|
filename: z.ZodString;
|
|
8
18
|
mimeType: z.ZodString;
|
|
9
19
|
isPublic: z.ZodOptional<z.ZodBoolean>;
|
|
20
|
+
accessScope: z.ZodOptional<z.ZodEnum<{
|
|
21
|
+
owner: "owner";
|
|
22
|
+
tenant: "tenant";
|
|
23
|
+
public: "public";
|
|
24
|
+
}>>;
|
|
25
|
+
deduplication: z.ZodOptional<z.ZodObject<{
|
|
26
|
+
namespace: z.ZodString;
|
|
27
|
+
algorithm: z.ZodLiteral<"sha256">;
|
|
28
|
+
hash: z.ZodString;
|
|
29
|
+
}, z.core.$strip>>;
|
|
10
30
|
totalSize: z.ZodNumber;
|
|
11
31
|
}, z.core.$strip>;
|
|
12
32
|
export type InitRequestPayload = z.infer<typeof initRequestSchema>;
|
|
@@ -17,6 +37,8 @@ export declare const initResponseSchema: z.ZodObject<{
|
|
|
17
37
|
uploadKey: z.ZodOptional<z.ZodString>;
|
|
18
38
|
chunkSize: z.ZodOptional<z.ZodNumber>;
|
|
19
39
|
chunksTotal: z.ZodOptional<z.ZodNumber>;
|
|
40
|
+
fileId: z.ZodOptional<z.ZodString>;
|
|
41
|
+
deduplicated: z.ZodOptional<z.ZodBoolean>;
|
|
20
42
|
}, z.core.$strip>;
|
|
21
43
|
export type InitResponsePayload = z.infer<typeof initResponseSchema>;
|
|
22
44
|
export declare const statusResponseSchema: z.ZodObject<{
|
|
@@ -38,6 +60,7 @@ export declare const completeResponseSchema: z.ZodObject<{
|
|
|
38
60
|
ok: z.ZodBoolean;
|
|
39
61
|
error: z.ZodOptional<z.ZodString>;
|
|
40
62
|
fileId: z.ZodOptional<z.ZodString>;
|
|
63
|
+
deduplicated: z.ZodOptional<z.ZodBoolean>;
|
|
41
64
|
}, z.core.$strip>;
|
|
42
65
|
export type CompleteResponsePayload = z.infer<typeof completeResponseSchema>;
|
|
43
66
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/uploads/api/file-uploads/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,SAAS,yBAAyB,CAAA;AAC/C,eAAO,MAAM,UAAU,iDAAiD,CAAA;AACxE,eAAO,MAAM,WAAW,0CAA0C,CAAA;AAClE,eAAO,MAAM,aAAa,4CAA4C,CAAA;AAEtE,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/uploads/api/file-uploads/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,SAAS,yBAAyB,CAAA;AAC/C,eAAO,MAAM,UAAU,iDAAiD,CAAA;AACxE,eAAO,MAAM,WAAW,0CAA0C,CAAA;AAClE,eAAO,MAAM,aAAa,4CAA4C,CAAA;AAEtE,eAAO,MAAM,uBAAuB;;;;EAAwC,CAAA;AAE5E,eAAO,MAAM,yBAAyB;;;;iBAIpC,CAAA;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;iBAe5B,CAAA;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAElE,eAAO,MAAM,kBAAkB;;;;;;;;;iBAS7B,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAEpE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;iBAQ/B,CAAA;AAEF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAExE,eAAO,MAAM,sBAAsB;;;;;iBAKjC,CAAA;AAEF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { UploadAccessScope } from './shared';
|
|
1
2
|
export type UploadPostProcessorContext = {
|
|
2
3
|
tenantId: string;
|
|
3
4
|
uploadId: string;
|
|
@@ -7,6 +8,7 @@ export type UploadPostProcessorContext = {
|
|
|
7
8
|
clientMimeType: string;
|
|
8
9
|
totalSize: number;
|
|
9
10
|
isPublic?: boolean;
|
|
11
|
+
accessScope?: UploadAccessScope;
|
|
10
12
|
userId?: string;
|
|
11
13
|
ownerKeyHash?: string;
|
|
12
14
|
inlineProcessors: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postProcessors.d.ts","sourceRoot":"","sources":["../../../../src/uploads/api/file-uploads/postProcessors.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"postProcessors.d.ts","sourceRoot":"","sources":["../../../../src/uploads/api/file-uploads/postProcessors.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAGjD,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAClC,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,0BAA0B,KAAK,OAAO,CAAA;IACpD,OAAO,EAAE,CAAC,GAAG,EAAE,0BAA0B,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAA;CACzE,CAAA;AAGD,eAAO,MAAM,2BAA2B,8BAA8B,CAAA;AAUtE,eAAO,MAAM,2BAA2B,GAAI,WAAW,mBAAmB,KAAG,IAa5E,CAAA;AAED,eAAO,MAAM,uBAAuB,cAfmB,mBAAmB,KAAG,IAeX,CAAA;AAElE,eAAO,MAAM,6BAA6B,GAAI,IAAI,MAAM,KAAG,IAI1D,CAAA;AAED,eAAO,MAAM,yBAAyB,OANY,MAAM,KAAG,IAMW,CAAA;AAEtE,eAAO,MAAM,yBAAyB,QAAO,IAI5C,CAAA;AAED,eAAO,MAAM,qBAAqB,QANW,IAMiB,CAAA;AAE9D,eAAO,MAAM,uBAAuB,QAAO,mBAAmB,EAAmC,CAAA;AAEjG,eAAO,MAAM,mBAAmB,QAFW,mBAAmB,EAEJ,CAAA;AAE1D,eAAO,MAAM,uBAAuB,GAAU,KAAK,0BAA0B,KAAG,OAAO,CAAC,IAAI,CAoC3F,CAAA;AAID,eAAO,MAAM,+BAA+B,QAAO,IAOlD,CAAA;AAED,eAAO,MAAM,2BAA2B,GAAU,KAAK,0BAA0B,KAAG,OAAO,CAAC,IAAI,CAO/F,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Ctx } from '@rpcbase/api';
|
|
2
2
|
import { IRBUploadChunk, IRBUploadSession, LoadModelCtx } from '@rpcbase/db';
|
|
3
3
|
import { AppAbility } from '@rpcbase/db/acl';
|
|
4
|
+
import { Db } from 'mongodb';
|
|
4
5
|
import { Model } from 'mongoose';
|
|
5
6
|
export type SessionUser = {
|
|
6
7
|
id?: string;
|
|
@@ -10,11 +11,14 @@ export type UploadSessionDoc = IRBUploadSession;
|
|
|
10
11
|
export type UploadChunkDoc = Omit<IRBUploadChunk, "data"> & {
|
|
11
12
|
data: Buffer;
|
|
12
13
|
};
|
|
14
|
+
export type UploadAccessScope = "owner" | "tenant" | "public";
|
|
15
|
+
export type UploadDeduplication = NonNullable<IRBUploadSession["deduplication"]>;
|
|
13
16
|
export declare const getChunkSizeBytes: () => number;
|
|
14
17
|
export declare const getMaxClientUploadBytesPerSecond: () => number | null;
|
|
15
18
|
export declare const getSessionTtlMs: () => number;
|
|
16
19
|
export declare const getRawBodyLimitBytes: (chunkSizeBytes: number) => number;
|
|
17
20
|
export declare const getBucketName: () => string;
|
|
21
|
+
export declare const getFileReferencesCollectionName: (bucketName: string) => string;
|
|
18
22
|
export declare const getUserId: (ctx: Ctx<SessionUser>) => string | null;
|
|
19
23
|
export declare const getTenantId: (ctx: Ctx<SessionUser>) => string | null;
|
|
20
24
|
export declare const computeSha256Hex: (data: Buffer) => string;
|
|
@@ -22,6 +26,23 @@ export declare const normalizeSha256Hex: (value: string) => string;
|
|
|
22
26
|
export declare const getModelCtx: (_ctx: Ctx<SessionUser>, tenantId: string, ability?: AppAbility) => LoadModelCtx;
|
|
23
27
|
export declare const toBufferPayload: (payload: unknown) => Buffer | null;
|
|
24
28
|
export declare const ensureUploadIndexes: (UploadSession: Model<UploadSessionDoc>, UploadChunk: Model<UploadChunkDoc>) => Promise<void>;
|
|
29
|
+
export declare const ensureFilesystemUploadIndexes: (db: Db, bucketName: string) => Promise<void>;
|
|
30
|
+
export declare const resolveUploadAccessScope: ({ accessScope, isPublic, }: {
|
|
31
|
+
accessScope?: UploadAccessScope;
|
|
32
|
+
isPublic?: boolean;
|
|
33
|
+
}) => UploadAccessScope;
|
|
34
|
+
export declare const resolveStoredUploadAccessScope: (metadata: Record<string, unknown>) => UploadAccessScope;
|
|
35
|
+
export declare const buildUploadDeduplication: ({ namespace, hash, filename, mimeType, totalSize, accessScope, userId, ownerKeyHash, }: {
|
|
36
|
+
namespace: string;
|
|
37
|
+
hash: string;
|
|
38
|
+
filename: string;
|
|
39
|
+
mimeType: string;
|
|
40
|
+
totalSize: number;
|
|
41
|
+
accessScope: UploadAccessScope;
|
|
42
|
+
userId?: string;
|
|
43
|
+
ownerKeyHash?: string;
|
|
44
|
+
}) => UploadDeduplication | null;
|
|
45
|
+
export declare const buildUploadAccessMetadata: (session: Pick<UploadSessionDoc, "accessScope" | "isPublic" | "userId" | "ownerKeyHash">) => Record<string, unknown>;
|
|
25
46
|
export declare const getUploadKeyHash: (ctx: Ctx<SessionUser>) => string | null;
|
|
26
47
|
export declare const buildUploadsAbility: (ctx: Ctx<SessionUser>, tenantId: string) => AppAbility;
|
|
27
48
|
export declare const getUploadSessionAccessQuery: (ability: AppAbility, action: "read" | "update" | "delete") => Record<string, unknown>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../src/uploads/api/file-uploads/shared.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../src/uploads/api/file-uploads/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deleteFile.d.ts","sourceRoot":"","sources":["../../../../../src/uploads/api/files/handlers/deleteFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"deleteFile.d.ts","sourceRoot":"","sources":["../../../../../src/uploads/api/files/handlers/deleteFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAQzC,OAAO,EAML,KAAK,WAAW,EACjB,MAAM,2BAA2B,CAAA;AAGlC,KAAK,qBAAqB,GAAG;IAC3B,EAAE,EAAE,OAAO,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAqBD,eAAO,MAAM,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,qBAAqB,EAAE,WAAW,CAgH5F,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFile.d.ts","sourceRoot":"","sources":["../../../../../src/uploads/api/files/handlers/getFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"getFile.d.ts","sourceRoot":"","sources":["../../../../../src/uploads/api/files/handlers/getFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAKzC,OAAO,EAML,KAAK,WAAW,EACjB,MAAM,2BAA2B,CAAA;AAyElC,eAAO,MAAM,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,CA+HzF,CAAA"}
|
package/dist/uploads/worker.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { o as registerUploadPostProcessor, s as registerUploadPostProcessorTask } from "../postProcessors-iffHvje4.js";
|
|
2
|
-
import {
|
|
2
|
+
import { s as getBucketName } from "../shared-Zt17vuAT.js";
|
|
3
3
|
import { n as registerConvertHeifToWebpTask } from "../convertHeifToWebp-BT1n72DQ.js";
|
|
4
4
|
import { GridFSBucket, ObjectId } from "mongodb";
|
|
5
5
|
import { getTenantFilesystemDb } from "@rpcbase/db";
|
|
@@ -56,7 +56,7 @@ var imageVariantsPostProcessor = {
|
|
|
56
56
|
if (typeof metadata.variantOf === "string") return false;
|
|
57
57
|
return supportedImageMimeTypes.has(normalizeMimeType(mimeType));
|
|
58
58
|
},
|
|
59
|
-
process: async ({ tenantId, fileId, filename, isPublic, userId, ownerKeyHash, totalSize }) => {
|
|
59
|
+
process: async ({ tenantId, fileId, filename, isPublic, accessScope, userId, ownerKeyHash, totalSize }) => {
|
|
60
60
|
const originalObjectId = toObjectId(fileId);
|
|
61
61
|
if (!originalObjectId) return;
|
|
62
62
|
const nativeDb = (await getTenantFilesystemDb(tenantId)).db;
|
|
@@ -106,6 +106,7 @@ var imageVariantsPostProcessor = {
|
|
|
106
106
|
variantFormat: IMAGE_VARIANT_FORMAT,
|
|
107
107
|
variantsVersion: IMAGE_VARIANTS_VERSION,
|
|
108
108
|
...typeof isPublic === "boolean" ? { isPublic } : {},
|
|
109
|
+
...accessScope ? { accessScope } : {},
|
|
109
110
|
...userId ? { userId } : {},
|
|
110
111
|
...ownerKeyHash ? { ownerKeyHash } : {}
|
|
111
112
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.js","names":["getTenantFilesystemDb","GridFSBucket","ObjectId","sharp","registerUploadPostProcessor","getBucketName","IMAGE_VARIANTS_PROCESSOR_ID","IMAGE_VARIANTS_VERSION","IMAGE_VARIANT_WIDTHS","const","IMAGE_VARIANT_QUALITY","IMAGE_VARIANT_MIME_TYPE","IMAGE_VARIANT_FORMAT","IMAGE_VARIANT_MAX_INPUT_BYTES","IMAGE_VARIANT_MAX_INPUT_PIXELS","supportedImageMimeTypes","Set","ImageVariantRecord","fileId","width","height","mimeType","size","normalizeMimeType","value","trim","toLowerCase","toObjectId","readGridFsFile","bucket","Promise","Buffer","resolve","reject","chunks","stream","openDownloadStream","on","chunk","push","isBuffer","from","once","concat","writeGridFsFile","filename","data","metadata","Record","openUploadStream","String","id","end","imageVariantsPostProcessor","version","match","variantOf","has","process","tenantId","isPublic","userId","ownerKeyHash","totalSize","originalObjectId","fsDb","nativeDb","db","bucketName","filesCollection","collection","existingFile","findOne","_id","existingImageMetadata","image","variantsStatus","variantsVersion","markVariantsSkipped","reason","updateOne","$set","$unset","existingFileLength","length","sourceBytes","source","limitInputPixels","targetWidths","filter","variants","output","rotate","resize","withoutEnlargement","webp","quality","effort","toBuffer","resolveWithObject","variantFileId","variantWidth","variantFormat","info","format","Object","keys","Parameters","isImageVariantsPostProcessorRegistered","registerImageVariantsPostProcessor","registerImageVariantsPostProcessor","registerConvertHeifToWebpTask","registerUploadPostProcessorTask","registerUploadWorkerTasks"],"sources":["../../src/uploads/api/file-uploads/imageVariantsPostProcessor.ts","../../src/uploads/worker.ts"],"sourcesContent":["import { getTenantFilesystemDb } from \"@rpcbase/db\"\nimport { GridFSBucket, ObjectId } from \"mongodb\"\nimport sharp from \"sharp\"\n\nimport { registerUploadPostProcessor } from \"./postProcessors\"\nimport { getBucketName } from \"./shared\"\n\n\nconst IMAGE_VARIANTS_PROCESSOR_ID = \"rb-image-variants\"\nconst IMAGE_VARIANTS_VERSION = 1\nconst IMAGE_VARIANT_WIDTHS = [320, 640, 960, 1600] as const\nconst IMAGE_VARIANT_QUALITY = 82\nconst IMAGE_VARIANT_MIME_TYPE = \"image/webp\"\nconst IMAGE_VARIANT_FORMAT = \"webp\"\nconst IMAGE_VARIANT_MAX_INPUT_BYTES = 32 * 1024 * 1024\nconst IMAGE_VARIANT_MAX_INPUT_PIXELS = 128 * 1024 * 1024\n\nconst supportedImageMimeTypes = new Set([\n \"image/avif\",\n \"image/heic\",\n \"image/heif\",\n \"image/jpeg\",\n \"image/png\",\n \"image/webp\",\n])\n\ntype ImageVariantRecord = {\n fileId: string\n width: number\n height: number\n mimeType: typeof IMAGE_VARIANT_MIME_TYPE\n size: number\n}\n\nconst normalizeMimeType = (value: string): string => value.trim().toLowerCase()\n\nconst toObjectId = (value: string): ObjectId | null => {\n try {\n return new ObjectId(value)\n } catch {\n return null\n }\n}\n\nconst readGridFsFile = async (bucket: GridFSBucket, fileId: ObjectId): Promise<Buffer> => new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n const stream = bucket.openDownloadStream(fileId)\n\n stream.on(\"data\", (chunk) => {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))\n })\n stream.once(\"error\", reject)\n stream.once(\"end\", () => resolve(Buffer.concat(chunks)))\n})\n\nconst writeGridFsFile = async (\n bucket: GridFSBucket,\n filename: string,\n data: Buffer,\n metadata: Record<string, unknown>,\n): Promise<string> => new Promise((resolve, reject) => {\n const stream = bucket.openUploadStream(filename, {\n metadata,\n })\n\n stream.once(\"error\", reject)\n stream.once(\"finish\", () => resolve(String((stream as unknown as { id?: unknown }).id ?? \"\")))\n stream.end(data)\n})\n\nconst imageVariantsPostProcessor = {\n id: IMAGE_VARIANTS_PROCESSOR_ID,\n version: IMAGE_VARIANTS_VERSION,\n match: ({ mimeType, metadata }) => {\n if (typeof metadata.variantOf === \"string\") return false\n return supportedImageMimeTypes.has(normalizeMimeType(mimeType))\n },\n process: async ({ tenantId, fileId, filename, isPublic, userId, ownerKeyHash, totalSize }) => {\n const originalObjectId = toObjectId(fileId)\n if (!originalObjectId) return\n\n const fsDb = await getTenantFilesystemDb(tenantId)\n const nativeDb = fsDb.db\n if (!nativeDb) return\n\n const bucketName = getBucketName()\n const filesCollection = nativeDb.collection(`${bucketName}.files`)\n const existingFile = await filesCollection.findOne({ _id: originalObjectId })\n if (!existingFile) return\n\n const existingImageMetadata = existingFile && typeof existingFile.metadata === \"object\" && existingFile.metadata\n ? (existingFile.metadata as Record<string, unknown>).image\n : null\n\n if (\n existingImageMetadata &&\n typeof existingImageMetadata === \"object\" &&\n (existingImageMetadata as Record<string, unknown>).variantsStatus === \"done\" &&\n (existingImageMetadata as Record<string, unknown>).variantsVersion === IMAGE_VARIANTS_VERSION\n ) {\n return\n }\n\n const markVariantsSkipped = async (reason: string): Promise<void> => {\n await filesCollection.updateOne(\n { _id: originalObjectId },\n {\n $set: {\n \"metadata.image.variantsStatus\": \"skipped\",\n \"metadata.image.variantsVersion\": IMAGE_VARIANTS_VERSION,\n \"metadata.image.variantsSkippedReason\": reason,\n },\n $unset: {\n \"metadata.image.variants\": \"\",\n },\n },\n )\n }\n\n const existingFileLength = typeof existingFile.length === \"number\" ? existingFile.length : null\n const sourceBytes = existingFileLength ?? totalSize\n if (sourceBytes > IMAGE_VARIANT_MAX_INPUT_BYTES) {\n await markVariantsSkipped(\"source_too_large\")\n return\n }\n\n const bucket = new GridFSBucket(nativeDb, { bucketName })\n const source = await readGridFsFile(bucket, originalObjectId)\n const metadata = await sharp(source, { limitInputPixels: IMAGE_VARIANT_MAX_INPUT_PIXELS }).metadata()\n\n if (!metadata.width || !metadata.height) {\n await markVariantsSkipped(\"missing_dimensions\")\n return\n }\n\n const targetWidths = IMAGE_VARIANT_WIDTHS.filter((width) => width < metadata.width)\n const variants: Record<string, ImageVariantRecord> = {}\n\n for (const width of targetWidths) {\n const output = await sharp(source, { limitInputPixels: IMAGE_VARIANT_MAX_INPUT_PIXELS })\n .rotate()\n .resize({ width, withoutEnlargement: true })\n .webp({ quality: IMAGE_VARIANT_QUALITY, effort: 4 })\n .toBuffer({ resolveWithObject: true })\n\n const variantFileId = await writeGridFsFile(\n bucket,\n `${filename}.${width}.${IMAGE_VARIANT_FORMAT}`,\n output.data,\n {\n mimeType: IMAGE_VARIANT_MIME_TYPE,\n totalSize: output.data.length,\n variantOf: fileId,\n variantWidth: width,\n variantFormat: IMAGE_VARIANT_FORMAT,\n variantsVersion: IMAGE_VARIANTS_VERSION,\n ...(typeof isPublic === \"boolean\" ? { isPublic } : {}),\n ...(userId ? { userId } : {}),\n ...(ownerKeyHash ? { ownerKeyHash } : {}),\n },\n )\n\n if (!variantFileId) continue\n\n variants[String(width)] = {\n fileId: variantFileId,\n width: output.info.width,\n height: output.info.height,\n mimeType: IMAGE_VARIANT_MIME_TYPE,\n size: output.data.length,\n }\n }\n\n await filesCollection.updateOne(\n { _id: originalObjectId },\n {\n $set: {\n \"metadata.image\": {\n width: metadata.width,\n height: metadata.height,\n format: metadata.format,\n variantsStatus: Object.keys(variants).length ? \"done\" : \"skipped\",\n variantsVersion: IMAGE_VARIANTS_VERSION,\n variants,\n },\n },\n },\n )\n },\n} satisfies Parameters<typeof registerUploadPostProcessor>[0]\n\nlet isImageVariantsPostProcessorRegistered = false\n\nexport const registerImageVariantsPostProcessor = (): void => {\n if (isImageVariantsPostProcessorRegistered) return\n\n registerUploadPostProcessor(imageVariantsPostProcessor)\n isImageVariantsPostProcessorRegistered = true\n}\n","import { registerImageVariantsPostProcessor } from \"./api/file-uploads/imageVariantsPostProcessor\"\nimport { registerConvertHeifToWebpTask } from \"./api/file-uploads/processors/convertHeifToWebp\"\nimport { registerUploadPostProcessorTask } from \"./api/file-uploads/postProcessors\"\n\n\nexport const registerUploadWorkerTasks = (): void => {\n registerConvertHeifToWebpTask()\n registerImageVariantsPostProcessor()\n registerUploadPostProcessorTask()\n}\n"],"mappings":";;;;;;;AAQA,IAAMM,8BAA8B;AACpC,IAAMC,yBAAyB;AAC/B,IAAMC,uBAAuB;CAAC;CAAK;CAAK;CAAK;AAAI;AACjD,IAAME,wBAAwB;AAC9B,IAAMC,0BAA0B;AAChC,IAAMC,uBAAuB;AAC7B,IAAMC,gCAAgC,KAAK,OAAO;AAClD,IAAMC,iCAAiC,MAAM,OAAO;AAEpD,IAAMC,0CAA0B,IAAIC,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;AAAY,CACb;AAUD,IAAMO,qBAAqBC,UAA0BA,MAAMC,KAAK,CAAC,CAACC,YAAY;AAE9E,IAAMC,cAAcH,UAAmC;CACrD,IAAI;EACF,OAAO,IAAItB,SAASsB,KAAK;CAC3B,QAAQ;EACN,OAAO;CACT;AACF;AAEA,IAAMI,iBAAiB,OAAOC,QAAsBX,WAAsC,IAAIY,SAASE,SAASC,WAAW;CACzH,MAAMC,SAAmB,CAAA;CACzB,MAAMC,SAASN,OAAOO,mBAAmBlB,MAAM;CAE/CiB,OAAOE,GAAG,SAASC,UAAU;EAC3BJ,OAAOK,KAAKR,OAAOS,SAASF,KAAK,IAAIA,QAAQP,OAAOU,KAAKH,KAAK,CAAC;CACjE,CAAC;CACDH,OAAOO,KAAK,SAAST,MAAM;CAC3BE,OAAOO,KAAK,aAAaV,QAAQD,OAAOY,OAAOT,MAAM,CAAC,CAAC;AACzD,CAAC;AAED,IAAMU,kBAAkB,OACtBf,QACAgB,UACAC,MACAC,aACoB,IAAIjB,SAASE,SAASC,WAAW;CACrD,MAAME,SAASN,OAAOoB,iBAAiBJ,UAAU,EAC/CE,SACF,CAAC;CAEDZ,OAAOO,KAAK,SAAST,MAAM;CAC3BE,OAAOO,KAAK,gBAAgBV,QAAQkB,OAAQf,OAAuCgB,MAAM,EAAE,CAAC,CAAC;CAC7FhB,OAAOiB,IAAIN,IAAI;AACjB,CAAC;AAED,IAAMO,6BAA6B;CACjCF,IAAI7C;CACJgD,SAAS/C;CACTgD,QAAQ,EAAElC,UAAU0B,eAAe;EACjC,IAAI,OAAOA,SAASS,cAAc,UAAU,OAAO;EACnD,OAAOzC,wBAAwB0C,IAAIlC,kBAAkBF,QAAQ,CAAC;CAChE;CACAqC,SAAS,OAAO,EAAEC,UAAUzC,QAAQ2B,UAAUe,UAAUC,QAAQC,cAAcC,gBAAgB;EAC5F,MAAMC,mBAAmBrC,WAAWT,MAAM;EAC1C,IAAI,CAAC8C,kBAAkB;EAGvB,MAAME,YAAWD,MADEjE,sBAAsB2D,QAAQ,EAAA,CAC3BQ;EACtB,IAAI,CAACD,UAAU;EAEf,MAAME,aAAa/D,cAAc;EACjC,MAAMgE,kBAAkBH,SAASI,WAAW,GAAGF,WAAU,OAAQ;EACjE,MAAMG,eAAe,MAAMF,gBAAgBG,QAAQ,EAAEC,KAAKT,iBAAiB,CAAC;EAC5E,IAAI,CAACO,cAAc;EAEnB,MAAMG,wBAAwBH,gBAAgB,OAAOA,aAAaxB,aAAa,YAAYwB,aAAaxB,WACnGwB,aAAaxB,SAAqC4B,QACnD;EAEJ,IACED,yBACA,OAAOA,0BAA0B,YAChCA,sBAAkDE,mBAAmB,UACrEF,sBAAkDG,oBAAoBtE,wBAEvE;EAGF,MAAMuE,sBAAsB,OAAOC,WAAkC;GACnE,MAAMV,gBAAgBW,UACpB,EAAEP,KAAKT,iBAAiB,GACxB;IACEiB,MAAM;KACJ,iCAAiC;KACjC,kCAAkC1E;KAClC,wCAAwCwE;IAC1C;IACAG,QAAQ,EACN,2BAA2B,GAC7B;GACF,CACF;EACF;EAIA,MAF2B,OAAOX,aAAaa,WAAW,WAAWb,aAAaa,SAAS,SACjDrB,aACxBlD,+BAA+B;GAC/C,MAAMiE,oBAAoB,kBAAkB;GAC5C;EACF;EAEA,MAAMjD,SAAS,IAAI5B,aAAaiE,UAAU,EAAEE,WAAW,CAAC;EACxD,MAAMkB,SAAS,MAAM1D,eAAeC,QAAQmC,gBAAgB;EAC5D,MAAMjB,WAAW,MAAM5C,MAAMmF,QAAQ,EAAEC,kBAAkBzE,+BAA+B,CAAC,CAAC,CAACiC,SAAS;EAEpG,IAAI,CAACA,SAAS5B,SAAS,CAAC4B,SAAS3B,QAAQ;GACvC,MAAM0D,oBAAoB,oBAAoB;GAC9C;EACF;EAEA,MAAMU,eAAehF,qBAAqBiF,QAAQtE,UAAUA,QAAQ4B,SAAS5B,KAAK;EAClF,MAAMuE,WAA+C,CAAC;EAEtD,KAAK,MAAMvE,SAASqE,cAAc;GAChC,MAAMG,SAAS,MAAMxF,MAAMmF,QAAQ,EAAEC,kBAAkBzE,+BAA+B,CAAC,CAAC,CACrF8E,OAAO,CAAC,CACRC,OAAO;IAAE1E;IAAO2E,oBAAoB;GAAK,CAAC,CAAC,CAC3CC,KAAK;IAAEC,SAAStF;IAAuBuF,QAAQ;GAAE,CAAC,CAAC,CACnDC,SAAS,EAAEC,mBAAmB,KAAK,CAAC;GAEvC,MAAMC,gBAAgB,MAAMxD,gBAC1Bf,QACA,GAAGgB,SAAQ,GAAI1B,MAAK,GAAIP,wBACxB+E,OAAO7C,MACP;IACEzB,UAAUV;IACVoD,WAAW4B,OAAO7C,KAAKsC;IACvB5B,WAAWtC;IACXmF,cAAclF;IACdmF,eAAe1F;IACfiE,iBAAiBtE;IACjB,GAAI,OAAOqD,aAAa,YAAY,EAAEA,SAAS,IAAI,CAAC;IACpD,GAAIC,SAAS,EAAEA,OAAO,IAAI,CAAC;IAC3B,GAAIC,eAAe,EAAEA,aAAa,IAAI,CAAC;GACzC,CACF;GAEA,IAAI,CAACsC,eAAe;GAEpBV,SAASxC,OAAO/B,KAAK,KAAK;IACxBD,QAAQkF;IACRjF,OAAOwE,OAAOY,KAAKpF;IACnBC,QAAQuE,OAAOY,KAAKnF;IACpBC,UAAUV;IACVW,MAAMqE,OAAO7C,KAAKsC;GACpB;EACF;EAEA,MAAMf,gBAAgBW,UACpB,EAAEP,KAAKT,iBAAiB,GACxB,EACEiB,MAAM,EACJ,kBAAkB;GAChB9D,OAAO4B,SAAS5B;GAChBC,QAAQ2B,SAAS3B;GACjBoF,QAAQzD,SAASyD;GACjB5B,gBAAgB6B,OAAOC,KAAKhB,QAAQ,CAAC,CAACN,SAAS,SAAS;GACxDP,iBAAiBtE;GACjBmF;EACF,EACF,EACF,CACF;CACF;AACF;AAEA,IAAIkB,yCAAyC;AAE7C,IAAaC,2CAAiD;CAC5D,IAAID,wCAAwC;CAE5CxG,4BAA4BiD,0BAA0B;CACtDuD,yCAAyC;AAC3C;;;ACjMA,IAAaK,kCAAwC;CACnDF,8BAA8B;CAC9BD,mCAAmC;CACnCE,gCAAgC;AAClC"}
|
|
1
|
+
{"version":3,"file":"worker.js","names":["getTenantFilesystemDb","GridFSBucket","ObjectId","sharp","registerUploadPostProcessor","getBucketName","IMAGE_VARIANTS_PROCESSOR_ID","IMAGE_VARIANTS_VERSION","IMAGE_VARIANT_WIDTHS","const","IMAGE_VARIANT_QUALITY","IMAGE_VARIANT_MIME_TYPE","IMAGE_VARIANT_FORMAT","IMAGE_VARIANT_MAX_INPUT_BYTES","IMAGE_VARIANT_MAX_INPUT_PIXELS","supportedImageMimeTypes","Set","ImageVariantRecord","fileId","width","height","mimeType","size","normalizeMimeType","value","trim","toLowerCase","toObjectId","readGridFsFile","bucket","Promise","Buffer","resolve","reject","chunks","stream","openDownloadStream","on","chunk","push","isBuffer","from","once","concat","writeGridFsFile","filename","data","metadata","Record","openUploadStream","String","id","end","imageVariantsPostProcessor","version","match","variantOf","has","process","tenantId","isPublic","accessScope","userId","ownerKeyHash","totalSize","originalObjectId","fsDb","nativeDb","db","bucketName","filesCollection","collection","existingFile","findOne","_id","existingImageMetadata","image","variantsStatus","variantsVersion","markVariantsSkipped","reason","updateOne","$set","$unset","existingFileLength","length","sourceBytes","source","limitInputPixels","targetWidths","filter","variants","output","rotate","resize","withoutEnlargement","webp","quality","effort","toBuffer","resolveWithObject","variantFileId","variantWidth","variantFormat","info","format","Object","keys","Parameters","isImageVariantsPostProcessorRegistered","registerImageVariantsPostProcessor","registerImageVariantsPostProcessor","registerConvertHeifToWebpTask","registerUploadPostProcessorTask","registerUploadWorkerTasks"],"sources":["../../src/uploads/api/file-uploads/imageVariantsPostProcessor.ts","../../src/uploads/worker.ts"],"sourcesContent":["import { getTenantFilesystemDb } from \"@rpcbase/db\"\nimport { GridFSBucket, ObjectId } from \"mongodb\"\nimport sharp from \"sharp\"\n\nimport { registerUploadPostProcessor } from \"./postProcessors\"\nimport { getBucketName } from \"./shared\"\n\n\nconst IMAGE_VARIANTS_PROCESSOR_ID = \"rb-image-variants\"\nconst IMAGE_VARIANTS_VERSION = 1\nconst IMAGE_VARIANT_WIDTHS = [320, 640, 960, 1600] as const\nconst IMAGE_VARIANT_QUALITY = 82\nconst IMAGE_VARIANT_MIME_TYPE = \"image/webp\"\nconst IMAGE_VARIANT_FORMAT = \"webp\"\nconst IMAGE_VARIANT_MAX_INPUT_BYTES = 32 * 1024 * 1024\nconst IMAGE_VARIANT_MAX_INPUT_PIXELS = 128 * 1024 * 1024\n\nconst supportedImageMimeTypes = new Set([\n \"image/avif\",\n \"image/heic\",\n \"image/heif\",\n \"image/jpeg\",\n \"image/png\",\n \"image/webp\",\n])\n\ntype ImageVariantRecord = {\n fileId: string\n width: number\n height: number\n mimeType: typeof IMAGE_VARIANT_MIME_TYPE\n size: number\n}\n\nconst normalizeMimeType = (value: string): string => value.trim().toLowerCase()\n\nconst toObjectId = (value: string): ObjectId | null => {\n try {\n return new ObjectId(value)\n } catch {\n return null\n }\n}\n\nconst readGridFsFile = async (bucket: GridFSBucket, fileId: ObjectId): Promise<Buffer> => new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n const stream = bucket.openDownloadStream(fileId)\n\n stream.on(\"data\", (chunk) => {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))\n })\n stream.once(\"error\", reject)\n stream.once(\"end\", () => resolve(Buffer.concat(chunks)))\n})\n\nconst writeGridFsFile = async (\n bucket: GridFSBucket,\n filename: string,\n data: Buffer,\n metadata: Record<string, unknown>,\n): Promise<string> => new Promise((resolve, reject) => {\n const stream = bucket.openUploadStream(filename, {\n metadata,\n })\n\n stream.once(\"error\", reject)\n stream.once(\"finish\", () => resolve(String((stream as unknown as { id?: unknown }).id ?? \"\")))\n stream.end(data)\n})\n\nconst imageVariantsPostProcessor = {\n id: IMAGE_VARIANTS_PROCESSOR_ID,\n version: IMAGE_VARIANTS_VERSION,\n match: ({ mimeType, metadata }) => {\n if (typeof metadata.variantOf === \"string\") return false\n return supportedImageMimeTypes.has(normalizeMimeType(mimeType))\n },\n process: async ({ tenantId, fileId, filename, isPublic, accessScope, userId, ownerKeyHash, totalSize }) => {\n const originalObjectId = toObjectId(fileId)\n if (!originalObjectId) return\n\n const fsDb = await getTenantFilesystemDb(tenantId)\n const nativeDb = fsDb.db\n if (!nativeDb) return\n\n const bucketName = getBucketName()\n const filesCollection = nativeDb.collection(`${bucketName}.files`)\n const existingFile = await filesCollection.findOne({ _id: originalObjectId })\n if (!existingFile) return\n\n const existingImageMetadata = existingFile && typeof existingFile.metadata === \"object\" && existingFile.metadata\n ? (existingFile.metadata as Record<string, unknown>).image\n : null\n\n if (\n existingImageMetadata &&\n typeof existingImageMetadata === \"object\" &&\n (existingImageMetadata as Record<string, unknown>).variantsStatus === \"done\" &&\n (existingImageMetadata as Record<string, unknown>).variantsVersion === IMAGE_VARIANTS_VERSION\n ) {\n return\n }\n\n const markVariantsSkipped = async (reason: string): Promise<void> => {\n await filesCollection.updateOne(\n { _id: originalObjectId },\n {\n $set: {\n \"metadata.image.variantsStatus\": \"skipped\",\n \"metadata.image.variantsVersion\": IMAGE_VARIANTS_VERSION,\n \"metadata.image.variantsSkippedReason\": reason,\n },\n $unset: {\n \"metadata.image.variants\": \"\",\n },\n },\n )\n }\n\n const existingFileLength = typeof existingFile.length === \"number\" ? existingFile.length : null\n const sourceBytes = existingFileLength ?? totalSize\n if (sourceBytes > IMAGE_VARIANT_MAX_INPUT_BYTES) {\n await markVariantsSkipped(\"source_too_large\")\n return\n }\n\n const bucket = new GridFSBucket(nativeDb, { bucketName })\n const source = await readGridFsFile(bucket, originalObjectId)\n const metadata = await sharp(source, { limitInputPixels: IMAGE_VARIANT_MAX_INPUT_PIXELS }).metadata()\n\n if (!metadata.width || !metadata.height) {\n await markVariantsSkipped(\"missing_dimensions\")\n return\n }\n\n const targetWidths = IMAGE_VARIANT_WIDTHS.filter((width) => width < metadata.width)\n const variants: Record<string, ImageVariantRecord> = {}\n\n for (const width of targetWidths) {\n const output = await sharp(source, { limitInputPixels: IMAGE_VARIANT_MAX_INPUT_PIXELS })\n .rotate()\n .resize({ width, withoutEnlargement: true })\n .webp({ quality: IMAGE_VARIANT_QUALITY, effort: 4 })\n .toBuffer({ resolveWithObject: true })\n\n const variantFileId = await writeGridFsFile(\n bucket,\n `${filename}.${width}.${IMAGE_VARIANT_FORMAT}`,\n output.data,\n {\n mimeType: IMAGE_VARIANT_MIME_TYPE,\n totalSize: output.data.length,\n variantOf: fileId,\n variantWidth: width,\n variantFormat: IMAGE_VARIANT_FORMAT,\n variantsVersion: IMAGE_VARIANTS_VERSION,\n ...(typeof isPublic === \"boolean\" ? { isPublic } : {}),\n ...(accessScope ? { accessScope } : {}),\n ...(userId ? { userId } : {}),\n ...(ownerKeyHash ? { ownerKeyHash } : {}),\n },\n )\n\n if (!variantFileId) continue\n\n variants[String(width)] = {\n fileId: variantFileId,\n width: output.info.width,\n height: output.info.height,\n mimeType: IMAGE_VARIANT_MIME_TYPE,\n size: output.data.length,\n }\n }\n\n await filesCollection.updateOne(\n { _id: originalObjectId },\n {\n $set: {\n \"metadata.image\": {\n width: metadata.width,\n height: metadata.height,\n format: metadata.format,\n variantsStatus: Object.keys(variants).length ? \"done\" : \"skipped\",\n variantsVersion: IMAGE_VARIANTS_VERSION,\n variants,\n },\n },\n },\n )\n },\n} satisfies Parameters<typeof registerUploadPostProcessor>[0]\n\nlet isImageVariantsPostProcessorRegistered = false\n\nexport const registerImageVariantsPostProcessor = (): void => {\n if (isImageVariantsPostProcessorRegistered) return\n\n registerUploadPostProcessor(imageVariantsPostProcessor)\n isImageVariantsPostProcessorRegistered = true\n}\n","import { registerImageVariantsPostProcessor } from \"./api/file-uploads/imageVariantsPostProcessor\"\nimport { registerConvertHeifToWebpTask } from \"./api/file-uploads/processors/convertHeifToWebp\"\nimport { registerUploadPostProcessorTask } from \"./api/file-uploads/postProcessors\"\n\n\nexport const registerUploadWorkerTasks = (): void => {\n registerConvertHeifToWebpTask()\n registerImageVariantsPostProcessor()\n registerUploadPostProcessorTask()\n}\n"],"mappings":"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"}
|
package/dist/uploads.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a as getUploadProcessors, c as registerUploadProcessor, d as unregisterUploadProcessor, f as uploadPostProcessorTaskName, i as getUploadPostProcessors, l as runUploadPostProcessors, n as clearUploadProcessors, o as registerUploadPostProcessor, r as enqueueUploadPostProcessors, s as registerUploadPostProcessorTask, t as clearUploadPostProcessors, u as unregisterUploadPostProcessor } from "./postProcessors-iffHvje4.js";
|
|
2
2
|
//#region src/uploads/routes.ts
|
|
3
3
|
var routes = Object.entries({ .../* #__PURE__ */ Object.assign({
|
|
4
|
-
"./api/file-uploads/handler.ts": () => import("./handler-
|
|
5
|
-
"./api/files/handler.ts": () => import("./handler-
|
|
4
|
+
"./api/file-uploads/handler.ts": () => import("./handler-CqSlSCdd.js"),
|
|
5
|
+
"./api/files/handler.ts": () => import("./handler-LRLmxrsg.js")
|
|
6
6
|
}) }).reduce((acc, [path, mod]) => {
|
|
7
7
|
acc[path.replace("./api/", "@rpcbase/server/uploads/api/")] = mod;
|
|
8
8
|
return acc;
|