Skip to content

Commit

Permalink
Apply review suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
djhi committed Jun 6, 2024
1 parent c59cce2 commit 7e883eb
Show file tree
Hide file tree
Showing 15 changed files with 251 additions and 223 deletions.
38 changes: 30 additions & 8 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,48 @@
# Upgrading to 4.0.0

## Constructors Of `FetchServer` and `Server` Take An Object
## Renamed `Server` And `FetchServer`

For `Server`:
The `Server` class has been renamed to `SinonServer`.

```diff
import { Server } from 'fakerest';
import { data } from './data';
-import { Server } from 'fakerest';
+import { SinonServer } from 'fakerest';

-const server = new Server('http://myapi.com');
+const server = new Server({ baseUrl: 'http://myapi.com' });
+const server = new SinonServer({ baseUrl: 'http://myapi.com' });
```

The `FetchServer` class has been renamed to `FetchMockServer`.

```diff
-import { FetchServer } from 'fakerest';
+import { FetchMockServer } from 'fakerest';

-const server = new FetchServer('http://myapi.com');
+const server = new FetchMockServer({ baseUrl: 'http://myapi.com' });
```

## Constructors Of `SinonServer` and `FetchMockServer` Take An Object

For `SinonServer`:

```diff
import { SinonServer } from 'fakerest';
import { data } from './data';

-const server = new SinonServer('http://myapi.com');
+const server = new SinonServer({ baseUrl: 'http://myapi.com' });
server.init(data);
```

For `FetchServer`:

```diff
import { FetchServer } from 'fakerest';
import { FetchMockServer } from 'fakerest';
import { data } from './data';

-const server = new FetchServer('http://myapi.com');
+const server = new FetchServer({ baseUrl: 'http://myapi.com' });
-const server = new FetchMockServer('http://myapi.com');
+const server = new FetchMockServer({ baseUrl: 'http://myapi.com' });
server.init(data);
```

Expand Down
5 changes: 2 additions & 3 deletions example/msw.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { setupWorker } from 'msw/browser';
import { HttpResponse } from 'msw';
import { MswServer, withDelay } from '../src/FakeRest';
import { MswServer, withDelay } from '../src';
import { data } from './data';
import { dataProvider as defaultDataProvider } from './dataProvider';

Expand Down Expand Up @@ -43,6 +42,6 @@ restServer.addMiddleware(async (request, context, next) => {
return next(request, context);
});

export const worker = setupWorker(...restServer.getHandlers());
export const worker = setupWorker(restServer.getHandler());

export const dataProvider = defaultDataProvider;
102 changes: 94 additions & 8 deletions src/BaseServer.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,67 @@
import {
type BaseResponse,
type FakeRestContext,
AbstractBaseServer,
} from './AbstractBaseServer.js';
import { Database, type DatabaseOptions } from './Database.js';
import type { QueryFunction } from './types.js';

export class BaseServer<RequestType, ResponseType> extends AbstractBaseServer {
export class BaseServer<RequestType, ResponseType> extends Database {
baseUrl = '';
defaultQuery: QueryFunction = () => ({});
middlewares: Array<Middleware<RequestType>> = [];

extractContext(
constructor({
baseUrl = '',
defaultQuery = () => ({}),
...options
}: BaseServerOptions = {}) {
super(options);
this.baseUrl = baseUrl;
this.defaultQuery = defaultQuery;
}

/**
* @param Function ResourceName => object
*/
setDefaultQuery(query: QueryFunction) {
this.defaultQuery = query;
}

getContext(
context: Pick<
FakeRestContext,
'url' | 'method' | 'params' | 'requestJson'
>,
): FakeRestContext {
for (const name of this.getSingleNames()) {
const matches = context.url?.match(
new RegExp(`^${this.baseUrl}\\/(${name})(\\/?.*)?$`),
);
if (!matches) continue;
return {
...context,
single: name,
};
}

const matches = context.url?.match(
new RegExp(`^${this.baseUrl}\\/([^\\/?]+)(\\/(\\w))?(\\?.*)?$`),
);
if (matches) {
const name = matches[1];
const params = Object.assign(
{},
this.defaultQuery(name),
context.params,
);

return {
...context,
collection: name,
params,
};
}

return context;
}

getNormalizedRequest(
request: RequestType,
): Promise<
Pick<FakeRestContext, 'url' | 'method' | 'params' | 'requestJson'>
Expand All @@ -24,7 +78,9 @@ export class BaseServer<RequestType, ResponseType> extends AbstractBaseServer {
}

async handle(request: RequestType): Promise<ResponseType | undefined> {
const context = this.getContext(await this.extractContext(request));
const context = this.getContext(
await this.getNormalizedRequest(request),
);

// Call middlewares
let index = 0;
Expand Down Expand Up @@ -294,3 +350,33 @@ export type Middleware<RequestType> = (
ctx: FakeRestContext,
) => Promise<BaseResponse | null> | BaseResponse | null,
) => Promise<BaseResponse | null> | BaseResponse | null;

export type BaseServerOptions = DatabaseOptions & {
baseUrl?: string;
batchUrl?: string | null;
defaultQuery?: QueryFunction;
};

export type BaseRequest = {
url?: string;
method?: string;
collection?: string;
single?: string;
requestJson?: Record<string, any> | undefined;
params?: { [key: string]: any };
};

export type BaseResponse = {
status: number;
body?: Record<string, any> | Record<string, any>[];
headers: { [key: string]: string };
};

export type FakeRestContext = {
url?: string;
method?: string;
collection?: string;
single?: string;
requestJson: Record<string, any> | undefined;
params: { [key: string]: any };
};
6 changes: 3 additions & 3 deletions src/Collection.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import get from 'lodash/get.js';
import matches from 'lodash/matches.js';
import type { AbstractBaseServer } from './AbstractBaseServer.js';
import type { Database } from './Database.js';
import type {
CollectionItem,
Embed,
Expand All @@ -14,7 +14,7 @@ import type {
export class Collection<T extends CollectionItem = CollectionItem> {
sequence = 0;
items: T[] = [];
server: AbstractBaseServer | null = null;
server: Database | null = null;
name: string | null = null;
identifierName = 'id';
getNewId: () => number | string;
Expand Down Expand Up @@ -42,7 +42,7 @@ export class Collection<T extends CollectionItem = CollectionItem> {
* A Collection may need to access other collections (e.g. for embedding references)
* This is done through a reference to the parent server.
*/
setServer(server: AbstractBaseServer) {
setServer(server: Database) {
this.server = server;
}

Expand Down
22 changes: 10 additions & 12 deletions src/AbstractBaseServer.spec.ts → src/Database.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import sinon, { type SinonFakeXMLHttpRequest } from 'sinon';

import { AbstractBaseServer } from './AbstractBaseServer.js';
import { Database } from './Database.js';
import { Single } from './Single.js';
import { Collection } from './Collection.js';

describe('AbstractBaseServer', () => {
describe('init', () => {
it('should populate several collections', () => {
const server = new AbstractBaseServer();
const server = new Database();
server.init({
foo: [{ a: 1 }, { a: 2 }, { a: 3 }],
bar: [{ b: true }, { b: false }],
Expand All @@ -28,7 +26,7 @@ describe('AbstractBaseServer', () => {

describe('addCollection', () => {
it('should add a collection and index it by name', () => {
const server = new AbstractBaseServer();
const server = new Database();
const collection = new Collection({
items: [
{ id: 1, name: 'foo' },
Expand All @@ -43,7 +41,7 @@ describe('AbstractBaseServer', () => {

describe('addSingle', () => {
it('should add a single object and index it by name', () => {
const server = new AbstractBaseServer();
const server = new Database();
const single = new Single({ name: 'foo', description: 'bar' });
server.addSingle('foo', single);
expect(server.getSingle('foo')).toEqual(single);
Expand All @@ -52,7 +50,7 @@ describe('AbstractBaseServer', () => {

describe('getAll', () => {
it('should return all items for a given name', () => {
const server = new AbstractBaseServer();
const server = new Database();
server.addCollection(
'foo',
new Collection({
Expand All @@ -74,7 +72,7 @@ describe('AbstractBaseServer', () => {
});

it('should support a query', () => {
const server = new AbstractBaseServer();
const server = new Database();
server.addCollection(
'foo',
new Collection({
Expand All @@ -100,7 +98,7 @@ describe('AbstractBaseServer', () => {

describe('getOne', () => {
it('should return an error when no collection match the identifier', () => {
const server = new AbstractBaseServer();
const server = new Database();
server.addCollection(
'foo',
new Collection({ items: [{ id: 1, name: 'foo' }] }),
Expand All @@ -111,7 +109,7 @@ describe('AbstractBaseServer', () => {
});

it('should return the first collection matching the identifier', () => {
const server = new AbstractBaseServer();
const server = new Database();
server.addCollection(
'foo',
new Collection({
Expand All @@ -126,7 +124,7 @@ describe('AbstractBaseServer', () => {
});

it('should use the identifierName', () => {
const server = new AbstractBaseServer();
const server = new Database();
server.addCollection(
'foo',
new Collection({
Expand All @@ -144,7 +142,7 @@ describe('AbstractBaseServer', () => {

describe('getOnly', () => {
it('should return the single matching the identifier', () => {
const server = new AbstractBaseServer();
const server = new Database();
server.addSingle('foo', new Single({ name: 'foo' }));
expect(server.getOnly('foo')).toEqual({ name: 'foo' });
});
Expand Down
Loading

0 comments on commit 7e883eb

Please sign in to comment.