payload 3.82.0-canary.6 → 3.82.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/index.bundled.d.ts +1 -0
- package/dist/uploads/checkFileAccess.d.ts +2 -1
- package/dist/uploads/checkFileAccess.d.ts.map +1 -1
- package/dist/uploads/checkFileAccess.js +25 -14
- package/dist/uploads/checkFileAccess.js.map +1 -1
- package/dist/uploads/checkFileAccess.spec.js +109 -0
- package/dist/uploads/checkFileAccess.spec.js.map +1 -0
- package/dist/uploads/endpoints/getFile.d.ts.map +1 -1
- package/dist/uploads/endpoints/getFile.js +4 -1
- package/dist/uploads/endpoints/getFile.js.map +1 -1
- package/dist/uploads/types.d.ts +1 -0
- package/dist/uploads/types.d.ts.map +1 -1
- package/dist/uploads/types.js.map +1 -1
- package/package.json +2 -2
package/dist/index.bundled.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { Collection, TypeWithID } from '../collections/config/types.js';
|
|
2
2
|
import type { PayloadRequest } from '../types/index.js';
|
|
3
|
-
export declare const checkFileAccess: ({ collection, filename, req, }: {
|
|
3
|
+
export declare const checkFileAccess: ({ collection, filename, prefix, req, }: {
|
|
4
4
|
collection: Collection;
|
|
5
5
|
filename: string;
|
|
6
|
+
prefix?: string;
|
|
6
7
|
req: PayloadRequest;
|
|
7
8
|
}) => Promise<TypeWithID | undefined>;
|
|
8
9
|
//# sourceMappingURL=checkFileAccess.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkFileAccess.d.ts","sourceRoot":"","sources":["../../src/uploads/checkFileAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAS,MAAM,mBAAmB,CAAA;AAK9D,eAAO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"checkFileAccess.d.ts","sourceRoot":"","sources":["../../src/uploads/checkFileAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAS,MAAM,mBAAmB,CAAA;AAK9D,eAAO,MAAM,eAAe,2CAKzB;IACD,UAAU,EAAE,UAAU,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,cAAc,CAAA;CACpB,KAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CA8CjC,CAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { executeAccess } from '../auth/executeAccess.js';
|
|
2
2
|
import { Forbidden } from '../errors/Forbidden.js';
|
|
3
|
-
export const checkFileAccess = async ({ collection, filename, req })=>{
|
|
3
|
+
export const checkFileAccess = async ({ collection, filename, prefix, req })=>{
|
|
4
4
|
if (filename.includes('../') || filename.includes('..\\')) {
|
|
5
5
|
throw new Forbidden(req.t);
|
|
6
6
|
}
|
|
@@ -12,24 +12,30 @@ export const checkFileAccess = async ({ collection, filename, req })=>{
|
|
|
12
12
|
isReadingStaticFile: true,
|
|
13
13
|
req
|
|
14
14
|
}, config.access.read);
|
|
15
|
+
const constraints = [];
|
|
15
16
|
if (typeof accessResult === 'object') {
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
constraints.push(accessResult);
|
|
18
|
+
}
|
|
19
|
+
if (typeof prefix === 'string') {
|
|
20
|
+
constraints.push({
|
|
21
|
+
prefix: {
|
|
22
|
+
equals: prefix
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (constraints.length > 0) {
|
|
27
|
+
const filenameCondition = {
|
|
28
|
+
or: [
|
|
18
29
|
{
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
]
|
|
26
|
-
},
|
|
27
|
-
accessResult
|
|
30
|
+
filename: {
|
|
31
|
+
equals: filename
|
|
32
|
+
}
|
|
33
|
+
}
|
|
28
34
|
]
|
|
29
35
|
};
|
|
30
36
|
if (config.upload.imageSizes) {
|
|
31
37
|
config.upload.imageSizes.forEach(({ name })=>{
|
|
32
|
-
|
|
38
|
+
filenameCondition.or.push({
|
|
33
39
|
[`sizes.${name}.filename`]: {
|
|
34
40
|
equals: filename
|
|
35
41
|
}
|
|
@@ -39,7 +45,12 @@ export const checkFileAccess = async ({ collection, filename, req })=>{
|
|
|
39
45
|
const doc = await req.payload.db.findOne({
|
|
40
46
|
collection: config.slug,
|
|
41
47
|
req,
|
|
42
|
-
where:
|
|
48
|
+
where: {
|
|
49
|
+
and: [
|
|
50
|
+
filenameCondition,
|
|
51
|
+
...constraints
|
|
52
|
+
]
|
|
53
|
+
}
|
|
43
54
|
});
|
|
44
55
|
if (!doc) {
|
|
45
56
|
throw new Forbidden(req.t);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/uploads/checkFileAccess.ts"],"sourcesContent":["import type { Collection, TypeWithID } from '../collections/config/types.js'\nimport type { PayloadRequest, Where } from '../types/index.js'\n\nimport { executeAccess } from '../auth/executeAccess.js'\nimport { Forbidden } from '../errors/Forbidden.js'\n\nexport const checkFileAccess = async ({\n collection,\n filename,\n req,\n}: {\n collection: Collection\n filename: string\n req: PayloadRequest\n}): Promise<TypeWithID | undefined> => {\n if (filename.includes('../') || filename.includes('..\\\\')) {\n throw new Forbidden(req.t)\n }\n const { config } = collection\n\n const accessResult = await executeAccess(\n { data: { filename }, isReadingStaticFile: true, req },\n config.access.read,\n )\n\n if (typeof accessResult === 'object') {\n
|
|
1
|
+
{"version":3,"sources":["../../src/uploads/checkFileAccess.ts"],"sourcesContent":["import type { Collection, TypeWithID } from '../collections/config/types.js'\nimport type { PayloadRequest, Where } from '../types/index.js'\n\nimport { executeAccess } from '../auth/executeAccess.js'\nimport { Forbidden } from '../errors/Forbidden.js'\n\nexport const checkFileAccess = async ({\n collection,\n filename,\n prefix,\n req,\n}: {\n collection: Collection\n filename: string\n prefix?: string\n req: PayloadRequest\n}): Promise<TypeWithID | undefined> => {\n if (filename.includes('../') || filename.includes('..\\\\')) {\n throw new Forbidden(req.t)\n }\n const { config } = collection\n\n const accessResult = await executeAccess(\n { data: { filename }, isReadingStaticFile: true, req },\n config.access.read,\n )\n\n const constraints: Where[] = []\n\n if (typeof accessResult === 'object') {\n constraints.push(accessResult)\n }\n\n if (typeof prefix === 'string') {\n constraints.push({ prefix: { equals: prefix } })\n }\n\n if (constraints.length > 0) {\n const filenameCondition: Where = {\n or: [{ filename: { equals: filename } }],\n }\n\n if (config.upload.imageSizes) {\n config.upload.imageSizes.forEach(({ name }) => {\n filenameCondition.or!.push({\n [`sizes.${name}.filename`]: { equals: filename },\n })\n })\n }\n\n const doc = await req.payload.db.findOne({\n collection: config.slug,\n req,\n where: { and: [filenameCondition, ...constraints] },\n })\n\n if (!doc) {\n throw new Forbidden(req.t)\n }\n\n return doc\n }\n}\n"],"names":["executeAccess","Forbidden","checkFileAccess","collection","filename","prefix","req","includes","t","config","accessResult","data","isReadingStaticFile","access","read","constraints","push","equals","length","filenameCondition","or","upload","imageSizes","forEach","name","doc","payload","db","findOne","slug","where","and"],"mappings":"AAGA,SAASA,aAAa,QAAQ,2BAA0B;AACxD,SAASC,SAAS,QAAQ,yBAAwB;AAElD,OAAO,MAAMC,kBAAkB,OAAO,EACpCC,UAAU,EACVC,QAAQ,EACRC,MAAM,EACNC,GAAG,EAMJ;IACC,IAAIF,SAASG,QAAQ,CAAC,UAAUH,SAASG,QAAQ,CAAC,SAAS;QACzD,MAAM,IAAIN,UAAUK,IAAIE,CAAC;IAC3B;IACA,MAAM,EAAEC,MAAM,EAAE,GAAGN;IAEnB,MAAMO,eAAe,MAAMV,cACzB;QAAEW,MAAM;YAAEP;QAAS;QAAGQ,qBAAqB;QAAMN;IAAI,GACrDG,OAAOI,MAAM,CAACC,IAAI;IAGpB,MAAMC,cAAuB,EAAE;IAE/B,IAAI,OAAOL,iBAAiB,UAAU;QACpCK,YAAYC,IAAI,CAACN;IACnB;IAEA,IAAI,OAAOL,WAAW,UAAU;QAC9BU,YAAYC,IAAI,CAAC;YAAEX,QAAQ;gBAAEY,QAAQZ;YAAO;QAAE;IAChD;IAEA,IAAIU,YAAYG,MAAM,GAAG,GAAG;QAC1B,MAAMC,oBAA2B;YAC/BC,IAAI;gBAAC;oBAAEhB,UAAU;wBAAEa,QAAQb;oBAAS;gBAAE;aAAE;QAC1C;QAEA,IAAIK,OAAOY,MAAM,CAACC,UAAU,EAAE;YAC5Bb,OAAOY,MAAM,CAACC,UAAU,CAACC,OAAO,CAAC,CAAC,EAAEC,IAAI,EAAE;gBACxCL,kBAAkBC,EAAE,CAAEJ,IAAI,CAAC;oBACzB,CAAC,CAAC,MAAM,EAAEQ,KAAK,SAAS,CAAC,CAAC,EAAE;wBAAEP,QAAQb;oBAAS;gBACjD;YACF;QACF;QAEA,MAAMqB,MAAM,MAAMnB,IAAIoB,OAAO,CAACC,EAAE,CAACC,OAAO,CAAC;YACvCzB,YAAYM,OAAOoB,IAAI;YACvBvB;YACAwB,OAAO;gBAAEC,KAAK;oBAACZ;uBAAsBJ;iBAAY;YAAC;QACpD;QAEA,IAAI,CAACU,KAAK;YACR,MAAM,IAAIxB,UAAUK,IAAIE,CAAC;QAC3B;QAEA,OAAOiB;IACT;AACF,EAAC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
vi.mock('../auth/executeAccess.js', ()=>({
|
|
3
|
+
executeAccess: vi.fn()
|
|
4
|
+
}));
|
|
5
|
+
import { executeAccess } from '../auth/executeAccess.js';
|
|
6
|
+
import { checkFileAccess } from './checkFileAccess.js';
|
|
7
|
+
const makeFindOne = (result = {
|
|
8
|
+
id: '1',
|
|
9
|
+
filename: 'logo.png'
|
|
10
|
+
})=>vi.fn().mockResolvedValue(result);
|
|
11
|
+
const makeCollection = ()=>({
|
|
12
|
+
config: {
|
|
13
|
+
slug: 'test-media',
|
|
14
|
+
access: {
|
|
15
|
+
read: vi.fn()
|
|
16
|
+
},
|
|
17
|
+
upload: {}
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
const makeReq = (findOne)=>({
|
|
21
|
+
t: vi.fn(),
|
|
22
|
+
payload: {
|
|
23
|
+
db: {
|
|
24
|
+
findOne
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
describe('checkFileAccess', ()=>{
|
|
29
|
+
beforeEach(()=>{
|
|
30
|
+
vi.mocked(executeAccess).mockResolvedValue({});
|
|
31
|
+
});
|
|
32
|
+
describe('prefix filtering', ()=>{
|
|
33
|
+
it('should add prefix clause to where query when prefix is provided', async ()=>{
|
|
34
|
+
const findOne = makeFindOne();
|
|
35
|
+
const req = makeReq(findOne);
|
|
36
|
+
const collection = makeCollection();
|
|
37
|
+
await checkFileAccess({
|
|
38
|
+
collection,
|
|
39
|
+
filename: 'logo.png',
|
|
40
|
+
prefix: 'abc123',
|
|
41
|
+
req
|
|
42
|
+
});
|
|
43
|
+
const whereArg = findOne.mock.calls[0]?.[0]?.where;
|
|
44
|
+
expect(whereArg?.and).toEqual(expect.arrayContaining([
|
|
45
|
+
{
|
|
46
|
+
prefix: {
|
|
47
|
+
equals: 'abc123'
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
]));
|
|
51
|
+
});
|
|
52
|
+
it('should not add prefix clause to where query when prefix is omitted', async ()=>{
|
|
53
|
+
const findOne = makeFindOne();
|
|
54
|
+
const req = makeReq(findOne);
|
|
55
|
+
const collection = makeCollection();
|
|
56
|
+
await checkFileAccess({
|
|
57
|
+
collection,
|
|
58
|
+
filename: 'logo.png',
|
|
59
|
+
req
|
|
60
|
+
});
|
|
61
|
+
const whereArg = findOne.mock.calls[0]?.[0]?.where;
|
|
62
|
+
const hasPrefixCondition = whereArg?.and?.some((clause)=>'prefix' in clause);
|
|
63
|
+
expect(hasPrefixCondition).toBeFalsy();
|
|
64
|
+
});
|
|
65
|
+
it('should still include filename in where query when prefix is provided', async ()=>{
|
|
66
|
+
const findOne = makeFindOne();
|
|
67
|
+
const req = makeReq(findOne);
|
|
68
|
+
const collection = makeCollection();
|
|
69
|
+
await checkFileAccess({
|
|
70
|
+
collection,
|
|
71
|
+
filename: 'logo.png',
|
|
72
|
+
prefix: 'abc123',
|
|
73
|
+
req
|
|
74
|
+
});
|
|
75
|
+
const whereArg = findOne.mock.calls[0]?.[0]?.where;
|
|
76
|
+
const filenameCondition = whereArg?.and?.[0];
|
|
77
|
+
expect(filenameCondition?.or).toEqual(expect.arrayContaining([
|
|
78
|
+
{
|
|
79
|
+
filename: {
|
|
80
|
+
equals: 'logo.png'
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
]));
|
|
84
|
+
});
|
|
85
|
+
it('should throw when no doc matches the given prefix', async ()=>{
|
|
86
|
+
const findOne = makeFindOne(null);
|
|
87
|
+
const req = makeReq(findOne);
|
|
88
|
+
const collection = makeCollection();
|
|
89
|
+
await expect(checkFileAccess({
|
|
90
|
+
collection,
|
|
91
|
+
filename: 'logo.png',
|
|
92
|
+
prefix: 'nonexistent',
|
|
93
|
+
req
|
|
94
|
+
})).rejects.toThrow();
|
|
95
|
+
});
|
|
96
|
+
it('should throw when filename contains path traversal sequence', async ()=>{
|
|
97
|
+
const findOne = makeFindOne();
|
|
98
|
+
const req = makeReq(findOne);
|
|
99
|
+
const collection = makeCollection();
|
|
100
|
+
await expect(checkFileAccess({
|
|
101
|
+
collection,
|
|
102
|
+
filename: '../etc/passwd',
|
|
103
|
+
req
|
|
104
|
+
})).rejects.toThrow();
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
//# sourceMappingURL=checkFileAccess.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/uploads/checkFileAccess.spec.ts"],"sourcesContent":["import { beforeEach, describe, expect, it, vi } from 'vitest'\n\nimport type { Collection } from '../collections/config/types.js'\nimport type { PayloadRequest } from '../types/index.js'\n\nvi.mock('../auth/executeAccess.js', () => ({\n executeAccess: vi.fn(),\n}))\n\nimport { executeAccess } from '../auth/executeAccess.js'\n\nimport { checkFileAccess } from './checkFileAccess.js'\n\nconst makeFindOne = (result: unknown = { id: '1', filename: 'logo.png' }) =>\n vi.fn().mockResolvedValue(result)\n\nconst makeCollection = (): Collection =>\n ({\n config: {\n slug: 'test-media',\n access: { read: vi.fn() },\n upload: {},\n },\n }) as unknown as Collection\n\nconst makeReq = (findOne: ReturnType<typeof vi.fn>): PayloadRequest =>\n ({\n t: vi.fn(),\n payload: {\n db: { findOne },\n },\n }) as unknown as PayloadRequest\n\ndescribe('checkFileAccess', () => {\n beforeEach(() => {\n vi.mocked(executeAccess).mockResolvedValue({})\n })\n\n describe('prefix filtering', () => {\n it('should add prefix clause to where query when prefix is provided', async () => {\n const findOne = makeFindOne()\n const req = makeReq(findOne)\n const collection = makeCollection()\n\n await checkFileAccess({ collection, filename: 'logo.png', prefix: 'abc123', req })\n\n const whereArg = findOne.mock.calls[0]?.[0]?.where\n expect(whereArg?.and).toEqual(expect.arrayContaining([{ prefix: { equals: 'abc123' } }]))\n })\n\n it('should not add prefix clause to where query when prefix is omitted', async () => {\n const findOne = makeFindOne()\n const req = makeReq(findOne)\n const collection = makeCollection()\n\n await checkFileAccess({ collection, filename: 'logo.png', req })\n\n const whereArg = findOne.mock.calls[0]?.[0]?.where\n const hasPrefixCondition = whereArg?.and?.some(\n (clause: Record<string, unknown>) => 'prefix' in clause,\n )\n expect(hasPrefixCondition).toBeFalsy()\n })\n\n it('should still include filename in where query when prefix is provided', async () => {\n const findOne = makeFindOne()\n const req = makeReq(findOne)\n const collection = makeCollection()\n\n await checkFileAccess({ collection, filename: 'logo.png', prefix: 'abc123', req })\n\n const whereArg = findOne.mock.calls[0]?.[0]?.where\n const filenameCondition = whereArg?.and?.[0]\n expect(filenameCondition?.or).toEqual(\n expect.arrayContaining([{ filename: { equals: 'logo.png' } }]),\n )\n })\n\n it('should throw when no doc matches the given prefix', async () => {\n const findOne = makeFindOne(null)\n const req = makeReq(findOne)\n const collection = makeCollection()\n\n await expect(\n checkFileAccess({ collection, filename: 'logo.png', prefix: 'nonexistent', req }),\n ).rejects.toThrow()\n })\n\n it('should throw when filename contains path traversal sequence', async () => {\n const findOne = makeFindOne()\n const req = makeReq(findOne)\n const collection = makeCollection()\n\n await expect(\n checkFileAccess({ collection, filename: '../etc/passwd', req }),\n ).rejects.toThrow()\n })\n })\n})\n"],"names":["beforeEach","describe","expect","it","vi","mock","executeAccess","fn","checkFileAccess","makeFindOne","result","id","filename","mockResolvedValue","makeCollection","config","slug","access","read","upload","makeReq","findOne","t","payload","db","mocked","req","collection","prefix","whereArg","calls","where","and","toEqual","arrayContaining","equals","hasPrefixCondition","some","clause","toBeFalsy","filenameCondition","or","rejects","toThrow"],"mappings":"AAAA,SAASA,UAAU,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,QAAQ,SAAQ;AAK7DA,GAAGC,IAAI,CAAC,4BAA4B,IAAO,CAAA;QACzCC,eAAeF,GAAGG,EAAE;IACtB,CAAA;AAEA,SAASD,aAAa,QAAQ,2BAA0B;AAExD,SAASE,eAAe,QAAQ,uBAAsB;AAEtD,MAAMC,cAAc,CAACC,SAAkB;IAAEC,IAAI;IAAKC,UAAU;AAAW,CAAC,GACtER,GAAGG,EAAE,GAAGM,iBAAiB,CAACH;AAE5B,MAAMI,iBAAiB,IACpB,CAAA;QACCC,QAAQ;YACNC,MAAM;YACNC,QAAQ;gBAAEC,MAAMd,GAAGG,EAAE;YAAG;YACxBY,QAAQ,CAAC;QACX;IACF,CAAA;AAEF,MAAMC,UAAU,CAACC,UACd,CAAA;QACCC,GAAGlB,GAAGG,EAAE;QACRgB,SAAS;YACPC,IAAI;gBAAEH;YAAQ;QAChB;IACF,CAAA;AAEFpB,SAAS,mBAAmB;IAC1BD,WAAW;QACTI,GAAGqB,MAAM,CAACnB,eAAeO,iBAAiB,CAAC,CAAC;IAC9C;IAEAZ,SAAS,oBAAoB;QAC3BE,GAAG,mEAAmE;YACpE,MAAMkB,UAAUZ;YAChB,MAAMiB,MAAMN,QAAQC;YACpB,MAAMM,aAAab;YAEnB,MAAMN,gBAAgB;gBAAEmB;gBAAYf,UAAU;gBAAYgB,QAAQ;gBAAUF;YAAI;YAEhF,MAAMG,WAAWR,QAAQhB,IAAI,CAACyB,KAAK,CAAC,EAAE,EAAE,CAAC,EAAE,EAAEC;YAC7C7B,OAAO2B,UAAUG,KAAKC,OAAO,CAAC/B,OAAOgC,eAAe,CAAC;gBAAC;oBAAEN,QAAQ;wBAAEO,QAAQ;oBAAS;gBAAE;aAAE;QACzF;QAEAhC,GAAG,sEAAsE;YACvE,MAAMkB,UAAUZ;YAChB,MAAMiB,MAAMN,QAAQC;YACpB,MAAMM,aAAab;YAEnB,MAAMN,gBAAgB;gBAAEmB;gBAAYf,UAAU;gBAAYc;YAAI;YAE9D,MAAMG,WAAWR,QAAQhB,IAAI,CAACyB,KAAK,CAAC,EAAE,EAAE,CAAC,EAAE,EAAEC;YAC7C,MAAMK,qBAAqBP,UAAUG,KAAKK,KACxC,CAACC,SAAoC,YAAYA;YAEnDpC,OAAOkC,oBAAoBG,SAAS;QACtC;QAEApC,GAAG,wEAAwE;YACzE,MAAMkB,UAAUZ;YAChB,MAAMiB,MAAMN,QAAQC;YACpB,MAAMM,aAAab;YAEnB,MAAMN,gBAAgB;gBAAEmB;gBAAYf,UAAU;gBAAYgB,QAAQ;gBAAUF;YAAI;YAEhF,MAAMG,WAAWR,QAAQhB,IAAI,CAACyB,KAAK,CAAC,EAAE,EAAE,CAAC,EAAE,EAAEC;YAC7C,MAAMS,oBAAoBX,UAAUG,KAAK,CAAC,EAAE;YAC5C9B,OAAOsC,mBAAmBC,IAAIR,OAAO,CACnC/B,OAAOgC,eAAe,CAAC;gBAAC;oBAAEtB,UAAU;wBAAEuB,QAAQ;oBAAW;gBAAE;aAAE;QAEjE;QAEAhC,GAAG,qDAAqD;YACtD,MAAMkB,UAAUZ,YAAY;YAC5B,MAAMiB,MAAMN,QAAQC;YACpB,MAAMM,aAAab;YAEnB,MAAMZ,OACJM,gBAAgB;gBAAEmB;gBAAYf,UAAU;gBAAYgB,QAAQ;gBAAeF;YAAI,IAC/EgB,OAAO,CAACC,OAAO;QACnB;QAEAxC,GAAG,+DAA+D;YAChE,MAAMkB,UAAUZ;YAChB,MAAMiB,MAAMN,QAAQC;YACpB,MAAMM,aAAab;YAEnB,MAAMZ,OACJM,gBAAgB;gBAAEmB;gBAAYf,UAAU;gBAAiBc;YAAI,IAC7DgB,OAAO,CAACC,OAAO;QACnB;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFile.d.ts","sourceRoot":"","sources":["../../../src/uploads/endpoints/getFile.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAU3D,eAAO,MAAM,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"getFile.d.ts","sourceRoot":"","sources":["../../../src/uploads/endpoints/getFile.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAU3D,eAAO,MAAM,cAAc,EAAE,cA6J5B,CAAA"}
|
|
@@ -12,12 +12,14 @@ import { headersWithCors } from '../../utilities/headersWithCors.js';
|
|
|
12
12
|
export const getFileHandler = async (req)=>{
|
|
13
13
|
const collection = getRequestCollection(req);
|
|
14
14
|
const filename = req.routeParams?.filename;
|
|
15
|
+
const prefix = req.searchParams?.get('prefix') ?? undefined;
|
|
15
16
|
if (!collection.config.upload) {
|
|
16
17
|
throw new APIError(`This collection is not an upload collection: ${collection.config.slug}`, httpStatus.BAD_REQUEST);
|
|
17
18
|
}
|
|
18
19
|
const accessResult = await checkFileAccess({
|
|
19
20
|
collection,
|
|
20
21
|
filename,
|
|
22
|
+
prefix,
|
|
21
23
|
req
|
|
22
24
|
});
|
|
23
25
|
if (accessResult instanceof Response) {
|
|
@@ -32,7 +34,8 @@ export const getFileHandler = async (req)=>{
|
|
|
32
34
|
headers,
|
|
33
35
|
params: {
|
|
34
36
|
collection: collection.config.slug,
|
|
35
|
-
filename
|
|
37
|
+
filename,
|
|
38
|
+
prefix
|
|
36
39
|
}
|
|
37
40
|
});
|
|
38
41
|
if (customResponse && customResponse instanceof Response) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/uploads/endpoints/getFile.ts"],"sourcesContent":["import type { Stats } from 'fs'\n\nimport { fileTypeFromFile } from 'file-type'\nimport fsPromises from 'fs/promises'\nimport { status as httpStatus } from 'http-status'\nimport path from 'path'\n\nimport type { PayloadHandler } from '../../config/types.js'\n\nimport { APIError } from '../../errors/APIError.js'\nimport { checkFileAccess } from '../../uploads/checkFileAccess.js'\nimport { streamFile } from '../../uploads/fetchAPI-stream-file/index.js'\nimport { getFileTypeFallback } from '../../uploads/getFileTypeFallback.js'\nimport { parseRangeHeader } from '../../uploads/parseRangeHeader.js'\nimport { getRequestCollection } from '../../utilities/getRequestEntity.js'\nimport { headersWithCors } from '../../utilities/headersWithCors.js'\n\nexport const getFileHandler: PayloadHandler = async (req) => {\n const collection = getRequestCollection(req)\n\n const filename = req.routeParams?.filename as string\n\n if (!collection.config.upload) {\n throw new APIError(\n `This collection is not an upload collection: ${collection.config.slug}`,\n httpStatus.BAD_REQUEST,\n )\n }\n\n const accessResult = (await checkFileAccess({\n collection,\n filename,\n req,\n }))!\n\n if (accessResult instanceof Response) {\n return accessResult\n }\n\n if (collection.config.upload.handlers?.length) {\n let customResponse: null | Response | void = null\n const headers = new Headers()\n\n for (const handler of collection.config.upload.handlers) {\n customResponse = await handler(req, {\n doc: accessResult,\n headers,\n params: {\n collection: collection.config.slug,\n filename,\n },\n })\n if (customResponse && customResponse instanceof Response) {\n break\n }\n }\n\n if (customResponse instanceof Response) {\n return customResponse\n }\n }\n\n // Local filesystem fallback — cloud storage handlers return a Response above\n // and have their own filename validation via sanitizeFilename.\n const fileDir = collection.config.upload?.staticDir || collection.config.slug\n const resolvedDir = path.resolve(fileDir)\n const filePath = path.resolve(resolvedDir, filename)\n\n if (!filePath.startsWith(resolvedDir + path.sep)) {\n throw new APIError('Invalid filename.', httpStatus.BAD_REQUEST)\n }\n\n let stats: Stats\n\n try {\n stats = await fsPromises.stat(filePath)\n } catch (err) {\n if ((err as { code?: string }).code === 'ENOENT') {\n req.payload.logger.error(\n `File ${filename} for collection ${collection.config.slug} is missing on the disk. Expected path: ${filePath}`,\n )\n\n // Omit going to the routeError handler by returning response instead of\n // throwing an error to cut down log noise. The response still matches what you get with APIError to not leak details to the user.\n return Response.json(\n {\n errors: [\n {\n message: 'Something went wrong.',\n },\n ],\n },\n {\n headers: headersWithCors({\n headers: new Headers(),\n req,\n }),\n status: 500,\n },\n )\n }\n\n throw err\n }\n\n const fileTypeResult = (await fileTypeFromFile(filePath)) || getFileTypeFallback(filePath)\n let mimeType = fileTypeResult.mime\n\n if (filePath.endsWith('.svg') && fileTypeResult.mime === 'application/xml') {\n mimeType = 'image/svg+xml'\n }\n\n // Parse Range header for byte range requests\n const rangeHeader = req.headers.get('range')\n const rangeResult = parseRangeHeader({\n fileSize: stats.size,\n rangeHeader,\n })\n\n if (rangeResult.type === 'invalid') {\n let headers = new Headers()\n headers.set('Content-Range', `bytes */${stats.size}`)\n headers = collection.config.upload?.modifyResponseHeaders\n ? collection.config.upload.modifyResponseHeaders({ headers }) || headers\n : headers\n\n return new Response(null, {\n headers: headersWithCors({\n headers,\n req,\n }),\n status: httpStatus.REQUESTED_RANGE_NOT_SATISFIABLE,\n })\n }\n\n let headers = new Headers()\n headers.set('Content-Type', mimeType)\n headers.set('Accept-Ranges', 'bytes')\n\n if (mimeType === 'image/svg+xml') {\n headers.set('Content-Security-Policy', \"script-src 'none'\")\n }\n\n let data: ReadableStream\n let status: number\n const isPartial = rangeResult.type === 'partial'\n const range = rangeResult.range\n\n if (isPartial && range) {\n const contentLength = range.end - range.start + 1\n headers.set('Content-Length', String(contentLength))\n headers.set('Content-Range', `bytes ${range.start}-${range.end}/${stats.size}`)\n data = streamFile({ filePath, options: { end: range.end, start: range.start } })\n status = httpStatus.PARTIAL_CONTENT\n } else {\n headers.set('Content-Length', String(stats.size))\n data = streamFile({ filePath })\n status = httpStatus.OK\n }\n\n headers = collection.config.upload?.modifyResponseHeaders\n ? collection.config.upload.modifyResponseHeaders({ headers }) || headers\n : headers\n\n return new Response(data, {\n headers: headersWithCors({\n headers,\n req,\n }),\n status,\n })\n}\n"],"names":["fileTypeFromFile","fsPromises","status","httpStatus","path","APIError","checkFileAccess","streamFile","getFileTypeFallback","parseRangeHeader","getRequestCollection","headersWithCors","getFileHandler","req","collection","filename","routeParams","config","upload","slug","BAD_REQUEST","accessResult","Response","handlers","length","customResponse","headers","Headers","handler","doc","params","fileDir","staticDir","resolvedDir","resolve","filePath","startsWith","sep","stats","stat","err","code","payload","logger","error","json","errors","message","fileTypeResult","mimeType","mime","endsWith","rangeHeader","
|
|
1
|
+
{"version":3,"sources":["../../../src/uploads/endpoints/getFile.ts"],"sourcesContent":["import type { Stats } from 'fs'\n\nimport { fileTypeFromFile } from 'file-type'\nimport fsPromises from 'fs/promises'\nimport { status as httpStatus } from 'http-status'\nimport path from 'path'\n\nimport type { PayloadHandler } from '../../config/types.js'\n\nimport { APIError } from '../../errors/APIError.js'\nimport { checkFileAccess } from '../../uploads/checkFileAccess.js'\nimport { streamFile } from '../../uploads/fetchAPI-stream-file/index.js'\nimport { getFileTypeFallback } from '../../uploads/getFileTypeFallback.js'\nimport { parseRangeHeader } from '../../uploads/parseRangeHeader.js'\nimport { getRequestCollection } from '../../utilities/getRequestEntity.js'\nimport { headersWithCors } from '../../utilities/headersWithCors.js'\n\nexport const getFileHandler: PayloadHandler = async (req) => {\n const collection = getRequestCollection(req)\n\n const filename = req.routeParams?.filename as string\n const prefix = req.searchParams?.get('prefix') ?? undefined\n\n if (!collection.config.upload) {\n throw new APIError(\n `This collection is not an upload collection: ${collection.config.slug}`,\n httpStatus.BAD_REQUEST,\n )\n }\n\n const accessResult = (await checkFileAccess({\n collection,\n filename,\n prefix,\n req,\n }))!\n\n if (accessResult instanceof Response) {\n return accessResult\n }\n\n if (collection.config.upload.handlers?.length) {\n let customResponse: null | Response | void = null\n const headers = new Headers()\n\n for (const handler of collection.config.upload.handlers) {\n customResponse = await handler(req, {\n doc: accessResult,\n headers,\n params: {\n collection: collection.config.slug,\n filename,\n prefix,\n },\n })\n if (customResponse && customResponse instanceof Response) {\n break\n }\n }\n\n if (customResponse instanceof Response) {\n return customResponse\n }\n }\n\n // Local filesystem fallback — cloud storage handlers return a Response above\n // and have their own filename validation via sanitizeFilename.\n const fileDir = collection.config.upload?.staticDir || collection.config.slug\n const resolvedDir = path.resolve(fileDir)\n const filePath = path.resolve(resolvedDir, filename)\n\n if (!filePath.startsWith(resolvedDir + path.sep)) {\n throw new APIError('Invalid filename.', httpStatus.BAD_REQUEST)\n }\n\n let stats: Stats\n\n try {\n stats = await fsPromises.stat(filePath)\n } catch (err) {\n if ((err as { code?: string }).code === 'ENOENT') {\n req.payload.logger.error(\n `File ${filename} for collection ${collection.config.slug} is missing on the disk. Expected path: ${filePath}`,\n )\n\n // Omit going to the routeError handler by returning response instead of\n // throwing an error to cut down log noise. The response still matches what you get with APIError to not leak details to the user.\n return Response.json(\n {\n errors: [\n {\n message: 'Something went wrong.',\n },\n ],\n },\n {\n headers: headersWithCors({\n headers: new Headers(),\n req,\n }),\n status: 500,\n },\n )\n }\n\n throw err\n }\n\n const fileTypeResult = (await fileTypeFromFile(filePath)) || getFileTypeFallback(filePath)\n let mimeType = fileTypeResult.mime\n\n if (filePath.endsWith('.svg') && fileTypeResult.mime === 'application/xml') {\n mimeType = 'image/svg+xml'\n }\n\n // Parse Range header for byte range requests\n const rangeHeader = req.headers.get('range')\n const rangeResult = parseRangeHeader({\n fileSize: stats.size,\n rangeHeader,\n })\n\n if (rangeResult.type === 'invalid') {\n let headers = new Headers()\n headers.set('Content-Range', `bytes */${stats.size}`)\n headers = collection.config.upload?.modifyResponseHeaders\n ? collection.config.upload.modifyResponseHeaders({ headers }) || headers\n : headers\n\n return new Response(null, {\n headers: headersWithCors({\n headers,\n req,\n }),\n status: httpStatus.REQUESTED_RANGE_NOT_SATISFIABLE,\n })\n }\n\n let headers = new Headers()\n headers.set('Content-Type', mimeType)\n headers.set('Accept-Ranges', 'bytes')\n\n if (mimeType === 'image/svg+xml') {\n headers.set('Content-Security-Policy', \"script-src 'none'\")\n }\n\n let data: ReadableStream\n let status: number\n const isPartial = rangeResult.type === 'partial'\n const range = rangeResult.range\n\n if (isPartial && range) {\n const contentLength = range.end - range.start + 1\n headers.set('Content-Length', String(contentLength))\n headers.set('Content-Range', `bytes ${range.start}-${range.end}/${stats.size}`)\n data = streamFile({ filePath, options: { end: range.end, start: range.start } })\n status = httpStatus.PARTIAL_CONTENT\n } else {\n headers.set('Content-Length', String(stats.size))\n data = streamFile({ filePath })\n status = httpStatus.OK\n }\n\n headers = collection.config.upload?.modifyResponseHeaders\n ? collection.config.upload.modifyResponseHeaders({ headers }) || headers\n : headers\n\n return new Response(data, {\n headers: headersWithCors({\n headers,\n req,\n }),\n status,\n })\n}\n"],"names":["fileTypeFromFile","fsPromises","status","httpStatus","path","APIError","checkFileAccess","streamFile","getFileTypeFallback","parseRangeHeader","getRequestCollection","headersWithCors","getFileHandler","req","collection","filename","routeParams","prefix","searchParams","get","undefined","config","upload","slug","BAD_REQUEST","accessResult","Response","handlers","length","customResponse","headers","Headers","handler","doc","params","fileDir","staticDir","resolvedDir","resolve","filePath","startsWith","sep","stats","stat","err","code","payload","logger","error","json","errors","message","fileTypeResult","mimeType","mime","endsWith","rangeHeader","rangeResult","fileSize","size","type","set","modifyResponseHeaders","REQUESTED_RANGE_NOT_SATISFIABLE","data","isPartial","range","contentLength","end","start","String","options","PARTIAL_CONTENT","OK"],"mappings":"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"}
|
package/dist/uploads/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/uploads/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/uploads/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/uploads/types.ts"],"sourcesContent":["import type { ResizeOptions, Sharp, SharpOptions } from 'sharp'\n\nimport type { CollectionConfig, TypeWithID } from '../collections/config/types.js'\nimport type { PayloadComponent } from '../config/types.js'\nimport type { PayloadRequest } from '../types/index.js'\nimport type { WithMetadata } from './optionallyAppendMetadata.js'\n\nexport type FileSize = {\n filename: null | string\n filesize: null | number\n height: null | number\n mimeType: null | string\n url?: null | string // TODO V4: make non-optional\n width: null | number\n}\n\n// TODO: deprecate in Payload v4.\n/**\n * FileSizeImproved is a more precise type, and will replace FileSize in Payload v4.\n * This type is for internal use only as it will be deprecated in the future.\n * @internal\n */\nexport type FileSizeImproved = {\n url: null | string\n} & FileSize\n\nexport type FileSizes = {\n [size: string]: FileSize\n}\n\nexport type FileData = {\n filename: string\n filesize: number\n focalX?: number\n focalY?: number\n height: number\n mimeType: string\n sizes: FileSizes\n tempFilePath?: string\n url?: string\n width: number\n}\n\nexport type ProbedImageSize = {\n height: number\n width: number\n}\n\n/**\n * Params sent to the sharp `toFormat()` function\n * @link https://sharp.pixelplumbing.com/api-output#toformat\n */\nexport type ImageUploadFormatOptions = {\n format: Parameters<Sharp['toFormat']>[0]\n options?: Parameters<Sharp['toFormat']>[1]\n}\n\n/**\n * Params sent to the sharp trim() function\n * @link https://sharp.pixelplumbing.com/api-resize#trim\n */\nexport type ImageUploadTrimOptions = Parameters<Sharp['trim']>[0]\n\nexport type GenerateImageName = (args: {\n extension: string\n height: number\n originalName: string\n sizeName: string\n width: number\n}) => string\n\nexport type ImageSize = {\n /**\n * Admin UI options that control how this image size appears in list views.\n *\n * NOTE: In Payload v4, these options (`disableGroupBy`, `disableListColumn` and `disableListFilter`)\n * should default to `true` so image size subfields are hidden from list columns\n * and filters by default, reducing noise in the admin UI.\n */\n admin?: {\n /**\n * If set to true, this image size will not be available\n * as a selectable groupBy option in the collection list view.\n * @default false\n */\n disableGroupBy?: boolean\n /**\n * If set to true, this image size will not be available\n * as a selectable column in the collection list view.\n * @default false\n */\n disableListColumn?: boolean\n /**\n * If set to true, this image size will not be available\n * as a filter option in the collection list view.\n * @default false\n */\n disableListFilter?: boolean\n }\n /**\n * @deprecated prefer position\n */\n crop?: string // comes from sharp package\n formatOptions?: ImageUploadFormatOptions\n /**\n * Generate a custom name for the file of this image size.\n */\n generateImageName?: GenerateImageName\n name: string\n trimOptions?: ImageUploadTrimOptions\n /**\n * When an uploaded image is smaller than the defined image size, we have 3 options:\n *\n * `undefined | false | true`\n *\n * 1. `undefined` [default]: uploading images with smaller width AND height than the image size will return null\n * 2. `false`: always enlarge images to the image size\n * 3. `true`: if the image is smaller than the image size, return the original image\n */\n withoutEnlargement?: ResizeOptions['withoutEnlargement']\n} & Omit<ResizeOptions, 'withoutEnlargement'>\n\nexport type GetAdminThumbnail = (args: { doc: Record<string, unknown> }) => false | null | string\n\nexport type AllowList = Array<{\n hostname: string\n pathname?: string\n port?: string\n protocol?: 'http' | 'https'\n search?: string\n}>\n\nexport type FileAllowList = Array<{\n extensions: string[]\n mimeType: string\n}>\n\ntype Admin = {\n components?: {\n /**\n * The Controls component to extend the upload controls in the admin panel.\n */\n controls?: PayloadComponent[]\n }\n}\n\nexport type UploadConfig = {\n /**\n * The adapter name to use for uploads. Used for storage adapter telemetry.\n * @default undefined\n */\n adapter?: string\n /**\n * The admin configuration for the upload field.\n */\n admin?: Admin\n /**\n * Represents an admin thumbnail, which can be either a React component or a string.\n * - If a string, it should be one of the image size names.\n * - A function that generates a fully qualified URL for the thumbnail, receives the doc as the only argument.\n **/\n adminThumbnail?: GetAdminThumbnail | string\n /**\n * Allow restricted file types known to be problematic.\n * - If set to `true`, it will allow all file types.\n * - If set to `false`, it will not allow file types and extensions known to be problematic.\n * - This setting is overriden by the `mimeTypes` option.\n * @default false\n */\n allowRestrictedFileTypes?: boolean\n /**\n * Enables bulk upload of files from the list view.\n * @default true\n */\n bulkUpload?: boolean\n /**\n * Appends a cache tag to the image URL when fetching the thumbnail in the admin panel. It may be desirable to disable this when hosting via CDNs with strict parameters.\n *\n * @default true\n */\n cacheTags?: boolean\n /**\n * Sharp constructor options to be passed to the uploaded file.\n * @link https://sharp.pixelplumbing.com/api-constructor/#sharp\n */\n constructorOptions?: SharpOptions\n /**\n * Enables cropping of images.\n * @default true\n */\n crop?: boolean\n /**\n * Disable the ability to save files to disk.\n * @default false\n */\n disableLocalStorage?: boolean\n /**\n * Enable displaying preview of the uploaded file in Upload fields related to this Collection.\n * Can be locally overridden by `displayPreview` option in Upload field.\n * @default false\n */\n displayPreview?: boolean\n /**\n *\n * Accepts existing headers and returns the headers after filtering or modifying.\n * If using this option, you should handle the removal of any sensitive cookies\n * (like payload-prefixed cookies) to prevent leaking session information to external\n * services. By default, Payload automatically filters out payload-prefixed cookies\n * when this option is NOT defined.\n *\n * Useful for adding custom headers to fetch from external providers.\n * @default undefined\n */\n externalFileHeaderFilter?: (headers: Record<string, string>) => Record<string, string>\n /**\n * Field slugs to use for a compound index instead of the default filename index.\n */\n filenameCompoundIndex?: string[]\n /**\n * Require files to be uploaded when creating a document.\n * @default true\n */\n filesRequiredOnCreate?: boolean\n /**\n * Enables focal point positioning for image manipulation.\n * @default true\n */\n focalPoint?: boolean\n /**\n * Format options for the uploaded file. Formatting image sizes needs to be done within each formatOptions individually.\n */\n formatOptions?: ImageUploadFormatOptions\n /**\n * Custom handlers to run when a file is fetched.\n *\n * - If a handler returns a Response, the response will be sent to the client and no further handlers will be run.\n * - If a handler returns null, the next handler will be run.\n * - If no handlers return a response the file will be returned by default.\n *\n * @link https://sharp.pixelplumbing.com/api-output/#toformat\n * @default undefined\n */\n handlers?: ((\n req: PayloadRequest,\n args: {\n doc: TypeWithID\n headers?: Headers\n params: { clientUploadContext?: unknown; collection: string; filename: string }\n },\n ) => Promise<Response> | Promise<void> | Response | void)[]\n /**\n * Set to `true` to prevent the admin UI from showing file inputs during document creation, useful for programmatic file generation.\n */\n hideFileInputOnCreate?: boolean\n /**\n * Set to `true` to prevent the admin UI having a way to remove an existing file while editing.\n */\n hideRemoveFile?: boolean\n imageSizes?: ImageSize[]\n /**\n * Restrict mimeTypes in the file picker. Array of valid mime types or mimetype wildcards\n * @example ['image/*', 'application/pdf']\n * @default undefined\n */\n mimeTypes?: string[]\n /**\n * Ability to modify the response headers fetching a file.\n * @default undefined\n */\n modifyResponseHeaders?: ({ headers }: { headers: Headers }) => Headers | void\n /**\n * Controls the behavior of pasting/uploading files from URLs.\n * If set to `false`, fetching from remote URLs is disabled.\n * If an `allowList` is provided, server-side fetching will be enabled for specified URLs.\n *\n * @default true (client-side fetching enabled)\n */\n pasteURL?:\n | {\n allowList: AllowList\n }\n | false\n /**\n * Sharp resize options for the original image.\n * @link https://sharp.pixelplumbing.com/api-resize#resize\n * @default undefined\n */\n resizeOptions?: ResizeOptions\n /**\n * Skip safe fetch when using server-side fetching for external files from these URLs.\n * @default false\n */\n skipSafeFetch?: AllowList | boolean\n /**\n * The directory to serve static files from. Defaults to collection slug.\n * @default undefined\n */\n staticDir?: string\n trimOptions?: ImageUploadTrimOptions\n /**\n * Optionally append metadata to the image during processing.\n *\n * Can be a boolean or a function.\n *\n * If true, metadata will be appended to the image.\n * If false, no metadata will be appended.\n * If a function, it will receive an object containing the metadata and should return a boolean indicating whether to append the metadata.\n * @default false\n */\n withMetadata?: WithMetadata\n}\nexport type checkFileRestrictionsParams = {\n collection: CollectionConfig\n file: File\n req: PayloadRequest\n}\n\nexport type SanitizedUploadConfig = {\n staticDir: UploadConfig['staticDir']\n} & UploadConfig\n\nexport type File = {\n /**\n * The buffer of the file.\n */\n data: Buffer\n /**\n * The mimetype of the file.\n */\n mimetype: string\n /**\n * The name of the file.\n */\n name: string\n /**\n * The size of the file in bytes.\n */\n size: number\n}\n\nexport type FileToSave = {\n /**\n * The buffer of the file.\n */\n buffer: Buffer\n /**\n * The path to save the file.\n */\n path: string\n}\n\ntype Crop = {\n height: number\n unit: '%' | 'px'\n width: number\n x: number\n y: number\n}\n\nexport type FocalPoint = {\n x: number\n y: number\n}\n\nexport type UploadEdits = {\n crop?: Crop\n focalPoint?: FocalPoint\n heightInPixels?: number\n widthInPixels?: number\n}\n"],"names":[],"mappings":"AA4WA,WAKC"}
|
|
1
|
+
{"version":3,"sources":["../../src/uploads/types.ts"],"sourcesContent":["import type { ResizeOptions, Sharp, SharpOptions } from 'sharp'\n\nimport type { CollectionConfig, TypeWithID } from '../collections/config/types.js'\nimport type { PayloadComponent } from '../config/types.js'\nimport type { PayloadRequest } from '../types/index.js'\nimport type { WithMetadata } from './optionallyAppendMetadata.js'\n\nexport type FileSize = {\n filename: null | string\n filesize: null | number\n height: null | number\n mimeType: null | string\n url?: null | string // TODO V4: make non-optional\n width: null | number\n}\n\n// TODO: deprecate in Payload v4.\n/**\n * FileSizeImproved is a more precise type, and will replace FileSize in Payload v4.\n * This type is for internal use only as it will be deprecated in the future.\n * @internal\n */\nexport type FileSizeImproved = {\n url: null | string\n} & FileSize\n\nexport type FileSizes = {\n [size: string]: FileSize\n}\n\nexport type FileData = {\n filename: string\n filesize: number\n focalX?: number\n focalY?: number\n height: number\n mimeType: string\n sizes: FileSizes\n tempFilePath?: string\n url?: string\n width: number\n}\n\nexport type ProbedImageSize = {\n height: number\n width: number\n}\n\n/**\n * Params sent to the sharp `toFormat()` function\n * @link https://sharp.pixelplumbing.com/api-output#toformat\n */\nexport type ImageUploadFormatOptions = {\n format: Parameters<Sharp['toFormat']>[0]\n options?: Parameters<Sharp['toFormat']>[1]\n}\n\n/**\n * Params sent to the sharp trim() function\n * @link https://sharp.pixelplumbing.com/api-resize#trim\n */\nexport type ImageUploadTrimOptions = Parameters<Sharp['trim']>[0]\n\nexport type GenerateImageName = (args: {\n extension: string\n height: number\n originalName: string\n sizeName: string\n width: number\n}) => string\n\nexport type ImageSize = {\n /**\n * Admin UI options that control how this image size appears in list views.\n *\n * NOTE: In Payload v4, these options (`disableGroupBy`, `disableListColumn` and `disableListFilter`)\n * should default to `true` so image size subfields are hidden from list columns\n * and filters by default, reducing noise in the admin UI.\n */\n admin?: {\n /**\n * If set to true, this image size will not be available\n * as a selectable groupBy option in the collection list view.\n * @default false\n */\n disableGroupBy?: boolean\n /**\n * If set to true, this image size will not be available\n * as a selectable column in the collection list view.\n * @default false\n */\n disableListColumn?: boolean\n /**\n * If set to true, this image size will not be available\n * as a filter option in the collection list view.\n * @default false\n */\n disableListFilter?: boolean\n }\n /**\n * @deprecated prefer position\n */\n crop?: string // comes from sharp package\n formatOptions?: ImageUploadFormatOptions\n /**\n * Generate a custom name for the file of this image size.\n */\n generateImageName?: GenerateImageName\n name: string\n trimOptions?: ImageUploadTrimOptions\n /**\n * When an uploaded image is smaller than the defined image size, we have 3 options:\n *\n * `undefined | false | true`\n *\n * 1. `undefined` [default]: uploading images with smaller width AND height than the image size will return null\n * 2. `false`: always enlarge images to the image size\n * 3. `true`: if the image is smaller than the image size, return the original image\n */\n withoutEnlargement?: ResizeOptions['withoutEnlargement']\n} & Omit<ResizeOptions, 'withoutEnlargement'>\n\nexport type GetAdminThumbnail = (args: { doc: Record<string, unknown> }) => false | null | string\n\nexport type AllowList = Array<{\n hostname: string\n pathname?: string\n port?: string\n protocol?: 'http' | 'https'\n search?: string\n}>\n\nexport type FileAllowList = Array<{\n extensions: string[]\n mimeType: string\n}>\n\ntype Admin = {\n components?: {\n /**\n * The Controls component to extend the upload controls in the admin panel.\n */\n controls?: PayloadComponent[]\n }\n}\n\nexport type UploadConfig = {\n /**\n * The adapter name to use for uploads. Used for storage adapter telemetry.\n * @default undefined\n */\n adapter?: string\n /**\n * The admin configuration for the upload field.\n */\n admin?: Admin\n /**\n * Represents an admin thumbnail, which can be either a React component or a string.\n * - If a string, it should be one of the image size names.\n * - A function that generates a fully qualified URL for the thumbnail, receives the doc as the only argument.\n **/\n adminThumbnail?: GetAdminThumbnail | string\n /**\n * Allow restricted file types known to be problematic.\n * - If set to `true`, it will allow all file types.\n * - If set to `false`, it will not allow file types and extensions known to be problematic.\n * - This setting is overriden by the `mimeTypes` option.\n * @default false\n */\n allowRestrictedFileTypes?: boolean\n /**\n * Enables bulk upload of files from the list view.\n * @default true\n */\n bulkUpload?: boolean\n /**\n * Appends a cache tag to the image URL when fetching the thumbnail in the admin panel. It may be desirable to disable this when hosting via CDNs with strict parameters.\n *\n * @default true\n */\n cacheTags?: boolean\n /**\n * Sharp constructor options to be passed to the uploaded file.\n * @link https://sharp.pixelplumbing.com/api-constructor/#sharp\n */\n constructorOptions?: SharpOptions\n /**\n * Enables cropping of images.\n * @default true\n */\n crop?: boolean\n /**\n * Disable the ability to save files to disk.\n * @default false\n */\n disableLocalStorage?: boolean\n /**\n * Enable displaying preview of the uploaded file in Upload fields related to this Collection.\n * Can be locally overridden by `displayPreview` option in Upload field.\n * @default false\n */\n displayPreview?: boolean\n /**\n *\n * Accepts existing headers and returns the headers after filtering or modifying.\n * If using this option, you should handle the removal of any sensitive cookies\n * (like payload-prefixed cookies) to prevent leaking session information to external\n * services. By default, Payload automatically filters out payload-prefixed cookies\n * when this option is NOT defined.\n *\n * Useful for adding custom headers to fetch from external providers.\n * @default undefined\n */\n externalFileHeaderFilter?: (headers: Record<string, string>) => Record<string, string>\n /**\n * Field slugs to use for a compound index instead of the default filename index.\n */\n filenameCompoundIndex?: string[]\n /**\n * Require files to be uploaded when creating a document.\n * @default true\n */\n filesRequiredOnCreate?: boolean\n /**\n * Enables focal point positioning for image manipulation.\n * @default true\n */\n focalPoint?: boolean\n /**\n * Format options for the uploaded file. Formatting image sizes needs to be done within each formatOptions individually.\n */\n formatOptions?: ImageUploadFormatOptions\n /**\n * Custom handlers to run when a file is fetched.\n *\n * - If a handler returns a Response, the response will be sent to the client and no further handlers will be run.\n * - If a handler returns null, the next handler will be run.\n * - If no handlers return a response the file will be returned by default.\n *\n * @link https://sharp.pixelplumbing.com/api-output/#toformat\n * @default undefined\n */\n handlers?: ((\n req: PayloadRequest,\n args: {\n doc: TypeWithID\n headers?: Headers\n params: {\n clientUploadContext?: unknown\n collection: string\n filename: string\n prefix?: string\n }\n },\n ) => Promise<Response> | Promise<void> | Response | void)[]\n /**\n * Set to `true` to prevent the admin UI from showing file inputs during document creation, useful for programmatic file generation.\n */\n hideFileInputOnCreate?: boolean\n /**\n * Set to `true` to prevent the admin UI having a way to remove an existing file while editing.\n */\n hideRemoveFile?: boolean\n imageSizes?: ImageSize[]\n /**\n * Restrict mimeTypes in the file picker. Array of valid mime types or mimetype wildcards\n * @example ['image/*', 'application/pdf']\n * @default undefined\n */\n mimeTypes?: string[]\n /**\n * Ability to modify the response headers fetching a file.\n * @default undefined\n */\n modifyResponseHeaders?: ({ headers }: { headers: Headers }) => Headers | void\n /**\n * Controls the behavior of pasting/uploading files from URLs.\n * If set to `false`, fetching from remote URLs is disabled.\n * If an `allowList` is provided, server-side fetching will be enabled for specified URLs.\n *\n * @default true (client-side fetching enabled)\n */\n pasteURL?:\n | {\n allowList: AllowList\n }\n | false\n /**\n * Sharp resize options for the original image.\n * @link https://sharp.pixelplumbing.com/api-resize#resize\n * @default undefined\n */\n resizeOptions?: ResizeOptions\n /**\n * Skip safe fetch when using server-side fetching for external files from these URLs.\n * @default false\n */\n skipSafeFetch?: AllowList | boolean\n /**\n * The directory to serve static files from. Defaults to collection slug.\n * @default undefined\n */\n staticDir?: string\n trimOptions?: ImageUploadTrimOptions\n /**\n * Optionally append metadata to the image during processing.\n *\n * Can be a boolean or a function.\n *\n * If true, metadata will be appended to the image.\n * If false, no metadata will be appended.\n * If a function, it will receive an object containing the metadata and should return a boolean indicating whether to append the metadata.\n * @default false\n */\n withMetadata?: WithMetadata\n}\nexport type checkFileRestrictionsParams = {\n collection: CollectionConfig\n file: File\n req: PayloadRequest\n}\n\nexport type SanitizedUploadConfig = {\n staticDir: UploadConfig['staticDir']\n} & UploadConfig\n\nexport type File = {\n /**\n * The buffer of the file.\n */\n data: Buffer\n /**\n * The mimetype of the file.\n */\n mimetype: string\n /**\n * The name of the file.\n */\n name: string\n /**\n * The size of the file in bytes.\n */\n size: number\n}\n\nexport type FileToSave = {\n /**\n * The buffer of the file.\n */\n buffer: Buffer\n /**\n * The path to save the file.\n */\n path: string\n}\n\ntype Crop = {\n height: number\n unit: '%' | 'px'\n width: number\n x: number\n y: number\n}\n\nexport type FocalPoint = {\n x: number\n y: number\n}\n\nexport type UploadEdits = {\n crop?: Crop\n focalPoint?: FocalPoint\n heightInPixels?: number\n widthInPixels?: number\n}\n"],"names":[],"mappings":"AAiXA,WAKC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payload",
|
|
3
|
-
"version": "3.82.0
|
|
3
|
+
"version": "3.82.0",
|
|
4
4
|
"description": "Node, React, Headless CMS and Application Framework built on Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"admin panel",
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"undici": "7.24.4",
|
|
116
116
|
"uuid": "10.0.0",
|
|
117
117
|
"ws": "^8.16.0",
|
|
118
|
-
"@payloadcms/translations": "3.82.0
|
|
118
|
+
"@payloadcms/translations": "3.82.0"
|
|
119
119
|
},
|
|
120
120
|
"devDependencies": {
|
|
121
121
|
"@hyrious/esbuild-plugin-commonjs": "0.2.6",
|