Skip to content

Commit

Permalink
Merge fc16928 into fcef73c
Browse files Browse the repository at this point in the history
  • Loading branch information
dylanwulf committed Apr 3, 2020
2 parents fcef73c + fc16928 commit 6bfba14
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 4 deletions.
3 changes: 2 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ declare module "moleculer-apollo-server" {
import { SchemaDirectiveVisitor, IResolvers } from "graphql-tools";

export {
GraphQLUpload,
GraphQLExtension,
gql,
ApolloError,
Expand All @@ -18,6 +17,8 @@ declare module "moleculer-apollo-server" {
defaultPlaygroundOptions,
} from "apollo-server-core";

export { GraphQLUpload } from 'graphql-upload';

export * from "graphql-tools";

export interface ApolloServerOptions {
Expand Down
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
"use strict";

const core = require("apollo-server-core");
const { GraphQLUpload } = require("graphql-upload");
const { ApolloServer } = require("./src/ApolloServer");
const ApolloService = require("./src/service");
const gql = require("./src/gql");

module.exports = {
// Core
GraphQLUpload: core.GraphQLUpload,
GraphQLUpload: GraphQLUpload,
GraphQLExtension: core.GraphQLExtension,
gql: core.gql,
ApolloError: core.ApolloError,
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"dependencies": {
"@apollographql/graphql-playground-html": "^1.6.24",
"@hapi/accept": "^3.2.4",
"@types/graphql-upload": "^8.0.0",
"apollo-server-core": "^2.10.0",
"dataloader": "^2.0.0",
"graphql-subscriptions": "^1.1.0",
Expand Down
27 changes: 26 additions & 1 deletion src/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ module.exports = function(mixinOptions) {
nullIfError = false,
params: staticParams = {},
rootParams = {},
fileUploadArg = null,
} = def;
const rootKeys = Object.keys(rootParams);

Expand Down Expand Up @@ -189,6 +190,27 @@ module.exports = function(mixinOptions) {
return Array.isArray(dataLoaderKey)
? await dataLoader.loadMany(dataLoaderKey)
: await dataLoader.load(dataLoaderKey);
} else if (fileUploadArg != null && args[fileUploadArg] != null) {
if (Array.isArray(args[fileUploadArg])) {
return await Promise.all(
args[fileUploadArg].map(async uploadPromise => {
const {
createReadStream,
...$fileInfo
} = await uploadPromise;
const stream = createReadStream();
return context.ctx.call(actionName, stream, {
meta: { $fileInfo },
});
})
);
}

const { createReadStream, ...$fileInfo } = await args[fileUploadArg];
const stream = createReadStream();
return await context.ctx.call(actionName, stream, {
meta: { $fileInfo },
});
} else {
const params = {};
if (root && rootKeys) {
Expand Down Expand Up @@ -411,7 +433,10 @@ module.exports = function(mixinOptions) {
const name = this.getFieldName(mutation);
mutations.push(mutation);
resolver.Mutation[name] = this.createActionResolver(
action.name
action.name,
{
fileUploadArg: def.fileUploadArg,
}
);
});
}
Expand Down
101 changes: 100 additions & 1 deletion test/unit/service.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ describe("Test Service", () => {
});
});

describe("Test 'createActionResolver' without DataLoader", () => {
describe("Test 'createActionResolver' without DataLoader or Upload", () => {
let broker, svc, stop;

beforeAll(async () => {
Expand Down Expand Up @@ -534,6 +534,105 @@ describe("Test Service", () => {
});
});

describe("Test 'createActionResolver' with File Upload", () => {
let broker, svc, stop;

beforeAll(async () => {
const res = await startService();
broker = res.broker;
svc = res.svc;
stop = res.stop;
});

afterAll(async () => await stop());

it("should create a stream and pass to call", async () => {
const resolver = svc.createActionResolver("posts.uploadSingle", {
fileUploadArg: "file",
});

const ctx = new Context(broker);
ctx.call = jest.fn(() => "response from action");

const fakeRoot = {};

const file = {
filename: "filename.txt",
encoding: "7bit",
mimetype: "text/plain",
createReadStream: () => "fake read stream",
};

const res = await resolver(fakeRoot, { file }, { ctx });

expect(res).toBe("response from action");

expect(ctx.call).toBeCalledTimes(1);
expect(ctx.call).toBeCalledWith("posts.uploadSingle", "fake read stream", {
meta: {
$fileInfo: {
filename: "filename.txt",
encoding: "7bit",
mimetype: "text/plain",
},
},
});
});

it("should invoke call once per file when handling an array of file uploads", async () => {
const resolver = svc.createActionResolver("posts.uploadMulti", {
fileUploadArg: "files",
});

const ctx = new Context(broker);
ctx.call = jest.fn((_, stream) => `response for ${stream}`);

const fakeRoot = {};

const files = [
{
filename: "filename1.txt",
encoding: "7bit",
mimetype: "text/plain",
createReadStream: () => "fake read stream 1",
},
{
filename: "filename2.txt",
encoding: "7bit",
mimetype: "text/plain",
createReadStream: () => "fake read stream 2",
},
];

const res = await resolver(fakeRoot, { files }, { ctx });

expect(res).toEqual([
"response for fake read stream 1",
"response for fake read stream 2",
]);

expect(ctx.call).toBeCalledTimes(2);
expect(ctx.call).toBeCalledWith("posts.uploadMulti", "fake read stream 1", {
meta: {
$fileInfo: {
filename: "filename1.txt",
encoding: "7bit",
mimetype: "text/plain",
},
},
});
expect(ctx.call).toBeCalledWith("posts.uploadMulti", "fake read stream 2", {
meta: {
$fileInfo: {
filename: "filename2.txt",
encoding: "7bit",
mimetype: "text/plain",
},
},
});
});
});

describe("Test 'createActionResolver' with DataLoader", () => {
let broker, svc, stop;

Expand Down

0 comments on commit 6bfba14

Please sign in to comment.