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