UNPKG

3.6 kBJavaScriptView Raw
1/* @flow */
2import fetch from 'node-fetch'
3import { createClient } from '@commercetools/sdk-client'
4import { createRequestBuilder } from '@commercetools/api-request-builder'
5import { createHttpMiddleware } from '@commercetools/sdk-middleware-http'
6import {
7 createAuthMiddlewareForClientCredentialsFlow,
8 createAuthMiddlewareWithExistingToken,
9} from '@commercetools/sdk-middleware-auth'
10import { createUserAgentMiddleware } from '@commercetools/sdk-middleware-user-agent'
11import JSONStream from 'JSONStream'
12import type {
13 ApiConfigOptions,
14 ExporterOptions,
15 LoggerOptions,
16} from 'types/customerGroups'
17import type { Client, ClientRequest } from 'types/sdk'
18import silentLogger from './utils/silent-logger'
19import pkg from '../package.json'
20
21export default class CustomerGroupsExporter {
22 // Set type annotations
23 apiConfig: ApiConfigOptions
24 client: Client
25 logger: LoggerOptions
26 predicate: ?string
27
28 constructor(options: ExporterOptions) {
29 if (!options.apiConfig)
30 throw new Error('The constructor must be passed an `apiConfig` object')
31 this.apiConfig = options.apiConfig
32 this.client = createClient({
33 middlewares: [
34 createAuthMiddlewareWithExistingToken(
35 options.accessToken ? `Bearer ${options.accessToken}` : ''
36 ),
37 createAuthMiddlewareForClientCredentialsFlow({
38 ...this.apiConfig,
39 fetch,
40 }),
41 createUserAgentMiddleware({
42 libraryName: pkg.name,
43 libraryVersion: pkg.version,
44 }),
45 createHttpMiddleware({
46 host: this.apiConfig.apiUrl,
47 enableRetry: true,
48 fetch,
49 }),
50 ],
51 })
52
53 this.predicate = options.predicate
54
55 this.logger = {
56 ...silentLogger,
57 ...options.logger,
58 }
59 }
60
61 run(outputStream: stream$Writable) {
62 this.logger.info('Starting Export')
63 const jsonStream = JSONStream.stringify()
64 jsonStream.pipe(outputStream)
65 this.handleOutput(outputStream, jsonStream, this.apiConfig.projectKey)
66 }
67
68 handleOutput(
69 outputStream: stream$Writable,
70 pipeStream: stream$Writable,
71 projectKey: string
72 ) {
73 this.fetchGroups(pipeStream, projectKey)
74 .then(() => {
75 this.logger.info('Export operation completed successfully')
76 if (outputStream !== process.stdout) pipeStream.end()
77 })
78 .catch((e: Error) => {
79 outputStream.emit('error', e)
80 })
81 }
82
83 fetchGroups(output: stream$Writable, projectKey: string): Promise<any> {
84 const request = CustomerGroupsExporter.buildRequest(
85 projectKey,
86 this.predicate
87 )
88
89 return this.client.process(
90 request,
91 ({ statusCode, body }: Object): Promise<any> => {
92 if (statusCode !== 200)
93 return Promise.reject(
94 new Error(`Request returned error ${statusCode}`)
95 )
96 body.results.forEach((object: Buffer) => {
97 output.write(object)
98 })
99 this.logger.debug(
100 `Successfully exported ${body.count} customer %s`,
101 body.count > 1 ? 'groups' : 'group'
102 )
103 return Promise.resolve()
104 },
105 {
106 accumulate: false,
107 }
108 )
109 }
110
111 static buildRequest(projectKey: string, predicate: ?string): ClientRequest {
112 const uri = CustomerGroupsExporter.buildUri(projectKey, predicate)
113 return {
114 uri,
115 method: 'GET',
116 }
117 }
118
119 static buildUri(projectKey: string, predicate: ?string): string {
120 const service = createRequestBuilder({
121 projectKey,
122 }).customerGroups
123 if (predicate) service.where(predicate)
124 return service.build()
125 }
126}