Project Structure
Running npm create @ci-hub/integration my-integration scaffolds:
index.ts
All integration logic lives in index.ts. The file contains defineIntegration, every handler, and all helper functions.
Split only for long static data (see below).
When to split
You might need to split your code into multiple files if you have a lot of static data like GraphQL queries, predefined renditions, or predefined filters.
| File | When to extract |
|---|---|
integration-types.ts | Shared type config for defineIntegration, auth helpers, and dah.ts. See Typed Integrations. |
dah.ts | Direct Access Helper for browser-side upload. See Direct Access Helper. |
dah-utils.ts | Shared helpers imported by both dah.ts and index.ts (browser-safe code only). |
queries.ts | Long GraphQL query strings. if your API uses GraphQL. |
renditions.ts | Static rendition/conversion lists (predefined sizes, aspect ratios). |
*.ect | Login screen templates (ECT format). See Login Templates. |
queries.ts and renditions.ts are just examples, if needed you can create any file you need to store your static data.
cihub.config.jsonc
The CLI configuration file that controls how source files, templates, and assets are discovered and bundled. Run integration-cli config --init to generate a starter file (see CLI reference for your package manager). See the CLI reference for all available fields and defaults.
config.json
Integration-specific configuration. Keys are accessed via config.get('integrationName.key').
{
"serverBaseUrl": "http://localhost:8080",
"IntegrationName": {
"contact": {
"text": "Support description",
"url": { "link": "https://your-platform.example.com/help", "email": "support@example.com" }
},
"authEndpoint": "/api/oauth/authorize",
"tokenEndpoint": "/api/oauth/accesstoken",
"clientId": "your-client-id",
"maxQuerySize": 100
}
}import { config } from '@ci-hub/integration-sdk'
const apiUrl = config.get('IntegrationName.apiUrl')
const limit = config.has('IntegrationName.uploadLimitMB')
? config.get<number>('IntegrationName.uploadLimitMB')
: 500Logo and glyph
Images are inlined as base64 data URLs. Place logo.png (600×134) and glyph.png (80×80) next to the index.ts file.
import { fs, path } from '@ci-hub/integration-sdk'
const imageBase64 = (name: string) =>
`data:image/png;base64,${Buffer.from(
fs.readFileSync(path.join(import.meta.dirname, name))
).toString('base64')}`
const logo = { data: imageBase64('logo.png'), width: 600, height: 134, backgroundColor: '#FFFFFF' }
const glyph = { data: imageBase64('glyph.png'), width: 80, height: 80, backgroundColor: '#FFFFFF' }| Field | Description |
|---|---|
data | Base64-encoded PNG as a data URI |
width / height | Pixel dimensions of the source image |
backgroundColor | Hex color — used when the image has a transparent background |
Use PNG format. Keep logos under 100 KB. The backgroundColor field matters for dark mode rendering in CI HUB.