Skip to content

Commit 92f11cd

Browse files
Merge branch 'master' into DEVORTEX-5439
2 parents d69eb4f + e9180d3 commit 92f11cd

35 files changed

+1260
-1057
lines changed

.eslintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@
6969
"react/jsx-indent-props": ["error", 4],
7070
"react/no-unescaped-entities": "off",
7171
"react/prefer-stateless-function": "off",
72-
"react/require-default-props": "off"
72+
"react/require-default-props": "off",
73+
"flowtype/no-types-missing-file-annotation": "off"
7374
},
7475
env: {
7576
browser: true,

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v18.20.8

CLAUDE.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Overview
6+
7+
This is the Smartling Translation API SDK for Node.js, providing TypeScript interfaces for interacting with Smartling's translation services. The SDK covers all major API endpoints including files, jobs, locales, projects, and translation management.
8+
9+
## Commands
10+
11+
### Build Commands
12+
- `npm run build` - Production build (TypeScript compilation to `built/` directory)
13+
- `npm run build:dev` - Development build (includes test files)
14+
15+
### Testing
16+
- `npm test` - Run full test suite with lint, build, and coverage
17+
- `npm run test:dev` - Run tests without JUnit reporting (for development)
18+
19+
### Linting
20+
- `npm run pretest` - Run ESLint on all TypeScript files
21+
- ESLint configuration in `.eslintrc` with TypeScript, Airbnb, and custom rules
22+
23+
### Single Test Execution
24+
Run individual test files using Mocha directly:
25+
```bash
26+
npm run build:dev && npx mocha built/test/[specific-test].spec.js
27+
```
28+
29+
## Architecture
30+
31+
### Core Structure
32+
- **API Layer**: Organized by feature domains (`/api/`)
33+
- `auth/` - Authentication and token management
34+
- `files/` - File upload/download operations
35+
- `jobs/` - Translation job management
36+
- `locales/` - Language and locale handling
37+
- `projects/` - Project management
38+
- `strings/` - String resource management
39+
- `context/` - Context matching for translations
40+
- `job-batches/` - Batch job processing
41+
- `published-files/` - Published file management
42+
- `file-translations/` - File translation services
43+
- `mt/` - Machine translation services
44+
45+
### Pattern Structure
46+
Each API domain follows a consistent pattern:
47+
- `index.ts` - Main API client class
48+
- `dto/` - Data transfer objects (response/request types)
49+
- `params/` - Parameter classes for API calls
50+
51+
### Key Components
52+
- **SmartlingApiClientBuilder**: Main entry point for creating API clients
53+
- **AccessTokenProvider**: Interface for authentication (with StaticAccessTokenProvider implementation)
54+
- **SmartlingListResponse**: Generic wrapper for paginated API responses
55+
- **Logger**: Centralized logging utility
56+
57+
### TypeScript Configuration
58+
- Uses `tsconfig.json` for production builds
59+
- Uses `tsconfig.dev.json` for development (includes test files)
60+
- Targets ES6 with CommonJS modules
61+
- Generates declaration files and source maps
62+
63+
### Testing Framework
64+
- Mocha test runner with TypeScript support
65+
- Sinon for mocking and stubbing
66+
- NYC for code coverage reporting
67+
- Tests located in `/test/` directory matching API structure

api/auth/access-token-provider.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface AccessTokenProvider {
2+
getAccessToken(): Promise<string>;
3+
getTokenType(): Promise<string>;
4+
resetToken(): void;
5+
}

api/auth/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { SmartlingBaseApi } from "../base/index";
22
import { SmartlingException } from "../exception/index";
33
import { Logger } from "../logger";
4+
import { AccessTokenProvider } from "./access-token-provider";
45
import { AccessTokenDto } from "./dto/access-token-dto";
56

6-
export class SmartlingAuthApi extends SmartlingBaseApi {
7+
export class SmartlingAuthApi extends SmartlingBaseApi implements AccessTokenProvider {
78
private ttlCorrectionSec: number;
89
private userIdentifier: string;
910
private tokenSecret: string;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { AccessTokenProvider } from "./access-token-provider";
2+
3+
export class StaticAccessTokenProvider implements AccessTokenProvider {
4+
private accessToken: string;
5+
private tokenType: string;
6+
7+
constructor(
8+
accessToken: string,
9+
tokenType: string
10+
) {
11+
this.accessToken = accessToken;
12+
this.tokenType = tokenType;
13+
}
14+
15+
async getAccessToken(): Promise<string> {
16+
return this.accessToken;
17+
}
18+
19+
async getTokenType(): Promise<string> {
20+
return this.tokenType;
21+
}
22+
23+
resetToken(): void {
24+
this.accessToken = null;
25+
this.tokenType = null;
26+
}
27+
}

api/base/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import fetch from "cross-fetch";
55
import { ParsedUrlQueryInput, stringify } from "querystring";
66
import { Logger } from "../logger";
77
import { SmartlingException } from "../exception/index";
8-
import { SmartlingAuthApi } from "../auth/index";
8+
import { AccessTokenProvider } from "../auth/access-token-provider";
99
import { ResponseBodyType } from "./enum/response-body-type";
1010

1111
/* eslint-disable-next-line @typescript-eslint/no-var-requires */
1212
const packageJson = require("../../package.json");
1313

1414
export class SmartlingBaseApi {
15-
protected authApi: SmartlingAuthApi = undefined;
15+
protected authApi: AccessTokenProvider = undefined;
1616
protected entrypoint: string;
1717
protected defaultClientLibId: string;
1818
protected defaultClientVersion: string;

api/builder/index.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { AccessTokenProvider } from "../auth/access-token-provider";
12
import { SmartlingAuthApi } from "../auth/index";
23
import { SmartlingBaseApi } from "../base/index";
34
import { Logger } from "../logger";
@@ -6,7 +7,7 @@ import { Logger } from "../logger";
67
const packageJson = require("../../package.json");
78

89
export class SmartlingApiClientBuilder {
9-
protected authApiClient: SmartlingAuthApi = null;
10+
protected authApiClient: AccessTokenProvider = null;
1011
protected userId: string = null;
1112
protected userSecret: string = null;
1213
protected baseSmartlingApiUrl: string;
@@ -60,14 +61,14 @@ export class SmartlingApiClientBuilder {
6061
return this;
6162
}
6263

63-
public authWithAuthApiClient(authApiClient: SmartlingAuthApi): SmartlingApiClientBuilder {
64+
public authWithAuthApiClient(authApiClient: AccessTokenProvider): SmartlingApiClientBuilder {
6465
this.authApiClient = authApiClient;
6566

6667
return this;
6768
}
6869

6970
public build<T extends SmartlingBaseApi>(
70-
constructor: new (baseUrl: string, authApi: SmartlingAuthApi, logger) => T
71+
constructor: new (baseUrl: string, authApi: AccessTokenProvider, logger) => T
7172
): T {
7273
if (this.authApiClient === null && this.userId !== null && this.userSecret !== null) {
7374
this.authApiClient = new SmartlingAuthApi(
@@ -77,9 +78,11 @@ export class SmartlingApiClientBuilder {
7778
this.logger
7879
);
7980

80-
this.authApiClient.setClientLibId(this.clientLibId);
81-
this.authApiClient.setClientLibVersion(this.clientLibVersion);
82-
this.authApiClient.setOptions(this.httpClientOptions);
81+
if (this.authApiClient instanceof SmartlingAuthApi) {
82+
this.authApiClient.setClientLibVersion(this.clientLibVersion);
83+
this.authApiClient.setClientLibId(this.clientLibId);
84+
this.authApiClient.setOptions(this.httpClientOptions);
85+
}
8386
}
8487

8588
const instance = new constructor(this.baseSmartlingApiUrl, this.authApiClient, this.logger);

api/context/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import string2fileStream from "string-to-file-stream";
22
import FormData from "form-data";
33
import { SmartlingBaseApi } from "../base/index";
4-
import { SmartlingAuthApi } from "../auth/index";
4+
import { AccessTokenProvider } from "../auth/access-token-provider";
55
import { ContextUploadParameters } from "./params/context-upload-parameters";
66
import { ContextDto } from "./dto/context-dto";
77
import { ContextAutomaticMatchParameters } from "./params/context-automatic-match-parameters";
@@ -13,7 +13,7 @@ import { ListParameters } from "./params/list-parameters";
1313
import { Logger } from "../logger";
1414

1515
export class SmartlingContextApi extends SmartlingBaseApi {
16-
constructor(smartlingApiBaseUrl: string, authApi: SmartlingAuthApi, logger: Logger) {
16+
constructor(smartlingApiBaseUrl: string, authApi: AccessTokenProvider, logger: Logger) {
1717
super(logger);
1818

1919
this.authApi = authApi;

api/file-translations/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import FormData from "form-data";
22
import { SmartlingBaseApi } from "../base";
3-
import { SmartlingAuthApi } from "../auth";
3+
import { AccessTokenProvider } from "../auth/access-token-provider";
44
import { Logger } from "../logger";
55
import { FtsUploadedFileDto } from "./dto/fts-uploaded-file-dto";
66
import { FtsUploadFileParameters } from "./params/fts-upload-file-parameters";
@@ -14,7 +14,7 @@ import { ResponseBodyType } from "../base/enum/response-body-type";
1414
import { LanguageDetectionParameters } from "./params/language-detection-parameters";
1515

1616
export class SmartlingFileTranslationsApi extends SmartlingBaseApi {
17-
constructor(smartlingApiBaseUrl: string, authApi: SmartlingAuthApi, logger: Logger) {
17+
constructor(smartlingApiBaseUrl: string, authApi: AccessTokenProvider, logger: Logger) {
1818
super(logger);
1919
this.authApi = authApi;
2020
this.entrypoint = `${smartlingApiBaseUrl}/file-translations-api/v2/accounts`;

0 commit comments

Comments
 (0)