Feat: multi content authoring (#4139)

This commit is contained in:
Erez Rokah
2020-09-20 10:30:46 -07:00
committed by GitHub
parent 7968e01e29
commit cb2ad687ee
65 changed files with 4331 additions and 1521 deletions

View File

@ -450,5 +450,59 @@ describe('config', () => {
);
}).not.toThrow();
});
describe('i18n', () => {
it('should throw error when locale has invalid characters', () => {
expect(() => {
validateConfig(
merge({}, validConfig, {
i18n: {
structure: 'multiple_folders',
locales: ['en', 'tr.TR'],
},
}),
);
}).toThrowError(`'i18n.locales[1]' should match pattern "^[a-zA-Z-_]+$"`);
});
it('should throw error when locale is less than 2 characters', () => {
expect(() => {
validateConfig(
merge({}, validConfig, {
i18n: {
structure: 'multiple_folders',
locales: ['en', 't'],
},
}),
);
}).toThrowError(`'i18n.locales[1]' should NOT be shorter than 2 characters`);
});
it('should throw error when locale is more than 10 characters', () => {
expect(() => {
validateConfig(
merge({}, validConfig, {
i18n: {
structure: 'multiple_folders',
locales: ['en', 'a_very_long_locale'],
},
}),
);
}).toThrowError(`'i18n.locales[1]' should NOT be longer than 10 characters`);
});
it('should allow valid locales strings', () => {
expect(() => {
validateConfig(
merge({}, validConfig, {
i18n: {
structure: 'multiple_folders',
locales: ['en', 'tr-TR', 'zh_CHS'],
},
}),
);
}).not.toThrow();
});
});
});
});

View File

@ -1,8 +1,43 @@
import AJV from 'ajv';
import { select, uniqueItemProperties, instanceof as instanceOf } from 'ajv-keywords/keywords';
import {
select,
uniqueItemProperties,
instanceof as instanceOf,
prohibited,
} from 'ajv-keywords/keywords';
import ajvErrors from 'ajv-errors';
import { formatExtensions, frontmatterFormats, extensionFormatters } from 'Formats/formats';
import { getWidgets } from 'Lib/registry';
import { I18N_STRUCTURE, I18N_FIELD } from '../lib/i18n';
const localeType = { type: 'string', minLength: 2, maxLength: 10, pattern: '^[a-zA-Z-_]+$' };
const i18n = {
type: 'object',
properties: {
structure: { type: 'string', enum: Object.values(I18N_STRUCTURE) },
locales: {
type: 'array',
minItems: 2,
items: localeType,
uniqueItems: true,
},
default_locale: localeType,
},
};
const i18nRoot = {
...i18n,
required: ['structure', 'locales'],
};
const i18nCollection = {
oneOf: [{ type: 'boolean' }, i18n],
};
const i18nField = {
oneOf: [{ type: 'boolean' }, { type: 'string', enum: Object.values(I18N_FIELD) }],
};
/**
* Config for fields in both file and folder collections.
@ -20,6 +55,7 @@ const fieldsConfig = () => ({
label: { type: 'string' },
widget: { type: 'string' },
required: { type: 'boolean' },
i18n: i18nField,
hint: { type: 'string' },
pattern: {
type: 'array',
@ -100,6 +136,7 @@ const getConfigSchema = () => ({
],
},
locale: { type: 'string', examples: ['en', 'fr', 'de'] },
i18n: i18nRoot,
site_url: { type: 'string', examples: ['https://example.com'] },
display_url: { type: 'string', examples: ['https://example.com'] },
logo_url: { type: 'string', examples: ['https://example.com/images/logo.svg'] },
@ -219,6 +256,7 @@ const getConfigSchema = () => ({
additionalProperties: false,
minProperties: 1,
},
i18n: i18nCollection,
},
required: ['name', 'label'],
oneOf: [{ required: ['files'] }, { required: ['folder', 'fields'] }],
@ -289,6 +327,7 @@ export function validateConfig(config) {
uniqueItemProperties(ajv);
select(ajv);
instanceOf(ajv);
prohibited(ajv);
ajvErrors(ajv);
const valid = ajv.validate(getConfigSchema(), config);