Prevent empty string as id in SDK (#12595)

* Prevent empty string as id in SDK

* test
This commit is contained in:
Azri Kahar
2022-04-06 22:42:29 +08:00
committed by GitHub
parent 4f7abf0733
commit 2f0921ffa9
7 changed files with 55 additions and 5 deletions

View File

@@ -1,5 +1,15 @@
import { ITransport } from '../transport';
import { IItems, Item, QueryOne, QueryMany, OneItem, ManyItems, PartialItem, ItemsOptions } from '../items';
import {
IItems,
Item,
QueryOne,
QueryMany,
OneItem,
ManyItems,
PartialItem,
ItemsOptions,
EmptyParamError,
} from '../items';
import { ID, FieldType } from '../types';
export class ItemsHandler<T extends Item> implements IItems<T> {
@@ -14,6 +24,7 @@ export class ItemsHandler<T extends Item> implements IItems<T> {
}
async readOne(id: ID, query?: QueryOne<T>, options?: ItemsOptions): Promise<OneItem<T>> {
if (`${id}` === '') throw new EmptyParamError('id');
const response = await this.transport.get<T>(`${this.endpoint}/${encodeURI(id as string)}`, {
params: query,
...options?.requestOptions,
@@ -74,6 +85,7 @@ export class ItemsHandler<T extends Item> implements IItems<T> {
}
async updateOne(id: ID, item: PartialItem<T>, query?: QueryOne<T>, options?: ItemsOptions): Promise<OneItem<T>> {
if (`${id}` === '') throw new EmptyParamError('id');
return (
await this.transport.patch<PartialItem<T>>(`${this.endpoint}/${encodeURI(id as string)}`, item, {
params: query,
@@ -121,6 +133,7 @@ export class ItemsHandler<T extends Item> implements IItems<T> {
}
async deleteOne(id: ID, options?: ItemsOptions): Promise<void> {
if (`${id}` === '') throw new EmptyParamError('id');
await this.transport.delete(`${this.endpoint}/${encodeURI(id as string)}`, undefined, options?.requestOptions);
}

View File

@@ -2,7 +2,7 @@
* Collections handler
*/
import { ManyItems, OneItem, PartialItem, QueryOne } from '../items';
import { ManyItems, OneItem, PartialItem, QueryOne, EmptyParamError } from '../items';
import { ITransport } from '../transport';
import { CollectionType, DefaultType } from '../types';
@@ -15,6 +15,7 @@ export class CollectionsHandler<T = CollectionItem> {
}
async readOne(collection: string): Promise<OneItem<T>> {
if (`${collection}` === '') throw new EmptyParamError('collection');
const response = await this.transport.get(`/collections/${collection}`);
return response.data as T;
}
@@ -42,6 +43,7 @@ export class CollectionsHandler<T = CollectionItem> {
}
async updateOne(collection: string, item: PartialItem<T>, query?: QueryOne<T>): Promise<OneItem<T>> {
if (`${collection}` === '') throw new EmptyParamError('collection');
return (
await this.transport.patch<PartialItem<T>>(`/collections/${collection}`, item, {
params: query,
@@ -50,6 +52,7 @@ export class CollectionsHandler<T = CollectionItem> {
}
async deleteOne(collection: string): Promise<void> {
if (`${collection}` === '') throw new EmptyParamError('collection');
await this.transport.delete(`/collections/${collection}`);
}
}

View File

@@ -1,6 +1,7 @@
import { Comment, ID } from '../types';
import { ITransport } from '../transport';
import { ActivityItem } from './activity';
import { EmptyParamError } from '../items';
export class CommentsHandler<T> {
private transport: ITransport;
@@ -15,6 +16,7 @@ export class CommentsHandler<T> {
}
async update(comment_activity_id: ID, comment: string): Promise<ActivityItem<T>> {
if (`${comment_activity_id}` === '') throw new EmptyParamError('comment_activity_id');
const response = await this.transport.patch(`/activity/comment/${encodeURI(comment_activity_id as string)}`, {
comment,
});
@@ -22,6 +24,7 @@ export class CommentsHandler<T> {
}
async delete(comment_activity_id: ID): Promise<void> {
if (`${comment_activity_id}` === '') throw new EmptyParamError('comment_activity_id');
await this.transport.delete(`/activity/comment/${encodeURI(comment_activity_id as string)}`);
}
}

View File

@@ -2,7 +2,7 @@
* Fields handler
*/
import { ManyItems, OneItem, PartialItem } from '../items';
import { ManyItems, OneItem, PartialItem, EmptyParamError } from '../items';
import { ITransport } from '../transport';
import { FieldType, DefaultType, ID } from '../types';
@@ -15,11 +15,14 @@ export class FieldsHandler<T = FieldItem> {
}
async readOne(collection: string, id: ID): Promise<OneItem<T>> {
if (`${collection}` === '') throw new EmptyParamError('collection');
if (`${id}` === '') throw new EmptyParamError('id');
const response = await this.transport.get(`/fields/${collection}/${id}`);
return response.data as T;
}
async readMany(collection: string): Promise<ManyItems<T>> {
if (`${collection}` === '') throw new EmptyParamError('collection');
const response = await this.transport.get(`/fields/${collection}`);
return response.data as T;
}
@@ -30,14 +33,19 @@ export class FieldsHandler<T = FieldItem> {
}
async createOne(collection: string, item: PartialItem<T>): Promise<OneItem<T>> {
if (`${collection}` === '') throw new EmptyParamError('collection');
return (await this.transport.post<T>(`/fields/${collection}`, item)).data;
}
async updateOne(collection: string, field: string, item: PartialItem<T>): Promise<OneItem<T>> {
if (`${collection}` === '') throw new EmptyParamError('collection');
if (`${field}` === '') throw new EmptyParamError('field');
return (await this.transport.patch<PartialItem<T>>(`/fields/${collection}/${field}`, item)).data;
}
async deleteOne(collection: string, field: string): Promise<void> {
if (`${collection}` === '') throw new EmptyParamError('collection');
if (`${field}` === '') throw new EmptyParamError('field');
await this.transport.delete(`/fields/${collection}/${field}`);
}
}

View File

@@ -1,7 +1,7 @@
/**
* Relations handler
*/
import { ManyItems, OneItem, PartialItem } from '../items';
import { ManyItems, OneItem, PartialItem, EmptyParamError } from '../items';
import { ITransport } from '../transport';
import { RelationType, DefaultType, ID } from '../types';
@@ -14,11 +14,14 @@ export class RelationsHandler<T = RelationItem> {
}
async readOne(collection: string, id: ID): Promise<OneItem<T>> {
if (`${collection}` === '') throw new EmptyParamError('collection');
if (`${id}` === '') throw new EmptyParamError('id');
const response = await this.transport.get(`/relations/${collection}/${id}`);
return response.data as T;
}
async readMany(collection: string): Promise<ManyItems<T>> {
if (`${collection}` === '') throw new EmptyParamError('collection');
const response = await this.transport.get(`/relations/${collection}`);
return response.data;
}
@@ -33,6 +36,8 @@ export class RelationsHandler<T = RelationItem> {
}
async updateOne(collection: string, field: string, item: PartialItem<T>): Promise<OneItem<T>> {
if (`${collection}` === '') throw new EmptyParamError('collection');
if (`${field}` === '') throw new EmptyParamError('field');
return (
await this.transport.patch<PartialItem<T>>(`/relations/${collection}/${field}`, {
params: item,
@@ -41,6 +46,8 @@ export class RelationsHandler<T = RelationItem> {
}
async deleteOne(collection: string, field: string): Promise<void> {
if (`${collection}` === '') throw new EmptyParamError('collection');
if (`${field}` === '') throw new EmptyParamError('field');
await this.transport.delete(`/relations/${collection}/${field}`);
}
}

View File

@@ -108,3 +108,9 @@ export interface IItems<T extends Item> {
deleteOne(id: ID, options?: ItemsOptions): Promise<void>;
deleteMany(ids: ID[], options?: ItemsOptions): Promise<void>;
}
export class EmptyParamError extends Error {
constructor(paramName?: string) {
super(`${paramName ?? 'ID'} cannot be an empty string`);
}
}

View File

@@ -3,10 +3,20 @@
*/
import { Blog } from './blog.d';
import { Directus, ItemsOptions } from '../src';
import { Directus, ItemsOptions, EmptyParamError } from '../src';
import { test } from './utils';
describe('items', function () {
test(`should throw EmptyParamError when using empty string as id`, async (url, _nock) => {
const sdk = new Directus<Blog>(url);
try {
await sdk.items('posts').readOne('');
} catch (err: any) {
expect(err).toBeInstanceOf(EmptyParamError);
}
});
test(`can get an item by id`, async (url, nock) => {
nock()
.get('/items/posts/1')