feat: async plugins (#2030)
* feat: async plugins * wip: async config * fix: async config
This commit is contained in:
@@ -3,10 +3,29 @@ import { SanitizedConfig } from '../../../../config/types';
|
|||||||
|
|
||||||
const Context = createContext<SanitizedConfig>({} as SanitizedConfig);
|
const Context = createContext<SanitizedConfig>({} as SanitizedConfig);
|
||||||
|
|
||||||
export const ConfigProvider: React.FC<{config: SanitizedConfig, children: React.ReactNode}> = ({ children, config }) => (
|
export const ConfigProvider: React.FC<{config: SanitizedConfig, children: React.ReactNode}> = ({ children, config: incomingConfig }) => {
|
||||||
<Context.Provider value={config}>
|
const [config, setConfig] = React.useState<SanitizedConfig>();
|
||||||
{children}
|
const hasAwaited = React.useRef(false);
|
||||||
</Context.Provider>
|
|
||||||
);
|
React.useEffect(() => {
|
||||||
|
if (incomingConfig && !hasAwaited.current) {
|
||||||
|
hasAwaited.current = true;
|
||||||
|
|
||||||
|
const awaitConfig = async () => {
|
||||||
|
const resolvedConfig = await incomingConfig;
|
||||||
|
setConfig(resolvedConfig);
|
||||||
|
};
|
||||||
|
awaitConfig();
|
||||||
|
}
|
||||||
|
}, [incomingConfig]);
|
||||||
|
|
||||||
|
if (!config) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Context.Provider value={config}>
|
||||||
|
{children}
|
||||||
|
</Context.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const useConfig = (): SanitizedConfig => useContext(Context);
|
export const useConfig = (): SanitizedConfig => useContext(Context);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const rawConfigPath = findConfig();
|
|||||||
|
|
||||||
export const build = async (): Promise<void> => {
|
export const build = async (): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
const config = loadConfig();
|
const config = await loadConfig();
|
||||||
|
|
||||||
const webpackProdConfig = getWebpackProdConfig(config);
|
const webpackProdConfig = getWebpackProdConfig(config);
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import payload from '..';
|
|||||||
|
|
||||||
export async function generateGraphQLSchema(): Promise<void> {
|
export async function generateGraphQLSchema(): Promise<void> {
|
||||||
const logger = Logger();
|
const logger = Logger();
|
||||||
const config = loadConfig();
|
const config = await loadConfig();
|
||||||
|
|
||||||
await payload.init({
|
await payload.init({
|
||||||
secret: '--unused--',
|
secret: '--unused--',
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ function configToJsonSchema(config: SanitizedConfig): JSONSchema4 {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateTypes(): void {
|
export async function generateTypes(): Promise<void> {
|
||||||
const logger = Logger();
|
const logger = Logger();
|
||||||
const config = loadConfig();
|
const config = await loadConfig();
|
||||||
const outputFile = process.env.PAYLOAD_TS_OUTPUT_PATH || config.typescript.outputFile;
|
const outputFile = process.env.PAYLOAD_TS_OUTPUT_PATH || config.typescript.outputFile;
|
||||||
|
|
||||||
logger.info('Compiling TS types for Collections and Globals...');
|
logger.info('Compiling TS types for Collections and Globals...');
|
||||||
|
|||||||
@@ -8,14 +8,17 @@ import sanitize from './sanitize';
|
|||||||
* @param config Payload Config
|
* @param config Payload Config
|
||||||
* @returns Built and sanitized Payload Config
|
* @returns Built and sanitized Payload Config
|
||||||
*/
|
*/
|
||||||
export function buildConfig(config: Config): SanitizedConfig {
|
export async function buildConfig(config: Config): Promise<SanitizedConfig> {
|
||||||
if (Array.isArray(config.plugins)) {
|
if (Array.isArray(config.plugins)) {
|
||||||
const configWithPlugins = config.plugins.reduce(
|
const configAfterPlugins = await config.plugins.reduce(
|
||||||
(updatedConfig, plugin) => plugin(updatedConfig),
|
async (acc, plugin) => {
|
||||||
config,
|
const configAfterPlugin = await acc;
|
||||||
|
return plugin(configAfterPlugin);
|
||||||
|
},
|
||||||
|
Promise.resolve(config),
|
||||||
);
|
);
|
||||||
|
|
||||||
const sanitizedConfig = sanitize(configWithPlugins);
|
const sanitizedConfig = sanitize(configAfterPlugins);
|
||||||
|
|
||||||
return sanitizedConfig;
|
return sanitizedConfig;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import findConfig from './find';
|
|||||||
import validate from './validate';
|
import validate from './validate';
|
||||||
import { clientFiles } from './clientFiles';
|
import { clientFiles } from './clientFiles';
|
||||||
|
|
||||||
const loadConfig = (logger?: pino.Logger): SanitizedConfig => {
|
const loadConfig = async (logger?: pino.Logger): Promise<SanitizedConfig> => {
|
||||||
const localLogger = logger ?? Logger();
|
const localLogger = logger ?? Logger();
|
||||||
|
|
||||||
const configPath = findConfig();
|
const configPath = findConfig();
|
||||||
@@ -19,18 +19,18 @@ const loadConfig = (logger?: pino.Logger): SanitizedConfig => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
let config = require(configPath);
|
const configPromise = require(configPath);
|
||||||
|
|
||||||
if (config.default) config = config.default;
|
let config = await configPromise;
|
||||||
|
|
||||||
let validatedConfig = config;
|
if (config.default) config = await config.default;
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
validatedConfig = validate(config, localLogger);
|
config = await validate(config, localLogger);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...validatedConfig,
|
...config,
|
||||||
paths: {
|
paths: {
|
||||||
configDir: path.dirname(configPath),
|
configDir: path.dirname(configPath),
|
||||||
config: configPath,
|
config: configPath,
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ type Email = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line no-use-before-define
|
// eslint-disable-next-line no-use-before-define
|
||||||
export type Plugin = (config: Config) => Config;
|
export type Plugin = (config: Config) => Promise<Config> | Config;
|
||||||
|
|
||||||
type GeneratePreviewURLOptions = {
|
type GeneratePreviewURLOptions = {
|
||||||
locale: string;
|
locale: string;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const validateFields = (context: string, entity: SanitizedCollectionConfig | San
|
|||||||
return errors;
|
return errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
const validateCollections = (collections: SanitizedCollectionConfig[]): string[] => {
|
const validateCollections = async (collections: SanitizedCollectionConfig[]): Promise<string[]> => {
|
||||||
const errors: string[] = [];
|
const errors: string[] = [];
|
||||||
collections.forEach((collection) => {
|
collections.forEach((collection) => {
|
||||||
const result = collectionSchema.validate(collection, { abortEarly: false });
|
const result = collectionSchema.validate(collection, { abortEarly: false });
|
||||||
@@ -62,13 +62,13 @@ const validateGlobals = (globals: SanitizedGlobalConfig[]): string[] => {
|
|||||||
return errors;
|
return errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
const validateSchema = (config: SanitizedConfig, logger: Logger): SanitizedConfig => {
|
const validateSchema = async (config: SanitizedConfig, logger: Logger): Promise<SanitizedConfig> => {
|
||||||
const result = schema.validate(config, {
|
const result = schema.validate(config, {
|
||||||
abortEarly: false,
|
abortEarly: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const nestedErrors = [
|
const nestedErrors = [
|
||||||
...validateCollections(config.collections),
|
...await validateCollections(config.collections),
|
||||||
...validateGlobals(config.globals),
|
...validateGlobals(config.globals),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ export class BasePayload<TGeneratedTypes extends GeneratedTypes> {
|
|||||||
} else {
|
} else {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires, global-require
|
// eslint-disable-next-line @typescript-eslint/no-var-requires, global-require
|
||||||
const loadConfig = require('./config/load').default;
|
const loadConfig = require('./config/load').default;
|
||||||
this.config = loadConfig(this.logger);
|
this.config = await loadConfig(this.logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure email service
|
// Configure email service
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ describe('access control', () => {
|
|||||||
let existingDoc: ReadOnlyCollection;
|
let existingDoc: ReadOnlyCollection;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
existingDoc = await payload.create<ReadOnlyCollection>({
|
existingDoc = await payload.create({
|
||||||
collection: readOnlySlug,
|
collection: readOnlySlug,
|
||||||
data: {
|
data: {
|
||||||
name: 'name',
|
name: 'name',
|
||||||
@@ -114,7 +114,7 @@ describe('access control', () => {
|
|||||||
let existingDoc: ReadOnlyCollection;
|
let existingDoc: ReadOnlyCollection;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
existingDoc = await payload.create<ReadOnlyCollection>({
|
existingDoc = await payload.create({
|
||||||
collection: readOnlySlug,
|
collection: readOnlySlug,
|
||||||
data: {
|
data: {
|
||||||
name: 'name',
|
name: 'name',
|
||||||
@@ -162,7 +162,7 @@ describe('access control', () => {
|
|||||||
let existingDoc: RestrictedVersion;
|
let existingDoc: RestrictedVersion;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
existingDoc = await payload.create<RestrictedVersion>({
|
existingDoc = await payload.create({
|
||||||
collection: restrictedVersionsSlug,
|
collection: restrictedVersionsSlug,
|
||||||
data: {
|
data: {
|
||||||
name: 'name',
|
name: 'name',
|
||||||
@@ -172,7 +172,7 @@ describe('access control', () => {
|
|||||||
|
|
||||||
test('versions sidebar should not show', async () => {
|
test('versions sidebar should not show', async () => {
|
||||||
await page.goto(restrictedVersionsUrl.edit(existingDoc.id));
|
await page.goto(restrictedVersionsUrl.edit(existingDoc.id));
|
||||||
await expect(page.locator('.versions-count')).not.toBeVisible();
|
await expect(page.locator('.versions-count')).toBeHidden();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Forbidden } from '../../src/errors';
|
|||||||
import type { PayloadRequest } from '../../src/types';
|
import type { PayloadRequest } from '../../src/types';
|
||||||
import { initPayloadTest } from '../helpers/configHelpers';
|
import { initPayloadTest } from '../helpers/configHelpers';
|
||||||
import { relyOnRequestHeadersSlug, requestHeaders, restrictedSlug, siblingDataSlug, slug } from './config';
|
import { relyOnRequestHeadersSlug, requestHeaders, restrictedSlug, siblingDataSlug, slug } from './config';
|
||||||
import type { Restricted, Post, SiblingDatum, RelyOnRequestHeader } from './payload-types';
|
import type { Restricted, Post, RelyOnRequestHeader } from './payload-types';
|
||||||
import { firstArrayText, secondArrayText } from './shared';
|
import { firstArrayText, secondArrayText } from './shared';
|
||||||
|
|
||||||
describe('Access Control', () => {
|
describe('Access Control', () => {
|
||||||
@@ -17,12 +17,12 @@ describe('Access Control', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
post1 = await payload.create<Post>({
|
post1 = await payload.create({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
data: { name: 'name' },
|
data: { name: 'name' },
|
||||||
});
|
});
|
||||||
|
|
||||||
restricted = await payload.create<Restricted>({
|
restricted = await payload.create({
|
||||||
collection: restrictedSlug,
|
collection: restrictedSlug,
|
||||||
data: { name: 'restricted' },
|
data: { name: 'restricted' },
|
||||||
});
|
});
|
||||||
@@ -37,7 +37,7 @@ describe('Access Control', () => {
|
|||||||
it.todo('should properly prevent / allow public users from reading a restricted field');
|
it.todo('should properly prevent / allow public users from reading a restricted field');
|
||||||
|
|
||||||
it('should be able to restrict access based upon siblingData', async () => {
|
it('should be able to restrict access based upon siblingData', async () => {
|
||||||
const { id } = await payload.create<SiblingDatum>({
|
const { id } = await payload.create({
|
||||||
collection: siblingDataSlug,
|
collection: siblingDataSlug,
|
||||||
data: {
|
data: {
|
||||||
array: [
|
array: [
|
||||||
@@ -53,7 +53,7 @@ describe('Access Control', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const doc = await payload.findByID<SiblingDatum>({
|
const doc = await payload.findByID({
|
||||||
id,
|
id,
|
||||||
collection: siblingDataSlug,
|
collection: siblingDataSlug,
|
||||||
overrideAccess: false,
|
overrideAccess: false,
|
||||||
@@ -64,7 +64,7 @@ describe('Access Control', () => {
|
|||||||
expect(doc.array?.[1].text).toBeUndefined();
|
expect(doc.array?.[1].text).toBeUndefined();
|
||||||
|
|
||||||
// Retrieve with default of overriding access
|
// Retrieve with default of overriding access
|
||||||
const docOverride = await payload.findByID<SiblingDatum>({
|
const docOverride = await payload.findByID({
|
||||||
id,
|
id,
|
||||||
collection: siblingDataSlug,
|
collection: siblingDataSlug,
|
||||||
});
|
});
|
||||||
@@ -150,7 +150,7 @@ describe('Access Control', () => {
|
|||||||
describe('Override Access', () => {
|
describe('Override Access', () => {
|
||||||
describe('Fields', () => {
|
describe('Fields', () => {
|
||||||
it('should allow overrideAccess: false', async () => {
|
it('should allow overrideAccess: false', async () => {
|
||||||
const req = async () => payload.update<Post>({
|
const req = async () => payload.update({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
id: post1.id,
|
id: post1.id,
|
||||||
data: { restrictedField: restricted.id },
|
data: { restrictedField: restricted.id },
|
||||||
@@ -161,7 +161,7 @@ describe('Access Control', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should allow overrideAccess: true', async () => {
|
it('should allow overrideAccess: true', async () => {
|
||||||
const doc = await payload.update<Post>({
|
const doc = await payload.update({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
id: post1.id,
|
id: post1.id,
|
||||||
data: { restrictedField: restricted.id },
|
data: { restrictedField: restricted.id },
|
||||||
@@ -172,7 +172,7 @@ describe('Access Control', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should allow overrideAccess by default', async () => {
|
it('should allow overrideAccess by default', async () => {
|
||||||
const doc = await payload.update<Post>({
|
const doc = await payload.update({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
id: post1.id,
|
id: post1.id,
|
||||||
data: { restrictedField: restricted.id },
|
data: { restrictedField: restricted.id },
|
||||||
@@ -221,7 +221,7 @@ describe('Access Control', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
async function createDoc<Collection>(data: Partial<Collection>, overrideSlug = slug, options?: Partial<CreateOptions<Collection>>): Promise<Collection> {
|
async function createDoc<Collection>(data: Partial<Collection>, overrideSlug = slug, options?: Partial<CreateOptions<Collection>>): Promise<Collection> {
|
||||||
return payload.create<Collection>({
|
return payload.create({
|
||||||
...options,
|
...options,
|
||||||
collection: overrideSlug,
|
collection: overrideSlug,
|
||||||
data: data ?? {},
|
data: data ?? {},
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import { initPayloadTest } from '../helpers/configHelpers';
|
import { initPayloadTest } from '../helpers/configHelpers';
|
||||||
import payload from '../../src';
|
import payload from '../../src';
|
||||||
import config from './config';
|
import configPromise from './config';
|
||||||
import type { Array as ArrayCollection } from './payload-types';
|
|
||||||
|
|
||||||
const collection = config.collections[0]?.slug;
|
let collection: string;
|
||||||
|
|
||||||
describe('array-update', () => {
|
describe('array-update', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
|
const config = await configPromise;
|
||||||
|
collection = config.collections[0]?.slug;
|
||||||
await initPayloadTest({ __dirname });
|
await initPayloadTest({ __dirname });
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ describe('array-update', () => {
|
|||||||
required: updatedText,
|
required: updatedText,
|
||||||
};
|
};
|
||||||
|
|
||||||
const updatedDoc = await payload.update<ArrayCollection>({
|
const updatedDoc = await payload.update({
|
||||||
id: doc.id,
|
id: doc.id,
|
||||||
collection,
|
collection,
|
||||||
data: {
|
data: {
|
||||||
@@ -67,7 +68,7 @@ describe('array-update', () => {
|
|||||||
optional: 'optional test',
|
optional: 'optional test',
|
||||||
};
|
};
|
||||||
|
|
||||||
const doc = await payload.create<ArrayCollection>({
|
const doc = await payload.create({
|
||||||
collection,
|
collection,
|
||||||
data: {
|
data: {
|
||||||
array: [
|
array: [
|
||||||
@@ -80,7 +81,7 @@ describe('array-update', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const updatedDoc = await payload.update<ArrayCollection>({
|
const updatedDoc = await payload.update({
|
||||||
id: doc.id,
|
id: doc.id,
|
||||||
collection,
|
collection,
|
||||||
data: {
|
data: {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Config, SanitizedConfig } from '../src/config/types';
|
import { Config, SanitizedConfig } from '../src/config/types';
|
||||||
import { buildConfig as buildPayloadConfig } from '../src/config/build';
|
import { buildConfig as buildPayloadConfig } from '../src/config/build';
|
||||||
|
|
||||||
export function buildConfig(config?: Partial<Config>): SanitizedConfig {
|
export function buildConfig(config?: Partial<Config>): Promise<SanitizedConfig> {
|
||||||
const [name] = process.argv.slice(2);
|
const [name] = process.argv.slice(2);
|
||||||
const baseConfig: Config = {
|
const baseConfig: Config = {
|
||||||
telemetry: false,
|
telemetry: false,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import type { CollectionConfig } from '../../src/collections/config/types';
|
import type { CollectionConfig } from '../../src/collections/config/types';
|
||||||
import { devUser } from '../credentials';
|
import { devUser } from '../credentials';
|
||||||
import { buildConfig } from '../buildConfig';
|
import { buildConfig } from '../buildConfig';
|
||||||
import type { Post } from './payload-types';
|
|
||||||
|
|
||||||
export interface Relation {
|
export interface Relation {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -88,20 +87,20 @@ export default buildConfig({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await payload.create<Post>({
|
await payload.create({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
data: {
|
data: {
|
||||||
title: 'post1',
|
title: 'post1',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await payload.create<Post>({
|
await payload.create({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
data: {
|
data: {
|
||||||
title: 'post2',
|
title: 'post2',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await payload.create<Post>({
|
await payload.create({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
data: {
|
data: {
|
||||||
title: 'with-description',
|
title: 'with-description',
|
||||||
@@ -109,14 +108,14 @@ export default buildConfig({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await payload.create<Post>({
|
await payload.create({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
data: {
|
data: {
|
||||||
title: 'numPost1',
|
title: 'numPost1',
|
||||||
number: 1,
|
number: 1,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await payload.create<Post>({
|
await payload.create({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
data: {
|
data: {
|
||||||
title: 'numPost2',
|
title: 'numPost2',
|
||||||
@@ -124,13 +123,13 @@ export default buildConfig({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const rel1 = await payload.create<Relation>({
|
const rel1 = await payload.create({
|
||||||
collection: relationSlug,
|
collection: relationSlug,
|
||||||
data: {
|
data: {
|
||||||
name: 'name',
|
name: 'name',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const rel2 = await payload.create<Relation>({
|
const rel2 = await payload.create({
|
||||||
collection: relationSlug,
|
collection: relationSlug,
|
||||||
data: {
|
data: {
|
||||||
name: 'name2',
|
name: 'name2',
|
||||||
@@ -138,14 +137,14 @@ export default buildConfig({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Relation - hasMany
|
// Relation - hasMany
|
||||||
await payload.create<Post>({
|
await payload.create({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
data: {
|
data: {
|
||||||
title: 'rel to hasMany',
|
title: 'rel to hasMany',
|
||||||
relationHasManyField: rel1.id,
|
relationHasManyField: rel1.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await payload.create<Post>({
|
await payload.create({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
data: {
|
data: {
|
||||||
title: 'rel to hasMany 2',
|
title: 'rel to hasMany 2',
|
||||||
@@ -154,7 +153,7 @@ export default buildConfig({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Relation - relationTo multi
|
// Relation - relationTo multi
|
||||||
await payload.create<Post>({
|
await payload.create({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
data: {
|
data: {
|
||||||
title: 'rel to multi',
|
title: 'rel to multi',
|
||||||
@@ -166,7 +165,7 @@ export default buildConfig({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Relation - relationTo multi hasMany
|
// Relation - relationTo multi hasMany
|
||||||
await payload.create<Post>({
|
await payload.create({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
data: {
|
data: {
|
||||||
title: 'rel to multi hasMany',
|
title: 'rel to multi hasMany',
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import { GraphQLClient } from 'graphql-request';
|
import { GraphQLClient } from 'graphql-request';
|
||||||
import { initPayloadTest } from '../helpers/configHelpers';
|
import { initPayloadTest } from '../helpers/configHelpers';
|
||||||
import config from './config';
|
import configPromise from './config';
|
||||||
import payload from '../../src';
|
import payload from '../../src';
|
||||||
import type { Post } from './payload-types';
|
import type { Post } from './payload-types';
|
||||||
|
|
||||||
const slug = config.collections[0]?.slug;
|
let slug = '';
|
||||||
const title = 'title';
|
const title = 'title';
|
||||||
|
|
||||||
let client: GraphQLClient;
|
let client: GraphQLClient;
|
||||||
@@ -13,6 +13,8 @@ let client: GraphQLClient;
|
|||||||
describe('collections-graphql', () => {
|
describe('collections-graphql', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } });
|
const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } });
|
||||||
|
const config = await configPromise;
|
||||||
|
slug = config.collections[0]?.slug;
|
||||||
const url = `${serverURL}${config.routes.api}${config.routes.graphQL}`;
|
const url = `${serverURL}${config.routes.api}${config.routes.graphQL}`;
|
||||||
client = new GraphQLClient(url);
|
client = new GraphQLClient(url);
|
||||||
});
|
});
|
||||||
@@ -354,7 +356,7 @@ describe('collections-graphql', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
async function createPost(overrides?: Partial<Post>) {
|
async function createPost(overrides?: Partial<Post>) {
|
||||||
const doc = await payload.create<Post>({
|
const doc = await payload.create({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
data: { title: 'title', ...overrides },
|
data: { title: 'title', ...overrides },
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import type { CollectionConfig } from '../../src/collections/config/types';
|
import type { CollectionConfig } from '../../src/collections/config/types';
|
||||||
import { devUser } from '../credentials';
|
import { devUser } from '../credentials';
|
||||||
import { buildConfig } from '../buildConfig';
|
import { buildConfig } from '../buildConfig';
|
||||||
import type { Post } from './payload-types';
|
|
||||||
|
|
||||||
export interface Relation {
|
export interface Relation {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -135,13 +134,13 @@ export default buildConfig({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const rel1 = await payload.create<Relation>({
|
const rel1 = await payload.create({
|
||||||
collection: relationSlug,
|
collection: relationSlug,
|
||||||
data: {
|
data: {
|
||||||
name: 'name',
|
name: 'name',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const rel2 = await payload.create<Relation>({
|
const rel2 = await payload.create({
|
||||||
collection: relationSlug,
|
collection: relationSlug,
|
||||||
data: {
|
data: {
|
||||||
name: 'name2',
|
name: 'name2',
|
||||||
@@ -156,14 +155,14 @@ export default buildConfig({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Relation - hasMany
|
// Relation - hasMany
|
||||||
await payload.create<Post>({
|
await payload.create({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
data: {
|
data: {
|
||||||
title: 'rel to hasMany',
|
title: 'rel to hasMany',
|
||||||
relationHasManyField: rel1.id,
|
relationHasManyField: rel1.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await payload.create<Post>({
|
await payload.create({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
data: {
|
data: {
|
||||||
title: 'rel to hasMany 2',
|
title: 'rel to hasMany 2',
|
||||||
@@ -172,7 +171,7 @@ export default buildConfig({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Relation - relationTo multi
|
// Relation - relationTo multi
|
||||||
await payload.create<Post>({
|
await payload.create({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
data: {
|
data: {
|
||||||
title: 'rel to multi',
|
title: 'rel to multi',
|
||||||
@@ -184,7 +183,7 @@ export default buildConfig({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Relation - relationTo multi hasMany
|
// Relation - relationTo multi hasMany
|
||||||
await payload.create<Post>({
|
await payload.create({
|
||||||
collection: slug,
|
collection: slug,
|
||||||
data: {
|
data: {
|
||||||
title: 'rel to multi hasMany',
|
title: 'rel to multi hasMany',
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import type { IndexDirection, IndexOptions } from 'mongoose';
|
import type { IndexDirection, IndexOptions } from 'mongoose';
|
||||||
import { initPayloadTest } from '../helpers/configHelpers';
|
import { initPayloadTest } from '../helpers/configHelpers';
|
||||||
import { RESTClient } from '../helpers/rest';
|
import { RESTClient } from '../helpers/rest';
|
||||||
import config from '../uploads/config';
|
import configPromise from '../uploads/config';
|
||||||
import payload from '../../src';
|
import payload from '../../src';
|
||||||
import { pointDoc } from './collections/Point';
|
import { pointDoc } from './collections/Point';
|
||||||
import type { ArrayField, GroupField, TabsField } from './payload-types';
|
|
||||||
import { arrayFieldsSlug, arrayDefaultValue, arrayDoc } from './collections/Array';
|
import { arrayFieldsSlug, arrayDefaultValue, arrayDoc } from './collections/Array';
|
||||||
import { groupFieldsSlug, groupDefaultChild, groupDefaultValue, groupDoc } from './collections/Group';
|
import { groupFieldsSlug, groupDefaultChild, groupDefaultValue, groupDoc } from './collections/Group';
|
||||||
import { defaultText } from './collections/Text';
|
import { defaultText } from './collections/Text';
|
||||||
@@ -17,6 +16,7 @@ let client;
|
|||||||
describe('Fields', () => {
|
describe('Fields', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } });
|
const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } });
|
||||||
|
const config = await configPromise;
|
||||||
client = new RESTClient(config, { serverURL, defaultSlug: 'point-fields' });
|
client = new RESTClient(config, { serverURL, defaultSlug: 'point-fields' });
|
||||||
await client.login();
|
await client.login();
|
||||||
});
|
});
|
||||||
@@ -268,14 +268,14 @@ describe('Fields', () => {
|
|||||||
const collection = arrayFieldsSlug;
|
const collection = arrayFieldsSlug;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
doc = await payload.create<ArrayField>({
|
doc = await payload.create({
|
||||||
collection,
|
collection,
|
||||||
data: {},
|
data: {},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return undefined arrays when no data present', async () => {
|
it('should return undefined arrays when no data present', async () => {
|
||||||
const document = await payload.create<ArrayField>({
|
const document = await payload.create({
|
||||||
collection: arrayFieldsSlug,
|
collection: arrayFieldsSlug,
|
||||||
data: arrayDoc,
|
data: arrayDoc,
|
||||||
});
|
});
|
||||||
@@ -284,7 +284,7 @@ describe('Fields', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should create with ids and nested ids', async () => {
|
it('should create with ids and nested ids', async () => {
|
||||||
const docWithIDs = await payload.create<GroupField>({
|
const docWithIDs = await payload.create({
|
||||||
collection: groupFieldsSlug,
|
collection: groupFieldsSlug,
|
||||||
data: groupDoc,
|
data: groupDoc,
|
||||||
});
|
});
|
||||||
@@ -300,14 +300,14 @@ describe('Fields', () => {
|
|||||||
const localized = [{ text: 'unique' }];
|
const localized = [{ text: 'unique' }];
|
||||||
const enText = 'english';
|
const enText = 'english';
|
||||||
const esText = 'spanish';
|
const esText = 'spanish';
|
||||||
const { id } = await payload.create<ArrayField>({
|
const { id } = await payload.create({
|
||||||
collection,
|
collection,
|
||||||
data: {
|
data: {
|
||||||
localized,
|
localized,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const enDoc = await payload.update<ArrayField>({
|
const enDoc = await payload.update({
|
||||||
collection,
|
collection,
|
||||||
id,
|
id,
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
@@ -316,7 +316,7 @@ describe('Fields', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const esDoc = await payload.update<ArrayField>({
|
const esDoc = await payload.update({
|
||||||
collection,
|
collection,
|
||||||
id,
|
id,
|
||||||
locale: 'es',
|
locale: 'es',
|
||||||
@@ -342,7 +342,7 @@ describe('Fields', () => {
|
|||||||
let document;
|
let document;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
document = await payload.create<GroupField>({
|
document = await payload.create({
|
||||||
collection: groupFieldsSlug,
|
collection: groupFieldsSlug,
|
||||||
data: {},
|
data: {},
|
||||||
});
|
});
|
||||||
@@ -358,7 +358,7 @@ describe('Fields', () => {
|
|||||||
let document;
|
let document;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
document = await payload.create<TabsField>({
|
document = await payload.create({
|
||||||
collection: tabsSlug,
|
collection: tabsSlug,
|
||||||
data: tabsDoc,
|
data: tabsDoc,
|
||||||
});
|
});
|
||||||
@@ -395,7 +395,7 @@ describe('Fields', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should allow hooks on a named tab', async () => {
|
it('should allow hooks on a named tab', async () => {
|
||||||
const newDocument = await payload.create<TabsField>({
|
const newDocument = await payload.create({
|
||||||
collection: tabsSlug,
|
collection: tabsSlug,
|
||||||
data: tabsDoc,
|
data: tabsDoc,
|
||||||
});
|
});
|
||||||
@@ -406,7 +406,7 @@ describe('Fields', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return empty object for groups when no data present', async () => {
|
it('should return empty object for groups when no data present', async () => {
|
||||||
const doc = await payload.create<GroupField>({
|
const doc = await payload.create({
|
||||||
collection: groupFieldsSlug,
|
collection: groupFieldsSlug,
|
||||||
data: groupDoc,
|
data: groupDoc,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { GraphQLClient } from 'graphql-request';
|
import { GraphQLClient } from 'graphql-request';
|
||||||
import { initPayloadTest } from '../helpers/configHelpers';
|
import { initPayloadTest } from '../helpers/configHelpers';
|
||||||
import config, { arraySlug, englishLocale, slug, spanishLocale } from './config';
|
import configPromise, { arraySlug, englishLocale, slug, spanishLocale } from './config';
|
||||||
import payload from '../../src';
|
import payload from '../../src';
|
||||||
import { RESTClient } from '../helpers/rest';
|
import { RESTClient } from '../helpers/rest';
|
||||||
|
|
||||||
@@ -13,6 +13,7 @@ describe('globals', () => {
|
|||||||
describe('REST', () => {
|
describe('REST', () => {
|
||||||
let client: RESTClient;
|
let client: RESTClient;
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
|
const config = await configPromise;
|
||||||
client = new RESTClient(config, { serverURL, defaultSlug: slug });
|
client = new RESTClient(config, { serverURL, defaultSlug: slug });
|
||||||
});
|
});
|
||||||
it('should create', async () => {
|
it('should create', async () => {
|
||||||
@@ -135,6 +136,7 @@ describe('globals', () => {
|
|||||||
describe('graphql', () => {
|
describe('graphql', () => {
|
||||||
let client: GraphQLClient;
|
let client: GraphQLClient;
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
|
const config = await configPromise;
|
||||||
const url = `${serverURL}${config.routes.api}${config.routes.graphQL}`;
|
const url = `${serverURL}${config.routes.api}${config.routes.graphQL}`;
|
||||||
client = new GraphQLClient(url);
|
client = new GraphQLClient(url);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ export class RESTClient {
|
|||||||
return { status, doc: result };
|
return { status, doc: result };
|
||||||
}
|
}
|
||||||
|
|
||||||
async endpoint<T = any>(path: string, method = 'get', params = undefined): Promise<{ status: number, data: T }> {
|
async endpoint<T = any>(path: string, method = 'get', params: any = undefined): Promise<{ status: number, data: T }> {
|
||||||
const response = await fetch(`${this.serverURL}${path}`, {
|
const response = await fetch(`${this.serverURL}${path}`, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import type {
|
|||||||
GlobalArray,
|
GlobalArray,
|
||||||
} from './payload-types';
|
} from './payload-types';
|
||||||
import type { LocalizedPostAllLocale } from './config';
|
import type { LocalizedPostAllLocale } from './config';
|
||||||
import config, { relationshipLocalizedSlug, slug, withLocalizedRelSlug, withRequiredLocalizedFields } from './config';
|
import configPromise, { relationshipLocalizedSlug, slug, withLocalizedRelSlug, withRequiredLocalizedFields } from './config';
|
||||||
import {
|
import {
|
||||||
defaultLocale,
|
defaultLocale,
|
||||||
englishTitle,
|
englishTitle,
|
||||||
@@ -23,8 +23,10 @@ import {
|
|||||||
} from './shared';
|
} from './shared';
|
||||||
import type { Where } from '../../src/types';
|
import type { Where } from '../../src/types';
|
||||||
import { arrayCollectionSlug } from './collections/Array';
|
import { arrayCollectionSlug } from './collections/Array';
|
||||||
|
import type { Config } from '../../src/config/types';
|
||||||
|
|
||||||
const collection = slug;
|
const collection = slug;
|
||||||
|
let config: Config;
|
||||||
|
|
||||||
let serverURL;
|
let serverURL;
|
||||||
|
|
||||||
@@ -34,6 +36,7 @@ describe('Localization', () => {
|
|||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
({ serverURL } = await initPayloadTest({ __dirname, init: { local: false } }));
|
({ serverURL } = await initPayloadTest({ __dirname, init: { local: false } }));
|
||||||
|
config = await configPromise;
|
||||||
|
|
||||||
post1 = await payload.create({
|
post1 = await payload.create({
|
||||||
collection,
|
collection,
|
||||||
@@ -49,7 +52,7 @@ describe('Localization', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await payload.update<LocalizedPost>({
|
await payload.update({
|
||||||
collection,
|
collection,
|
||||||
id: postWithLocalizedData.id,
|
id: postWithLocalizedData.id,
|
||||||
locale: spanishLocale,
|
locale: spanishLocale,
|
||||||
@@ -67,7 +70,7 @@ describe('Localization', () => {
|
|||||||
|
|
||||||
describe('localized text', () => {
|
describe('localized text', () => {
|
||||||
it('create english', async () => {
|
it('create english', async () => {
|
||||||
const allDocs = await payload.find<LocalizedPost>({
|
const allDocs = await payload.find({
|
||||||
collection,
|
collection,
|
||||||
where: {
|
where: {
|
||||||
title: { equals: post1.title },
|
title: { equals: post1.title },
|
||||||
@@ -77,7 +80,7 @@ describe('Localization', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('add spanish translation', async () => {
|
it('add spanish translation', async () => {
|
||||||
const updated = await payload.update<LocalizedPost>({
|
const updated = await payload.update({
|
||||||
collection,
|
collection,
|
||||||
id: post1.id,
|
id: post1.id,
|
||||||
locale: spanishLocale,
|
locale: spanishLocale,
|
||||||
@@ -88,7 +91,7 @@ describe('Localization', () => {
|
|||||||
|
|
||||||
expect(updated.title).toEqual(spanishTitle);
|
expect(updated.title).toEqual(spanishTitle);
|
||||||
|
|
||||||
const localized = await payload.findByID<LocalizedPostAllLocale>({
|
const localized = await payload.findByID({
|
||||||
collection,
|
collection,
|
||||||
id: post1.id,
|
id: post1.id,
|
||||||
locale: 'all',
|
locale: 'all',
|
||||||
@@ -99,7 +102,7 @@ describe('Localization', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should fallback to english translation when empty', async () => {
|
it('should fallback to english translation when empty', async () => {
|
||||||
const updated = await payload.update<LocalizedPost>({
|
const updated = await payload.update({
|
||||||
collection,
|
collection,
|
||||||
id: post1.id,
|
id: post1.id,
|
||||||
locale: spanishLocale,
|
locale: spanishLocale,
|
||||||
@@ -110,7 +113,7 @@ describe('Localization', () => {
|
|||||||
|
|
||||||
expect(updated.title).toEqual(englishTitle);
|
expect(updated.title).toEqual(englishTitle);
|
||||||
|
|
||||||
const localizedFallback = await payload.findByID<LocalizedPostAllLocale>({
|
const localizedFallback = await payload.findByID({
|
||||||
collection,
|
collection,
|
||||||
id: post1.id,
|
id: post1.id,
|
||||||
locale: 'all',
|
locale: 'all',
|
||||||
@@ -123,14 +126,14 @@ describe('Localization', () => {
|
|||||||
describe('querying', () => {
|
describe('querying', () => {
|
||||||
let localizedPost: LocalizedPost;
|
let localizedPost: LocalizedPost;
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const { id } = await payload.create<LocalizedPost>({
|
const { id } = await payload.create({
|
||||||
collection,
|
collection,
|
||||||
data: {
|
data: {
|
||||||
title: englishTitle,
|
title: englishTitle,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
localizedPost = await payload.update<LocalizedPost>({
|
localizedPost = await payload.update({
|
||||||
collection,
|
collection,
|
||||||
id,
|
id,
|
||||||
locale: spanishLocale,
|
locale: spanishLocale,
|
||||||
@@ -170,7 +173,7 @@ describe('Localization', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('all locales', async () => {
|
it('all locales', async () => {
|
||||||
const localized = await payload.findByID<LocalizedPostAllLocale>({
|
const localized = await payload.findByID({
|
||||||
collection,
|
collection,
|
||||||
locale: 'all',
|
locale: 'all',
|
||||||
id: localizedPost.id,
|
id: localizedPost.id,
|
||||||
@@ -181,7 +184,7 @@ describe('Localization', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('by localized field value - default locale', async () => {
|
it('by localized field value - default locale', async () => {
|
||||||
const result = await payload.find<LocalizedPost>({
|
const result = await payload.find({
|
||||||
collection,
|
collection,
|
||||||
where: {
|
where: {
|
||||||
title: {
|
title: {
|
||||||
@@ -194,7 +197,7 @@ describe('Localization', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('by localized field value - alternate locale', async () => {
|
it('by localized field value - alternate locale', async () => {
|
||||||
const result = await payload.find<LocalizedPost>({
|
const result = await payload.find({
|
||||||
collection,
|
collection,
|
||||||
locale: spanishLocale,
|
locale: spanishLocale,
|
||||||
where: {
|
where: {
|
||||||
@@ -208,7 +211,7 @@ describe('Localization', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('by localized field value - opposite locale???', async () => {
|
it('by localized field value - opposite locale???', async () => {
|
||||||
const result = await payload.find<LocalizedPost>({
|
const result = await payload.find({
|
||||||
collection,
|
collection,
|
||||||
locale: 'all',
|
locale: 'all',
|
||||||
where: {
|
where: {
|
||||||
@@ -258,7 +261,7 @@ describe('Localization', () => {
|
|||||||
|
|
||||||
describe('regular relationship', () => {
|
describe('regular relationship', () => {
|
||||||
it('can query localized relationship', async () => {
|
it('can query localized relationship', async () => {
|
||||||
const result = await payload.find<WithLocalizedRelationship>({
|
const result = await payload.find({
|
||||||
collection: withLocalizedRelSlug,
|
collection: withLocalizedRelSlug,
|
||||||
where: {
|
where: {
|
||||||
'localizedRelationship.title': {
|
'localizedRelationship.title': {
|
||||||
@@ -271,7 +274,7 @@ describe('Localization', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('specific locale', async () => {
|
it('specific locale', async () => {
|
||||||
const result = await payload.find<WithLocalizedRelationship>({
|
const result = await payload.find({
|
||||||
collection: withLocalizedRelSlug,
|
collection: withLocalizedRelSlug,
|
||||||
locale: spanishLocale,
|
locale: spanishLocale,
|
||||||
where: {
|
where: {
|
||||||
@@ -285,7 +288,7 @@ describe('Localization', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('all locales', async () => {
|
it('all locales', async () => {
|
||||||
const result = await payload.find<WithLocalizedRelationship>({
|
const result = await payload.find({
|
||||||
collection: withLocalizedRelSlug,
|
collection: withLocalizedRelSlug,
|
||||||
locale: 'all',
|
locale: 'all',
|
||||||
where: {
|
where: {
|
||||||
@@ -300,7 +303,7 @@ describe('Localization', () => {
|
|||||||
|
|
||||||
it('populates relationships with all locales', async () => {
|
it('populates relationships with all locales', async () => {
|
||||||
// the relationship fields themselves are localized on this collection
|
// the relationship fields themselves are localized on this collection
|
||||||
const result = await payload.find<RelationshipLocalized>({
|
const result = await payload.find({
|
||||||
collection: relationshipLocalizedSlug,
|
collection: relationshipLocalizedSlug,
|
||||||
locale: 'all',
|
locale: 'all',
|
||||||
depth: 1,
|
depth: 1,
|
||||||
@@ -314,7 +317,7 @@ describe('Localization', () => {
|
|||||||
|
|
||||||
describe('relationship - hasMany', () => {
|
describe('relationship - hasMany', () => {
|
||||||
it('default locale', async () => {
|
it('default locale', async () => {
|
||||||
const result = await payload.find<WithLocalizedRelationship>({
|
const result = await payload.find({
|
||||||
collection: withLocalizedRelSlug,
|
collection: withLocalizedRelSlug,
|
||||||
where: {
|
where: {
|
||||||
'localizedRelationHasManyField.title': {
|
'localizedRelationHasManyField.title': {
|
||||||
@@ -326,7 +329,7 @@ describe('Localization', () => {
|
|||||||
expect(result.docs[0].id).toEqual(withRelationship.id);
|
expect(result.docs[0].id).toEqual(withRelationship.id);
|
||||||
|
|
||||||
// Second relationship
|
// Second relationship
|
||||||
const result2 = await payload.find<WithLocalizedRelationship>({
|
const result2 = await payload.find({
|
||||||
collection: withLocalizedRelSlug,
|
collection: withLocalizedRelSlug,
|
||||||
where: {
|
where: {
|
||||||
'localizedRelationHasManyField.title': {
|
'localizedRelationHasManyField.title': {
|
||||||
@@ -339,7 +342,7 @@ describe('Localization', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('specific locale', async () => {
|
it('specific locale', async () => {
|
||||||
const result = await payload.find<WithLocalizedRelationship>({
|
const result = await payload.find({
|
||||||
collection: withLocalizedRelSlug,
|
collection: withLocalizedRelSlug,
|
||||||
locale: spanishLocale,
|
locale: spanishLocale,
|
||||||
where: {
|
where: {
|
||||||
@@ -352,7 +355,7 @@ describe('Localization', () => {
|
|||||||
expect(result.docs[0].id).toEqual(withRelationship.id);
|
expect(result.docs[0].id).toEqual(withRelationship.id);
|
||||||
|
|
||||||
// Second relationship
|
// Second relationship
|
||||||
const result2 = await payload.find<WithLocalizedRelationship>({
|
const result2 = await payload.find({
|
||||||
collection: withLocalizedRelSlug,
|
collection: withLocalizedRelSlug,
|
||||||
locale: spanishLocale,
|
locale: spanishLocale,
|
||||||
where: {
|
where: {
|
||||||
@@ -366,7 +369,7 @@ describe('Localization', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('relationship population uses locale', async () => {
|
it('relationship population uses locale', async () => {
|
||||||
const result = await payload.findByID<WithLocalizedRelationship>({
|
const result = await payload.findByID({
|
||||||
collection: withLocalizedRelSlug,
|
collection: withLocalizedRelSlug,
|
||||||
depth: 1,
|
depth: 1,
|
||||||
id: withRelationship.id,
|
id: withRelationship.id,
|
||||||
@@ -377,7 +380,7 @@ describe('Localization', () => {
|
|||||||
|
|
||||||
it('all locales', async () => {
|
it('all locales', async () => {
|
||||||
const queryRelation = (where: Where) => {
|
const queryRelation = (where: Where) => {
|
||||||
return payload.find<WithLocalizedRelationship>({
|
return payload.find({
|
||||||
collection: withLocalizedRelSlug,
|
collection: withLocalizedRelSlug,
|
||||||
locale: 'all',
|
locale: 'all',
|
||||||
where,
|
where,
|
||||||
@@ -423,7 +426,7 @@ describe('Localization', () => {
|
|||||||
|
|
||||||
describe('relationTo multi', () => {
|
describe('relationTo multi', () => {
|
||||||
it('by id', async () => {
|
it('by id', async () => {
|
||||||
const result = await payload.find<WithLocalizedRelationship>({
|
const result = await payload.find({
|
||||||
collection: withLocalizedRelSlug,
|
collection: withLocalizedRelSlug,
|
||||||
where: {
|
where: {
|
||||||
'localizedRelationMultiRelationTo.value': {
|
'localizedRelationMultiRelationTo.value': {
|
||||||
@@ -435,7 +438,7 @@ describe('Localization', () => {
|
|||||||
expect(result.docs[0].id).toEqual(withRelationship.id);
|
expect(result.docs[0].id).toEqual(withRelationship.id);
|
||||||
|
|
||||||
// Second relationship
|
// Second relationship
|
||||||
const result2 = await payload.find<WithLocalizedRelationship>({
|
const result2 = await payload.find({
|
||||||
collection: withLocalizedRelSlug,
|
collection: withLocalizedRelSlug,
|
||||||
locale: spanishLocale,
|
locale: spanishLocale,
|
||||||
where: {
|
where: {
|
||||||
@@ -451,7 +454,7 @@ describe('Localization', () => {
|
|||||||
|
|
||||||
describe('relationTo multi hasMany', () => {
|
describe('relationTo multi hasMany', () => {
|
||||||
it('by id', async () => {
|
it('by id', async () => {
|
||||||
const result = await payload.find<WithLocalizedRelationship>({
|
const result = await payload.find({
|
||||||
collection: withLocalizedRelSlug,
|
collection: withLocalizedRelSlug,
|
||||||
where: {
|
where: {
|
||||||
'localizedRelationMultiRelationToHasMany.value': {
|
'localizedRelationMultiRelationToHasMany.value': {
|
||||||
@@ -463,7 +466,7 @@ describe('Localization', () => {
|
|||||||
expect(result.docs[0].id).toEqual(withRelationship.id);
|
expect(result.docs[0].id).toEqual(withRelationship.id);
|
||||||
|
|
||||||
// First relationship - spanish locale
|
// First relationship - spanish locale
|
||||||
const result2 = await payload.find<WithLocalizedRelationship>({
|
const result2 = await payload.find({
|
||||||
collection: withLocalizedRelSlug,
|
collection: withLocalizedRelSlug,
|
||||||
locale: spanishLocale,
|
locale: spanishLocale,
|
||||||
where: {
|
where: {
|
||||||
@@ -476,7 +479,7 @@ describe('Localization', () => {
|
|||||||
expect(result2.docs[0].id).toEqual(withRelationship.id);
|
expect(result2.docs[0].id).toEqual(withRelationship.id);
|
||||||
|
|
||||||
// Second relationship
|
// Second relationship
|
||||||
const result3 = await payload.find<WithLocalizedRelationship>({
|
const result3 = await payload.find({
|
||||||
collection: withLocalizedRelSlug,
|
collection: withLocalizedRelSlug,
|
||||||
where: {
|
where: {
|
||||||
'localizedRelationMultiRelationToHasMany.value': {
|
'localizedRelationMultiRelationToHasMany.value': {
|
||||||
@@ -488,7 +491,7 @@ describe('Localization', () => {
|
|||||||
expect(result3.docs[0].id).toEqual(withRelationship.id);
|
expect(result3.docs[0].id).toEqual(withRelationship.id);
|
||||||
|
|
||||||
// Second relationship - spanish locale
|
// Second relationship - spanish locale
|
||||||
const result4 = await payload.find<WithLocalizedRelationship>({
|
const result4 = await payload.find({
|
||||||
collection: withLocalizedRelSlug,
|
collection: withLocalizedRelSlug,
|
||||||
where: {
|
where: {
|
||||||
'localizedRelationMultiRelationToHasMany.value': {
|
'localizedRelationMultiRelationToHasMany.value': {
|
||||||
@@ -504,7 +507,7 @@ describe('Localization', () => {
|
|||||||
|
|
||||||
describe('Localized - arrays with nested localized fields', () => {
|
describe('Localized - arrays with nested localized fields', () => {
|
||||||
it('should allow moving rows and retain existing row locale data', async () => {
|
it('should allow moving rows and retain existing row locale data', async () => {
|
||||||
const globalArray = await payload.findGlobal<GlobalArray>({
|
const globalArray = await payload.findGlobal({
|
||||||
slug: 'global-array',
|
slug: 'global-array',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -553,7 +556,7 @@ describe('Localization', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const updatedDoc = await payload.update<LocalizedRequired>({
|
const updatedDoc = await payload.update({
|
||||||
collection: withRequiredLocalizedFields,
|
collection: withRequiredLocalizedFields,
|
||||||
id: newDoc.id,
|
id: newDoc.id,
|
||||||
data: {
|
data: {
|
||||||
@@ -577,7 +580,7 @@ describe('Localization', () => {
|
|||||||
let token;
|
let token;
|
||||||
|
|
||||||
it('should allow user to login and retrieve populated localized field', async () => {
|
it('should allow user to login and retrieve populated localized field', async () => {
|
||||||
const url = `${serverURL}${config.routes.api}${config.routes.graphQL}?locale=en`;
|
const url = `${serverURL}${config?.routes?.api}${config?.routes?.graphQL}?locale=en`;
|
||||||
const client = new GraphQLClient(url);
|
const client = new GraphQLClient(url);
|
||||||
|
|
||||||
const query = `mutation {
|
const query = `mutation {
|
||||||
@@ -602,7 +605,7 @@ describe('Localization', () => {
|
|||||||
|
|
||||||
it('should allow retrieval of populated localized fields within meUser', async () => {
|
it('should allow retrieval of populated localized fields within meUser', async () => {
|
||||||
// Defining locale=en in graphQL string should not break JWT strategy
|
// Defining locale=en in graphQL string should not break JWT strategy
|
||||||
const url = `${serverURL}${config.routes.api}${config.routes.graphQL}?locale=en`;
|
const url = `${serverURL}${config?.routes?.api}${config?.routes?.graphQL}?locale=en`;
|
||||||
const client = new GraphQLClient(url);
|
const client = new GraphQLClient(url);
|
||||||
|
|
||||||
const query = `query {
|
const query = `query {
|
||||||
@@ -626,7 +629,7 @@ describe('Localization', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should create and update collections', async () => {
|
it('should create and update collections', async () => {
|
||||||
const url = `${serverURL}${config.routes.api}${config.routes.graphQL}`;
|
const url = `${serverURL}${config?.routes?.api}${config?.routes?.graphQL}`;
|
||||||
const client = new GraphQLClient(url);
|
const client = new GraphQLClient(url);
|
||||||
|
|
||||||
const create = `mutation {
|
const create = `mutation {
|
||||||
@@ -749,14 +752,14 @@ async function createLocalizedPost(data: {
|
|||||||
[spanishLocale]: string;
|
[spanishLocale]: string;
|
||||||
};
|
};
|
||||||
}): Promise<LocalizedPost> {
|
}): Promise<LocalizedPost> {
|
||||||
const localizedRelation = await payload.create<LocalizedPost>({
|
const localizedRelation = await payload.create({
|
||||||
collection,
|
collection,
|
||||||
data: {
|
data: {
|
||||||
title: data.title.en,
|
title: data.title.en,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await payload.update<LocalizedPost>({
|
await payload.update({
|
||||||
collection,
|
collection,
|
||||||
id: localizedRelation.id,
|
id: localizedRelation.id,
|
||||||
locale: spanishLocale,
|
locale: spanishLocale,
|
||||||
|
|||||||
1
test/plugins/.gitignore
vendored
Normal file
1
test/plugins/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
media
|
||||||
40
test/plugins/config.ts
Normal file
40
test/plugins/config.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { buildConfig } from '../buildConfig';
|
||||||
|
import { devUser } from '../credentials';
|
||||||
|
|
||||||
|
export const pagesSlug = 'pages';
|
||||||
|
|
||||||
|
export default buildConfig({
|
||||||
|
collections: [
|
||||||
|
{
|
||||||
|
slug: 'users',
|
||||||
|
auth: true,
|
||||||
|
fields: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
plugins: [
|
||||||
|
async (config) => ({
|
||||||
|
...config,
|
||||||
|
collections: [
|
||||||
|
...config.collections || [],
|
||||||
|
{
|
||||||
|
slug: pagesSlug,
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'title',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
onInit: async (payload) => {
|
||||||
|
await payload.create({
|
||||||
|
collection: 'users',
|
||||||
|
data: {
|
||||||
|
email: devUser.email,
|
||||||
|
password: devUser.password,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
0
test/plugins/e2e.todo-spec.ts
Normal file
0
test/plugins/e2e.todo-spec.ts
Normal file
28
test/plugins/int.spec.ts
Normal file
28
test/plugins/int.spec.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import { initPayloadTest } from '../helpers/configHelpers';
|
||||||
|
import { RESTClient } from '../helpers/rest';
|
||||||
|
import configPromise, { pagesSlug } from './config';
|
||||||
|
import payload from '../../src';
|
||||||
|
|
||||||
|
require('isomorphic-fetch');
|
||||||
|
|
||||||
|
let client;
|
||||||
|
|
||||||
|
describe('Collections - Plugins', () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } });
|
||||||
|
const config = await configPromise;
|
||||||
|
client = new RESTClient(config, { serverURL, defaultSlug: pagesSlug });
|
||||||
|
await client.login();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('created pages collection', async () => {
|
||||||
|
const { id } = await payload.create({
|
||||||
|
collection: pagesSlug,
|
||||||
|
data: {
|
||||||
|
title: 'Test Page',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(id).toEqual(expect.any(String));
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { request, GraphQLClient } from 'graphql-request';
|
import { request, GraphQLClient } from 'graphql-request';
|
||||||
import { initPayloadTest } from '../helpers/configHelpers';
|
import { initPayloadTest } from '../helpers/configHelpers';
|
||||||
import payload from '../../src';
|
import payload from '../../src';
|
||||||
import config from './config';
|
import configPromise from './config';
|
||||||
import AutosavePosts from './collections/Autosave';
|
import AutosavePosts from './collections/Autosave';
|
||||||
import AutosaveGlobal from './globals/Autosave';
|
import AutosaveGlobal from './globals/Autosave';
|
||||||
import { devUser } from '../credentials';
|
import { devUser } from '../credentials';
|
||||||
@@ -27,6 +27,8 @@ const globalGraphQLOriginalTitle = 'updated global title';
|
|||||||
|
|
||||||
describe('Versions', () => {
|
describe('Versions', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
|
const config = await configPromise;
|
||||||
|
|
||||||
const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } });
|
const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } });
|
||||||
graphQLURL = `${serverURL}${config.routes.api}${config.routes.graphQL}`;
|
graphQLURL = `${serverURL}${config.routes.api}${config.routes.graphQL}`;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user