veritone-redux-common
Advanced tools
Comparing version 3.6.1 to 3.7.0
@@ -70,2 +70,9 @@ # veritone-redux-common changelog | ||
## 3.6.1 | ||
* Fix export of `callGraphQLApi` in 3.6.0 due to babel bug (cannot `export default async function`) | ||
* Fix export of `callGraphQLApi` in 3.6.0 due to babel bug (cannot `export default async function`) | ||
## 3.7.0 | ||
* Bolster error handling in the OAuth flow | ||
* Change credentials mode for API calls based on whether we're in a veritone-internal host | ||
* Add engine module action to fetch engine categories + related selectors | ||
* Always clear user state after logout | ||
* Add selectors to user module: selectUserOrganizationID and hasFeature |
{ | ||
"name": "veritone-redux-common", | ||
"version": "3.6.1", | ||
"version": "3.7.0", | ||
"dependencies": { | ||
@@ -5,0 +5,0 @@ "lodash": "^4.17.4", |
@@ -0,1 +1,3 @@ | ||
import { getCredentialsMode } from './'; | ||
export default function fetchGraphQLApi({ | ||
@@ -18,4 +20,5 @@ endpoint = 'https://api.veritone.com/v3/graphql', | ||
'Content-Type': 'application/json' | ||
} | ||
}, | ||
credentials: getCredentialsMode() | ||
}).then(r => r.json()); | ||
} |
@@ -18,1 +18,9 @@ import { selectSessionToken, selectOAuthToken } from 'modules/auth'; | ||
} | ||
export function getCredentialsMode() { | ||
const origin = (window && window.origin) || ''; | ||
// app.veritone.com on port 80 in prod, or | ||
// ie. local.veritone.com on any port in dev | ||
const isVeritoneInternalApp = origin.match(/\.veritone\.com(:\d{1,5})?$/); | ||
return isVeritoneInternalApp ? 'include' : 'omit'; | ||
} |
@@ -14,2 +14,4 @@ import { createReducer } from 'helpers/redux'; | ||
OAuthToken: null, | ||
OAuthErrorCode: null, | ||
OAuthErrorDescription: null, | ||
sessionToken: null | ||
@@ -27,6 +29,21 @@ }; | ||
...state, | ||
OAuthToken | ||
OAuthToken, | ||
OAuthErrorCode: null, | ||
OAuthErrorDescription: null | ||
}; | ||
}, | ||
[constants.OAUTH_GRANT_FLOW_FAILED]( | ||
state, | ||
{ | ||
payload: { error, errorDescription } | ||
} | ||
) { | ||
return { | ||
...state, | ||
OAuthErrorCode: error, | ||
OAuthErrorDescription: errorDescription | ||
}; | ||
}, | ||
[LOGIN_SUCCESS](state, action) { | ||
@@ -63,3 +80,5 @@ return { | ||
...state, | ||
OAuthToken: payload | ||
OAuthToken: payload, | ||
OAuthErrorCode: null, | ||
OAuthErrorDescription: null | ||
}; | ||
@@ -137,6 +156,6 @@ } | ||
export function OAuthGrantFailure({ error }) { | ||
export function OAuthGrantFailure({ error, errorDescription }) { | ||
return { | ||
type: constants.OAUTH_GRANT_FLOW_FAILED, | ||
payload: { error }, | ||
payload: { error, errorDescription }, | ||
error: true | ||
@@ -153,1 +172,8 @@ }; | ||
} | ||
export function selectOAuthError(state) { | ||
return { | ||
code: local(state).OAuthErrorCode, | ||
description: local(state).OAuthErrorDescription | ||
}; | ||
} |
@@ -53,3 +53,7 @@ /* eslint-disable import/order */ | ||
if (e.data.OAuthToken || e.data.error) { | ||
emitter({ OAuthToken: e.data.OAuthToken, error: e.data.error }); | ||
emitter({ | ||
OAuthToken: e.data.OAuthToken, | ||
error: e.data.error, | ||
errorDescription: e.data.errorDescription | ||
}); | ||
emitter(END); | ||
@@ -67,3 +71,5 @@ } | ||
const { OAuthToken, error } = yield take(windowEventChannel); | ||
const { OAuthToken, error, errorDescription } = yield take( | ||
windowEventChannel | ||
); | ||
yield call([authWindow, authWindow.close]); | ||
@@ -75,4 +81,4 @@ | ||
} else if (error) { | ||
yield put(OAuthGrantFailure({ error })); | ||
yield call(onFailure, error); | ||
yield put(OAuthGrantFailure({ error, errorDescription })); | ||
yield call(onFailure, error, errorDescription); | ||
} | ||
@@ -79,0 +85,0 @@ } |
@@ -59,5 +59,5 @@ import { put } from 'redux-saga/effects'; // eslint-disable-line | ||
next = gen.next({ cancel: module.cancelConfirmAction('123') }); | ||
expect(next.value).toBe(undefined) | ||
expect(next.value).toBe(undefined); | ||
}); | ||
}); | ||
}); |
import { isEmpty, keyBy, get, pickBy } from 'lodash'; | ||
import { getConfig } from 'modules/config'; | ||
import fetchGraphQLApi from 'helpers/api/fetchGraphQLApi'; | ||
import callGraphQLApi from 'helpers/api/callGraphQLApi'; | ||
import { createReducer } from 'helpers/redux'; | ||
@@ -13,6 +14,15 @@ import { selectSessionToken, selectOAuthToken } from 'modules/auth'; | ||
export const FETCH_ENGINE_CATEGORIES = 'vtn/engine/FETCH_ENGINE_CATEGORIES'; | ||
export const FETCH_ENGINE_CATEGORIES_SUCCESS = | ||
'vtn/engine/FETCH_ENGINE_CATEGORIES_SUCCESS'; | ||
export const FETCH_ENGINE_CATEGORIES_FAILURE = | ||
'vtn/engine/FETCH_ENGINES_CATEGORIES_FAILURE'; | ||
const defaultState = { | ||
enginesById: {}, | ||
isFetching: false, | ||
fetchingFailed: false | ||
fetchingFailed: false, | ||
engineCategories: [], | ||
isFetchingCategories: false, | ||
fetchingCategoriesFailed: false | ||
}; | ||
@@ -45,2 +55,24 @@ | ||
}; | ||
}, | ||
[FETCH_ENGINE_CATEGORIES](state, action) { | ||
return { | ||
...state, | ||
isFetchingCategories: true, | ||
fetchingCategoriesFailed: false | ||
}; | ||
}, | ||
[FETCH_ENGINE_CATEGORIES_SUCCESS](state, action) { | ||
return { | ||
...state, | ||
isFetchingCategories: false, | ||
fetchingCategoriesFailed: false, | ||
engineCategories: [...action.payload.results.records] | ||
}; | ||
}, | ||
[FETCH_ENGINE_CATEGORIES_FAILURE](state, action) { | ||
return { | ||
...state, | ||
isFetchingCategories: false, | ||
fetchingCategoriesFailed: true | ||
}; | ||
} | ||
@@ -54,3 +86,3 @@ }); | ||
export function fetchEngines( | ||
{ offset, limit, owned }, | ||
{ offset, limit, owned } = {}, | ||
searchQuery, | ||
@@ -152,2 +184,46 @@ filters = {}, | ||
export const fetchEngineCategories = ( | ||
{ offset, limit } = {}, | ||
searchQuery, | ||
type | ||
) => async (dispatch, getState) => { | ||
const query = ` | ||
${engineCategoryFieldsFragment} | ||
query EngineCategories( | ||
$name: String = "" | ||
$offset: Int | ||
$limit: Int | ||
$type: String | ||
) { | ||
results: engineCategories( | ||
name: $name | ||
offset: $offset | ||
limit: $limit | ||
type: $type | ||
) { | ||
records { | ||
...engineCategoryFields | ||
} | ||
} | ||
} | ||
`; | ||
return await callGraphQLApi({ | ||
actionTypes: [ | ||
FETCH_ENGINE_CATEGORIES, | ||
FETCH_ENGINE_CATEGORIES_SUCCESS, | ||
FETCH_ENGINE_CATEGORIES_FAILURE | ||
], | ||
query, | ||
variables: { | ||
name: searchQuery, | ||
offset, | ||
limit, | ||
type | ||
}, | ||
dispatch, | ||
getState | ||
}); | ||
}; | ||
export function getEngines(state) { | ||
@@ -169,2 +245,14 @@ return local(state).enginesById; | ||
export function getEngineCategories(state) { | ||
return local(state).engineCategories; | ||
} | ||
export function isFetchingEngineCategories(state) { | ||
return local(state).isFetchingCategories; | ||
} | ||
export function failedToFetchEngineCategories(state) { | ||
return local(state).fetchingCategoriesFailed; | ||
} | ||
const engineFieldsFragment = ` | ||
@@ -190,1 +278,16 @@ fragment engineFields on Engine { | ||
`; | ||
const engineCategoryFieldsFragment = ` | ||
fragment engineCategoryFields on EngineCategory{ | ||
id | ||
name | ||
description | ||
categoryType | ||
type { | ||
name | ||
description | ||
} | ||
iconClass | ||
color | ||
} | ||
`; |
@@ -8,3 +8,3 @@ import { CALL_API } from 'redux-api-middleware-fixed'; | ||
import { commonHeaders } from 'helpers/api'; | ||
import { commonHeaders, getCredentialsMode } from 'helpers/api'; | ||
import { createReducer } from 'helpers/redux'; | ||
@@ -110,2 +110,9 @@ import { getConfig } from 'modules/config'; | ||
[constants.LOGOUT_SUCCESS](state) { | ||
return { | ||
...state, | ||
user: {} | ||
}; | ||
}, | ||
[constants.FETCH_USER_APPLICATIONS](state, action) { | ||
@@ -181,3 +188,4 @@ const requestSuccessState = { | ||
method: 'GET', | ||
headers: commonHeaders | ||
headers: commonHeaders, | ||
credentials: getCredentialsMode() | ||
} | ||
@@ -201,7 +209,4 @@ }; | ||
}), | ||
headers: { | ||
Accept: 'application/json', | ||
'Content-Type': 'application/json' | ||
}, | ||
credentials: 'include' | ||
headers: commonHeaders, | ||
credentials: getCredentialsMode() | ||
} | ||
@@ -223,3 +228,4 @@ }; | ||
method: 'GET', | ||
headers: commonHeaders | ||
headers: commonHeaders, | ||
credentials: getCredentialsMode() | ||
} | ||
@@ -241,3 +247,4 @@ }; | ||
method: 'GET', | ||
headers: commonHeaders | ||
headers: commonHeaders, | ||
credentials: getCredentialsMode() | ||
} | ||
@@ -258,3 +265,4 @@ }; | ||
method: 'GET', | ||
headers: commonHeaders | ||
headers: commonHeaders, | ||
credentials: getCredentialsMode() | ||
} | ||
@@ -288,2 +296,6 @@ }; | ||
export function selectUserOrganizationId(state) { | ||
return get(local(state).user, 'organization.organizationId'); | ||
} | ||
export function selectUserOrganizationKvp(state) { | ||
@@ -342,1 +354,13 @@ return get(local(state).user, 'organization.kvp'); | ||
} | ||
export function hasFeature(state, featureName) { | ||
return ( | ||
get(local(state), [ | ||
'user', | ||
'organization', | ||
'kvp', | ||
'features', | ||
featureName | ||
]) === 'enabled' | ||
); | ||
} |
@@ -80,2 +80,3 @@ import nock from 'nock'; | ||
const store = mockStore({ | ||
auth: {}, | ||
config: { | ||
@@ -102,2 +103,3 @@ apiRoot: 'http://www.test.com' | ||
const store = mockStore({ | ||
auth: {}, | ||
config: { | ||
@@ -104,0 +106,0 @@ apiRoot: 'http://www.test.com' |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
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
282300
8030