mirror of
https://github.com/directus/directus.git
synced 2026-01-29 16:28:02 -05:00
Add batch type overrides + Item type
This commit is contained in:
@@ -6,6 +6,7 @@ import * as FilesService from '../services/files';
|
||||
import logger from '../logger';
|
||||
import { InvalidPayloadException } from '../exceptions';
|
||||
import useCollection from '../middleware/use-collection';
|
||||
import { Item } from '../types';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
@@ -14,7 +15,7 @@ router.use(useCollection('directus_files'));
|
||||
const multipartHandler = (operation: 'create' | 'update') =>
|
||||
asyncHandler(async (req, res, next) => {
|
||||
const busboy = new Busboy({ headers: req.headers });
|
||||
const savedFiles: Record<string, any> = [];
|
||||
const savedFiles: Item[] = [];
|
||||
|
||||
/**
|
||||
* The order of the fields in multipart/form-data is important. We require that all fields
|
||||
@@ -23,7 +24,7 @@ const multipartHandler = (operation: 'create' | 'update') =>
|
||||
*/
|
||||
|
||||
let disk: string;
|
||||
let payload: Record<string, any> = {};
|
||||
let payload: Partial<Item> = {};
|
||||
|
||||
busboy.on('field', (fieldname, val) => {
|
||||
if (fieldname === 'storage') {
|
||||
@@ -134,7 +135,7 @@ router.patch(
|
||||
'/:pk',
|
||||
sanitizeQuery,
|
||||
asyncHandler(async (req, res, next) => {
|
||||
let file: Record<string, any>;
|
||||
let file: Item;
|
||||
|
||||
if (req.is('multipart/form-data')) {
|
||||
file = await multipartHandler('update')(req, res, next);
|
||||
|
||||
@@ -26,29 +26,16 @@ router.post(
|
||||
userAgent: req.get('user-agent'),
|
||||
};
|
||||
|
||||
const isBatch = Array.isArray(req.body);
|
||||
const primaryKey = await ItemsService.createItem(req.collection, req.body, accountability);
|
||||
|
||||
if (isBatch) {
|
||||
const body: Record<string, any>[] = req.body;
|
||||
const primaryKeys = await ItemsService.createItem(req.collection, body, accountability);
|
||||
const items = await ItemsService.readItem(
|
||||
req.collection,
|
||||
primaryKeys,
|
||||
req.sanitizedQuery,
|
||||
accountability
|
||||
);
|
||||
res.json({ data: items || null });
|
||||
} else {
|
||||
const body: Record<string, any> = req.body;
|
||||
const primaryKey = await ItemsService.createItem(req.collection, body, accountability);
|
||||
const item = await ItemsService.readItem(
|
||||
req.collection,
|
||||
primaryKey,
|
||||
req.sanitizedQuery,
|
||||
accountability
|
||||
);
|
||||
res.json({ data: item || null });
|
||||
}
|
||||
const result = await ItemsService.readItem(
|
||||
req.collection,
|
||||
primaryKey,
|
||||
req.sanitizedQuery,
|
||||
accountability
|
||||
);
|
||||
|
||||
res.json({ data: result || null });
|
||||
})
|
||||
);
|
||||
|
||||
@@ -132,39 +119,30 @@ router.patch(
|
||||
throw new RouteNotFoundException(req.path);
|
||||
}
|
||||
|
||||
const primaryKey = req.params.pk;
|
||||
const isBatch = primaryKey.includes(',');
|
||||
const accountability: Accountability = {
|
||||
user: req.user,
|
||||
role: req.role,
|
||||
admin: req.admin,
|
||||
ip: req.ip,
|
||||
userAgent: req.get('user-agent'),
|
||||
};
|
||||
|
||||
if (isBatch) {
|
||||
const primaryKeys = primaryKey.split(',');
|
||||
const items = await Promise.all(primaryKeys.map(updateItem));
|
||||
return res.json({ data: items || null });
|
||||
} else {
|
||||
const item = await updateItem(primaryKey);
|
||||
return res.json({ data: item || null });
|
||||
}
|
||||
const primaryKey = req.params.pk.includes(',') ? req.params.pk.split(',') : req.params.pk;
|
||||
const updatedPrimaryKey = await ItemsService.updateItem(
|
||||
req.collection,
|
||||
primaryKey,
|
||||
req.body,
|
||||
accountability
|
||||
);
|
||||
|
||||
async function updateItem(pk: string | number) {
|
||||
const primaryKey = await ItemsService.updateItem(req.collection, pk, req.body, {
|
||||
role: req.role,
|
||||
admin: req.admin,
|
||||
ip: req.ip,
|
||||
userAgent: req.get('user-agent'),
|
||||
user: req.user,
|
||||
});
|
||||
const result = await ItemsService.readItem(
|
||||
req.collection,
|
||||
updatedPrimaryKey,
|
||||
req.sanitizedQuery,
|
||||
accountability
|
||||
);
|
||||
|
||||
const item = await ItemsService.readItem(
|
||||
req.collection,
|
||||
primaryKey,
|
||||
req.sanitizedQuery,
|
||||
{
|
||||
role: req.role,
|
||||
admin: req.admin,
|
||||
}
|
||||
);
|
||||
|
||||
return item;
|
||||
}
|
||||
res.json({ data: result || null });
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Query } from '../types/query';
|
||||
import * as ItemsService from './items';
|
||||
import { Accountability } from '../types';
|
||||
import { Accountability, Item, Query } from '../types';
|
||||
|
||||
export enum Action {
|
||||
CREATE = 'create',
|
||||
@@ -12,7 +11,7 @@ export enum Action {
|
||||
AUTHENTICATE = 'authenticate',
|
||||
}
|
||||
|
||||
export const createActivity = async (data: Record<string, any>) => {
|
||||
export const createActivity = async (data: Partial<Item>) => {
|
||||
return await ItemsService.createItem('directus_activity', data);
|
||||
};
|
||||
|
||||
@@ -30,7 +29,7 @@ export const readActivity = async (
|
||||
|
||||
export const updateActivity = async (
|
||||
pk: string | number,
|
||||
data: Record<string, any>,
|
||||
data: Partial<Item>,
|
||||
accountability: Accountability
|
||||
) => {
|
||||
return await ItemsService.updateItem('directus_activity', pk, data, accountability);
|
||||
|
||||
@@ -9,17 +9,17 @@ import parseEXIF from 'exif-reader';
|
||||
import parseIPTC from '../utils/parse-iptc';
|
||||
import path from 'path';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { Accountability } from '../types';
|
||||
import { Accountability, Item } from '../types';
|
||||
import { Readable } from 'stream';
|
||||
|
||||
export const createFile = async (
|
||||
data: Record<string, any>,
|
||||
data: Partial<Item>,
|
||||
stream: NodeJS.ReadableStream,
|
||||
accountability: Accountability
|
||||
) => {
|
||||
const id = uuidv4();
|
||||
|
||||
const payload: Record<string, any> = {
|
||||
const payload: Partial<Item> = {
|
||||
...data,
|
||||
id,
|
||||
};
|
||||
@@ -70,7 +70,7 @@ export const readFile = async (
|
||||
|
||||
export const updateFile = async (
|
||||
pk: string | number,
|
||||
data: Record<string, any>,
|
||||
data: Partial<Item>,
|
||||
accountability: Accountability,
|
||||
stream?: NodeJS.ReadableStream
|
||||
) => {
|
||||
@@ -98,6 +98,7 @@ export const updateFile = async (
|
||||
};
|
||||
|
||||
export const deleteFile = async (pk: string, accountability: Accountability) => {
|
||||
/** @todo use ItemsService */
|
||||
const file = await database
|
||||
.select('storage', 'filename_disk')
|
||||
.from('directus_files')
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as ItemsService from './items';
|
||||
import { Accountability, Query } from '../types';
|
||||
import { Accountability, Query, Item } from '../types';
|
||||
|
||||
export const createFolder = async (
|
||||
data: Record<string, any>,
|
||||
data: Partial<Item>,
|
||||
accountability: Accountability
|
||||
): Promise<string> => {
|
||||
return (await ItemsService.createItem('directus_folders', data, accountability)) as string;
|
||||
@@ -18,7 +18,7 @@ export const readFolder = async (pk: string, query: Query, accountability?: Acco
|
||||
|
||||
export const updateFolder = async (
|
||||
pk: string,
|
||||
data: Record<string, any>,
|
||||
data: Partial<Item>,
|
||||
accountability: Accountability
|
||||
): Promise<string> => {
|
||||
return (await ItemsService.updateItem('directus_folders', pk, data, accountability)) as string;
|
||||
|
||||
@@ -2,21 +2,26 @@ import database, { schemaInspector } from '../database';
|
||||
import { Query } from '../types/query';
|
||||
import runAST from '../database/run-ast';
|
||||
import getASTFromQuery from '../utils/get-ast-from-query';
|
||||
import { Accountability, Operation } from '../types';
|
||||
import { Accountability, Operation, Item } from '../types';
|
||||
|
||||
import * as PayloadService from './payload';
|
||||
import * as PermissionsService from './permissions';
|
||||
import * as ActivityService from './activity';
|
||||
import * as RevisionsService from './revisions';
|
||||
|
||||
import { pick } from 'lodash';
|
||||
import { pick, clone } from 'lodash';
|
||||
import logger from '../logger';
|
||||
|
||||
/**
|
||||
* @todo
|
||||
* have this support passing in a knex instance, so we can hook it up to the same TX instance
|
||||
* as batch insert / update
|
||||
*/
|
||||
async function saveActivityAndRevision(
|
||||
action: ActivityService.Action,
|
||||
collection: string,
|
||||
item: string,
|
||||
payload: Record<string, any>,
|
||||
payload: Partial<Item>,
|
||||
accountability: Accountability
|
||||
) {
|
||||
const activityID = await ActivityService.createActivity({
|
||||
@@ -43,17 +48,17 @@ async function saveActivityAndRevision(
|
||||
|
||||
export async function createItem(
|
||||
collection: string,
|
||||
data: Record<string, any>[],
|
||||
data: Partial<Item>[],
|
||||
accountability?: Accountability
|
||||
): Promise<(string | number)[]>;
|
||||
export async function createItem(
|
||||
collection: string,
|
||||
data: Record<string, any>,
|
||||
data: Partial<Item>,
|
||||
accountability?: Accountability
|
||||
): Promise<string | number>;
|
||||
export async function createItem(
|
||||
collection: string,
|
||||
data: Record<string, any> | Record<string, any>[],
|
||||
data: Partial<Item> | Partial<Item>[],
|
||||
accountability?: Accountability
|
||||
): Promise<string | number | (string | number)[]> {
|
||||
const isBatch = Array.isArray(data);
|
||||
@@ -62,7 +67,7 @@ export async function createItem(
|
||||
let payloads = isBatch ? data : [data];
|
||||
|
||||
const primaryKeys: (string | number)[] = await Promise.all(
|
||||
payloads.map(async (payload: Record<string, any>) => {
|
||||
payloads.map(async (payload: Partial<Item>) => {
|
||||
if (accountability && accountability.admin === false) {
|
||||
payload = await PermissionsService.processValues(
|
||||
'create',
|
||||
@@ -116,7 +121,7 @@ export async function createItem(
|
||||
});
|
||||
}
|
||||
|
||||
export const readItems = async <T = Record<string, any>>(
|
||||
export const readItems = async <T = Partial<Item>>(
|
||||
collection: string,
|
||||
query: Query,
|
||||
accountability?: Accountability
|
||||
@@ -131,27 +136,13 @@ export const readItems = async <T = Record<string, any>>(
|
||||
return await PayloadService.processValues('read', collection, records);
|
||||
};
|
||||
|
||||
export async function readItem<T = Record<string, any>>(
|
||||
export const readItem = async <T extends number | string | (number | string)[]>(
|
||||
collection: string,
|
||||
pk: number | string,
|
||||
query?: Query,
|
||||
accountability?: Accountability,
|
||||
operation?: Operation
|
||||
): Promise<T>;
|
||||
export async function readItem<T = Record<string, any>>(
|
||||
collection: string,
|
||||
pk: (number | string)[],
|
||||
query?: Query,
|
||||
accountability?: Accountability,
|
||||
operation?: Operation
|
||||
): Promise<T[]>;
|
||||
export async function readItem<T = Record<string, any>>(
|
||||
collection: string,
|
||||
pk: number | string | (number | string)[],
|
||||
pk: T,
|
||||
query: Query = {},
|
||||
accountability?: Accountability,
|
||||
operation?: Operation
|
||||
): Promise<T | T[]> {
|
||||
): Promise<T extends number | string ? Partial<Item> : Partial<Item>[]> => {
|
||||
// We allow overriding the operation, so we can use the item read logic to validate permissions
|
||||
// for update and delete as well
|
||||
operation = operation || 'read';
|
||||
@@ -190,56 +181,71 @@ export async function readItem<T = Record<string, any>>(
|
||||
const records = await runAST(ast);
|
||||
const processedRecords = await PayloadService.processValues('read', collection, records);
|
||||
return isBatch ? processedRecords : processedRecords[0];
|
||||
}
|
||||
};
|
||||
|
||||
export const updateItem = async (
|
||||
export const updateItem = async <T extends number | string | (number | string)[]>(
|
||||
collection: string,
|
||||
pk: number | string,
|
||||
data: Record<string, any>,
|
||||
pk: T,
|
||||
data: Partial<Item>,
|
||||
accountability?: Accountability
|
||||
): Promise<string | number> => {
|
||||
let payload = data;
|
||||
): Promise<T> => {
|
||||
const primaryKeys: any[] = Array.isArray(pk) ? pk : [pk];
|
||||
|
||||
if (accountability && accountability.admin === false) {
|
||||
await PermissionsService.checkAccess('update', collection, pk, accountability.role);
|
||||
const updatedPrimaryKeys = database.transaction(async (tx) => {
|
||||
let payload = clone(data);
|
||||
|
||||
payload = await PermissionsService.processValues(
|
||||
'validate',
|
||||
collection,
|
||||
accountability.role,
|
||||
data
|
||||
return await Promise.all(
|
||||
primaryKeys.map(async (key) => {
|
||||
if (accountability && accountability.admin === false) {
|
||||
await PermissionsService.checkAccess(
|
||||
'update',
|
||||
collection,
|
||||
key,
|
||||
accountability.role
|
||||
);
|
||||
|
||||
payload = await PermissionsService.processValues(
|
||||
'validate',
|
||||
collection,
|
||||
accountability.role,
|
||||
data
|
||||
);
|
||||
}
|
||||
|
||||
payload = await PayloadService.processValues('update', collection, payload);
|
||||
payload = await PayloadService.processM2O(collection, payload);
|
||||
|
||||
const primaryKeyField = await schemaInspector.primary(collection);
|
||||
|
||||
// Only insert the values that actually save to an existing column. This ensures we ignore aliases etc
|
||||
const columns = await schemaInspector.columns(collection);
|
||||
|
||||
const payloadWithoutAlias = pick(
|
||||
payload,
|
||||
columns.map(({ column }) => column)
|
||||
);
|
||||
|
||||
await tx(collection)
|
||||
.update(payloadWithoutAlias)
|
||||
.where({ [primaryKeyField]: key });
|
||||
|
||||
if (accountability) {
|
||||
// Don't await this. It can run async in the background
|
||||
saveActivityAndRevision(
|
||||
ActivityService.Action.UPDATE,
|
||||
collection,
|
||||
String(pk),
|
||||
payloadWithoutAlias,
|
||||
accountability
|
||||
).catch((err) => logger.error(err));
|
||||
}
|
||||
|
||||
return pk;
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
payload = await PayloadService.processValues('update', collection, payload);
|
||||
payload = await PayloadService.processM2O(collection, payload);
|
||||
|
||||
const primaryKeyField = await schemaInspector.primary(collection);
|
||||
|
||||
// Only insert the values that actually save to an existing column. This ensures we ignore aliases etc
|
||||
const columns = await schemaInspector.columns(collection);
|
||||
|
||||
const payloadWithoutAlias = pick(
|
||||
payload,
|
||||
columns.map(({ column }) => column)
|
||||
);
|
||||
|
||||
await database(collection)
|
||||
.update(payloadWithoutAlias)
|
||||
.where({ [primaryKeyField]: pk });
|
||||
|
||||
if (accountability) {
|
||||
// Don't await this. It can run async in the background
|
||||
saveActivityAndRevision(
|
||||
ActivityService.Action.UPDATE,
|
||||
collection,
|
||||
String(pk),
|
||||
payloadWithoutAlias,
|
||||
accountability
|
||||
).catch((err) => logger.error(err));
|
||||
}
|
||||
|
||||
return pk;
|
||||
return Array.isArray(pk) ? updatedPrimaryKeys : updatedPrimaryKeys[0];
|
||||
};
|
||||
|
||||
export const deleteItem = async (
|
||||
@@ -293,7 +299,7 @@ export const readSingleton = async (
|
||||
|
||||
export const upsertSingleton = async (
|
||||
collection: string,
|
||||
data: Record<string, any>,
|
||||
data: Partial<Item>,
|
||||
accountability: Accountability
|
||||
) => {
|
||||
const primaryKeyField = await schemaInspector.primary(collection);
|
||||
|
||||
@@ -15,11 +15,7 @@ import * as ItemsService from './items';
|
||||
type Operation = 'create' | 'read' | 'update';
|
||||
|
||||
type Transformers = {
|
||||
[type: string]: (
|
||||
operation: Operation,
|
||||
value: any,
|
||||
payload: Record<string, any>
|
||||
) => Promise<any>;
|
||||
[type: string]: (operation: Operation, value: any, payload: Partial<Item>) => Promise<any>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -72,7 +68,7 @@ const transformers: Transformers = {
|
||||
export const processValues = async (
|
||||
operation: Operation,
|
||||
collection: string,
|
||||
payload: Record<string, any> | Record<string, any>[]
|
||||
payload: Partial<Item> | Partial<Item>[]
|
||||
) => {
|
||||
let processedPayload = clone(payload);
|
||||
|
||||
@@ -113,7 +109,7 @@ export const processValues = async (
|
||||
|
||||
async function processField(
|
||||
field: Pick<System, 'field' | 'special'>,
|
||||
payload: Record<string, any>,
|
||||
payload: Partial<Item>,
|
||||
operation: Operation
|
||||
) {
|
||||
if (transformers.hasOwnProperty(field.special)) {
|
||||
@@ -126,7 +122,7 @@ async function processField(
|
||||
/**
|
||||
* Recursively checks for nested relational items, and saves them bottom up, to ensure we have IDs etc ready
|
||||
*/
|
||||
export const processM2O = async (collection: string, payload: Record<string, any>) => {
|
||||
export const processM2O = async (collection: string, payload: Partial<Item>) => {
|
||||
const payloadClone = clone(payload);
|
||||
|
||||
const relations = await database
|
||||
@@ -145,7 +141,7 @@ export const processM2O = async (collection: string, payload: Record<string, any
|
||||
// Save all nested m2o records
|
||||
await Promise.all(
|
||||
relationsToProcess.map(async (relation) => {
|
||||
const relatedRecord: Record<string, any> = payloadClone[relation.field_many];
|
||||
const relatedRecord: Partial<Item> = payloadClone[relation.field_many];
|
||||
const hasPrimaryKey = relatedRecord.hasOwnProperty(relation.primary_one);
|
||||
|
||||
let relatedPrimaryKey: string | number;
|
||||
@@ -172,7 +168,7 @@ export const processM2O = async (collection: string, payload: Record<string, any
|
||||
return payloadClone;
|
||||
};
|
||||
|
||||
export const processO2M = async (collection: string, payload: Record<string, any>) => {
|
||||
export const processO2M = async (collection: string, payload: Partial<Item>) => {
|
||||
const payloadClone = clone(payload);
|
||||
|
||||
const relations = await database
|
||||
@@ -194,7 +190,7 @@ export const processO2M = async (collection: string, payload: Record<string, any
|
||||
const relatedRecords = payloadClone[relation.field_one];
|
||||
|
||||
await Promise.all(
|
||||
relatedRecords.map(async (relatedRecord: Record<string, any>, index: number) => {
|
||||
relatedRecords.map(async (relatedRecord: Partial<Item>, index: number) => {
|
||||
relatedRecord[relation.field_many] = payloadClone[relation.primary_one];
|
||||
|
||||
const hasPrimaryKey = relatedRecord.hasOwnProperty(relation.primary_many);
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
Query,
|
||||
Permission,
|
||||
Operation,
|
||||
Item,
|
||||
} from '../types';
|
||||
import * as ItemsService from './items';
|
||||
import database from '../database';
|
||||
@@ -14,7 +15,7 @@ import { uniq } from 'lodash';
|
||||
import generateJoi from '../utils/generate-joi';
|
||||
|
||||
export const createPermission = async (
|
||||
data: Record<string, any>,
|
||||
data: Partial<Item>,
|
||||
accountability: Accountability
|
||||
): Promise<number> => {
|
||||
return (await ItemsService.createItem('directus_permissions', data, accountability)) as number;
|
||||
@@ -30,7 +31,7 @@ export const readPermission = async (pk: number, query: Query, accountability?:
|
||||
|
||||
export const updatePermission = async (
|
||||
pk: number,
|
||||
data: Record<string, any>,
|
||||
data: Partial<Item>,
|
||||
accountability: Accountability
|
||||
): Promise<number> => {
|
||||
return (await ItemsService.updateItem(
|
||||
@@ -183,7 +184,7 @@ export const processValues = async (
|
||||
operation: Operation,
|
||||
collection: string,
|
||||
role: string | null,
|
||||
data: Record<string, any>
|
||||
data: Partial<Item>
|
||||
) => {
|
||||
const permission = await database
|
||||
.select<Permission>('*')
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Accountability, Query } from '../types';
|
||||
import { Accountability, Query, Item } from '../types';
|
||||
import * as ItemsService from './items';
|
||||
|
||||
/** @todo check if we want to save activity for collection presets */
|
||||
|
||||
export const createCollectionPreset = async (
|
||||
data: Record<string, any>,
|
||||
data: Partial<Item>,
|
||||
accountability: Accountability
|
||||
) => {
|
||||
return await ItemsService.createItem('directus_presets', data, accountability);
|
||||
@@ -24,7 +24,7 @@ export const readCollectionPreset = async (
|
||||
|
||||
export const updateCollectionPreset = async (
|
||||
pk: string | number,
|
||||
data: Record<string, any>,
|
||||
data: Partial<Item>,
|
||||
accountability: Accountability
|
||||
) => {
|
||||
return await ItemsService.updateItem('directus_presets', pk, data, accountability);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Accountability, Query } from '../types';
|
||||
import { Accountability, Query, Item } from '../types';
|
||||
import * as ItemsService from './items';
|
||||
|
||||
export const createRelation = async (data: Record<string, any>, accountability: Accountability) => {
|
||||
export const createRelation = async (data: Partial<Item>, accountability: Accountability) => {
|
||||
return await ItemsService.createItem('directus_relations', data, accountability);
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ export const readRelation = async (
|
||||
|
||||
export const updateRelation = async (
|
||||
pk: string | number,
|
||||
data: Record<string, any>,
|
||||
data: Partial<Item>,
|
||||
accountability: Accountability
|
||||
) => {
|
||||
return await ItemsService.updateItem('directus_relations', pk, data, accountability);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as ItemsService from './items';
|
||||
import { Accountability, Query } from '../types';
|
||||
import { Accountability, Query, Item } from '../types';
|
||||
|
||||
export const createRevision = async (data: Record<string, any>) => {
|
||||
export const createRevision = async (data: Partial<Item>) => {
|
||||
return await ItemsService.createItem('directus_revisions', data);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Accountability, Query } from '../types';
|
||||
import { Accountability, Query, Item } from '../types';
|
||||
import * as ItemsService from './items';
|
||||
|
||||
export const createRole = async (data: Record<string, any>, accountability: Accountability) => {
|
||||
export const createRole = async (data: Partial<Item>, accountability: Accountability) => {
|
||||
return await ItemsService.createItem('directus_roles', data, accountability);
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ export const readRole = async (
|
||||
|
||||
export const updateRole = async (
|
||||
pk: string | number,
|
||||
data: Record<string, any>,
|
||||
data: Partial<Item>,
|
||||
accountability: Accountability
|
||||
) => {
|
||||
return await ItemsService.updateItem('directus_roles', pk, data, accountability);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Query } from '../types/query';
|
||||
import { Query, Item } from '../types/query';
|
||||
import * as ItemsService from './items';
|
||||
import { Accountability } from '../types';
|
||||
|
||||
@@ -6,6 +6,6 @@ export const readSettings = async (query: Query, accountability?: Accountability
|
||||
return await ItemsService.readSingleton('directus_settings', query, accountability);
|
||||
};
|
||||
|
||||
export const updateSettings = async (data: Record<string, any>, accountability: Accountability) => {
|
||||
export const updateSettings = async (data: Partial<Item>, accountability: Accountability) => {
|
||||
return await ItemsService.upsertSingleton('directus_settings', data, accountability);
|
||||
};
|
||||
|
||||
@@ -4,9 +4,9 @@ import { sendInviteMail } from '../mail';
|
||||
import database from '../database';
|
||||
import argon2 from 'argon2';
|
||||
import { InvalidPayloadException } from '../exceptions';
|
||||
import { Accountability, Query } from '../types';
|
||||
import { Accountability, Query, Item } from '../types';
|
||||
|
||||
export const createUser = async (data: Record<string, any>, accountability: Accountability) => {
|
||||
export const createUser = async (data: Partial<Item>, accountability: Accountability) => {
|
||||
return await ItemsService.createItem('directus_users', data, accountability);
|
||||
};
|
||||
|
||||
@@ -24,7 +24,7 @@ export const readUser = async (
|
||||
|
||||
export const updateUser = async (
|
||||
pk: string | number,
|
||||
data: Record<string, any>,
|
||||
data: Partial<Item>,
|
||||
accountability: Accountability
|
||||
) => {
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Accountability, Query } from '../types';
|
||||
import { Accountability, Query, Item } from '../types';
|
||||
import * as ItemsService from './items';
|
||||
|
||||
export const createWebhook = async (data: Record<string, any>, accountability: Accountability) => {
|
||||
export const createWebhook = async (data: Partial<Item>, accountability: Accountability) => {
|
||||
return await ItemsService.createItem('directus_webhooks', data, accountability);
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ export const readWebhook = async (
|
||||
|
||||
export const updateWebhook = async (
|
||||
pk: string | number,
|
||||
data: Record<string, any>,
|
||||
data: Partial<Item>,
|
||||
accountability: Accountability
|
||||
) => {
|
||||
return await ItemsService.updateItem('directus_webhooks', pk, data, accountability);
|
||||
|
||||
3
src/types/express.d.ts
vendored
3
src/types/express.d.ts
vendored
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
|
||||
import { Permission } from './permissions';
|
||||
import { Query } from './query';
|
||||
|
||||
export {};
|
||||
|
||||
@@ -14,7 +15,7 @@ declare global {
|
||||
role: string | null;
|
||||
admin: boolean;
|
||||
collection?: string;
|
||||
sanitizedQuery?: Record<string, any>;
|
||||
sanitizedQuery?: Query;
|
||||
single?: boolean;
|
||||
permissions?: Permission;
|
||||
}
|
||||
|
||||
@@ -9,3 +9,4 @@ export * from './permissions';
|
||||
export * from './query';
|
||||
export * from './relation';
|
||||
export * from './sessions';
|
||||
export * from './items';
|
||||
|
||||
6
src/types/items.ts
Normal file
6
src/types/items.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* I know this looks a little silly, but it allows us to explicitly differentiate between when we're
|
||||
* expecting an item vs any other generic object.
|
||||
*/
|
||||
|
||||
export type Item = Record<string, any>;
|
||||
Reference in New Issue
Block a user