sharetribe-flex-sdk 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.circleci/config.yml +22 -0
- package/.eslintignore +3 -0
- package/.eslintrc.js +19 -0
- package/CHANGELOG.md +231 -0
- package/LICENSE +201 -0
- package/README.md +76 -0
- package/build/sharetribe-flex-sdk-node.js +13592 -0
- package/build/sharetribe-flex-sdk-web.js +1 -0
- package/docs/README.md +20 -0
- package/docs/authentication.md +179 -0
- package/docs/calling-the-api.md +217 -0
- package/docs/configurations.md +95 -0
- package/docs/developing-sdk.md +131 -0
- package/docs/docpress.json +14 -0
- package/docs/features.md +14 -0
- package/docs/keep-alive.md +48 -0
- package/docs/object-query-parameters.md +36 -0
- package/docs/scripts.js +41 -0
- package/docs/serializing-types-to-json.md +40 -0
- package/docs/sharing-session-between-client-and-server.md +19 -0
- package/docs/styles.css +95 -0
- package/docs/token-store.md +114 -0
- package/docs/try-it-in-browser.md +32 -0
- package/docs/try-it-in-the-playground.md +153 -0
- package/docs/types.md +27 -0
- package/docs/writing-your-own-token-store.md +29 -0
- package/docs/your-own-types.md +61 -0
- package/examples/README.md +5 -0
- package/examples/getting-started-browser/README.md +22 -0
- package/examples/getting-started-browser/index.html +89 -0
- package/examples/getting-started-browser/index.js +156 -0
- package/examples/getting-started-browser/screenshots/screenshot1.png +0 -0
- package/examples/getting-started-browser/screenshots/screenshot2.png +0 -0
- package/examples/getting-started-node/README.md +23 -0
- package/examples/getting-started-node/index.js +139 -0
- package/examples/getting-started-node/screenshots/screenshot.png +0 -0
- package/package.json +83 -0
- package/playground.js +295 -0
- package/src/browser_cookie_store.js +26 -0
- package/src/context_runner.js +151 -0
- package/src/context_runner.test.js +185 -0
- package/src/detect.js +11 -0
- package/src/express_cookie_store.js +57 -0
- package/src/fake/adapter.js +130 -0
- package/src/fake/api.js +137 -0
- package/src/fake/auth.js +84 -0
- package/src/fake/token_store.js +231 -0
- package/src/index.js +25 -0
- package/src/interceptors/.eslintrc.js +5 -0
- package/src/interceptors/add_auth_header.js +32 -0
- package/src/interceptors/add_auth_header.test.js +50 -0
- package/src/interceptors/add_auth_token_response.js +16 -0
- package/src/interceptors/add_client_id_to_params.js +12 -0
- package/src/interceptors/add_client_secret_to_params.js +15 -0
- package/src/interceptors/add_grant_type_to_params.js +23 -0
- package/src/interceptors/add_idp_client_id_to_params.js +17 -0
- package/src/interceptors/add_idp_id_to_params.js +17 -0
- package/src/interceptors/add_idp_token_to_params.js +17 -0
- package/src/interceptors/add_scope_to_params.js +18 -0
- package/src/interceptors/add_subject_token_to_params.js +18 -0
- package/src/interceptors/add_token_exchange_grant_type_to_params.js +12 -0
- package/src/interceptors/auth_info.js +50 -0
- package/src/interceptors/clear_token_after_revoke.js +45 -0
- package/src/interceptors/default_params.js +12 -0
- package/src/interceptors/fetch_auth_token_from_api.js +33 -0
- package/src/interceptors/fetch_auth_token_from_store.js +27 -0
- package/src/interceptors/fetch_refresh_token_for_revoke.js +24 -0
- package/src/interceptors/multipart_request.js +35 -0
- package/src/interceptors/retry_with_anon_token.js +58 -0
- package/src/interceptors/retry_with_refresh_token.js +70 -0
- package/src/interceptors/save_token.js +20 -0
- package/src/interceptors/transit_request.js +27 -0
- package/src/interceptors/transit_request.test.js +58 -0
- package/src/interceptors/transit_response.js +27 -0
- package/src/memory_store.js +19 -0
- package/src/params_serializer.js +65 -0
- package/src/params_serializer.test.js +58 -0
- package/src/sdk.js +894 -0
- package/src/sdk.test.js +908 -0
- package/src/serializer.js +279 -0
- package/src/serializer.test.js +229 -0
- package/src/token_store.js +15 -0
- package/src/types.js +108 -0
- package/src/types.test.js +75 -0
- package/src/utils.js +68 -0
- package/src/utils.test.js +85 -0
- package/webpack.config.babel.js +47 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createTransitConverters } from '../serializer';
|
|
2
|
+
import TransitRequest from './transit_request';
|
|
3
|
+
|
|
4
|
+
describe('TransitRequest', () => {
|
|
5
|
+
it('encodes to Transit', () => {
|
|
6
|
+
const data = {
|
|
7
|
+
data: {
|
|
8
|
+
a: 1,
|
|
9
|
+
b: [2, 3],
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const ctx = {
|
|
14
|
+
params: data,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const transitRequest = new TransitRequest();
|
|
18
|
+
|
|
19
|
+
const newCtx = transitRequest.enter(ctx);
|
|
20
|
+
const { writer } = createTransitConverters();
|
|
21
|
+
|
|
22
|
+
expect(newCtx).toEqual(
|
|
23
|
+
expect.objectContaining({
|
|
24
|
+
headers: expect.objectContaining({
|
|
25
|
+
'Content-Type': 'application/transit+json',
|
|
26
|
+
}),
|
|
27
|
+
params: writer.write(data),
|
|
28
|
+
})
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('is idempotent', () => {
|
|
33
|
+
const data = {
|
|
34
|
+
data: {
|
|
35
|
+
a: 1,
|
|
36
|
+
b: [2, 3],
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const ctx = {
|
|
41
|
+
params: data,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const transitRequest = new TransitRequest();
|
|
45
|
+
|
|
46
|
+
const newCtx = transitRequest.enter(transitRequest.enter(ctx));
|
|
47
|
+
const { writer } = createTransitConverters();
|
|
48
|
+
|
|
49
|
+
expect(newCtx).toEqual(
|
|
50
|
+
expect.objectContaining({
|
|
51
|
+
headers: expect.objectContaining({
|
|
52
|
+
'Content-Type': 'application/transit+json',
|
|
53
|
+
}),
|
|
54
|
+
params: writer.write(data),
|
|
55
|
+
})
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import { createTransitConverters } from '../serializer';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
Transit encode the response
|
|
6
|
+
*/
|
|
7
|
+
export default class TransitResponse {
|
|
8
|
+
error(ctx) {
|
|
9
|
+
const { reader } = createTransitConverters(ctx.typeHandlers);
|
|
10
|
+
|
|
11
|
+
if (!ctx.error.response) {
|
|
12
|
+
return ctx;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return _.update({ ...ctx }, 'error.response.data', data => reader.read(data));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
leave(ctx) {
|
|
19
|
+
const { reader } = createTransitConverters(ctx.typeHandlers);
|
|
20
|
+
|
|
21
|
+
if (!ctx.res) {
|
|
22
|
+
return ctx;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return _.update({ ...ctx }, 'res.data', data => reader.read(data));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const createStore = () => {
|
|
2
|
+
let memo;
|
|
3
|
+
|
|
4
|
+
const getToken = () => memo;
|
|
5
|
+
const setToken = tokenData => {
|
|
6
|
+
memo = tokenData;
|
|
7
|
+
};
|
|
8
|
+
const removeToken = () => {
|
|
9
|
+
memo = null;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
getToken,
|
|
14
|
+
setToken,
|
|
15
|
+
removeToken,
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default createStore;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import { UUID, LatLng, LatLngBounds } from './types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Takes a value for query string and returns it in encoded form.
|
|
6
|
+
*
|
|
7
|
+
* Uses `encodeURIComponent` with few exceptions:
|
|
8
|
+
*
|
|
9
|
+
* - Don't encode comma (,)
|
|
10
|
+
*
|
|
11
|
+
* Inspired by the `encode` function in Axios:
|
|
12
|
+
* https://github.com/mzabriskie/axios/blob/b8f6f5049cf3da8126a184b6b270316402b5b374/lib/helpers/buildURL.js#L5
|
|
13
|
+
*/
|
|
14
|
+
const encode = value => encodeURIComponent(value).replace(/%2C/gi, ',');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Take `key` and `value` and return a key-value tuple where
|
|
18
|
+
* key and value are stringified.
|
|
19
|
+
*
|
|
20
|
+
* TODO Consider moving this function closer to the type definitions,
|
|
21
|
+
* maybe in types.js file(?).
|
|
22
|
+
*/
|
|
23
|
+
const serialize = (key, value) => {
|
|
24
|
+
let v;
|
|
25
|
+
|
|
26
|
+
if (value instanceof UUID) {
|
|
27
|
+
v = value.uuid;
|
|
28
|
+
} else if (value instanceof LatLng) {
|
|
29
|
+
v = `${value.lat},${value.lng}`;
|
|
30
|
+
} else if (value instanceof LatLngBounds) {
|
|
31
|
+
v = `${value.ne.lat},${value.ne.lng},${value.sw.lat},${value.sw.lng}`;
|
|
32
|
+
} else if (Array.isArray(value)) {
|
|
33
|
+
v = value;
|
|
34
|
+
} else if (value instanceof Date) {
|
|
35
|
+
v = value.toISOString();
|
|
36
|
+
} else if (value == null) {
|
|
37
|
+
v = value;
|
|
38
|
+
} else if (typeof value !== 'object') {
|
|
39
|
+
v = value;
|
|
40
|
+
} else {
|
|
41
|
+
throw new Error(`Don't know how to serialize query parameter '${key}': ${value}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Ignore null and undefined values
|
|
45
|
+
if (v == null) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return [key, encode(v)];
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const paramsSerializer = params =>
|
|
53
|
+
_.compact(
|
|
54
|
+
_.map(params, (value, key) => {
|
|
55
|
+
const serialized = serialize(key, value);
|
|
56
|
+
|
|
57
|
+
if (serialized) {
|
|
58
|
+
return serialized.join('=');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return null;
|
|
62
|
+
})
|
|
63
|
+
).join('&');
|
|
64
|
+
|
|
65
|
+
export default paramsSerializer;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import ps from './params_serializer';
|
|
2
|
+
import { UUID, LatLng, LatLngBounds } from './types';
|
|
3
|
+
|
|
4
|
+
describe('params serializer', () => {
|
|
5
|
+
it('serializes params Object', () => {
|
|
6
|
+
expect(ps({ a: 1 })).toEqual('a=1');
|
|
7
|
+
expect(ps({ a: 1, b: 'foo' })).toEqual('a=1&b=foo');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('serializes UUID', () => {
|
|
11
|
+
expect(ps({ uuid: new UUID('0e0b60fe-d9a2-11e6-bf26-cec0c932ce01') })).toEqual(
|
|
12
|
+
'uuid=0e0b60fe-d9a2-11e6-bf26-cec0c932ce01'
|
|
13
|
+
);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('serializes LatLng', () => {
|
|
17
|
+
expect(ps({ location: new LatLng(12.34, -56.70001) })).toEqual('location=12.34,-56.70001');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('serializes LatLngBounds', () => {
|
|
21
|
+
expect(
|
|
22
|
+
ps({ bounds: new LatLngBounds(new LatLng(12.34, -56.70001), new LatLng(-45.67, 12)) })
|
|
23
|
+
).toEqual('bounds=12.34,-56.70001,-45.67,12');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('serializes array', () => {
|
|
27
|
+
expect(ps({ alphabets: ['a', 'b', 'c'] })).toEqual('alphabets=a,b,c');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('serializes Date', () => {
|
|
31
|
+
expect(ps({ start: new Date('2018-07-01T00:00:00.000Z') })).toEqual(
|
|
32
|
+
'start=2018-07-01T00%3A00%3A00.000Z'
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('throws for Objects that it can not encode', () => {
|
|
37
|
+
class Point {
|
|
38
|
+
construct(x, y) {
|
|
39
|
+
this.x = x;
|
|
40
|
+
this.y = y;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
expect(() => ps({ point: new Point(12, -5) })).toThrowError(
|
|
45
|
+
"Don't know how to serialize query parameter 'point': [object Object]"
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
expect(() => ps({ foo: { a: 1, b: 'bar' } })).toThrowError(
|
|
49
|
+
"Don't know how to serialize query parameter 'foo': [object Object]"
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('ignores null and undefined values', () => {
|
|
54
|
+
expect(
|
|
55
|
+
ps({ a: null, b: undefined, c: 'value', d: false, e: 0, f: '', g: [], h: [1, 2, 3] })
|
|
56
|
+
).toEqual('c=value&d=false&e=0&f=&g=&h=1,2,3');
|
|
57
|
+
});
|
|
58
|
+
});
|