liferay-headless-sdk
v1.0.8
Published
A production-ready JavaScript SDK dynamically generated from Liferay Headless API Swagger/OpenAPI specifications.
Maintainers
Readme
Liferay Headless SDK
A JavaScript SDK that dynamically generates API client methods from Liferay's OpenAPI specifications at runtime.
Zero manual mapping required — point it at a Liferay instance and call APIs immediately.
Table of Contents
- Installation
- Quick Start
- Configuration
- Authentication
- Dynamic Method Usage
- Pagination
- Interceptors
- Error Handling
- CLI Tool
- TypeScript
- Advanced Usage
- File Structure
Installation
npm install liferay-headless-sdkNode.js 18+ required (uses native fetch and ESM).
Quick Start
import { LiferayHeadlessClient } from 'liferay-headless-sdk';
const client = new LiferayHeadlessClient({
baseUrl: 'https://your-liferay.com',
swaggerUrls: ['/o/headless-delivery/v1.0/openapi.json', '/o/headless-admin-user/v1.0/openapi.json'],
username: '[email protected]',
password: 'test',
});
await client.init();
const { data } = await client.headlessAdminUser.site.getMyUserAccountSitesPage();
console.log(data.items);Configuration
const client = new LiferayHeadlessClient({
baseUrl: 'https://your-liferay.com',
swaggerUrls: ['/o/headless-delivery/v1.0/openapi.json', '/o/headless-admin-user/v1.0/openapi.json'],
operationIds: [], // optional filter
tags: [], // optional filter
username: '[email protected]',
password: 'test',
timeout: 30000,
retries: 2,
autoGenerate: true, // Proxy-based lazy init
});Authentication
Basic Auth
const client = new LiferayHeadlessClient({
baseUrl: '...',
username: '[email protected]',
password: 'test',
});OAuth2 Bearer Token
const client = new LiferayHeadlessClient({
baseUrl: '...',
clientId: 'id-cbc930e2-3766-4ea2-24bd-6887b5fc112',
clientSecret: 'secret-95f02f64-1033-5ad2-7066-2c393bdd',
});Switch Authentication at Runtime
client.setBasicAuth('username', 'password');
client.setClientCredentials('clientId', 'clientSecret');
client.clearAuth();Dynamic Method Usage
After initialization:
await client.init();Access APIs:
// GET /v1.0/sites/{siteId}
const { data } = await client.headlessAdminUser.site.getSite({ siteId: 12345 });
// GET /v1.0/structured-contents/{structuredContentId}
const { data: content } = await client.headlessDelivery.structuredContent.getStructuredContent({
structuredContentId: 123,
});
// POST /v1.0/sites/{siteId}/structured-contents
await client.headlessDelivery.structuredContent.postSiteStructuredContent({
siteId: 1,
body: {
title: 'My Article',
},
});Parameter Mapping
| Type | Example |
| ----------- | -------------------- |
| Path param | { siteId: 123 } |
| Query param | { page: 1 } |
| Body | { body: {...} } |
| Headers | { headers: {...} } |
Pagination
Iterate lazily
import { iteratePages } from 'liferay-headless-sdk';
for await (const item of iteratePages(client.headlessAdminUser.site.getMyUserAccountSitesPage, { pageSize: 50 })) {
console.log(item);
}Collect all
import { collectAllPages } from 'liferay-headless-sdk';
const all = await collectAllPages(client.headlessAdminUser.site.getMyUserAccountSitesPage, { pageSize: 100 });Interceptors
Request Interceptor
client.addRequestInterceptor((config) => {
console.log('→', config.method, config.path);
return config;
});Response Interceptor
client.addResponseInterceptor((response) => {
console.log('←', response.status);
return response;
});Add headers dynamically
client.addRequestInterceptor((config) => ({
...config,
headers: {
...config.headers,
'X-Request-ID': crypto.randomUUID(),
},
}));Error Handling
import { LiferayAPIError, LiferayNetworkError, LiferayTimeoutError } from 'liferay-headless-sdk';
try {
await client.headlessAdminUser.site.getMyUserAccountSitesPage();
} catch (err) {
if (err instanceof LiferayAPIError) {
console.log(err.statusCode);
console.log(err.responseBody);
}
if (err instanceof LiferayTimeoutError) {
console.log(err.timeoutMs);
}
if (err instanceof LiferayNetworkError) {
console.log(err.cause);
}
}Behavior
- 4xx errors → not retried
- 5xx + network errors → retried with exponential backoff
- timeouts → wrapped in
LiferayTimeoutError
CLI Tool
npx liferay-sdk-cli generate \
--baseUrl https://your-liferay.com \
--output ./generated-sdk \
--username [email protected] \
--password testOptions
| Flag | Description |
| ------------ | ------------------------ |
| --baseUrl | Liferay instance URL |
| --output | Output directory |
| --swagger | Custom OpenAPI endpoints |
| --username | Basic auth username |
| --password | Basic auth password |
| --token | OAuth token |
TypeScript
import { LiferayHeadlessClient } from 'liferay-headless-sdk';
const client = new LiferayHeadlessClient({
baseUrl: 'https://your-liferay.com',
username: '[email protected]',
password: 'test',
});Dynamic access:
const ns = client['headlessDelivery'];
const result = await ns['structuredContent']['getStructuredContents']();Advanced Usage
Load schema on demand
await client.loadSchema('/o/headless-delivery/v1.0/openapi.json');Raw HTTP access
const { data } = await client.request({
method: 'GET',
path: '/o/headless-delivery/v1.0/sites',
});Cache reset
client.clearSchemaCache();
await client.init();File Structure
src/
├── client.js
├── http.js
├── auth.js
├── swagger-loader.js
├── api-generator.js
├── pagination.js
├── errors.js
├── utils.js
├── cli.jsLicense
MIT
