mirror of
https://github.com/strapi/strapi.git
synced 2025-12-29 08:04:51 +00:00
Update content-types
This commit is contained in:
parent
62837bf4ce
commit
877ccaa485
@ -5,6 +5,6 @@ module.exports = {
|
||||
transform: {
|
||||
'^.+\\.ts$': ['@swc/jest'],
|
||||
},
|
||||
testMatch: ['<rootDir>/**/*.test.js'],
|
||||
testMatch: ['<rootDir>/**/*.test.(j|t)s'],
|
||||
displayName: 'Core utils',
|
||||
};
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const { pipeAsync, mapAsync, reduceAsync } = require('../async');
|
||||
import { pipeAsync, mapAsync, reduceAsync } from '../async';
|
||||
|
||||
describe('Async utils', () => {
|
||||
describe('pipeAsync', () => {
|
||||
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
import {
|
||||
isPrivateAttribute,
|
||||
isTypedAttribute,
|
||||
getPrivateAttributes,
|
||||
@ -8,7 +6,7 @@ const {
|
||||
getNonWritableAttributes,
|
||||
getScalarAttributes,
|
||||
constants,
|
||||
} = require('../content-types');
|
||||
} from '../content-types';
|
||||
|
||||
const createModelWithPrivates = (privateAttributes = []) => ({
|
||||
uid: 'myModel',
|
||||
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const envHelper = require('../env-helper');
|
||||
import envHelper from '../env-helper';
|
||||
|
||||
describe('Env helper', () => {
|
||||
describe('env without cast', () => {
|
||||
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const hooks = require('../hooks');
|
||||
import * as hooks from '../hooks';
|
||||
|
||||
describe('Hooks Module', () => {
|
||||
describe('Internals', () => {
|
||||
@ -16,7 +14,7 @@ describe('Hooks Module', () => {
|
||||
|
||||
test('Call is not implemented by default', async () => {
|
||||
const hook = hooks.internals.createHook();
|
||||
const doCall = () => hook.call('foo');
|
||||
const doCall = () => hook.call();
|
||||
|
||||
expect(doCall).toThrowError('Method not implemented');
|
||||
});
|
||||
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const importDefault = require('../../import-default');
|
||||
import path from 'node:path';
|
||||
import importDefault from '../../import-default';
|
||||
|
||||
const getPath = (file) => path.resolve(__dirname, file);
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const { withDefaultPagination } = require('../pagination');
|
||||
import { withDefaultPagination } from '../pagination';
|
||||
|
||||
const defaultLimit = 20;
|
||||
const defaults = {
|
||||
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const format = require('date-fns/format');
|
||||
const parseType = require('../parse-type');
|
||||
import format from 'date-fns/format';
|
||||
import parseType from '../parse-type';
|
||||
|
||||
describe('parseType', () => {
|
||||
describe('boolean', () => {
|
||||
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const policyUtils = require('../policy');
|
||||
import * as policyUtils from '../policy';
|
||||
|
||||
describe('Policy util', () => {
|
||||
describe('Get policy', () => {
|
||||
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const providerFactory = require('../provider-factory');
|
||||
import providerFactory from '../provider-factory';
|
||||
|
||||
const providerMethods = [
|
||||
'register',
|
||||
@ -143,7 +141,7 @@ describe('Provider Factory', () => {
|
||||
|
||||
expect(provider.get(key)).toBe(item);
|
||||
|
||||
await provider.delete(key, item);
|
||||
await provider.delete(key);
|
||||
|
||||
expect(provider.get(key)).toBeUndefined();
|
||||
});
|
||||
@ -1,12 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
const { getRelationalFields } = require('../relations');
|
||||
import { getRelationalFields } from '../relations';
|
||||
|
||||
describe('Relations', () => {
|
||||
describe('getRelationalFields', () => {
|
||||
test('Attribute must have a type relation', () => {
|
||||
expect(
|
||||
getRelationalFields({
|
||||
kind: 'collectionType',
|
||||
info: {
|
||||
singularName: 'test',
|
||||
pluralName: 'test',
|
||||
},
|
||||
options: {
|
||||
populateCreatorFields: false,
|
||||
},
|
||||
attributes: {
|
||||
rel: {
|
||||
type: 'relation',
|
||||
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
import {
|
||||
escapeQuery,
|
||||
stringIncludes,
|
||||
stringEquals,
|
||||
@ -8,7 +6,7 @@ const {
|
||||
getCommonPath,
|
||||
toRegressedEnumValue,
|
||||
joinBy,
|
||||
} = require('../string-formatting');
|
||||
} from '../string-formatting';
|
||||
|
||||
describe('string-formatting', () => {
|
||||
describe('Escape Query', () => {
|
||||
@ -140,7 +138,8 @@ describe('string-formatting', () => {
|
||||
[['/', 'a//', '//b//', '//c'], 'a/b/c'],
|
||||
[['/', '///a///', '///b///', '///c///'], '///a/b/c///'],
|
||||
])('%s => %s', (args, expectedResult) => {
|
||||
expect(joinBy(...args)).toBe(expectedResult);
|
||||
const [joint, ...rest] = args;
|
||||
expect(joinBy(joint, ...rest)).toBe(expectedResult);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const { yup } = require('../validators');
|
||||
import { yup } from '../validators';
|
||||
|
||||
describe('validators', () => {
|
||||
describe('strapiID', () => {
|
||||
@ -1,8 +1,8 @@
|
||||
'use strict';
|
||||
import * as visitors from '../sanitize/visitors';
|
||||
import * as contentTypeUtils from '../content-types';
|
||||
import type { Model } from '../types';
|
||||
|
||||
const visitors = require('../sanitize/visitors');
|
||||
|
||||
const { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = require('../content-types').constants;
|
||||
const { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = contentTypeUtils.constants;
|
||||
|
||||
describe('Sanitize visitors util', () => {
|
||||
describe('removeRestrictedRelations', () => {
|
||||
@ -25,7 +25,20 @@ describe('Sanitize visitors util', () => {
|
||||
data,
|
||||
key,
|
||||
attribute,
|
||||
schema: { options: { populateCreatorFields: true } },
|
||||
schema: {
|
||||
kind: 'collectionType',
|
||||
info: {
|
||||
singularName: 'test',
|
||||
pluralName: 'tests',
|
||||
},
|
||||
options: { populateCreatorFields: true },
|
||||
attributes: {},
|
||||
},
|
||||
value: {},
|
||||
path: {
|
||||
attribute: null,
|
||||
raw: null,
|
||||
},
|
||||
},
|
||||
{ remove, set }
|
||||
);
|
||||
@ -45,7 +58,20 @@ describe('Sanitize visitors util', () => {
|
||||
data,
|
||||
key,
|
||||
attribute,
|
||||
schema: { options: { populateCreatorFields: false } },
|
||||
schema: {
|
||||
kind: 'collectionType',
|
||||
info: {
|
||||
singularName: 'test',
|
||||
pluralName: 'tests',
|
||||
},
|
||||
options: { populateCreatorFields: false },
|
||||
attributes: {},
|
||||
},
|
||||
value: {},
|
||||
path: {
|
||||
attribute: null,
|
||||
raw: null,
|
||||
},
|
||||
},
|
||||
{ remove, set }
|
||||
);
|
||||
@ -1,8 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const { yup } = require('../validators');
|
||||
const { formatYupErrors } = require('../format-yup-error');
|
||||
const { YupValidationError } = require('../errors');
|
||||
import { yup } from '../validators';
|
||||
import { formatYupErrors } from '../format-yup-error';
|
||||
import { YupValidationError } from '../errors';
|
||||
|
||||
describe('formatYupErrors', () => {
|
||||
test('Error message is sanitized', async () => {
|
||||
@ -1,56 +1,57 @@
|
||||
import pMap from 'p-map';
|
||||
import { curry, curryN } from 'lodash/fp';
|
||||
import type { CurriedFunction3 } from 'lodash';
|
||||
|
||||
interface MapOptions {
|
||||
concurrency?: number;
|
||||
}
|
||||
type AnyFunc = (...args: any) => any;
|
||||
|
||||
type MapFunc<T = unknown, R = unknown> = (element: T, index: number) => R | Promise<R>;
|
||||
type PipeArgs<F extends AnyFunc[], PrevReturn = Parameters<F[0]>[0]> = F extends [
|
||||
(arg: any) => infer B
|
||||
]
|
||||
? [(arg: PrevReturn) => B]
|
||||
: F extends [(arg: any) => infer B, ...infer Tail]
|
||||
? Tail extends AnyFunc[]
|
||||
? [(arg: PrevReturn) => B, ...PipeArgs<Tail, B>]
|
||||
: []
|
||||
: [];
|
||||
|
||||
export type ReduceAsync<T = unknown, V = T, R = V> = CurriedFunction3<
|
||||
T[],
|
||||
(accumulator: V | R, current: Awaited<T>, index: number) => R | Promise<R>,
|
||||
V,
|
||||
Promise<R>
|
||||
>;
|
||||
export function pipeAsync<F extends AnyFunc[], FirstFn extends F[0]>(
|
||||
...fns: PipeArgs<F> extends F ? F : PipeArgs<F>
|
||||
) {
|
||||
type Args = Parameters<FirstFn>;
|
||||
type ReturnT = F extends [...AnyFunc[], (...arg: any) => infer R]
|
||||
? R extends Promise<infer R>
|
||||
? R
|
||||
: R
|
||||
: never;
|
||||
|
||||
type CurriedMapAsync<T = unknown, R = unknown> = CurriedFunction3<
|
||||
T[],
|
||||
MapFunc<T, R>,
|
||||
MapOptions,
|
||||
Promise<R[]>
|
||||
>;
|
||||
const [firstFn, ...fnRest] = fns;
|
||||
|
||||
interface Method {
|
||||
(...args: any[]): any;
|
||||
}
|
||||
return async (...args: Args): Promise<ReturnT> => {
|
||||
let res: ReturnT = firstFn(args);
|
||||
|
||||
function pipeAsync(...methods: Method[]) {
|
||||
return async (data: unknown) => {
|
||||
let res = data;
|
||||
for (let i = 0; i < methods.length; i += 1) {
|
||||
res = await methods[i](res);
|
||||
for (let i = 0; i < fnRest.length; i += 1) {
|
||||
res = await fnRest[i](res);
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
const mapAsync: CurriedMapAsync = curry(pMap);
|
||||
export const mapAsync = curry(pMap);
|
||||
|
||||
const reduceAsync: ReduceAsync = curryN(2, async (mixedArray, iteratee, initialValue) => {
|
||||
let acc = initialValue;
|
||||
for (let i = 0; i < mixedArray.length; i += 1) {
|
||||
acc = await iteratee(acc, await mixedArray[i], i);
|
||||
}
|
||||
return acc;
|
||||
});
|
||||
export const reduceAsync =
|
||||
(mixedArray: any[]) =>
|
||||
async <T>(iteratee: AnyFunc, initialValue?: T) => {
|
||||
let acc = initialValue;
|
||||
for (let i = 0; i < mixedArray.length; i += 1) {
|
||||
acc = await iteratee(acc, await mixedArray[i], i);
|
||||
}
|
||||
return acc;
|
||||
};
|
||||
|
||||
const forEachAsync = curry(
|
||||
async <T = unknown, R = unknown>(array: T[], func: MapFunc<T, R>, options: MapOptions) => {
|
||||
await mapAsync(array, func, options);
|
||||
}
|
||||
);
|
||||
|
||||
export { mapAsync, reduceAsync, forEachAsync, pipeAsync };
|
||||
export const forEachAsync = async <T, R>(
|
||||
array: T[],
|
||||
func: pMap.Mapper<T, R>,
|
||||
options: pMap.Options
|
||||
) => {
|
||||
await pMap(array, func, options);
|
||||
};
|
||||
|
||||
@ -101,20 +101,20 @@ const isSingleType = ({ kind = COLLECTION_TYPE }) => kind === SINGLE_TYPE;
|
||||
const isCollectionType = ({ kind = COLLECTION_TYPE }) => kind === COLLECTION_TYPE;
|
||||
const isKind = (kind: Kind) => (model: Model) => model.kind === kind;
|
||||
|
||||
const getStoredPrivateAttributes = (model) =>
|
||||
const getStoredPrivateAttributes = (model: Model) =>
|
||||
union(
|
||||
strapi?.config?.get('api.responses.privateAttributes', []) ?? [],
|
||||
(strapi?.config?.get('api.responses.privateAttributes', []) ?? []) as Array<string>,
|
||||
getOr([], 'options.privateAttributes', model)
|
||||
);
|
||||
|
||||
const getPrivateAttributes = (model = {}) => {
|
||||
const getPrivateAttributes = (model: Model) => {
|
||||
return _.union(
|
||||
getStoredPrivateAttributes(model),
|
||||
_.keys(_.pickBy(model.attributes, (attr) => !!attr.private))
|
||||
);
|
||||
};
|
||||
|
||||
const isPrivateAttribute = (model, attributeName) => {
|
||||
const isPrivateAttribute = (model: Model, attributeName: string) => {
|
||||
if (model?.attributes?.[attributeName]?.private === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -34,16 +34,16 @@ const { PUBLISHED_AT_ATTRIBUTE } = contentTypesUtils.constants;
|
||||
|
||||
type SortOrder = 'asc' | 'desc';
|
||||
|
||||
interface SortMap {
|
||||
export interface SortMap {
|
||||
[key: string]: SortOrder | SortMap;
|
||||
}
|
||||
|
||||
type SortQuery = string | string[] | object;
|
||||
|
||||
type FieldsQuery = string | string[];
|
||||
interface FiltersQuery {}
|
||||
|
||||
type PopulateParams = {
|
||||
export interface FiltersQuery {}
|
||||
|
||||
export interface PopulateParams {
|
||||
sort?: SortQuery;
|
||||
fields?: FieldsQuery;
|
||||
filters?: FiltersQuery;
|
||||
@ -51,11 +51,11 @@ type PopulateParams = {
|
||||
on: {
|
||||
[key: string]: PopulateParams;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
type PopulateQuery = string | string[] | PopulateParams;
|
||||
type PopulateQuery = boolean | string | string[] | PopulateParams;
|
||||
|
||||
interface Query {
|
||||
export interface Query {
|
||||
sort?: SortQuery;
|
||||
fields?: FieldsQuery;
|
||||
filters?: FiltersQuery;
|
||||
@ -67,15 +67,18 @@ interface Query {
|
||||
start?: number | string;
|
||||
page?: number | string;
|
||||
pageSize?: number | string;
|
||||
publicationState?: 'live' | 'preview';
|
||||
}
|
||||
|
||||
interface ConvertedQuery {
|
||||
export interface ConvertedQuery {
|
||||
orderBy?: SortQuery;
|
||||
select?: FieldsQuery;
|
||||
where?: FiltersQuery;
|
||||
// NOTE: those are internal DB filters do not modify
|
||||
filters?: any;
|
||||
populate?: PopulateQuery;
|
||||
count: boolean;
|
||||
ordering: unknown;
|
||||
count?: boolean;
|
||||
ordering?: unknown;
|
||||
_q?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
@ -248,7 +251,11 @@ class InvalidPopulateError extends Error {
|
||||
}
|
||||
|
||||
// NOTE: we could support foo.* or foo.bar.* etc later on
|
||||
const convertPopulateQueryParams = (populate: PopulateQuery, schema: Model, depth = 0) => {
|
||||
const convertPopulateQueryParams = (
|
||||
populate: PopulateQuery,
|
||||
schema: Model,
|
||||
depth = 0
|
||||
): PopulateQuery => {
|
||||
if (depth === 0 && populate === '*') {
|
||||
return true;
|
||||
}
|
||||
@ -539,8 +546,12 @@ const convertAndSanitizeFilters = (filters: FiltersQuery, schema: Model) => {
|
||||
return filters;
|
||||
};
|
||||
|
||||
const convertPublicationStateParams = (type, params = {}, query = {}) => {
|
||||
if (!type) {
|
||||
const convertPublicationStateParams = (
|
||||
schema: Model,
|
||||
params: { publicationState?: 'live' | 'preview' } = {},
|
||||
query: ConvertedQuery = {}
|
||||
) => {
|
||||
if (!schema) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -554,7 +565,7 @@ const convertPublicationStateParams = (type, params = {}, query = {}) => {
|
||||
}
|
||||
|
||||
// NOTE: this is the query layer filters not the entity service filters
|
||||
query.filters = ({ meta }) => {
|
||||
query.filters = ({ meta }: { meta: Model }) => {
|
||||
if (publicationState === 'live' && has(PUBLISHED_AT_ATTRIBUTE, meta.attributes)) {
|
||||
return { [PUBLISHED_AT_ATTRIBUTE]: { $notNull: true } };
|
||||
}
|
||||
@ -613,7 +624,7 @@ const transformParamsToQuery = (uid: string, params: Query) => {
|
||||
return query;
|
||||
};
|
||||
|
||||
export = {
|
||||
export default {
|
||||
convertSortQueryParams,
|
||||
convertStartQueryParams,
|
||||
convertLimitQueryParams,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
|
||||
function env<T>(key: string, defaultValue?: T): string | T | undefined {
|
||||
function envFn<T>(key: string, defaultValue?: T): string | T | undefined {
|
||||
return _.has(process.env, key) ? process.env[key] : defaultValue;
|
||||
}
|
||||
|
||||
@ -9,24 +9,24 @@ function getKey(key: string) {
|
||||
}
|
||||
|
||||
const utils = {
|
||||
int(key: string, defaultValue?: number): number {
|
||||
if (!_.has(process.env, key) && defaultValue) {
|
||||
int(key: string, defaultValue?: number): number | undefined {
|
||||
if (!_.has(process.env, key)) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return parseInt(getKey(key), 10);
|
||||
},
|
||||
|
||||
float(key: string, defaultValue?: number): number {
|
||||
if (!_.has(process.env, key) && defaultValue) {
|
||||
float(key: string, defaultValue?: number): number | undefined {
|
||||
if (!_.has(process.env, key)) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return parseFloat(getKey(key));
|
||||
},
|
||||
|
||||
bool(key: string, defaultValue?: boolean): boolean {
|
||||
if (!_.has(process.env, key) && defaultValue) {
|
||||
bool(key: string, defaultValue?: boolean): boolean | undefined {
|
||||
if (!_.has(process.env, key)) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ const utils = {
|
||||
},
|
||||
|
||||
json(key: string, defaultValue?: object) {
|
||||
if (!_.has(process.env, key) && defaultValue) {
|
||||
if (!_.has(process.env, key)) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@ -49,8 +49,8 @@ const utils = {
|
||||
}
|
||||
},
|
||||
|
||||
array(key: string, defaultValue?: string[]): string[] {
|
||||
if (!_.has(process.env, key) && defaultValue) {
|
||||
array(key: string, defaultValue?: string[]): string[] | undefined {
|
||||
if (!_.has(process.env, key)) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@ -65,8 +65,8 @@ const utils = {
|
||||
});
|
||||
},
|
||||
|
||||
date(key: string, defaultValue?: Date): Date {
|
||||
if (!_.has(process.env, key) && defaultValue) {
|
||||
date(key: string, defaultValue?: Date): Date | undefined {
|
||||
if (!_.has(process.env, key)) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@ -94,6 +94,6 @@ const utils = {
|
||||
},
|
||||
};
|
||||
|
||||
Object.assign(env, utils);
|
||||
const env = Object.assign(envFn, utils);
|
||||
|
||||
export = env;
|
||||
export default env;
|
||||
|
||||
@ -24,7 +24,7 @@ class ValidationError extends ApplicationError {
|
||||
}
|
||||
|
||||
class YupValidationError extends ValidationError {
|
||||
constructor(yupError: yup.ValidationError, message: string) {
|
||||
constructor(yupError: yup.ValidationError, message?: string) {
|
||||
super('Validation');
|
||||
const { errors, message: yupMessage } = formatYupErrors(yupError);
|
||||
this.message = message || yupMessage;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
|
||||
export = function importDefault(modName: string) {
|
||||
export default function importDefault(modName: string) {
|
||||
const mod = require(modName);
|
||||
return mod && mod.__esModule ? mod.default : mod;
|
||||
};
|
||||
|
||||
@ -1,16 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Export shared utilities
|
||||
*/
|
||||
const { buildQuery, hasDeepFilters } = require('./build-query');
|
||||
const parseMultipartData = require('./parse-multipart');
|
||||
const parseType = require('./parse-type');
|
||||
const policy = require('./policy');
|
||||
const templateConfiguration = require('./template-configuration');
|
||||
const { yup, handleYupError, validateYupSchema, validateYupSchemaSync } = require('./validators');
|
||||
const errors = require('./errors');
|
||||
const {
|
||||
import parseMultipartData from './parse-multipart';
|
||||
import parseType from './parse-type';
|
||||
import * as policy from './policy';
|
||||
import templateConfiguration from './template-configuration';
|
||||
import { yup, handleYupError, validateYupSchema, validateYupSchemaSync } from './validators';
|
||||
import * as errors from './errors';
|
||||
import {
|
||||
nameToSlug,
|
||||
nameToCollectionName,
|
||||
getCommonBeginning,
|
||||
@ -23,33 +20,31 @@ const {
|
||||
startsWithANumber,
|
||||
joinBy,
|
||||
toKebabCase,
|
||||
} = require('./string-formatting');
|
||||
const { removeUndefined, keysDeep } = require('./object-formatting');
|
||||
const { getConfigUrls, getAbsoluteAdminUrl, getAbsoluteServerUrl } = require('./config');
|
||||
const { generateTimestampCode } = require('./code-generator');
|
||||
const contentTypes = require('./content-types');
|
||||
const env = require('./env-helper');
|
||||
const relations = require('./relations');
|
||||
const setCreatorFields = require('./set-creator-fields');
|
||||
const hooks = require('./hooks');
|
||||
const providerFactory = require('./provider-factory');
|
||||
const pagination = require('./pagination');
|
||||
const sanitize = require('./sanitize');
|
||||
const traverseEntity = require('./traverse-entity');
|
||||
const { pipeAsync, mapAsync, reduceAsync, forEachAsync } = require('./async');
|
||||
const convertQueryParams = require('./convert-query-params');
|
||||
const importDefault = require('./import-default');
|
||||
const template = require('./template');
|
||||
const file = require('./file');
|
||||
const traverse = require('./traverse');
|
||||
} from './string-formatting';
|
||||
import { removeUndefined, keysDeep } from './object-formatting';
|
||||
import { getConfigUrls, getAbsoluteAdminUrl, getAbsoluteServerUrl } from './config';
|
||||
import { generateTimestampCode } from './code-generator';
|
||||
import * as contentTypes from './content-types';
|
||||
import env from './env-helper';
|
||||
import * as relations from './relations';
|
||||
import setCreatorFields from './set-creator-fields';
|
||||
import * as hooks from './hooks';
|
||||
import providerFactory from './provider-factory';
|
||||
import * as pagination from './pagination';
|
||||
import sanitize from './sanitize';
|
||||
import traverseEntity from './traverse-entity';
|
||||
import { pipeAsync, mapAsync, reduceAsync, forEachAsync } from './async';
|
||||
import convertQueryParams from './convert-query-params';
|
||||
import importDefault from './import-default';
|
||||
import * as template from './template';
|
||||
import * as file from './file';
|
||||
import * as traverse from './traverse';
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
yup,
|
||||
handleYupError,
|
||||
policy,
|
||||
templateConfiguration,
|
||||
buildQuery,
|
||||
hasDeepFilters,
|
||||
parseMultipartData,
|
||||
sanitize,
|
||||
traverseEntity,
|
||||
@ -92,3 +87,53 @@ module.exports = {
|
||||
file,
|
||||
traverse,
|
||||
};
|
||||
|
||||
const utils = {
|
||||
yup,
|
||||
handleYupError,
|
||||
policy,
|
||||
templateConfiguration,
|
||||
parseMultipartData,
|
||||
sanitize,
|
||||
traverseEntity,
|
||||
parseType,
|
||||
nameToSlug,
|
||||
toRegressedEnumValue,
|
||||
startsWithANumber,
|
||||
joinBy,
|
||||
nameToCollectionName,
|
||||
getCommonBeginning,
|
||||
getConfigUrls,
|
||||
escapeQuery,
|
||||
removeUndefined,
|
||||
keysDeep,
|
||||
getAbsoluteAdminUrl,
|
||||
getAbsoluteServerUrl,
|
||||
generateTimestampCode,
|
||||
stringIncludes,
|
||||
stringEquals,
|
||||
template,
|
||||
isKebabCase,
|
||||
isCamelCase,
|
||||
toKebabCase,
|
||||
contentTypes,
|
||||
env,
|
||||
relations,
|
||||
setCreatorFields,
|
||||
hooks,
|
||||
providerFactory,
|
||||
pagination,
|
||||
pipeAsync,
|
||||
mapAsync,
|
||||
reduceAsync,
|
||||
forEachAsync,
|
||||
errors,
|
||||
validateYupSchema,
|
||||
validateYupSchemaSync,
|
||||
convertQueryParams,
|
||||
importDefault,
|
||||
file,
|
||||
traverse,
|
||||
};
|
||||
|
||||
export default utils;
|
||||
|
||||
@ -53,7 +53,10 @@ const withNoLimit = (pagination: Pagination, maxLimit = -1) => ({
|
||||
limit: pagination.limit === -1 ? maxLimit : pagination.limit,
|
||||
});
|
||||
|
||||
const withDefaultPagination = (args: PaginationArgs, { defaults = {}, maxLimit = -1 } = {}) => {
|
||||
const withDefaultPagination = (
|
||||
args: Partial<PaginationArgs>,
|
||||
{ defaults = {}, maxLimit = -1 } = {}
|
||||
) => {
|
||||
const defaultValues = merge(STRAPI_DEFAULTS, defaults);
|
||||
|
||||
const usePagePagination = !isNil(args.page) || !isNil(args.pageSize);
|
||||
@ -87,7 +90,7 @@ const withDefaultPagination = (args: PaginationArgs, { defaults = {}, maxLimit =
|
||||
if (usePagePagination) {
|
||||
const { page, pageSize } = merge(defaultValues.page, {
|
||||
...args,
|
||||
pageSize: Math.max(1, args.pageSize),
|
||||
pageSize: Math.max(1, args.pageSize ?? 0),
|
||||
});
|
||||
|
||||
Object.assign(pagination, {
|
||||
|
||||
@ -73,7 +73,7 @@ type TypeMap = {
|
||||
datetime: Date;
|
||||
};
|
||||
|
||||
interface ParseTypeOptions {
|
||||
export interface ParseTypeOptions {
|
||||
type: keyof TypeMap;
|
||||
value: any;
|
||||
forceCast?: boolean;
|
||||
|
||||
@ -92,7 +92,7 @@ const findPolicy = (name: string, policyContext: PolicyContext) => {
|
||||
throw new Error(`Could not find policy "${name}"`);
|
||||
};
|
||||
|
||||
const getPolicy = (policyConfig: PolicyConfig, policyContext: PolicyContext) => {
|
||||
const getPolicy = (policyConfig: PolicyConfig, policyContext?: PolicyContext) => {
|
||||
const { pluginName, apiName } = policyContext ?? {};
|
||||
|
||||
if (typeof policyConfig === 'function') {
|
||||
|
||||
@ -22,7 +22,7 @@ const createProviderHooksMap = () => ({
|
||||
didDelete: createAsyncParallelHook(),
|
||||
});
|
||||
|
||||
interface Options {
|
||||
export interface Options {
|
||||
throwOnDuplicates?: boolean;
|
||||
}
|
||||
|
||||
@ -113,4 +113,4 @@ const providerFactory = (options: Options = {}) => {
|
||||
};
|
||||
};
|
||||
|
||||
export = providerFactory;
|
||||
export default providerFactory;
|
||||
|
||||
@ -11,7 +11,7 @@ import traverseEntity, { Data } from '../traverse-entity';
|
||||
import { traverseQueryFilters, traverseQuerySort, traverseQueryPopulate } from '../traverse';
|
||||
import { Model } from '../types';
|
||||
|
||||
interface Options {
|
||||
export interface Options {
|
||||
auth?: unknown;
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ const createContentAPISanitizers = () => {
|
||||
.get('content-api.input')
|
||||
.forEach((sanitizer: Sanitizer) => transforms.push(sanitizer(schema)));
|
||||
|
||||
return pipeAsync(...transforms)(data);
|
||||
return pipeAsync(...transforms)(data as Data);
|
||||
};
|
||||
|
||||
const sanitizeOutput: SanitizeFunc = async (data, schema: Model, { auth } = {}) => {
|
||||
@ -68,7 +68,7 @@ const createContentAPISanitizers = () => {
|
||||
.get('content-api.output')
|
||||
.forEach((sanitizer: Sanitizer) => transforms.push(sanitizer(schema)));
|
||||
|
||||
return pipeAsync(...transforms)(data);
|
||||
return pipeAsync(...transforms)(data as Data);
|
||||
};
|
||||
|
||||
const sanitizeQuery = async (
|
||||
|
||||
@ -3,7 +3,7 @@ import * as contentTypes from './content-types';
|
||||
|
||||
const { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = contentTypes.constants;
|
||||
|
||||
interface Options {
|
||||
export interface Options {
|
||||
user: User;
|
||||
isEdition?: boolean;
|
||||
}
|
||||
@ -12,7 +12,7 @@ interface User {
|
||||
id: string | number;
|
||||
}
|
||||
|
||||
export = ({ user, isEdition = false }: Options) =>
|
||||
export default ({ user, isEdition = false }: Options) =>
|
||||
(data: object) => {
|
||||
if (isEdition) {
|
||||
return assoc(UPDATED_BY_ATTRIBUTE, user.id, data);
|
||||
|
||||
@ -26,7 +26,7 @@ const getCommonPath = (...paths: string[]) => {
|
||||
);
|
||||
};
|
||||
|
||||
const escapeQuery = (query: string, charsToEscape: string[], escapeChar = '\\') => {
|
||||
const escapeQuery = (query: string, charsToEscape: string, escapeChar = '\\') => {
|
||||
return query
|
||||
.split('')
|
||||
.reduce(
|
||||
|
||||
@ -26,7 +26,7 @@ export interface Path {
|
||||
attribute: string | null;
|
||||
}
|
||||
|
||||
interface TraverseOptions {
|
||||
export interface TraverseOptions {
|
||||
path?: Path;
|
||||
schema: Model;
|
||||
}
|
||||
|
||||
@ -70,10 +70,6 @@ class StrapiIDSchema extends MixedSchemaType {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
yup.strapiID = () => new StrapiIDSchema();
|
||||
|
||||
const handleYupError = (error: yup.ValidationError, errorMessage: string) => {
|
||||
throw new YupValidationError(error, errorMessage);
|
||||
};
|
||||
@ -140,4 +136,14 @@ yup.setLocale({
|
||||
},
|
||||
});
|
||||
|
||||
export { yup, handleYupError, validateYupSchema, validateYupSchemaSync };
|
||||
const customYup = Object.assign(yup, {
|
||||
strapiID: (): InstanceType<typeof StrapiIDSchema> => new StrapiIDSchema(),
|
||||
});
|
||||
|
||||
export {
|
||||
customYup as yup,
|
||||
StrapiIDSchema,
|
||||
handleYupError,
|
||||
validateYupSchema,
|
||||
validateYupSchemaSync,
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user