From 0100eed82ddad56a00d40893d3034550fb910d3f Mon Sep 17 00:00:00 2001 From: nKOxxx Date: Wed, 4 Mar 2026 18:22:23 +0400 Subject: [PATCH 1/2] chore: setup prettier for consistent code formatting - Add prettier.config.js with sensible defaults - Add .prettierignore to exclude build artifacts - Add npm scripts: format and format:check - Add prettier@^3.2.0 to devDependencies Closes #11 --- .prettierignore | 23 +++++++++++++++++++++++ package.json | 3 +++ prettier.config.js | 17 +++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 .prettierignore create mode 100644 prettier.config.js diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..2641e9a --- /dev/null +++ b/.prettierignore @@ -0,0 +1,23 @@ +# Dependencies +node_modules/ + +# Build output +dist/ + +# Coverage +coverage/ + +# Logs +*.log + +# Environment variables +.env +.env.local + +# IDE +.vscode/ +.idea/ + +# OS files +.DS_Store +Thumbs.db diff --git a/package.json b/package.json index 72314de..44632c9 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ "scripts": { "build": "tsc", "lint": "eslint src", + "format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"", + "format:check": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"", "test": "vitest run", "test:unit": "vitest run tests/unit", "test:e2e": "vitest run tests/e2e", @@ -41,6 +43,7 @@ "eslint": "^9.39.2", "eslint-plugin-import": "^2.32.0", "nock": "^13.4.0", + "prettier": "^3.2.0", "typedoc": "^0.28.14", "typedoc-plugin-markdown": "^4.9.0", "typescript": "^5.3.2", diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 0000000..acb82fb --- /dev/null +++ b/prettier.config.js @@ -0,0 +1,17 @@ +/** + * @see https://prettier.io/docs/en/configuration + * @type {import("prettier").Config} + */ +const config = { + semi: true, + trailingComma: 'es5', + singleQuote: true, + printWidth: 100, + tabWidth: 2, + useTabs: false, + bracketSpacing: true, + arrowParens: 'avoid', + endOfLine: 'lf', +}; + +export default config; From 4a34ee5dd651bc44ddea198e3084e63fffa47ffc Mon Sep 17 00:00:00 2001 From: nKOxxx Date: Wed, 4 Mar 2026 18:25:45 +0400 Subject: [PATCH 2/2] refactor(tests): migrate auth tests from JS to TypeScript - Convert auth.test.js to auth.test.ts - Add proper TypeScript types for Base44Client, nock.Scope - Add type annotations for mock objects - Use @ts-expect-error for intentional window deletion in tests - Maintain all existing test coverage and functionality Part of #13 - migrating tests to TypeScript --- tests/unit/{auth.test.js => auth.test.ts} | 43 ++++++++++++----------- 1 file changed, 22 insertions(+), 21 deletions(-) rename tests/unit/{auth.test.js => auth.test.ts} (94%) diff --git a/tests/unit/auth.test.js b/tests/unit/auth.test.ts similarity index 94% rename from tests/unit/auth.test.js rename to tests/unit/auth.test.ts index 81aa9aa..2eeb13e 100644 --- a/tests/unit/auth.test.js +++ b/tests/unit/auth.test.ts @@ -1,10 +1,10 @@ import { describe, test, expect, beforeEach, afterEach, vi } from 'vitest'; import nock from 'nock'; -import { createClient } from '../../src/index.ts'; +import { createClient, Base44Client } from '../../src/index.ts'; describe('Auth Module', () => { - let base44; - let scope; + let base44: Base44Client; + let scope: nock.Scope; const appId = 'test-app-id'; const serverUrl = 'https://api.base44.com'; const appBaseUrl = 'https://api.base44.com'; @@ -13,15 +13,15 @@ describe('Auth Module', () => { // Mock window.addEventListener and document for analytics module if (typeof window !== 'undefined') { if (!window.addEventListener) { - window.addEventListener = vi.fn(); - window.removeEventListener = vi.fn(); + window.addEventListener = vi.fn() as unknown as typeof window.addEventListener; + window.removeEventListener = vi.fn() as unknown as typeof window.removeEventListener; } } if (typeof document === 'undefined') { global.document = { referrer: '', visibilityState: 'visible' - }; + } as Document; } // Create a new client for each test @@ -36,7 +36,7 @@ describe('Auth Module', () => { // Enable request debugging for Nock nock.disableNetConnect(); - nock.emitter.on('no match', (req) => { + nock.emitter.on('no match', (req: nock.Req) => { console.log(`Nock: No match for ${req.method} ${req.path}`); console.log('Headers:', req.getHeaders()); }); @@ -142,6 +142,7 @@ describe('Auth Module', () => { test('should throw error when not in browser environment', () => { // Mock window as undefined to simulate non-browser environment const originalWindow = global.window; + // @ts-expect-error - Intentionally deleting window for test delete global.window; expect(() => { @@ -158,7 +159,7 @@ describe('Auth Module', () => { const originalWindow = global.window; global.window = { location: mockLocation - }; + } as unknown as Window & typeof globalThis; const nextUrl = 'https://example.com/dashboard'; base44.auth.redirectToLogin(nextUrl); @@ -179,7 +180,7 @@ describe('Auth Module', () => { const originalWindow = global.window; global.window = { location: mockLocation - }; + } as unknown as Window & typeof globalThis; base44.auth.redirectToLogin(); @@ -205,7 +206,7 @@ describe('Auth Module', () => { const mockLocation = { href: '' }; global.window = { location: mockLocation - }; + } as unknown as Window & typeof globalThis; const nextUrl = 'https://example.com/dashboard'; clientWithCustomUrl.auth.redirectToLogin(nextUrl); @@ -231,7 +232,7 @@ describe('Auth Module', () => { const mockLocation = { href: '', origin: 'https://current-app.com' }; global.window = { location: mockLocation - }; + } as unknown as Window & typeof globalThis; const nextUrl = 'https://example.com/dashboard'; clientWithoutAppBaseUrl.auth.redirectToLogin(nextUrl); @@ -265,7 +266,7 @@ describe('Auth Module', () => { // Mock another me() call to verify no Authorization header is sent scope.get(`/api/apps/${appId}/entities/User/me`) - .matchHeader('Authorization', (val) => !val) // Should not have Authorization header + .matchHeader('Authorization', (val: string | undefined) => !val) // Should not have Authorization header .reply(401, { detail: 'Unauthorized' }); // Verify no Authorization header is sent after logout (should throw 401) @@ -287,7 +288,7 @@ describe('Auth Module', () => { location: { reload: vi.fn() } - }; + } as unknown as Window & typeof globalThis; // Set a token to localStorage first base44.auth.setToken('test-token', true); @@ -318,7 +319,7 @@ describe('Auth Module', () => { location: { reload: vi.fn() } - }; + } as unknown as Window & typeof globalThis; // Call logout - should not throw base44.auth.logout(); @@ -337,7 +338,7 @@ describe('Auth Module', () => { const originalWindow = global.window; global.window = { location: mockLocation - }; + } as unknown as Window & typeof globalThis; const redirectUrl = 'https://example.com/logout-success'; base44.auth.logout(redirectUrl); @@ -356,7 +357,7 @@ describe('Auth Module', () => { const originalWindow = global.window; global.window = { location: mockLocation - }; + } as unknown as Window & typeof globalThis; // Call logout without redirect URL base44.auth.logout(); @@ -397,7 +398,7 @@ describe('Auth Module', () => { const originalWindow = global.window; global.window = { localStorage: mockLocalStorage - }; + } as unknown as Window & typeof globalThis; const token = 'test-access-token'; base44.auth.setToken(token, true); @@ -420,7 +421,7 @@ describe('Auth Module', () => { const originalWindow = global.window; global.window = { localStorage: mockLocalStorage - }; + } as unknown as Window & typeof globalThis; const token = 'test-access-token'; base44.auth.setToken(token, false); @@ -437,7 +438,7 @@ describe('Auth Module', () => { // Mock the API response for me() call scope.get(`/api/apps/${appId}/entities/User/me`) - .matchHeader('Authorization', (val) => !val) // Should not have Authorization header + .matchHeader('Authorization', (val: string | undefined) => !val) // Should not have Authorization header .reply(401, { detail: 'Unauthorized' }); // Verify no Authorization header is sent (should throw 401) @@ -456,7 +457,7 @@ describe('Auth Module', () => { const originalWindow = global.window; global.window = { localStorage: mockLocalStorage - }; + } as unknown as Window & typeof globalThis; const token = 'test-access-token'; base44.auth.setToken(token, true); @@ -643,4 +644,4 @@ describe('Auth Module', () => { expect(scope.isDone()).toBe(true); }); }); -}); \ No newline at end of file +});