├── test
├── mock
│ ├── invalid.json
│ ├── error.json
│ ├── image-1.json
│ ├── issue-falsy-meta-value.json
│ ├── event-1c.json
│ ├── session-1.json
│ ├── event-1b.json
│ ├── event-1.json
│ ├── queue-1.json
│ ├── issue-84b.json
│ ├── events-2.json
│ ├── issue-84e.json
│ ├── issue-84a.json
│ ├── issue-84c.json
│ ├── issue-84d.json
│ ├── event-1d.json
│ ├── jsonapi-object.json
│ ├── events-1.json
│ └── issue-29.json
├── mocha.opts
├── main.ts
├── utils
│ ├── setup.ts
│ └── api.ts
├── network
│ ├── headers.ts
│ ├── error-handling.ts
│ ├── params.ts
│ ├── caching.ts
│ └── basics.ts
└── issues.ts
├── dist
├── interfaces
│ ├── IJsonApiRecord.js
│ ├── IJsonApiResponse.js
│ ├── IJsonApiIdentifier.js
│ ├── IJsonApiRelationship.js
│ ├── ICache.js
│ ├── IFilters.js
│ ├── IHeaders.js
│ ├── JsonApi.js
│ ├── IDictionary.js
│ ├── IRawResponse.js
│ ├── IRequestOptions.js
│ ├── IResponseHeaders.js
│ ├── IDictionary.d.ts
│ ├── IResponseHeaders.d.ts
│ ├── IHeaders.d.ts
│ ├── IFilters.d.ts
│ ├── IJsonApiIdentifier.d.ts
│ ├── IJsonApiResponse.d.ts
│ ├── ICache.d.ts
│ ├── IJsonApiRelationship.d.ts
│ ├── IJsonApiRecord.d.ts
│ ├── IRawResponse.d.ts
│ ├── IRequestOptions.d.ts
│ └── JsonApi.d.ts
├── enums
│ ├── ParamArrayType.d.ts
│ └── ParamArrayType.js
├── index.js
├── index.d.ts
├── NetworkStore.d.ts
├── NetworkStore.js
├── utils.d.ts
├── NetworkUtils.d.ts
├── Store.d.ts
├── utils.js
├── Response.d.ts
├── Record.d.ts
├── Response.js
├── Store.js
├── NetworkUtils.js
└── Record.js
├── typings
├── index.d.ts
└── globals
│ └── isomorphic-fetch
│ ├── typings.json
│ └── index.d.ts
├── .npmignore
├── src
├── interfaces
│ ├── IDictionary.ts
│ ├── IHeaders.ts
│ ├── IResponseHeaders.ts
│ ├── IFilters.ts
│ ├── ICache.ts
│ ├── IRequestOptions.ts
│ ├── IRawResponse.ts
│ └── JsonApi.ts
├── enums
│ └── ParamArrayType.ts
├── index.ts
├── NetworkStore.ts
├── utils.ts
├── Response.ts
├── Store.ts
├── Record.ts
└── NetworkUtils.ts
├── typings.json
├── .codeclimate.yml
├── .travis.yml
├── tslint.json
├── tsconfig.json
├── .gitignore
├── LICENSE
├── package.json
├── README.md
└── jsonapi.md
/test/mock/invalid.json:
--------------------------------------------------------------------------------
1 |
Not found
--------------------------------------------------------------------------------
/dist/interfaces/IJsonApiRecord.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
--------------------------------------------------------------------------------
/dist/interfaces/IJsonApiResponse.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
--------------------------------------------------------------------------------
/dist/interfaces/IJsonApiIdentifier.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
--------------------------------------------------------------------------------
/dist/interfaces/IJsonApiRelationship.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
--------------------------------------------------------------------------------
/typings/index.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | src
2 | test
3 | .codeclimate.yml
4 | .travis.yml
5 | tsconfig.json
6 | tslint.json
7 |
--------------------------------------------------------------------------------
/dist/interfaces/ICache.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 |
--------------------------------------------------------------------------------
/dist/interfaces/IFilters.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 |
--------------------------------------------------------------------------------
/dist/interfaces/IHeaders.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 |
--------------------------------------------------------------------------------
/dist/interfaces/JsonApi.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 |
--------------------------------------------------------------------------------
/test/mock/error.json:
--------------------------------------------------------------------------------
1 | {
2 | "errors": [{
3 | "title": "Unknown error",
4 | "status": "123"
5 | }]
6 | }
--------------------------------------------------------------------------------
/dist/interfaces/IDictionary.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 |
--------------------------------------------------------------------------------
/dist/interfaces/IRawResponse.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 |
--------------------------------------------------------------------------------
/dist/interfaces/IRequestOptions.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 |
--------------------------------------------------------------------------------
/dist/interfaces/IResponseHeaders.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 |
--------------------------------------------------------------------------------
/dist/interfaces/IDictionary.d.ts:
--------------------------------------------------------------------------------
1 | interface IDictionary {
2 | [key: string]: T;
3 | }
4 | export default IDictionary;
5 |
--------------------------------------------------------------------------------
/src/interfaces/IDictionary.ts:
--------------------------------------------------------------------------------
1 | interface IDictionary {
2 | [key: string]: T;
3 | }
4 |
5 | export default IDictionary;
6 |
--------------------------------------------------------------------------------
/test/mocha.opts:
--------------------------------------------------------------------------------
1 | --require ts-node/register
2 | --full-trace
3 | --check-leaks
4 | --recursive
5 | --bail
6 | src/**/*.ts test/main.ts
--------------------------------------------------------------------------------
/dist/interfaces/IResponseHeaders.d.ts:
--------------------------------------------------------------------------------
1 | interface IResponseHeaders {
2 | get(name: string): string;
3 | }
4 | export default IResponseHeaders;
5 |
--------------------------------------------------------------------------------
/src/interfaces/IHeaders.ts:
--------------------------------------------------------------------------------
1 | import IDictionary from './IDictionary';
2 |
3 | type IHeaders = IDictionary;
4 | export default IHeaders;
5 |
--------------------------------------------------------------------------------
/src/interfaces/IResponseHeaders.ts:
--------------------------------------------------------------------------------
1 | interface IResponseHeaders {
2 | get(name: string): string;
3 | }
4 |
5 | export default IResponseHeaders;
6 |
--------------------------------------------------------------------------------
/typings.json:
--------------------------------------------------------------------------------
1 | {
2 | "globalDevDependencies": {
3 | "isomorphic-fetch": "registry:dt/isomorphic-fetch#0.0.0+20170223183302"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/dist/interfaces/IHeaders.d.ts:
--------------------------------------------------------------------------------
1 | import IDictionary from './IDictionary';
2 | declare type IHeaders = IDictionary;
3 | export default IHeaders;
4 |
--------------------------------------------------------------------------------
/src/interfaces/IFilters.ts:
--------------------------------------------------------------------------------
1 | interface IFilters {
2 | [key: string]: number|string|Array|Array|IFilters;
3 | }
4 |
5 | export default IFilters;
6 |
--------------------------------------------------------------------------------
/dist/interfaces/IFilters.d.ts:
--------------------------------------------------------------------------------
1 | interface IFilters {
2 | [key: string]: number | string | Array | Array | IFilters;
3 | }
4 | export default IFilters;
5 |
--------------------------------------------------------------------------------
/dist/interfaces/IJsonApiIdentifier.d.ts:
--------------------------------------------------------------------------------
1 | interface IJsonApiIdentifier {
2 | id: number | string;
3 | type: string;
4 | }
5 | export default IJsonApiIdentifier;
6 |
--------------------------------------------------------------------------------
/test/mock/image-1.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "id": 1,
4 | "type": "image",
5 | "attributes": {
6 | "url": "http://example.com/1.jpg"
7 | }
8 | }
9 | }
--------------------------------------------------------------------------------
/test/mock/issue-falsy-meta-value.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "id": 1,
4 | "type": "event",
5 | "attributes": {},
6 | "meta": {
7 | "count": 0
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/dist/enums/ParamArrayType.d.ts:
--------------------------------------------------------------------------------
1 | declare enum ParamArrayType {
2 | MULTIPLE_PARAMS = 0,
3 | COMMA_SEPARATED = 1,
4 | PARAM_ARRAY = 2,
5 | OBJECT_PATH = 3
6 | }
7 | export default ParamArrayType;
8 |
--------------------------------------------------------------------------------
/test/mock/event-1c.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "id": "110ec58a-a0f2-4ac4-8393-c866d813b8d1",
4 | "type": "event",
5 | "attributes": {
6 | "title": "Test 1",
7 | "date": "2017-03-19"
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/test/mock/session-1.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "id": 12345,
4 | "type": "sessions",
5 | "attributes": {
6 | "token": "test123"
7 | },
8 | "links": {
9 | "image": "http://example.com/user/1"
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/dist/interfaces/IJsonApiResponse.d.ts:
--------------------------------------------------------------------------------
1 | import IJsonApiRecord from './IJsonApiRecord';
2 | interface IJsonApiResponse {
3 | data: IJsonApiRecord | Array;
4 | included?: Array;
5 | }
6 | export default IJsonApiResponse;
7 |
--------------------------------------------------------------------------------
/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | engines:
2 | duplication:
3 | enabled: true
4 | config:
5 | languages:
6 | - javascript
7 | fixme:
8 | enabled: true
9 | ratings:
10 | paths:
11 | "**.ts"
12 | exclude_paths:
13 | - dist/
14 | - test/
--------------------------------------------------------------------------------
/test/main.ts:
--------------------------------------------------------------------------------
1 | import './general';
2 |
3 | import './network/basics';
4 | import './network/caching';
5 | import './network/error-handling';
6 | import './network/headers';
7 | import './network/params';
8 | import './network/updates';
9 |
10 | import './issues';
11 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "6"
4 | - "8"
5 | - "10"
6 | install:
7 | - npm install
8 | script:
9 | - npm test
10 | after_success:
11 | - npm install -g codeclimate-test-reporter
12 | - codeclimate-test-reporter < coverage/lcov.info
13 |
--------------------------------------------------------------------------------
/test/mock/event-1b.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "id": 1,
4 | "type": "event",
5 | "attributes": {
6 | "title": "Test 1",
7 | "date": "2017-03-19"
8 | },
9 | "links": {
10 | "self": "http://example.com/event/1234"
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/test/mock/event-1.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "id": 12345,
4 | "type": "event",
5 | "attributes": {
6 | "title": "Test 1",
7 | "date": "2017-03-19"
8 | },
9 | "links": {
10 | "image": "http://example.com/images/1"
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/src/enums/ParamArrayType.ts:
--------------------------------------------------------------------------------
1 | enum ParamArrayType {
2 | MULTIPLE_PARAMS, // filter[a]=1&filter[a]=2
3 | COMMA_SEPARATED, // filter[a]=1,2
4 | PARAM_ARRAY, // filter[a][]=1&filter[a][]=2
5 | OBJECT_PATH, // filter[a.0]=1&filter[a.1]=2
6 | }
7 |
8 | export default ParamArrayType;
9 |
--------------------------------------------------------------------------------
/dist/interfaces/ICache.d.ts:
--------------------------------------------------------------------------------
1 | import IDictionary from './IDictionary';
2 | import { Response } from '../Response';
3 | interface ICache {
4 | fetchAll: IDictionary>>;
5 | fetch: IDictionary>>;
6 | }
7 | export default ICache;
8 |
--------------------------------------------------------------------------------
/test/mock/queue-1.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "type": "queue",
4 | "id": "5234",
5 | "attributes": {
6 | "status": "Pending request, waiting other process"
7 | },
8 | "links": {
9 | "self": "http://example.com/events/queue-jobs/123"
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "tslint:recommended",
3 | "rules": {
4 | "no-string-literal": false,
5 | "array-type": [true, "generic"],
6 | "quotemark": [true, "single", "avoid-escape"],
7 | "variable-name": [true, "ban-keywords"],
8 | "ban-types": [false]
9 | }
10 | }
--------------------------------------------------------------------------------
/src/interfaces/ICache.ts:
--------------------------------------------------------------------------------
1 | import IDictionary from './IDictionary';
2 |
3 | import {Response} from '../Response';
4 |
5 | interface ICache {
6 | fetchAll: IDictionary>>;
7 | fetch: IDictionary>>;
8 | }
9 |
10 | export default ICache;
11 |
--------------------------------------------------------------------------------
/dist/interfaces/IJsonApiRelationship.d.ts:
--------------------------------------------------------------------------------
1 | import IDictionary from './IDictionary';
2 | import IJsonApiIdentifier from './IJsonApiIdentifier';
3 | interface IJsonApiRelationship {
4 | data?: IJsonApiIdentifier | Array;
5 | links?: IDictionary;
6 | }
7 | export default IJsonApiRelationship;
8 |
--------------------------------------------------------------------------------
/dist/interfaces/IJsonApiRecord.d.ts:
--------------------------------------------------------------------------------
1 | import IDictionary from './IDictionary';
2 | import IJsonApiRelationship from './IJsonApiRelationship';
3 | interface IJsonApiRecord {
4 | id: number | string;
5 | type: string;
6 | attributes: IDictionary;
7 | relationships?: IDictionary;
8 | }
9 | export default IJsonApiRecord;
10 |
--------------------------------------------------------------------------------
/test/mock/issue-84b.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "id": 12345,
4 | "type": "event",
5 | "attributes": {
6 | "title": "Test 1",
7 | "date": "2017-03-19"
8 | },
9 | "meta": {
10 | "createdAt": "2017-03-19T16:00:00.000Z"
11 | },
12 | "relationships": {
13 | "image": {
14 | "data": null
15 | }
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/test/mock/events-2.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": [{
3 | "id": 5,
4 | "type": "event",
5 | "attributes": {
6 | "title": "Test 5",
7 | "date": "2017-03-23"
8 | }
9 | }, {
10 | "id": 6,
11 | "type": "event",
12 | "attributes": {
13 | "title": "Test 6",
14 | "date": "2017-03-24"
15 | }
16 | }],
17 | "links": {
18 | "prev": "http://example.com/event"
19 | }
20 | }
--------------------------------------------------------------------------------
/src/interfaces/IRequestOptions.ts:
--------------------------------------------------------------------------------
1 | import IDictionary from './IDictionary';
2 | import IFilters from './IFilters';
3 | import IHeaders from './IHeaders';
4 |
5 | interface IRequestOptions {
6 | headers?: IHeaders;
7 | include?: string|Array;
8 | filter?: IFilters;
9 | sort?: string|Array;
10 | fields?: IDictionary>;
11 | params?: Array<{key: string, value: string}|string>;
12 | }
13 |
14 | export default IRequestOptions;
15 |
--------------------------------------------------------------------------------
/typings/globals/isomorphic-fetch/typings.json:
--------------------------------------------------------------------------------
1 | {
2 | "resolution": "main",
3 | "tree": {
4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/1b30c8e5c2aa0e179a1b82d7f337124721be2aa6/isomorphic-fetch/index.d.ts",
5 | "raw": "registry:dt/isomorphic-fetch#0.0.0+20170223183302",
6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/1b30c8e5c2aa0e179a1b82d7f337124721be2aa6/isomorphic-fetch/index.d.ts"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/interfaces/IRawResponse.ts:
--------------------------------------------------------------------------------
1 | import {Store} from '../Store';
2 | import IHeaders from './IHeaders';
3 | import IResponseHeaders from './IResponseHeaders';
4 | import * as JsonApi from './JsonApi';
5 |
6 | interface IRawResponse {
7 | data?: JsonApi.IResponse;
8 | error?: Error;
9 | headers?: IResponseHeaders;
10 | requestHeaders?: IHeaders;
11 | status?: number;
12 | jsonapi?: JsonApi.IJsonApiObject;
13 | store?: Store;
14 | }
15 |
16 | export default IRawResponse;
17 |
--------------------------------------------------------------------------------
/dist/interfaces/IRawResponse.d.ts:
--------------------------------------------------------------------------------
1 | import { Store } from '../Store';
2 | import IHeaders from './IHeaders';
3 | import IResponseHeaders from './IResponseHeaders';
4 | import * as JsonApi from './JsonApi';
5 | interface IRawResponse {
6 | data?: JsonApi.IResponse;
7 | error?: Error;
8 | headers?: IResponseHeaders;
9 | requestHeaders?: IHeaders;
10 | status?: number;
11 | jsonapi?: JsonApi.IJsonApiObject;
12 | store?: Store;
13 | }
14 | export default IRawResponse;
15 |
--------------------------------------------------------------------------------
/dist/interfaces/IRequestOptions.d.ts:
--------------------------------------------------------------------------------
1 | import IDictionary from './IDictionary';
2 | import IFilters from './IFilters';
3 | import IHeaders from './IHeaders';
4 | interface IRequestOptions {
5 | headers?: IHeaders;
6 | include?: string | Array;
7 | filter?: IFilters;
8 | sort?: string | Array;
9 | fields?: IDictionary>;
10 | params?: Array<{
11 | key: string;
12 | value: string;
13 | } | string>;
14 | }
15 | export default IRequestOptions;
16 |
--------------------------------------------------------------------------------
/test/mock/issue-84e.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "id": 12345,
4 | "type": "event",
5 | "attributes": {
6 | "title": "Test 1",
7 | "date": "2017-03-19"
8 | },
9 | "meta": {
10 | "createdAt": "2017-03-19T16:00:00.000Z"
11 | },
12 | "relationships": {
13 | "image": {
14 | "data": []
15 | }
16 | }
17 | },
18 | "included": [{
19 | "id": 1,
20 | "type": "image",
21 | "attributes": {
22 | "url": "http://example.com/1.jpg"
23 | }
24 | }]
25 | }
26 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "declaration": true,
6 | "noImplicitAny": false,
7 | "removeComments": false,
8 | "experimentalDecorators": true,
9 | "noLib": false,
10 | "outDir": "../dist",
11 | "inlineSourceMap": true,
12 | "inlineSources": true,
13 | "lib": [
14 | "dom",
15 | "es5",
16 | "scripthost",
17 | "es2015.promise"
18 | ]
19 | },
20 | "exclude": [
21 | "node_modules",
22 | "test"
23 | ]
24 | }
--------------------------------------------------------------------------------
/dist/enums/ParamArrayType.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | var ParamArrayType;
4 | (function (ParamArrayType) {
5 | ParamArrayType[ParamArrayType["MULTIPLE_PARAMS"] = 0] = "MULTIPLE_PARAMS";
6 | ParamArrayType[ParamArrayType["COMMA_SEPARATED"] = 1] = "COMMA_SEPARATED";
7 | ParamArrayType[ParamArrayType["PARAM_ARRAY"] = 2] = "PARAM_ARRAY";
8 | ParamArrayType[ParamArrayType["OBJECT_PATH"] = 3] = "OBJECT_PATH";
9 | })(ParamArrayType || (ParamArrayType = {}));
10 | exports.default = ParamArrayType;
11 |
--------------------------------------------------------------------------------
/test/mock/issue-84a.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "id": 12345,
4 | "type": "event",
5 | "attributes": {
6 | "title": "Test 1",
7 | "date": "2017-03-19"
8 | },
9 | "meta": {
10 | "createdAt": "2017-03-19T16:00:00.000Z"
11 | },
12 | "relationships": {
13 | "image": {
14 | "data": {
15 | "type": "image",
16 | "id": "1"
17 | }
18 | }
19 | }
20 | },
21 | "included": [{
22 | "id": 1,
23 | "type": "image",
24 | "attributes": {
25 | "url": "http://example.com/1.jpg"
26 | }
27 | }]
28 | }
29 |
--------------------------------------------------------------------------------
/test/mock/issue-84c.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "id": 12345,
4 | "type": "event",
5 | "attributes": {
6 | "title": "Test 1",
7 | "date": "2017-03-19"
8 | },
9 | "meta": {
10 | "createdAt": "2017-03-19T16:00:00.000Z"
11 | },
12 | "relationships": {
13 | "image": {
14 | "data": {
15 | "type": "image",
16 | "id": "2"
17 | }
18 | }
19 | }
20 | },
21 | "included": [{
22 | "id": 2,
23 | "type": "image",
24 | "attributes": {
25 | "url": "http://example.com/2.jpg"
26 | }
27 | }]
28 | }
29 |
--------------------------------------------------------------------------------
/test/mock/issue-84d.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "id": 12345,
4 | "type": "event",
5 | "attributes": {
6 | "title": "Test 1",
7 | "date": "2017-03-19"
8 | },
9 | "meta": {
10 | "createdAt": "2017-03-19T16:00:00.000Z"
11 | },
12 | "relationships": {
13 | "image": {
14 | "data": [{
15 | "type": "image",
16 | "id": "1"
17 | }]
18 | }
19 | }
20 | },
21 | "included": [{
22 | "id": 1,
23 | "type": "image",
24 | "attributes": {
25 | "url": "http://example.com/1.jpg"
26 | }
27 | }]
28 | }
29 |
--------------------------------------------------------------------------------
/dist/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | function __export(m) {
3 | for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
4 | }
5 | Object.defineProperty(exports, "__esModule", { value: true });
6 | var JsonApi = require("./interfaces/JsonApi");
7 | exports.JsonApi = JsonApi;
8 | var Store_1 = require("./Store");
9 | exports.Store = Store_1.Store;
10 | var Record_1 = require("./Record");
11 | exports.Record = Record_1.Record;
12 | var Response_1 = require("./Response");
13 | exports.Response = Response_1.Response;
14 | __export(require("./NetworkUtils"));
15 | var ParamArrayType_1 = require("./enums/ParamArrayType");
16 | exports.ParamArrayType = ParamArrayType_1.default;
17 |
--------------------------------------------------------------------------------
/test/mock/event-1d.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "id": 12345,
4 | "type": "event",
5 | "attributes": {
6 | "title": "Test 1",
7 | "date": "2017-03-19"
8 | },
9 | "meta": {
10 | "createdAt": "2017-03-19T16:00:00.000Z"
11 | },
12 | "relationships": {
13 | "image": {
14 | "data": [{
15 | "type": "image",
16 | "id": "1"
17 | }, {
18 | "type": "image",
19 | "id": "2"
20 | }],
21 | "links": {
22 | "self": "http://example.com/images/1"
23 | },
24 | "meta": {
25 | "foo": "bar"
26 | }
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 |
33 | # Optional npm cache directory
34 | .npm
35 |
36 | # Optional REPL history
37 | .node_repl_history
38 |
39 | *.map
40 | dist/test.*
41 |
42 | .DS_Store
43 |
44 | .vscode
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import * as JsonApi from './interfaces/JsonApi';
2 |
3 | export {JsonApi};
4 | export {Store} from './Store';
5 | export {Record} from './Record';
6 | export {Response} from './Response';
7 | export * from './NetworkUtils';
8 |
9 | export {default as ICache} from './interfaces/ICache';
10 | export {default as IDictionary} from './interfaces/IDictionary';
11 | export {default as IFilters} from './interfaces/IFilters';
12 | export {default as IHeaders} from './interfaces/IHeaders';
13 | export {default as IRawResponse} from './interfaces/IRawResponse';
14 | export {default as IRequestOptions} from './interfaces/IRequestOptions';
15 | export {default as IResponseHeaders} from './interfaces/IResponseHeaders';
16 |
17 | export {default as ParamArrayType} from './enums/ParamArrayType';
18 |
19 | export {ICollection, IModel, IModelConstructor, IReferences} from 'mobx-collection-store';
20 |
--------------------------------------------------------------------------------
/dist/index.d.ts:
--------------------------------------------------------------------------------
1 | import * as JsonApi from './interfaces/JsonApi';
2 | export { JsonApi };
3 | export { Store } from './Store';
4 | export { Record } from './Record';
5 | export { Response } from './Response';
6 | export * from './NetworkUtils';
7 | export { default as ICache } from './interfaces/ICache';
8 | export { default as IDictionary } from './interfaces/IDictionary';
9 | export { default as IFilters } from './interfaces/IFilters';
10 | export { default as IHeaders } from './interfaces/IHeaders';
11 | export { default as IRawResponse } from './interfaces/IRawResponse';
12 | export { default as IRequestOptions } from './interfaces/IRequestOptions';
13 | export { default as IResponseHeaders } from './interfaces/IResponseHeaders';
14 | export { default as ParamArrayType } from './enums/ParamArrayType';
15 | export { ICollection, IModel, IModelConstructor, IReferences } from 'mobx-collection-store';
16 |
--------------------------------------------------------------------------------
/test/mock/jsonapi-object.json:
--------------------------------------------------------------------------------
1 | {
2 | "jsonapi": {
3 | "version": "1.0",
4 | "meta": {
5 | "foo": "bar"
6 | }
7 | },
8 | "data": [{
9 | "id": 1,
10 | "type": "event",
11 | "attributes": {
12 | "title": "Test 1",
13 | "date": "2017-03-19"
14 | },
15 | "meta": {
16 | "createdAt": "2017-03-19T16:00:00.000Z"
17 | }
18 | }, {
19 | "id": 2,
20 | "type": "event",
21 | "attributes": {
22 | "title": "Test 2",
23 | "date": "2017-03-20"
24 | }
25 | }, {
26 | "id": 3,
27 | "type": "event",
28 | "attributes": {
29 | "title": "Test 3",
30 | "date": "2017-03-21"
31 | }
32 | }, {
33 | "id": 4,
34 | "type": "event",
35 | "attributes": {
36 | "title": "Test 4",
37 | "date": "2017-03-22"
38 | }
39 | }],
40 | "links": {
41 | "self": "http://example.com/event",
42 | "next": "http://example.com/event?page=2"
43 | }
44 | }
--------------------------------------------------------------------------------
/dist/NetworkStore.d.ts:
--------------------------------------------------------------------------------
1 | import { Collection } from 'mobx-collection-store';
2 | import IHeaders from './interfaces/IHeaders';
3 | import IRequestOptions from './interfaces/IRequestOptions';
4 | import * as JsonApi from './interfaces/JsonApi';
5 | export declare class NetworkStore extends Collection {
6 | /**
7 | * Prepare the query params for the API call
8 | *
9 | * @protected
10 | * @param {string} type Record type
11 | * @param {(number|string)} [id] Record ID
12 | * @param {JsonApi.IRequest} [data] Request data
13 | * @param {IRequestOptions} [options] Server options
14 | * @returns {{
15 | * url: string,
16 | * data?: object,
17 | * headers: IHeaders,
18 | * }} Options needed for an API call
19 | *
20 | * @memberOf NetworkStore
21 | */
22 | protected __prepareQuery(type: string, id?: number | string, data?: JsonApi.IRequest, options?: IRequestOptions): {
23 | url: string;
24 | data?: object;
25 | headers: IHeaders;
26 | };
27 | }
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Infinum
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/test/mock/events-1.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": [{
3 | "id": 1,
4 | "type": "event",
5 | "attributes": {
6 | "title": "Test 1",
7 | "date": "2017-03-19"
8 | },
9 | "meta": {
10 | "createdAt": "2017-03-19T16:00:00.000Z"
11 | },
12 | "relationships": {
13 | "image": {
14 | "data": {
15 | "type": "image",
16 | "id": "1"
17 | },
18 | "links": {
19 | "self": "http://example.com/images/1"
20 | },
21 | "meta": {
22 | "foo": "bar"
23 | }
24 | }
25 | }
26 | }, {
27 | "id": 2,
28 | "type": "event",
29 | "attributes": {
30 | "title": "Test 2",
31 | "date": "2017-03-20"
32 | }
33 | }, {
34 | "id": 3,
35 | "type": "event",
36 | "attributes": {
37 | "title": "Test 3",
38 | "date": "2017-03-21"
39 | }
40 | }, {
41 | "id": 4,
42 | "type": "event",
43 | "attributes": {
44 | "title": "Test 4",
45 | "date": "2017-03-22"
46 | }
47 | }],
48 | "links": {
49 | "self": "http://example.com/event",
50 | "next": {
51 | "href": "http://example.com/event?page=2",
52 | "meta": {
53 | "foo": "bar"
54 | }
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/dist/interfaces/JsonApi.d.ts:
--------------------------------------------------------------------------------
1 | import IDictionary from './IDictionary';
2 | interface IIdentifier {
3 | id?: number | string;
4 | type: string;
5 | }
6 | interface IJsonApiObject {
7 | version?: string;
8 | meta?: IDictionary;
9 | }
10 | declare type ILink = string | {
11 | href: string;
12 | meta: IDictionary;
13 | };
14 | interface IError {
15 | id?: string | number;
16 | links?: {
17 | about: ILink;
18 | };
19 | status?: number;
20 | code?: string;
21 | title?: string;
22 | detail?: string;
23 | source?: {
24 | pointer?: string;
25 | parameter?: string;
26 | };
27 | meta?: IDictionary;
28 | }
29 | interface IRelationship {
30 | data?: IIdentifier | Array;
31 | links?: IDictionary;
32 | meta?: IDictionary;
33 | }
34 | interface IRecord extends IIdentifier {
35 | attributes: IDictionary;
36 | relationships?: IDictionary;
37 | links?: IDictionary;
38 | meta?: IDictionary;
39 | }
40 | interface IResponse {
41 | data?: IRecord | Array;
42 | errors?: Array;
43 | included?: Array;
44 | meta?: IDictionary;
45 | links?: IDictionary;
46 | jsonapi?: IJsonApiObject;
47 | }
48 | declare type IRequest = IResponse;
49 | export { IIdentifier, IJsonApiObject, ILink, IError, IRelationship, IRecord, IResponse, IRequest, };
50 |
--------------------------------------------------------------------------------
/src/NetworkStore.ts:
--------------------------------------------------------------------------------
1 | import {Collection, IModelConstructor} from 'mobx-collection-store';
2 |
3 | import IDictionary from './interfaces/IDictionary';
4 | import IHeaders from './interfaces/IHeaders';
5 | import IRequestOptions from './interfaces/IRequestOptions';
6 | import * as JsonApi from './interfaces/JsonApi';
7 | import {buildUrl} from './NetworkUtils';
8 |
9 | export class NetworkStore extends Collection {
10 |
11 | /**
12 | * Prepare the query params for the API call
13 | *
14 | * @protected
15 | * @param {string} type Record type
16 | * @param {(number|string)} [id] Record ID
17 | * @param {JsonApi.IRequest} [data] Request data
18 | * @param {IRequestOptions} [options] Server options
19 | * @returns {{
20 | * url: string,
21 | * data?: object,
22 | * headers: IHeaders,
23 | * }} Options needed for an API call
24 | *
25 | * @memberOf NetworkStore
26 | */
27 | protected __prepareQuery(
28 | type: string,
29 | id?: number|string,
30 | data?: JsonApi.IRequest,
31 | options?: IRequestOptions,
32 | ): {
33 | url: string,
34 | data?: object,
35 | headers: IHeaders,
36 | } {
37 | const model: IModelConstructor = this.static.types.filter((item) => item.type === type)[0];
38 | const headers: IDictionary = (options ? options.headers : {}) || {};
39 |
40 | const url = buildUrl(type, id, model, options);
41 | return {data, headers, url};
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/interfaces/JsonApi.ts:
--------------------------------------------------------------------------------
1 | import IDictionary from './IDictionary';
2 |
3 | interface IIdentifier {
4 | id?: number|string;
5 | type: string;
6 | }
7 |
8 | interface IJsonApiObject {
9 | version?: string;
10 | meta?: IDictionary;
11 | }
12 |
13 | type ILink = string | {href: string, meta: IDictionary};
14 |
15 | interface IError {
16 | id?: string|number;
17 | links?: {
18 | about: ILink,
19 | };
20 | status?: number;
21 | code?: string;
22 | title?: string;
23 | detail?: string;
24 | source?: {
25 | pointer?: string,
26 | parameter?: string,
27 | };
28 | meta?: IDictionary;
29 | }
30 |
31 | interface IRelationship {
32 | data?: IIdentifier|Array;
33 | links?: IDictionary;
34 | meta?: IDictionary;
35 | }
36 |
37 | interface IRecord extends IIdentifier {
38 | attributes: IDictionary;
39 |
40 | relationships?: IDictionary;
41 | links?: IDictionary;
42 | meta?: IDictionary;
43 | }
44 |
45 | interface IResponse {
46 | data?: IRecord|Array;
47 | errors?: Array;
48 |
49 | included?: Array;
50 |
51 | meta?: IDictionary;
52 | links?: IDictionary;
53 | jsonapi?: IJsonApiObject;
54 | }
55 |
56 | type IRequest = IResponse; // Not sure if this is correct, but it's ok for now
57 |
58 | export {
59 | IIdentifier,
60 | IJsonApiObject,
61 | ILink,
62 | IError,
63 | IRelationship,
64 | IRecord,
65 | IResponse,
66 | IRequest,
67 | };
68 |
--------------------------------------------------------------------------------
/test/utils/setup.ts:
--------------------------------------------------------------------------------
1 | import {computed} from 'mobx';
2 |
3 | import {IDictionary, Record, Store} from '../../src';
4 |
5 | // tslint:disable:max-classes-per-file
6 |
7 | export class User extends Record {
8 | public static type: string = 'user';
9 |
10 | public firstName: string;
11 | public lastName: string;
12 |
13 | @computed get fullName(): string {
14 | return `${this.firstName} ${this.lastName}`;
15 | }
16 | }
17 |
18 | export class Event extends Record {
19 | public static type: string = 'events';
20 | public static refs = {
21 | image: 'images',
22 | images: 'images',
23 | organisers: 'organisers',
24 | };
25 |
26 | public name: string;
27 | public organisers: Array;
28 | public images: Array;
29 | public image: Image;
30 | public imagesLinks: IDictionary;
31 | }
32 |
33 | export class Image extends Record {
34 | public static type: string = 'images';
35 | public static refs = {event: 'events'};
36 |
37 | public name: string;
38 | public event: Event;
39 | }
40 |
41 | export class Organiser extends User {
42 | public static type = 'organisers';
43 | public static refs = {image: 'images'};
44 |
45 | public image: Image;
46 | }
47 |
48 | export class Photo extends Record {
49 | public static type = 'photo';
50 | public static defaults = {
51 | selected: false,
52 | };
53 |
54 | public selected: boolean;
55 | }
56 |
57 | export class TestStore extends Store {
58 | public static types = [User, Event, Image, Organiser, Photo];
59 |
60 | public user: Array;
61 | public events: Array;
62 | public images: Array;
63 |
64 | public organisers: Array;
65 | public photo: Array;
66 | }
67 |
--------------------------------------------------------------------------------
/test/network/headers.ts:
--------------------------------------------------------------------------------
1 | import {expect} from 'chai';
2 | import * as fetch from 'isomorphic-fetch';
3 |
4 | // tslint:disable:no-string-literal
5 |
6 | import {config, Record, Store} from '../../src';
7 |
8 | import mockApi from '../utils/api';
9 | import {Event, Image, Organiser, Photo, TestStore, User} from '../utils/setup';
10 |
11 | const baseStoreFetch = config.storeFetch;
12 |
13 | describe('headers', () => {
14 | beforeEach(() => {
15 | config.fetchReference = fetch;
16 | config.baseUrl = 'http://example.com/';
17 | config.defaultHeaders = {
18 | 'X-Auth': '12345',
19 | 'content-type': 'application/vnd.api+json',
20 | };
21 | });
22 |
23 | it ('should send the default headers', async () => {
24 | mockApi({
25 | name: 'events-1',
26 | reqheaders: {
27 | 'X-Auth': '12345',
28 | },
29 | url: 'event',
30 | });
31 |
32 | const store = new Store();
33 | const events = await store.fetchAll('event');
34 |
35 | expect(events.data).to.be.an('array');
36 | });
37 |
38 | it ('should send custom headers', async () => {
39 | mockApi({
40 | name: 'events-1',
41 | reqheaders: {
42 | 'X-Auth': '54321',
43 | },
44 | url: 'event',
45 | });
46 |
47 | const store = new Store();
48 | const events = await store.fetchAll('event', false, {
49 | headers: {
50 | 'X-Auth': '54321',
51 | },
52 | });
53 |
54 | expect(events.data).to.be.an('array');
55 | });
56 |
57 | it ('should receive headers', async () => {
58 | mockApi({
59 | headers: {
60 | 'X-Auth': '98765',
61 | },
62 | name: 'events-1',
63 | url: 'event',
64 | });
65 |
66 | const store = new Store();
67 | const events = await store.fetchAll('event');
68 |
69 | expect(events.data).to.be.an('array');
70 | expect(events.headers.get('X-Auth')).to.equal('98765');
71 | });
72 | });
73 |
--------------------------------------------------------------------------------
/dist/NetworkStore.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __extends = (this && this.__extends) || (function () {
3 | var extendStatics = function (d, b) {
4 | extendStatics = Object.setPrototypeOf ||
5 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
7 | return extendStatics(d, b);
8 | };
9 | return function (d, b) {
10 | extendStatics(d, b);
11 | function __() { this.constructor = d; }
12 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13 | };
14 | })();
15 | Object.defineProperty(exports, "__esModule", { value: true });
16 | var mobx_collection_store_1 = require("mobx-collection-store");
17 | var NetworkUtils_1 = require("./NetworkUtils");
18 | var NetworkStore = /** @class */ (function (_super) {
19 | __extends(NetworkStore, _super);
20 | function NetworkStore() {
21 | return _super !== null && _super.apply(this, arguments) || this;
22 | }
23 | /**
24 | * Prepare the query params for the API call
25 | *
26 | * @protected
27 | * @param {string} type Record type
28 | * @param {(number|string)} [id] Record ID
29 | * @param {JsonApi.IRequest} [data] Request data
30 | * @param {IRequestOptions} [options] Server options
31 | * @returns {{
32 | * url: string,
33 | * data?: object,
34 | * headers: IHeaders,
35 | * }} Options needed for an API call
36 | *
37 | * @memberOf NetworkStore
38 | */
39 | NetworkStore.prototype.__prepareQuery = function (type, id, data, options) {
40 | var model = this.static.types.filter(function (item) { return item.type === type; })[0];
41 | var headers = (options ? options.headers : {}) || {};
42 | var url = NetworkUtils_1.buildUrl(type, id, model, options);
43 | return { data: data, headers: headers, url: url };
44 | };
45 | return NetworkStore;
46 | }(mobx_collection_store_1.Collection));
47 | exports.NetworkStore = NetworkStore;
48 |
--------------------------------------------------------------------------------
/dist/utils.d.ts:
--------------------------------------------------------------------------------
1 | import IDictionary from './interfaces/IDictionary';
2 | import * as JsonApi from './interfaces/JsonApi';
3 | /**
4 | * Iterate trough object keys
5 | *
6 | * @param {object} obj - Object that needs to be iterated
7 | * @param {Function} fn - Function that should be called for every iteration
8 | */
9 | export declare function objectForEach(obj: object, fn: Function): void;
10 | /**
11 | * Iterate trough one item or array of items and call the defined function
12 | *
13 | * @export
14 | * @template T
15 | * @param {(object|Array