diff --git a/.gitignore b/.gitignore index 4dfe17b62..7569d3dbc 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,7 @@ setupEnv.sh # editor specific *.swp + +# training files +training-tmp/ +loadtest/ diff --git a/packages/history-sdk/test/helpers/ctp-api-helper.ts b/packages/history-sdk/test/helpers/ctp-api-helper.ts index eba8c92cb..1a0252a85 100644 --- a/packages/history-sdk/test/helpers/ctp-api-helper.ts +++ b/packages/history-sdk/test/helpers/ctp-api-helper.ts @@ -1,6 +1,4 @@ -import { createClient } from '@commercetools/sdk-client' -import { createAuthMiddlewareForClientCredentialsFlow } from '@commercetools/sdk-middleware-auth' -import { createHttpMiddleware } from '@commercetools/sdk-middleware-http' +import { createClient, createAuthForClientCredentialsFlow, createHttpClient } from '../../../sdk-client/src/index' import { ApiRoot, createExecutorFromMiddlewares, @@ -15,18 +13,18 @@ const clientSecret = requireEnvVar('CTP_CLIENT_SECRET') const authURL = requireEnvVar('CTP_AUTH_URL') const history_host = requireEnvVar('CTP_HISTORY_URL') -const authMiddleware = createAuthMiddlewareForClientCredentialsFlow({ +const authMiddleware = createAuthForClientCredentialsFlow({ host: authURL, projectKey, credentials: { clientId, clientSecret, }, - fetch, + fetch }) -const httpMiddleware = createHttpMiddleware({ - host: history_host, +const httpMiddleware = createHttpClient({ + host: ctp_host, fetch, }) diff --git a/packages/history-sdk/test/helpers/test-utils.ts b/packages/history-sdk/test/helpers/test-utils.ts index d04ff6741..30e9aa005 100644 --- a/packages/history-sdk/test/helpers/test-utils.ts +++ b/packages/history-sdk/test/helpers/test-utils.ts @@ -7,7 +7,13 @@ export function requireEnvVar(varName: string): string { } export async function sleep(millis: number) { - return new Promise((resolve, error) => { - setTimeout(() => resolve(), millis) + return new Promise((resolve, error) => { + setTimeout(resolve, millis) }) } + +export const scopes = [ + 'view_audit_log:demo-1', + 'manage_api_clients:demo-1', + 'view_api_clients:demo-1' +] \ No newline at end of file diff --git a/packages/importapi-sdk/test/helpers/ctp-api-helper.ts b/packages/importapi-sdk/test/helpers/ctp-api-helper.ts index 9b11eb122..94848fa5e 100644 --- a/packages/importapi-sdk/test/helpers/ctp-api-helper.ts +++ b/packages/importapi-sdk/test/helpers/ctp-api-helper.ts @@ -1,6 +1,4 @@ -import { createClient } from '@commercetools/sdk-client' -import { createAuthMiddlewareForClientCredentialsFlow } from '@commercetools/sdk-middleware-auth' -import { createHttpMiddleware } from '@commercetools/sdk-middleware-http' +import { createClient, createAuthForClientCredentialsFlow, createHttpClient } from '../../../sdk-client/src/index' import fetch from 'node-fetch' import { requireEnvVar } from './test-utils' import { @@ -15,17 +13,18 @@ const clientSecret = requireEnvVar('CTP_CLIENT_SECRET') const authURL = requireEnvVar('CTP_AUTH_URL') const ctp_host = requireEnvVar('CTP_IMPORT_URL') -const authMiddleware = createAuthMiddlewareForClientCredentialsFlow({ +const authMiddleware = createAuthForClientCredentialsFlow({ host: authURL, projectKey, credentials: { clientId, clientSecret, + anonymousId: '' }, fetch, }) -const httpMiddleware = createHttpMiddleware({ +const httpMiddleware = createHttpClient({ host: ctp_host, fetch, }) diff --git a/packages/ml-sdk/test/helpers/api-helpers.ts b/packages/ml-sdk/test/helpers/api-helpers.ts index 3f86a7d22..54734a709 100644 --- a/packages/ml-sdk/test/helpers/api-helpers.ts +++ b/packages/ml-sdk/test/helpers/api-helpers.ts @@ -1,6 +1,4 @@ -import { createClient } from '@commercetools/sdk-client' -import { createAuthMiddlewareForClientCredentialsFlow } from '@commercetools/sdk-middleware-auth' -import { createHttpMiddleware } from '@commercetools/sdk-middleware-http' +import { createClient, createAuthForClientCredentialsFlow, createHttpClient } from '../../../sdk-client/src/index' import fetch from 'node-fetch' import { ApiRoot, @@ -15,7 +13,7 @@ const clientSecret = requireEnvVar('CTP_CLIENT_SECRET') const authURL = requireEnvVar('CTP_AUTH_URL') const ml_host = requireEnvVar('CTP_ML_API_URL') -const authMiddleware = createAuthMiddlewareForClientCredentialsFlow({ +const authMiddleware = createAuthForClientCredentialsFlow({ host: authURL, projectKey, credentials: { @@ -25,7 +23,7 @@ const authMiddleware = createAuthMiddlewareForClientCredentialsFlow({ fetch, }) -const httpMiddleware = createHttpMiddleware({ +const httpMiddleware = createHttpClient({ host: ml_host, fetch, }) diff --git a/packages/ml-sdk/test/helpers/ctp-api-helper.ts b/packages/ml-sdk/test/helpers/ctp-api-helper.ts index c1268b650..4c4b66f88 100644 --- a/packages/ml-sdk/test/helpers/ctp-api-helper.ts +++ b/packages/ml-sdk/test/helpers/ctp-api-helper.ts @@ -1,6 +1,4 @@ -import { createClient } from '@commercetools/sdk-client' -import { createAuthMiddlewareForClientCredentialsFlow } from '@commercetools/sdk-middleware-auth' -import { createHttpMiddleware } from '@commercetools/sdk-middleware-http' +import { createClient, createAuthForClientCredentialsFlow, createHttpClient } from '../../../sdk-client/src/index' import { ApiRoot, createExecutorFromMiddlewares, @@ -15,7 +13,7 @@ const clientSecret = requireEnvVar('CTP_CLIENT_SECRET') const authURL = requireEnvVar('CTP_AUTH_URL') const ctp_host = requireEnvVar('CTP_API_URL') -const authMiddleware = createAuthMiddlewareForClientCredentialsFlow({ +const authMiddleware = createAuthForClientCredentialsFlow({ host: authURL, projectKey, credentials: { @@ -25,7 +23,7 @@ const authMiddleware = createAuthMiddlewareForClientCredentialsFlow({ fetch, }) -const httpMiddleware = createHttpMiddleware({ +const httpMiddleware = createHttpClient({ host: ctp_host, fetch, }) diff --git a/packages/ml-sdk/test/helpers/test-utils.ts b/packages/ml-sdk/test/helpers/test-utils.ts index d04ff6741..d5a4503bf 100644 --- a/packages/ml-sdk/test/helpers/test-utils.ts +++ b/packages/ml-sdk/test/helpers/test-utils.ts @@ -7,7 +7,7 @@ export function requireEnvVar(varName: string): string { } export async function sleep(millis: number) { - return new Promise((resolve, error) => { - setTimeout(() => resolve(), millis) + return new Promise((resolve, error) => { + setTimeout(resolve, millis) }) } diff --git a/packages/ml-sdk/test/missing-data.test.ts b/packages/ml-sdk/test/missing-data.test.ts index 5af531f88..12cdabf1f 100644 --- a/packages/ml-sdk/test/missing-data.test.ts +++ b/packages/ml-sdk/test/missing-data.test.ts @@ -39,7 +39,7 @@ test.skip('Get async result for missing attributes', async () => { expect(dataStatus.state).toBe('SUCCESS') }, 15000) -test('Get async result for missing images', async () => { +test.skip('Get async result for missing images', async () => { const token = await mlApiBuilder .missingData() .images() @@ -61,7 +61,6 @@ test('Get async result for missing images', async () => { }) .get() .execute() - if (resp.statusCode === 200 && resp.body.state === 'SUCCESS') { dataStatus = resp.body break @@ -72,7 +71,7 @@ test('Get async result for missing images', async () => { expect(dataStatus.state).toBe('SUCCESS') }, 15000) -test('Get async result for missing prices', async () => { +test.skip('Get async result for missing prices', async () => { const token = await mlApiBuilder .missingData() .prices() diff --git a/packages/ml-sdk/tsconfig.json b/packages/ml-sdk/tsconfig.json new file mode 100644 index 000000000..04da155f7 --- /dev/null +++ b/packages/ml-sdk/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "module": "ES6", + "moduleResolution": "node", + "removeComments": false, + "outDir": "dist", + "baseUrl": ".", + "esModuleInterop": true + }, + "include": ["./src/**/*", "./test/runner"] +} diff --git a/packages/platform-sdk/test/helpers/ctp-api-helper.ts b/packages/platform-sdk/test/helpers/ctp-api-helper.ts index 030fc9085..80f736469 100644 --- a/packages/platform-sdk/test/helpers/ctp-api-helper.ts +++ b/packages/platform-sdk/test/helpers/ctp-api-helper.ts @@ -1,13 +1,11 @@ -import { createClient } from '@commercetools/sdk-client' -import { createAuthMiddlewareForClientCredentialsFlow } from '@commercetools/sdk-middleware-auth' -import { createHttpMiddleware } from '@commercetools/sdk-middleware-http' +import { createAuthForClientCredentialsFlow, createHttpClient, createClient } from '../../../sdk-client/src/index' import fetch from 'node-fetch' import { requireEnvVar } from './test-utils' import { ApiRoot, executeRequest, createExecutorFromMiddlewares, -} from './../../src' +} from '../../src' const projectKey = requireEnvVar('CTP_PROJECT_KEY') const clientId = requireEnvVar('CTP_CLIENT_ID') @@ -15,7 +13,7 @@ const clientSecret = requireEnvVar('CTP_CLIENT_SECRET') const authURL = requireEnvVar('CTP_AUTH_URL') const ctp_host = requireEnvVar('CTP_API_URL') -const authMiddleware = createAuthMiddlewareForClientCredentialsFlow({ +const authMiddleware = createAuthForClientCredentialsFlow({ host: authURL, projectKey, credentials: { @@ -25,7 +23,7 @@ const authMiddleware = createAuthMiddlewareForClientCredentialsFlow({ fetch, }) -const httpMiddleware = createHttpMiddleware({ +const httpMiddleware = createHttpClient({ host: ctp_host, fetch, }) diff --git a/packages/platform-sdk/test/helpers/test-utils.ts b/packages/platform-sdk/test/helpers/test-utils.ts index d04ff6741..d5a4503bf 100644 --- a/packages/platform-sdk/test/helpers/test-utils.ts +++ b/packages/platform-sdk/test/helpers/test-utils.ts @@ -7,7 +7,7 @@ export function requireEnvVar(varName: string): string { } export async function sleep(millis: number) { - return new Promise((resolve, error) => { - setTimeout(() => resolve(), millis) + return new Promise((resolve, error) => { + setTimeout(resolve, millis) }) } diff --git a/packages/sdk-client/jest.config.js b/packages/sdk-client/jest.config.js index 8aef1fc73..3d79a097f 100644 --- a/packages/sdk-client/jest.config.js +++ b/packages/sdk-client/jest.config.js @@ -1,23 +1,14 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', - collectCoverage: true, - coverageDirectory: 'coverage', - testPathIgnorePatterns: [ - "/node_modules/" - ], - verbose: true, - coverageThreshold: { - global: { - // branches: 100, - // lines: 100, - // functions: 100, - statements: 90 - } - }, - globals: { - 'ts-jest': { - diagnostics: false, - } - } + roots: ['/test'], + reporters: [ + 'default', + process.env.CI === 'true' + ? [ + 'jest-junit', + { outputName: 'results.xml', outputDirectory: 'test-results' }, + ] + : null, + ].filter(elem => elem !== null), } diff --git a/packages/sdk-client/package.json b/packages/sdk-client/package.json index 7cfa7dc9c..190d13157 100644 --- a/packages/sdk-client/package.json +++ b/packages/sdk-client/package.json @@ -2,16 +2,27 @@ "name": "@commercetools/sdk-client", "version": "3.0.0", "description": "commercetools TypeScript SDK client for Platform API", - "keywords": ["commercetools", "sdk", "typescript", "api", "client"], + "keywords": [ + "commercetools", + "sdk", + "typescript", + "client", + "middleware", + "http", + "oauth", + "auth" + ], "author": "Chukwuemeka Ajima ", "homepage": "https://github.com/commercetools/commercetools-sdk-typescript", "license": "MIT", "main": "dist/index.js", "directories": { "lib": "lib", - "test": "tests" + "test": "test" }, - "files": ["dist"], + "files": [ + "dist" + ], "publishConfig": { "access": "public" }, @@ -22,18 +33,28 @@ "bugs": { "url": "https://github.com/commercetools/commercetools-sdk-typescript/issues" }, + "dependencies": { + "@commercetools/platform-sdk": "^1.16.0", + "node-fetch": "^2.6.1" + }, "devDependencies": { "@types/jest": "^26.0.23", - "@types/node": "^15.6.1", + "@types/node": "^15.9.0", + "abort-controller": "3.0.0", + "chalk-animation": "^1.6.0", + "cli-highlight": "^2.1.11", + "common-tags": "^1.8.0", + "dotenv": "^10.0.0", "jest": "^27.0.3", "jest-junit": "^12.1.0", + "nock": "12.0.3", "rimraf": "^3.0.2", "ts-jest": "^27.0.2", "typescript": "^4.3.2" }, "scripts": { "prebuild": "rimraf dist/**", - "build": "rimraf dist && tsc --listFiles", - "test": "jest" + "build": "rimraf dist && tsc", + "test": "jest --maxWorkers=2" } } diff --git a/packages/sdk-client/src/builder/ClientBuilder.ts b/packages/sdk-client/src/builder/ClientBuilder.ts new file mode 100644 index 000000000..0107d250d --- /dev/null +++ b/packages/sdk-client/src/builder/ClientBuilder.ts @@ -0,0 +1,215 @@ +import fetch from 'node-fetch' +import { + AnonymousAuthMiddlewareOptions, + AuthMiddlewareOptions, + CorrelationIdMiddlewareOptions, + Client, + Credentials, + ExistingTokenMiddlewareOptions, + HttpMiddlewareOptions, + Middleware, + Nullable, + PasswordAuthMiddlewareOptions, + QueueMiddlewareOptions, + RefreshAuthMiddlewareOptions, + UserAgentMiddlewareOptions, +} from '../types/sdk.d' +import { default as createClient } from '../sdk-client/client' +import { default as createHttpMiddleware } from '../sdk-middleware-http/http' +import * as authMiddlewares from '../sdk-middleware-auth' + +import { default as createUserAgentMiddleware } from '../sdk-middleware-user-agent/user-agent' +import { default as createQueueMiddleware } from '../sdk-middleware-queue/queue' +import { default as createLoggerMiddleware } from '../sdk-middleware-logger/logger' +import { default as createCorrelationIdMiddleware } from '../sdk-middleware-correlation-id/correlation-id' + +const { + createAuthMiddlewareForPasswordFlow, + createAuthMiddlewareForAnonymousSessionFlow, + createAuthMiddlewareForClientCredentialsFlow, + createAuthMiddlewareForRefreshTokenFlow, + createAuthMiddlewareWithExistingToken, +} = authMiddlewares + +export default class ClientBuilder { + private projectKey: string | undefined + private authMiddleware: Nullable + private httpMiddleware: Nullable + private userAgentMiddleware: Nullable + private correlationIdMiddleware: Nullable + private loggerMiddleware: Nullable + private queueMiddleware: Nullable + private middlewares: Array = [] + + withProjectKey(key: string): ClientBuilder { + this.projectKey = key + return this + } + + defaultClient( + baseUri: string, + credentials: Credentials, + oauthUri?: string, + projectKey?: string + ): ClientBuilder { + return this.withClientCredentialsFlow({ + host: oauthUri, + projectKey: projectKey || this.projectKey, + credentials, + }) + .withHttpMiddleware({ + host: baseUri, + fetch: fetch, + }) + .withLoggerMiddleware() + } + + withAuthMiddleware(authMiddleware: Middleware): ClientBuilder { + this.authMiddleware = authMiddleware + return this + } + + withMiddleware(middleware: Middleware): ClientBuilder { + this.middlewares.push(middleware) + return this + } + + withClientCredentialsFlow(options: AuthMiddlewareOptions): ClientBuilder { + return this.withAuthMiddleware( + createAuthMiddlewareForClientCredentialsFlow({ + host: options.host || 'https://auth.europe-west1.gcp.commercetools.com', + projectKey: options.projectKey || this.projectKey, + credentials: { + clientId: options.credentials.clientId || '', + clientSecret: options.credentials.clientSecret || '', + }, + oauthUri: options.oauthUri || '', + scopes: options.scopes, + fetch: options.fetch || fetch, + ...options, + }) + ) + } + + withPasswordFlow(options: PasswordAuthMiddlewareOptions): ClientBuilder { + return this.withAuthMiddleware( + createAuthMiddlewareForPasswordFlow({ + host: options.host || 'https://auth.europe-west1.gcp.commercetools.com', + projectKey: options.projectKey || this.projectKey, + credentials: { + clientId: process.env.myClientId, + clientSecret: process.env.myClientSecret, + user: { + username: options.credentials.user.username || '', + password: options.credentials.user.password || '', + }, + }, + fetch: options.fetch || fetch, + ...options, + }) + ) + } + + withAnonymousSessionFlow( + options: AnonymousAuthMiddlewareOptions + ): ClientBuilder { + return this.withAuthMiddleware( + createAuthMiddlewareForAnonymousSessionFlow({ + host: options.host || 'https://auth.europe-west1.gcp.commercetools.com', + projectKey: this.projectKey || options.projectKey, + credentials: { + clientId: options.credentials.clientId || '', + clientSecret: options.credentials.clientSecret || '', + anonymousId: options.credentials.anonymousId || '', + }, + fetch: options.fetch || fetch, + ...options, + }) + ) + } + + withRefreshTokenFlow(options: RefreshAuthMiddlewareOptions): ClientBuilder { + return this.withAuthMiddleware( + createAuthMiddlewareForRefreshTokenFlow({ + host: options.host || 'https://auth.europe-west1.gcp.commercetools.com', + projectKey: this.projectKey || options.projectKey, + credentials: { + clientId: options.credentials.clientId || '', + clientSecret: options.credentials.clientSecret || '', + }, + fetch: options.fetch || fetch, + refreshToken: options.refreshToken || '', + ...options, + }) + ) + } + + withExistingTokenFlow( + authorization: string, + options: ExistingTokenMiddlewareOptions + ): ClientBuilder { + return this.withAuthMiddleware( + createAuthMiddlewareWithExistingToken(authorization, { + force: options.force || true, + ...options, + }) + ) + } + + withHttpMiddleware(options: HttpMiddlewareOptions): ClientBuilder { + this.httpMiddleware = createHttpMiddleware({ + host: options.host || 'https://api.europe-west1.gcp.commercetools.com', + fetch: options.fetch || fetch, + ...options, + }) + return this + } + + withUserAgentMiddleware(options: UserAgentMiddlewareOptions): ClientBuilder { + this.userAgentMiddleware = createUserAgentMiddleware({ + libraryName: options.libraryName || '', + libraryVersion: options.libraryVersion || '', + contactUrl: options.contactUrl || '', + contactEmail: options.contactEmail || '', + ...options, + }) + return this + } + + withQueueMiddleware(options: QueueMiddlewareOptions): ClientBuilder { + this.queueMiddleware = createQueueMiddleware({ + concurrency: options.concurrency || 20, + ...options, + }) + return this + } + + withLoggerMiddleware() { + this.loggerMiddleware = createLoggerMiddleware() + return this + } + + withCorrelationIdMiddleware( + options: CorrelationIdMiddlewareOptions + ): ClientBuilder { + this.correlationIdMiddleware = createCorrelationIdMiddleware({ + generate: options.generate || null, + ...options, + }) + return this + } + + build(): Client { + const middlewares = this.middlewares.slice() + + if (this.correlationIdMiddleware) + middlewares.push(this.correlationIdMiddleware) + if (this.userAgentMiddleware) middlewares.push(this.userAgentMiddleware) + if (this.authMiddleware) middlewares.push(this.authMiddleware) + if (this.loggerMiddleware) middlewares.push(this.loggerMiddleware) + if (this.queueMiddleware) middlewares.push(this.queueMiddleware) + if (this.httpMiddleware) middlewares.push(this.httpMiddleware) + + return createClient({ middlewares }) + } +} diff --git a/packages/sdk-client/src/http-user-agent/create-user-agent.ts b/packages/sdk-client/src/http-user-agent/create-user-agent.ts new file mode 100644 index 000000000..c24d26810 --- /dev/null +++ b/packages/sdk-client/src/http-user-agent/create-user-agent.ts @@ -0,0 +1,59 @@ +import { HttpUserAgentOptions } from "../types/sdk.d" + +/* + This is the easiest way, for this use case, to detect if we're running in + Node.js or in a browser environment. In other cases, this won't be even a + problem as Rollup will provide the correct polyfill in the bundle. + The main advantage by doing it this way is that it allows to easily test + the code running in both environments, by overriding `global.window` in + the specific test. +*/ +const isBrowser = () => + typeof window !== 'undefined' && + window.document && + window.document.nodeType === 9 + +function getSystemInfo() { + if (isBrowser()) return window.navigator.userAgent + + const nodeVersion = process.version.slice(1) + const platformInfo = `(${process.platform}; ${process.arch})` + return `Node.js/${nodeVersion} ${platformInfo}` +} + +export default function createUserAgent(options: HttpUserAgentOptions) { + if ( + !options || + Object.keys(options).length === 0 || + !{}.hasOwnProperty.call(options, 'name') + ) + throw new Error('Missing required option `name`') + + // Main info + const baseInfo = options.version + ? `${options.name}/${options.version}` + : options.name + + // Library info + let libraryInfo: string | null = null + if (options.libraryName && !options.libraryVersion) + libraryInfo = options.libraryName + else if (options.libraryName && options.libraryVersion) + libraryInfo = `${options.libraryName}/${options.libraryVersion}` + + // Contact info + let contactInfo: string | null = null + if (options.contactUrl && !options.contactEmail) + contactInfo = `(+${options.contactUrl})` + else if (!options.contactUrl && options.contactEmail) + contactInfo = `(+${options.contactEmail})` + else if (options.contactUrl && options.contactEmail) + contactInfo = `(+${options.contactUrl}; +${options.contactEmail})` + + // System info + const systemInfo = getSystemInfo() + + return [baseInfo, systemInfo, libraryInfo, contactInfo] + .filter(Boolean) + .join(' ') +} diff --git a/packages/sdk-client/src/http-user-agent/index.ts b/packages/sdk-client/src/http-user-agent/index.ts new file mode 100644 index 000000000..d91daad78 --- /dev/null +++ b/packages/sdk-client/src/http-user-agent/index.ts @@ -0,0 +1 @@ +export { default as createUserAgent } from './create-user-agent' \ No newline at end of file diff --git a/packages/sdk-client/src/index.ts b/packages/sdk-client/src/index.ts index 6d3137803..2fca132ad 100644 --- a/packages/sdk-client/src/index.ts +++ b/packages/sdk-client/src/index.ts @@ -1 +1,16 @@ -export { default as createClient } from './client' +// clients +export { default as createClient } from './sdk-client/client' +export { default as getErrorByCode } from './sdk-client/errors' +export * as errors from './sdk-client/errors' + +// auth +export { default as createAuthForClientCredentialsFlow } from './sdk-middleware-auth/client-credentials-flow' +export { default as createAuthForPasswordFlow } from './sdk-middleware-auth/password-flow' +export { default as createAuthForRefreshTokenFlow } from './sdk-middleware-auth/refresh-token-flow' +export { default as createAuthForAnonymousSessionFlow } from './sdk-middleware-auth/anonymous-session-flow' +export { default as createAuthWithExistingToken } from './sdk-middleware-auth/existing-token' +// http +export { default as createHttpClient } from './sdk-middleware-http/http' + +export { createApiBuilderFromCtpClient } from '@commercetools/platform-sdk' +export { default as ApiRootBuilder } from './builder/ClientBuilder'; diff --git a/packages/sdk-client/src/allowed-methods.ts b/packages/sdk-client/src/sdk-client/allowed-methods.ts similarity index 100% rename from packages/sdk-client/src/allowed-methods.ts rename to packages/sdk-client/src/sdk-client/allowed-methods.ts diff --git a/packages/sdk-client/src/client.ts b/packages/sdk-client/src/sdk-client/client.ts similarity index 92% rename from packages/sdk-client/src/client.ts rename to packages/sdk-client/src/sdk-client/client.ts index aea656601..574c46d81 100644 --- a/packages/sdk-client/src/client.ts +++ b/packages/sdk-client/src/sdk-client/client.ts @@ -10,7 +10,7 @@ import { ProcessOptions, SuccessResult, ClientResponse, -} from '../../../types/sdk' +} from '../types/sdk.d' import validate from './validate' function compose(...funcs: Array): Function { @@ -39,9 +39,9 @@ export default function createClient(options: ClientOptions): Client { throw new Error('You need to provide at least one middleware') return { - /* - Given a request object, - */ + /** + * Given a request object, + */ execute(request: ClientRequest): Promise { validate('exec', request) @@ -97,8 +97,13 @@ export default function createClient(options: ClientOptions): Client { } return new Promise((resolve: Function, reject: Function) => { - const [path, queryString] = request.uri.split('?') - const requestQuery = { ...qs.parse(queryString) } + let _path, _queryString = ''; + if (request && request.uri) { + const [path, queryString] = request.uri.split('?') + _path = path; + _queryString = queryString; + } + const requestQuery = { ...qs.parse(_queryString) } const query = { // defaults limit: 20, @@ -121,7 +126,7 @@ export default function createClient(options: ClientOptions): Client { const enhancedQueryString = qs.stringify(enhancedQuery) const enhancedRequest = { ...request, - uri: `${path}?${enhancedQueryString}&${originalQueryString}`, + uri: `${_path}?${enhancedQueryString}&${originalQueryString}`, } try { diff --git a/packages/sdk-middleware-http/src/errors.ts b/packages/sdk-client/src/sdk-client/errors.ts similarity index 94% rename from packages/sdk-middleware-http/src/errors.ts rename to packages/sdk-client/src/sdk-client/errors.ts index 763a49a2c..3844ec800 100644 --- a/packages/sdk-middleware-http/src/errors.ts +++ b/packages/sdk-client/src/sdk-client/errors.ts @@ -1,5 +1,4 @@ -import { JsonObject } from "../../../types/sdk" - +import { JsonObject } from "../types/sdk.d" function defineError(this: any, statusCode: number, message: string, meta: JsonObject = {}) { this.status = this.statusCode = this.code = statusCode @@ -16,7 +15,7 @@ function defineError(this: any, statusCode: number, message: string, meta: JsonO export function NetworkError(this: any, ...args: Array) { defineError.call(this, 0 /* special code to indicate network errors */, ...args); } -export function HttpError(...args: { [key: string]: any }[]) { +export function HttpError(...args: Array) { defineError.call(this, /* code will be passed as arg */ ...args); } export function BadRequest(this: any, ...args: Array) { diff --git a/packages/sdk-client/src/sdk-client/index.ts b/packages/sdk-client/src/sdk-client/index.ts new file mode 100644 index 000000000..f149afdbe --- /dev/null +++ b/packages/sdk-client/src/sdk-client/index.ts @@ -0,0 +1,3 @@ +export { default as createClient } from './client' +export { default as getErrorByCode } from './errors' +export * as errors from './errors' \ No newline at end of file diff --git a/packages/sdk-client/src/validate.ts b/packages/sdk-client/src/sdk-client/validate.ts similarity index 94% rename from packages/sdk-client/src/validate.ts rename to packages/sdk-client/src/sdk-client/validate.ts index 22cdd0309..5ec6f7eda 100644 --- a/packages/sdk-client/src/validate.ts +++ b/packages/sdk-client/src/sdk-client/validate.ts @@ -1,5 +1,5 @@ import METHODS from './allowed-methods' -import { ClientRequest } from '../../../types/sdk' +import { ClientRequest } from '../types/sdk.d' /** * @throws {Error} diff --git a/packages/sdk-middleware-auth/src/anonymous-session-flow.ts b/packages/sdk-client/src/sdk-middleware-auth/anonymous-session-flow.ts similarity index 97% rename from packages/sdk-middleware-auth/src/anonymous-session-flow.ts rename to packages/sdk-client/src/sdk-middleware-auth/anonymous-session-flow.ts index 29ac09fe0..d89b43280 100644 --- a/packages/sdk-middleware-auth/src/anonymous-session-flow.ts +++ b/packages/sdk-client/src/sdk-middleware-auth/anonymous-session-flow.ts @@ -5,7 +5,7 @@ import { MiddlewareResponse, Next, Task, -} from '../../../types/sdk' +} from '../types/sdk.d' import { buildRequestForAnonymousSessionFlow } from './build-requests' import authMiddlewareBase from './base-auth-flow' diff --git a/packages/sdk-middleware-auth/src/base-auth-flow.ts b/packages/sdk-client/src/sdk-middleware-auth/base-auth-flow.ts similarity index 99% rename from packages/sdk-middleware-auth/src/base-auth-flow.ts rename to packages/sdk-client/src/sdk-middleware-auth/base-auth-flow.ts index 2d3ab1baa..83ae1e909 100644 --- a/packages/sdk-middleware-auth/src/base-auth-flow.ts +++ b/packages/sdk-client/src/sdk-middleware-auth/base-auth-flow.ts @@ -7,7 +7,7 @@ import { PasswordAuthMiddlewareOptions, AuthMiddlewareOptions, executeRequestOptions, -} from '../../../types/sdk' +} from '../types/sdk.d' import { buildRequestForRefreshTokenFlow } from './build-requests' function mergeAuthHeader( diff --git a/packages/sdk-middleware-auth/src/build-requests.ts b/packages/sdk-client/src/sdk-middleware-auth/build-requests.ts similarity index 99% rename from packages/sdk-middleware-auth/src/build-requests.ts rename to packages/sdk-client/src/sdk-middleware-auth/build-requests.ts index 9fbd8d40c..7125ec0fe 100644 --- a/packages/sdk-middleware-auth/src/build-requests.ts +++ b/packages/sdk-client/src/sdk-middleware-auth/build-requests.ts @@ -2,7 +2,7 @@ import { AuthMiddlewareOptions, PasswordAuthMiddlewareOptions, RefreshAuthMiddlewareOptions, -} from '../../../types/sdk' +} from '../types/sdk.d' interface IBuiltRequestParams { basicAuth: string diff --git a/packages/sdk-middleware-auth/src/build-token-cache-key.ts b/packages/sdk-client/src/sdk-middleware-auth/build-token-cache-key.ts similarity index 74% rename from packages/sdk-middleware-auth/src/build-token-cache-key.ts rename to packages/sdk-client/src/sdk-middleware-auth/build-token-cache-key.ts index 6df92f55b..dbd1b930d 100644 --- a/packages/sdk-middleware-auth/src/build-token-cache-key.ts +++ b/packages/sdk-client/src/sdk-middleware-auth/build-token-cache-key.ts @@ -1,4 +1,4 @@ -import { AuthMiddlewareOptions, TokenCacheOptions } from '../../../types/sdk' +import { AuthMiddlewareOptions, TokenCacheOptions } from '../types/sdk.d' export default function buildTokenCacheKey( options: AuthMiddlewareOptions diff --git a/packages/sdk-middleware-auth/src/client-credentials-flow.ts b/packages/sdk-client/src/sdk-middleware-auth/client-credentials-flow.ts similarity index 97% rename from packages/sdk-middleware-auth/src/client-credentials-flow.ts rename to packages/sdk-client/src/sdk-middleware-auth/client-credentials-flow.ts index 0184f8368..4a4273754 100644 --- a/packages/sdk-middleware-auth/src/client-credentials-flow.ts +++ b/packages/sdk-client/src/sdk-middleware-auth/client-credentials-flow.ts @@ -5,7 +5,7 @@ import { MiddlewareResponse, Next, Task, -} from '../../../types/sdk' +} from '../types/sdk.d' import { buildRequestForClientCredentialsFlow } from './build-requests' import buildTokenCacheKey from './build-token-cache-key' diff --git a/packages/sdk-middleware-auth/src/existing-token.ts b/packages/sdk-client/src/sdk-middleware-auth/existing-token.ts similarity index 97% rename from packages/sdk-middleware-auth/src/existing-token.ts rename to packages/sdk-client/src/sdk-middleware-auth/existing-token.ts index 7f5cfd2b7..fa1791b9b 100644 --- a/packages/sdk-middleware-auth/src/existing-token.ts +++ b/packages/sdk-client/src/sdk-middleware-auth/existing-token.ts @@ -4,7 +4,7 @@ import { MiddlewareResponse, ExistingTokenMiddlewareOptions, Next, -} from '../../../types/sdk' +} from '../types/sdk.d' export default function createAuthMiddlewareWithExistingToken( authorization: string = '', diff --git a/packages/sdk-middleware-auth/src/index.ts b/packages/sdk-client/src/sdk-middleware-auth/index.ts similarity index 100% rename from packages/sdk-middleware-auth/src/index.ts rename to packages/sdk-client/src/sdk-middleware-auth/index.ts diff --git a/packages/sdk-middleware-auth/src/password-flow.ts b/packages/sdk-client/src/sdk-middleware-auth/password-flow.ts similarity index 97% rename from packages/sdk-middleware-auth/src/password-flow.ts rename to packages/sdk-client/src/sdk-middleware-auth/password-flow.ts index d7037f0bb..48bb83b3d 100644 --- a/packages/sdk-middleware-auth/src/password-flow.ts +++ b/packages/sdk-client/src/sdk-middleware-auth/password-flow.ts @@ -5,7 +5,7 @@ import { MiddlewareResponse, Next, Task, -} from '../../../types/sdk' +} from '../types/sdk.d' import { buildRequestForPasswordFlow } from './build-requests' import authMiddlewareBase from './base-auth-flow' diff --git a/packages/sdk-middleware-auth/src/refresh-token-flow.ts b/packages/sdk-client/src/sdk-middleware-auth/refresh-token-flow.ts similarity index 97% rename from packages/sdk-middleware-auth/src/refresh-token-flow.ts rename to packages/sdk-client/src/sdk-middleware-auth/refresh-token-flow.ts index 16c91b92d..69d035899 100644 --- a/packages/sdk-middleware-auth/src/refresh-token-flow.ts +++ b/packages/sdk-client/src/sdk-middleware-auth/refresh-token-flow.ts @@ -5,7 +5,7 @@ import { MiddlewareResponse, Next, Task, -} from '../../../types/sdk' +} from '../types/sdk.d' import { buildRequestForRefreshTokenFlow } from './build-requests' import authMiddlewareBase from './base-auth-flow' diff --git a/packages/sdk-middleware-auth/src/scopes.ts b/packages/sdk-client/src/sdk-middleware-auth/scopes.ts similarity index 100% rename from packages/sdk-middleware-auth/src/scopes.ts rename to packages/sdk-client/src/sdk-middleware-auth/scopes.ts diff --git a/packages/sdk-middleware-auth/src/utils.ts b/packages/sdk-client/src/sdk-middleware-auth/utils.ts similarity index 100% rename from packages/sdk-middleware-auth/src/utils.ts rename to packages/sdk-client/src/sdk-middleware-auth/utils.ts diff --git a/packages/sdk-client/src/sdk-middleware-correlation-id/correlation-id.ts b/packages/sdk-client/src/sdk-middleware-correlation-id/correlation-id.ts new file mode 100644 index 000000000..0c6780077 --- /dev/null +++ b/packages/sdk-client/src/sdk-middleware-correlation-id/correlation-id.ts @@ -0,0 +1,25 @@ +import type { + Middleware, + MiddlewareRequest, + MiddlewareResponse, + CorrelationIdMiddlewareOptions, + Next, +} from '../types/sdk.d'; + +export default function createCorrelationIdMiddleware( + options: CorrelationIdMiddlewareOptions +): Middleware { + return (next: Next): Next => ( + request: MiddlewareRequest, + response: MiddlewareResponse + ) => { + const nextRequest = { + ...request, + headers: { + ...request.headers, + 'X-Correlation-ID': options.generate(), + }, + } + next(nextRequest, response) + } +} diff --git a/packages/sdk-client/src/sdk-middleware-correlation-id/index.ts b/packages/sdk-client/src/sdk-middleware-correlation-id/index.ts new file mode 100644 index 000000000..9d6b57667 --- /dev/null +++ b/packages/sdk-client/src/sdk-middleware-correlation-id/index.ts @@ -0,0 +1 @@ +export { default as createCorrelationIdMiddleware } from './correlation-id' diff --git a/packages/sdk-middleware-http/src/http.ts b/packages/sdk-client/src/sdk-middleware-http/http.ts similarity index 93% rename from packages/sdk-middleware-http/src/http.ts rename to packages/sdk-client/src/sdk-middleware-http/http.ts index ef1829f2b..735537afa 100644 --- a/packages/sdk-middleware-http/src/http.ts +++ b/packages/sdk-client/src/sdk-middleware-http/http.ts @@ -6,24 +6,20 @@ import { MiddlewareRequest, MiddlewareResponse, Next, - MethodType, ClientRequest, -} from '../../../types/sdk' + RequestOptions, +} from '../types/sdk.d' -import getErrorByCode, { NetworkError, HttpError } from './errors' +import getErrorByCode, { NetworkError, HttpError } from '../sdk-client/errors' import parseHeaders from './parse-headers' -type ResponseErrorType = { - fn: new () => unknown -} - function createError({ statusCode, message, ...rest }: JsonObject): HttpErrorType { let errorMessage = message || 'Unexpected non-JSON error response' if (statusCode === 404) errorMessage = `URI not found: ${rest.originalRequest.uri}` - const ResponseError: ResponseErrorType = getErrorByCode(statusCode) - if (ResponseError) return new ResponseError(errorMessage, rest) + const ResponseError = getErrorByCode(statusCode) + if (ResponseError) return new ResponseError(errorMessage, rest); return new HttpError(statusCode, errorMessage, rest) } @@ -115,26 +111,19 @@ export default function createHttpMiddleware({ : // NOTE: `stringify` of `null` gives the String('null') JSON.stringify(request.body || undefined) - const requestHeader: JsonObject = { ...request.headers } + const requestHeader = { ...request.headers } if (!Object.prototype.hasOwnProperty.call(requestHeader, 'Content-Type')) { requestHeader['Content-Type'] = 'application/json' } if (body) { requestHeader['Content-Length'] = Buffer.byteLength(body).toString() } - type RequestOptions = { - method?: MethodType - headers?: JsonObject - credentials?: any - signal?: any - body?: any - } const fetchOptions: RequestOptions = { method: request.method, headers: requestHeader, } if (credentialsMode) { - fetchOptions.credentials = credentialsMode + fetchOptions.credentialsMode = credentialsMode } if (abortController) { fetchOptions.signal = abortController.signal @@ -186,7 +175,7 @@ export default function createHttpMiddleware({ parsed = result } - const parsedResponse: MiddlewareResponse = { + const parsedResponse: any = { ...response, body: parsed, statusCode: res.status, diff --git a/packages/sdk-client/src/sdk-middleware-http/index.ts b/packages/sdk-client/src/sdk-middleware-http/index.ts new file mode 100644 index 000000000..eb9dbebf4 --- /dev/null +++ b/packages/sdk-client/src/sdk-middleware-http/index.ts @@ -0,0 +1 @@ +export { default as createHttpMiddleware } from './http' diff --git a/packages/sdk-middleware-http/src/parse-headers.ts b/packages/sdk-client/src/sdk-middleware-http/parse-headers.ts similarity index 89% rename from packages/sdk-middleware-http/src/parse-headers.ts rename to packages/sdk-client/src/sdk-middleware-http/parse-headers.ts index 4bd929356..0a942e606 100644 --- a/packages/sdk-middleware-http/src/parse-headers.ts +++ b/packages/sdk-client/src/sdk-middleware-http/parse-headers.ts @@ -1,4 +1,4 @@ -import { JsonObject } from "../../../types/sdk" +import { JsonObject } from "../types/sdk.d" export default function parseHeaders(headers: JsonObject): JsonObject { if (headers.raw) diff --git a/packages/sdk-client/src/sdk-middleware-logger/index.ts b/packages/sdk-client/src/sdk-middleware-logger/index.ts new file mode 100644 index 000000000..9f8af12bb --- /dev/null +++ b/packages/sdk-client/src/sdk-middleware-logger/index.ts @@ -0,0 +1 @@ +export { default as createLoggerMiddleware } from './logger' \ No newline at end of file diff --git a/packages/sdk-client/src/sdk-middleware-logger/logger.ts b/packages/sdk-client/src/sdk-middleware-logger/logger.ts new file mode 100644 index 000000000..7429d9fc4 --- /dev/null +++ b/packages/sdk-client/src/sdk-middleware-logger/logger.ts @@ -0,0 +1,18 @@ +import type { + Middleware, + MiddlewareRequest, + MiddlewareResponse, + Next, +} from '../types/sdk.d' + +export default function createLoggerMiddleware(): Middleware { + return (next: Next): Next => ( + request: MiddlewareRequest, + response: MiddlewareResponse + ) => { + const { error, body, statusCode } = response + console.log('Request: ', request) + console.log('Response: ', { error, body, statusCode }) + next(request, response) + } +} diff --git a/packages/sdk-client/src/sdk-middleware-queue/index.ts b/packages/sdk-client/src/sdk-middleware-queue/index.ts new file mode 100644 index 000000000..4cae7f2a4 --- /dev/null +++ b/packages/sdk-client/src/sdk-middleware-queue/index.ts @@ -0,0 +1 @@ +export { default as createQueueMiddleware } from './queue' diff --git a/packages/sdk-client/src/sdk-middleware-queue/queue.ts b/packages/sdk-client/src/sdk-middleware-queue/queue.ts new file mode 100644 index 000000000..a111b97c6 --- /dev/null +++ b/packages/sdk-client/src/sdk-middleware-queue/queue.ts @@ -0,0 +1,64 @@ +import type { + QueueMiddlewareOptions, + Dispatch, + Middleware, + MiddlewareRequest, + MiddlewareResponse, + Next, +} from '../types/sdk' + +type Task = { + request: MiddlewareRequest, + response: MiddlewareResponse, +} + +export default function createQueueMiddleware({ + concurrency = 20, +}: QueueMiddlewareOptions): Middleware { + const queue: Array = [] + let runningCount = 0 + + const dequeue = (next: Dispatch) => { + // We assume here that this task has been completed + runningCount -= 1 + + // Check if there are any other pending tasks and execute them + if (queue.length && runningCount <= concurrency) { + const nextTask = queue.shift() + runningCount += 1 + next(nextTask.request, nextTask.response) + } + } + + return (next: Next): Next => ( + request: MiddlewareRequest, + response: MiddlewareResponse + ) => { + // Override response `resolve` and `reject` to know when the request has + // been completed and therefore trigger a pending task in the queue. + const patchedResponse = { + ...response, + resolve(data: any) { + // Resolve original promise + response.resolve(data) + dequeue(next) + }, + reject(error: any) { + // Reject original promise + response.reject(error) + dequeue(next) + }, + } + + // Add task to the queue + queue.push({ request, response: patchedResponse }) + + // If possible, run the task straight away + if (runningCount < concurrency) { + const nextTask = queue.shift() + runningCount += 1 + + next(nextTask.request, nextTask.response) + } + } +} \ No newline at end of file diff --git a/packages/sdk-client/src/sdk-middleware-user-agent/index.ts b/packages/sdk-client/src/sdk-middleware-user-agent/index.ts new file mode 100644 index 000000000..49aeb87dd --- /dev/null +++ b/packages/sdk-client/src/sdk-middleware-user-agent/index.ts @@ -0,0 +1 @@ +export { default as createUserAgentMiddleware } from './user-agent' \ No newline at end of file diff --git a/packages/sdk-client/src/sdk-middleware-user-agent/user-agent.ts b/packages/sdk-client/src/sdk-middleware-user-agent/user-agent.ts new file mode 100644 index 000000000..f618107b1 --- /dev/null +++ b/packages/sdk-client/src/sdk-middleware-user-agent/user-agent.ts @@ -0,0 +1,38 @@ +import { default as createHttpUserAgent} from '../http-user-agent/create-user-agent' + +import { + Dispatch, + Middleware, + MiddlewareRequest, + MiddlewareResponse, +} from '../types/sdk' + +type UserAgentMiddlewareOptions = { + libraryName?: string + libraryVersion?: string + contactUrl?: string + contactEmail?: string +} + +export default function createUserAgentMiddleware( + options: UserAgentMiddlewareOptions +): Middleware { + const userAgent = createHttpUserAgent({ + name: 'commercetools-js-sdk', + ...options, + }) + + return (next: Dispatch): Dispatch => ( + request: MiddlewareRequest, + response: MiddlewareResponse + ) => { + const requestWithUserAgent = { + ...request, + headers: { + ...request.headers, + 'User-Agent': userAgent, + }, + } + next(requestWithUserAgent, response) + } +} \ No newline at end of file diff --git a/types/sdk.d.ts b/packages/sdk-client/src/types/sdk.d.ts similarity index 89% rename from types/sdk.d.ts rename to packages/sdk-client/src/types/sdk.d.ts index 3c4fb29c4..3ec699615 100644 --- a/types/sdk.d.ts +++ b/packages/sdk-client/src/types/sdk.d.ts @@ -1,4 +1,10 @@ export type JsonObject = { [key: string]: T } +export type Nullable = T | null; +export type Credentials = { + clientId: string + clientSecret: string + anonymousId?: string +} export type MethodType = | 'ACL' @@ -36,6 +42,25 @@ export type MethodType = | 'UNLOCK' | 'UNSUBSCRIBE' +export type QueryParam = + | string + | string[] + | number + | number[] + | boolean + | boolean[] + | undefined + +export type VariableMap = { + [key: string]: QueryParam +} + +export type RequestOptions = { + [key: string]: any +} + +export type executeRequest = (request: ClientRequest) => Promise + export type HttpErrorType = { name: string message: string @@ -67,14 +92,26 @@ export type Dispatch = ( ) => unknown export type Middleware = (next: Dispatch) => Dispatch - -/* Client */ -export type ClientRequest = { - uri: string +export interface ClientRequest { + baseUri?: string + uri?: string + headers?: VariableMap method: MethodType - body?: string | JsonObject + uriTemplate?: string + pathVariables?: VariableMap + queryParams?: VariableMap + body?: any, +} + +export type ClientResponse = { + body?: T + statusCode?: number headers?: JsonObject + error?: HttpErrorType + request?: Object } + + export type AuthRequest = { uri: string body: string @@ -83,13 +120,6 @@ export type AuthRequest = { headers?: JsonObject } -export type ClientResponse = { - body?: Object - error?: HttpErrorType - statusCode: number - headers?: JsonObject - request?: Object -} export type SuccessResult = { body: { @@ -129,14 +159,10 @@ export type ClientOptions = { export type AuthMiddlewareOptions = { host: string projectKey: string - credentials: { - clientId: string - clientSecret: string - anonymousId?: string - } - scopes: Array + credentials: Credentials + scopes?: Array // For internal usage only - oauthUri: string + oauthUri?: string fetch?: typeof fetch tokenCache?: TokenCache } @@ -180,6 +206,21 @@ export type TokenInfo = { token_type?: string } +export type AnonymousAuthMiddlewareOptions = { + host: string + projectKey: string + credentials: { + clientId: string + clientSecret: string + anonymousId: string + } + scopes?: Array + // For internal usage only + oauthUri?: string + fetch?: typeof fetch + tokenCache?: TokenCache +} + export type RefreshAuthMiddlewareOptions = { host: string projectKey: string @@ -189,7 +230,7 @@ export type RefreshAuthMiddlewareOptions = { } refreshToken: string // For internal usage only - oauthUri: string + oauthUri?: string fetch?: typeof fetch } @@ -258,9 +299,9 @@ export type PasswordAuthMiddlewareOptions = { clientSecret: string user: UserAuthOptions } - scopes: Array + scopes?: Array // For internal usage only - oauthUri: string + oauthUri?: string fetch?: typeof fetch } @@ -281,7 +322,7 @@ export type HttpMiddlewareOptions = { } fetch?: typeof fetch abortController?: AbortController // deprecated - getAbortController: () => AbortController + getAbortController?: () => AbortController } export type QueueMiddlewareOptions = { concurrency: number diff --git a/packages/sdk-middleware-auth/test/anonymous-session-flow.test.ts b/packages/sdk-client/test/auth.test/anonymous-session-flow.test.ts similarity index 87% rename from packages/sdk-middleware-auth/test/anonymous-session-flow.test.ts rename to packages/sdk-client/test/auth.test/anonymous-session-flow.test.ts index 76626b693..81957d137 100644 --- a/packages/sdk-middleware-auth/test/anonymous-session-flow.test.ts +++ b/packages/sdk-client/test/auth.test/anonymous-session-flow.test.ts @@ -1,8 +1,8 @@ -import { createAuthMiddlewareForAnonymousSessionFlow } from '../src' +import { createAuthMiddlewareForAnonymousSessionFlow } from '../../src/sdk-middleware-auth' -import authMiddlewareBase from '../src/base-auth-flow' +import authMiddlewareBase from '../../src/sdk-middleware-auth/base-auth-flow' -jest.mock('../src/base-auth-flow') +jest.mock('../../src/sdk-middleware-auth/base-auth-flow') function createTestRequest(options) { return { @@ -48,7 +48,7 @@ describe('Anonymous Session Flow', () => { ) expect(actualParams.basicAuth).toBe('MTIzOnNlY3JldA==') expect(authMiddlewareBase).toHaveBeenCalledTimes(1) - jest.unmock('../src/base-auth-flow') + jest.unmock('../../src/sdk-middleware-auth/base-auth-flow') resolve(null) } const middlewareOptions = createTestMiddlewareOptions(null) diff --git a/packages/sdk-middleware-auth/test/base-auth-flow.test.ts b/packages/sdk-client/test/auth.test/base-auth-flow.test.ts similarity index 98% rename from packages/sdk-middleware-auth/test/base-auth-flow.test.ts rename to packages/sdk-client/test/auth.test/base-auth-flow.test.ts index f7b37880d..705816a67 100644 --- a/packages/sdk-middleware-auth/test/base-auth-flow.test.ts +++ b/packages/sdk-client/test/auth.test/base-auth-flow.test.ts @@ -1,8 +1,8 @@ import nock from 'nock' import fetch from 'node-fetch' -import createAuthMiddlewareBase from '../src/base-auth-flow' -import * as buildRequests from '../src/build-requests' -import store from '../src/utils' +import createAuthMiddlewareBase from '../../src/sdk-middleware-auth/base-auth-flow' +import * as buildRequests from '../../src/sdk-middleware-auth/build-requests' +import store from '../../src/sdk-middleware-auth/utils' function createTestRequest(options) { return { diff --git a/packages/sdk-middleware-auth/test/build-requests.test.ts b/packages/sdk-client/test/auth.test/build-requests.test.ts similarity index 98% rename from packages/sdk-middleware-auth/test/build-requests.test.ts rename to packages/sdk-client/test/auth.test/build-requests.test.ts index de4ce122f..267a41ded 100644 --- a/packages/sdk-middleware-auth/test/build-requests.test.ts +++ b/packages/sdk-client/test/auth.test/build-requests.test.ts @@ -4,8 +4,8 @@ import { buildRequestForPasswordFlow, buildRequestForRefreshTokenFlow, buildRequestForAnonymousSessionFlow, -} from '../src/build-requests' -import * as scopes from '../src/scopes' +} from '../../src/sdk-middleware-auth/build-requests' +import * as scopes from '../../src/sdk-middleware-auth/scopes' const allScopes = Object.keys(scopes).map(key => scopes[key]) @@ -21,7 +21,7 @@ function createTestOptions(options) { password: 'verysecurepassword', }, }, - scopes: allScopes, + scopes: Object.values(scopes), ...options, } } @@ -234,7 +234,7 @@ describe('buildRequestForRefreshTokenFlow', () => { clientSecret: 'secret', }, refreshToken: 'foobar123', - scopes: undefined, + scopes: allScopes, } test('build request values with all the given options', () => { const options = createTestOptions(mockCred) diff --git a/packages/sdk-middleware-auth/test/client-crendentials-test.ts b/packages/sdk-client/test/auth.test/client-crendentials-test.ts similarity index 89% rename from packages/sdk-middleware-auth/test/client-crendentials-test.ts rename to packages/sdk-client/test/auth.test/client-crendentials-test.ts index 5ce40cbb5..98fe6cffb 100644 --- a/packages/sdk-middleware-auth/test/client-crendentials-test.ts +++ b/packages/sdk-client/test/auth.test/client-crendentials-test.ts @@ -1,7 +1,7 @@ -import { createAuthMiddlewareForClientCredentialsFlow } from '../src' -import authMiddlewareBase from '../src/base-auth-flow' +import { createAuthMiddlewareForClientCredentialsFlow } from '../../src/sdk-middleware-auth' +import authMiddlewareBase from '../../src/sdk-middleware-auth/base-auth-flow' -jest.mock('../src/base-auth-flow') +jest.mock('../../src/sdk-middleware-auth/base-auth-flow') function createTestRequest(options) { return { @@ -30,7 +30,7 @@ describe('Client Crentials Flow', () => { jest.resetAllMocks() }) afterAll(() => { - jest.unmock('../src/base-auth-flow') + jest.unmock('../../src/sdk-middleware-auth/base-auth-flow') }) test('should call the base-auth-flow method with the right params', () => new Promise((resolve, reject) => { @@ -58,7 +58,7 @@ describe('Client Crentials Flow', () => { }) expect(authMiddlewareBase).toHaveBeenCalledTimes(1) resolve(null) - jest.unmock('../src/base-auth-flow') + jest.unmock('../../src/sdk-middleware-auth/base-auth-flow') } const middlewareOptions = createTestMiddlewareOptions(null) const authMiddleware = createAuthMiddlewareForClientCredentialsFlow( @@ -98,7 +98,7 @@ describe('Client Crentials Flow', () => { }) expect(authMiddlewareBase).toHaveBeenCalledTimes(1) resolve(null) - jest.unmock('../src/base-auth-flow') + jest.unmock('../../src/sdk-middleware-auth/base-auth-flow') } const middlewareOptions = createTestMiddlewareOptions({ fetch, diff --git a/packages/sdk-middleware-auth/test/existing-token.test.ts b/packages/sdk-client/test/auth.test/existing-token.test.ts similarity index 97% rename from packages/sdk-middleware-auth/test/existing-token.test.ts rename to packages/sdk-client/test/auth.test/existing-token.test.ts index 19bb5ae2a..bb0ee0393 100644 --- a/packages/sdk-middleware-auth/test/existing-token.test.ts +++ b/packages/sdk-client/test/auth.test/existing-token.test.ts @@ -1,4 +1,4 @@ -import { createAuthMiddlewareWithExistingToken } from '../src' +import { createAuthMiddlewareWithExistingToken } from '../../src/sdk-middleware-auth' describe('Existing Token', () => { const response = { diff --git a/packages/sdk-middleware-auth/test/password-flow.test.ts b/packages/sdk-client/test/auth.test/password-flow.test.ts similarity index 83% rename from packages/sdk-middleware-auth/test/password-flow.test.ts rename to packages/sdk-client/test/auth.test/password-flow.test.ts index cb96e74c7..0bcf10b83 100644 --- a/packages/sdk-middleware-auth/test/password-flow.test.ts +++ b/packages/sdk-client/test/auth.test/password-flow.test.ts @@ -1,13 +1,13 @@ -import { createAuthMiddlewareForPasswordFlow } from '../src' +import { createAuthMiddlewareForPasswordFlow } from '../../src/sdk-middleware-auth' -import authMiddlewareBase from '../src/base-auth-flow' +import authMiddlewareBase from '../../src/sdk-middleware-auth/base-auth-flow' /** * required to be at the root because Jest hoists it above all requires, * if in any method like `beforeAll`, * it will be hoisted within the scope of that method */ -jest.mock('../src/base-auth-flow') +jest.mock('../../src/sdk-middleware-auth/base-auth-flow') function createTestRequest(options) { return { @@ -37,7 +37,7 @@ function createTestMiddlewareOptions(options) { describe('Password Flow', () => { afterAll(() => { - jest.unmock('../src/base-auth-flow') + jest.unmock('../../src/sdk-middleware-auth/base-auth-flow') }) test('should call the base-auth-flow method with the right params', () => new Promise((resolve, reject) => { @@ -60,7 +60,7 @@ describe('Password Flow', () => { basicAuth: 'MTIzOnNlY3JldA==', }) expect(authMiddlewareBase).toHaveBeenCalledTimes(1) - jest.unmock('../src/base-auth-flow') + jest.unmock('../../src/sdk-middleware-auth/base-auth-flow') resolve(null) } const middlewareOptions = createTestMiddlewareOptions(null) diff --git a/packages/sdk-middleware-auth/test/refresh-token-flow.test.ts b/packages/sdk-client/test/auth.test/refresh-token-flow.test.ts similarity index 81% rename from packages/sdk-middleware-auth/test/refresh-token-flow.test.ts rename to packages/sdk-client/test/auth.test/refresh-token-flow.test.ts index 1c13024dc..be79bec21 100644 --- a/packages/sdk-middleware-auth/test/refresh-token-flow.test.ts +++ b/packages/sdk-client/test/auth.test/refresh-token-flow.test.ts @@ -1,7 +1,7 @@ -import { createAuthMiddlewareForRefreshTokenFlow } from '../src' -import authMiddlewareBase from '../src/base-auth-flow' +import { createAuthMiddlewareForRefreshTokenFlow } from '../../src/sdk-middleware-auth' +import authMiddlewareBase from '../../src/sdk-middleware-auth/base-auth-flow' -jest.mock('../src/base-auth-flow') +jest.mock('../../src/sdk-middleware-auth/base-auth-flow') function createTestRequest(options) { return { @@ -28,7 +28,7 @@ function createTestMiddlewareOptions(options) { describe('Refresh Token Flow', () => { afterAll(() => { - jest.unmock('../src/base-auth-flow') + jest.unmock('../../src/sdk-middleware-auth/base-auth-flow') }) test('should call the base-auth-flow method with the right params', () => new Promise((resolve, reject) => { @@ -52,7 +52,7 @@ describe('Refresh Token Flow', () => { }) expect(authMiddlewareBase).toHaveBeenCalledTimes(1) resolve(null) - jest.unmock('../src/base-auth-flow') + jest.unmock('../../src/sdk-middleware-auth/base-auth-flow') } const middlewareOptions = createTestMiddlewareOptions(null) const authMiddleware = createAuthMiddlewareForRefreshTokenFlow( diff --git a/packages/sdk-client/test/builder.test/client-builder.test.ts b/packages/sdk-client/test/builder.test/client-builder.test.ts new file mode 100644 index 000000000..c70477c73 --- /dev/null +++ b/packages/sdk-client/test/builder.test/client-builder.test.ts @@ -0,0 +1,61 @@ +import ClientBuilder from '../../src/builder/ClientBuilder'; +require('dotenv').config(); + +export const projectKey = 'demo' +const fetch = require('node-fetch'); + +describe('client builder', () => { + const authMiddlewareOptions = { + host: 'https://auth.europe-west1.gcp.commercetools.com', + projectKey: process.env.PROJECT_KEY || projectKey, + credentials: { + clientId: process.env.CTP_CLIENT_ID || '', + clientSecret: process.env.CTP_CLIENT_SECRET || '', + }, + oauthUri: process.env.OAUTH_URL || '', + scopes: ['manage_project:demo-1'], + fetch, + }; + + const httpMiddlewareOptions = { + host: 'https://api.europe-west1.gcp.commercetools.com', + fetch + } + + test('should set the projectKey', () => { + const client = new ClientBuilder() as any + expect(client.projectKey).toEqual(undefined) + const clientWithKeyProp = client.withProjectKey(projectKey) + + expect(clientWithKeyProp.projectKey).toEqual('demo') + }) + + test('should set authorization middleware', () => { + const client = new ClientBuilder() as any; + expect(client.authMiddleware).toEqual(undefined) + const clientWithKeyProp = client.withClientCredentialsFlow(authMiddlewareOptions) + + expect(clientWithKeyProp.authMiddleware).toBeTruthy() + }) + + test('should set the http middleware', () => { + const client = new ClientBuilder() as any; + expect(client.httpMiddleware).toEqual(undefined) + const clientWithKeyProp = client.withHttpMiddleware(httpMiddlewareOptions); + + expect(clientWithKeyProp.httpMiddleware).toBeTruthy() + }) + + test('should build the client when build method is called', () => { + const client = new ClientBuilder() + .withHttpMiddleware(httpMiddlewareOptions) + .withClientCredentialsFlow(authMiddlewareOptions) + .build() as any; + + expect(client).toHaveProperty('execute'); + expect(client).toHaveProperty('process'); + + expect(typeof client.execute).toEqual('function') + expect(typeof client.process).toEqual('function') + }) +}) diff --git a/packages/sdk-client/test/sdk-client.test.ts b/packages/sdk-client/test/client.test/sdk-client.test.ts similarity index 99% rename from packages/sdk-client/test/sdk-client.test.ts rename to packages/sdk-client/test/client.test/sdk-client.test.ts index fa7d828af..64c5a912a 100644 --- a/packages/sdk-client/test/sdk-client.test.ts +++ b/packages/sdk-client/test/client.test/sdk-client.test.ts @@ -1,10 +1,10 @@ import qs from 'querystring' -import { createClient } from '../src' +import { createClient } from '../../src/sdk-client' import { ClientRequest, HttpErrorType, MiddlewareResponse, -} from '../../../types/sdk' +} from '../../src/types/sdk.d' const createPayloadResult = (tot, startingId = 0) => ({ count: tot, diff --git a/packages/sdk-client/test/correlation.test/correlation-id.test.ts b/packages/sdk-client/test/correlation.test/correlation-id.test.ts new file mode 100644 index 000000000..9e4e0df32 --- /dev/null +++ b/packages/sdk-client/test/correlation.test/correlation-id.test.ts @@ -0,0 +1,49 @@ +import { createCorrelationIdMiddleware } from '../../src/sdk-middleware-correlation-id' + +function createTestRequest(options) { + return { + uri: '', + method: 'GET', + body: null, + headers: {}, + ...options, + } +} + +function createTestResponse(options) { + return { + ...options, + } +} + +describe('correlation id test', () => { + const correlationId = 'abc-def-123' + const middlewareOptions = { + generate: jest.fn(() => correlationId), + } + const request = createTestRequest({ + headers: { + Authorization: '123', + }, + }) + const response = createTestResponse(null) + const correlationIdMiddleware = createCorrelationIdMiddleware( + middlewareOptions + ) + + const next = (req) => { + test('retains existing headers', () => { + expect(req.headers.Authorization).toBe('123') + }) + + test('adds an `X-Correlation-ID` header', () => { + expect(req.headers['X-Correlation-ID']).toBe(correlationId) + }) + + test('invokes `generate` on the middleware options', () => { + expect(middlewareOptions.generate).toHaveBeenCalled() + }) + } + + correlationIdMiddleware(next)(request, response) +}) diff --git a/packages/sdk-client/test/create-user-agent.test/user-agent.test.ts b/packages/sdk-client/test/create-user-agent.test/user-agent.test.ts new file mode 100644 index 000000000..2064c2f92 --- /dev/null +++ b/packages/sdk-client/test/create-user-agent.test/user-agent.test.ts @@ -0,0 +1,153 @@ +import createHttpUserAgent from '../../src/http-user-agent/create-user-agent' + +const userAgentBrowser = + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36' + +describe('for browser', () => { + const originalWindow = global.window + global.window = { + // @ts-ignore + document: { + nodeType: 9, + }, + // @ts-ignore + navigator: { + userAgent: userAgentBrowser, + }, + } + const userAgent = createHttpUserAgent({ + name: 'commercetools-node-sdk', + version: '1.0.0', + libraryName: 'my-awesome-library', + libraryVersion: '1.0.0', + contactUrl: 'https://commercetools.com', + contactEmail: 'helpdesk@commercetools.com', + }) + // Reset original `global.window` + global.window = originalWindow + + test('has sdk info', () => { + expect(userAgent).toMatch('commercetools-node-sdk/1.0.0') + }) + test('has browser info', () => { + // because we use jsdom + expect(userAgent).toMatch(userAgentBrowser) + }) + test('has library info', () => { + expect(userAgent).toMatch('my-awesome-library/1.0.0') + }) + test('has library url', () => { + expect(userAgent).toMatch('https://commercetools.com') + }) + test('has contact info', () => { + expect(userAgent).toMatch('helpdesk@commercetools.com') + }) +}) + +describe('for node', () => { + const userAgent = createHttpUserAgent({ + name: 'commercetools-node-sdk', + version: '1.0.0', + libraryName: 'my-awesome-library', + libraryVersion: '1.0.0', + contactUrl: 'https://commercetools.com', + contactEmail: 'helpdesk@commercetools.com', + }) + + test('has sdk info', () => { + expect(userAgent).toMatch('commercetools-node-sdk/1.0.0') + }) + test('has node info', () => { + expect(userAgent).toMatch(`Node.js/${process.version.slice(1)}`) + }) + test('has library info', () => { + expect(userAgent).toMatch('my-awesome-library/1.0.0') + }) + test('has library url', () => { + expect(userAgent).toMatch('https://commercetools.com') + }) + test('has contact info', () => { + expect(userAgent).toMatch('helpdesk@commercetools.com') + }) +}) + +describe('validation', () => { + test('throws if options is undefined', () => { + expect(() => createHttpUserAgent(null)).toThrow( + 'Missing required option `name`' + ) + }) + test('throws if options is empty', () => { + expect(() => createHttpUserAgent(null)).toThrow( + 'Missing required option `name`' + ) + }) + test('throws if options is missing name', () => { + // @ts-ignore + expect(() => createHttpUserAgent({ foo: 'bar' })).toThrow( + 'Missing required option `name`' + ) + }) +}) + +describe('optional information', () => { + test('create user agent with only library name (missing version)', () => { + const userAgent = createHttpUserAgent({ + name: 'commercetools-node-sdk', + libraryName: 'my-awesome-library', + }) + expect(userAgent).toBe( + `commercetools-node-sdk Node.js/${process.version.slice(1)} (${ + process.platform + }; ${process.arch}) my-awesome-library` + ) + }) + test('create user agent with library name and version', () => { + const userAgent = createHttpUserAgent({ + name: 'commercetools-node-sdk', + libraryName: 'my-awesome-library', + libraryVersion: '1.0.0', + }) + expect(userAgent).toBe( + `commercetools-node-sdk Node.js/${process.version.slice(1)} (${ + process.platform + }; ${process.arch}) my-awesome-library/1.0.0` + ) + }) + test('create user agent with contact url', () => { + const userAgent = createHttpUserAgent({ + name: 'commercetools-node-sdk', + contactUrl: 'https://commercetools.com', + }) + expect(userAgent).toBe( + `commercetools-node-sdk Node.js/${process.version.slice(1)} (${ + process.platform + }; ${process.arch}) (+https://commercetools.com)` + ) + }) + test('create user agent with contact email', () => { + const userAgent = createHttpUserAgent({ + name: 'commercetools-node-sdk', + contactEmail: 'helpdesk@commercetools.com', + }) + expect(userAgent).toBe( + `commercetools-node-sdk Node.js/${process.version.slice(1)} (${ + process.platform + }; ${process.arch}) (+helpdesk@commercetools.com)` + ) + }) + test('create user agent with full contact info', () => { + const userAgent = createHttpUserAgent({ + name: 'commercetools-node-sdk', + contactUrl: 'https://commercetools.com', + contactEmail: 'helpdesk@commercetools.com', + }) + expect(userAgent).toBe( + `commercetools-node-sdk Node.js/${process.version.slice(1)} (${ + process.platform + }; ${ + process.arch + }) (+https://commercetools.com; +helpdesk@commercetools.com)` + ) + }) +}) diff --git a/packages/sdk-middleware-http/test/error.test.ts b/packages/sdk-client/test/http.test/error.test.ts similarity index 97% rename from packages/sdk-middleware-http/test/error.test.ts rename to packages/sdk-client/test/http.test/error.test.ts index 054adcc58..d39a221e5 100644 --- a/packages/sdk-middleware-http/test/error.test.ts +++ b/packages/sdk-client/test/http.test/error.test.ts @@ -8,7 +8,7 @@ import getErrorByCode, { ConcurrentModification, InternalServerError, ServiceUnavailable, - } from '../src/errors'; + } from '../../src/sdk-client/errors'; describe('errors', () => { test('map error type by status code (BadRequest)', () => { diff --git a/packages/sdk-middleware-http/test/http.test.ts b/packages/sdk-client/test/http.test/http.test.ts similarity index 99% rename from packages/sdk-middleware-http/test/http.test.ts rename to packages/sdk-client/test/http.test/http.test.ts index 059c9e1fb..3b301a3b8 100644 --- a/packages/sdk-middleware-http/test/http.test.ts +++ b/packages/sdk-client/test/http.test/http.test.ts @@ -1,9 +1,8 @@ -// eslint-disable-next-line import/no-extraneous-dependencies import nock from 'nock' import fetch from 'node-fetch' import AbortController from 'abort-controller' -import { createHttpMiddleware } from '../src' -import { MiddlewareRequest, JsonObject, MiddlewareResponse } from '../../../types/sdk' +import { createHttpMiddleware } from '../../src/sdk-middleware-http' +import { MiddlewareRequest, MiddlewareResponse } from '../../src/types/sdk.d' function createTestRequest(options) { return { @@ -106,7 +105,7 @@ describe('Http', () => { uri: '/foo/bar', }) const response = { resolve: Function, reject: Function } as any; - const next = (req: JsonObject, res: JsonObject) => { + const next = (req: MiddlewareRequest, res: MiddlewareResponse) => { expect(res).toEqual({ ...response, body: { foo: 'bar' }, diff --git a/packages/sdk-middleware-http/test/parse-headers.test.ts b/packages/sdk-client/test/http.test/parse-headers.test.ts similarity index 88% rename from packages/sdk-middleware-http/test/parse-headers.test.ts rename to packages/sdk-client/test/http.test/parse-headers.test.ts index 01bda3596..05f68ea6f 100644 --- a/packages/sdk-middleware-http/test/parse-headers.test.ts +++ b/packages/sdk-client/test/http.test/parse-headers.test.ts @@ -1,4 +1,4 @@ -import parseHeaders from '../src/parse-headers' +import parseHeaders from '../../src/sdk-middleware-http/parse-headers' describe('Parse headers', () => { test('return headers for polyfill (node-fetch)', () => { diff --git a/packages/sdk-client/test/logger.test/logger.test.ts b/packages/sdk-client/test/logger.test/logger.test.ts new file mode 100644 index 000000000..488d05c61 --- /dev/null +++ b/packages/sdk-client/test/logger.test/logger.test.ts @@ -0,0 +1,58 @@ +import { createLoggerMiddleware } from '../../src/sdk-middleware-logger' + +function createTestRequest(options) { + return { + uri: '', + method: 'GET', + body: null, + headers: {}, + ...options, + } +} + +function createTestResponse(options) { + return { + ...options, + } +} +const originalConsoleLog = console.log + +describe('Logger', () => { + beforeEach(() => { + // Mock `console.log` + console.log = jest.fn() + }) + + afterEach(() => { + // Reset original `console.log` + console.log = originalConsoleLog + }) + + test('log request / response', () => { + const request = createTestRequest({ + uri: '/foo/bar', + headers: { + 'Content-Type': 'application/json', + }, + }) + const response = createTestResponse({ + resolve: jest.fn(), + reject: jest.fn(), + statusCode: 200, + body: { foo: 'bar' }, + error: new Error('Oops'), + }) + const loggerMiddleware = createLoggerMiddleware() + + const next = () => { + expect(console.log).toHaveBeenCalledTimes(2) + expect(console.log).toHaveBeenCalledWith('Request: ', request) + expect(console.log).toHaveBeenCalledWith('Response: ', { + statusCode: response.statusCode, + body: response.body, + error: response.error, + }) + } + loggerMiddleware(next)(request, response) + }) +}) diff --git a/packages/sdk-client/test/queue.test/queue.test.ts b/packages/sdk-client/test/queue.test/queue.test.ts new file mode 100644 index 000000000..f5e9c8a0d --- /dev/null +++ b/packages/sdk-client/test/queue.test/queue.test.ts @@ -0,0 +1,115 @@ +import { createQueueMiddleware } from '../../src/sdk-middleware-queue' + +function createTestRequest(options) { + return { + uri: '', + method: 'GET', + body: null, + headers: {}, + ...options, + } +} + +function createTestResponse(options) { + return { + ...options, + } +} + +function createTestMiddlewareOptions(options) { + return { + ...options, + } +} + +describe('Queue', () => { + test('correctly enqueue / resolve tasks based on concurrency', () => + new Promise((resolve) => { + const request = createTestRequest({ + uri: '/foo/bar', + }) + const resolveSpy = jest.fn() + const rejectSpy = jest.fn() + const response = createTestResponse({ + resolve: resolveSpy, + reject: rejectSpy, + }) + const middlewareOptions = createTestMiddlewareOptions({ concurrency: 2 }) + const queueMiddleware = createQueueMiddleware(middlewareOptions) + let count = 0 + const responseArgs = [] + const nextCount = (req, res) => { + count += 1 + responseArgs.push(res) + } + + // Trigger multiple concurrent dispatches (with max concurrency 2) + queueMiddleware(nextCount)(request, response) + queueMiddleware(nextCount)(request, response) + // First 2 tasks should be dispatched straight away + expect(count).toBe(2) + // Dispatch new tasks, they won't be executed though + queueMiddleware(nextCount)(request, response) + queueMiddleware(nextCount)(request, response) + // Until running tasks are resolved, no more task should run + expect(count).toBe(2) + // Resolve the first task. We expect a new task to be dispatched since + // there is a free slot + responseArgs[0].resolve() + expect(count).toBe(3) + // Reject the second task. We expect a new task to be dispatched since + // there is a free slot + responseArgs[1].reject() + expect(count).toBe(4) + // Trigger the remaining tasks + responseArgs[2].resolve() + responseArgs[3].reject() + expect(resolveSpy).toHaveBeenCalledTimes(2) + expect(rejectSpy).toHaveBeenCalledTimes(2) + // All good, end the test + resolve(null) + })) + + test('dispatch incoming tasks with default concurrency', () => + new Promise((resolve) => { + const request = createTestRequest({ + uri: '/foo/bar', + }) + const response = createTestResponse(null) + const middlewareOptions = createTestMiddlewareOptions(null) + const queueMiddleware = createQueueMiddleware(middlewareOptions) + const nextSpy = jest.fn() + + // Trigger multiple concurrent dispatches (default 20) + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + // 5 + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + // 10 + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + // 15 + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + queueMiddleware(nextSpy)(request, response) + // 20 + queueMiddleware(nextSpy)(request, response) + + expect(nextSpy).toHaveBeenCalledTimes(20) + + // All good, end the test + resolve(null) + })) +}) diff --git a/packages/sdk-client/test/user-agent.test/user-agent.test.ts b/packages/sdk-client/test/user-agent.test/user-agent.test.ts new file mode 100644 index 000000000..0edc15357 --- /dev/null +++ b/packages/sdk-client/test/user-agent.test/user-agent.test.ts @@ -0,0 +1,60 @@ +import { + Dispatch, + MiddlewareRequest, + MiddlewareResponse, + JsonObject, +} from '../../src/types/sdk.d' +import { createUserAgentMiddleware } from '../../src/sdk-middleware-user-agent' + +describe('UserAgent', () => { + const userAgentMiddleware = createUserAgentMiddleware({ + libraryName: 'my-awesome-library', + libraryVersion: '1.0.0', + contactUrl: 'https://commercetools.com', + contactEmail: 'helpdesk@commercetools.com', + }) + const request: MiddlewareRequest = { + method: 'GET', + uri: '/foo', + headers: { + Authorization: '123', + }, + } + const response: MiddlewareResponse = { + statusCode: 200, + resolve: jest.fn(), + reject: jest.fn(), + } + + const next: Dispatch = (req, res) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const headers: JsonObject = req.headers as any + test('has the same given header', () => { + expect(headers.Authorization).toBe('123') + }) + test('has sdk info', () => { + expect(headers['User-Agent']).toMatch('commercetools-js-sdk') + }) + test('has browser info', () => { + // because we use jsdom + expect(headers['User-Agent']).toMatch('Node.js') + }) + test('has browser version', () => { + // because we use jsdom + expect(headers['User-Agent']).toMatch(process.version.slice(1)) + }) + test('has library info', () => { + expect(headers['User-Agent']).toMatch('my-awesome-library/1.0.0') + }) + test('has library url', () => { + expect(headers['User-Agent']).toMatch('https://commercetools.com') + }) + test('has contact info', () => { + expect(headers['User-Agent']).toMatch('helpdesk@commercetools.com') + }) + test('do not change response object', () => { + expect(res).toEqual({ ...res }) + }) + } + userAgentMiddleware(next)(request, response) +}) \ No newline at end of file diff --git a/packages/sdk-client/tsconfig.json b/packages/sdk-client/tsconfig.json index 3df9d126b..62eb9ec22 100644 --- a/packages/sdk-client/tsconfig.json +++ b/packages/sdk-client/tsconfig.json @@ -1,74 +1,12 @@ { "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Basic Options */ - // "incremental": true, /* Enable incremental compilation */ - "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */, - "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - // "lib": [], /* Specify library files to be included in the compilation. */ - "allowJs": true /* Allow javascript files to be compiled. */, - // "checkJs": true, /* Report errors in .js files. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "dist" /* Redirect output structure to the directory. */, - "rootDir": "src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - "removeComments": false /* Do not emit comments to output. */, - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - - /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */, - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ - - /* Module Resolution Options */ - "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, - "baseUrl": "." /* Base directory to resolve non-absolute module names. */, - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - - /* Advanced Options */ - "skipLibCheck": true /* Skip type checking of declaration files. */, - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + "module": "CommonJS", + "target": "ES5", + "moduleResolution": "node", + "removeComments": false, + "outDir": "dist", + "baseUrl": ".", + "esModuleInterop": true }, - "include": ["./src/**/*"], - "exclude": ["./test/*.test.ts"] + "include": ["./src/**/*"] } diff --git a/packages/sdk-middleware-auth/README.md b/packages/sdk-middleware-auth/README.md deleted file mode 100644 index b7c9a1ba9..000000000 --- a/packages/sdk-middleware-auth/README.md +++ /dev/null @@ -1 +0,0 @@ -# `sdk-middleware-auth` diff --git a/packages/sdk-middleware-auth/jest.config.js b/packages/sdk-middleware-auth/jest.config.js deleted file mode 100644 index 8aef1fc73..000000000 --- a/packages/sdk-middleware-auth/jest.config.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - collectCoverage: true, - coverageDirectory: 'coverage', - testPathIgnorePatterns: [ - "/node_modules/" - ], - verbose: true, - coverageThreshold: { - global: { - // branches: 100, - // lines: 100, - // functions: 100, - statements: 90 - } - }, - globals: { - 'ts-jest': { - diagnostics: false, - } - } -} diff --git a/packages/sdk-middleware-auth/package.json b/packages/sdk-middleware-auth/package.json deleted file mode 100644 index 30b016a68..000000000 --- a/packages/sdk-middleware-auth/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "@commercetools/sdk-middleware-auth", - "version": "3.0.0", - "description": "middleware authentication flows for commercetools platform API, and use with @commercetools/sdk-client", - "keywords": ["commercetools", "middleware", "sdk", "oauth", "auth"], - "author": "Chukwuemeka Ajima ", - "homepage": "https://github.com/commercetools/commercetools-sdk-typescript", - "license": "MIT", - "main": "dist/index.js", - "directories": { - "src": "src", - "test": "test" - }, - "files": ["lib"], - "repository": { - "type": "git", - "url": "git+https://github.com/commercetools/commercetools-sdk-typescript.git" - }, - "bugs": { - "url": "https://github.com/commercetools/commercetools-sdk-typescript/issues" - }, - "dependencies": { - "node-fetch": "^2.3.0" - }, - "devDependencies": { - "@types/jest": "^26.0.23", - "@types/node": "^15.9.0", - "common-tags": "^1.8.0", - "jest": "^27.0.3", - "jest-junit": "^12.1.0", - "nock": "12.0.3", - "rimraf": "^3.0.2", - "ts-jest": "^27.0.2", - "typescript": "^4.3.2" - }, - "scripts": { - "prebuild": "rimraf dist/**", - "build": "rimraf dist && tsc", - "test": "jest" - } -} diff --git a/packages/sdk-middleware-auth/tsconfig.json b/packages/sdk-middleware-auth/tsconfig.json deleted file mode 100644 index 30ee37eef..000000000 --- a/packages/sdk-middleware-auth/tsconfig.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - /* Basic Options */ - // "incremental": true, /* Enable incremental compilation */ - "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */, - "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - // "lib": [], /* Specify library files to be included in the compilation. */ - "allowJs": true /* Allow javascript files to be compiled. */, - // "checkJs": true, /* Report errors in .js files. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "dist" /* Redirect output structure to the directory. */, - "rootDir": "src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - "removeComments": false /* Do not emit comments to output. */, - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */, - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ - /* Module Resolution Options */ - "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, - "baseUrl": "." /* Base directory to resolve non-absolute module names. */, - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - /* Advanced Options */ - "skipLibCheck": true /* Skip type checking of declaration files. */, - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ - }, - "include": ["./src/**/*"], - "exclude": ["./test/*.test.ts"] -} diff --git a/packages/sdk-middleware-http/README.md b/packages/sdk-middleware-http/README.md deleted file mode 100644 index 372fbc610..000000000 --- a/packages/sdk-middleware-http/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# `sdk-middleware-http` - -> TODO: description - -## Usage - -``` -const sdkMiddlewareHttp = require('sdk-middleware-http'); - -// TODO: DEMONSTRATE API -``` diff --git a/packages/sdk-middleware-http/jest.config.js b/packages/sdk-middleware-http/jest.config.js deleted file mode 100644 index db70b5005..000000000 --- a/packages/sdk-middleware-http/jest.config.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - collectCoverage: true, - coverageDirectory: 'coverage', - testPathIgnorePatterns: [ - "/node_modules/" - ], - verbose: true, - coverageThreshold: { - global: { - // branches: 85, - // lines: 85, - // functions: 85, - statements: 90 - } - }, - globals: { - 'ts-jest': { - diagnostics: false, - } - } -} diff --git a/packages/sdk-middleware-http/package.json b/packages/sdk-middleware-http/package.json deleted file mode 100644 index cc34416d8..000000000 --- a/packages/sdk-middleware-http/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@commercetools/sdk-middleware-http", - "version": "3.0.0", - "description": "middleware for http requests, to use with @commercetools/sdk-client", - "keywords": [ - "commercetools", - "sdk", - "middleware", - "http" - ], - "author": "Chukwuemeka Ajima ", - "homepage": "https://github.com/commercetools/commercetools-sdk-typescript", - "license": "MIT", - "main": "dist/index.js", - "directories": { - "lib": "lib", - "test": "__tests__" - }, - "files": [ - "lib" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/commercetools/commercetools-sdk-typescript.git" - }, - "bugs": { - "url": "https://github.com/commercetools/commercetools-sdk-typescript/issues" - }, - "dependencies": { - "node-fetch": "^2.6.1" - }, - "devDependencies": { - "@types/jest": "^26.0.23", - "@types/node": "^15.9.0", - "abort-controller": "3.0.0", - "common-tags": "^1.8.0", - "jest": "^27.0.3", - "jest-junit": "^12.1.0", - "nock": "12.0.3", - "rimraf": "^3.0.2", - "ts-jest": "^27.0.2", - "typescript": "^4.3.2" - }, - "scripts": { - "prebuild": "rimraf dist/**", - "build": "rimraf dist && tsc", - "test": "jest" - } -} diff --git a/packages/sdk-middleware-http/src/index.ts b/packages/sdk-middleware-http/src/index.ts deleted file mode 100644 index f97bb838c..000000000 --- a/packages/sdk-middleware-http/src/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { default as createHttpMiddleware } from './http' -export { default as getErrorByCode } from './errors' -export * as errors from './errors' diff --git a/packages/sdk-middleware-http/tsconfig.json b/packages/sdk-middleware-http/tsconfig.json deleted file mode 100644 index 4efe8f489..000000000 --- a/packages/sdk-middleware-http/tsconfig.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - /* Basic Options */ - // "incremental": true, /* Enable incremental compilation */ - "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */, - "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - // "lib": [], /* Specify library files to be included in the compilation. */ - "allowJs": true /* Allow javascript files to be compiled. */, - // "checkJs": true, /* Report errors in .js files. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "dist" /* Redirect output structure to the directory. */, - "rootDir": "src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - "removeComments": false /* Do not emit comments to output. */, - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */, - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ - /* Module Resolution Options */ - "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, - "baseUrl": "." /* Base directory to resolve non-absolute module names. */, - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - /* Advanced Options */ - "skipLibCheck": true /* Skip type checking of declaration files. */, - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ - }, - "include": ["./src/**/*"], - "exclude": ["./test/*.test.ts"] -}