Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintignore

This file was deleted.

86 changes: 0 additions & 86 deletions .eslintrc

This file was deleted.

4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ CI (`.github/workflows/node.js.yml`) runs `yarn lint` + `yarn test` on Node 18/2

## Code style

- TypeScript with native **private fields (`#field`)**, ESLint (airbnb + `@typescript-eslint` + prettier), Prettier with single quotes.
- TypeScript with native **private fields (`#field`)**, ESLint **flat config** (`eslint.config.js`: `@eslint/js` recommended + `@typescript-eslint` recommended + `eslint-plugin-import` + `eslint-config-prettier`), Prettier with single quotes.
- Import order is enforced (alphabetized, grouped: react → external → `@mapado/*` → internal). A pre-commit hook (husky + lint-staged) runs Prettier.

## Architecture
Expand All @@ -52,4 +52,4 @@ Entry point `src/index.ts` re-exports everything; `RestClientSdk` is the default
- **`utils/logging`**: optional request/response `Logger`, enabled via `config.loggerEnabled`.

### TypeScript generics
The SDK is parameterized by a metadata type: `new RestClientSdk<TSMetadata>(...)`, where `TSMetadata` is a `Record<key, { entity; list }>`. This is what makes `getRepository(key)` return a correctly-typed repository. Note `typescript@^3.9.6` is pinned (old) — avoid newer TS syntax.
The SDK is parameterized by a metadata type: `new RestClientSdk<TSMetadata>(...)`, where `TSMetadata` is a `Record<key, { entity; list }>`. This is what makes `getRepository(key)` return a correctly-typed repository. The SDK builds on modern TypeScript (`typescript@^6`, `module`/`moduleResolution` set to `esnext`/`bundler`). It is isomorphic (browser + Node): it does **not** pull in `@types/node` — the few Node/V8-only globals it touches (`Error.captureStackTrace`, `require`) are declared as optional in `src/globals.d.ts` and guarded at runtime.
100 changes: 100 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import js from '@eslint/js';
import tseslint from '@typescript-eslint/eslint-plugin';
import tsParser from '@typescript-eslint/parser';
import prettierConfig from 'eslint-config-prettier/flat';
import importPlugin from 'eslint-plugin-import';
import globals from 'globals';

export default [
{
ignores: ['dist/'],
},
js.configs.recommended,
...tseslint.configs['flat/recommended'],
{
files: ['**/*.{js,jsx,ts,tsx}'],
plugins: {
import: importPlugin,
},
languageOptions: {
parser: tsParser,
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
globals: {
...globals.browser,
},
},
settings: {
'import/resolver': {
node: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
},
},
},
rules: {
'import/extensions': [
'error',
'ignorePackages',
{
js: 'never',
ts: 'never',
jsx: 'never',
tsx: 'never',
},
],
// sort imports. see https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md
// TLDR; sorted by : ['react', 'external packages', 'mapado packages', 'internal']
'import/order': [
'error',
{
alphabetize: { order: 'asc' },
pathGroups: [
{
pattern: 'react',
group: 'builtin',
position: 'before',
},
{
pattern: '@mapado/**',
group: 'external',
position: 'after',
},
{
pattern: 'mapado-*',
group: 'external',
position: 'after',
},
],
pathGroupsExcludedImportTypes: ['react'],
},
],

'new-cap': [
'error',
{
newIsCap: true,
capIsNew: false,
},
],
'no-underscore-dangle': [
'error',
{
allowAfterThis: true,
allow: ['_groups'],
},
],
},
},
{
files: ['__tests__/**/*'],
languageOptions: {
globals: {
...globals.jest,
},
},
},
// disable rules that conflict with prettier — must stay last
prettierConfig,
];
21 changes: 9 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"check:src": "npm run test",
"prepublishOnly": "npm run clean && npm run check:src && npm run build",
"lint": "yarn lint:types && yarn lint:eslint",
"lint:eslint": "eslint --ext js,jsx,jsx,ts,tsx src/",
"lint:eslint": "eslint src/",
"lint:types": "tsc --noEmit",
"version": "sed -i \"s/current_version = .*/current_version = $npm_package_version/\" .bumpversion.cfg && git add .bumpversion.cfg"
},
Expand All @@ -38,22 +38,19 @@
"@babel/plugin-proposal-object-rest-spread": "^7.20.7",
"@babel/preset-env": "^7.29.7",
"@babel/preset-typescript": "^7.29.7",
"@eslint/js": "^10.0.1",
"@types/deep-diff": "^1.0.5",
"@types/jest": "^26.0.24",
"@types/urijs": "^1.19.26",
"@typescript-eslint/eslint-plugin": "^3.10.1",
"@typescript-eslint/parser": "^3.10.1",
"@typescript-eslint/eslint-plugin": "^8.62.0",
"@typescript-eslint/parser": "^8.62.0",
"babel-jest": "^25.5.1",
"core-js": "^3.49.0",
"eslint": "^6.8.0",
"eslint-config-airbnb": "^18.1.0",
"eslint-config-prettier": "^6.10.1",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-prettier": "^3.1.2",
"eslint-plugin-react": "^7.19.0",
"eslint-plugin-react-hooks": "^2.5.0 || ^1.7.0",
"eslint": "^10.6.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-import": "^2.32.0",
"fetch-mock": "^9.11.0",
"globals": "^14.0.0",
"husky": "^4.3.8",
"immutable": "^5.1.8",
"jest": "^25.5.4",
Expand All @@ -67,7 +64,7 @@
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
"typescript": "^3.9.10"
"typescript": "^6.0.3"
},
"optionalDependencies": {
"pluralize": "^8.0.0"
Expand Down
1 change: 0 additions & 1 deletion src/ErrorFactory.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable max-classes-per-file, no-use-before-define */
/**
* It's a bit tricky to extends native errors
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
Expand Down
9 changes: 5 additions & 4 deletions src/Mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,17 @@ class Mapping {
const endsWithList = attribute.attributeName.endsWith('List');

try {
// eslint-disable-next-line global-require, import/no-extraneous-dependencies, @typescript-eslint/no-var-requires
const pluralize = require('pluralize');
// eslint-disable-next-line @typescript-eslint/no-require-imports
const pluralize = require('pluralize') as {
isPlural(word: string): boolean;
};
if (
!endsWithList &&
!pluralize.isPlural(attribute.attributeName)
) {
return message;
}
} catch (e) {
} catch {
if (!endsWithList) {
return `${message}.\nIf your keys does not ends with "List", then you should install the "pluralize" package.`;
}
Expand All @@ -105,7 +107,6 @@ class Mapping {

const nbError = errorList.filter((error) => {
if (error) {
// eslint-disable-next-line no-console
console.warn(error);
}

Expand Down
7 changes: 2 additions & 5 deletions src/RestClientSdk.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Mapping from './Mapping';
// eslint-disable-next-line import/no-duplicates

import type RestClientSdkInterface from './RestClientSdkInterface';
// eslint-disable-next-line import/no-duplicates

import type { Config } from './RestClientSdkInterface';
import { Token } from './TokenGenerator/types';
import TokenStorageInterface from './TokenStorageInterface';
Expand All @@ -16,7 +16,6 @@ import { generateRepository } from './utils/repositoryGenerator';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Entity = any;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
// export type SdkMetadata = Record<string, [any, Iterable<any>, undefined | any]>;
export type MetadataDefinition = {
entity: Entity;
Expand Down Expand Up @@ -91,15 +90,13 @@ class RestClientSdk<
);
}

// eslint-disable-next-line new-cap
this.#repositoryList[key] = generateRepository<M[K]>(
this,
metadata,
this.config.unitOfWorkEnabled
);
}

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return this.#repositoryList[key]! as unknown as AbstractClient<M[K]>;
}

Expand Down
1 change: 0 additions & 1 deletion src/TokenGenerator/AuthorizationCodeFlowTokenGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable camelcase */
import AbstractTokenGenerator from './AbstractTokenGenerator';
import { Token, TokenResponse } from './types';

Expand Down
1 change: 0 additions & 1 deletion src/TokenGenerator/ClientCredentialsGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable camelcase */
import { memoizePromise } from '../decorator';
import AbstractTokenGenerator from './AbstractTokenGenerator';
import { Token, TokenResponse } from './types';
Expand Down
1 change: 0 additions & 1 deletion src/TokenGenerator/PasswordGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable camelcase */
import AbstractTokenGenerator from './AbstractTokenGenerator';
import { Token, TokenResponse } from './types';

Expand Down
3 changes: 0 additions & 3 deletions src/TokenGenerator/ProvidedTokenGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable camelcase */
import TokenGeneratorInterface from './TokenGeneratorInterface';
import { Token } from './types';

Expand All @@ -22,12 +21,10 @@ class ProvidedTokenGenerator implements TokenGeneratorInterface<Token> {
this.#token = token;
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
generateToken(): Promise<Token> {
return Promise.resolve(this.#token);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
refreshToken(accessToken: null | Token): Promise<Token> {
if (typeof this.#refreshTokenFunc === 'function') {
return this.#refreshTokenFunc(accessToken);
Expand Down
2 changes: 0 additions & 2 deletions src/TokenGenerator/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/* eslint-disable camelcase */

/**
* See {@link https://tools.ietf.org/html/rfc6749#section-5.1 Successful Response}
*/
Expand Down
5 changes: 2 additions & 3 deletions src/TokenStorage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable camelcase */
import AsyncStorageInterface from './AsyncStorageInterface';
import {
getHttpErrorFromResponse,
Expand All @@ -11,9 +10,9 @@ import TokenGeneratorInterface, {
TokenBodyReturn,
} from './TokenGenerator/TokenGeneratorInterface';
import { ErrorBody, Token, TokenResponse } from './TokenGenerator/types';
// eslint-disable-next-line import/no-duplicates

import type TokenStorageInterface from './TokenStorageInterface';
// eslint-disable-next-line import/no-duplicates

import type { HasExpiresAt } from './TokenStorageInterface';
import { memoizePromise } from './decorator';
import { Logger } from './utils/logging';
Expand Down
1 change: 0 additions & 1 deletion src/TokenStorageInterface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export interface HasExpiresAt {
// eslint-disable-next-line camelcase
expires_at: null | number;
}

Expand Down
Loading