Skip to content
Open
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
23 changes: 23 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
17 changes: 17 additions & 0 deletions prettier.config.js
Original file line number Diff line number Diff line change
@@ -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;
43 changes: 22 additions & 21 deletions tests/unit/auth.test.js → tests/unit/auth.test.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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
Expand All @@ -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());
});
Expand Down Expand Up @@ -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(() => {
Expand All @@ -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);
Expand All @@ -179,7 +180,7 @@ describe('Auth Module', () => {
const originalWindow = global.window;
global.window = {
location: mockLocation
};
} as unknown as Window & typeof globalThis;

base44.auth.redirectToLogin();

Expand All @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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)
Expand All @@ -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);
Expand Down Expand Up @@ -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();
Expand All @@ -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);
Expand All @@ -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();
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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)
Expand All @@ -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);
Expand Down Expand Up @@ -643,4 +644,4 @@ describe('Auth Module', () => {
expect(scope.isDone()).toBe(true);
});
});
});
});