Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added S3 PutObjectRequest config option #340

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packages/aws-appsync-react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

<a name="1.2.6"></a>
## [1.2.6](https://github.com/awslabs/aws-mobile-appsync-sdk-js/compare/[email protected]@1.2.6) (2019-01-11)




**Note:** Version bump only for package aws-appsync-react

<a name="1.2.5"></a>
## [1.2.5](https://github.com/awslabs/aws-mobile-appsync-sdk-js/compare/[email protected]@1.2.5) (2018-12-12)

Expand Down
4 changes: 2 additions & 2 deletions packages/aws-appsync-react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "aws-appsync-react",
"version": "1.2.5",
"version": "1.2.6",
"main": "lib/index.js",
"license": "SEE LICENSE IN LICENSE",
"description": "AWS Mobile AppSync SDK for JavaScript - React and React Native components",
Expand All @@ -27,7 +27,7 @@
"devDependencies": {
"@types/graphql": "0.12.4",
"@types/react": "^16.0.25",
"aws-appsync": "^1.7.0",
"aws-appsync": "^1.7.1",
"react": "^16.1.1",
"react-apollo": "^2.1.9",
"react-native": "^0.50.3",
Expand Down
15 changes: 15 additions & 0 deletions packages/aws-appsync/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

<a name="1.7.1"></a>
## [1.7.1](https://github.com/awslabs/aws-mobile-appsync-sdk-js/compare/[email protected]@1.7.1) (2019-01-11)


### Bug Fixes

* **deltasync:** Fix error when baseQuery is not specified ([#320](https://github.com/awslabs/aws-mobile-appsync-sdk-js/issues/320)) ([8dbe01d](https://github.com/awslabs/aws-mobile-appsync-sdk-js/commit/8dbe01d))
* **offline-helpers:** Offline helpers types and fix issue with different options ([#329](https://github.com/awslabs/aws-mobile-appsync-sdk-js/issues/329)) ([42ac50a](https://github.com/awslabs/aws-mobile-appsync-sdk-js/commit/42ac50a))
* **offline-helpers:** Preserve order of elements in update cache operation type ([#325](https://github.com/awslabs/aws-mobile-appsync-sdk-js/issues/325)) ([5b49946](https://github.com/awslabs/aws-mobile-appsync-sdk-js/commit/5b49946))
* **subscriptions:** Do not retry mqtt disconnections ([#319](https://github.com/awslabs/aws-mobile-appsync-sdk-js/issues/319)) ([b933379](https://github.com/awslabs/aws-mobile-appsync-sdk-js/commit/b933379))
* **subscriptions:** Guard against errors: null response in subscription handshake ([#337](https://github.com/awslabs/aws-mobile-appsync-sdk-js/issues/337)) ([a2035d0](https://github.com/awslabs/aws-mobile-appsync-sdk-js/commit/a2035d0))




<a name="1.7.0"></a>
# [1.7.0](https://github.com/awslabs/aws-mobile-appsync-sdk-js/compare/[email protected]@1.7.0) (2018-12-12)

Expand Down
2 changes: 1 addition & 1 deletion packages/aws-appsync/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "aws-appsync",
"version": "1.7.0",
"version": "1.7.1",
"main": "lib/index.js",
"license": "SEE LICENSE IN LICENSE",
"description": "AWS Mobile AppSync SDK for JavaScript",
Expand Down
9 changes: 7 additions & 2 deletions packages/aws-appsync/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { createRetryLink } from './link/retry-link';
import { boundEnqueueDeltaSync, buildSync, DELTASYNC_KEY, hashForOptions } from "./deltaSync";
import { Subscription } from 'apollo-client/util/Observable';
import { CONTROL_EVENTS_KEY } from './link/subscription-handshake-link';
import { S3Config } from "./link/complex-object-link";

export { defaultDataIdFromObject };

Expand Down Expand Up @@ -77,18 +78,20 @@ export const createAppSyncLink = ({
complexObjectsCredentials,
resultsFetcherLink = createHttpLink({ uri: url }),
conflictResolver,
s3Config
}: {
url: string,
region: string,
auth: AuthOptions,
complexObjectsCredentials: CredentialsGetter,
resultsFetcherLink?: ApolloLink,
conflictResolver?: ConflictResolver,
s3Config?: S3Config,
}) => {
const link = ApolloLink.from([
createLinkWithStore((store) => new OfflineLink(store)),
new ConflictResolutionLink(conflictResolver),
new ComplexObjectLink(complexObjectsCredentials),
new ComplexObjectLink(complexObjectsCredentials, s3Config),
createRetryLink(ApolloLink.from([
createAuthLink({ url, region, auth }),
createSubscriptionHandshakeLink(url, resultsFetcherLink)
Expand Down Expand Up @@ -135,6 +138,7 @@ export interface AWSAppSyncClientOptions {
cacheOptions?: ApolloReducerConfig,
disableOffline?: boolean,
offlineConfig?: OfflineConfig,
s3Config?: S3Config,
}

export interface OfflineConfig {
Expand Down Expand Up @@ -181,6 +185,7 @@ class AWSAppSyncClient<TCacheShape extends NormalizedCacheObject> extends Apollo
callback = () => { },
storeCacheRootMutation = false,
} = {},
s3Config = {}
}: AWSAppSyncClientOptions, options?: Partial<ApolloClientOptions<TCacheShape>>) {
const { cache: customCache = undefined, link: customLink = undefined } = options || {};

Expand Down Expand Up @@ -218,7 +223,7 @@ class AWSAppSyncClient<TCacheShape extends NormalizedCacheObject> extends Apollo
};
});
});
const link = waitForRehydrationLink.concat(customLink || createAppSyncLink({ url, region, auth, complexObjectsCredentials, conflictResolver }));
const link = waitForRehydrationLink.concat(customLink || createAppSyncLink({ url, region, auth, complexObjectsCredentials, conflictResolver , s3Config}));

const newOptions = {
...options,
Expand Down
2 changes: 1 addition & 1 deletion packages/aws-appsync/src/deltaSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ const effect = async <TCache extends NormalizedCacheObject>(
}
//#endregion

const { baseRefreshIntervalInSeconds } = baseQuery;
const { baseRefreshIntervalInSeconds } = baseQuery || { baseRefreshIntervalInSeconds: undefined };
upperBoundTimeMS = baseRefreshIntervalInSeconds ? baseRefreshIntervalInSeconds * 1000 : DEFAULT_UPPER_BOUND_TIME_MS;

const skipBaseQuery = !(baseQuery && baseQuery.query) || (baseLastSyncTimestamp
Expand Down
15 changes: 10 additions & 5 deletions packages/aws-appsync/src/helpers/offline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ export type CacheUpdateQuery = QueryWithVariables | DocumentNode;

export type CacheUpdatesDefinitions = {
[key in CacheOperationTypes]?: CacheUpdateQuery | CacheUpdateQuery[]
};
} | CacheUpdateQuery | CacheUpdateQuery[];

export type CacheUpdatesOptions = (variables?: object) => CacheUpdatesDefinitions | CacheUpdatesDefinitions;
export type CacheUpdatesOptions = ((variables?: object) => CacheUpdatesDefinitions) | CacheUpdatesDefinitions;

/**
* Builds a SubscribeToMoreOptions object ready to be used by Apollo's subscribeToMore() to automatically update the query result in the
Expand Down Expand Up @@ -171,9 +171,14 @@ const getOpTypeQueriesMap = (cacheUpdateQuery: CacheUpdatesOptions, variables):
const cacheUpdateQueryVal = typeof cacheUpdateQuery === 'function' ?
cacheUpdateQuery(variables) :
cacheUpdateQuery || {};
const opTypeQueriesMap = isDocument(cacheUpdateQueryVal) ?
{ [CacheOperationTypes.AUTO]: [].concat(cacheUpdateQueryVal) } as CacheUpdatesDefinitions :
cacheUpdateQueryVal;

let opTypeQueriesMap = cacheUpdateQueryVal;

if (isDocument(cacheUpdateQueryVal) ||
isDocument((cacheUpdateQueryVal as QueryWithVariables).query) ||
Array.isArray(cacheUpdateQuery)) {
opTypeQueriesMap = { [CacheOperationTypes.AUTO]: [].concat(cacheUpdateQueryVal) } as CacheUpdatesDefinitions;
}

return opTypeQueriesMap;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/
import * as S3 from 'aws-sdk/clients/s3';

export default (fileField, { credentials }) => {
export default (fileField, { credentials, s3Config }) => {
const {
bucket: Bucket,
key: Key,
Expand All @@ -22,10 +22,16 @@ export default (fileField, { credentials }) => {
region,
});

return s3.upload({
let params: S3.PutObjectRequest = {
Bucket,
Key,
Body,
ContentType,
}).promise();
};

if (s3Config && s3Config.modifyPutObjectRequest) {
params = s3Config.modifyPutObjectRequest(params);
}

return s3.upload(params).promise();
};
12 changes: 9 additions & 3 deletions packages/aws-appsync/src/link/complex-object-link-uploader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/
import * as S3 from 'aws-sdk/clients/s3';

export default (fileField, { credentials }) => {
export default (fileField, { credentials, s3Config }) => {
const {
bucket: Bucket,
key: Key,
Expand All @@ -22,10 +22,16 @@ export default (fileField, { credentials }) => {
region,
});

return s3.upload({
let params: S3.PutObjectRequest = {
Bucket,
Key,
Body,
ContentType,
}).promise();
};

if (s3Config && s3Config.modifyPutObjectRequest) {
params = s3Config.modifyPutObjectRequest(params);
}

return s3.upload(params).promise();
};
15 changes: 11 additions & 4 deletions packages/aws-appsync/src/link/complex-object-link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,30 @@ import { ExecutionResult, GraphQLError } from 'graphql';

import upload from "./complex-object-link-uploader";
import { AWSAppsyncGraphQLError } from '../types';
import { S3 } from "aws-sdk";

export interface S3Config{
modifyPutObjectRequest?: (request: S3.PutObjectRequest) => S3.PutObjectRequest
}

export class ComplexObjectLink extends ApolloLink {

private link: ApolloLink;

constructor(credentials) {
constructor(credentials, s3Config = null) {
super();

this.link = complexObjectLink(credentials);
this.link = complexObjectLink(credentials, s3Config);
}

request(operation, forward) {
return this.link.request(operation, forward);
}
}

export const complexObjectLink = (credentials) => {


export const complexObjectLink = (credentials, s3Config = null) => {
return new ApolloLink((operation, forward) => {
return new Observable(observer => {
let handle;
Expand All @@ -46,7 +53,7 @@ export const complexObjectLink = (credentials) => {

uploadPromise = Promise.resolve(uploadCredentials)
.then(credentials => {
const uploadPromises = Object.entries(objectsToUpload).map(([_, fileField]) => upload(fileField, { credentials }));
const uploadPromises = Object.entries(objectsToUpload).map(([_, fileField]) => upload(fileField, { credentials, s3Config }));

return Promise.all([operation, ...uploadPromises] as Promise<any>[]);
})
Expand Down
6 changes: 6 additions & 0 deletions packages/aws-appsync/src/link/retry-link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const MAX_DELAY_MS = 5 * 60 * 1000;
const getDelay = count => ((2 ** count) * BASE_TIME_MS) + (JITTER_FACTOR * Math.random());

export const SKIP_RETRY_KEY = '@@skipRetry';
export const PERMANENT_ERROR_KEY = typeof Symbol !== 'undefined' ? Symbol('permanentError') : '@@permanentError';

export const getEffectDelay = (_action: OfflineAction, retries: number) => {
const delay = getDelay(retries);
Expand All @@ -30,8 +31,13 @@ export const createRetryLink = (origLink: ApolloLink) => {

const retryLink = new RetryLink({
attempts: (count, operation, error) => {
const { [PERMANENT_ERROR_KEY]: permanent = false } = error;
const { [SKIP_RETRY_KEY]: skipRetry = false } = operation.variables;

if (permanent) {
return false;
}

if (error.statusCode >= 400 && error.statusCode < 500) {
return false;
}
Expand Down
15 changes: 8 additions & 7 deletions packages/aws-appsync/src/link/subscription-handshake-link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import * as Paho from '../vendor/paho-mqtt';
import { ApolloError } from "apollo-client";
import { FieldNode } from "graphql";
import { getMainDefinition } from "apollo-utilities";
import { PERMANENT_ERROR_KEY } from "./retry-link";

const logger = rootLogger.extend('subscriptions');
const mqttLogger = logger.extend('mqtt');
Expand Down Expand Up @@ -66,13 +67,13 @@ export class SubscriptionHandshakeLink extends ApolloLink {
} = { subscription: { newSubscriptions: {}, mqttConnections: [] } },
errors = [],
}: {
extensions?: {
subscription: SubscriptionExtension
},
errors: any[]
} = subsInfo;
extensions?: {
subscription: SubscriptionExtension
},
errors: any[]
} = subsInfo;

if (errors.length) {
if (errors && errors.length) {
return new Observable(observer => {
observer.error(new ApolloError({
errorMessage: 'Error during subscription handshake',
Expand Down Expand Up @@ -170,7 +171,7 @@ export class SubscriptionHandshakeLink extends ApolloLink {
if (errorCode !== 0) {
topics.forEach(t => {
if (this.topicObservers.has(t)) {
this.topicObservers.get(t).forEach(observer => observer.error(args));
this.topicObservers.get(t).forEach(observer => observer.error({ ...args, [PERMANENT_ERROR_KEY]: true }));
}
});
}
Expand Down