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 | 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 | }
|