@payloadcms/next 3.89.0-internal.95c9cba → 3.90.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/elements/DocumentHeader/Tabs/Tab/index.d.ts +2 -1
- package/dist/elements/DocumentHeader/Tabs/Tab/index.d.ts.map +1 -1
- package/dist/elements/DocumentHeader/Tabs/Tab/index.js +3 -2
- package/dist/elements/DocumentHeader/Tabs/Tab/index.js.map +1 -1
- package/dist/elements/DocumentHeader/Tabs/index.d.ts +2 -1
- package/dist/elements/DocumentHeader/Tabs/index.d.ts.map +1 -1
- package/dist/elements/DocumentHeader/Tabs/index.js +5 -3
- package/dist/elements/DocumentHeader/Tabs/index.js.map +1 -1
- package/dist/elements/DocumentHeader/index.d.ts +2 -1
- package/dist/elements/DocumentHeader/index.d.ts.map +1 -1
- package/dist/elements/DocumentHeader/index.js +4 -2
- package/dist/elements/DocumentHeader/index.js.map +1 -1
- package/dist/layouts/Root/index.js +6 -5
- package/dist/layouts/Root/index.js.map +1 -1
- package/dist/prod/styles.css +1 -1
- package/dist/routes/graphql/handler.d.ts.map +1 -1
- package/dist/routes/graphql/handler.js +55 -47
- package/dist/routes/graphql/handler.js.map +1 -1
- package/dist/utilities/handleServerFunctions.d.ts.map +1 -1
- package/dist/utilities/handleServerFunctions.js +6 -3
- package/dist/utilities/handleServerFunctions.js.map +1 -1
- package/dist/utilities/initReq.d.ts.map +1 -1
- package/dist/utilities/initReq.js +35 -2
- package/dist/utilities/initReq.js.map +1 -1
- package/dist/utilities/initReq.spec.js +240 -0
- package/dist/utilities/initReq.spec.js.map +1 -0
- package/dist/utilities/isPublicAdminRoute.d.ts.map +1 -1
- package/dist/utilities/isPublicAdminRoute.js +11 -9
- package/dist/utilities/isPublicAdminRoute.js.map +1 -1
- package/dist/utilities/isPublicAdminRoute.spec.js +34 -0
- package/dist/utilities/isPublicAdminRoute.spec.js.map +1 -0
- package/dist/views/Account/index.d.ts +1 -1
- package/dist/views/Account/index.d.ts.map +1 -1
- package/dist/views/Account/index.js +10 -7
- package/dist/views/Account/index.js.map +1 -1
- package/dist/views/BrowseByFolder/buildView.js +4 -4
- package/dist/views/BrowseByFolder/buildView.js.map +1 -1
- package/dist/views/CollectionFolders/buildView.js +4 -4
- package/dist/views/CollectionFolders/buildView.js.map +1 -1
- package/dist/views/Dashboard/Default/ModularDashboard/index.d.ts.map +1 -1
- package/dist/views/Dashboard/Default/ModularDashboard/index.js +1 -0
- package/dist/views/Dashboard/Default/ModularDashboard/index.js.map +1 -1
- package/dist/views/Dashboard/Default/ModularDashboard/renderWidget/getDefaultLayoutServerFn.d.ts.map +1 -1
- package/dist/views/Dashboard/Default/ModularDashboard/renderWidget/getDefaultLayoutServerFn.js +3 -1
- package/dist/views/Dashboard/Default/ModularDashboard/renderWidget/getDefaultLayoutServerFn.js.map +1 -1
- package/dist/views/Dashboard/Default/ModularDashboard/renderWidget/renderWidgetServerFn.d.ts.map +1 -1
- package/dist/views/Dashboard/Default/ModularDashboard/renderWidget/renderWidgetServerFn.js +2 -0
- package/dist/views/Dashboard/Default/ModularDashboard/renderWidget/renderWidgetServerFn.js.map +1 -1
- package/dist/views/Dashboard/index.js +5 -3
- package/dist/views/Dashboard/index.js.map +1 -1
- package/dist/views/Document/handleServerFunction.d.ts.map +1 -1
- package/dist/views/Document/handleServerFunction.js +2 -0
- package/dist/views/Document/handleServerFunction.js.map +1 -1
- package/dist/views/Document/index.d.ts +1 -1
- package/dist/views/Document/index.d.ts.map +1 -1
- package/dist/views/Document/index.js +9 -4
- package/dist/views/Document/index.js.map +1 -1
- package/dist/views/Document/renderDocumentSlots.d.ts +1 -0
- package/dist/views/Document/renderDocumentSlots.d.ts.map +1 -1
- package/dist/views/Document/renderDocumentSlots.js +7 -4
- package/dist/views/Document/renderDocumentSlots.js.map +1 -1
- package/dist/views/ForgotPassword/ForgotPasswordForm/index.d.ts +1 -0
- package/dist/views/ForgotPassword/ForgotPasswordForm/index.d.ts.map +1 -1
- package/dist/views/ForgotPassword/ForgotPasswordForm/index.js +212 -159
- package/dist/views/ForgotPassword/ForgotPasswordForm/index.js.map +1 -1
- package/dist/views/ForgotPassword/index.d.ts.map +1 -1
- package/dist/views/ForgotPassword/index.js +3 -11
- package/dist/views/ForgotPassword/index.js.map +1 -1
- package/dist/views/List/handleServerFunction.d.ts.map +1 -1
- package/dist/views/List/handleServerFunction.js +4 -2
- package/dist/views/List/handleServerFunction.js.map +1 -1
- package/dist/views/List/index.d.ts.map +1 -1
- package/dist/views/List/index.js +2 -1
- package/dist/views/List/index.js.map +1 -1
- package/dist/views/NotFound/index.d.ts.map +1 -1
- package/dist/views/NotFound/index.js +3 -2
- package/dist/views/NotFound/index.js.map +1 -1
- package/dist/views/Root/index.d.ts.map +1 -1
- package/dist/views/Root/index.js +6 -4
- package/dist/views/Root/index.js.map +1 -1
- package/dist/views/Verify/index.d.ts +1 -1
- package/dist/views/Verify/index.d.ts.map +1 -1
- package/dist/views/Verify/index.js +4 -4
- package/dist/views/Verify/index.js.map +1 -1
- package/dist/views/Version/RenderFieldsToDiff/DiffCollapser/index.d.ts +1 -0
- package/dist/views/Version/RenderFieldsToDiff/DiffCollapser/index.d.ts.map +1 -1
- package/dist/views/Version/RenderFieldsToDiff/DiffCollapser/index.js +56 -50
- package/dist/views/Version/RenderFieldsToDiff/DiffCollapser/index.js.map +1 -1
- package/dist/views/Version/RenderFieldsToDiff/buildVersionFields.d.ts.map +1 -1
- package/dist/views/Version/RenderFieldsToDiff/buildVersionFields.js +42 -28
- package/dist/views/Version/RenderFieldsToDiff/buildVersionFields.js.map +1 -1
- package/dist/views/Version/RenderFieldsToDiff/buildVersionFields.spec.js +258 -0
- package/dist/views/Version/RenderFieldsToDiff/buildVersionFields.spec.js.map +1 -0
- package/dist/views/Version/RenderFieldsToDiff/fields/Iterable/index.d.ts.map +1 -1
- package/dist/views/Version/RenderFieldsToDiff/fields/Iterable/index.js +10 -0
- package/dist/views/Version/RenderFieldsToDiff/fields/Iterable/index.js.map +1 -1
- package/dist/views/Version/RenderFieldsToDiff/utilities/countChangedFields.d.ts.map +1 -1
- package/dist/views/Version/RenderFieldsToDiff/utilities/countChangedFields.js +33 -1
- package/dist/views/Version/RenderFieldsToDiff/utilities/countChangedFields.js.map +1 -1
- package/dist/views/Version/RenderFieldsToDiff/utilities/countChangedFields.spec.js +56 -2
- package/dist/views/Version/RenderFieldsToDiff/utilities/countChangedFields.spec.js.map +1 -1
- package/dist/views/Version/RenderFieldsToDiff/utilities/getFieldsForRowComparison.d.ts +8 -2
- package/dist/views/Version/RenderFieldsToDiff/utilities/getFieldsForRowComparison.d.ts.map +1 -1
- package/dist/views/Version/RenderFieldsToDiff/utilities/getFieldsForRowComparison.js +17 -19
- package/dist/views/Version/RenderFieldsToDiff/utilities/getFieldsForRowComparison.js.map +1 -1
- package/dist/views/Version/RenderFieldsToDiff/utilities/getFieldsForRowComparison.spec.js +3 -13
- package/dist/views/Version/RenderFieldsToDiff/utilities/getFieldsForRowComparison.spec.js.map +1 -1
- package/package.json +9 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/routes/graphql/handler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAqC,eAAe,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/routes/graphql/handler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAqC,eAAe,EAAE,MAAM,SAAS,CAAA;AAsEjF,eAAO,MAAM,UAAU,WAAkB,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,iBAyBlF,CAAA;AAED,eAAO,MAAM,IAAI,WACN,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,eAAqB,OAAO,sBAmE9E,CAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { configToSchema } from '@payloadcms/graphql';
|
|
2
2
|
import { createHandler } from 'graphql-http/lib/use/fetch';
|
|
3
3
|
import { status as httpStatus } from 'http-status';
|
|
4
|
-
import { addDataAndFileToRequest, addLocalesToRequestFromData, createPayloadRequest, headersWithCors, logError, mergeHeaders } from 'payload';
|
|
4
|
+
import { addDataAndFileToRequest, addLocalesToRequestFromData, createPayloadRequest, headersWithCors, logError, mergeHeaders, unlinkClientUploadTempFile } from 'payload';
|
|
5
5
|
const handleError = async ({
|
|
6
6
|
err,
|
|
7
7
|
payload,
|
|
@@ -90,53 +90,61 @@ export const POST = config => async request => {
|
|
|
90
90
|
status: 404
|
|
91
91
|
});
|
|
92
92
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
93
|
+
try {
|
|
94
|
+
await addDataAndFileToRequest(req);
|
|
95
|
+
addLocalesToRequestFromData(req);
|
|
96
|
+
const {
|
|
97
|
+
schema,
|
|
98
|
+
validationRules
|
|
99
|
+
} = await getGraphql(config);
|
|
100
|
+
const headers = {};
|
|
101
|
+
const apiResponse = await createHandler({
|
|
102
|
+
context: {
|
|
103
|
+
headers,
|
|
104
|
+
req
|
|
105
|
+
},
|
|
106
|
+
onOperation: async (request, args, result) => {
|
|
107
|
+
const response = typeof payload.extensions === 'function' ? await payload.extensions({
|
|
108
|
+
args,
|
|
109
|
+
req: request,
|
|
110
|
+
result
|
|
111
|
+
}) : result;
|
|
112
|
+
if (response.errors) {
|
|
113
|
+
const errors = await Promise.all(result.errors.map(error => {
|
|
114
|
+
return handleError({
|
|
115
|
+
err: error,
|
|
116
|
+
payload,
|
|
117
|
+
req
|
|
118
|
+
});
|
|
119
|
+
}));
|
|
120
|
+
// errors type should be FormattedGraphQLError[] but onOperation has a return type of ExecutionResult instead of FormattedExecutionResult
|
|
121
|
+
return {
|
|
122
|
+
...response,
|
|
123
|
+
errors
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
return response;
|
|
127
|
+
},
|
|
128
|
+
schema,
|
|
129
|
+
validationRules: (_, args, defaultRules) => defaultRules.concat(validationRules(args))
|
|
130
|
+
})(originalRequest);
|
|
131
|
+
const resHeaders = headersWithCors({
|
|
132
|
+
headers: new Headers(apiResponse.headers),
|
|
103
133
|
req
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}));
|
|
119
|
-
// errors type should be FormattedGraphQLError[] but onOperation has a return type of ExecutionResult instead of FormattedExecutionResult
|
|
120
|
-
return {
|
|
121
|
-
...response,
|
|
122
|
-
errors
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
return response;
|
|
126
|
-
},
|
|
127
|
-
schema,
|
|
128
|
-
validationRules: (_, args, defaultRules) => defaultRules.concat(validationRules(args))
|
|
129
|
-
})(originalRequest);
|
|
130
|
-
const resHeaders = headersWithCors({
|
|
131
|
-
headers: new Headers(apiResponse.headers),
|
|
132
|
-
req
|
|
133
|
-
});
|
|
134
|
-
for (const key in headers) {
|
|
135
|
-
resHeaders.append(key, headers[key]);
|
|
134
|
+
});
|
|
135
|
+
for (const key in headers) {
|
|
136
|
+
resHeaders.append(key, headers[key]);
|
|
137
|
+
}
|
|
138
|
+
return new Response(apiResponse.body, {
|
|
139
|
+
headers: req.responseHeaders ? mergeHeaders(req.responseHeaders, resHeaders) : resHeaders,
|
|
140
|
+
status: apiResponse.status
|
|
141
|
+
});
|
|
142
|
+
} finally {
|
|
143
|
+
// GraphQL parses the body itself instead of going through wrapInternalEndpoints, and an
|
|
144
|
+
// operation that writes no document never reaches the operation-level cleanup.
|
|
145
|
+
await unlinkClientUploadTempFile({
|
|
146
|
+
req
|
|
147
|
+
});
|
|
136
148
|
}
|
|
137
|
-
return new Response(apiResponse.body, {
|
|
138
|
-
headers: req.responseHeaders ? mergeHeaders(req.responseHeaders, resHeaders) : resHeaders,
|
|
139
|
-
status: apiResponse.status
|
|
140
|
-
});
|
|
141
149
|
};
|
|
142
150
|
//# sourceMappingURL=handler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.js","names":["configToSchema","createHandler","status","httpStatus","addDataAndFileToRequest","addLocalesToRequestFromData","createPayloadRequest","headersWithCors","logError","mergeHeaders","handleError","err","payload","req","originalError","INTERNAL_SERVER_ERROR","errorMessage","message","config","debug","response","extensions","name","undefined","data","stack","statusCode","locations","path","hooks","afterError","reduce","promise","hook","result","context","error","graphqlResult","Promise","resolve","cached","global","_payload_graphql","graphql","getGraphql","process","env","NODE_ENV","resolvedConfig","schema","e","POST","request","originalRequest","clone","canSetHeaders","graphQL","disable","Response","validationRules","headers","apiResponse","onOperation","args","errors","all","map","_","defaultRules","concat","resHeaders","Headers","key","append","body","responseHeaders"],"sources":["../../../src/routes/graphql/handler.ts"],"sourcesContent":["import type { GraphQLError, GraphQLFormattedError } from 'graphql'\nimport type { APIError, Payload, PayloadRequest, SanitizedConfig } from 'payload'\n\nimport { configToSchema } from '@payloadcms/graphql'\nimport { createHandler } from 'graphql-http/lib/use/fetch'\nimport { status as httpStatus } from 'http-status'\nimport {\n addDataAndFileToRequest,\n addLocalesToRequestFromData,\n createPayloadRequest,\n headersWithCors,\n logError,\n mergeHeaders,\n} from 'payload'\n\nconst handleError = async ({\n err,\n payload,\n req,\n}: {\n err: GraphQLError\n payload: Payload\n req: PayloadRequest\n}): Promise<GraphQLFormattedError> => {\n const status = (err.originalError as APIError).status || httpStatus.INTERNAL_SERVER_ERROR\n let errorMessage = err.message\n logError({ err, payload })\n\n // Internal server errors can contain anything, including potentially sensitive data.\n // Therefore, error details will be hidden from the response unless `config.debug` is `true`\n if (!payload.config.debug && status === httpStatus.INTERNAL_SERVER_ERROR) {\n errorMessage = 'Something went wrong.'\n }\n\n let response: GraphQLFormattedError = {\n extensions: {\n name: err?.originalError?.name || undefined,\n data: (err && err.originalError && (err.originalError as APIError).data) || undefined,\n stack: payload.config.debug ? err.stack : undefined,\n statusCode: status,\n },\n locations: err.locations,\n message: errorMessage,\n path: err.path,\n }\n\n await payload.config.hooks.afterError?.reduce(async (promise, hook) => {\n await promise\n\n const result = await hook({\n context: req.context,\n error: err,\n graphqlResult: response,\n req,\n })\n\n if (result) {\n response = result.graphqlResult || response\n }\n }, Promise.resolve())\n\n return response\n}\n\nlet cached = global._payload_graphql\n\nif (!cached) {\n cached = global._payload_graphql = { graphql: null, promise: null }\n}\n\nexport const getGraphql = async (config: Promise<SanitizedConfig> | SanitizedConfig) => {\n if (process.env.NODE_ENV === 'development') {\n cached = global._payload_graphql = { graphql: null, promise: null }\n }\n\n if (cached.graphql) {\n return cached.graphql\n }\n\n if (!cached.promise) {\n const resolvedConfig = await config\n cached.promise = new Promise((resolve) => {\n const schema = configToSchema(resolvedConfig)\n resolve(cached.graphql || schema)\n })\n }\n\n try {\n cached.graphql = await cached.promise\n } catch (e) {\n cached.promise = null\n throw e\n }\n\n return cached.graphql\n}\n\nexport const POST =\n (config: Promise<SanitizedConfig> | SanitizedConfig) => async (request: Request) => {\n const originalRequest = request.clone()\n const req = await createPayloadRequest({\n canSetHeaders: true,\n config,\n request,\n })\n\n const { payload } = req\n\n if (payload.config.graphQL?.disable) {\n return new Response(null, {\n status: 404,\n })\n }\n\n await addDataAndFileToRequest(req)\n
|
|
1
|
+
{"version":3,"file":"handler.js","names":["configToSchema","createHandler","status","httpStatus","addDataAndFileToRequest","addLocalesToRequestFromData","createPayloadRequest","headersWithCors","logError","mergeHeaders","unlinkClientUploadTempFile","handleError","err","payload","req","originalError","INTERNAL_SERVER_ERROR","errorMessage","message","config","debug","response","extensions","name","undefined","data","stack","statusCode","locations","path","hooks","afterError","reduce","promise","hook","result","context","error","graphqlResult","Promise","resolve","cached","global","_payload_graphql","graphql","getGraphql","process","env","NODE_ENV","resolvedConfig","schema","e","POST","request","originalRequest","clone","canSetHeaders","graphQL","disable","Response","validationRules","headers","apiResponse","onOperation","args","errors","all","map","_","defaultRules","concat","resHeaders","Headers","key","append","body","responseHeaders"],"sources":["../../../src/routes/graphql/handler.ts"],"sourcesContent":["import type { GraphQLError, GraphQLFormattedError } from 'graphql'\nimport type { APIError, Payload, PayloadRequest, SanitizedConfig } from 'payload'\n\nimport { configToSchema } from '@payloadcms/graphql'\nimport { createHandler } from 'graphql-http/lib/use/fetch'\nimport { status as httpStatus } from 'http-status'\nimport {\n addDataAndFileToRequest,\n addLocalesToRequestFromData,\n createPayloadRequest,\n headersWithCors,\n logError,\n mergeHeaders,\n unlinkClientUploadTempFile,\n} from 'payload'\n\nconst handleError = async ({\n err,\n payload,\n req,\n}: {\n err: GraphQLError\n payload: Payload\n req: PayloadRequest\n}): Promise<GraphQLFormattedError> => {\n const status = (err.originalError as APIError).status || httpStatus.INTERNAL_SERVER_ERROR\n let errorMessage = err.message\n logError({ err, payload })\n\n // Internal server errors can contain anything, including potentially sensitive data.\n // Therefore, error details will be hidden from the response unless `config.debug` is `true`\n if (!payload.config.debug && status === httpStatus.INTERNAL_SERVER_ERROR) {\n errorMessage = 'Something went wrong.'\n }\n\n let response: GraphQLFormattedError = {\n extensions: {\n name: err?.originalError?.name || undefined,\n data: (err && err.originalError && (err.originalError as APIError).data) || undefined,\n stack: payload.config.debug ? err.stack : undefined,\n statusCode: status,\n },\n locations: err.locations,\n message: errorMessage,\n path: err.path,\n }\n\n await payload.config.hooks.afterError?.reduce(async (promise, hook) => {\n await promise\n\n const result = await hook({\n context: req.context,\n error: err,\n graphqlResult: response,\n req,\n })\n\n if (result) {\n response = result.graphqlResult || response\n }\n }, Promise.resolve())\n\n return response\n}\n\nlet cached = global._payload_graphql\n\nif (!cached) {\n cached = global._payload_graphql = { graphql: null, promise: null }\n}\n\nexport const getGraphql = async (config: Promise<SanitizedConfig> | SanitizedConfig) => {\n if (process.env.NODE_ENV === 'development') {\n cached = global._payload_graphql = { graphql: null, promise: null }\n }\n\n if (cached.graphql) {\n return cached.graphql\n }\n\n if (!cached.promise) {\n const resolvedConfig = await config\n cached.promise = new Promise((resolve) => {\n const schema = configToSchema(resolvedConfig)\n resolve(cached.graphql || schema)\n })\n }\n\n try {\n cached.graphql = await cached.promise\n } catch (e) {\n cached.promise = null\n throw e\n }\n\n return cached.graphql\n}\n\nexport const POST =\n (config: Promise<SanitizedConfig> | SanitizedConfig) => async (request: Request) => {\n const originalRequest = request.clone()\n const req = await createPayloadRequest({\n canSetHeaders: true,\n config,\n request,\n })\n\n const { payload } = req\n\n if (payload.config.graphQL?.disable) {\n return new Response(null, {\n status: 404,\n })\n }\n\n try {\n await addDataAndFileToRequest(req)\n addLocalesToRequestFromData(req)\n\n const { schema, validationRules } = await getGraphql(config)\n\n const headers = {}\n const apiResponse = await createHandler({\n context: { headers, req },\n onOperation: async (request, args, result) => {\n const response =\n typeof payload.extensions === 'function'\n ? await payload.extensions({\n args,\n req: request,\n result,\n })\n : result\n if (response.errors) {\n const errors = (await Promise.all(\n result.errors.map((error) => {\n return handleError({ err: error, payload, req })\n }),\n )) as GraphQLError[]\n // errors type should be FormattedGraphQLError[] but onOperation has a return type of ExecutionResult instead of FormattedExecutionResult\n return { ...response, errors }\n }\n return response\n },\n schema,\n validationRules: (_, args, defaultRules) => defaultRules.concat(validationRules(args)),\n })(originalRequest)\n\n const resHeaders = headersWithCors({\n headers: new Headers(apiResponse.headers),\n req,\n })\n\n for (const key in headers) {\n resHeaders.append(key, headers[key])\n }\n\n return new Response(apiResponse.body, {\n headers: req.responseHeaders ? mergeHeaders(req.responseHeaders, resHeaders) : resHeaders,\n status: apiResponse.status,\n })\n } finally {\n // GraphQL parses the body itself instead of going through wrapInternalEndpoints, and an\n // operation that writes no document never reaches the operation-level cleanup.\n await unlinkClientUploadTempFile({ req })\n }\n }\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleServerFunctions.d.ts","sourceRoot":"","sources":["../../src/utilities/handleServerFunctions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6C,qBAAqB,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"handleServerFunctions.d.ts","sourceRoot":"","sources":["../../src/utilities/handleServerFunctions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6C,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAmC/F,eAAO,MAAM,qBAAqB,EAAE,qBAgCnC,CAAA"}
|
|
@@ -2,7 +2,7 @@ import { _internal_renderFieldHandler, copyDataFromLocaleHandler } from '@payloa
|
|
|
2
2
|
import { buildFormStateHandler } from '@payloadcms/ui/utilities/buildFormState';
|
|
3
3
|
import { buildTableStateHandler } from '@payloadcms/ui/utilities/buildTableState';
|
|
4
4
|
import { getFolderResultsComponentAndDataHandler } from '@payloadcms/ui/utilities/getFolderResultsComponentAndData';
|
|
5
|
-
import { schedulePublishHandler } from '@payloadcms/ui/utilities/schedulePublishHandler';
|
|
5
|
+
import { getUpcomingScheduledPublishHandler, schedulePublishHandler } from '@payloadcms/ui/utilities/schedulePublishHandler';
|
|
6
6
|
import { getDefaultLayoutHandler } from '../views/Dashboard/Default/ModularDashboard/renderWidget/getDefaultLayoutServerFn.js';
|
|
7
7
|
import { renderWidgetHandler } from '../views/Dashboard/Default/ModularDashboard/renderWidget/renderWidgetServerFn.js';
|
|
8
8
|
import { renderDocumentHandler } from '../views/Document/handleServerFunction.js';
|
|
@@ -15,6 +15,7 @@ const baseServerFunctions = {
|
|
|
15
15
|
'form-state': buildFormStateHandler,
|
|
16
16
|
'get-default-layout': getDefaultLayoutHandler,
|
|
17
17
|
'get-folder-results-component-and-data': getFolderResultsComponentAndDataHandler,
|
|
18
|
+
'get-upcoming-scheduled-publish': getUpcomingScheduledPublishHandler,
|
|
18
19
|
'render-document': renderDocumentHandler,
|
|
19
20
|
'render-document-slots': renderDocumentSlotsHandler,
|
|
20
21
|
'render-field': _internal_renderFieldHandler,
|
|
@@ -36,7 +37,8 @@ export const handleServerFunctions = async args => {
|
|
|
36
37
|
cookies,
|
|
37
38
|
locale,
|
|
38
39
|
permissions,
|
|
39
|
-
req
|
|
40
|
+
req,
|
|
41
|
+
user
|
|
40
42
|
} = await initReq({
|
|
41
43
|
configPromise,
|
|
42
44
|
importMap,
|
|
@@ -48,7 +50,8 @@ export const handleServerFunctions = async args => {
|
|
|
48
50
|
importMap,
|
|
49
51
|
locale,
|
|
50
52
|
permissions,
|
|
51
|
-
req
|
|
53
|
+
req,
|
|
54
|
+
user
|
|
52
55
|
};
|
|
53
56
|
const fn = extraServerFunctions?.[fnKey] || baseServerFunctions[fnKey];
|
|
54
57
|
if (!fn) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleServerFunctions.js","names":["_internal_renderFieldHandler","copyDataFromLocaleHandler","buildFormStateHandler","buildTableStateHandler","getFolderResultsComponentAndDataHandler","schedulePublishHandler","getDefaultLayoutHandler","renderWidgetHandler","renderDocumentHandler","renderDocumentSlotsHandler","renderListHandler","initReq","slugifyHandler","baseServerFunctions","slugify","handleServerFunctions","args","name","fnKey","fnArgs","config","configPromise","importMap","serverFunctions","extraServerFunctions","cookies","locale","permissions","req","key","augmentedArgs","fn","Error"],"sources":["../../src/utilities/handleServerFunctions.ts"],"sourcesContent":["import type { DefaultServerFunctionArgs, ServerFunction, ServerFunctionHandler } from 'payload'\n\nimport { _internal_renderFieldHandler, copyDataFromLocaleHandler } from '@payloadcms/ui/rsc'\nimport { buildFormStateHandler } from '@payloadcms/ui/utilities/buildFormState'\nimport { buildTableStateHandler } from '@payloadcms/ui/utilities/buildTableState'\nimport { getFolderResultsComponentAndDataHandler } from '@payloadcms/ui/utilities/getFolderResultsComponentAndData'\nimport {
|
|
1
|
+
{"version":3,"file":"handleServerFunctions.js","names":["_internal_renderFieldHandler","copyDataFromLocaleHandler","buildFormStateHandler","buildTableStateHandler","getFolderResultsComponentAndDataHandler","getUpcomingScheduledPublishHandler","schedulePublishHandler","getDefaultLayoutHandler","renderWidgetHandler","renderDocumentHandler","renderDocumentSlotsHandler","renderListHandler","initReq","slugifyHandler","baseServerFunctions","slugify","handleServerFunctions","args","name","fnKey","fnArgs","config","configPromise","importMap","serverFunctions","extraServerFunctions","cookies","locale","permissions","req","user","key","augmentedArgs","fn","Error"],"sources":["../../src/utilities/handleServerFunctions.ts"],"sourcesContent":["import type { DefaultServerFunctionArgs, ServerFunction, ServerFunctionHandler } from 'payload'\n\nimport { _internal_renderFieldHandler, copyDataFromLocaleHandler } from '@payloadcms/ui/rsc'\nimport { buildFormStateHandler } from '@payloadcms/ui/utilities/buildFormState'\nimport { buildTableStateHandler } from '@payloadcms/ui/utilities/buildTableState'\nimport { getFolderResultsComponentAndDataHandler } from '@payloadcms/ui/utilities/getFolderResultsComponentAndData'\nimport {\n getUpcomingScheduledPublishHandler,\n schedulePublishHandler,\n} from '@payloadcms/ui/utilities/schedulePublishHandler'\n\nimport { getDefaultLayoutHandler } from '../views/Dashboard/Default/ModularDashboard/renderWidget/getDefaultLayoutServerFn.js'\nimport { renderWidgetHandler } from '../views/Dashboard/Default/ModularDashboard/renderWidget/renderWidgetServerFn.js'\nimport { renderDocumentHandler } from '../views/Document/handleServerFunction.js'\nimport { renderDocumentSlotsHandler } from '../views/Document/renderDocumentSlots.js'\nimport { renderListHandler } from '../views/List/handleServerFunction.js'\nimport { initReq } from './initReq.js'\nimport { slugifyHandler } from './slugify.js'\n\nconst baseServerFunctions: Record<string, ServerFunction<any, any>> = {\n 'copy-data-from-locale': copyDataFromLocaleHandler,\n 'form-state': buildFormStateHandler,\n 'get-default-layout': getDefaultLayoutHandler,\n 'get-folder-results-component-and-data': getFolderResultsComponentAndDataHandler,\n 'get-upcoming-scheduled-publish': getUpcomingScheduledPublishHandler,\n 'render-document': renderDocumentHandler,\n 'render-document-slots': renderDocumentSlotsHandler,\n 'render-field': _internal_renderFieldHandler,\n 'render-list': renderListHandler,\n 'render-widget': renderWidgetHandler,\n 'schedule-publish': schedulePublishHandler,\n slugify: slugifyHandler,\n 'table-state': buildTableStateHandler,\n}\n\nexport const handleServerFunctions: ServerFunctionHandler = async (args) => {\n const {\n name: fnKey,\n args: fnArgs,\n config: configPromise,\n importMap,\n serverFunctions: extraServerFunctions,\n } = args\n\n const { cookies, locale, permissions, req, user } = await initReq({\n configPromise,\n importMap,\n key: 'RootLayout',\n })\n\n const augmentedArgs: DefaultServerFunctionArgs = {\n ...fnArgs,\n cookies,\n importMap,\n locale,\n permissions,\n req,\n user,\n }\n\n const fn = extraServerFunctions?.[fnKey] || baseServerFunctions[fnKey]\n\n if (!fn) {\n throw new Error(`Unknown Server Function: ${fnKey}`)\n }\n\n return fn(augmentedArgs)\n}\n"],"mappings":"AAEA,SAASA,4BAA4B,EAAEC,yBAAyB,QAAQ;AACxE,SAASC,qBAAqB,QAAQ;AACtC,SAASC,sBAAsB,QAAQ;AACvC,SAASC,uCAAuC,QAAQ;AACxD,SACEC,kCAAkC,EAClCC,sBAAsB,QACjB;AAEP,SAASC,uBAAuB,QAAQ;AACxC,SAASC,mBAAmB,QAAQ;AACpC,SAASC,qBAAqB,QAAQ;AACtC,SAASC,0BAA0B,QAAQ;AAC3C,SAASC,iBAAiB,QAAQ;AAClC,SAASC,OAAO,QAAQ;AACxB,SAASC,cAAc,QAAQ;AAE/B,MAAMC,mBAAA,GAAgE;EACpE,yBAAyBb,yBAAA;EACzB,cAAcC,qBAAA;EACd,sBAAsBK,uBAAA;EACtB,yCAAyCH,uCAAA;EACzC,kCAAkCC,kCAAA;EAClC,mBAAmBI,qBAAA;EACnB,yBAAyBC,0BAAA;EACzB,gBAAgBV,4BAAA;EAChB,eAAeW,iBAAA;EACf,iBAAiBH,mBAAA;EACjB,oBAAoBF,sBAAA;EACpBS,OAAA,EAASF,cAAA;EACT,eAAeV;AACjB;AAEA,OAAO,MAAMa,qBAAA,GAA+C,MAAOC,IAAA;EACjE,MAAM;IACJC,IAAA,EAAMC,KAAK;IACXF,IAAA,EAAMG,MAAM;IACZC,MAAA,EAAQC,aAAa;IACrBC,SAAS;IACTC,eAAA,EAAiBC;EAAoB,CACtC,GAAGR,IAAA;EAEJ,MAAM;IAAES,OAAO;IAAEC,MAAM;IAAEC,WAAW;IAAEC,GAAG;IAAEC;EAAI,CAAE,GAAG,MAAMlB,OAAA,CAAQ;IAChEU,aAAA;IACAC,SAAA;IACAQ,GAAA,EAAK;EACP;EAEA,MAAMC,aAAA,GAA2C;IAC/C,GAAGZ,MAAM;IACTM,OAAA;IACAH,SAAA;IACAI,MAAA;IACAC,WAAA;IACAC,GAAA;IACAC;EACF;EAEA,MAAMG,EAAA,GAAKR,oBAAA,GAAuBN,KAAA,CAAM,IAAIL,mBAAmB,CAACK,KAAA,CAAM;EAEtE,IAAI,CAACc,EAAA,EAAI;IACP,MAAM,IAAIC,KAAA,CAAM,4BAA4Bf,KAAA,EAAO;EACrD;EAEA,OAAOc,EAAA,CAAGD,aAAA;AACZ","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initReq.d.ts","sourceRoot":"","sources":["../../src/utilities/initReq.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAkB,eAAe,EAAE,MAAM,SAAS,CAAA;AAIxF,OAAO,EACL,cAAc,EAMf,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"initReq.d.ts","sourceRoot":"","sources":["../../src/utilities/initReq.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAkB,eAAe,EAAE,MAAM,SAAS,CAAA;AAIxF,OAAO,EACL,cAAc,EAMf,MAAM,SAAS,CAAA;AAehB;;;GAGG;AACH,eAAO,MAAM,OAAO,iEAMjB;IACD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,aAAa,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAAA;IACzD,SAAS,EAAE,SAAS,CAAA;IACpB,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA;CACjD,KAAG,OAAO,CAAC,aAAa,CA8HxB,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { initI18n } from '@payloadcms/translations';
|
|
2
2
|
import { headers as getHeaders } from 'next/headers.js';
|
|
3
3
|
import { createLocalReq, executeAuthStrategies, getAccessResults, getPayload, getRequestLanguage, parseCookies } from 'payload';
|
|
4
|
+
import { applyUserReadAccess } from 'payload/internal';
|
|
4
5
|
import { getRequestLocale } from './getRequestLocale.js';
|
|
5
6
|
import { selectiveCache } from './selectiveCache.js';
|
|
6
7
|
// Create cache instances for different parts of our application
|
|
@@ -64,6 +65,10 @@ export const initReq = async function ({
|
|
|
64
65
|
req: reqOverrides,
|
|
65
66
|
...optionsOverrides
|
|
66
67
|
} = overrides || {};
|
|
68
|
+
const hasOptionsUserOverride = Object.hasOwn(optionsOverrides, 'user');
|
|
69
|
+
const hasReqUserOverride = Object.hasOwn(reqOverrides ?? {}, 'user');
|
|
70
|
+
const hasUserOverride = hasOptionsUserOverride || hasReqUserOverride;
|
|
71
|
+
const userOverride = hasOptionsUserOverride ? optionsOverrides.user : reqOverrides?.user;
|
|
67
72
|
const req = await createLocalReq({
|
|
68
73
|
req: {
|
|
69
74
|
headers,
|
|
@@ -75,10 +80,37 @@ export const initReq = async function ({
|
|
|
75
80
|
},
|
|
76
81
|
...(optionsOverrides || {})
|
|
77
82
|
}, payload);
|
|
83
|
+
if (hasUserOverride && userOverride == null) {
|
|
84
|
+
req.user = null;
|
|
85
|
+
}
|
|
86
|
+
let userWithReadAccess = req.user;
|
|
78
87
|
const locale = await getRequestLocale({
|
|
79
88
|
req
|
|
80
89
|
});
|
|
81
90
|
req.locale = locale?.code;
|
|
91
|
+
if (!hasUserOverride && req.user) {
|
|
92
|
+
try {
|
|
93
|
+
const collectionSlug = req.user.collection ?? payload.config.admin.user;
|
|
94
|
+
const collection = payload.collections[collectionSlug];
|
|
95
|
+
if (!collection?.config.auth) {
|
|
96
|
+
throw new Error('Authenticated user collection not found');
|
|
97
|
+
}
|
|
98
|
+
userWithReadAccess = await applyUserReadAccess({
|
|
99
|
+
collection: collection.config,
|
|
100
|
+
depth: collection.config.auth.depth,
|
|
101
|
+
overrideAccess: false,
|
|
102
|
+
req,
|
|
103
|
+
showHiddenFields: false,
|
|
104
|
+
user: req.user
|
|
105
|
+
});
|
|
106
|
+
} catch (error) {
|
|
107
|
+
payload.logger.error({
|
|
108
|
+
err: error
|
|
109
|
+
});
|
|
110
|
+
req.user = null;
|
|
111
|
+
userWithReadAccess = null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
82
114
|
const permissions = await getAccessResults({
|
|
83
115
|
req
|
|
84
116
|
});
|
|
@@ -88,9 +120,10 @@ export const initReq = async function ({
|
|
|
88
120
|
languageCode,
|
|
89
121
|
locale,
|
|
90
122
|
permissions,
|
|
91
|
-
req
|
|
123
|
+
req,
|
|
124
|
+
user: userWithReadAccess
|
|
92
125
|
};
|
|
93
|
-
}, key).then(result => {
|
|
126
|
+
}, key, overrides).then(result => {
|
|
94
127
|
// CRITICAL: Create a shallow copy of req before returning to prevent
|
|
95
128
|
// mutations from propagating to the cached req object.
|
|
96
129
|
// This ensures parallel operations using the same cache key don't affect each other.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initReq.js","names":["initI18n","headers","getHeaders","createLocalReq","executeAuthStrategies","getAccessResults","getPayload","getRequestLanguage","parseCookies","getRequestLocale","selectiveCache","partialReqCache","reqCache","initReq","canSetHeaders","configPromise","importMap","key","overrides","cookies","partialResult","get","config","payload","cron","languageCode","i18n","context","language","responseHeaders","user","req","reqOverrides","optionsOverrides","host","locale","code","permissions","then","result"],"sources":["../../src/utilities/initReq.ts"],"sourcesContent":["import type { I18n, I18nClient } from '@payloadcms/translations'\nimport type { ImportMap, InitReqResult, PayloadRequest, SanitizedConfig } from 'payload'\n\nimport { initI18n } from '@payloadcms/translations'\nimport { headers as getHeaders } from 'next/headers.js'\nimport {\n createLocalReq,\n executeAuthStrategies,\n getAccessResults,\n getPayload,\n getRequestLanguage,\n parseCookies,\n} from 'payload'\n\nimport { getRequestLocale } from './getRequestLocale.js'\nimport { selectiveCache } from './selectiveCache.js'\n\ntype PartialResult = {\n i18n: I18nClient\n} & Pick<InitReqResult, 'languageCode'> &\n Pick<PayloadRequest, 'payload' | 'responseHeaders' | 'user'>\n\n// Create cache instances for different parts of our application\nconst partialReqCache = selectiveCache<PartialResult>('partialReq')\nconst reqCache = selectiveCache<InitReqResult>('req')\n\n/**\n * Initializes a full request object, including the `req` object and access control.\n * As access control and getting the request locale is dependent on the current URL and\n */\nexport const initReq = async function ({\n canSetHeaders,\n configPromise,\n importMap,\n key,\n overrides,\n}: {\n canSetHeaders?: boolean\n configPromise: Promise<SanitizedConfig> | SanitizedConfig\n importMap: ImportMap\n key: string\n overrides?: Parameters<typeof createLocalReq>[0]\n}): Promise<InitReqResult> {\n const headers = await getHeaders()\n const cookies = parseCookies(headers)\n\n const partialResult = await partialReqCache.get(async () => {\n const config = await configPromise\n const payload = await getPayload({ config, cron: true, importMap })\n const languageCode = getRequestLanguage({\n config,\n cookies,\n headers,\n })\n\n const i18n: I18nClient = await initI18n({\n config: config.i18n,\n context: 'client',\n language: languageCode,\n })\n\n const { responseHeaders, user } = await executeAuthStrategies({\n canSetHeaders,\n headers,\n payload,\n })\n\n return {\n i18n,\n languageCode,\n payload,\n responseHeaders,\n user,\n }\n }, 'global')\n\n return reqCache\n .get(async () => {\n
|
|
1
|
+
{"version":3,"file":"initReq.js","names":["initI18n","headers","getHeaders","createLocalReq","executeAuthStrategies","getAccessResults","getPayload","getRequestLanguage","parseCookies","applyUserReadAccess","getRequestLocale","selectiveCache","partialReqCache","reqCache","initReq","canSetHeaders","configPromise","importMap","key","overrides","cookies","partialResult","get","config","payload","cron","languageCode","i18n","context","language","responseHeaders","user","req","reqOverrides","optionsOverrides","hasOptionsUserOverride","Object","hasOwn","hasReqUserOverride","hasUserOverride","userOverride","host","userWithReadAccess","locale","code","collectionSlug","collection","admin","collections","auth","Error","depth","overrideAccess","showHiddenFields","error","logger","err","permissions","then","result"],"sources":["../../src/utilities/initReq.ts"],"sourcesContent":["import type { I18n, I18nClient } from '@payloadcms/translations'\nimport type { ImportMap, InitReqResult, PayloadRequest, SanitizedConfig } from 'payload'\n\nimport { initI18n } from '@payloadcms/translations'\nimport { headers as getHeaders } from 'next/headers.js'\nimport {\n createLocalReq,\n executeAuthStrategies,\n getAccessResults,\n getPayload,\n getRequestLanguage,\n parseCookies,\n} from 'payload'\nimport { applyUserReadAccess } from 'payload/internal'\n\nimport { getRequestLocale } from './getRequestLocale.js'\nimport { selectiveCache } from './selectiveCache.js'\n\ntype PartialResult = {\n i18n: I18nClient\n} & Pick<InitReqResult, 'languageCode'> &\n Pick<PayloadRequest, 'payload' | 'responseHeaders' | 'user'>\n\n// Create cache instances for different parts of our application\nconst partialReqCache = selectiveCache<PartialResult>('partialReq')\nconst reqCache = selectiveCache<InitReqResult>('req')\n\n/**\n * Initializes a full request object, including the `req` object and access control.\n * As access control and getting the request locale is dependent on the current URL and\n */\nexport const initReq = async function ({\n canSetHeaders,\n configPromise,\n importMap,\n key,\n overrides,\n}: {\n canSetHeaders?: boolean\n configPromise: Promise<SanitizedConfig> | SanitizedConfig\n importMap: ImportMap\n key: string\n overrides?: Parameters<typeof createLocalReq>[0]\n}): Promise<InitReqResult> {\n const headers = await getHeaders()\n const cookies = parseCookies(headers)\n\n const partialResult = await partialReqCache.get(async () => {\n const config = await configPromise\n const payload = await getPayload({ config, cron: true, importMap })\n const languageCode = getRequestLanguage({\n config,\n cookies,\n headers,\n })\n\n const i18n: I18nClient = await initI18n({\n config: config.i18n,\n context: 'client',\n language: languageCode,\n })\n\n const { responseHeaders, user } = await executeAuthStrategies({\n canSetHeaders,\n headers,\n payload,\n })\n\n return {\n i18n,\n languageCode,\n payload,\n responseHeaders,\n user,\n }\n }, 'global')\n\n return reqCache\n .get(\n async () => {\n const { i18n, languageCode, payload, responseHeaders, user } = partialResult\n\n const { req: reqOverrides, ...optionsOverrides } = overrides || {}\n const hasOptionsUserOverride = Object.hasOwn(optionsOverrides, 'user')\n const hasReqUserOverride = Object.hasOwn(reqOverrides ?? {}, 'user')\n const hasUserOverride = hasOptionsUserOverride || hasReqUserOverride\n const userOverride = hasOptionsUserOverride ? optionsOverrides.user : reqOverrides?.user\n\n const req = await createLocalReq(\n {\n req: {\n headers,\n host: headers.get('host'),\n i18n: i18n as I18n,\n responseHeaders,\n user,\n ...(reqOverrides || {}),\n },\n ...(optionsOverrides || {}),\n },\n payload,\n )\n\n if (hasUserOverride && userOverride == null) {\n req.user = null\n }\n\n let userWithReadAccess = req.user\n\n const locale = await getRequestLocale({ req })\n req.locale = locale?.code\n\n if (!hasUserOverride && req.user) {\n try {\n const collectionSlug = req.user.collection ?? payload.config.admin.user\n const collection = payload.collections[collectionSlug]\n\n if (!collection?.config.auth) {\n throw new Error('Authenticated user collection not found')\n }\n\n userWithReadAccess = await applyUserReadAccess({\n collection: collection.config,\n depth: collection.config.auth.depth,\n overrideAccess: false,\n req,\n showHiddenFields: false,\n user: req.user,\n })\n } catch (error) {\n payload.logger.error({ err: error })\n req.user = null\n userWithReadAccess = null\n }\n }\n\n const permissions = await getAccessResults({\n req,\n })\n\n return {\n cookies,\n headers,\n languageCode,\n locale,\n permissions,\n req,\n user: userWithReadAccess,\n }\n },\n key,\n overrides,\n )\n .then((result) => {\n // CRITICAL: Create a shallow copy of req before returning to prevent\n // mutations from propagating to the cached req object.\n // This ensures parallel operations using the same cache key don't affect each other.\n return {\n ...result,\n req: {\n ...result.req,\n ...(result.req?.context\n ? {\n context: { ...result.req.context },\n }\n : {}),\n },\n }\n })\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { getAccessResults } from 'payload';
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
const mocks = vi.hoisted(() => ({
|
|
4
|
+
applyUserReadAccess: vi.fn(async ({
|
|
5
|
+
req,
|
|
6
|
+
user
|
|
7
|
+
}) => {
|
|
8
|
+
mocks.readAccessCalls += 1;
|
|
9
|
+
if (!mocks.readAccessSucceeds) {
|
|
10
|
+
throw new Error('User read access failed');
|
|
11
|
+
}
|
|
12
|
+
const userWithReadAccess = {
|
|
13
|
+
...user,
|
|
14
|
+
requestLocale: req.locale
|
|
15
|
+
};
|
|
16
|
+
delete userWithReadAccess.authorizationRole;
|
|
17
|
+
return userWithReadAccess;
|
|
18
|
+
}),
|
|
19
|
+
authenticationSucceeds: true,
|
|
20
|
+
cacheStores: new Map(),
|
|
21
|
+
executeAuthStrategies: vi.fn(async () => ({
|
|
22
|
+
responseHeaders: new Headers({
|
|
23
|
+
'x-auth': 'authenticated'
|
|
24
|
+
}),
|
|
25
|
+
user: mocks.authenticationSucceeds ? {
|
|
26
|
+
authorizationRole: 'admin',
|
|
27
|
+
collection: 'users',
|
|
28
|
+
id: 'user-id'
|
|
29
|
+
} : null
|
|
30
|
+
})),
|
|
31
|
+
readAccessCalls: 0,
|
|
32
|
+
readAccessSucceeds: true
|
|
33
|
+
}));
|
|
34
|
+
vi.mock('@payloadcms/translations', () => ({
|
|
35
|
+
initI18n: vi.fn(async () => ({
|
|
36
|
+
dateFNSKey: 'en-US',
|
|
37
|
+
fallbackLanguage: 'en',
|
|
38
|
+
language: 'en',
|
|
39
|
+
t: key => key,
|
|
40
|
+
translations: {}
|
|
41
|
+
}))
|
|
42
|
+
}));
|
|
43
|
+
vi.mock('next/headers.js', () => ({
|
|
44
|
+
headers: vi.fn(async () => new Headers())
|
|
45
|
+
}));
|
|
46
|
+
vi.mock('payload', async importOriginal => {
|
|
47
|
+
const payloadModule = await importOriginal();
|
|
48
|
+
return {
|
|
49
|
+
...payloadModule,
|
|
50
|
+
createLocalReq: vi.fn(async (options, payload) => {
|
|
51
|
+
const request = options.req ?? {};
|
|
52
|
+
const url = new URL(options.urlSuffix ?? '/', 'http://localhost');
|
|
53
|
+
const user = options.user ?? request.user ?? null;
|
|
54
|
+
return {
|
|
55
|
+
...request,
|
|
56
|
+
context: options.context ?? request.context ?? {},
|
|
57
|
+
fallbackLocale: options.fallbackLocale,
|
|
58
|
+
headers: request.headers ?? new Headers(),
|
|
59
|
+
locale: options.locale ?? request.locale ?? request.query?.locale ?? 'en',
|
|
60
|
+
pathname: request.pathname ?? url.pathname,
|
|
61
|
+
payload,
|
|
62
|
+
query: request.query ?? {},
|
|
63
|
+
responseHeaders: request.responseHeaders ?? new Headers(),
|
|
64
|
+
url: request.url ?? url.href,
|
|
65
|
+
user: user && !user.collection ? {
|
|
66
|
+
...user,
|
|
67
|
+
collection: payload.config.admin.user
|
|
68
|
+
} : user
|
|
69
|
+
};
|
|
70
|
+
}),
|
|
71
|
+
executeAuthStrategies: mocks.executeAuthStrategies,
|
|
72
|
+
getAccessResults: vi.fn(async ({
|
|
73
|
+
req
|
|
74
|
+
}) => ({
|
|
75
|
+
canAccessAdmin: req.user?.authorizationRole === 'admin'
|
|
76
|
+
})),
|
|
77
|
+
getPayload: vi.fn(async () => ({
|
|
78
|
+
collections: {
|
|
79
|
+
users: {
|
|
80
|
+
config: {
|
|
81
|
+
auth: {
|
|
82
|
+
depth: 0
|
|
83
|
+
},
|
|
84
|
+
slug: 'users'
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
config: {
|
|
89
|
+
admin: {
|
|
90
|
+
user: 'users'
|
|
91
|
+
},
|
|
92
|
+
i18n: {
|
|
93
|
+
fallbackLanguage: 'en',
|
|
94
|
+
supportedLanguages: {
|
|
95
|
+
en: {}
|
|
96
|
+
},
|
|
97
|
+
translations: {}
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
logger: {
|
|
101
|
+
error: vi.fn()
|
|
102
|
+
}
|
|
103
|
+
})),
|
|
104
|
+
getRequestLanguage: vi.fn(() => 'en')
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
vi.mock('payload/internal', () => ({
|
|
108
|
+
applyUserReadAccess: mocks.applyUserReadAccess
|
|
109
|
+
}));
|
|
110
|
+
vi.mock('./getRequestLocale.js', () => ({
|
|
111
|
+
getRequestLocale: vi.fn(async ({
|
|
112
|
+
req
|
|
113
|
+
}) => ({
|
|
114
|
+
code: req.locale ?? 'en'
|
|
115
|
+
}))
|
|
116
|
+
}));
|
|
117
|
+
vi.mock('./selectiveCache.js', () => ({
|
|
118
|
+
selectiveCache: namespace => ({
|
|
119
|
+
get: async (factory, ...args) => {
|
|
120
|
+
let cacheEntry = mocks.cacheStores.get(namespace);
|
|
121
|
+
if (!cacheEntry) {
|
|
122
|
+
cacheEntry = {
|
|
123
|
+
children: new Map()
|
|
124
|
+
};
|
|
125
|
+
mocks.cacheStores.set(namespace, cacheEntry);
|
|
126
|
+
}
|
|
127
|
+
for (const arg of args) {
|
|
128
|
+
let child = cacheEntry.children.get(arg);
|
|
129
|
+
if (!child) {
|
|
130
|
+
child = {
|
|
131
|
+
children: new Map()
|
|
132
|
+
};
|
|
133
|
+
cacheEntry.children.set(arg, child);
|
|
134
|
+
}
|
|
135
|
+
cacheEntry = child;
|
|
136
|
+
}
|
|
137
|
+
if (!('value' in cacheEntry)) {
|
|
138
|
+
cacheEntry.value = await factory();
|
|
139
|
+
}
|
|
140
|
+
return cacheEntry.value;
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
}));
|
|
144
|
+
import { initReq } from './initReq.js';
|
|
145
|
+
describe('initReq', () => {
|
|
146
|
+
beforeEach(() => {
|
|
147
|
+
mocks.authenticationSucceeds = true;
|
|
148
|
+
mocks.applyUserReadAccess.mockClear();
|
|
149
|
+
mocks.cacheStores.clear();
|
|
150
|
+
mocks.executeAuthStrategies.mockClear();
|
|
151
|
+
mocks.readAccessCalls = 0;
|
|
152
|
+
mocks.readAccessSucceeds = true;
|
|
153
|
+
});
|
|
154
|
+
it('should authenticate once and apply user read access for each request shape', async () => {
|
|
155
|
+
const first = await initReq({
|
|
156
|
+
configPromise: {},
|
|
157
|
+
importMap: {},
|
|
158
|
+
key: 'shared-request',
|
|
159
|
+
overrides: {
|
|
160
|
+
locale: 'en'
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
const second = await initReq({
|
|
164
|
+
configPromise: {},
|
|
165
|
+
importMap: {},
|
|
166
|
+
key: 'shared-request',
|
|
167
|
+
overrides: {
|
|
168
|
+
locale: 'fr'
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
expect(mocks.executeAuthStrategies).toHaveBeenCalledOnce();
|
|
172
|
+
expect(mocks.readAccessCalls).toBe(2);
|
|
173
|
+
expect(first.user).toMatchObject({
|
|
174
|
+
requestLocale: 'en'
|
|
175
|
+
});
|
|
176
|
+
expect(second.user).toMatchObject({
|
|
177
|
+
requestLocale: 'fr'
|
|
178
|
+
});
|
|
179
|
+
expect(first.req.user).toHaveProperty('authorizationRole', 'admin');
|
|
180
|
+
expect(second.req.user).toHaveProperty('authorizationRole', 'admin');
|
|
181
|
+
});
|
|
182
|
+
it('should preserve complete fields for subsequent access checks', async () => {
|
|
183
|
+
const result = await initReq({
|
|
184
|
+
configPromise: {},
|
|
185
|
+
importMap: {},
|
|
186
|
+
key: 'subsequent-access'
|
|
187
|
+
});
|
|
188
|
+
const subsequentPermissions = await getAccessResults({
|
|
189
|
+
req: result.req
|
|
190
|
+
});
|
|
191
|
+
expect(result.req.user).toHaveProperty('authorizationRole', 'admin');
|
|
192
|
+
expect(result.user).not.toHaveProperty('authorizationRole');
|
|
193
|
+
expect(subsequentPermissions.canAccessAdmin).toBe(true);
|
|
194
|
+
});
|
|
195
|
+
it('should clear authentication when client user processing fails', async () => {
|
|
196
|
+
mocks.readAccessSucceeds = false;
|
|
197
|
+
const result = await initReq({
|
|
198
|
+
configPromise: {},
|
|
199
|
+
importMap: {},
|
|
200
|
+
key: 'failed-user-read'
|
|
201
|
+
});
|
|
202
|
+
expect(result.user).toBeNull();
|
|
203
|
+
expect(result.req.user).toBeNull();
|
|
204
|
+
expect(result.permissions.canAccessAdmin).toBe(false);
|
|
205
|
+
});
|
|
206
|
+
it('should preserve an explicit user override without applying read access', async () => {
|
|
207
|
+
const user = {
|
|
208
|
+
authorizationRole: 'admin',
|
|
209
|
+
collection: 'users',
|
|
210
|
+
id: 'override-user'
|
|
211
|
+
};
|
|
212
|
+
const result = await initReq({
|
|
213
|
+
configPromise: {},
|
|
214
|
+
importMap: {},
|
|
215
|
+
key: 'user-override',
|
|
216
|
+
overrides: {
|
|
217
|
+
user
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
expect(mocks.applyUserReadAccess).not.toHaveBeenCalled();
|
|
221
|
+
expect(result.user).toBe(user);
|
|
222
|
+
expect(result.req.user).toBe(user);
|
|
223
|
+
expect(result.permissions.canAccessAdmin).toBe(true);
|
|
224
|
+
});
|
|
225
|
+
it('should preserve an explicit top-level null user override', async () => {
|
|
226
|
+
const result = await initReq({
|
|
227
|
+
configPromise: {},
|
|
228
|
+
importMap: {},
|
|
229
|
+
key: 'top-level-null-user-override',
|
|
230
|
+
overrides: {
|
|
231
|
+
user: null
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
expect(mocks.applyUserReadAccess).not.toHaveBeenCalled();
|
|
235
|
+
expect(result.user).toBeNull();
|
|
236
|
+
expect(result.req.user).toBeNull();
|
|
237
|
+
expect(result.permissions.canAccessAdmin).toBe(false);
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
//# sourceMappingURL=initReq.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initReq.spec.js","names":["getAccessResults","beforeEach","describe","expect","it","vi","mocks","hoisted","applyUserReadAccess","fn","req","user","readAccessCalls","readAccessSucceeds","Error","userWithReadAccess","requestLocale","locale","authorizationRole","authenticationSucceeds","cacheStores","Map","executeAuthStrategies","responseHeaders","Headers","collection","id","mock","initI18n","dateFNSKey","fallbackLanguage","language","t","key","translations","headers","importOriginal","payloadModule","createLocalReq","options","payload","request","url","URL","urlSuffix","context","fallbackLocale","query","pathname","href","config","admin","canAccessAdmin","getPayload","collections","users","auth","depth","slug","i18n","supportedLanguages","en","logger","error","getRequestLanguage","getRequestLocale","code","selectiveCache","namespace","get","factory","args","cacheEntry","children","set","arg","child","value","initReq","mockClear","clear","first","configPromise","importMap","overrides","second","toHaveBeenCalledOnce","toBe","toMatchObject","toHaveProperty","result","subsequentPermissions","not","toBeNull","permissions","toHaveBeenCalled"],"sources":["../../src/utilities/initReq.spec.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nimport { getAccessResults } from 'payload'\nimport { beforeEach, describe, expect, it, vi } from 'vitest'\n\ntype CacheEntry = {\n children: Map<unknown, CacheEntry>\n value?: object\n}\n\nconst mocks = vi.hoisted(() => ({\n applyUserReadAccess: vi.fn(\n async ({ req, user }: { req: PayloadRequest; user: NonNullable<PayloadRequest['user']> }) => {\n mocks.readAccessCalls += 1\n\n if (!mocks.readAccessSucceeds) {\n throw new Error('User read access failed')\n }\n\n const userWithReadAccess = {\n ...user,\n requestLocale: req.locale,\n }\n\n delete userWithReadAccess.authorizationRole\n\n return userWithReadAccess\n },\n ),\n authenticationSucceeds: true,\n cacheStores: new Map<string, CacheEntry>(),\n executeAuthStrategies: vi.fn(async () => ({\n responseHeaders: new Headers({ 'x-auth': 'authenticated' }),\n user: mocks.authenticationSucceeds\n ? {\n authorizationRole: 'admin',\n collection: 'users',\n id: 'user-id',\n }\n : null,\n })),\n readAccessCalls: 0,\n readAccessSucceeds: true,\n}))\n\nvi.mock('@payloadcms/translations', () => ({\n initI18n: vi.fn(async () => ({\n dateFNSKey: 'en-US',\n fallbackLanguage: 'en',\n language: 'en',\n t: (key: string) => key,\n translations: {},\n })),\n}))\n\nvi.mock('next/headers.js', () => ({\n headers: vi.fn(async () => new Headers()),\n}))\n\nvi.mock('payload', async (importOriginal) => {\n const payloadModule = await importOriginal<typeof import('payload')>()\n\n return {\n ...payloadModule,\n createLocalReq: vi.fn(async (options, payload) => {\n const request = options.req ?? {}\n const url = new URL(options.urlSuffix ?? '/', 'http://localhost')\n const user = options.user ?? request.user ?? null\n\n return {\n ...request,\n context: options.context ?? request.context ?? {},\n fallbackLocale: options.fallbackLocale,\n headers: request.headers ?? new Headers(),\n locale: options.locale ?? request.locale ?? request.query?.locale ?? 'en',\n pathname: request.pathname ?? url.pathname,\n payload,\n query: request.query ?? {},\n responseHeaders: request.responseHeaders ?? new Headers(),\n url: request.url ?? url.href,\n user: user && !user.collection ? { ...user, collection: payload.config.admin.user } : user,\n }\n }),\n executeAuthStrategies: mocks.executeAuthStrategies,\n getAccessResults: vi.fn(async ({ req }: { req: PayloadRequest }) => ({\n canAccessAdmin: req.user?.authorizationRole === 'admin',\n })),\n getPayload: vi.fn(async () => ({\n collections: {\n users: {\n config: {\n auth: { depth: 0 },\n slug: 'users',\n },\n },\n },\n config: {\n admin: { user: 'users' },\n i18n: {\n fallbackLanguage: 'en',\n supportedLanguages: { en: {} },\n translations: {},\n },\n },\n logger: { error: vi.fn() },\n })),\n getRequestLanguage: vi.fn(() => 'en'),\n }\n})\n\nvi.mock('payload/internal', () => ({\n applyUserReadAccess: mocks.applyUserReadAccess,\n}))\n\nvi.mock('./getRequestLocale.js', () => ({\n getRequestLocale: vi.fn(async ({ req }: { req: PayloadRequest }) => ({\n code: req.locale ?? 'en',\n })),\n}))\n\nvi.mock('./selectiveCache.js', () => ({\n selectiveCache: (namespace: string) => ({\n get: async (factory: () => Promise<object>, ...args: unknown[]) => {\n let cacheEntry = mocks.cacheStores.get(namespace)\n\n if (!cacheEntry) {\n cacheEntry = { children: new Map() }\n mocks.cacheStores.set(namespace, cacheEntry)\n }\n\n for (const arg of args) {\n let child = cacheEntry.children.get(arg)\n\n if (!child) {\n child = { children: new Map() }\n cacheEntry.children.set(arg, child)\n }\n\n cacheEntry = child\n }\n\n if (!('value' in cacheEntry)) {\n cacheEntry.value = await factory()\n }\n\n return cacheEntry.value\n },\n }),\n}))\n\nimport { initReq } from './initReq.js'\n\ndescribe('initReq', () => {\n beforeEach(() => {\n mocks.authenticationSucceeds = true\n mocks.applyUserReadAccess.mockClear()\n mocks.cacheStores.clear()\n mocks.executeAuthStrategies.mockClear()\n mocks.readAccessCalls = 0\n mocks.readAccessSucceeds = true\n })\n\n it('should authenticate once and apply user read access for each request shape', async () => {\n const first = await initReq({\n configPromise: {} as never,\n importMap: {},\n key: 'shared-request',\n overrides: { locale: 'en' },\n })\n const second = await initReq({\n configPromise: {} as never,\n importMap: {},\n key: 'shared-request',\n overrides: { locale: 'fr' },\n })\n\n expect(mocks.executeAuthStrategies).toHaveBeenCalledOnce()\n expect(mocks.readAccessCalls).toBe(2)\n expect(first.user).toMatchObject({ requestLocale: 'en' })\n expect(second.user).toMatchObject({ requestLocale: 'fr' })\n expect(first.req.user).toHaveProperty('authorizationRole', 'admin')\n expect(second.req.user).toHaveProperty('authorizationRole', 'admin')\n })\n\n it('should preserve complete fields for subsequent access checks', async () => {\n const result = await initReq({\n configPromise: {} as never,\n importMap: {},\n key: 'subsequent-access',\n })\n\n const subsequentPermissions = await getAccessResults({ req: result.req })\n\n expect(result.req.user).toHaveProperty('authorizationRole', 'admin')\n expect(result.user).not.toHaveProperty('authorizationRole')\n expect(subsequentPermissions.canAccessAdmin).toBe(true)\n })\n\n it('should clear authentication when client user processing fails', async () => {\n mocks.readAccessSucceeds = false\n\n const result = await initReq({\n configPromise: {} as never,\n importMap: {},\n key: 'failed-user-read',\n })\n\n expect(result.user).toBeNull()\n expect(result.req.user).toBeNull()\n expect(result.permissions.canAccessAdmin).toBe(false)\n })\n\n it('should preserve an explicit user override without applying read access', async () => {\n const user = { authorizationRole: 'admin', collection: 'users', id: 'override-user' }\n\n const result = await initReq({\n configPromise: {} as never,\n importMap: {},\n key: 'user-override',\n overrides: { user },\n })\n\n expect(mocks.applyUserReadAccess).not.toHaveBeenCalled()\n expect(result.user).toBe(user)\n expect(result.req.user).toBe(user)\n expect(result.permissions.canAccessAdmin).toBe(true)\n })\n\n it('should preserve an explicit top-level null user override', async () => {\n const result = await initReq({\n configPromise: {} as never,\n importMap: {},\n key: 'top-level-null-user-override',\n overrides: { user: null },\n })\n\n expect(mocks.applyUserReadAccess).not.toHaveBeenCalled()\n expect(result.user).toBeNull()\n expect(result.req.user).toBeNull()\n expect(result.permissions.canAccessAdmin).toBe(false)\n })\n})\n"],"mappings":"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","ignoreList":[]}
|