chore(eslint): curly [skip-lint] (#7959)
Now enforcing curly brackets on all if statements. Includes auto-fixer. ```ts // ❌ Bad if (foo) foo++; // ✅ Good if (foo) { foo++; } ``` Note: this did not lint the `drizzle` package or any `db-*` packages. This will be done in the future.
This commit is contained in:
@@ -40,6 +40,7 @@ export const rootEslintConfig = [
|
|||||||
{
|
{
|
||||||
ignores: [
|
ignores: [
|
||||||
...defaultESLintIgnores,
|
...defaultESLintIgnores,
|
||||||
|
'packages/eslint-*/**',
|
||||||
'test/live-preview/next-app',
|
'test/live-preview/next-app',
|
||||||
'packages/**/*.spec.ts',
|
'packages/**/*.spec.ts',
|
||||||
'templates/**',
|
'templates/**',
|
||||||
|
|||||||
@@ -167,7 +167,9 @@ async function installAndConfigurePayload(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const logDebug = (message: string) => {
|
const logDebug = (message: string) => {
|
||||||
if (debug) origDebug(message)
|
if (debug) {
|
||||||
|
origDebug(message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fs.existsSync(projectDir)) {
|
if (!fs.existsSync(projectDir)) {
|
||||||
|
|||||||
@@ -4,13 +4,19 @@ import slugify from '@sindresorhus/slugify'
|
|||||||
import type { CliArgs } from '../types.js'
|
import type { CliArgs } from '../types.js'
|
||||||
|
|
||||||
export async function parseProjectName(args: CliArgs): Promise<string> {
|
export async function parseProjectName(args: CliArgs): Promise<string> {
|
||||||
if (args['--name']) return slugify(args['--name'])
|
if (args['--name']) {
|
||||||
if (args._[0]) return slugify(args._[0])
|
return slugify(args['--name'])
|
||||||
|
}
|
||||||
|
if (args._[0]) {
|
||||||
|
return slugify(args._[0])
|
||||||
|
}
|
||||||
|
|
||||||
const projectName = await p.text({
|
const projectName = await p.text({
|
||||||
message: 'Project name?',
|
message: 'Project name?',
|
||||||
validate: (value) => {
|
validate: (value) => {
|
||||||
if (!value) return 'Please enter a project name.'
|
if (!value) {
|
||||||
|
return 'Please enter a project name.'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if (p.isCancel(projectName)) {
|
if (p.isCancel(projectName)) {
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ export async function parseTemplate(
|
|||||||
if (args['--template']) {
|
if (args['--template']) {
|
||||||
const templateName = args['--template']
|
const templateName = args['--template']
|
||||||
const template = validTemplates.find((t) => t.name === templateName)
|
const template = validTemplates.find((t) => t.name === templateName)
|
||||||
if (!template) throw new Error('Invalid template given')
|
if (!template) {
|
||||||
|
throw new Error('Invalid template given')
|
||||||
|
}
|
||||||
return template
|
return template
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,9 @@ export async function selectDb(args: CliArgs, projectName: string): Promise<DbDe
|
|||||||
value: dbChoice.value,
|
value: dbChoice.value,
|
||||||
})),
|
})),
|
||||||
})
|
})
|
||||||
if (p.isCancel(dbType)) process.exit(0)
|
if (p.isCancel(dbType)) {
|
||||||
|
process.exit(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const dbChoice = dbChoiceRecord[dbType]
|
const dbChoice = dbChoiceRecord[dbType]
|
||||||
@@ -73,7 +75,9 @@ export async function selectDb(args: CliArgs, projectName: string): Promise<DbDe
|
|||||||
initialValue: initialDbUri,
|
initialValue: initialDbUri,
|
||||||
message: `Enter ${dbChoice.title.split(' ')[0]} connection string`, // strip beta from title
|
message: `Enter ${dbChoice.title.split(' ')[0]} connection string`, // strip beta from title
|
||||||
})
|
})
|
||||||
if (p.isCancel(dbUri)) process.exit(0)
|
if (p.isCancel(dbUri)) {
|
||||||
|
process.exit(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import { installPackages } from './install-packages.js'
|
|||||||
export async function updatePayloadInProject(
|
export async function updatePayloadInProject(
|
||||||
appDetails: NextAppDetails,
|
appDetails: NextAppDetails,
|
||||||
): Promise<{ message: string; success: boolean }> {
|
): Promise<{ message: string; success: boolean }> {
|
||||||
if (!appDetails.nextConfigPath) return { message: 'No Next.js config found', success: false }
|
if (!appDetails.nextConfigPath) {
|
||||||
|
return { message: 'No Next.js config found', success: false }
|
||||||
|
}
|
||||||
|
|
||||||
const projectDir = path.dirname(appDetails.nextConfigPath)
|
const projectDir = path.dirname(appDetails.nextConfigPath)
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ export async function writeEnvFile(args: {
|
|||||||
.split('\n')
|
.split('\n')
|
||||||
.filter((e) => e)
|
.filter((e) => e)
|
||||||
.map((line) => {
|
.map((line) => {
|
||||||
if (line.startsWith('#') || !line.includes('=')) return line
|
if (line.startsWith('#') || !line.includes('=')) {
|
||||||
|
return line
|
||||||
|
}
|
||||||
|
|
||||||
const split = line.split('=')
|
const split = line.split('=')
|
||||||
const key = split[0]
|
const key = split[0]
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ async function buildEmail(emailConfig?: NodemailerAdapterArgs): Promise<{
|
|||||||
}> {
|
}> {
|
||||||
if (!emailConfig) {
|
if (!emailConfig) {
|
||||||
const transport = await createMockAccount(emailConfig)
|
const transport = await createMockAccount(emailConfig)
|
||||||
if (!transport) throw new InvalidConfiguration('Unable to create Nodemailer test account.')
|
if (!transport) {
|
||||||
|
throw new InvalidConfiguration('Unable to create Nodemailer test account.')
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
defaultFromAddress: 'info@payloadcms.com',
|
defaultFromAddress: 'info@payloadcms.com',
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { deepMerge } from './deepMerge.js'
|
|||||||
const baseRules = {
|
const baseRules = {
|
||||||
// This rule makes no sense when overriding class methods. This is used a lot in richtext-lexical.
|
// This rule makes no sense when overriding class methods. This is used a lot in richtext-lexical.
|
||||||
'class-methods-use-this': 'off',
|
'class-methods-use-this': 'off',
|
||||||
|
curly: ['warn', 'all'],
|
||||||
'arrow-body-style': 0,
|
'arrow-body-style': 0,
|
||||||
'import-x/prefer-default-export': 'off',
|
'import-x/prefer-default-export': 'off',
|
||||||
'no-restricted-exports': ['warn', { restrictDefaultExports: { direct: true } }],
|
'no-restricted-exports': ['warn', { restrictDefaultExports: { direct: true } }],
|
||||||
|
|||||||
@@ -6,8 +6,12 @@ import type { Context } from '../types.js'
|
|||||||
|
|
||||||
export function resetPassword(collection: Collection): any {
|
export function resetPassword(collection: Collection): any {
|
||||||
async function resolver(_, args, context: Context) {
|
async function resolver(_, args, context: Context) {
|
||||||
if (args.locale) context.req.locale = args.locale
|
if (args.locale) {
|
||||||
if (args.fallbackLocale) context.req.fallbackLocale = args.fallbackLocale
|
context.req.locale = args.locale
|
||||||
|
}
|
||||||
|
if (args.fallbackLocale) {
|
||||||
|
context.req.fallbackLocale = args.fallbackLocale
|
||||||
|
}
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
api: 'GraphQL',
|
api: 'GraphQL',
|
||||||
|
|||||||
@@ -6,8 +6,12 @@ import type { Context } from '../types.js'
|
|||||||
|
|
||||||
export function verifyEmail(collection: Collection) {
|
export function verifyEmail(collection: Collection) {
|
||||||
async function resolver(_, args, context: Context) {
|
async function resolver(_, args, context: Context) {
|
||||||
if (args.locale) context.req.locale = args.locale
|
if (args.locale) {
|
||||||
if (args.fallbackLocale) context.req.fallbackLocale = args.fallbackLocale
|
context.req.locale = args.locale
|
||||||
|
}
|
||||||
|
if (args.fallbackLocale) {
|
||||||
|
context.req.fallbackLocale = args.fallbackLocale
|
||||||
|
}
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
api: 'GraphQL',
|
api: 'GraphQL',
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ export function getDeleteResolver<TSlug extends CollectionSlug>(
|
|||||||
req = isolateObjectProperty(req, 'fallbackLocale')
|
req = isolateObjectProperty(req, 'fallbackLocale')
|
||||||
req.locale = args.locale || locale
|
req.locale = args.locale || locale
|
||||||
req.fallbackLocale = args.fallbackLocale || fallbackLocale
|
req.fallbackLocale = args.fallbackLocale || fallbackLocale
|
||||||
if (!req.query) req.query = {}
|
if (!req.query) {
|
||||||
|
req.query = {}
|
||||||
|
}
|
||||||
|
|
||||||
const draft: boolean =
|
const draft: boolean =
|
||||||
args.draft ?? req.query?.draft === 'false'
|
args.draft ?? req.query?.draft === 'false'
|
||||||
@@ -36,7 +38,9 @@ export function getDeleteResolver<TSlug extends CollectionSlug>(
|
|||||||
: req.query?.draft === 'true'
|
: req.query?.draft === 'true'
|
||||||
? true
|
? true
|
||||||
: undefined
|
: undefined
|
||||||
if (typeof draft === 'boolean') req.query.draft = String(draft)
|
if (typeof draft === 'boolean') {
|
||||||
|
req.query.draft = String(draft)
|
||||||
|
}
|
||||||
|
|
||||||
context.req = req
|
context.req = req
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ export function findResolver(collection: Collection): Resolver {
|
|||||||
req = isolateObjectProperty(req, ['locale', 'fallbackLocale', 'transactionID'])
|
req = isolateObjectProperty(req, ['locale', 'fallbackLocale', 'transactionID'])
|
||||||
req.locale = args.locale || locale
|
req.locale = args.locale || locale
|
||||||
req.fallbackLocale = args.fallbackLocale || fallbackLocale
|
req.fallbackLocale = args.fallbackLocale || fallbackLocale
|
||||||
if (!req.query) req.query = {}
|
if (!req.query) {
|
||||||
|
req.query = {}
|
||||||
|
}
|
||||||
|
|
||||||
const draft: boolean =
|
const draft: boolean =
|
||||||
args.draft ?? req.query?.draft === 'false'
|
args.draft ?? req.query?.draft === 'false'
|
||||||
@@ -39,7 +41,9 @@ export function findResolver(collection: Collection): Resolver {
|
|||||||
: req.query?.draft === 'true'
|
: req.query?.draft === 'true'
|
||||||
? true
|
? true
|
||||||
: undefined
|
: undefined
|
||||||
if (typeof draft === 'boolean') req.query.draft = String(draft)
|
if (typeof draft === 'boolean') {
|
||||||
|
req.query.draft = String(draft)
|
||||||
|
}
|
||||||
|
|
||||||
context.req = req
|
context.req = req
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ export function findByIDResolver<TSlug extends CollectionSlug>(
|
|||||||
req = isolateObjectProperty(req, 'fallbackLocale')
|
req = isolateObjectProperty(req, 'fallbackLocale')
|
||||||
req.locale = args.locale || locale
|
req.locale = args.locale || locale
|
||||||
req.fallbackLocale = args.fallbackLocale || fallbackLocale
|
req.fallbackLocale = args.fallbackLocale || fallbackLocale
|
||||||
if (!req.query) req.query = {}
|
if (!req.query) {
|
||||||
|
req.query = {}
|
||||||
|
}
|
||||||
|
|
||||||
const draft: boolean =
|
const draft: boolean =
|
||||||
args.draft ?? req.query?.draft === 'false'
|
args.draft ?? req.query?.draft === 'false'
|
||||||
@@ -36,7 +38,9 @@ export function findByIDResolver<TSlug extends CollectionSlug>(
|
|||||||
: req.query?.draft === 'true'
|
: req.query?.draft === 'true'
|
||||||
? true
|
? true
|
||||||
: undefined
|
: undefined
|
||||||
if (typeof draft === 'boolean') req.query.draft = String(draft)
|
if (typeof draft === 'boolean') {
|
||||||
|
req.query.draft = String(draft)
|
||||||
|
}
|
||||||
|
|
||||||
context.req = req
|
context.req = req
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ export function findVersionsResolver(collection: Collection): Resolver {
|
|||||||
req = isolateObjectProperty(req, 'fallbackLocale')
|
req = isolateObjectProperty(req, 'fallbackLocale')
|
||||||
req.locale = args.locale || locale
|
req.locale = args.locale || locale
|
||||||
req.fallbackLocale = args.fallbackLocale || fallbackLocale
|
req.fallbackLocale = args.fallbackLocale || fallbackLocale
|
||||||
if (!req.query) req.query = {}
|
if (!req.query) {
|
||||||
|
req.query = {}
|
||||||
|
}
|
||||||
|
|
||||||
const draft: boolean =
|
const draft: boolean =
|
||||||
args.draft ?? req.query?.draft === 'false'
|
args.draft ?? req.query?.draft === 'false'
|
||||||
@@ -37,7 +39,9 @@ export function findVersionsResolver(collection: Collection): Resolver {
|
|||||||
: req.query?.draft === 'true'
|
: req.query?.draft === 'true'
|
||||||
? true
|
? true
|
||||||
: undefined
|
: undefined
|
||||||
if (typeof draft === 'boolean') req.query.draft = String(draft)
|
if (typeof draft === 'boolean') {
|
||||||
|
req.query.draft = String(draft)
|
||||||
|
}
|
||||||
|
|
||||||
context.req = req
|
context.req = req
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ export function updateResolver<TSlug extends CollectionSlug>(
|
|||||||
req = isolateObjectProperty(req, 'fallbackLocale')
|
req = isolateObjectProperty(req, 'fallbackLocale')
|
||||||
req.locale = args.locale || locale
|
req.locale = args.locale || locale
|
||||||
req.fallbackLocale = args.fallbackLocale || fallbackLocale
|
req.fallbackLocale = args.fallbackLocale || fallbackLocale
|
||||||
if (!req.query) req.query = {}
|
if (!req.query) {
|
||||||
|
req.query = {}
|
||||||
|
}
|
||||||
|
|
||||||
const draft: boolean =
|
const draft: boolean =
|
||||||
args.draft ?? req.query?.draft === 'false'
|
args.draft ?? req.query?.draft === 'false'
|
||||||
@@ -38,7 +40,9 @@ export function updateResolver<TSlug extends CollectionSlug>(
|
|||||||
: req.query?.draft === 'true'
|
: req.query?.draft === 'true'
|
||||||
? true
|
? true
|
||||||
: undefined
|
: undefined
|
||||||
if (typeof draft === 'boolean') req.query.draft = String(draft)
|
if (typeof draft === 'boolean') {
|
||||||
|
req.query.draft = String(draft)
|
||||||
|
}
|
||||||
|
|
||||||
context.req = req
|
context.req = req
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,12 @@ import type { Context } from '../types.js'
|
|||||||
|
|
||||||
export function findOne(globalConfig: SanitizedGlobalConfig): Document {
|
export function findOne(globalConfig: SanitizedGlobalConfig): Document {
|
||||||
return async function resolver(_, args, context: Context) {
|
return async function resolver(_, args, context: Context) {
|
||||||
if (args.locale) context.req.locale = args.locale
|
if (args.locale) {
|
||||||
if (args.fallbackLocale) context.req.fallbackLocale = args.fallbackLocale
|
context.req.locale = args.locale
|
||||||
|
}
|
||||||
|
if (args.fallbackLocale) {
|
||||||
|
context.req.fallbackLocale = args.fallbackLocale
|
||||||
|
}
|
||||||
|
|
||||||
const { slug } = globalConfig
|
const { slug } = globalConfig
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,12 @@ export type Resolver = (
|
|||||||
|
|
||||||
export function findVersionByID(globalConfig: SanitizedGlobalConfig): Resolver {
|
export function findVersionByID(globalConfig: SanitizedGlobalConfig): Resolver {
|
||||||
return async function resolver(_, args, context: Context) {
|
return async function resolver(_, args, context: Context) {
|
||||||
if (args.locale) context.req.locale = args.locale
|
if (args.locale) {
|
||||||
if (args.fallbackLocale) context.req.fallbackLocale = args.fallbackLocale
|
context.req.locale = args.locale
|
||||||
|
}
|
||||||
|
if (args.fallbackLocale) {
|
||||||
|
context.req.fallbackLocale = args.fallbackLocale
|
||||||
|
}
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
id: args.id,
|
id: args.id,
|
||||||
|
|||||||
@@ -22,8 +22,12 @@ export function update<TSlug extends GlobalSlug>(
|
|||||||
globalConfig: SanitizedGlobalConfig,
|
globalConfig: SanitizedGlobalConfig,
|
||||||
): Resolver<TSlug> {
|
): Resolver<TSlug> {
|
||||||
return async function resolver(_, args, context: Context) {
|
return async function resolver(_, args, context: Context) {
|
||||||
if (args.locale) context.req.locale = args.locale
|
if (args.locale) {
|
||||||
if (args.fallbackLocale) context.req.fallbackLocale = args.fallbackLocale
|
context.req.locale = args.locale
|
||||||
|
}
|
||||||
|
if (args.fallbackLocale) {
|
||||||
|
context.req.fallbackLocale = args.fallbackLocale
|
||||||
|
}
|
||||||
|
|
||||||
const { slug } = globalConfig
|
const { slug } = globalConfig
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,9 @@ export function buildMutationInputType({
|
|||||||
parentName: fullName,
|
parentName: fullName,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!type) return inputObjectTypeConfig
|
if (!type) {
|
||||||
|
return inputObjectTypeConfig
|
||||||
|
}
|
||||||
|
|
||||||
type = new GraphQLList(withNullableType(field, type, forceNullable))
|
type = new GraphQLList(withNullableType(field, type, forceNullable))
|
||||||
return {
|
return {
|
||||||
@@ -120,7 +122,9 @@ export function buildMutationInputType({
|
|||||||
collapsible: (inputObjectTypeConfig: InputObjectTypeConfig, field: CollapsibleField) =>
|
collapsible: (inputObjectTypeConfig: InputObjectTypeConfig, field: CollapsibleField) =>
|
||||||
field.fields.reduce((acc, subField: CollapsibleField) => {
|
field.fields.reduce((acc, subField: CollapsibleField) => {
|
||||||
const addSubField = fieldToSchemaMap[subField.type]
|
const addSubField = fieldToSchemaMap[subField.type]
|
||||||
if (addSubField) return addSubField(acc, subField)
|
if (addSubField) {
|
||||||
|
return addSubField(acc, subField)
|
||||||
|
}
|
||||||
return acc
|
return acc
|
||||||
}, inputObjectTypeConfig),
|
}, inputObjectTypeConfig),
|
||||||
date: (inputObjectTypeConfig: InputObjectTypeConfig, field: DateField) => ({
|
date: (inputObjectTypeConfig: InputObjectTypeConfig, field: DateField) => ({
|
||||||
@@ -142,9 +146,13 @@ export function buildMutationInputType({
|
|||||||
parentName: fullName,
|
parentName: fullName,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!type) return inputObjectTypeConfig
|
if (!type) {
|
||||||
|
return inputObjectTypeConfig
|
||||||
|
}
|
||||||
|
|
||||||
if (requiresAtLeastOneField) type = new GraphQLNonNull(type)
|
if (requiresAtLeastOneField) {
|
||||||
|
type = new GraphQLNonNull(type)
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...inputObjectTypeConfig,
|
...inputObjectTypeConfig,
|
||||||
[field.name]: { type },
|
[field.name]: { type },
|
||||||
@@ -227,7 +235,9 @@ export function buildMutationInputType({
|
|||||||
row: (inputObjectTypeConfig: InputObjectTypeConfig, field: RowField) =>
|
row: (inputObjectTypeConfig: InputObjectTypeConfig, field: RowField) =>
|
||||||
field.fields.reduce((acc, subField: Field) => {
|
field.fields.reduce((acc, subField: Field) => {
|
||||||
const addSubField = fieldToSchemaMap[subField.type]
|
const addSubField = fieldToSchemaMap[subField.type]
|
||||||
if (addSubField) return addSubField(acc, subField)
|
if (addSubField) {
|
||||||
|
return addSubField(acc, subField)
|
||||||
|
}
|
||||||
return acc
|
return acc
|
||||||
}, inputObjectTypeConfig),
|
}, inputObjectTypeConfig),
|
||||||
select: (inputObjectTypeConfig: InputObjectTypeConfig, field: SelectField) => {
|
select: (inputObjectTypeConfig: InputObjectTypeConfig, field: SelectField) => {
|
||||||
@@ -274,9 +284,13 @@ export function buildMutationInputType({
|
|||||||
parentName: fullName,
|
parentName: fullName,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!type) return acc
|
if (!type) {
|
||||||
|
return acc
|
||||||
|
}
|
||||||
|
|
||||||
if (requiresAtLeastOneField) type = new GraphQLNonNull(type)
|
if (requiresAtLeastOneField) {
|
||||||
|
type = new GraphQLNonNull(type)
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...acc,
|
...acc,
|
||||||
[tab.name]: { type },
|
[tab.name]: { type },
|
||||||
@@ -287,7 +301,9 @@ export function buildMutationInputType({
|
|||||||
...acc,
|
...acc,
|
||||||
...tab.fields.reduce((subFieldSchema, subField) => {
|
...tab.fields.reduce((subFieldSchema, subField) => {
|
||||||
const addSubField = fieldToSchemaMap[subField.type]
|
const addSubField = fieldToSchemaMap[subField.type]
|
||||||
if (addSubField) return addSubField(subFieldSchema, subField)
|
if (addSubField) {
|
||||||
|
return addSubField(subFieldSchema, subField)
|
||||||
|
}
|
||||||
return subFieldSchema
|
return subFieldSchema
|
||||||
}, acc),
|
}, acc),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -171,7 +171,9 @@ export function buildObjectType({
|
|||||||
collapsible: (objectTypeConfig: ObjectTypeConfig, field: CollapsibleField) =>
|
collapsible: (objectTypeConfig: ObjectTypeConfig, field: CollapsibleField) =>
|
||||||
field.fields.reduce((objectTypeConfigWithCollapsibleFields, subField) => {
|
field.fields.reduce((objectTypeConfigWithCollapsibleFields, subField) => {
|
||||||
const addSubField = fieldToSchemaMap[subField.type]
|
const addSubField = fieldToSchemaMap[subField.type]
|
||||||
if (addSubField) return addSubField(objectTypeConfigWithCollapsibleFields, subField)
|
if (addSubField) {
|
||||||
|
return addSubField(objectTypeConfigWithCollapsibleFields, subField)
|
||||||
|
}
|
||||||
return objectTypeConfigWithCollapsibleFields
|
return objectTypeConfigWithCollapsibleFields
|
||||||
}, objectTypeConfig),
|
}, objectTypeConfig),
|
||||||
date: (objectTypeConfig: ObjectTypeConfig, field: DateField) => ({
|
date: (objectTypeConfig: ObjectTypeConfig, field: DateField) => ({
|
||||||
@@ -459,7 +461,9 @@ export function buildObjectType({
|
|||||||
},
|
},
|
||||||
async resolve(parent, args, context: Context) {
|
async resolve(parent, args, context: Context) {
|
||||||
let depth = config.defaultDepth
|
let depth = config.defaultDepth
|
||||||
if (typeof args.depth !== 'undefined') depth = args.depth
|
if (typeof args.depth !== 'undefined') {
|
||||||
|
depth = args.depth
|
||||||
|
}
|
||||||
if (!field?.editor) {
|
if (!field?.editor) {
|
||||||
throw new MissingEditorProp(field) // while we allow disabling editor functionality, you should not have any richText fields defined if you do not have an editor
|
throw new MissingEditorProp(field) // while we allow disabling editor functionality, you should not have any richText fields defined if you do not have an editor
|
||||||
}
|
}
|
||||||
@@ -506,7 +510,9 @@ export function buildObjectType({
|
|||||||
row: (objectTypeConfig: ObjectTypeConfig, field: RowField) =>
|
row: (objectTypeConfig: ObjectTypeConfig, field: RowField) =>
|
||||||
field.fields.reduce((objectTypeConfigWithRowFields, subField) => {
|
field.fields.reduce((objectTypeConfigWithRowFields, subField) => {
|
||||||
const addSubField = fieldToSchemaMap[subField.type]
|
const addSubField = fieldToSchemaMap[subField.type]
|
||||||
if (addSubField) return addSubField(objectTypeConfigWithRowFields, subField)
|
if (addSubField) {
|
||||||
|
return addSubField(objectTypeConfigWithRowFields, subField)
|
||||||
|
}
|
||||||
return objectTypeConfigWithRowFields
|
return objectTypeConfigWithRowFields
|
||||||
}, objectTypeConfig),
|
}, objectTypeConfig),
|
||||||
select: (objectTypeConfig: ObjectTypeConfig, field: SelectField) => {
|
select: (objectTypeConfig: ObjectTypeConfig, field: SelectField) => {
|
||||||
@@ -560,7 +566,9 @@ export function buildObjectType({
|
|||||||
...tabSchema,
|
...tabSchema,
|
||||||
...tab.fields.reduce((subFieldSchema, subField) => {
|
...tab.fields.reduce((subFieldSchema, subField) => {
|
||||||
const addSubField = fieldToSchemaMap[subField.type]
|
const addSubField = fieldToSchemaMap[subField.type]
|
||||||
if (addSubField) return addSubField(subFieldSchema, subField)
|
if (addSubField) {
|
||||||
|
return addSubField(subFieldSchema, subField)
|
||||||
|
}
|
||||||
return subFieldSchema
|
return subFieldSchema
|
||||||
}, tabSchema),
|
}, tabSchema),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,9 @@ export function buildPolicyType(args: BuildPolicyType): GraphQLObjectType {
|
|||||||
|
|
||||||
let operations = []
|
let operations = []
|
||||||
|
|
||||||
if (graphQL === false) return null
|
if (graphQL === false) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
if (type === 'collection') {
|
if (type === 'collection') {
|
||||||
operations = ['create', 'read', 'update', 'delete']
|
operations = ['create', 'read', 'update', 'delete']
|
||||||
|
|||||||
@@ -57,7 +57,9 @@ export function initCollections({ config, graphqlResult }: InitCollectionsGraphQ
|
|||||||
config: { fields, graphQL = {} as SanitizedCollectionConfig['graphQL'], versions },
|
config: { fields, graphQL = {} as SanitizedCollectionConfig['graphQL'], versions },
|
||||||
} = collection
|
} = collection
|
||||||
|
|
||||||
if (!graphQL) return
|
if (!graphQL) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let singularName
|
let singularName
|
||||||
let pluralName
|
let pluralName
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ export function initGlobals({ config, graphqlResult }: InitGlobalsGraphQLArgs):
|
|||||||
|
|
||||||
const forceNullableObjectType = Boolean(versions?.drafts)
|
const forceNullableObjectType = Boolean(versions?.drafts)
|
||||||
|
|
||||||
if (!graphqlResult.globals.graphQL) graphqlResult.globals.graphQL = {}
|
if (!graphqlResult.globals.graphQL) {
|
||||||
|
graphqlResult.globals.graphQL = {}
|
||||||
|
}
|
||||||
|
|
||||||
const updateMutationInputType = buildMutationInputType({
|
const updateMutationInputType = buildMutationInputType({
|
||||||
name: formattedName,
|
name: formattedName,
|
||||||
|
|||||||
@@ -263,7 +263,9 @@ export const withOperators = (
|
|||||||
field: FieldAffectingData,
|
field: FieldAffectingData,
|
||||||
parentName: string,
|
parentName: string,
|
||||||
): GraphQLInputObjectType => {
|
): GraphQLInputObjectType => {
|
||||||
if (!defaults?.[field.type]) throw new Error(`Error: ${field.type} has no defaults configured.`)
|
if (!defaults?.[field.type]) {
|
||||||
|
throw new Error(`Error: ${field.type} has no defaults configured.`)
|
||||||
|
}
|
||||||
|
|
||||||
const name = `${combineParentName(parentName, field.name)}_operator`
|
const name = `${combineParentName(parentName, field.name)}_operator`
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,10 @@ const fs = require('fs')
|
|||||||
const ReactCompilerConfig = {
|
const ReactCompilerConfig = {
|
||||||
sources: (filename) => {
|
sources: (filename) => {
|
||||||
const isInNodeModules = filename.includes('node_modules')
|
const isInNodeModules = filename.includes('node_modules')
|
||||||
if (isInNodeModules || ( !filename.endsWith('.tsx') && !filename.endsWith('.jsx') && !filename.endsWith('.js'))) {
|
if (
|
||||||
|
isInNodeModules ||
|
||||||
|
(!filename.endsWith('.tsx') && !filename.endsWith('.jsx') && !filename.endsWith('.js'))
|
||||||
|
) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,9 +40,13 @@ export const DocumentTabs: React.FC<{
|
|||||||
// if no `order`, append the view to the end
|
// if no `order`, append the view to the end
|
||||||
// TODO: open `order` to the config and merge `defaultViews` with `customViews`
|
// TODO: open `order` to the config and merge `defaultViews` with `customViews`
|
||||||
?.sort(([, a], [, b]) => {
|
?.sort(([, a], [, b]) => {
|
||||||
if (a.order === undefined && b.order === undefined) return 0
|
if (a.order === undefined && b.order === undefined) {
|
||||||
else if (a.order === undefined) return 1
|
return 0
|
||||||
else if (b.order === undefined) return -1
|
} else if (a.order === undefined) {
|
||||||
|
return 1
|
||||||
|
} else if (b.order === undefined) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
return a.order - b.order
|
return a.order - b.order
|
||||||
})
|
})
|
||||||
?.map(([name, tab], index) => {
|
?.map(([name, tab], index) => {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export const VersionsPill: React.FC = () => {
|
|||||||
// documents that are version enabled _always_ have at least one version
|
// documents that are version enabled _always_ have at least one version
|
||||||
const hasVersions = versions?.totalDocs > 0
|
const hasVersions = versions?.totalDocs > 0
|
||||||
|
|
||||||
if (hasVersions)
|
if (hasVersions) {
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
className={[`${baseClass}__count`, hasVersions ? `${baseClass}__count--has-count` : '']
|
className={[`${baseClass}__count`, hasVersions ? `${baseClass}__count--has-count` : '']
|
||||||
@@ -22,4 +22,5 @@ export const VersionsPill: React.FC = () => {
|
|||||||
{versions.totalDocs.toString()}
|
{versions.totalDocs.toString()}
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,11 @@ const Component: React.FC<{
|
|||||||
// }, [modalState, isActive, onCancel])
|
// }, [modalState, isActive, onCancel])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isActive) openModal(modalSlug)
|
if (isActive) {
|
||||||
else closeModal(modalSlug)
|
openModal(modalSlug)
|
||||||
|
} else {
|
||||||
|
closeModal(modalSlug)
|
||||||
|
}
|
||||||
}, [isActive, openModal, closeModal])
|
}, [isActive, openModal, closeModal])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -145,7 +145,9 @@ export const usePreventLeave = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (hasAccepted && cancelledURL.current) {
|
if (hasAccepted && cancelledURL.current) {
|
||||||
if (onAccept) onAccept()
|
if (onAccept) {
|
||||||
|
onAccept()
|
||||||
|
}
|
||||||
router.push(cancelledURL.current)
|
router.push(cancelledURL.current)
|
||||||
}
|
}
|
||||||
}, [hasAccepted, onAccept, router])
|
}, [hasAccepted, onAccept, router])
|
||||||
|
|||||||
@@ -55,7 +55,9 @@ export const tempFileHandler: Handler = (options, fieldname, filename) => {
|
|||||||
complete: () => {
|
complete: () => {
|
||||||
completed = true
|
completed = true
|
||||||
debugLog(options, `Upload ${fieldname}->${filename} completed, bytes:${fileSize}.`)
|
debugLog(options, `Upload ${fieldname}->${filename} completed, bytes:${fileSize}.`)
|
||||||
if (writeStream instanceof WriteStream) writeStream.end()
|
if (writeStream instanceof WriteStream) {
|
||||||
|
writeStream.end()
|
||||||
|
}
|
||||||
// Return empty buff since data was uploaded into a temp file.
|
// Return empty buff since data was uploaded into a temp file.
|
||||||
return Buffer.concat([])
|
return Buffer.concat([])
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { isSafeFromPollution } from './utilities.js'
|
import { isSafeFromPollution } from './utilities.js'
|
||||||
|
|
||||||
export const processNested = function (data) {
|
export const processNested = function (data) {
|
||||||
if (!data || data.length < 1) return Object.create(null)
|
if (!data || data.length < 1) {
|
||||||
|
return Object.create(null)
|
||||||
|
}
|
||||||
|
|
||||||
const d = Object.create(null),
|
const d = Object.create(null),
|
||||||
keys = Object.keys(data)
|
keys = Object.keys(data)
|
||||||
@@ -23,7 +25,9 @@ export const processNested = function (data) {
|
|||||||
if (index >= keyParts.length - 1) {
|
if (index >= keyParts.length - 1) {
|
||||||
current[k] = value
|
current[k] = value
|
||||||
} else {
|
} else {
|
||||||
if (!current[k]) current[k] = !keyParts[index + 1] ? [] : Object.create(null)
|
if (!current[k]) {
|
||||||
|
current[k] = !keyParts[index + 1] ? [] : Object.create(null)
|
||||||
|
}
|
||||||
current = current[k]
|
current = current[k]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ export const createUploadTimer: CreateUploadTimer = (timeout = 0, callback = ()
|
|||||||
|
|
||||||
const set = () => {
|
const set = () => {
|
||||||
// Do not start a timer if zero timeout or it hasn't been set.
|
// Do not start a timer if zero timeout or it hasn't been set.
|
||||||
if (!timeout) return false
|
if (!timeout) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
clear()
|
clear()
|
||||||
timer = setTimeout(callback, timeout)
|
timer = setTimeout(callback, timeout)
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ let tempCounter = 0
|
|||||||
*/
|
*/
|
||||||
export const debugLog = (options: FetchAPIFileUploadOptions, msg: string) => {
|
export const debugLog = (options: FetchAPIFileUploadOptions, msg: string) => {
|
||||||
const opts = options || {}
|
const opts = options || {}
|
||||||
if (!opts.debug) return false
|
if (!opts.debug) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
console.log(`Next-file-upload: ${msg}`) // eslint-disable-line
|
console.log(`Next-file-upload: ${msg}`) // eslint-disable-line
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -84,7 +86,9 @@ export const isSafeFromPollution: IsSafeFromPollution = (base, key) => {
|
|||||||
type BuildFields = (instance: any, field: string, value: any) => any
|
type BuildFields = (instance: any, field: string, value: any) => any
|
||||||
export const buildFields: BuildFields = (instance, field, value) => {
|
export const buildFields: BuildFields = (instance, field, value) => {
|
||||||
// Do nothing if value is not set.
|
// Do nothing if value is not set.
|
||||||
if (value === null || value === undefined) return instance
|
if (value === null || value === undefined) {
|
||||||
|
return instance
|
||||||
|
}
|
||||||
instance = instance || Object.create(null)
|
instance = instance || Object.create(null)
|
||||||
|
|
||||||
if (!isSafeFromPollution(instance, field)) {
|
if (!isSafeFromPollution(instance, field)) {
|
||||||
@@ -110,11 +114,15 @@ export const buildFields: BuildFields = (instance, field, value) => {
|
|||||||
*/
|
*/
|
||||||
type CheckAndMakeDir = (fileUploadOptions: FetchAPIFileUploadOptions, filePath: string) => boolean
|
type CheckAndMakeDir = (fileUploadOptions: FetchAPIFileUploadOptions, filePath: string) => boolean
|
||||||
export const checkAndMakeDir: CheckAndMakeDir = (fileUploadOptions, filePath) => {
|
export const checkAndMakeDir: CheckAndMakeDir = (fileUploadOptions, filePath) => {
|
||||||
if (!fileUploadOptions.createParentPath) return false
|
if (!fileUploadOptions.createParentPath) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
// Check whether folder for the file exists.
|
// Check whether folder for the file exists.
|
||||||
const parentPath = path.dirname(filePath)
|
const parentPath = path.dirname(filePath)
|
||||||
// Create folder if it doesn't exist.
|
// Create folder if it doesn't exist.
|
||||||
if (!fs.existsSync(parentPath)) fs.mkdirSync(parentPath, { recursive: true })
|
if (!fs.existsSync(parentPath)) {
|
||||||
|
fs.mkdirSync(parentPath, { recursive: true })
|
||||||
|
}
|
||||||
// Checks folder again and return a results.
|
// Checks folder again and return a results.
|
||||||
return fs.existsSync(parentPath)
|
return fs.existsSync(parentPath)
|
||||||
}
|
}
|
||||||
@@ -134,7 +142,9 @@ const copyFile: CopyFile = (src, dst, callback) => {
|
|||||||
// cbCalled flag and runCb helps to run cb only once.
|
// cbCalled flag and runCb helps to run cb only once.
|
||||||
let cbCalled = false
|
let cbCalled = false
|
||||||
const runCb = (err?: Error) => {
|
const runCb = (err?: Error) => {
|
||||||
if (cbCalled) return
|
if (cbCalled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
cbCalled = true
|
cbCalled = true
|
||||||
callback(err)
|
callback(err)
|
||||||
}
|
}
|
||||||
@@ -247,14 +257,18 @@ export const parseFileNameExtension: ParseFileNameExtension = (preserveExtension
|
|||||||
name: fileName,
|
name: fileName,
|
||||||
extension: '',
|
extension: '',
|
||||||
}
|
}
|
||||||
if (!preserveExtension) return defaultResult
|
if (!preserveExtension) {
|
||||||
|
return defaultResult
|
||||||
|
}
|
||||||
|
|
||||||
// Define maximum extension length
|
// Define maximum extension length
|
||||||
const maxExtLength =
|
const maxExtLength =
|
||||||
typeof preserveExtension === 'boolean' ? MAX_EXTENSION_LENGTH : preserveExtension
|
typeof preserveExtension === 'boolean' ? MAX_EXTENSION_LENGTH : preserveExtension
|
||||||
|
|
||||||
const nameParts = fileName.split('.')
|
const nameParts = fileName.split('.')
|
||||||
if (nameParts.length < 2) return defaultResult
|
if (nameParts.length < 2) {
|
||||||
|
return defaultResult
|
||||||
|
}
|
||||||
|
|
||||||
let extension = nameParts.pop()
|
let extension = nameParts.pop()
|
||||||
if (extension.length > maxExtLength && maxExtLength > 0) {
|
if (extension.length > maxExtLength && maxExtLength > 0) {
|
||||||
@@ -274,13 +288,17 @@ export const parseFileNameExtension: ParseFileNameExtension = (preserveExtension
|
|||||||
type ParseFileName = (opts: FetchAPIFileUploadOptions, fileName: string) => string
|
type ParseFileName = (opts: FetchAPIFileUploadOptions, fileName: string) => string
|
||||||
export const parseFileName: ParseFileName = (opts, fileName) => {
|
export const parseFileName: ParseFileName = (opts, fileName) => {
|
||||||
// Check fileName argument
|
// Check fileName argument
|
||||||
if (!fileName || typeof fileName !== 'string') return getTempFilename()
|
if (!fileName || typeof fileName !== 'string') {
|
||||||
|
return getTempFilename()
|
||||||
|
}
|
||||||
// Cut off file name if it's length more then 255.
|
// Cut off file name if it's length more then 255.
|
||||||
let parsedName = fileName.length <= 255 ? fileName : fileName.substr(0, 255)
|
let parsedName = fileName.length <= 255 ? fileName : fileName.substr(0, 255)
|
||||||
// Decode file name if uriDecodeFileNames option set true.
|
// Decode file name if uriDecodeFileNames option set true.
|
||||||
parsedName = uriDecodeFileName(opts, parsedName)
|
parsedName = uriDecodeFileName(opts, parsedName)
|
||||||
// Stop parsing file name if safeFileNames options hasn't been set.
|
// Stop parsing file name if safeFileNames options hasn't been set.
|
||||||
if (!opts.safeFileNames) return parsedName
|
if (!opts.safeFileNames) {
|
||||||
|
return parsedName
|
||||||
|
}
|
||||||
// Set regular expression for the file name.
|
// Set regular expression for the file name.
|
||||||
const nameRegex =
|
const nameRegex =
|
||||||
typeof opts.safeFileNames === 'object' && opts.safeFileNames instanceof RegExp
|
typeof opts.safeFileNames === 'object' && opts.safeFileNames instanceof RegExp
|
||||||
@@ -288,8 +306,9 @@ export const parseFileName: ParseFileName = (opts, fileName) => {
|
|||||||
: SAFE_FILE_NAME_REGEX
|
: SAFE_FILE_NAME_REGEX
|
||||||
// Parse file name extension.
|
// Parse file name extension.
|
||||||
const parsedFileName = parseFileNameExtension(opts.preserveExtension, parsedName)
|
const parsedFileName = parseFileNameExtension(opts.preserveExtension, parsedName)
|
||||||
if (parsedFileName.extension.length)
|
if (parsedFileName.extension.length) {
|
||||||
parsedFileName.extension = '.' + parsedFileName.extension.replace(nameRegex, '')
|
parsedFileName.extension = '.' + parsedFileName.extension.replace(nameRegex, '')
|
||||||
|
}
|
||||||
|
|
||||||
return parsedFileName.name.replace(nameRegex, '').concat(parsedFileName.extension)
|
return parsedFileName.name.replace(nameRegex, '').concat(parsedFileName.extension)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,8 +35,12 @@ export const updateByID: CollectionRouteHandlerWithID = async ({
|
|||||||
|
|
||||||
let message = req.t('general:updatedSuccessfully')
|
let message = req.t('general:updatedSuccessfully')
|
||||||
|
|
||||||
if (draft) message = req.t('version:draftSavedSuccessfully')
|
if (draft) {
|
||||||
if (autosave) message = req.t('version:autosavedSuccessfully')
|
message = req.t('version:draftSavedSuccessfully')
|
||||||
|
}
|
||||||
|
if (autosave) {
|
||||||
|
message = req.t('version:autosavedSuccessfully')
|
||||||
|
}
|
||||||
|
|
||||||
return Response.json(
|
return Response.json(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ export async function checkFileAccess({
|
|||||||
}): Promise<Response | TypeWithID> {
|
}): Promise<Response | TypeWithID> {
|
||||||
const { config } = collection
|
const { config } = collection
|
||||||
const disableEndpoints = endpointsAreDisabled({ endpoints: config.endpoints, request: req })
|
const disableEndpoints = endpointsAreDisabled({ endpoints: config.endpoints, request: req })
|
||||||
if (disableEndpoints) return disableEndpoints
|
if (disableEndpoints) {
|
||||||
|
return disableEndpoints
|
||||||
|
}
|
||||||
|
|
||||||
const accessResult = await executeAccess({ isReadingStaticFile: true, req }, config.access.read)
|
const accessResult = await executeAccess({ isReadingStaticFile: true, req }, config.access.read)
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ export const getFile = async ({ collection, filename, req }: Args): Promise<Resp
|
|||||||
req,
|
req,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (accessResult instanceof Response) return accessResult
|
if (accessResult instanceof Response) {
|
||||||
|
return accessResult
|
||||||
|
}
|
||||||
|
|
||||||
if (collection.config.upload.handlers?.length) {
|
if (collection.config.upload.handlers?.length) {
|
||||||
let customResponse = null
|
let customResponse = null
|
||||||
@@ -47,7 +49,9 @@ export const getFile = async ({ collection, filename, req }: Args): Promise<Resp
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (customResponse instanceof Response) return customResponse
|
if (customResponse instanceof Response) {
|
||||||
|
return customResponse
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileDir = collection.config.upload?.staticDir || collection.config.slug
|
const fileDir = collection.config.upload?.staticDir || collection.config.slug
|
||||||
|
|||||||
@@ -24,8 +24,12 @@ export const update: GlobalRouteHandler = async ({ globalConfig, req }) => {
|
|||||||
|
|
||||||
let message = req.t('general:updatedSuccessfully')
|
let message = req.t('general:updatedSuccessfully')
|
||||||
|
|
||||||
if (draft) message = req.t('version:draftSavedSuccessfully')
|
if (draft) {
|
||||||
if (autosave) message = req.t('version:autosavedSuccessfully')
|
message = req.t('version:draftSavedSuccessfully')
|
||||||
|
}
|
||||||
|
if (autosave) {
|
||||||
|
message = req.t('version:autosavedSuccessfully')
|
||||||
|
}
|
||||||
|
|
||||||
return Response.json(
|
return Response.json(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -246,7 +246,9 @@ export const GET =
|
|||||||
request,
|
request,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (disableEndpoints) return disableEndpoints
|
if (disableEndpoints) {
|
||||||
|
return disableEndpoints
|
||||||
|
}
|
||||||
|
|
||||||
collection = req.payload.collections?.[slug1]
|
collection = req.payload.collections?.[slug1]
|
||||||
|
|
||||||
@@ -256,7 +258,9 @@ export const GET =
|
|||||||
endpoints: collection.config.endpoints,
|
endpoints: collection.config.endpoints,
|
||||||
request,
|
request,
|
||||||
})
|
})
|
||||||
if (disableEndpoints) return disableEndpoints
|
if (disableEndpoints) {
|
||||||
|
return disableEndpoints
|
||||||
|
}
|
||||||
|
|
||||||
const customEndpointResponse = await handleCustomEndpoints({
|
const customEndpointResponse = await handleCustomEndpoints({
|
||||||
endpoints: collection.config.endpoints,
|
endpoints: collection.config.endpoints,
|
||||||
@@ -327,7 +331,9 @@ export const GET =
|
|||||||
endpoints: globalConfig.endpoints,
|
endpoints: globalConfig.endpoints,
|
||||||
request,
|
request,
|
||||||
})
|
})
|
||||||
if (disableEndpoints) return disableEndpoints
|
if (disableEndpoints) {
|
||||||
|
return disableEndpoints
|
||||||
|
}
|
||||||
|
|
||||||
const customEndpointResponse = await handleCustomEndpoints({
|
const customEndpointResponse = await handleCustomEndpoints({
|
||||||
endpoints: globalConfig.endpoints,
|
endpoints: globalConfig.endpoints,
|
||||||
@@ -403,7 +409,9 @@ export const GET =
|
|||||||
req,
|
req,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (customEndpointResponse) return customEndpointResponse
|
if (customEndpointResponse) {
|
||||||
|
return customEndpointResponse
|
||||||
|
}
|
||||||
|
|
||||||
return RouteNotFoundResponse({
|
return RouteNotFoundResponse({
|
||||||
slug,
|
slug,
|
||||||
@@ -445,7 +453,9 @@ export const POST =
|
|||||||
request,
|
request,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (disableEndpoints) return disableEndpoints
|
if (disableEndpoints) {
|
||||||
|
return disableEndpoints
|
||||||
|
}
|
||||||
|
|
||||||
if (collection) {
|
if (collection) {
|
||||||
req.routeParams.collection = slug1
|
req.routeParams.collection = slug1
|
||||||
@@ -453,7 +463,9 @@ export const POST =
|
|||||||
endpoints: collection.config.endpoints,
|
endpoints: collection.config.endpoints,
|
||||||
request,
|
request,
|
||||||
})
|
})
|
||||||
if (disableEndpoints) return disableEndpoints
|
if (disableEndpoints) {
|
||||||
|
return disableEndpoints
|
||||||
|
}
|
||||||
|
|
||||||
const customEndpointResponse = await handleCustomEndpoints({
|
const customEndpointResponse = await handleCustomEndpoints({
|
||||||
endpoints: collection.config.endpoints,
|
endpoints: collection.config.endpoints,
|
||||||
@@ -516,7 +528,9 @@ export const POST =
|
|||||||
endpoints: globalConfig.endpoints,
|
endpoints: globalConfig.endpoints,
|
||||||
request,
|
request,
|
||||||
})
|
})
|
||||||
if (disableEndpoints) return disableEndpoints
|
if (disableEndpoints) {
|
||||||
|
return disableEndpoints
|
||||||
|
}
|
||||||
|
|
||||||
const customEndpointResponse = await handleCustomEndpoints({
|
const customEndpointResponse = await handleCustomEndpoints({
|
||||||
endpoints: globalConfig.endpoints,
|
endpoints: globalConfig.endpoints,
|
||||||
@@ -585,7 +599,9 @@ export const POST =
|
|||||||
req,
|
req,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (customEndpointResponse) return customEndpointResponse
|
if (customEndpointResponse) {
|
||||||
|
return customEndpointResponse
|
||||||
|
}
|
||||||
|
|
||||||
return RouteNotFoundResponse({
|
return RouteNotFoundResponse({
|
||||||
slug,
|
slug,
|
||||||
@@ -620,7 +636,9 @@ export const DELETE =
|
|||||||
endpoints: req.payload.config.endpoints,
|
endpoints: req.payload.config.endpoints,
|
||||||
request,
|
request,
|
||||||
})
|
})
|
||||||
if (disableEndpoints) return disableEndpoints
|
if (disableEndpoints) {
|
||||||
|
return disableEndpoints
|
||||||
|
}
|
||||||
|
|
||||||
if (collection) {
|
if (collection) {
|
||||||
req.routeParams.collection = slug1
|
req.routeParams.collection = slug1
|
||||||
@@ -629,7 +647,9 @@ export const DELETE =
|
|||||||
endpoints: collection.config.endpoints,
|
endpoints: collection.config.endpoints,
|
||||||
request,
|
request,
|
||||||
})
|
})
|
||||||
if (disableEndpoints) return disableEndpoints
|
if (disableEndpoints) {
|
||||||
|
return disableEndpoints
|
||||||
|
}
|
||||||
|
|
||||||
const customEndpointResponse = await handleCustomEndpoints({
|
const customEndpointResponse = await handleCustomEndpoints({
|
||||||
endpoints: collection.config.endpoints,
|
endpoints: collection.config.endpoints,
|
||||||
@@ -679,7 +699,9 @@ export const DELETE =
|
|||||||
req,
|
req,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (customEndpointResponse) return customEndpointResponse
|
if (customEndpointResponse) {
|
||||||
|
return customEndpointResponse
|
||||||
|
}
|
||||||
|
|
||||||
return RouteNotFoundResponse({
|
return RouteNotFoundResponse({
|
||||||
slug,
|
slug,
|
||||||
@@ -714,7 +736,9 @@ export const PATCH =
|
|||||||
endpoints: req.payload.config.endpoints,
|
endpoints: req.payload.config.endpoints,
|
||||||
request,
|
request,
|
||||||
})
|
})
|
||||||
if (disableEndpoints) return disableEndpoints
|
if (disableEndpoints) {
|
||||||
|
return disableEndpoints
|
||||||
|
}
|
||||||
|
|
||||||
if (collection) {
|
if (collection) {
|
||||||
req.routeParams.collection = slug1
|
req.routeParams.collection = slug1
|
||||||
@@ -723,7 +747,9 @@ export const PATCH =
|
|||||||
endpoints: collection.config.endpoints,
|
endpoints: collection.config.endpoints,
|
||||||
request,
|
request,
|
||||||
})
|
})
|
||||||
if (disableEndpoints) return disableEndpoints
|
if (disableEndpoints) {
|
||||||
|
return disableEndpoints
|
||||||
|
}
|
||||||
|
|
||||||
const customEndpointResponse = await handleCustomEndpoints({
|
const customEndpointResponse = await handleCustomEndpoints({
|
||||||
endpoints: collection.config.endpoints,
|
endpoints: collection.config.endpoints,
|
||||||
@@ -774,7 +800,9 @@ export const PATCH =
|
|||||||
req,
|
req,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (customEndpointResponse) return customEndpointResponse
|
if (customEndpointResponse) {
|
||||||
|
return customEndpointResponse
|
||||||
|
}
|
||||||
|
|
||||||
return RouteNotFoundResponse({
|
return RouteNotFoundResponse({
|
||||||
slug,
|
slug,
|
||||||
|
|||||||
@@ -14,10 +14,14 @@ export const sanitizeCollectionID = ({ id, collectionSlug, payload }: Args): num
|
|||||||
let shouldSanitize = Boolean(payload.db.defaultIDType === 'number')
|
let shouldSanitize = Boolean(payload.db.defaultIDType === 'number')
|
||||||
|
|
||||||
// UNLESS the customIDType for this collection is text.... then we leave it
|
// UNLESS the customIDType for this collection is text.... then we leave it
|
||||||
if (shouldSanitize && collection.customIDType === 'text') shouldSanitize = false
|
if (shouldSanitize && collection.customIDType === 'text') {
|
||||||
|
shouldSanitize = false
|
||||||
|
}
|
||||||
|
|
||||||
// If we still should sanitize, parse float
|
// If we still should sanitize, parse float
|
||||||
if (shouldSanitize) sanitizedID = parseFloat(sanitizedID)
|
if (shouldSanitize) {
|
||||||
|
sanitizedID = parseFloat(sanitizedID)
|
||||||
|
}
|
||||||
|
|
||||||
return sanitizedID
|
return sanitizedID
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&--nav-open {
|
&--nav-open {
|
||||||
|
|
||||||
.template-default {
|
.template-default {
|
||||||
&__nav-overlay {
|
&__nav-overlay {
|
||||||
transition: opacity var(--nav-trans-time) linear;
|
transition: opacity var(--nav-trans-time) linear;
|
||||||
|
|||||||
@@ -31,8 +31,12 @@ export function addLocalesToRequestFromData(req: PayloadRequest): void {
|
|||||||
localization: config.localization,
|
localization: config.localization,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (locale) req.locale = locale
|
if (locale) {
|
||||||
if (fallbackLocale) req.fallbackLocale = fallbackLocale
|
req.locale = locale
|
||||||
|
}
|
||||||
|
if (fallbackLocale) {
|
||||||
|
req.fallbackLocale = fallbackLocale
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,8 +69,12 @@ export const createPayloadRequest = async ({
|
|||||||
fallbackLocale = locales.fallbackLocale
|
fallbackLocale = locales.fallbackLocale
|
||||||
|
|
||||||
// Override if query params are present, in order to respect HTTP method override
|
// Override if query params are present, in order to respect HTTP method override
|
||||||
if (query.locale) locale = query.locale
|
if (query.locale) {
|
||||||
if (query?.['fallback-locale']) fallbackLocale = query['fallback-locale']
|
locale = query.locale
|
||||||
|
}
|
||||||
|
if (query?.['fallback-locale']) {
|
||||||
|
fallbackLocale = query['fallback-locale']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const customRequest: CustomPayloadRequestProperties = {
|
const customRequest: CustomPayloadRequestProperties = {
|
||||||
@@ -110,7 +114,9 @@ export const createPayloadRequest = async ({
|
|||||||
|
|
||||||
req.user = user
|
req.user = user
|
||||||
|
|
||||||
if (responseHeaders) req.responseHeaders = responseHeaders
|
if (responseHeaders) {
|
||||||
|
req.responseHeaders = responseHeaders
|
||||||
|
}
|
||||||
|
|
||||||
return req
|
return req
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ export const handleAuthRedirect = ({
|
|||||||
} = config
|
} = config
|
||||||
|
|
||||||
if (!isAdminAuthRoute({ adminRoute, config, route })) {
|
if (!isAdminAuthRoute({ adminRoute, config, route })) {
|
||||||
if (searchParams && 'redirect' in searchParams) delete searchParams.redirect
|
if (searchParams && 'redirect' in searchParams) {
|
||||||
|
delete searchParams.redirect
|
||||||
|
}
|
||||||
|
|
||||||
const redirectRoute = encodeURIComponent(
|
const redirectRoute = encodeURIComponent(
|
||||||
route + Object.keys(searchParams ?? {}).length
|
route + Object.keys(searchParams ?? {}).length
|
||||||
|
|||||||
@@ -117,7 +117,9 @@ export const initPage = async ({
|
|||||||
|
|
||||||
locale = findLocaleFromCode(localization, localeCode)
|
locale = findLocaleFromCode(localization, localeCode)
|
||||||
|
|
||||||
if (!locale) locale = findLocaleFromCode(localization, defaultLocaleCode)
|
if (!locale) {
|
||||||
|
locale = findLocaleFromCode(localization, defaultLocaleCode)
|
||||||
|
}
|
||||||
req.locale = locale.code
|
req.locale = locale.code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
export const timestamp = (label: string) => {
|
export const timestamp = (label: string) => {
|
||||||
if (!process.env.PAYLOAD_TIME) process.env.PAYLOAD_TIME = String(new Date().getTime())
|
if (!process.env.PAYLOAD_TIME) {
|
||||||
|
process.env.PAYLOAD_TIME = String(new Date().getTime())
|
||||||
|
}
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
console.log(`[${now.getTime() - Number(process.env.PAYLOAD_TIME)}ms] ${label}`)
|
console.log(`[${now.getTime() - Number(process.env.PAYLOAD_TIME)}ms] ${label}`)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
import type { AdminViewProps } from 'payload'
|
import type { AdminViewProps } from 'payload'
|
||||||
|
|
||||||
import { DocumentInfoProvider, EditDepthProvider, HydrateAuthProvider, RenderComponent } from '@payloadcms/ui'
|
import {
|
||||||
|
DocumentInfoProvider,
|
||||||
|
EditDepthProvider,
|
||||||
|
HydrateAuthProvider,
|
||||||
|
RenderComponent,
|
||||||
|
} from '@payloadcms/ui'
|
||||||
import { getCreateMappedComponent } from '@payloadcms/ui/shared'
|
import { getCreateMappedComponent } from '@payloadcms/ui/shared'
|
||||||
import { notFound } from 'next/navigation.js'
|
import { notFound } from 'next/navigation.js'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
@@ -92,16 +97,15 @@ export const Account: React.FC<AdminViewProps> = async ({
|
|||||||
isEditing
|
isEditing
|
||||||
>
|
>
|
||||||
<EditDepthProvider depth={1}>
|
<EditDepthProvider depth={1}>
|
||||||
|
<DocumentHeader
|
||||||
<DocumentHeader
|
collectionConfig={collectionConfig}
|
||||||
collectionConfig={collectionConfig}
|
hideTabs
|
||||||
hideTabs
|
i18n={i18n}
|
||||||
i18n={i18n}
|
payload={payload}
|
||||||
payload={payload}
|
permissions={permissions}
|
||||||
permissions={permissions}
|
/>
|
||||||
/>
|
<HydrateAuthProvider permissions={permissions} />
|
||||||
<HydrateAuthProvider permissions={permissions} />
|
<RenderComponent mappedComponent={mappedAccountComponent} />
|
||||||
<RenderComponent mappedComponent={mappedAccountComponent} />
|
|
||||||
<AccountClient />
|
<AccountClient />
|
||||||
</EditDepthProvider>
|
</EditDepthProvider>
|
||||||
</DocumentInfoProvider>
|
</DocumentInfoProvider>
|
||||||
|
|||||||
@@ -91,7 +91,9 @@ export const SetDocumentStepNav: React.FC<{
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drawerDepth <= 1) setStepNav(nav)
|
if (drawerDepth <= 1) {
|
||||||
|
setStepNav(nav)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
setStepNav,
|
setStepNav,
|
||||||
|
|||||||
@@ -95,8 +95,12 @@ export const DefaultEditView: React.FC = () => {
|
|||||||
|
|
||||||
const classes = [baseClass, id && `${baseClass}--is-editing`]
|
const classes = [baseClass, id && `${baseClass}--is-editing`]
|
||||||
|
|
||||||
if (globalSlug) classes.push(`global-edit--${globalSlug}`)
|
if (globalSlug) {
|
||||||
if (collectionSlug) classes.push(`collection-edit--${collectionSlug}`)
|
classes.push(`global-edit--${globalSlug}`)
|
||||||
|
}
|
||||||
|
if (collectionSlug) {
|
||||||
|
classes.push(`collection-edit--${collectionSlug}`)
|
||||||
|
}
|
||||||
|
|
||||||
const [schemaPath, setSchemaPath] = React.useState(() => {
|
const [schemaPath, setSchemaPath] = React.useState(() => {
|
||||||
if (operation === 'create' && auth && !auth.disableLocalStrategy) {
|
if (operation === 'create' && auth && !auth.disableLocalStrategy) {
|
||||||
|
|||||||
@@ -146,7 +146,9 @@ export const LivePreviewProvider: React.FC<LivePreviewProviderProps> = ({
|
|||||||
(type: 'iframe' | 'popup') => {
|
(type: 'iframe' | 'popup') => {
|
||||||
setAppIsReady(false)
|
setAppIsReady(false)
|
||||||
setPreviewWindowType(type)
|
setPreviewWindowType(type)
|
||||||
if (type === 'popup') openPopupWindow()
|
if (type === 'popup') {
|
||||||
|
openPopupWindow()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[openPopupWindow],
|
[openPopupWindow],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -54,8 +54,11 @@ export const DeviceContainer: React.FC<{
|
|||||||
if (deviceIsLargerThanFrame) {
|
if (deviceIsLargerThanFrame) {
|
||||||
if (zoom > 1) {
|
if (zoom > 1) {
|
||||||
const differenceFromDeviceToFrame = measuredDeviceSize.width - outerFrameSize.width
|
const differenceFromDeviceToFrame = measuredDeviceSize.width - outerFrameSize.width
|
||||||
if (differenceFromDeviceToFrame < 0) x = `${differenceFromDeviceToFrame / 2}px`
|
if (differenceFromDeviceToFrame < 0) {
|
||||||
else x = '0'
|
x = `${differenceFromDeviceToFrame / 2}px`
|
||||||
|
} else {
|
||||||
|
x = '0'
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
x = '0'
|
x = '0'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ export const PreviewFrameSizeInput: React.FC<{
|
|||||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
let newValue = Number(e.target.value)
|
let newValue = Number(e.target.value)
|
||||||
|
|
||||||
if (newValue < 0) newValue = 0
|
if (newValue < 0) {
|
||||||
|
newValue = 0
|
||||||
|
}
|
||||||
|
|
||||||
setInternalState(newValue)
|
setInternalState(newValue)
|
||||||
setBreakpoint('custom')
|
setBreakpoint('custom')
|
||||||
@@ -46,8 +48,11 @@ export const PreviewFrameSizeInput: React.FC<{
|
|||||||
// so we need to take the measurements provided by `actualDeviceSize` and sync internal state
|
// so we need to take the measurements provided by `actualDeviceSize` and sync internal state
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (breakpoint === 'responsive' && measuredDeviceSize) {
|
if (breakpoint === 'responsive' && measuredDeviceSize) {
|
||||||
if (axis === 'x') setInternalState(Number(measuredDeviceSize.width.toFixed(0)) * zoom)
|
if (axis === 'x') {
|
||||||
else setInternalState(Number(measuredDeviceSize.height.toFixed(0)) * zoom)
|
setInternalState(Number(measuredDeviceSize.width.toFixed(0)) * zoom)
|
||||||
|
} else {
|
||||||
|
setInternalState(Number(measuredDeviceSize.height.toFixed(0)) * zoom)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (breakpoint !== 'responsive' && size) {
|
if (breakpoint !== 'responsive' && size) {
|
||||||
|
|||||||
@@ -40,8 +40,12 @@ export const LoginForm: React.FC<{
|
|||||||
const canLoginWithUsername = authOptions.loginWithUsername
|
const canLoginWithUsername = authOptions.loginWithUsername
|
||||||
|
|
||||||
const [loginType] = React.useState<LoginFieldProps['type']>(() => {
|
const [loginType] = React.useState<LoginFieldProps['type']>(() => {
|
||||||
if (canLoginWithEmail && canLoginWithUsername) return 'emailOrUsername'
|
if (canLoginWithEmail && canLoginWithUsername) {
|
||||||
if (canLoginWithUsername) return 'username'
|
return 'emailOrUsername'
|
||||||
|
}
|
||||||
|
if (canLoginWithUsername) {
|
||||||
|
return 'username'
|
||||||
|
}
|
||||||
return 'email'
|
return 'email'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ export const isPathMatchingRoute = ({
|
|||||||
const match = regex.exec(currentRoute)
|
const match = regex.exec(currentRoute)
|
||||||
const viewRoute = match?.[0] || viewPath
|
const viewRoute = match?.[0] || viewPath
|
||||||
|
|
||||||
if (exact) return currentRoute === viewRoute
|
if (exact) {
|
||||||
if (!exact) return viewRoute.startsWith(currentRoute)
|
return currentRoute === viewRoute
|
||||||
|
}
|
||||||
|
if (!exact) {
|
||||||
|
return viewRoute.startsWith(currentRoute)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ export const Verify: React.FC<AdminViewProps> = async ({
|
|||||||
return redirect(formatAdminURL({ adminRoute, path: '/login' }))
|
return redirect(formatAdminURL({ adminRoute, path: '/login' }))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// already verified
|
// already verified
|
||||||
if (e?.status === 202) redirect(formatAdminURL({ adminRoute, path: '/login' }))
|
if (e?.status === 202) {
|
||||||
|
redirect(formatAdminURL({ adminRoute, path: '/login' }))
|
||||||
|
}
|
||||||
textToRender = req.t('authentication:unableToVerify')
|
textToRender = req.t('authentication:unableToVerify')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ const Iterable: React.FC<DiffComponentProps> = ({
|
|||||||
|
|
||||||
let fields: ClientField[] = []
|
let fields: ClientField[] = []
|
||||||
|
|
||||||
if (field.type === 'array' && 'fields' in field) fields = field.fields
|
if (field.type === 'array' && 'fields' in field) {
|
||||||
|
fields = field.fields
|
||||||
|
}
|
||||||
|
|
||||||
if (field.type === 'blocks') {
|
if (field.type === 'blocks') {
|
||||||
fields = [
|
fields = [
|
||||||
|
|||||||
@@ -55,7 +55,9 @@ const Select: React.FC<DiffComponentProps<SelectFieldClient>> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
let placeholder = ''
|
let placeholder = ''
|
||||||
|
|
||||||
if (version === comparison) placeholder = `[${i18n.t('general:noValue')}]`
|
if (version === comparison) {
|
||||||
|
placeholder = `[${i18n.t('general:noValue')}]`
|
||||||
|
}
|
||||||
|
|
||||||
const options = 'options' in field && field.options
|
const options = 'options' in field && field.options
|
||||||
|
|
||||||
|
|||||||
@@ -24,14 +24,20 @@ const Text: React.FC<DiffComponentProps<TextFieldClient>> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
let placeholder = ''
|
let placeholder = ''
|
||||||
|
|
||||||
if (version === comparison) placeholder = `[${i18n.t('general:noValue')}]`
|
if (version === comparison) {
|
||||||
|
placeholder = `[${i18n.t('general:noValue')}]`
|
||||||
|
}
|
||||||
|
|
||||||
let versionToRender = version
|
let versionToRender = version
|
||||||
let comparisonToRender = comparison
|
let comparisonToRender = comparison
|
||||||
|
|
||||||
if (isRichText) {
|
if (isRichText) {
|
||||||
if (typeof version === 'object') versionToRender = JSON.stringify(version, null, 2)
|
if (typeof version === 'object') {
|
||||||
if (typeof comparison === 'object') comparisonToRender = JSON.stringify(comparison, null, 2)
|
versionToRender = JSON.stringify(version, null, 2)
|
||||||
|
}
|
||||||
|
if (typeof comparison === 'object') {
|
||||||
|
comparisonToRender = JSON.stringify(comparison, null, 2)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ const RenderFieldsToDiff: React.FC<Props> = ({
|
|||||||
return (
|
return (
|
||||||
<div className={baseClass}>
|
<div className={baseClass}>
|
||||||
{fields?.map((field, i) => {
|
{fields?.map((field, i) => {
|
||||||
if ('name' in field && field.name === 'id') return null
|
if ('name' in field && field.name === 'id') {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
const Component = diffComponents[field.type]
|
const Component = diffComponents[field.type]
|
||||||
|
|
||||||
@@ -53,7 +55,9 @@ const RenderFieldsToDiff: React.FC<Props> = ({
|
|||||||
|
|
||||||
const subFieldPermissions = fieldPermissions?.[fieldName]?.fields
|
const subFieldPermissions = fieldPermissions?.[fieldName]?.fields
|
||||||
|
|
||||||
if (hasPermission === false) return null
|
if (hasPermission === false) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
const baseCellProps: FieldDiffProps = {
|
const baseCellProps: FieldDiffProps = {
|
||||||
comparison: comparisonValue,
|
comparison: comparisonValue,
|
||||||
|
|||||||
@@ -48,7 +48,9 @@ export const SelectComparison: React.FC<Props> = (props) => {
|
|||||||
|
|
||||||
const getResults = useCallback(
|
const getResults = useCallback(
|
||||||
async ({ lastLoadedPage: lastLoadedPageArg }) => {
|
async ({ lastLoadedPage: lastLoadedPageArg }) => {
|
||||||
if (loadedAllOptionsRef.current) return
|
if (loadedAllOptionsRef.current) {
|
||||||
|
return
|
||||||
|
}
|
||||||
const query: {
|
const query: {
|
||||||
[key: string]: unknown
|
[key: string]: unknown
|
||||||
where: Where
|
where: Where
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ export const SelectLocales: React.FC<Props> = ({ onChange, options, value }) =>
|
|||||||
|
|
||||||
const format = (items) => {
|
const format = (items) => {
|
||||||
return items.map((item) => {
|
return items.map((item) => {
|
||||||
if (typeof item.label === 'string') return item
|
if (typeof item.label === 'string') {
|
||||||
|
return item
|
||||||
|
}
|
||||||
if (typeof item.label !== 'string' && item.label[code]) {
|
if (typeof item.label !== 'string' && item.label[code]) {
|
||||||
return {
|
return {
|
||||||
label: item.label[code],
|
label: item.label[code],
|
||||||
|
|||||||
@@ -32,17 +32,19 @@ export const CreatedAtCell: React.FC<CreatedAtCellProps> = ({
|
|||||||
|
|
||||||
let to: string
|
let to: string
|
||||||
|
|
||||||
if (collectionSlug)
|
if (collectionSlug) {
|
||||||
to = formatAdminURL({
|
to = formatAdminURL({
|
||||||
adminRoute,
|
adminRoute,
|
||||||
path: `/collections/${collectionSlug}/${docID}/versions/${versionID}`,
|
path: `/collections/${collectionSlug}/${docID}/versions/${versionID}`,
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if (globalSlug)
|
if (globalSlug) {
|
||||||
to = formatAdminURL({
|
to = formatAdminURL({
|
||||||
adminRoute,
|
adminRoute,
|
||||||
path: `/globals/${globalSlug}/versions/${versionID}`,
|
path: `/globals/${globalSlug}/versions/${versionID}`,
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link href={to}>
|
<Link href={to}>
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ const executeAccess = async (
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
if (!disableErrors) throw new Forbidden(req.t)
|
if (!disableErrors) {
|
||||||
|
throw new Forbidden(req.t)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -33,7 +35,9 @@ const executeAccess = async (
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!disableErrors) throw new Forbidden(req.t)
|
if (!disableErrors) {
|
||||||
|
throw new Forbidden(req.t)
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ export const getBaseAuthFields = (authConfig: IncomingAuthType): Field[] => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
authFields.push(emailField)
|
authFields.push(emailField)
|
||||||
if (usernameField) authFields.push(usernameField)
|
if (usernameField) {
|
||||||
|
authFields.push(usernameField)
|
||||||
|
}
|
||||||
|
|
||||||
authFields.push(...baseAuthFields)
|
authFields.push(...baseAuthFields)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
const isLocked = (date: number): boolean => {
|
const isLocked = (date: number): boolean => {
|
||||||
if (!date) return false
|
if (!date) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return date > Date.now()
|
return date > Date.now()
|
||||||
}
|
}
|
||||||
export default isLocked
|
export default isLocked
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ export const auth = async (args: Required<AuthArgs>): Promise<AuthResult> => {
|
|||||||
req,
|
req,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (shouldCommit) await commitTransaction(req)
|
if (shouldCommit) {
|
||||||
|
await commitTransaction(req)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
permissions,
|
permissions,
|
||||||
|
|||||||
@@ -128,7 +128,9 @@ export const forgotPasswordOperation = async <TSlug extends CollectionSlug>(
|
|||||||
// We don't want to indicate specifically that an email was not found,
|
// We don't want to indicate specifically that an email was not found,
|
||||||
// as doing so could lead to the exposure of registered emails.
|
// as doing so could lead to the exposure of registered emails.
|
||||||
// Therefore, we prefer to fail silently.
|
// Therefore, we prefer to fail silently.
|
||||||
if (!user) return null
|
if (!user) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
user.resetPasswordToken = token
|
user.resetPasswordToken = token
|
||||||
user.resetPasswordExpiration = new Date(expiration || Date.now() + 3600000).toISOString() // 1 hour
|
user.resetPasswordExpiration = new Date(expiration || Date.now() + 3600000).toISOString() // 1 hour
|
||||||
@@ -197,7 +199,9 @@ export const forgotPasswordOperation = async <TSlug extends CollectionSlug>(
|
|||||||
result: token,
|
result: token,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (shouldCommit) await commitTransaction(req)
|
if (shouldCommit) {
|
||||||
|
await commitTransaction(req)
|
||||||
|
}
|
||||||
|
|
||||||
return token
|
return token
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
|
|||||||
@@ -202,7 +202,9 @@ export const loginOperation = async <TSlug extends CollectionSlug>(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldCommit) await commitTransaction(req)
|
if (shouldCommit) {
|
||||||
|
await commitTransaction(req)
|
||||||
|
}
|
||||||
|
|
||||||
throw new AuthenticationError(req.t)
|
throw new AuthenticationError(req.t)
|
||||||
}
|
}
|
||||||
@@ -332,7 +334,9 @@ export const loginOperation = async <TSlug extends CollectionSlug>(
|
|||||||
// Return results
|
// Return results
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
|
|
||||||
if (shouldCommit) await commitTransaction(req)
|
if (shouldCommit) {
|
||||||
|
await commitTransaction(req)
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
|
|||||||
@@ -18,9 +18,12 @@ export const logoutOperation = async (incomingArgs: Arguments): Promise<boolean>
|
|||||||
req,
|
req,
|
||||||
} = incomingArgs
|
} = incomingArgs
|
||||||
|
|
||||||
if (!user) throw new APIError('No User', httpStatus.BAD_REQUEST)
|
if (!user) {
|
||||||
if (user.collection !== collectionConfig.slug)
|
throw new APIError('No User', httpStatus.BAD_REQUEST)
|
||||||
|
}
|
||||||
|
if (user.collection !== collectionConfig.slug) {
|
||||||
throw new APIError('Incorrect collection', httpStatus.FORBIDDEN)
|
throw new APIError('Incorrect collection', httpStatus.FORBIDDEN)
|
||||||
|
}
|
||||||
|
|
||||||
await collectionConfig.hooks.afterLogout.reduce(async (priorHook, hook) => {
|
await collectionConfig.hooks.afterLogout.reduce(async (priorHook, hook) => {
|
||||||
await priorHook
|
await priorHook
|
||||||
|
|||||||
@@ -69,8 +69,12 @@ export const meOperation = async (args: Arguments): Promise<MeOperationResult> =
|
|||||||
|
|
||||||
if (currentToken) {
|
if (currentToken) {
|
||||||
const decoded = jwt.decode(currentToken) as jwt.JwtPayload
|
const decoded = jwt.decode(currentToken) as jwt.JwtPayload
|
||||||
if (decoded) result.exp = decoded.exp
|
if (decoded) {
|
||||||
if (!collection.config.auth.removeTokenFromResponses) result.token = currentToken
|
result.exp = decoded.exp
|
||||||
|
}
|
||||||
|
if (!collection.config.auth.removeTokenFromResponses) {
|
||||||
|
result.token = currentToken
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,9 @@ export const refreshOperation = async (incomingArgs: Arguments): Promise<Result>
|
|||||||
},
|
},
|
||||||
} = args
|
} = args
|
||||||
|
|
||||||
if (!args.req.user) throw new Forbidden(args.req.t)
|
if (!args.req.user) {
|
||||||
|
throw new Forbidden(args.req.t)
|
||||||
|
}
|
||||||
|
|
||||||
const parsedURL = url.parse(args.req.url)
|
const parsedURL = url.parse(args.req.url)
|
||||||
const isGraphQL = parsedURL.pathname === config.routes.graphQL
|
const isGraphQL = parsedURL.pathname === config.routes.graphQL
|
||||||
@@ -143,7 +145,9 @@ export const refreshOperation = async (incomingArgs: Arguments): Promise<Result>
|
|||||||
// Return results
|
// Return results
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
|
|
||||||
if (shouldCommit) await commitTransaction(req)
|
if (shouldCommit) {
|
||||||
|
await commitTransaction(req)
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ export const registerFirstUserOperation = async <TSlug extends CollectionSlug>(
|
|||||||
req,
|
req,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (doc) throw new Forbidden(req.t)
|
if (doc) {
|
||||||
|
throw new Forbidden(req.t)
|
||||||
|
}
|
||||||
|
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
// Register first user
|
// Register first user
|
||||||
@@ -93,7 +95,9 @@ export const registerFirstUserOperation = async <TSlug extends CollectionSlug>(
|
|||||||
req,
|
req,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (shouldCommit) await commitTransaction(req)
|
if (shouldCommit) {
|
||||||
|
await commitTransaction(req)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
exp,
|
exp,
|
||||||
|
|||||||
@@ -64,7 +64,9 @@ export const resetPasswordOperation = async (args: Arguments): Promise<Result> =
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!user) throw new APIError('Token is either invalid or has expired.', httpStatus.FORBIDDEN)
|
if (!user) {
|
||||||
|
throw new APIError('Token is either invalid or has expired.', httpStatus.FORBIDDEN)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: replace this method
|
// TODO: replace this method
|
||||||
const { hash, salt } = await generatePasswordSaltHash({
|
const { hash, salt } = await generatePasswordSaltHash({
|
||||||
@@ -108,7 +110,9 @@ export const resetPasswordOperation = async (args: Arguments): Promise<Result> =
|
|||||||
overrideAccess,
|
overrideAccess,
|
||||||
req,
|
req,
|
||||||
})
|
})
|
||||||
if (shouldCommit) await commitTransaction(req)
|
if (shouldCommit) {
|
||||||
|
await commitTransaction(req)
|
||||||
|
}
|
||||||
|
|
||||||
const result = {
|
const result = {
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -102,7 +102,9 @@ export const unlockOperation = async <TSlug extends CollectionSlug>(
|
|||||||
result = null
|
result = null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldCommit) await commitTransaction(req)
|
if (shouldCommit) {
|
||||||
|
await commitTransaction(req)
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
|
|||||||
@@ -31,9 +31,12 @@ export const verifyEmailOperation = async (args: Args): Promise<boolean> => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!user) throw new APIError('Verification token is invalid.', httpStatus.FORBIDDEN)
|
if (!user) {
|
||||||
if (user && user._verified === true)
|
throw new APIError('Verification token is invalid.', httpStatus.FORBIDDEN)
|
||||||
|
}
|
||||||
|
if (user && user._verified === true) {
|
||||||
throw new APIError('This account has already been activated.', httpStatus.ACCEPTED)
|
throw new APIError('This account has already been activated.', httpStatus.ACCEPTED)
|
||||||
|
}
|
||||||
|
|
||||||
await req.payload.db.updateOne({
|
await req.payload.db.updateOne({
|
||||||
id: user.id,
|
id: user.id,
|
||||||
@@ -46,7 +49,9 @@ export const verifyEmailOperation = async (args: Args): Promise<boolean> => {
|
|||||||
req,
|
req,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (shouldCommit) await commitTransaction(req)
|
if (shouldCommit) {
|
||||||
|
await commitTransaction(req)
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ export const authenticateLocalStrategy = async ({ doc, password }: Args): Promis
|
|||||||
if (typeof salt === 'string' && typeof hash === 'string') {
|
if (typeof salt === 'string' && typeof hash === 'string') {
|
||||||
const res = await new Promise<Doc | null>((resolve, reject) => {
|
const res = await new Promise<Doc | null>((resolve, reject) => {
|
||||||
crypto.pbkdf2(password, salt, 25000, 512, 'sha256', (e, hashBuffer) => {
|
crypto.pbkdf2(password, salt, 25000, 512, 'sha256', (e, hashBuffer) => {
|
||||||
if (e) reject(null)
|
if (e) {
|
||||||
|
reject(null)
|
||||||
|
}
|
||||||
|
|
||||||
if (scmp(hashBuffer, Buffer.from(hash, 'hex'))) {
|
if (scmp(hashBuffer, Buffer.from(hash, 'hex'))) {
|
||||||
resolve(doc)
|
resolve(doc)
|
||||||
|
|||||||
@@ -78,7 +78,9 @@ export const registerLocalStrategy = async ({
|
|||||||
const { hash, salt } = await generatePasswordSaltHash({ collection, password, req })
|
const { hash, salt } = await generatePasswordSaltHash({ collection, password, req })
|
||||||
|
|
||||||
const sanitizedDoc = { ...doc }
|
const sanitizedDoc = { ...doc }
|
||||||
if (sanitizedDoc.password) delete sanitizedDoc.password
|
if (sanitizedDoc.password) {
|
||||||
|
delete sanitizedDoc.password
|
||||||
|
}
|
||||||
|
|
||||||
return payload.db.create({
|
return payload.db.create({
|
||||||
collection: collection.slug,
|
collection: collection.slug,
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ export const resetLoginAttempts = async ({
|
|||||||
payload,
|
payload,
|
||||||
req,
|
req,
|
||||||
}: Args): Promise<void> => {
|
}: Args): Promise<void> => {
|
||||||
if (!('lockUntil' in doc && typeof doc.lockUntil === 'string') || doc.loginAttempts === 0) return
|
if (!('lockUntil' in doc && typeof doc.lockUntil === 'string') || doc.loginAttempts === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
await payload.update({
|
await payload.update({
|
||||||
id: doc.id,
|
id: doc.id,
|
||||||
collection: collection.slug,
|
collection: collection.slug,
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ export async function generateTypes(
|
|||||||
|
|
||||||
const shouldLog = options?.log ?? true
|
const shouldLog = options?.log ?? true
|
||||||
|
|
||||||
if (shouldLog) logger.info('Compiling TS types for Collections and Globals...')
|
if (shouldLog) {
|
||||||
|
logger.info('Compiling TS types for Collections and Globals...')
|
||||||
|
}
|
||||||
|
|
||||||
const jsonSchema = configToJSONSchema(config, config.db.defaultIDType)
|
const jsonSchema = configToJSONSchema(config, config.db.defaultIDType)
|
||||||
|
|
||||||
@@ -54,5 +56,7 @@ export async function generateTypes(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(outputFile, compiled)
|
fs.writeFileSync(outputFile, compiled)
|
||||||
if (shouldLog) logger.info(`Types written to ${outputFile}`)
|
if (shouldLog) {
|
||||||
|
logger.info(`Types written to ${outputFile}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ export const bin = async () => {
|
|||||||
const configPath = findConfig()
|
const configPath = findConfig()
|
||||||
const configPromise = await import(pathToFileURL(configPath).toString())
|
const configPromise = await import(pathToFileURL(configPath).toString())
|
||||||
let config = await configPromise
|
let config = await configPromise
|
||||||
if (config.default) config = await config.default
|
if (config.default) {
|
||||||
|
config = await config.default
|
||||||
|
}
|
||||||
|
|
||||||
const userBinScript = Array.isArray(config.bin)
|
const userBinScript = Array.isArray(config.bin)
|
||||||
? config.bin.find(({ key }) => key === script)
|
? config.bin.find(({ key }) => key === script)
|
||||||
|
|||||||
@@ -50,8 +50,12 @@ export const sanitizeCollection = async (
|
|||||||
let hasCreatedAt = null
|
let hasCreatedAt = null
|
||||||
sanitized.fields.some((field) => {
|
sanitized.fields.some((field) => {
|
||||||
if (fieldAffectsData(field)) {
|
if (fieldAffectsData(field)) {
|
||||||
if (field.name === 'updatedAt') hasUpdatedAt = true
|
if (field.name === 'updatedAt') {
|
||||||
if (field.name === 'createdAt') hasCreatedAt = true
|
hasUpdatedAt = true
|
||||||
|
}
|
||||||
|
if (field.name === 'createdAt') {
|
||||||
|
hasCreatedAt = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return hasCreatedAt && hasUpdatedAt
|
return hasCreatedAt && hasUpdatedAt
|
||||||
})
|
})
|
||||||
@@ -84,7 +88,9 @@ export const sanitizeCollection = async (
|
|||||||
sanitized.labels = sanitized.labels || formatLabels(sanitized.slug)
|
sanitized.labels = sanitized.labels || formatLabels(sanitized.slug)
|
||||||
|
|
||||||
if (sanitized.versions) {
|
if (sanitized.versions) {
|
||||||
if (sanitized.versions === true) sanitized.versions = { drafts: false }
|
if (sanitized.versions === true) {
|
||||||
|
sanitized.versions = { drafts: false }
|
||||||
|
}
|
||||||
|
|
||||||
if (sanitized.timestamps === false) {
|
if (sanitized.timestamps === false) {
|
||||||
throw new TimestampsRequired(collection)
|
throw new TimestampsRequired(collection)
|
||||||
@@ -113,7 +119,9 @@ export const sanitizeCollection = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sanitized.upload) {
|
if (sanitized.upload) {
|
||||||
if (sanitized.upload === true) sanitized.upload = {}
|
if (sanitized.upload === true) {
|
||||||
|
sanitized.upload = {}
|
||||||
|
}
|
||||||
|
|
||||||
// sanitize fields for reserved names
|
// sanitize fields for reserved names
|
||||||
sanitizeUploadFields(sanitized.fields, sanitized)
|
sanitizeUploadFields(sanitized.fields, sanitized)
|
||||||
|
|||||||
@@ -75,7 +75,9 @@ const batchAndLoadDocs =
|
|||||||
|
|
||||||
let sanitizedID: number | string = id
|
let sanitizedID: number | string = id
|
||||||
|
|
||||||
if (idType === 'number') sanitizedID = parseFloat(id)
|
if (idType === 'number') {
|
||||||
|
sanitizedID = parseFloat(id)
|
||||||
|
}
|
||||||
|
|
||||||
if (isValidID(sanitizedID, idType)) {
|
if (isValidID(sanitizedID, idType)) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -364,7 +364,9 @@ export const createOperation = async <TSlug extends CollectionSlug>(
|
|||||||
// Return results
|
// Return results
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
|
|
||||||
if (shouldCommit) await commitTransaction(req)
|
if (shouldCommit) {
|
||||||
|
await commitTransaction(req)
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
|
|||||||
@@ -261,7 +261,9 @@ export const deleteOperation = async <TSlug extends CollectionSlug>(
|
|||||||
result,
|
result,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (shouldCommit) await commitTransaction(req)
|
if (shouldCommit) {
|
||||||
|
await commitTransaction(req)
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
|
|||||||
@@ -102,8 +102,12 @@ export const deleteByIDOperation = async <TSlug extends CollectionSlug>(
|
|||||||
where: combineQueries({ id: { equals: id } }, accessResults),
|
where: combineQueries({ id: { equals: id } }, accessResults),
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!docToDelete && !hasWhereAccess) throw new NotFound(req.t)
|
if (!docToDelete && !hasWhereAccess) {
|
||||||
if (!docToDelete && hasWhereAccess) throw new Forbidden(req.t)
|
throw new NotFound(req.t)
|
||||||
|
}
|
||||||
|
if (!docToDelete && hasWhereAccess) {
|
||||||
|
throw new Forbidden(req.t)
|
||||||
|
}
|
||||||
|
|
||||||
await deleteAssociatedFiles({
|
await deleteAssociatedFiles({
|
||||||
collectionConfig,
|
collectionConfig,
|
||||||
@@ -213,7 +217,9 @@ export const deleteByIDOperation = async <TSlug extends CollectionSlug>(
|
|||||||
// 8. Return results
|
// 8. Return results
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
|
|
||||||
if (shouldCommit) await commitTransaction(req)
|
if (shouldCommit) {
|
||||||
|
await commitTransaction(req)
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
|
|||||||
@@ -101,8 +101,12 @@ export const duplicateOperation = async <TSlug extends CollectionSlug>(
|
|||||||
req,
|
req,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!docWithLocales && !hasWherePolicy) throw new NotFound(req.t)
|
if (!docWithLocales && !hasWherePolicy) {
|
||||||
if (!docWithLocales && hasWherePolicy) throw new Forbidden(req.t)
|
throw new NotFound(req.t)
|
||||||
|
}
|
||||||
|
if (!docWithLocales && hasWherePolicy) {
|
||||||
|
throw new Forbidden(req.t)
|
||||||
|
}
|
||||||
|
|
||||||
// remove the createdAt timestamp and id to rely on the db to set the default it
|
// remove the createdAt timestamp and id to rely on the db to set the default it
|
||||||
delete docWithLocales.createdAt
|
delete docWithLocales.createdAt
|
||||||
@@ -324,7 +328,9 @@ export const duplicateOperation = async <TSlug extends CollectionSlug>(
|
|||||||
// Return results
|
// Return results
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
|
|
||||||
if (shouldCommit) await commitTransaction(req)
|
if (shouldCommit) {
|
||||||
|
await commitTransaction(req)
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
|
|||||||
@@ -68,7 +68,9 @@ export const findByIDOperation = async <TSlug extends CollectionSlug>(
|
|||||||
: true
|
: true
|
||||||
|
|
||||||
// If errors are disabled, and access returns false, return null
|
// If errors are disabled, and access returns false, return null
|
||||||
if (accessResult === false) return null
|
if (accessResult === false) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
const findOneArgs: FindOneArgs = {
|
const findOneArgs: FindOneArgs = {
|
||||||
collection: collectionConfig.slug,
|
collection: collectionConfig.slug,
|
||||||
@@ -83,7 +85,9 @@ export const findByIDOperation = async <TSlug extends CollectionSlug>(
|
|||||||
// Find by ID
|
// Find by ID
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
|
|
||||||
if (!findOneArgs.where.and[0].id) throw new NotFound(t)
|
if (!findOneArgs.where.and[0].id) {
|
||||||
|
throw new NotFound(t)
|
||||||
|
}
|
||||||
|
|
||||||
let result: DataFromCollectionSlug<TSlug> = await req.payload.db.findOne(findOneArgs)
|
let result: DataFromCollectionSlug<TSlug> = await req.payload.db.findOne(findOneArgs)
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,9 @@ export const findVersionByIDOperation = async <TData extends TypeWithID = any>(
|
|||||||
: true
|
: true
|
||||||
|
|
||||||
// If errors are disabled, and access returns false, return null
|
// If errors are disabled, and access returns false, return null
|
||||||
if (accessResults === false) return null
|
if (accessResults === false) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
const hasWhereAccess = typeof accessResults === 'object'
|
const hasWhereAccess = typeof accessResults === 'object'
|
||||||
|
|
||||||
@@ -73,8 +75,12 @@ export const findVersionByIDOperation = async <TData extends TypeWithID = any>(
|
|||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
if (!disableErrors) {
|
if (!disableErrors) {
|
||||||
if (!hasWhereAccess) throw new NotFound(req.t)
|
if (!hasWhereAccess) {
|
||||||
if (hasWhereAccess) throw new Forbidden(req.t)
|
throw new NotFound(req.t)
|
||||||
|
}
|
||||||
|
if (hasWhereAccess) {
|
||||||
|
throw new Forbidden(req.t)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -87,8 +87,12 @@ export const restoreVersionOperation = async <TData extends TypeWithID = any>(
|
|||||||
|
|
||||||
const doc = await req.payload.db.findOne(findOneArgs)
|
const doc = await req.payload.db.findOne(findOneArgs)
|
||||||
|
|
||||||
if (!doc && !hasWherePolicy) throw new NotFound(req.t)
|
if (!doc && !hasWherePolicy) {
|
||||||
if (!doc && hasWherePolicy) throw new Forbidden(req.t)
|
throw new NotFound(req.t)
|
||||||
|
}
|
||||||
|
if (!doc && hasWherePolicy) {
|
||||||
|
throw new Forbidden(req.t)
|
||||||
|
}
|
||||||
|
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
// fetch previousDoc
|
// fetch previousDoc
|
||||||
|
|||||||
@@ -428,7 +428,9 @@ export const updateOperation = async <TSlug extends CollectionSlug>(
|
|||||||
result,
|
result,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (shouldCommit) await commitTransaction(req)
|
if (shouldCommit) {
|
||||||
|
await commitTransaction(req)
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
|
|||||||
@@ -127,8 +127,12 @@ export const updateByIDOperation = async <TSlug extends CollectionSlug>(
|
|||||||
req,
|
req,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!docWithLocales && !hasWherePolicy) throw new NotFound(req.t)
|
if (!docWithLocales && !hasWherePolicy) {
|
||||||
if (!docWithLocales && hasWherePolicy) throw new Forbidden(req.t)
|
throw new NotFound(req.t)
|
||||||
|
}
|
||||||
|
if (!docWithLocales && hasWherePolicy) {
|
||||||
|
throw new Forbidden(req.t)
|
||||||
|
}
|
||||||
|
|
||||||
const originalDoc = await afterRead({
|
const originalDoc = await afterRead({
|
||||||
collection: collectionConfig,
|
collection: collectionConfig,
|
||||||
@@ -404,7 +408,9 @@ export const updateByIDOperation = async <TSlug extends CollectionSlug>(
|
|||||||
// Return results
|
// Return results
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
|
|
||||||
if (shouldCommit) await commitTransaction(req)
|
if (shouldCommit) {
|
||||||
|
await commitTransaction(req)
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
|
|||||||
@@ -71,7 +71,9 @@ export const findConfig = (): string => {
|
|||||||
: [configPath, srcPath, rootPath]
|
: [configPath, srcPath, rootPath]
|
||||||
|
|
||||||
for (const searchPath of searchPaths) {
|
for (const searchPath of searchPaths) {
|
||||||
if (!searchPath) continue
|
if (!searchPath) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
const configPath = findUpSync(
|
const configPath = findUpSync(
|
||||||
(dir) => {
|
(dir) => {
|
||||||
@@ -106,13 +108,17 @@ export const findConfig = (): string => {
|
|||||||
cwd: path.resolve(process.cwd(), 'dist'),
|
cwd: path.resolve(process.cwd(), 'dist'),
|
||||||
})
|
})
|
||||||
|
|
||||||
if (distConfigPath) return distConfigPath
|
if (distConfigPath) {
|
||||||
|
return distConfigPath
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const srcConfigPath = findUpSync(['payload.config.js', 'payload.config.ts'], {
|
const srcConfigPath = findUpSync(['payload.config.js', 'payload.config.ts'], {
|
||||||
cwd: path.resolve(process.cwd(), 'src'),
|
cwd: path.resolve(process.cwd(), 'src'),
|
||||||
})
|
})
|
||||||
|
|
||||||
if (srcConfigPath) return srcConfigPath
|
if (srcConfigPath) {
|
||||||
|
return srcConfigPath
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
|||||||
@@ -173,13 +173,17 @@ export const sanitizeConfig = async (incomingConfig: Config): Promise<SanitizedC
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get deduped list of upload adapters
|
// Get deduped list of upload adapters
|
||||||
if (!config.upload) config.upload = { adapters: [] }
|
if (!config.upload) {
|
||||||
|
config.upload = { adapters: [] }
|
||||||
|
}
|
||||||
config.upload.adapters = Array.from(
|
config.upload.adapters = Array.from(
|
||||||
new Set(config.collections.map((c) => c.upload?.adapter).filter(Boolean)),
|
new Set(config.collections.map((c) => c.upload?.adapter).filter(Boolean)),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Pass through the email config as is so adapters don't break
|
// Pass through the email config as is so adapters don't break
|
||||||
if (incomingConfig.email) config.email = incomingConfig.email
|
if (incomingConfig.email) {
|
||||||
|
config.email = incomingConfig.email
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Execute richText sanitization
|
Execute richText sanitization
|
||||||
|
|||||||
@@ -3,14 +3,20 @@ import type { Where } from '../types/index.js'
|
|||||||
import { hasWhereAccessResult } from '../auth/index.js'
|
import { hasWhereAccessResult } from '../auth/index.js'
|
||||||
|
|
||||||
export const combineQueries = (where: Where, access: Where | boolean): Where => {
|
export const combineQueries = (where: Where, access: Where | boolean): Where => {
|
||||||
if (!where && !access) return {}
|
if (!where && !access) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
|
||||||
const result: Where = {
|
const result: Where = {
|
||||||
and: [],
|
and: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
if (where) result.and.push(where)
|
if (where) {
|
||||||
if (hasWhereAccessResult(access)) result.and.push(access)
|
result.and.push(where)
|
||||||
|
}
|
||||||
|
if (hasWhereAccessResult(access)) {
|
||||||
|
result.and.push(access)
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,7 +154,9 @@ export async function getLocalizedPaths({
|
|||||||
lastIncompletePath.fields = flattenFields(lastIncompletePath.field.fields, false)
|
lastIncompletePath.fields = flattenFields(lastIncompletePath.field.fields, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i + 1 === pathSegments.length) lastIncompletePath.complete = true
|
if (i + 1 === pathSegments.length) {
|
||||||
|
lastIncompletePath.complete = true
|
||||||
|
}
|
||||||
lastIncompletePath.path = currentPath
|
lastIncompletePath.path = currentPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ export const readMigrationFiles = async ({
|
|||||||
typeof require === 'function'
|
typeof require === 'function'
|
||||||
? await eval(`require('${filePath.replaceAll('\\', '/')}')`)
|
? await eval(`require('${filePath.replaceAll('\\', '/')}')`)
|
||||||
: await eval(`import('${pathToFileURL(filePath).href}')`)
|
: await eval(`import('${pathToFileURL(filePath).href}')`)
|
||||||
if ('default' in migration) migration = migration.default
|
if ('default' in migration) {
|
||||||
|
migration = migration.default
|
||||||
|
}
|
||||||
|
|
||||||
const result: Migration = {
|
const result: Migration = {
|
||||||
name: path.basename(filePath).split('.')?.[0],
|
name: path.basename(filePath).split('.')?.[0],
|
||||||
|
|||||||
@@ -53,7 +53,9 @@ export const sanitizeFields = async ({
|
|||||||
richTextSanitizationPromises,
|
richTextSanitizationPromises,
|
||||||
validRelationships,
|
validRelationships,
|
||||||
}: Args): Promise<Field[]> => {
|
}: Args): Promise<Field[]> => {
|
||||||
if (!fields) return []
|
if (!fields) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0; i < fields.length; i++) {
|
for (let i = 0; i < fields.length; i++) {
|
||||||
const field = fields[i]
|
const field = fields[i]
|
||||||
@@ -62,7 +64,9 @@ export const sanitizeFields = async ({
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!field.type) throw new MissingFieldType(field)
|
if (!field.type) {
|
||||||
|
throw new MissingFieldType(field)
|
||||||
|
}
|
||||||
|
|
||||||
// assert that field names do not contain forbidden characters
|
// assert that field names do not contain forbidden characters
|
||||||
if (fieldAffectsData(field) && field.name.includes('.')) {
|
if (fieldAffectsData(field) && field.name.includes('.')) {
|
||||||
@@ -160,8 +164,12 @@ export const sanitizeFields = async ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!field.hooks) field.hooks = {}
|
if (!field.hooks) {
|
||||||
if (!field.access) field.access = {}
|
field.hooks = {}
|
||||||
|
}
|
||||||
|
if (!field.access) {
|
||||||
|
field.access = {}
|
||||||
|
}
|
||||||
|
|
||||||
setDefaultBeforeDuplicate(field)
|
setDefaultBeforeDuplicate(field)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ export async function afterRead<T extends JsonObject>(args: Args<T>): Promise<T>
|
|||||||
incomingDepth || incomingDepth === 0
|
incomingDepth || incomingDepth === 0
|
||||||
? parseInt(String(incomingDepth), 10)
|
? parseInt(String(incomingDepth), 10)
|
||||||
: req.payload.config.defaultDepth
|
: req.payload.config.defaultDepth
|
||||||
if (depth > req.payload.config.maxDepth) depth = req.payload.config.maxDepth
|
if (depth > req.payload.config.maxDepth) {
|
||||||
|
depth = req.payload.config.maxDepth
|
||||||
|
}
|
||||||
|
|
||||||
const currentDepth = incomingCurrentDepth || 1
|
const currentDepth = incomingCurrentDepth || 1
|
||||||
|
|
||||||
|
|||||||
@@ -313,7 +313,9 @@ export const promise = async ({
|
|||||||
switch (field.type) {
|
switch (field.type) {
|
||||||
case 'group': {
|
case 'group': {
|
||||||
let groupDoc = siblingDoc[field.name] as JsonObject
|
let groupDoc = siblingDoc[field.name] as JsonObject
|
||||||
if (typeof siblingDoc[field.name] !== 'object') groupDoc = {}
|
if (typeof siblingDoc[field.name] !== 'object') {
|
||||||
|
groupDoc = {}
|
||||||
|
}
|
||||||
|
|
||||||
traverseFields({
|
traverseFields({
|
||||||
collection,
|
collection,
|
||||||
@@ -524,7 +526,9 @@ export const promise = async ({
|
|||||||
let tabDoc = siblingDoc
|
let tabDoc = siblingDoc
|
||||||
if (tabHasName(field)) {
|
if (tabHasName(field)) {
|
||||||
tabDoc = siblingDoc[field.name] as JsonObject
|
tabDoc = siblingDoc[field.name] as JsonObject
|
||||||
if (typeof siblingDoc[field.name] !== 'object') tabDoc = {}
|
if (typeof siblingDoc[field.name] !== 'object') {
|
||||||
|
tabDoc = {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
traverseFields({
|
traverseFields({
|
||||||
|
|||||||
@@ -10,13 +10,17 @@ export const getExistingRowDoc = (incomingRow: JsonObject, existingRows?: unknow
|
|||||||
if (incomingRow.id && Array.isArray(existingRows)) {
|
if (incomingRow.id && Array.isArray(existingRows)) {
|
||||||
const matchedExistingRow = existingRows.find((existingRow) => {
|
const matchedExistingRow = existingRows.find((existingRow) => {
|
||||||
if (typeof existingRow === 'object' && 'id' in existingRow) {
|
if (typeof existingRow === 'object' && 'id' in existingRow) {
|
||||||
if (existingRow.id === incomingRow.id) return existingRow
|
if (existingRow.id === incomingRow.id) {
|
||||||
|
return existingRow
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
|
||||||
if (matchedExistingRow) return matchedExistingRow
|
if (matchedExistingRow) {
|
||||||
|
return matchedExistingRow
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {}
|
return {}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user