
Security News
pnpm 11.5 Adds Support for Recognizing npm Staged Publishes
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.
@felixgeelhaar/sdk-core
Advanced tools
Shared core for Atlassian Cloud API SDKs - auth, transport, errors, and common types
Shared infrastructure for Atlassian Cloud API SDKs - authentication, HTTP transport, errors, middleware, and resilience patterns.
This package provides the foundational building blocks for creating type-safe, resilient API clients:
npm install @felixgeelhaar/sdk-core
# or
pnpm add @felixgeelhaar/sdk-core
import { createApiTokenAuth } from '@felixgeelhaar/sdk-core';
const auth = createApiTokenAuth({
email: 'your-email@example.com',
apiToken: 'your-api-token',
});
import { createPatAuth } from '@felixgeelhaar/sdk-core';
const auth = createPatAuth({
token: 'your-personal-access-token',
});
import { createBasicAuth } from '@felixgeelhaar/sdk-core';
const auth = createBasicAuth({
username: 'your-username',
password: 'your-password',
});
import { createOAuth2Auth } from '@felixgeelhaar/sdk-core';
const auth = createOAuth2Auth({
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
accessToken: 'current-access-token',
refreshToken: 'refresh-token',
expiresAt: Date.now() + 3600000,
});
// Automatic token refresh with persistence callback
auth.onTokenRefresh = async (tokens) => {
await saveTokensToDatabase(tokens);
};
import { HttpClient, createApiTokenAuth } from '@felixgeelhaar/sdk-core';
const client = new HttpClient({
baseUrl: 'https://your-domain.atlassian.net',
auth: createApiTokenAuth({ email: '...', apiToken: '...' }),
timeout: 30000,
});
// Make requests
const response = await client.get('/rest/api/3/myself');
const created = await client.post('/rest/api/3/issue', { fields: { ... } });
The HTTP client supports a middleware pipeline for cross-cutting concerns:
import {
HttpClient,
createLoggingMiddleware,
createRetryMiddleware,
createRateLimitMiddleware,
createRequestIdMiddleware,
createUserAgentMiddleware,
ConsoleLogger,
} from '@felixgeelhaar/sdk-core';
const logger = new ConsoleLogger('debug');
const client = new HttpClient({
baseUrl: 'https://api.example.com',
middleware: [
createLoggingMiddleware(logger),
createRequestIdMiddleware(),
createUserAgentMiddleware('MyApp/1.0'),
createRetryMiddleware({
maxRetries: 3,
initialDelayMs: 1000,
maxDelayMs: 30000,
multiplier: 2,
jitter: true,
}),
createRateLimitMiddleware({
maxRequests: 100,
windowMs: 60000,
waitForSlot: true,
}),
],
});
import type { Middleware } from '@felixgeelhaar/sdk-core';
const customMiddleware: Middleware = async (context, next) => {
// Pre-request processing
console.log('Request:', context.request.url);
const response = await next(context);
// Post-response processing
console.log('Response:', response.status);
return response;
};
client.use(customMiddleware);
import { composeMiddleware } from '@felixgeelhaar/sdk-core';
const combined = composeMiddleware(
loggingMiddleware,
retryMiddleware,
rateLimitMiddleware
);
const client = new HttpClient({
baseUrl: 'https://api.example.com',
middleware: [combined],
});
Implement fail-fast behavior for cascading failure prevention:
import {
CircuitBreaker,
createCircuitBreakerMiddleware,
CircuitState,
} from '@felixgeelhaar/sdk-core';
const circuitBreaker = new CircuitBreaker({
failureThreshold: 5, // Open after 5 failures
resetTimeoutMs: 30000, // Try again after 30 seconds
failureWindowMs: 60000, // Count failures within 60 seconds
successThreshold: 1, // Close after 1 success in half-open
});
const client = new HttpClient({
baseUrl: 'https://api.example.com',
middleware: [createCircuitBreakerMiddleware(circuitBreaker)],
});
// Monitor circuit state
console.log(circuitBreaker.getStats());
// { state: 'CLOSED', failures: 0, successes: 5, ... }
// Check state
if (circuitBreaker.getState() === CircuitState.OPEN) {
console.log('Circuit is open - requests will fail fast');
}
The package provides a hierarchical error system:
import {
ApiError,
UnauthorizedError,
ForbiddenError,
NotFoundError,
RateLimitError,
ServerError,
NetworkError,
TimeoutError,
AbortError,
ValidationError,
CircuitBreakerOpenError,
} from '@felixgeelhaar/sdk-core';
try {
await client.get('/resource');
} catch (error) {
if (error instanceof NotFoundError) {
// 404 - Resource doesn't exist
} else if (error instanceof UnauthorizedError) {
// 401 - Invalid or expired credentials
} else if (error instanceof ForbiddenError) {
// 403 - Insufficient permissions
} else if (error instanceof RateLimitError) {
// 429 - Rate limit exceeded
console.log(`Retry after ${error.retryAfter}ms`);
} else if (error instanceof ServerError) {
// 5xx - Server error
} else if (error instanceof TimeoutError) {
// Request timed out
} else if (error instanceof NetworkError) {
// Network connectivity issue
} else if (error instanceof CircuitBreakerOpenError) {
// Circuit breaker is open
} else if (error instanceof ApiError) {
// Other API errors
console.log(error.statusCode, error.responseBody);
}
}
Pluggable logging with multiple implementations:
import { ConsoleLogger, NoopLogger, type Logger } from '@felixgeelhaar/sdk-core';
// Console logger with configurable level
const logger = new ConsoleLogger('info'); // 'debug' | 'info' | 'warn' | 'error'
// Silent logger for tests
const silent = new NoopLogger();
// Custom logger
const customLogger: Logger = {
debug: (message, context) => myLogger.debug(message, context),
info: (message, context) => myLogger.info(message, context),
warn: (message, context) => myLogger.warn(message, context),
error: (message, context) => myLogger.error(message, context),
};
By default, the HTTP client enforces HTTPS in production:
// This will throw in production (NODE_ENV=production)
const client = new HttpClient({
baseUrl: 'http://insecure-api.com', // Error!
});
// Allow HTTP for testing (not recommended for production)
const client = new HttpClient({
baseUrl: 'http://internal-api.local',
allowInsecureHttp: true,
});
// Localhost is always allowed for development
const client = new HttpClient({
baseUrl: 'http://localhost:3000', // OK
});
The OAuth2 provider uses a mutex pattern to prevent concurrent token refresh races:
const auth = createOAuth2Auth({ ... });
// Multiple concurrent requests won't cause multiple refresh calls
await Promise.all([
client.get('/api/resource1'),
client.get('/api/resource2'),
client.get('/api/resource3'),
]);
Import specific modules for better tree-shaking:
// Auth only
import { createApiTokenAuth } from '@felixgeelhaar/sdk-core/auth';
// Transport only
import { HttpClient } from '@felixgeelhaar/sdk-core/transport';
// Errors only
import { ApiError, NotFoundError } from '@felixgeelhaar/sdk-core/errors';
// Schemas only
import { PaginationSchema } from '@felixgeelhaar/sdk-core/schemas';
Full TypeScript support with strict mode enabled:
import type {
AuthProvider,
HttpRequest,
HttpResponse,
Middleware,
MiddlewareContext,
Logger,
LogLevel,
} from '@felixgeelhaar/sdk-core';
| Method | Description |
|---|---|
get(path, params?, options?) | Make a GET request |
post(path, body?, options?) | Make a POST request |
put(path, body?, options?) | Make a PUT request |
patch(path, body?, options?) | Make a PATCH request |
delete(path, options?) | Make a DELETE request |
request(config) | Make a request with full control |
use(middleware) | Add middleware to the chain |
| Method | Description |
|---|---|
execute(fn) | Execute function through circuit breaker |
getState() | Get current state (CLOSED, OPEN, HALF_OPEN) |
getStats() | Get statistics and metrics |
reset() | Reset to closed state |
| Method | Description |
|---|---|
getAuthHeaders() | Get authentication headers |
isValid() | Check if credentials are valid |
refresh() | Refresh credentials (OAuth2 only) |
MIT
FAQs
Shared core for Atlassian Cloud API SDKs - auth, transport, errors, and common types
We found that @felixgeelhaar/sdk-core demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.

Security News
Federal audit finds NIST lacked a plan to clear the NVD backlog, wasted funds on duplicate work, and delayed use of CISA data.

Research
/Security News
A mini Shai-Hulud campaign compromised Red Hat Cloud Services npm packages to steal developer and CI/CD secrets during installation.