Comparing version 4.0.0-beta.2 to 4.0.0-beta.3
import { MockResponseObject } from 'fetch-mock'; | ||
import { BaseResponse, APIServer, NormalizedRequest } from '../types.js'; | ||
import { BaseServerOptions } from '../SimpleRestServer.js'; | ||
import { BaseResponse, APIServer, NormalizedRequest } from '../types.ts'; | ||
import { BaseServerOptions } from '../SimpleRestServer.ts'; | ||
@@ -5,0 +5,0 @@ export declare class FetchMockAdapter { |
@@ -1,3 +0,3 @@ | ||
import { APIServer, NormalizedRequest } from '../types.js'; | ||
import { BaseServerOptions } from '../SimpleRestServer.js'; | ||
import { APIServer, NormalizedRequest } from '../types.ts'; | ||
import { BaseServerOptions } from '../SimpleRestServer.ts'; | ||
@@ -4,0 +4,0 @@ export declare class MswAdapter { |
@@ -1,3 +0,3 @@ | ||
import { BaseResponse, APIServer, NormalizedRequest } from '../types.js'; | ||
import { BaseServerOptions } from '../SimpleRestServer.js'; | ||
import { BaseResponse, APIServer, NormalizedRequest } from '../types.ts'; | ||
import { BaseServerOptions } from '../SimpleRestServer.ts'; | ||
import { SinonFakeXMLHttpRequest } from 'sinon'; | ||
@@ -4,0 +4,0 @@ |
import { CollectionItem, Embed, Query } from './types.js'; | ||
import { Database } from './Database.js'; | ||
import { Database } from './Database.ts'; | ||
@@ -4,0 +4,0 @@ export declare class Collection<T extends CollectionItem = CollectionItem> { |
@@ -1,4 +0,4 @@ | ||
import { CollectionItem, Query, QueryFunction } from './types.js'; | ||
import { Single } from './Single.js'; | ||
import { Collection } from './Collection.js'; | ||
import { CollectionItem, Query, QueryFunction } from './types.ts'; | ||
import { Single } from './Single.ts'; | ||
import { Collection } from './Collection.ts'; | ||
@@ -5,0 +5,0 @@ export declare class Database { |
@@ -1090,11 +1090,8 @@ var Gt = Object.defineProperty; | ||
} | ||
const Rd = (t, e) => t.reduce((r, a) => r && e(a), !0), Ld = (t, e) => t.reduce((r, a) => r || e(a), !1), Dd = (t, e) => t.reduce( | ||
(r, a, n) => { | ||
if (r != null) | ||
return r; | ||
const s = t.slice(0, n + 1).join("."), i = t.slice(n + 1).join("."), o = y(e, s); | ||
return Array.isArray(o) && n < t.length - 1 ? [s, i] : void 0; | ||
}, | ||
void 0 | ||
), ct = (t, e) => { | ||
const Rd = (t, e) => t.reduce((r, a) => r && e(a), !0), Ld = (t, e) => t.reduce((r, a) => r || e(a), !1), Dd = (t, e) => t.reduce((r, a, n) => { | ||
if (r != null) | ||
return r; | ||
const s = t.slice(0, n + 1).join("."), i = t.slice(n + 1).join("."), o = y(e, s); | ||
return Array.isArray(o) && n < t.length - 1 ? [s, i] : void 0; | ||
}, void 0), ct = (t, e) => { | ||
if (t.indexOf("_q") !== -1) { | ||
@@ -1101,0 +1098,0 @@ const r = t.replace(/(_q)$/, ""), a = new RegExp(e.toString(), "i"); |
@@ -1,9 +0,9 @@ | ||
export * from './types.js'; | ||
export * from './adapters/SinonAdapter.js'; | ||
export * from './adapters/FetchMockAdapter.js'; | ||
export * from './adapters/MswAdapter.js'; | ||
export * from './Database.js'; | ||
export * from './SimpleRestServer.js'; | ||
export * from './Collection.js'; | ||
export * from './Single.js'; | ||
export * from './withDelay.js'; | ||
export * from './types.ts'; | ||
export * from './adapters/SinonAdapter.ts'; | ||
export * from './adapters/FetchMockAdapter.ts'; | ||
export * from './adapters/MswAdapter.ts'; | ||
export * from './Database.ts'; | ||
export * from './SimpleRestServer.ts'; | ||
export * from './Collection.ts'; | ||
export * from './Single.ts'; | ||
export * from './withDelay.ts'; |
@@ -1,5 +0,5 @@ | ||
import { APIServer, BaseResponse, FakeRestContext, CollectionItem, QueryFunction, NormalizedRequest } from './types.js'; | ||
import { Single } from './Single.js'; | ||
import { Database, DatabaseOptions } from './Database.js'; | ||
import { Collection } from './Collection.js'; | ||
import { APIServer, BaseResponse, FakeRestContext, CollectionItem, QueryFunction, NormalizedRequest } from './types.ts'; | ||
import { Single } from './Single.ts'; | ||
import { Database, DatabaseOptions } from './Database.ts'; | ||
import { Collection } from './Collection.ts'; | ||
@@ -6,0 +6,0 @@ export declare class SimpleRestServer implements APIServer { |
@@ -1,3 +0,3 @@ | ||
import { CollectionItem, Embed, Query } from './types.js'; | ||
import { Database } from './Database.js'; | ||
import { CollectionItem, Embed, Query } from './types.ts'; | ||
import { Database } from './Database.ts'; | ||
@@ -4,0 +4,0 @@ export declare class Single<T extends CollectionItem = CollectionItem> { |
@@ -1,3 +0,3 @@ | ||
import { Middleware } from './SimpleRestServer.js'; | ||
import { Middleware } from './SimpleRestServer.ts'; | ||
export declare const withDelay: (delayMs: number) => Middleware; |
{ | ||
"name": "fakerest", | ||
"version": "4.0.0-beta.2", | ||
"version": "4.0.0-beta.3", | ||
"repository": "https://github.com/marmelab/FakeRest", | ||
@@ -5,0 +5,0 @@ "description": "Patch XMLHttpRequest to fake a REST server based on JSON data. ", |
425
README.md
@@ -40,16 +40,16 @@ # FakeRest | ||
'authors': [ | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi' }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen' } | ||
], | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi' }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen' } | ||
], | ||
'books': [ | ||
{ id: 0, author_id: 0, title: 'Anna Karenina' }, | ||
{ id: 1, author_id: 0, title: 'War and Peace' }, | ||
{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, | ||
{ id: 3, author_id: 1, title: 'Sense and Sensibility' } | ||
], | ||
{ id: 0, author_id: 0, title: 'Anna Karenina' }, | ||
{ id: 1, author_id: 0, title: 'War and Peace' }, | ||
{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, | ||
{ id: 3, author_id: 1, title: 'Sense and Sensibility' } | ||
], | ||
'settings': { | ||
language: 'english', | ||
preferred_format: 'hardback', | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
@@ -98,16 +98,16 @@ export const worker = setupWorker( | ||
'authors': [ | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi' }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen' } | ||
], | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi' }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen' } | ||
], | ||
'books': [ | ||
{ id: 0, author_id: 0, title: 'Anna Karenina' }, | ||
{ id: 1, author_id: 0, title: 'War and Peace' }, | ||
{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, | ||
{ id: 3, author_id: 1, title: 'Sense and Sensibility' } | ||
], | ||
{ id: 0, author_id: 0, title: 'Anna Karenina' }, | ||
{ id: 1, author_id: 0, title: 'War and Peace' }, | ||
{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, | ||
{ id: 3, author_id: 1, title: 'Sense and Sensibility' } | ||
], | ||
'settings': { | ||
language: 'english', | ||
preferred_format: 'hardback', | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
@@ -138,16 +138,16 @@ | ||
'authors': [ | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi' }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen' } | ||
], | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi' }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen' } | ||
], | ||
'books': [ | ||
{ id: 0, author_id: 0, title: 'Anna Karenina' }, | ||
{ id: 1, author_id: 0, title: 'War and Peace' }, | ||
{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, | ||
{ id: 3, author_id: 1, title: 'Sense and Sensibility' } | ||
], | ||
{ id: 0, author_id: 0, title: 'Anna Karenina' }, | ||
{ id: 1, author_id: 0, title: 'War and Peace' }, | ||
{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, | ||
{ id: 3, author_id: 1, title: 'Sense and Sensibility' } | ||
], | ||
'settings': { | ||
language: 'english', | ||
preferred_format: 'hardback', | ||
} | ||
}, | ||
} | ||
}, | ||
}); | ||
@@ -172,88 +172,88 @@ | ||
GET /books?filter={"author_id":1}&embed=["author"]&sort=["title","desc"]&range=[0-9] | ||
GET /books?filter={"author_id":1}&embed=["author"]&sort=["title","desc"]&range=[0-9] | ||
HTTP 1.1 200 OK | ||
Content-Range: items 0-1/2 | ||
Content-Type: application/json | ||
[ | ||
{ "id": 3, "author_id": 1, "title": "Sense and Sensibility", "author": { "id": 1, "first_name": "Jane", "last_name": "Austen" } }, | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice", "author": { "id": 1, "first_name": "Jane", "last_name": "Austen" } } | ||
] | ||
HTTP 1.1 200 OK | ||
Content-Range: items 0-1/2 | ||
Content-Type: application/json | ||
[ | ||
{ "id": 3, "author_id": 1, "title": "Sense and Sensibility", "author": { "id": 1, "first_name": "Jane", "last_name": "Austen" } }, | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice", "author": { "id": 1, "first_name": "Jane", "last_name": "Austen" } } | ||
] | ||
The `filter` param must be a serialized object literal describing the criteria to apply to the search query. See the [supported filters](#supported-filters) for more details. | ||
GET /books?filter={"author_id":1} // return books where author_id is equal to 1 | ||
HTTP 1.1 200 OK | ||
Content-Range: items 0-1/2 | ||
Content-Type: application/json | ||
[ | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice" }, | ||
{ "id": 3, "author_id": 1, "title": "Sense and Sensibility" } | ||
] | ||
GET /books?filter={"author_id":1} // return books where author_id is equal to 1 | ||
HTTP 1.1 200 OK | ||
Content-Range: items 0-1/2 | ||
Content-Type: application/json | ||
[ | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice" }, | ||
{ "id": 3, "author_id": 1, "title": "Sense and Sensibility" } | ||
] | ||
// array values are possible | ||
GET /books?filter={"id":[2,3]} // return books where id is in [2,3] | ||
HTTP 1.1 200 OK | ||
Content-Range: items 0-1/2 | ||
Content-Type: application/json | ||
[ | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice" }, | ||
{ "id": 3, "author_id": 1, "title": "Sense and Sensibility" } | ||
] | ||
// array values are possible | ||
GET /books?filter={"id":[2,3]} // return books where id is in [2,3] | ||
HTTP 1.1 200 OK | ||
Content-Range: items 0-1/2 | ||
Content-Type: application/json | ||
[ | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice" }, | ||
{ "id": 3, "author_id": 1, "title": "Sense and Sensibility" } | ||
] | ||
// use the special "q" filter to make a full-text search on all text fields | ||
GET /books?filter={"q":"and"} // return books where any of the book properties contains the string 'and' | ||
// use the special "q" filter to make a full-text search on all text fields | ||
GET /books?filter={"q":"and"} // return books where any of the book properties contains the string 'and' | ||
HTTP 1.1 200 OK | ||
Content-Range: items 0-2/3 | ||
Content-Type: application/json | ||
[ | ||
{ "id": 1, "author_id": 0, "title": "War and Peace" }, | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice" }, | ||
{ "id": 3, "author_id": 1, "title": "Sense and Sensibility" } | ||
] | ||
HTTP 1.1 200 OK | ||
Content-Range: items 0-2/3 | ||
Content-Type: application/json | ||
[ | ||
{ "id": 1, "author_id": 0, "title": "War and Peace" }, | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice" }, | ||
{ "id": 3, "author_id": 1, "title": "Sense and Sensibility" } | ||
] | ||
// use _gt, _gte, _lte, _lt, or _neq suffix on filter names to make range queries | ||
GET /books?filter={"price_lte":20} // return books where the price is less than or equal to 20 | ||
GET /books?filter={"price_gt":20} // return books where the price is greater than 20 | ||
// use _gt, _gte, _lte, _lt, or _neq suffix on filter names to make range queries | ||
GET /books?filter={"price_lte":20} // return books where the price is less than or equal to 20 | ||
GET /books?filter={"price_gt":20} // return books where the price is greater than 20 | ||
// when the filter object contains more than one property, the criteria combine with an AND logic | ||
GET /books?filter={"published_at_gte":"2015-06-12","published_at_lte":"2015-06-15"} // return books published between two dates | ||
// when the filter object contains more than one property, the criteria combine with an AND logic | ||
GET /books?filter={"published_at_gte":"2015-06-12","published_at_lte":"2015-06-15"} // return books published between two dates | ||
The `sort` param must be a serialized array literal defining first the property used for sorting, then the sorting direction. | ||
GET /author?sort=["date_of_birth","asc"] // return authors, the oldest first | ||
GET /author?sort=["date_of_birth","desc"] // return authors, the youngest first | ||
GET /author?sort=["date_of_birth","asc"] // return authors, the oldest first | ||
GET /author?sort=["date_of_birth","desc"] // return authors, the youngest first | ||
The `range` param defines the number of results by specifying the rank of the first and last results. The first result is #0. | ||
GET /books?range=[0-9] // return the first 10 books | ||
GET /books?range=[10-19] // return the 10 next books | ||
GET /books?range=[0-9] // return the first 10 books | ||
GET /books?range=[10-19] // return the 10 next books | ||
The `embed` param sets the related objects or collections to be embedded in the response. | ||
// embed author in books | ||
GET /books?embed=["author"] | ||
HTTP 1.1 200 OK | ||
Content-Range: items 0-3/4 | ||
Content-Type: application/json | ||
[ | ||
{ "id": 0, "author_id": 0, "title": "Anna Karenina", "author": { "id": 0, "first_name": "Leo", "last_name": "Tolstoi" } }, | ||
{ "id": 1, "author_id": 0, "title": "War and Peace", "author": { "id": 0, "first_name": "Leo", "last_name": "Tolstoi" } }, | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice", "author": { "id": 1, "first_name": "Jane", "last_name": "Austen" } }, | ||
{ "id": 3, "author_id": 1, "title": "Sense and Sensibility", "author": { "id": 1, "first_name": "Jane", "last_name": "Austen" } } | ||
] | ||
// embed author in books | ||
GET /books?embed=["author"] | ||
HTTP 1.1 200 OK | ||
Content-Range: items 0-3/4 | ||
Content-Type: application/json | ||
[ | ||
{ "id": 0, "author_id": 0, "title": "Anna Karenina", "author": { "id": 0, "first_name": "Leo", "last_name": "Tolstoi" } }, | ||
{ "id": 1, "author_id": 0, "title": "War and Peace", "author": { "id": 0, "first_name": "Leo", "last_name": "Tolstoi" } }, | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice", "author": { "id": 1, "first_name": "Jane", "last_name": "Austen" } }, | ||
{ "id": 3, "author_id": 1, "title": "Sense and Sensibility", "author": { "id": 1, "first_name": "Jane", "last_name": "Austen" } } | ||
] | ||
// embed books in author | ||
GET /authors?embed=["books"] | ||
HTTP 1.1 200 OK | ||
Content-Range: items 0-1/2 | ||
Content-Type: application/json | ||
[ | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi', books: [{ id: 0, author_id: 0, title: 'Anna Karenina' }, { id: 1, author_id: 0, title: 'War and Peace' }] }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen', books: [{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, { id: 3, author_id: 1, title: 'Sense and Sensibility' }] } | ||
] | ||
// embed books in author | ||
GET /authors?embed=["books"] | ||
HTTP 1.1 200 OK | ||
Content-Range: items 0-1/2 | ||
Content-Type: application/json | ||
[ | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi', books: [{ id: 0, author_id: 0, title: 'Anna Karenina' }, { id: 1, author_id: 0, title: 'War and Peace' }] }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen', books: [{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, { id: 3, author_id: 1, title: 'Sense and Sensibility' }] } | ||
] | ||
// you can embed several objects | ||
GET /authors?embed=["books","country"] | ||
// you can embed several objects | ||
GET /authors?embed=["books","country"] | ||
@@ -264,15 +264,15 @@ ### Get A Single Record | ||
GET /books/2 | ||
GET /books/2 | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice" } | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice" } | ||
The `embed` param sets the related objects or collections to be embedded in the response. | ||
GET /books/2?embed=['author'] | ||
GET /books/2?embed=['author'] | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice", "author": { "id": 1, "first_name": "Jane", "last_name": "Austen" } } | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice", "author": { "id": 1, "first_name": "Jane", "last_name": "Austen" } } | ||
@@ -283,21 +283,20 @@ ### Create A Record | ||
POST /books | ||
{ "author_id": 1, "title": "Emma" } | ||
POST /books | ||
{ "author_id": 1, "title": "Emma" } | ||
HTTP 1.1 201 Created | ||
Location: /books/4 | ||
Content-Type: application/json | ||
{ "author_id": 1, "title": "Emma", "id": 4 } | ||
HTTP 1.1 201 Created | ||
Location: /books/4 | ||
Content-Type: application/json | ||
{ "author_id": 1, "title": "Emma", "id": 4 } | ||
### Update A Record | ||
### Update A Record | ||
`PUT /[name]/:id` returns the modified JSON object, and a status 200, unless the resource doesn't exist. | ||
PUT /books/2 | ||
{ "author_id": 1, "title": "Pride and Prejudice" } | ||
PUT /books/2 | ||
{ "author_id": 1, "title": "Pride and Prejudice" } | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice" } | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice" } | ||
@@ -308,7 +307,7 @@ ### Delete A Single Record | ||
DELETE /books/2 | ||
DELETE /books/2 | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice" } | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice" } | ||
@@ -319,43 +318,43 @@ ### Supported Filters | ||
GET /books?filter={"price_lte":20} // return books where the price is less than or equal to 20 | ||
GET /books?filter={"price_lte":20} // return books where the price is less than or equal to 20 | ||
- `_eq`: check for equality on simple values: | ||
GET /books?filter={"price_eq":20} // return books where the price is equal to 20 | ||
GET /books?filter={"price_eq":20} // return books where the price is equal to 20 | ||
- `_neq`: check for inequality on simple values | ||
GET /books?filter={"price_neq":20} // return books where the price is not equal to 20 | ||
GET /books?filter={"price_neq":20} // return books where the price is not equal to 20 | ||
- `_eq_any`: check for equality on any passed values | ||
GET /books?filter={"price_eq_any":[20, 30]} // return books where the price is equal to 20 or 30 | ||
GET /books?filter={"price_eq_any":[20, 30]} // return books where the price is equal to 20 or 30 | ||
- `_neq_any`: check for inequality on any passed values | ||
GET /books?filter={"price_neq_any":[20, 30]} // return books where the price is not equal to 20 nor 30 | ||
GET /books?filter={"price_neq_any":[20, 30]} // return books where the price is not equal to 20 nor 30 | ||
- `_inc_any`: check for items that include any of the passed values | ||
GET /books?filter={"authors_inc_any":['William Gibson', 'Pat Cadigan']} // return books where authors include either 'William Gibson' or 'Pat Cadigan' or both | ||
GET /books?filter={"authors_inc_any":['William Gibson', 'Pat Cadigan']} // return books where authors include either 'William Gibson' or 'Pat Cadigan' or both | ||
- `_q`: check for items that contain the provided text | ||
GET /books?filter={"author_q":['Gibson']} // return books where the author includes 'Gibson' not considering the other fields | ||
GET /books?filter={"author_q":['Gibson']} // return books where the author includes 'Gibson' not considering the other fields | ||
- `_lt`: check for items that have a value lower than the provided value | ||
GET /books?filter={"price_lte":100} // return books that have a price lower that 100 | ||
GET /books?filter={"price_lte":100} // return books that have a price lower that 100 | ||
- `_lte`: check for items that have a value lower than or equal to the provided value | ||
GET /books?filter={"price_lte":100} // return books that have a price lower or equal to 100 | ||
GET /books?filter={"price_lte":100} // return books that have a price lower or equal to 100 | ||
- `_gt`: check for items that have a value greater than the provided value | ||
GET /books?filter={"price_gte":100} // return books that have a price greater that 100 | ||
GET /books?filter={"price_gte":100} // return books that have a price greater that 100 | ||
- `_gte`: check for items that have a value greater than or equal to the provided value | ||
GET /books?filter={"price_gte":100} // return books that have a price greater or equal to 100 | ||
GET /books?filter={"price_gte":100} // return books that have a price greater or equal to 100 | ||
@@ -366,20 +365,20 @@ ### Single Elements | ||
GET /settings | ||
GET /settings | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "language": "english", "preferred_format": "hardback" } | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "language": "english", "preferred_format": "hardback" } | ||
PUT /settings | ||
{ "language": "french", "preferred_format": "paperback" } | ||
PUT /settings | ||
{ "language": "french", "preferred_format": "paperback" } | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "language": "french", "preferred_format": "paperback" } | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "language": "french", "preferred_format": "paperback" } | ||
DELETE /settings | ||
DELETE /settings | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "language": "french", "preferred_format": "paperback" } | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "language": "french", "preferred_format": "paperback" } | ||
@@ -409,9 +408,9 @@ ## Middlewares | ||
headers: {}, | ||
}; | ||
} | ||
}; | ||
} | ||
return next(context); | ||
}, | ||
}, | ||
withDelay(300), | ||
], | ||
], | ||
}); | ||
@@ -448,6 +447,6 @@ ``` | ||
return { status: 401, headers: {} }; | ||
} | ||
} | ||
return next(context); | ||
} | ||
] | ||
} | ||
] | ||
}); | ||
@@ -470,3 +469,3 @@ ``` | ||
!context.requestBody?.title | ||
) { | ||
) { | ||
return { | ||
@@ -478,10 +477,10 @@ status: 400, | ||
title: 'An article with this title already exists. The title must be unique.', | ||
}, | ||
}, | ||
}; | ||
} | ||
}, | ||
}, | ||
}; | ||
} | ||
return next(context); | ||
} | ||
] | ||
} | ||
] | ||
}); | ||
@@ -503,11 +502,11 @@ ``` | ||
context.method === 'POST' | ||
) { | ||
) { | ||
const response = await next(context); | ||
response.body.updatedAt = new Date().toISOString(); | ||
return response; | ||
} | ||
} | ||
return next(context); | ||
} | ||
] | ||
} | ||
] | ||
}); | ||
@@ -529,6 +528,6 @@ ``` | ||
resolve(next(context)); | ||
}, 500); | ||
}); | ||
} | ||
] | ||
}, 500); | ||
}); | ||
} | ||
] | ||
}); | ||
@@ -547,3 +546,3 @@ ``` | ||
withDelay(500), // delay in ms | ||
] | ||
] | ||
}); | ||
@@ -625,3 +624,3 @@ ``` | ||
return {}; | ||
} | ||
} | ||
}); | ||
@@ -660,16 +659,16 @@ ``` | ||
'authors': [ | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi' }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen' } | ||
], | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi' }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen' } | ||
], | ||
'books': [ | ||
{ id: 0, author_id: 0, title: 'Anna Karenina' }, | ||
{ id: 1, author_id: 0, title: 'War and Peace' }, | ||
{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, | ||
{ id: 3, author_id: 1, title: 'Sense and Sensibility' } | ||
], | ||
{ id: 0, author_id: 0, title: 'Anna Karenina' }, | ||
{ id: 1, author_id: 0, title: 'War and Peace' }, | ||
{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, | ||
{ id: 3, author_id: 1, title: 'Sense and Sensibility' } | ||
], | ||
'settings': { | ||
language: 'english', | ||
preferred_format: 'hardback', | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
@@ -693,16 +692,16 @@ window.fakerest = adapter; | ||
'authors': [ | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi' }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen' } | ||
], | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi' }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen' } | ||
], | ||
'books': [ | ||
{ id: 0, author_id: 0, title: 'Anna Karenina' }, | ||
{ id: 1, author_id: 0, title: 'War and Peace' }, | ||
{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, | ||
{ id: 3, author_id: 1, title: 'Sense and Sensibility' } | ||
], | ||
{ id: 0, author_id: 0, title: 'Anna Karenina' }, | ||
{ id: 1, author_id: 0, title: 'War and Peace' }, | ||
{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, | ||
{ id: 3, author_id: 1, title: 'Sense and Sensibility' } | ||
], | ||
'settings': { | ||
language: 'english', | ||
preferred_format: 'hardback', | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
@@ -750,16 +749,16 @@ const adapter = new MswAdapter({ server }); | ||
'authors': [ | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi' }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen' } | ||
], | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi' }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen' } | ||
], | ||
'books': [ | ||
{ id: 0, author_id: 0, title: 'Anna Karenina' }, | ||
{ id: 1, author_id: 0, title: 'War and Peace' }, | ||
{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, | ||
{ id: 3, author_id: 1, title: 'Sense and Sensibility' } | ||
], | ||
{ id: 0, author_id: 0, title: 'Anna Karenina' }, | ||
{ id: 1, author_id: 0, title: 'War and Peace' }, | ||
{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, | ||
{ id: 3, author_id: 1, title: 'Sense and Sensibility' } | ||
], | ||
'settings': { | ||
language: 'english', | ||
preferred_format: 'hardback', | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
@@ -784,16 +783,16 @@ const server = new SimpleRestServer({ baseUrl: 'http://my.custom.domain', database }); | ||
'authors': [ | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi' }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen' } | ||
], | ||
{ id: 0, first_name: 'Leo', last_name: 'Tolstoi' }, | ||
{ id: 1, first_name: 'Jane', last_name: 'Austen' } | ||
], | ||
'books': [ | ||
{ id: 0, author_id: 0, title: 'Anna Karenina' }, | ||
{ id: 1, author_id: 0, title: 'War and Peace' }, | ||
{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, | ||
{ id: 3, author_id: 1, title: 'Sense and Sensibility' } | ||
], | ||
{ id: 0, author_id: 0, title: 'Anna Karenina' }, | ||
{ id: 1, author_id: 0, title: 'War and Peace' }, | ||
{ id: 2, author_id: 1, title: 'Pride and Prejudice' }, | ||
{ id: 3, author_id: 1, title: 'Sense and Sensibility' } | ||
], | ||
'settings': { | ||
language: 'english', | ||
preferred_format: 'hardback', | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
@@ -810,7 +809,7 @@ ``` | ||
GET /books/2?embed=['author'] | ||
GET /books/2?embed=['author'] | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice", "author": { "id": 1, "first_name": "Jane", "last_name": "Austen" } } | ||
HTTP 1.1 200 OK | ||
Content-Type: application/json | ||
{ "id": 2, "author_id": 1, "title": "Pride and Prejudice", "author": { "id": 1, "first_name": "Jane", "last_name": "Austen" } } | ||
@@ -817,0 +816,0 @@ Embeds are defined by the query, they require no setup in the database. |
@@ -1,5 +0,5 @@ | ||
import { SimpleRestServer } from '../SimpleRestServer.js'; | ||
import { parseQueryString } from '../parseQueryString.js'; | ||
import type { BaseServerOptions } from '../SimpleRestServer.js'; | ||
import type { BaseResponse, APIServer, NormalizedRequest } from '../types.js'; | ||
import { SimpleRestServer } from '../SimpleRestServer.ts'; | ||
import { parseQueryString } from '../parseQueryString.ts'; | ||
import type { BaseServerOptions } from '../SimpleRestServer.ts'; | ||
import type { BaseResponse, APIServer, NormalizedRequest } from '../types.ts'; | ||
import type { MockResponseObject } from 'fetch-mock'; | ||
@@ -59,3 +59,3 @@ | ||
response: BaseResponse, | ||
normalizedRequest: NormalizedRequest, | ||
normalizedRequest: NormalizedRequest | ||
) { | ||
@@ -68,3 +68,3 @@ if (!this.loggingEnabled) return; | ||
normalizedRequest.url, | ||
'(FakeRest)', | ||
'(FakeRest)' | ||
); | ||
@@ -89,3 +89,3 @@ console.group('request'); | ||
'body', | ||
request.requestJson, | ||
request.requestJson | ||
); | ||
@@ -98,3 +98,3 @@ console.log( | ||
'body', | ||
response.body, | ||
response.body | ||
); | ||
@@ -101,0 +101,0 @@ } |
@@ -1,4 +0,4 @@ | ||
import { SimpleRestServer } from '../SimpleRestServer.js'; | ||
import type { BaseServerOptions } from '../SimpleRestServer.js'; | ||
import type { APIServer, NormalizedRequest } from '../types.js'; | ||
import { SimpleRestServer } from '../SimpleRestServer.ts'; | ||
import type { BaseServerOptions } from '../SimpleRestServer.ts'; | ||
import type { APIServer, NormalizedRequest } from '../types.ts'; | ||
@@ -27,4 +27,4 @@ export class MswAdapter { | ||
Array.from(new URLSearchParams(url.search).entries()).map( | ||
([key, value]) => [key, JSON.parse(value)], | ||
), | ||
([key, value]) => [key, JSON.parse(value)] | ||
) | ||
); | ||
@@ -31,0 +31,0 @@ let requestBody: Record<string, any> | undefined = undefined; |
import sinon, { type SinonFakeXMLHttpRequest } from 'sinon'; | ||
import { SinonAdapter } from './SinonAdapter.js'; | ||
import type { BaseResponse } from '../types.js'; | ||
import { SinonAdapter } from './SinonAdapter.ts'; | ||
import type { BaseResponse } from '../types.ts'; | ||
@@ -9,3 +9,3 @@ function getFakeXMLHTTPRequest( | ||
url: string, | ||
data?: any, | ||
data?: any | ||
): SinonFakeXMLHttpRequest | null { | ||
@@ -60,3 +60,3 @@ const xhr = sinon.useFakeXMLHttpRequest(); | ||
expect(request?.getResponseHeader('Content-Range')).toEqual( | ||
'items 0-0/2', | ||
'items 0-0/2' | ||
); | ||
@@ -70,3 +70,3 @@ request = getFakeXMLHTTPRequest('GET', '/foo?_start=2&_end=2'); | ||
expect(request?.getResponseHeader('Content-Range')).toEqual( | ||
'items 1-1/2', | ||
'items 1-1/2' | ||
); | ||
@@ -106,3 +106,3 @@ }); | ||
expect(request.responseText).toEqual( | ||
'{"data":[{"id":1,"name":"foo"},{"id":2,"name":"bar"}],"status":200}', | ||
'{"data":[{"id":1,"name":"foo"},{"id":2,"name":"bar"}],"status":200}' | ||
); | ||
@@ -138,9 +138,9 @@ }); | ||
expect(request.responseText).toEqual( | ||
'[{"id":1,"name":"foo"},{"id":2,"name":"bar"}]', | ||
'[{"id":1,"name":"foo"},{"id":2,"name":"bar"}]' | ||
); | ||
expect(request.getResponseHeader('Content-Type')).toEqual( | ||
'application/json', | ||
'application/json' | ||
); | ||
expect(request.getResponseHeader('Content-Range')).toEqual( | ||
'items 0-1/2', | ||
'items 0-1/2' | ||
); | ||
@@ -163,3 +163,3 @@ }); | ||
'GET', | ||
'/foos?filter={"arg":true}&sort=name&slice=[0,10]&embed=["bars"]', | ||
'/foos?filter={"arg":true}&sort=name&slice=[0,10]&embed=["bars"]' | ||
); | ||
@@ -171,9 +171,9 @@ if (request == null) throw new Error('request is null'); | ||
expect(request.responseText).toEqual( | ||
'[{"id":2,"name":"a","arg":true,"bars":[]},{"id":1,"name":"b","arg":true,"bars":[{"id":0,"name":"a","foo_id":1}]}]', | ||
'[{"id":2,"name":"a","arg":true,"bars":[]},{"id":1,"name":"b","arg":true,"bars":[{"id":0,"name":"a","foo_id":1}]}]' | ||
); | ||
expect(request.getResponseHeader('Content-Type')).toEqual( | ||
'application/json', | ||
'application/json' | ||
); | ||
expect(request.getResponseHeader('Content-Range')).toEqual( | ||
'items 0-1/2', | ||
'items 0-1/2' | ||
); | ||
@@ -193,3 +193,3 @@ }); | ||
expect(request.getResponseHeader('Content-Range')).toEqual( | ||
'items 0-10/11', | ||
'items 0-10/11' | ||
); | ||
@@ -201,3 +201,3 @@ request = getFakeXMLHTTPRequest('GET', '/foo?range=[0,4]'); | ||
expect(request.getResponseHeader('Content-Range')).toEqual( | ||
'items 0-4/11', | ||
'items 0-4/11' | ||
); | ||
@@ -209,3 +209,3 @@ request = getFakeXMLHTTPRequest('GET', '/foo?range=[5,9]'); | ||
expect(request.getResponseHeader('Content-Range')).toEqual( | ||
'items 5-9/11', | ||
'items 5-9/11' | ||
); | ||
@@ -217,3 +217,3 @@ request = getFakeXMLHTTPRequest('GET', '/foo?range=[10,14]'); | ||
expect(request.getResponseHeader('Content-Range')).toEqual( | ||
'items 10-10/11', | ||
'items 10-10/11' | ||
); | ||
@@ -234,3 +234,3 @@ }); | ||
expect(request.getResponseHeader('Content-Range')).toEqual( | ||
'items */0', | ||
'items */0' | ||
); | ||
@@ -252,3 +252,3 @@ }); | ||
'/foo', | ||
JSON.stringify({ name: 'baz' }), | ||
JSON.stringify({ name: 'baz' }) | ||
); | ||
@@ -261,3 +261,3 @@ if (request == null) throw new Error('request is null'); | ||
expect(request.getResponseHeader('Content-Type')).toEqual( | ||
'application/json', | ||
'application/json' | ||
); | ||
@@ -279,3 +279,3 @@ expect(request.getResponseHeader('Location')).toEqual('/foo/3'); | ||
'/foo', | ||
JSON.stringify({ name: 'baz' }), | ||
JSON.stringify({ name: 'baz' }) | ||
); | ||
@@ -288,3 +288,3 @@ if (request == null) throw new Error('request is null'); | ||
expect(request.getResponseHeader('Content-Type')).toEqual( | ||
'application/json', | ||
'application/json' | ||
); | ||
@@ -315,3 +315,3 @@ expect(request.getResponseHeader('Location')).toEqual('/foo/0'); | ||
expect(request.getResponseHeader('Content-Type')).toEqual( | ||
'application/json', | ||
'application/json' | ||
); | ||
@@ -342,3 +342,3 @@ }); | ||
'/foo/2', | ||
JSON.stringify({ name: 'baz' }), | ||
JSON.stringify({ name: 'baz' }) | ||
); | ||
@@ -351,3 +351,3 @@ if (request == null) throw new Error('request is null'); | ||
expect(request.getResponseHeader('Content-Type')).toEqual( | ||
'application/json', | ||
'application/json' | ||
); | ||
@@ -367,3 +367,3 @@ // @ts-ignore | ||
'/foo/3', | ||
JSON.stringify({ name: 'baz' }), | ||
JSON.stringify({ name: 'baz' }) | ||
); | ||
@@ -388,3 +388,3 @@ if (request == null) throw new Error('request is null'); | ||
'/foo/2', | ||
JSON.stringify({ name: 'baz' }), | ||
JSON.stringify({ name: 'baz' }) | ||
); | ||
@@ -397,3 +397,3 @@ if (request == null) throw new Error('request is null'); | ||
expect(request.getResponseHeader('Content-Type')).toEqual( | ||
'application/json', | ||
'application/json' | ||
); | ||
@@ -413,3 +413,3 @@ // @ts-ignore | ||
'/foo/3', | ||
JSON.stringify({ name: 'baz' }), | ||
JSON.stringify({ name: 'baz' }) | ||
); | ||
@@ -438,3 +438,3 @@ if (request == null) throw new Error('request is null'); | ||
expect(request.getResponseHeader('Content-Type')).toEqual( | ||
'application/json', | ||
'application/json' | ||
); | ||
@@ -468,3 +468,3 @@ // @ts-ignore | ||
expect(request.getResponseHeader('Content-Type')).toEqual( | ||
'application/json', | ||
'application/json' | ||
); | ||
@@ -481,3 +481,3 @@ }); | ||
'/foo/', | ||
JSON.stringify({ name: 'baz' }), | ||
JSON.stringify({ name: 'baz' }) | ||
); | ||
@@ -490,3 +490,3 @@ if (request == null) throw new Error('request is null'); | ||
expect(request.getResponseHeader('Content-Type')).toEqual( | ||
'application/json', | ||
'application/json' | ||
); | ||
@@ -507,3 +507,3 @@ // @ts-ignore | ||
'/foo/', | ||
JSON.stringify({ name: 'baz' }), | ||
JSON.stringify({ name: 'baz' }) | ||
); | ||
@@ -516,3 +516,3 @@ if (request == null) throw new Error('request is null'); | ||
expect(request.getResponseHeader('Content-Type')).toEqual( | ||
'application/json', | ||
'application/json' | ||
); | ||
@@ -538,3 +538,3 @@ // @ts-ignore | ||
expect(request.getResponseHeader('Content-Range')).toEqual( | ||
'items 2-4/10', | ||
'items 2-4/10' | ||
); | ||
@@ -557,3 +557,3 @@ const expected = [{ id: 2 }, { id: 3 }, { id: 4 }]; | ||
expect(request.getResponseHeader('Content-Range')).toEqual( | ||
'items 0-4/10', | ||
'items 0-4/10' | ||
); | ||
@@ -560,0 +560,0 @@ const expected = [ |
@@ -5,5 +5,5 @@ import type { SinonFakeXMLHttpRequest } from 'sinon'; | ||
type BaseServerOptions, | ||
} from '../SimpleRestServer.js'; | ||
import { parseQueryString } from '../parseQueryString.js'; | ||
import type { BaseResponse, APIServer, NormalizedRequest } from '../types.js'; | ||
} from '../SimpleRestServer.ts'; | ||
import { parseQueryString } from '../parseQueryString.ts'; | ||
import type { BaseResponse, APIServer, NormalizedRequest } from '../types.ts'; | ||
@@ -49,3 +49,3 @@ export class SinonAdapter { | ||
requestBody = JSON.parse( | ||
(req as SinonFakeXMLHttpRequest).requestBody, | ||
(req as SinonFakeXMLHttpRequest).requestBody | ||
); | ||
@@ -102,3 +102,3 @@ } catch (error) { | ||
sinonResponse.headers, | ||
JSON.stringify(sinonResponse.body), | ||
JSON.stringify(sinonResponse.body) | ||
); | ||
@@ -132,3 +132,3 @@ | ||
'body', | ||
request.requestBody, | ||
request.requestBody | ||
); | ||
@@ -141,3 +141,3 @@ console.log( | ||
'body', | ||
response.body, | ||
response.body | ||
); | ||
@@ -144,0 +144,0 @@ } |
@@ -1,4 +0,4 @@ | ||
import { Collection } from './Collection.js'; | ||
import { Database } from './Database.js'; | ||
import type { CollectionItem } from './types.js'; | ||
import { Collection } from './Collection.ts'; | ||
import { Database } from './Database.ts'; | ||
import type { CollectionItem } from './types.ts'; | ||
@@ -124,3 +124,3 @@ describe('Collection', () => { | ||
expect(collection.getAll({ sort: ['name', 'asc'] })).toEqual( | ||
expected, | ||
expected | ||
); | ||
@@ -133,3 +133,3 @@ expected = [ | ||
expect(collection.getAll({ sort: ['name', 'desc'] })).toEqual( | ||
expected, | ||
expected | ||
); | ||
@@ -181,3 +181,3 @@ }); | ||
expect(collection.getAll({ filter: { name: 'b' } })).toEqual( | ||
expected, | ||
expected | ||
); | ||
@@ -196,3 +196,3 @@ }); | ||
expect( | ||
collection.getAll({ filter: { 'deep.value': 'b' } }), | ||
collection.getAll({ filter: { 'deep.value': 'b' } }) | ||
).toEqual(expected); | ||
@@ -211,3 +211,3 @@ }); | ||
expect( | ||
collection.getAll({ filter: { deep: { value: 'b' } } }), | ||
collection.getAll({ filter: { deep: { value: 'b' } } }) | ||
).toEqual(expected); | ||
@@ -230,12 +230,12 @@ }); | ||
expect(collection.getAll({ filter: { is: 'false' } })).toEqual( | ||
expectedFalse, | ||
expectedFalse | ||
); | ||
expect(collection.getAll({ filter: { is: false } })).toEqual( | ||
expectedFalse, | ||
expectedFalse | ||
); | ||
expect(collection.getAll({ filter: { is: 'true' } })).toEqual( | ||
expectedTrue, | ||
expectedTrue | ||
); | ||
expect(collection.getAll({ filter: { is: true } })).toEqual( | ||
expectedTrue, | ||
expectedTrue | ||
); | ||
@@ -257,6 +257,6 @@ }); | ||
expect(collection.getAll({ filter: { tags: 'b' } })).toEqual( | ||
expected, | ||
expected | ||
); | ||
expect(collection.getAll({ filter: { tags: 'f' } })).toEqual( | ||
[], | ||
[] | ||
); | ||
@@ -278,6 +278,6 @@ }); | ||
expect( | ||
collection.getAll({ filter: { 'deep.tags': 'b' } }), | ||
collection.getAll({ filter: { 'deep.tags': 'b' } }) | ||
).toEqual(expected); | ||
expect( | ||
collection.getAll({ filter: { 'deep.tags': 'f' } }), | ||
collection.getAll({ filter: { 'deep.tags': 'f' } }) | ||
).toEqual([]); | ||
@@ -299,6 +299,6 @@ }); | ||
expect( | ||
collection.getAll({ filter: { 'tags.deep': 'b' } }), | ||
collection.getAll({ filter: { 'tags.deep': 'b' } }) | ||
).toEqual(expected); | ||
expect( | ||
collection.getAll({ filter: { 'tags.deep': 'f' } }), | ||
collection.getAll({ filter: { 'tags.deep': 'f' } }) | ||
).toEqual([]); | ||
@@ -326,6 +326,6 @@ }); | ||
expect( | ||
collection.getAll({ filter: { 'tags.name': 'b' } }), | ||
collection.getAll({ filter: { 'tags.name': 'b' } }) | ||
).toEqual(expected); | ||
expect( | ||
collection.getAll({ filter: { 'tags.name': 'f' } }), | ||
collection.getAll({ filter: { 'tags.name': 'f' } }) | ||
).toEqual([]); | ||
@@ -344,3 +344,3 @@ }); | ||
expect( | ||
collection.getAll({ filter: { 'deep.tags': ['b', 'd'] } }), | ||
collection.getAll({ filter: { 'deep.tags': ['b', 'd'] } }) | ||
).toEqual(expected); | ||
@@ -350,3 +350,3 @@ expect( | ||
filter: { 'deep.tags': ['a', 'b', 'e'] }, | ||
}), | ||
}) | ||
).toEqual([]); | ||
@@ -374,6 +374,6 @@ }); | ||
expect( | ||
collection.getAll({ filter: { 'tags.name': ['c'] } }), | ||
collection.getAll({ filter: { 'tags.name': ['c'] } }) | ||
).toEqual(expected); | ||
expect( | ||
collection.getAll({ filter: { 'tags.name': ['h', 'i'] } }), | ||
collection.getAll({ filter: { 'tags.name': ['h', 'i'] } }) | ||
).toEqual([]); | ||
@@ -392,6 +392,6 @@ }); | ||
expect( | ||
collection.getAll({ filter: { tags: ['b', 'd'] } }), | ||
collection.getAll({ filter: { tags: ['b', 'd'] } }) | ||
).toEqual(expected); | ||
expect( | ||
collection.getAll({ filter: { tags: ['a', 'b', 'e'] } }), | ||
collection.getAll({ filter: { tags: ['a', 'b', 'e'] } }) | ||
).toEqual([]); | ||
@@ -468,3 +468,3 @@ }); | ||
expect( | ||
collection.getAll({ filter: { v_eq_any: [1, 3] } }), | ||
collection.getAll({ filter: { v_eq_any: [1, 3] } }) | ||
).toEqual([ | ||
@@ -481,3 +481,3 @@ { v: 1, id: 0 }, | ||
expect( | ||
collection.getAll({ filter: { v_neq_any: [1, 3] } }), | ||
collection.getAll({ filter: { v_neq_any: [1, 3] } }) | ||
).toEqual([{ v: 2, id: 1 }]); | ||
@@ -491,3 +491,3 @@ }); | ||
expect( | ||
collection.getAll({ filter: { v_inc_any: [1, 3] } }), | ||
collection.getAll({ filter: { v_inc_any: [1, 3] } }) | ||
).toEqual([ | ||
@@ -504,3 +504,3 @@ { v: [1, 2], id: 0 }, | ||
expect( | ||
collection.getAll({ filter: { v_ninc_any: [1, 3] } }), | ||
collection.getAll({ filter: { v_ninc_any: [1, 3] } }) | ||
).toEqual([{ v: [2, 4], id: 1 }]); | ||
@@ -514,3 +514,3 @@ }); | ||
expect( | ||
collection.getAll({ filter: { v_inc: [1, 3] } }), | ||
collection.getAll({ filter: { v_inc: [1, 3] } }) | ||
).toEqual([{ v: [3, 1], id: 2 }]); | ||
@@ -545,3 +545,3 @@ }); | ||
expect( | ||
collection.getAll({ filter: { id: [1, 2, 3] } }), | ||
collection.getAll({ filter: { id: [1, 2, 3] } }) | ||
).toEqual([ | ||
@@ -553,3 +553,3 @@ { id: 1, a: 'e' }, | ||
expect( | ||
collection.getAll({ filter: { id: ['1', '2', '3'] } }), | ||
collection.getAll({ filter: { id: ['1', '2', '3'] } }) | ||
).toEqual([ | ||
@@ -567,3 +567,3 @@ { id: 1, a: 'e' }, | ||
expect( | ||
collection.getAll({ filter: { v_gte: 2, v_lte: 2 } }), | ||
collection.getAll({ filter: { v_gte: 2, v_lte: 2 } }) | ||
).toEqual([{ v: 2, id: 1 }]); | ||
@@ -657,3 +657,3 @@ }); | ||
}).toThrow( | ||
new Error("Can't embed a non-existing collection bar"), | ||
new Error("Can't embed a non-existing collection bar") | ||
); | ||
@@ -717,3 +717,3 @@ }); | ||
}).toThrow( | ||
new Error("Can't embed a non-existing collection bars"), | ||
new Error("Can't embed a non-existing collection bars") | ||
); | ||
@@ -872,3 +872,3 @@ }); | ||
expect(authors.getAll({ embed: ['books', 'country'] })).toEqual( | ||
expected, | ||
expected | ||
); | ||
@@ -969,3 +969,3 @@ }); | ||
}).toThrow( | ||
new Error('An item with the identifier 0 already exists'), | ||
new Error('An item with the identifier 0 already exists') | ||
); | ||
@@ -1065,3 +1065,3 @@ }); | ||
expect( | ||
collection.getOne('6090eb22-e140-4720-b7b2-e1416a3d2447'), | ||
collection.getOne('6090eb22-e140-4720-b7b2-e1416a3d2447') | ||
).toEqual({ | ||
@@ -1068,0 +1068,0 @@ id: '6090eb22-e140-4720-b7b2-e1416a3d2447', |
import get from 'lodash/get.js'; | ||
import matches from 'lodash/matches.js'; | ||
import type { Database } from './Database.js'; | ||
import type { Database } from './Database.ts'; | ||
import type { | ||
@@ -33,3 +33,3 @@ CollectionItem, | ||
throw new Error( | ||
"Can't initialize a Collection with anything else than an array of items", | ||
"Can't initialize a Collection with anything else than an array of items" | ||
); | ||
@@ -76,3 +76,3 @@ } | ||
throw new Error( | ||
`Can't embed a non-existing collection ${resourceName}`, | ||
`Can't embed a non-existing collection ${resourceName}` | ||
); | ||
@@ -85,3 +85,3 @@ if (Array.isArray(item[resourceName])) { | ||
item[resourceName].indexOf( | ||
i[otherCollection.identifierName], | ||
i[otherCollection.identifierName] | ||
) !== -1, | ||
@@ -121,3 +121,3 @@ }); | ||
throw new Error( | ||
`Can't embed a non-existing collection ${resourceName}`, | ||
`Can't embed a non-existing collection ${resourceName}` | ||
); | ||
@@ -127,3 +127,3 @@ try { | ||
item[resourceName] = otherCollection.getOne( | ||
item[referenceName], | ||
item[referenceName] | ||
); | ||
@@ -146,3 +146,3 @@ } catch (e) { | ||
? this._oneToManyEmbedder(resourceName) | ||
: this._manyToOneEmbedder(resourceName), | ||
: this._manyToOneEmbedder(resourceName) | ||
); | ||
@@ -152,3 +152,3 @@ return (item: T) => | ||
(itemWithEmbeds, embedder) => embedder(itemWithEmbeds), | ||
item, | ||
item | ||
); | ||
@@ -184,3 +184,3 @@ } | ||
// biome-ignore lint/suspicious/noDoubleEquals: we want implicit type coercion | ||
(item) => item[this.identifierName] == identifier, | ||
(item) => item[this.identifierName] == identifier | ||
); | ||
@@ -211,3 +211,3 @@ } | ||
throw new Error( | ||
`An item with the identifier ${identifier} already exists`, | ||
`An item with the identifier ${identifier} already exists` | ||
); | ||
@@ -254,3 +254,3 @@ } | ||
array: T[], | ||
predicate: Predicate, | ||
predicate: Predicate | ||
) => array.reduce((acc, value) => acc && predicate(value), true); | ||
@@ -260,3 +260,3 @@ | ||
array: T[], | ||
predicate: Predicate, | ||
predicate: Predicate | ||
) => array.reduce((acc, value) => acc || predicate(value), false); | ||
@@ -266,24 +266,21 @@ | ||
keyParts: string[], | ||
item: T, | ||
item: T | ||
) => | ||
keyParts.reduce( | ||
(acc, key, index) => { | ||
// If we already found an array, we don't need to explore further | ||
// For example with path `tags.name` when tags is an array of objects | ||
if (acc != null) { | ||
return acc; | ||
} | ||
keyParts.reduce((acc, key, index) => { | ||
// If we already found an array, we don't need to explore further | ||
// For example with path `tags.name` when tags is an array of objects | ||
if (acc != null) { | ||
return acc; | ||
} | ||
const keyToArray = keyParts.slice(0, index + 1).join('.'); | ||
const keyToItem = keyParts.slice(index + 1).join('.'); | ||
const itemValue = get(item, keyToArray); | ||
const keyToArray = keyParts.slice(0, index + 1).join('.'); | ||
const keyToItem = keyParts.slice(index + 1).join('.'); | ||
const itemValue = get(item, keyToArray); | ||
// If the array is at the end of the key path, we will process it like we do normally with arrays | ||
// For example with path `deep.tags` where tags is the array. In this case, we return undefined | ||
return Array.isArray(itemValue) && index < keyParts.length - 1 | ||
? [keyToArray, keyToItem] | ||
: undefined; | ||
}, | ||
undefined as Array<string> | undefined, | ||
); | ||
// If the array is at the end of the key path, we will process it like we do normally with arrays | ||
// For example with path `deep.tags` where tags is the array. In this case, we return undefined | ||
return Array.isArray(itemValue) && index < keyParts.length - 1 | ||
? [keyToArray, keyToItem] | ||
: undefined; | ||
}, undefined as Array<string> | undefined); | ||
@@ -328,3 +325,3 @@ const getSimpleFilter = (key: string, value: any) => { | ||
return <T extends CollectionItem = CollectionItem>( | ||
item: T, | ||
item: T | ||
// biome-ignore lint/suspicious/noDoubleEquals: we want implicit type coercion | ||
@@ -337,3 +334,3 @@ ) => finalValue.every((val) => get(item, realKey) != val); | ||
return <T extends CollectionItem = CollectionItem>( | ||
item: T, | ||
item: T | ||
// biome-ignore lint/suspicious/noDoubleEquals: we want implicit type coercion | ||
@@ -347,3 +344,3 @@ ) => get(item, realKey) != value; | ||
return <T extends CollectionItem = CollectionItem>( | ||
item: T, | ||
item: T | ||
// biome-ignore lint/suspicious/noDoubleEquals: we want implicit type coercion | ||
@@ -356,3 +353,3 @@ ) => finalValue.some((val) => get(item, realKey) == val); | ||
return <T extends CollectionItem = CollectionItem>( | ||
item: T, | ||
item: T | ||
// biome-ignore lint/suspicious/noDoubleEquals: we want implicit type coercion | ||
@@ -451,3 +448,3 @@ ) => get(item, realKey) == value; | ||
items: T[], | ||
filter: Filter, | ||
filter: Filter | ||
) { | ||
@@ -464,5 +461,5 @@ if (typeof filter === 'function') { | ||
const filterWithQuery = < | ||
T2 extends CollectionItem = CollectionItem, | ||
T2 extends CollectionItem = CollectionItem | ||
>( | ||
item: T2, | ||
item: T2 | ||
) => { | ||
@@ -495,7 +492,7 @@ for (const itemKey in item) { | ||
return <T2 extends CollectionItem = CollectionItem>( | ||
item: T2, | ||
item: T2 | ||
): boolean => { | ||
const arrayOfObjectsPaths = getArrayOfObjectsPaths( | ||
keyParts, | ||
item, | ||
item | ||
); | ||
@@ -525,4 +522,4 @@ | ||
(selected, filterFunction) => selected && filterFunction(item), | ||
true, | ||
), | ||
true | ||
) | ||
); | ||
@@ -535,3 +532,3 @@ } | ||
items: T[], | ||
sort: Sort, | ||
sort: Sort | ||
) { | ||
@@ -570,3 +567,3 @@ if (typeof sort === 'function') { | ||
items: T[], | ||
range: Range, | ||
range: Range | ||
) { | ||
@@ -576,3 +573,3 @@ if (Array.isArray(range)) { | ||
range[0], | ||
range[1] !== undefined ? range[1] + 1 : undefined, | ||
range[1] !== undefined ? range[1] + 1 : undefined | ||
); | ||
@@ -579,0 +576,0 @@ } |
@@ -1,4 +0,4 @@ | ||
import { Database } from './Database.js'; | ||
import { Single } from './Single.js'; | ||
import { Collection } from './Collection.js'; | ||
import { Database } from './Database.ts'; | ||
import { Single } from './Single.ts'; | ||
import { Collection } from './Collection.ts'; | ||
@@ -61,7 +61,7 @@ describe('Database', () => { | ||
], | ||
}), | ||
}) | ||
); | ||
server.addCollection( | ||
'baz', | ||
new Collection({ items: [{ id: 1, name: 'baz' }] }), | ||
new Collection({ items: [{ id: 1, name: 'baz' }] }) | ||
); | ||
@@ -85,3 +85,3 @@ expect(server.getAll('foo')).toEqual([ | ||
], | ||
}), | ||
}) | ||
); | ||
@@ -106,3 +106,3 @@ const params = { | ||
'foo', | ||
new Collection({ items: [{ id: 1, name: 'foo' }] }), | ||
new Collection({ items: [{ id: 1, name: 'foo' }] }) | ||
); | ||
@@ -123,3 +123,3 @@ expect(() => { | ||
], | ||
}), | ||
}) | ||
); | ||
@@ -140,3 +140,3 @@ expect(server.getOne('foo', 1)).toEqual({ id: 1, name: 'foo' }); | ||
identifierName: '_id', | ||
}), | ||
}) | ||
); | ||
@@ -143,0 +143,0 @@ expect(server.getOne('foo', 1)).toEqual({ _id: 1, name: 'foo' }); |
@@ -1,4 +0,4 @@ | ||
import { Collection } from './Collection.js'; | ||
import { Single } from './Single.js'; | ||
import type { CollectionItem, Query, QueryFunction } from './types.js'; | ||
import { Collection } from './Collection.ts'; | ||
import { Single } from './Single.ts'; | ||
import type { CollectionItem, Query, QueryFunction } from './types.ts'; | ||
@@ -37,3 +37,3 @@ export class Database { | ||
getNewId: this.getNewId, | ||
}), | ||
}) | ||
); | ||
@@ -48,3 +48,3 @@ } else { | ||
name: string, | ||
collection: Collection<T>, | ||
collection: Collection<T> | ||
) { | ||
@@ -66,3 +66,3 @@ this.collections[name] = collection; | ||
name: string, | ||
single: Single<T>, | ||
single: Single<T> | ||
) { | ||
@@ -110,3 +110,3 @@ this.singles[name] = single; | ||
getNewId: this.getNewId, | ||
}), | ||
}) | ||
); | ||
@@ -113,0 +113,0 @@ } |
@@ -1,9 +0,9 @@ | ||
export * from './types.js'; | ||
export * from './adapters/SinonAdapter.js'; | ||
export * from './adapters/FetchMockAdapter.js'; | ||
export * from './adapters/MswAdapter.js'; | ||
export * from './Database.js'; | ||
export * from './SimpleRestServer.js'; | ||
export * from './Collection.js'; | ||
export * from './Single.js'; | ||
export * from './withDelay.js'; | ||
export * from './types.ts'; | ||
export * from './adapters/SinonAdapter.ts'; | ||
export * from './adapters/FetchMockAdapter.ts'; | ||
export * from './adapters/MswAdapter.ts'; | ||
export * from './Database.ts'; | ||
export * from './SimpleRestServer.ts'; | ||
export * from './Collection.ts'; | ||
export * from './Single.ts'; | ||
export * from './withDelay.ts'; |
@@ -1,4 +0,4 @@ | ||
import type { Collection } from './Collection.js'; | ||
import { Database, type DatabaseOptions } from './Database.js'; | ||
import type { Single } from './Single.js'; | ||
import type { Collection } from './Collection.ts'; | ||
import { Database, type DatabaseOptions } from './Database.ts'; | ||
import type { Single } from './Single.ts'; | ||
import type { | ||
@@ -11,3 +11,3 @@ APIServer, | ||
NormalizedRequest, | ||
} from './types.js'; | ||
} from './types.ts'; | ||
@@ -48,3 +48,3 @@ export class SimpleRestServer implements APIServer { | ||
const matches = normalizedRequest.url?.match( | ||
new RegExp(`^${this.baseUrl}\\/(${name})(\\/?.*)?$`), | ||
new RegExp(`^${this.baseUrl}\\/(${name})(\\/?.*)?$`) | ||
); | ||
@@ -59,3 +59,3 @@ if (!matches) continue; | ||
const matches = normalizedRequest.url?.match( | ||
new RegExp(`^${this.baseUrl}\\/([^\\/?]+)(\\/(\\w))?(\\?.*)?$`), | ||
new RegExp(`^${this.baseUrl}\\/([^\\/?]+)(\\/(\\w))?(\\?.*)?$`) | ||
); | ||
@@ -67,3 +67,3 @@ if (matches) { | ||
this.defaultQuery(name), | ||
normalizedRequest.params, | ||
normalizedRequest.params | ||
); | ||
@@ -111,3 +111,3 @@ | ||
const matches = context.url?.match( | ||
new RegExp(`^${this.baseUrl}\\/(${name})(\\/?.*)?$`), | ||
new RegExp(`^${this.baseUrl}\\/(${name})(\\/?.*)?$`) | ||
); | ||
@@ -144,3 +144,3 @@ if (!matches) continue; | ||
name, | ||
context.requestBody, | ||
context.requestBody | ||
), | ||
@@ -170,3 +170,3 @@ headers: { | ||
name, | ||
context.requestBody, | ||
context.requestBody | ||
), | ||
@@ -188,3 +188,3 @@ headers: { | ||
const matches = context.url?.match( | ||
new RegExp(`^${this.baseUrl}\\/([^\\/?]+)(\\/(\\w))?(\\?.*)?$`), | ||
new RegExp(`^${this.baseUrl}\\/([^\\/?]+)(\\/(\\w))?(\\?.*)?$`) | ||
); | ||
@@ -198,3 +198,3 @@ if (!matches) { | ||
this.defaultQuery(name), | ||
context.params, | ||
context.params | ||
); | ||
@@ -208,3 +208,3 @@ if (!matches[2]) { | ||
name, | ||
params.filter ? { filter: params.filter } : {}, | ||
params.filter ? { filter: params.filter } : {} | ||
); | ||
@@ -218,3 +218,3 @@ if (count > 0) { | ||
items.length - 1 + first, | ||
params.range[1], | ||
params.range[1] | ||
) | ||
@@ -252,3 +252,3 @@ : items.length - 1; | ||
name, | ||
context.requestBody, | ||
context.requestBody | ||
); | ||
@@ -304,3 +304,3 @@ const newResourceURI = `${this.baseUrl}/${name}/${ | ||
id, | ||
context.requestBody, | ||
context.requestBody | ||
), | ||
@@ -331,3 +331,3 @@ headers: { | ||
id, | ||
context.requestBody, | ||
context.requestBody | ||
), | ||
@@ -374,3 +374,3 @@ headers: { | ||
name: string, | ||
collection: Collection<T>, | ||
collection: Collection<T> | ||
) { | ||
@@ -390,3 +390,3 @@ this.database.addCollection(name, collection); | ||
name: string, | ||
single: Single<T>, | ||
single: Single<T> | ||
) { | ||
@@ -407,3 +407,3 @@ this.database.addSingle(name, single); | ||
context: FakeRestContext, | ||
next: (context: FakeRestContext) => Promise<BaseResponse> | BaseResponse, | ||
next: (context: FakeRestContext) => Promise<BaseResponse> | BaseResponse | ||
) => Promise<BaseResponse> | BaseResponse; | ||
@@ -410,0 +410,0 @@ |
@@ -1,4 +0,4 @@ | ||
import { Single } from './Single.js'; | ||
import { Collection } from './Collection.js'; | ||
import { Database } from './Database.js'; | ||
import { Single } from './Single.ts'; | ||
import { Collection } from './Collection.ts'; | ||
import { Database } from './Database.ts'; | ||
@@ -27,3 +27,3 @@ describe('Single', () => { | ||
}).toThrow( | ||
new Error("Can't embed a non-existing collection bar"), | ||
new Error("Can't embed a non-existing collection bar") | ||
); | ||
@@ -69,3 +69,3 @@ }); | ||
}).toThrow( | ||
new Error("Can't embed a non-existing collection bars"), | ||
new Error("Can't embed a non-existing collection bars") | ||
); | ||
@@ -132,3 +132,3 @@ }); | ||
expect(foo.getOnly({ embed: ['bars', 'bazs'] })).toEqual( | ||
expected, | ||
expected | ||
); | ||
@@ -135,0 +135,0 @@ }); |
@@ -1,3 +0,3 @@ | ||
import type { Database } from './Database.js'; | ||
import type { CollectionItem, Embed, Query } from './types.js'; | ||
import type { Database } from './Database.ts'; | ||
import type { CollectionItem, Embed, Query } from './types.ts'; | ||
@@ -12,3 +12,3 @@ export class Single<T extends CollectionItem = CollectionItem> { | ||
throw new Error( | ||
"Can't initialize a Single with anything except an object", | ||
"Can't initialize a Single with anything except an object" | ||
); | ||
@@ -42,3 +42,3 @@ } | ||
throw new Error( | ||
`Can't embed a non-existing collection ${resourceName}`, | ||
`Can't embed a non-existing collection ${resourceName}` | ||
); | ||
@@ -51,3 +51,3 @@ // We have an array of ids {posts: [1,2]} (back refs are not valid | ||
item[resourceName].indexOf( | ||
i[otherCollection.identifierName], | ||
i[otherCollection.identifierName] | ||
) !== -1, | ||
@@ -70,3 +70,3 @@ }); | ||
throw new Error( | ||
`Can't embed a non-existing collection ${resourceName}`, | ||
`Can't embed a non-existing collection ${resourceName}` | ||
); | ||
@@ -76,3 +76,3 @@ try { | ||
item[resourceName] = otherCollection.getOne( | ||
item[referenceName], | ||
item[referenceName] | ||
); | ||
@@ -91,3 +91,3 @@ } catch (e) { | ||
? this._oneToManyEmbedder(resourceName) | ||
: this._manyToOneEmbedder(resourceName), | ||
: this._manyToOneEmbedder(resourceName) | ||
); | ||
@@ -97,3 +97,3 @@ return (item: T) => | ||
(itemWithEmbeds, embedder) => embedder(itemWithEmbeds), | ||
item, | ||
item | ||
); | ||
@@ -100,0 +100,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import type { Middleware } from './SimpleRestServer.js'; | ||
import type { Middleware } from './SimpleRestServer.ts'; | ||
@@ -3,0 +3,0 @@ export const withDelay = |
@@ -14,3 +14,4 @@ { | ||
"types": ["vitest/globals"], | ||
"jsx": "react-jsx" | ||
"jsx": "react-jsx", | ||
"allowImportingTsExtensions": true | ||
}, | ||
@@ -17,0 +18,0 @@ "include": ["src"], |
@@ -16,2 +16,3 @@ # Upgrading to 4.0.0 | ||
```diff | ||
import sinon from 'sinon'; | ||
-import { Server } from 'fakerest'; | ||
@@ -24,2 +25,4 @@ +import { SinonAdapter } from 'fakerest'; | ||
+const server = new SinonAdapter({ baseUrl: 'http://myapi.com', data }); | ||
const server = sinon.fakeServer.create(); | ||
server.respondWith(server.getHandler()); | ||
``` | ||
@@ -32,2 +35,3 @@ | ||
```diff | ||
import fetchMock from 'fetch-mock'; | ||
-import { FetchServer } from 'fakerest'; | ||
@@ -40,2 +44,3 @@ +import { FetchMockAdapter } from 'fakerest'; | ||
+const server = new FetchMockAdapter({ baseUrl: 'http://myapi.com', data }); | ||
fetchMock.mock('begin:http://myapi.com', server.getHandler()); | ||
``` | ||
@@ -46,2 +51,4 @@ | ||
```diff | ||
import { Collection } from 'fakerest'; | ||
-const posts = new Collection([ | ||
@@ -61,2 +68,18 @@ - { id: 1, title: 'baz' }, | ||
## `addCollection` is now `adapter.server.addCollection` | ||
```diff | ||
import fetchMock from 'fetch-mock'; | ||
-import { FetchServer } from 'fakerest'; | ||
+import { FetchMockAdapter } from 'fakerest'; | ||
import { posts } from './posts'; | ||
-const server = new FetchServer('http://myapi.com'); | ||
-server.addCollection('posts', posts); | ||
-fetchMock.mock('begin:http://myapi.com', server.getHandler()); | ||
+const adapter = new FetchMockAdapter({ baseUrl: 'http://myapi.com', data }); | ||
+adapter.server.addCollection('posts', posts); | ||
+fetchMock.mock('begin:http://myapi.com', adapter.getHandler()); | ||
``` | ||
## Request and Response Interceptors Have Been Replaced By Middlewares | ||
@@ -63,0 +86,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1438868
11985
823