From e2f4fffbe077c02464a5823cf7c084f7cff9ebce Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 08:01:19 +0000 Subject: [PATCH 1/4] Initial plan From 2404f7b2cd7e8f6d9818814f9d22f4b48dc6fd9f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 08:07:45 +0000 Subject: [PATCH 2/4] Add connector protocols with authentication, sync, webhooks, and templates Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- packages/spec/src/system/connector.test.ts | 624 +++++++++++++++++ packages/spec/src/system/connector.zod.ts | 658 ++++++++++++++++++ .../spec/src/system/connector/database.zod.ts | 342 +++++++++ .../src/system/connector/file-storage.zod.ts | 398 +++++++++++ .../src/system/connector/message-queue.zod.ts | 499 +++++++++++++ .../spec/src/system/connector/saas.zod.ts | 253 +++++++ packages/spec/src/system/index.ts | 7 + 7 files changed, 2781 insertions(+) create mode 100644 packages/spec/src/system/connector.test.ts create mode 100644 packages/spec/src/system/connector.zod.ts create mode 100644 packages/spec/src/system/connector/database.zod.ts create mode 100644 packages/spec/src/system/connector/file-storage.zod.ts create mode 100644 packages/spec/src/system/connector/message-queue.zod.ts create mode 100644 packages/spec/src/system/connector/saas.zod.ts diff --git a/packages/spec/src/system/connector.test.ts b/packages/spec/src/system/connector.test.ts new file mode 100644 index 000000000..9886a1320 --- /dev/null +++ b/packages/spec/src/system/connector.test.ts @@ -0,0 +1,624 @@ +import { describe, it, expect } from 'vitest'; +import { + // Authentication Schemas + ApiKeyAuthSchema, + OAuth2AuthSchema, + JwtAuthSchema, + SamlAuthSchema, + BasicAuthSchema, + BearerTokenAuthSchema, + NoAuthSchema, + AuthenticationSchema, + + // Field Mapping + FieldMappingSchema, + FieldTransformSchema, + + // Data Sync + DataSyncConfigSchema, + SyncStrategySchema, + ConflictResolutionSchema, + + // Webhook + WebhookConfigSchema, + WebhookEventSchema, + + // Rate Limiting & Retry + RateLimitConfigSchema, + RetryConfigSchema, + + // Base Connector + ConnectorSchema, + ConnectorTypeSchema, + ConnectorStatusSchema, + + // Types + type Connector, + type ApiKeyAuth, + type OAuth2Auth, + type FieldMapping, + type DataSyncConfig, + type WebhookConfig, +} from './connector.zod'; + +// ============================================================================ +// Authentication Schemas Tests +// ============================================================================ + +describe('ApiKeyAuthSchema', () => { + it('should accept valid API key authentication', () => { + const auth: ApiKeyAuth = { + type: 'api_key', + apiKey: 'test-api-key-12345', + headerName: 'X-API-Key', + }; + + expect(() => ApiKeyAuthSchema.parse(auth)).not.toThrow(); + }); + + it('should accept API key with query parameter', () => { + const auth = { + type: 'api_key', + apiKey: 'test-key', + headerName: 'X-Custom-Key', + paramName: 'api_key', + }; + + const parsed = ApiKeyAuthSchema.parse(auth); + expect(parsed.paramName).toBe('api_key'); + }); + + it('should use default header name', () => { + const auth = { + type: 'api_key', + apiKey: 'test-key', + }; + + const parsed = ApiKeyAuthSchema.parse(auth); + expect(parsed.headerName).toBe('X-API-Key'); + }); +}); + +describe('OAuth2AuthSchema', () => { + it('should accept valid OAuth2 configuration', () => { + const auth: OAuth2Auth = { + type: 'oauth2', + clientId: 'client-id', + clientSecret: 'client-secret', + authorizationUrl: 'https://auth.example.com/authorize', + tokenUrl: 'https://auth.example.com/token', + grantType: 'authorization_code', + }; + + expect(() => OAuth2AuthSchema.parse(auth)).not.toThrow(); + }); + + it('should accept OAuth2 with scopes and refresh token', () => { + const auth = { + type: 'oauth2', + clientId: 'client-id', + clientSecret: 'client-secret', + authorizationUrl: 'https://auth.example.com/authorize', + tokenUrl: 'https://auth.example.com/token', + scopes: ['read', 'write'], + refreshToken: 'refresh-token-xyz', + grantType: 'client_credentials', + }; + + const parsed = OAuth2AuthSchema.parse(auth); + expect(parsed.scopes).toHaveLength(2); + expect(parsed.refreshToken).toBe('refresh-token-xyz'); + }); + + it('should use default grant type', () => { + const auth = { + type: 'oauth2', + clientId: 'client-id', + clientSecret: 'client-secret', + authorizationUrl: 'https://auth.example.com/authorize', + tokenUrl: 'https://auth.example.com/token', + }; + + const parsed = OAuth2AuthSchema.parse(auth); + expect(parsed.grantType).toBe('authorization_code'); + }); +}); + +describe('JwtAuthSchema', () => { + it('should accept JWT with token', () => { + const auth = { + type: 'jwt', + token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', + algorithm: 'HS256', + }; + + expect(() => JwtAuthSchema.parse(auth)).not.toThrow(); + }); + + it('should accept JWT with secret key and claims', () => { + const auth = { + type: 'jwt', + secretKey: 'my-secret-key', + algorithm: 'HS256', + issuer: 'objectstack', + audience: 'api', + expiresIn: 3600, + claims: { role: 'admin' }, + }; + + const parsed = JwtAuthSchema.parse(auth); + expect(parsed.claims).toEqual({ role: 'admin' }); + }); + + it('should use default algorithm and expiry', () => { + const auth = { + type: 'jwt', + token: 'test-token', + }; + + const parsed = JwtAuthSchema.parse(auth); + expect(parsed.algorithm).toBe('HS256'); + expect(parsed.expiresIn).toBe(3600); + }); +}); + +describe('SamlAuthSchema', () => { + it('should accept valid SAML configuration', () => { + const auth = { + type: 'saml', + entryPoint: 'https://idp.example.com/sso', + issuer: 'objectstack-sp', + certificate: '-----BEGIN CERTIFICATE-----...', + signatureAlgorithm: 'sha256', + }; + + expect(() => SamlAuthSchema.parse(auth)).not.toThrow(); + }); + + it('should use default values', () => { + const auth = { + type: 'saml', + entryPoint: 'https://idp.example.com/sso', + issuer: 'objectstack-sp', + certificate: 'cert-content', + }; + + const parsed = SamlAuthSchema.parse(auth); + expect(parsed.signatureAlgorithm).toBe('sha256'); + expect(parsed.wantAssertionsSigned).toBe(true); + }); +}); + +describe('AuthenticationSchema', () => { + it('should accept all authentication types via discriminated union', () => { + const apiKeyAuth = { type: 'api_key', apiKey: 'key' }; + const oauth2Auth = { + type: 'oauth2', + clientId: 'id', + clientSecret: 'secret', + authorizationUrl: 'https://auth.example.com/authorize', + tokenUrl: 'https://auth.example.com/token', + }; + const basicAuth = { type: 'basic', username: 'user', password: 'pass' }; + const noAuth = { type: 'none' }; + + expect(() => AuthenticationSchema.parse(apiKeyAuth)).not.toThrow(); + expect(() => AuthenticationSchema.parse(oauth2Auth)).not.toThrow(); + expect(() => AuthenticationSchema.parse(basicAuth)).not.toThrow(); + expect(() => AuthenticationSchema.parse(noAuth)).not.toThrow(); + }); +}); + +// ============================================================================ +// Field Mapping Tests +// ============================================================================ + +describe('FieldMappingSchema', () => { + it('should accept valid field mapping', () => { + const mapping: FieldMapping = { + sourceField: 'firstName', + targetField: 'first_name', + dataType: 'string', + syncMode: 'bidirectional', + }; + + expect(() => FieldMappingSchema.parse(mapping)).not.toThrow(); + }); + + it('should validate target field snake_case format', () => { + expect(() => FieldMappingSchema.parse({ + sourceField: 'field', + targetField: 'valid_field_name', + })).not.toThrow(); + + expect(() => FieldMappingSchema.parse({ + sourceField: 'field', + targetField: 'InvalidField', + })).toThrow(); + }); + + it('should accept field with transformation', () => { + const mapping = { + sourceField: 'name', + targetField: 'full_name', + transform: { + type: 'uppercase', + }, + }; + + const parsed = FieldMappingSchema.parse(mapping); + expect(parsed.transform?.type).toBe('uppercase'); + }); + + it('should use default values', () => { + const mapping = { + sourceField: 'field1', + targetField: 'field_1', + }; + + const parsed = FieldMappingSchema.parse(mapping); + expect(parsed.required).toBe(false); + expect(parsed.syncMode).toBe('bidirectional'); + }); +}); + +// ============================================================================ +// Data Sync Configuration Tests +// ============================================================================ + +describe('DataSyncConfigSchema', () => { + it('should accept valid sync configuration', () => { + const config: DataSyncConfig = { + strategy: 'incremental', + direction: 'bidirectional', + schedule: '0 */6 * * *', + realtimeSync: true, + conflictResolution: 'latest_wins', + batchSize: 1000, + deleteMode: 'soft_delete', + }; + + expect(() => DataSyncConfigSchema.parse(config)).not.toThrow(); + }); + + it('should use default values', () => { + const config = {}; + + const parsed = DataSyncConfigSchema.parse(config); + expect(parsed.strategy).toBe('incremental'); + expect(parsed.direction).toBe('import'); + expect(parsed.realtimeSync).toBe(false); + expect(parsed.conflictResolution).toBe('latest_wins'); + expect(parsed.batchSize).toBe(1000); + expect(parsed.deleteMode).toBe('soft_delete'); + }); + + it('should validate batch size range', () => { + expect(() => DataSyncConfigSchema.parse({ batchSize: 0 })).toThrow(); + expect(() => DataSyncConfigSchema.parse({ batchSize: 10001 })).toThrow(); + expect(() => DataSyncConfigSchema.parse({ batchSize: 500 })).not.toThrow(); + }); +}); + +// ============================================================================ +// Webhook Configuration Tests +// ============================================================================ + +describe('WebhookConfigSchema', () => { + it('should accept valid webhook configuration', () => { + const webhook: WebhookConfig = { + url: 'https://api.example.com/webhooks', + events: ['record.created', 'record.updated'], + secret: 'webhook-secret', + signatureAlgorithm: 'hmac_sha256', + enabled: true, + }; + + expect(() => WebhookConfigSchema.parse(webhook)).not.toThrow(); + }); + + it('should accept webhook with retry configuration', () => { + const webhook = { + url: 'https://api.example.com/webhooks', + events: ['sync.completed'], + retryConfig: { + maxAttempts: 3, + backoffMultiplier: 2, + initialDelayMs: 1000, + }, + }; + + const parsed = WebhookConfigSchema.parse(webhook); + expect(parsed.retryConfig?.maxAttempts).toBe(3); + }); + + it('should use default values', () => { + const webhook = { + url: 'https://api.example.com/webhooks', + events: ['record.created'], + }; + + const parsed = WebhookConfigSchema.parse(webhook); + expect(parsed.signatureAlgorithm).toBe('hmac_sha256'); + expect(parsed.timeoutMs).toBe(30000); + expect(parsed.enabled).toBe(true); + }); +}); + +// ============================================================================ +// Rate Limiting & Retry Tests +// ============================================================================ + +describe('RateLimitConfigSchema', () => { + it('should accept valid rate limit configuration', () => { + const config = { + strategy: 'token_bucket', + maxRequests: 100, + windowSeconds: 60, + burstCapacity: 150, + respectUpstreamLimits: true, + }; + + expect(() => RateLimitConfigSchema.parse(config)).not.toThrow(); + }); + + it('should use default values', () => { + const config = { + maxRequests: 100, + windowSeconds: 60, + }; + + const parsed = RateLimitConfigSchema.parse(config); + expect(parsed.strategy).toBe('token_bucket'); + expect(parsed.respectUpstreamLimits).toBe(true); + }); +}); + +describe('RetryConfigSchema', () => { + it('should accept valid retry configuration', () => { + const config = { + strategy: 'exponential_backoff', + maxAttempts: 3, + initialDelayMs: 1000, + maxDelayMs: 60000, + backoffMultiplier: 2, + retryableStatusCodes: [429, 500, 502, 503], + retryOnNetworkError: true, + jitter: true, + }; + + expect(() => RetryConfigSchema.parse(config)).not.toThrow(); + }); + + it('should use default values', () => { + const config = {}; + + const parsed = RetryConfigSchema.parse(config); + expect(parsed.strategy).toBe('exponential_backoff'); + expect(parsed.maxAttempts).toBe(3); + expect(parsed.initialDelayMs).toBe(1000); + expect(parsed.maxDelayMs).toBe(60000); + expect(parsed.backoffMultiplier).toBe(2); + expect(parsed.retryableStatusCodes).toEqual([408, 429, 500, 502, 503, 504]); + expect(parsed.retryOnNetworkError).toBe(true); + expect(parsed.jitter).toBe(true); + }); + + it('should validate max attempts range', () => { + expect(() => RetryConfigSchema.parse({ maxAttempts: -1 })).toThrow(); + expect(() => RetryConfigSchema.parse({ maxAttempts: 11 })).toThrow(); + expect(() => RetryConfigSchema.parse({ maxAttempts: 5 })).not.toThrow(); + }); +}); + +// ============================================================================ +// Base Connector Tests +// ============================================================================ + +describe('ConnectorSchema', () => { + it('should accept valid minimal connector', () => { + const connector: Connector = { + name: 'test_connector', + label: 'Test Connector', + type: 'api', + authentication: { + type: 'api_key', + apiKey: 'test-key', + }, + status: 'inactive', + enabled: true, + }; + + expect(() => ConnectorSchema.parse(connector)).not.toThrow(); + }); + + it('should validate connector name format (snake_case)', () => { + expect(() => ConnectorSchema.parse({ + name: 'valid_connector_name', + label: 'Test', + type: 'saas', + authentication: { type: 'none' }, + })).not.toThrow(); + + expect(() => ConnectorSchema.parse({ + name: 'InvalidConnector', + label: 'Test', + type: 'saas', + authentication: { type: 'none' }, + })).toThrow(); + }); + + it('should accept connector with all fields', () => { + const connector = { + name: 'full_connector', + label: 'Full Connector', + type: 'saas', + description: 'A comprehensive connector', + icon: 'cloud', + authentication: { + type: 'oauth2', + clientId: 'client', + clientSecret: 'secret', + authorizationUrl: 'https://auth.example.com/authorize', + tokenUrl: 'https://auth.example.com/token', + }, + syncConfig: { + strategy: 'incremental', + direction: 'bidirectional', + }, + fieldMappings: [ + { + sourceField: 'id', + targetField: 'external_id', + }, + ], + webhooks: [ + { + url: 'https://api.example.com/webhook', + events: ['record.created'], + }, + ], + rateLimitConfig: { + maxRequests: 100, + windowSeconds: 60, + }, + retryConfig: { + maxAttempts: 3, + }, + status: 'active', + enabled: true, + metadata: { + version: '1.0', + }, + }; + + const parsed = ConnectorSchema.parse(connector); + expect(parsed.description).toBe('A comprehensive connector'); + expect(parsed.fieldMappings).toHaveLength(1); + expect(parsed.webhooks).toHaveLength(1); + }); + + it('should use default values', () => { + const connector = { + name: 'default_connector', + label: 'Default Connector', + type: 'database', + authentication: { type: 'none' }, + }; + + const parsed = ConnectorSchema.parse(connector); + expect(parsed.connectionTimeoutMs).toBe(30000); + expect(parsed.requestTimeoutMs).toBe(30000); + expect(parsed.status).toBe('inactive'); + expect(parsed.enabled).toBe(true); + }); + + it('should validate timeout ranges', () => { + expect(() => ConnectorSchema.parse({ + name: 'test', + label: 'Test', + type: 'api', + authentication: { type: 'none' }, + connectionTimeoutMs: 500, + })).toThrow(); + + expect(() => ConnectorSchema.parse({ + name: 'test', + label: 'Test', + type: 'api', + authentication: { type: 'none' }, + connectionTimeoutMs: 350000, + })).toThrow(); + + expect(() => ConnectorSchema.parse({ + name: 'test', + label: 'Test', + type: 'api', + authentication: { type: 'none' }, + connectionTimeoutMs: 5000, + })).not.toThrow(); + }); +}); + +describe('ConnectorTypeSchema', () => { + it('should accept all valid connector types', () => { + const types = ['saas', 'database', 'file_storage', 'message_queue', 'api', 'custom']; + + types.forEach(type => { + expect(() => ConnectorTypeSchema.parse(type)).not.toThrow(); + }); + }); + + it('should reject invalid connector types', () => { + expect(() => ConnectorTypeSchema.parse('invalid_type')).toThrow(); + }); +}); + +describe('ConnectorStatusSchema', () => { + it('should accept all valid statuses', () => { + const statuses = ['active', 'inactive', 'error', 'configuring']; + + statuses.forEach(status => { + expect(() => ConnectorStatusSchema.parse(status)).not.toThrow(); + }); + }); +}); + +// ============================================================================ +// Integration Tests +// ============================================================================ + +describe('Connector Integration', () => { + it('should create a complete SaaS connector', () => { + const connector = { + name: 'salesforce_prod', + label: 'Salesforce Production', + type: 'saas', + description: 'Production Salesforce connector', + authentication: { + type: 'oauth2', + clientId: '${SF_CLIENT_ID}', + clientSecret: '${SF_CLIENT_SECRET}', + authorizationUrl: 'https://login.salesforce.com/services/oauth2/authorize', + tokenUrl: 'https://login.salesforce.com/services/oauth2/token', + scopes: ['api', 'refresh_token'], + }, + syncConfig: { + strategy: 'incremental', + direction: 'bidirectional', + schedule: '0 */6 * * *', + realtimeSync: true, + batchSize: 200, + }, + fieldMappings: [ + { + sourceField: 'FirstName', + targetField: 'first_name', + dataType: 'string', + required: true, + }, + { + sourceField: 'LastName', + targetField: 'last_name', + dataType: 'string', + required: true, + }, + ], + rateLimitConfig: { + strategy: 'token_bucket', + maxRequests: 100, + windowSeconds: 20, + }, + retryConfig: { + strategy: 'exponential_backoff', + maxAttempts: 3, + }, + status: 'active', + enabled: true, + }; + + const parsed = ConnectorSchema.parse(connector); + expect(parsed.type).toBe('saas'); + expect(parsed.fieldMappings).toHaveLength(2); + }); +}); diff --git a/packages/spec/src/system/connector.zod.ts b/packages/spec/src/system/connector.zod.ts new file mode 100644 index 000000000..e8d56b592 --- /dev/null +++ b/packages/spec/src/system/connector.zod.ts @@ -0,0 +1,658 @@ +import { z } from 'zod'; + +/** + * Connector Protocol + * + * Defines the standard connector specification for external system integration. + * Connectors enable ObjectStack to sync data with SaaS apps, databases, file storage, + * and message queues through a unified protocol. + * + * This protocol supports multiple authentication strategies, bidirectional sync, + * field mapping, webhooks, and comprehensive rate limiting. + */ + +// ============================================================================ +// Authentication Schemas +// ============================================================================ + +/** + * API Key Authentication Schema + */ +export const ApiKeyAuthSchema = z.object({ + type: z.literal('api_key').describe('Authentication type'), + apiKey: z.string().describe('API key (typically from ENV)'), + headerName: z.string().default('X-API-Key').describe('HTTP header name for API key'), + paramName: z.string().optional().describe('Query parameter name (alternative to header)'), +}); + +export type ApiKeyAuth = z.infer; + +/** + * OAuth2 Authentication Schema + */ +export const OAuth2AuthSchema = z.object({ + type: z.literal('oauth2').describe('Authentication type'), + + clientId: z.string().describe('OAuth2 client ID'), + clientSecret: z.string().describe('OAuth2 client secret (typically from ENV)'), + + authorizationUrl: z.string().url().describe('OAuth2 authorization endpoint'), + tokenUrl: z.string().url().describe('OAuth2 token endpoint'), + + scopes: z.array(z.string()).optional().describe('Requested OAuth2 scopes'), + + redirectUri: z.string().url().optional().describe('OAuth2 callback URL'), + + grantType: z.enum([ + 'authorization_code', + 'client_credentials', + 'password', + 'refresh_token', + ]).default('authorization_code').describe('OAuth2 grant type'), + + refreshToken: z.string().optional().describe('Refresh token for token renewal'), + + tokenExpiry: z.number().optional().describe('Token expiry timestamp'), +}); + +export type OAuth2Auth = z.infer; + +/** + * JWT Authentication Schema + */ +export const JwtAuthSchema = z.object({ + type: z.literal('jwt').describe('Authentication type'), + + token: z.string().optional().describe('Pre-generated JWT token'), + + secretKey: z.string().optional().describe('Secret key for JWT signing'), + + algorithm: z.enum([ + 'HS256', 'HS384', 'HS512', + 'RS256', 'RS384', 'RS512', + 'ES256', 'ES384', 'ES512', + ]).default('HS256').describe('JWT signing algorithm'), + + issuer: z.string().optional().describe('JWT issuer claim'), + + audience: z.string().optional().describe('JWT audience claim'), + + subject: z.string().optional().describe('JWT subject claim'), + + expiresIn: z.number().default(3600).describe('Token expiry in seconds'), + + claims: z.record(z.any()).optional().describe('Additional JWT claims'), +}); + +export type JwtAuth = z.infer; + +/** + * SAML Authentication Schema + */ +export const SamlAuthSchema = z.object({ + type: z.literal('saml').describe('Authentication type'), + + entryPoint: z.string().url().describe('SAML IdP entry point URL'), + + issuer: z.string().describe('SAML service provider issuer'), + + certificate: z.string().describe('SAML IdP certificate (X.509)'), + + privateKey: z.string().optional().describe('SAML service provider private key'), + + callbackUrl: z.string().url().optional().describe('SAML assertion consumer service URL'), + + signatureAlgorithm: z.enum([ + 'sha1', + 'sha256', + 'sha512', + ]).default('sha256').describe('SAML signature algorithm'), + + wantAssertionsSigned: z.boolean().default(true).describe('Require signed SAML assertions'), + + identifierFormat: z.string().optional().describe('SAML NameID format'), +}); + +export type SamlAuth = z.infer; + +/** + * Basic Authentication Schema + */ +export const BasicAuthSchema = z.object({ + type: z.literal('basic').describe('Authentication type'), + username: z.string().describe('Username'), + password: z.string().describe('Password (typically from ENV)'), +}); + +export type BasicAuth = z.infer; + +/** + * Bearer Token Authentication Schema + */ +export const BearerTokenAuthSchema = z.object({ + type: z.literal('bearer').describe('Authentication type'), + token: z.string().describe('Bearer token'), +}); + +export type BearerTokenAuth = z.infer; + +/** + * No Authentication Schema + */ +export const NoAuthSchema = z.object({ + type: z.literal('none').describe('No authentication required'), +}); + +export type NoAuth = z.infer; + +/** + * Unified Authentication Configuration + * Discriminated union of all authentication methods + */ +export const AuthenticationSchema = z.discriminatedUnion('type', [ + ApiKeyAuthSchema, + OAuth2AuthSchema, + JwtAuthSchema, + SamlAuthSchema, + BasicAuthSchema, + BearerTokenAuthSchema, + NoAuthSchema, +]); + +export type Authentication = z.infer; + +// ============================================================================ +// Field Mapping Schema +// ============================================================================ + +/** + * Field Transformation Function + */ +export const FieldTransformSchema = z.object({ + type: z.enum([ + 'uppercase', + 'lowercase', + 'trim', + 'date_format', + 'number_format', + 'custom', + ]).describe('Transformation type'), + + params: z.record(z.any()).optional().describe('Transformation parameters'), + + function: z.string().optional().describe('Custom JavaScript function for transformation'), +}); + +export type FieldTransform = z.infer; + +/** + * Field Mapping Configuration + * Maps fields between ObjectStack and external system + */ +export const FieldMappingSchema = z.object({ + /** + * Source field name (in external system) + */ + sourceField: z.string().describe('Field name in external system'), + + /** + * Target field name (in ObjectStack) + */ + targetField: z.string().regex(/^[a-z_][a-z0-9_]*$/).describe('Field name in ObjectStack (snake_case)'), + + /** + * Data type mapping + */ + dataType: z.enum([ + 'string', + 'number', + 'boolean', + 'date', + 'datetime', + 'json', + 'array', + ]).optional().describe('Target data type'), + + /** + * Is this field required? + */ + required: z.boolean().default(false).describe('Field is required'), + + /** + * Default value if source is empty + */ + defaultValue: z.any().optional().describe('Default value'), + + /** + * Field transformation rules + */ + transform: FieldTransformSchema.optional().describe('Field transformation'), + + /** + * Bidirectional sync mode + */ + syncMode: z.enum([ + 'read_only', // Only sync from external to ObjectStack + 'write_only', // Only sync from ObjectStack to external + 'bidirectional', // Sync both ways + ]).default('bidirectional').describe('Sync mode'), +}); + +export type FieldMapping = z.infer; + +// ============================================================================ +// Data Synchronization Configuration +// ============================================================================ + +/** + * Sync Strategy Schema + */ +export const SyncStrategySchema = z.enum([ + 'full', // Full refresh (delete all and re-import) + 'incremental', // Only sync changes since last sync + 'upsert', // Insert new, update existing + 'append_only', // Only insert new records +]).describe('Synchronization strategy'); + +export type SyncStrategy = z.infer; + +/** + * Conflict Resolution Strategy + */ +export const ConflictResolutionSchema = z.enum([ + 'source_wins', // External system data takes precedence + 'target_wins', // ObjectStack data takes precedence + 'latest_wins', // Most recently modified wins + 'manual', // Flag for manual resolution +]).describe('Conflict resolution strategy'); + +export type ConflictResolution = z.infer; + +/** + * Data Synchronization Configuration + */ +export const DataSyncConfigSchema = z.object({ + /** + * Sync strategy + */ + strategy: SyncStrategySchema.default('incremental'), + + /** + * Sync direction + */ + direction: z.enum([ + 'import', // External → ObjectStack + 'export', // ObjectStack → External + 'bidirectional', // Both ways + ]).default('import').describe('Sync direction'), + + /** + * Sync frequency (cron expression) + */ + schedule: z.string().optional().describe('Cron expression for scheduled sync'), + + /** + * Enable real-time sync via webhooks + */ + realtimeSync: z.boolean().default(false).describe('Enable real-time sync'), + + /** + * Field to track last sync timestamp + */ + timestampField: z.string().optional().describe('Field to track last modification time'), + + /** + * Conflict resolution strategy + */ + conflictResolution: ConflictResolutionSchema.default('latest_wins'), + + /** + * Batch size for bulk operations + */ + batchSize: z.number().min(1).max(10000).default(1000).describe('Records per batch'), + + /** + * Delete handling + */ + deleteMode: z.enum([ + 'hard_delete', // Permanently delete + 'soft_delete', // Mark as deleted + 'ignore', // Don't sync deletions + ]).default('soft_delete').describe('Delete handling mode'), + + /** + * Filter criteria for selective sync + */ + filters: z.record(z.any()).optional().describe('Filter criteria for selective sync'), +}); + +export type DataSyncConfig = z.infer; + +// ============================================================================ +// Webhook Configuration +// ============================================================================ + +/** + * Webhook Event Schema + */ +export const WebhookEventSchema = z.enum([ + 'record.created', + 'record.updated', + 'record.deleted', + 'sync.started', + 'sync.completed', + 'sync.failed', + 'auth.expired', + 'rate_limit.exceeded', +]).describe('Webhook event type'); + +export type WebhookEvent = z.infer; + +/** + * Webhook Signature Algorithm + */ +export const WebhookSignatureAlgorithmSchema = z.enum([ + 'hmac_sha256', + 'hmac_sha512', + 'none', +]).describe('Webhook signature algorithm'); + +export type WebhookSignatureAlgorithm = z.infer; + +/** + * Webhook Configuration Schema + */ +export const WebhookConfigSchema = z.object({ + /** + * Webhook endpoint URL + */ + url: z.string().url().describe('Webhook endpoint URL'), + + /** + * Events to listen for + */ + events: z.array(WebhookEventSchema).describe('Events to subscribe to'), + + /** + * Webhook secret for signature verification + */ + secret: z.string().optional().describe('Secret for HMAC signature'), + + /** + * Signature algorithm + */ + signatureAlgorithm: WebhookSignatureAlgorithmSchema.default('hmac_sha256'), + + /** + * Custom headers to include in webhook requests + */ + headers: z.record(z.string()).optional().describe('Custom HTTP headers'), + + /** + * Retry configuration for failed webhook deliveries + */ + retryConfig: z.object({ + maxAttempts: z.number().min(0).max(10).default(3).describe('Maximum retry attempts'), + backoffMultiplier: z.number().min(1).default(2).describe('Exponential backoff multiplier'), + initialDelayMs: z.number().min(100).default(1000).describe('Initial retry delay in ms'), + }).optional().describe('Retry configuration'), + + /** + * Timeout for webhook requests + */ + timeoutMs: z.number().min(1000).max(60000).default(30000).describe('Request timeout in ms'), + + /** + * Enable webhook + */ + enabled: z.boolean().default(true).describe('Enable webhook'), +}); + +export type WebhookConfig = z.infer; + +// ============================================================================ +// Rate Limiting and Retry Configuration +// ============================================================================ + +/** + * Rate Limiting Strategy + */ +export const RateLimitStrategySchema = z.enum([ + 'fixed_window', // Fixed time window + 'sliding_window', // Sliding time window + 'token_bucket', // Token bucket algorithm + 'leaky_bucket', // Leaky bucket algorithm +]).describe('Rate limiting strategy'); + +export type RateLimitStrategy = z.infer; + +/** + * Rate Limiting Configuration + */ +export const RateLimitConfigSchema = z.object({ + /** + * Rate limiting strategy + */ + strategy: RateLimitStrategySchema.default('token_bucket'), + + /** + * Maximum requests per window + */ + maxRequests: z.number().min(1).describe('Maximum requests per window'), + + /** + * Time window in seconds + */ + windowSeconds: z.number().min(1).describe('Time window in seconds'), + + /** + * Burst capacity (for token bucket) + */ + burstCapacity: z.number().min(1).optional().describe('Burst capacity'), + + /** + * Respect external system rate limits + */ + respectUpstreamLimits: z.boolean().default(true).describe('Respect external rate limit headers'), + + /** + * Custom rate limit headers to check + */ + rateLimitHeaders: z.object({ + remaining: z.string().default('X-RateLimit-Remaining').describe('Header for remaining requests'), + limit: z.string().default('X-RateLimit-Limit').describe('Header for rate limit'), + reset: z.string().default('X-RateLimit-Reset').describe('Header for reset time'), + }).optional().describe('Custom rate limit headers'), +}); + +export type RateLimitConfig = z.infer; + +/** + * Retry Strategy + */ +export const RetryStrategySchema = z.enum([ + 'exponential_backoff', + 'linear_backoff', + 'fixed_delay', + 'no_retry', +]).describe('Retry strategy'); + +export type RetryStrategy = z.infer; + +/** + * Retry Configuration + */ +export const RetryConfigSchema = z.object({ + /** + * Retry strategy + */ + strategy: RetryStrategySchema.default('exponential_backoff'), + + /** + * Maximum retry attempts + */ + maxAttempts: z.number().min(0).max(10).default(3).describe('Maximum retry attempts'), + + /** + * Initial delay in milliseconds + */ + initialDelayMs: z.number().min(100).default(1000).describe('Initial retry delay in ms'), + + /** + * Maximum delay in milliseconds + */ + maxDelayMs: z.number().min(1000).default(60000).describe('Maximum retry delay in ms'), + + /** + * Backoff multiplier (for exponential backoff) + */ + backoffMultiplier: z.number().min(1).default(2).describe('Exponential backoff multiplier'), + + /** + * HTTP status codes to retry + */ + retryableStatusCodes: z.array(z.number()).default([408, 429, 500, 502, 503, 504]).describe('HTTP status codes to retry'), + + /** + * Retry on network errors + */ + retryOnNetworkError: z.boolean().default(true).describe('Retry on network errors'), + + /** + * Jitter to add randomness to retry delays + */ + jitter: z.boolean().default(true).describe('Add jitter to retry delays'), +}); + +export type RetryConfig = z.infer; + +// ============================================================================ +// Base Connector Schema +// ============================================================================ + +/** + * Connector Type + */ +export const ConnectorTypeSchema = z.enum([ + 'saas', // SaaS application connector + 'database', // Database connector + 'file_storage', // File storage connector + 'message_queue', // Message queue connector + 'api', // Generic REST/GraphQL API + 'custom', // Custom connector +]).describe('Connector type'); + +export type ConnectorType = z.infer; + +/** + * Connector Status + */ +export const ConnectorStatusSchema = z.enum([ + 'active', // Connector is active and syncing + 'inactive', // Connector is configured but disabled + 'error', // Connector has errors + 'configuring', // Connector is being set up +]).describe('Connector status'); + +export type ConnectorStatus = z.infer; + +/** + * Base Connector Schema + * Core connector configuration shared across all connector types + */ +export const ConnectorSchema = z.object({ + /** + * Machine name (snake_case) + */ + name: z.string().regex(/^[a-z_][a-z0-9_]*$/).describe('Unique connector identifier'), + + /** + * Human-readable label + */ + label: z.string().describe('Display label'), + + /** + * Connector type + */ + type: ConnectorTypeSchema.describe('Connector type'), + + /** + * Description + */ + description: z.string().optional().describe('Connector description'), + + /** + * Icon identifier + */ + icon: z.string().optional().describe('Icon identifier'), + + /** + * Authentication configuration + */ + authentication: AuthenticationSchema.describe('Authentication configuration'), + + /** + * Data synchronization configuration + */ + syncConfig: DataSyncConfigSchema.optional().describe('Data sync configuration'), + + /** + * Field mappings + */ + fieldMappings: z.array(FieldMappingSchema).optional().describe('Field mapping rules'), + + /** + * Webhook configuration + */ + webhooks: z.array(WebhookConfigSchema).optional().describe('Webhook configurations'), + + /** + * Rate limiting configuration + */ + rateLimitConfig: RateLimitConfigSchema.optional().describe('Rate limiting configuration'), + + /** + * Retry configuration + */ + retryConfig: RetryConfigSchema.optional().describe('Retry configuration'), + + /** + * Connection timeout in milliseconds + */ + connectionTimeoutMs: z.number().min(1000).max(300000).default(30000).describe('Connection timeout in ms'), + + /** + * Request timeout in milliseconds + */ + requestTimeoutMs: z.number().min(1000).max(300000).default(30000).describe('Request timeout in ms'), + + /** + * Connector status + */ + status: ConnectorStatusSchema.default('inactive').describe('Connector status'), + + /** + * Enable connector + */ + enabled: z.boolean().default(true).describe('Enable connector'), + + /** + * Custom metadata + */ + metadata: z.record(z.any()).optional().describe('Custom connector metadata'), +}); + +export type Connector = z.infer; + +// ============================================================================ +// TypeScript Exports +// ============================================================================ + +export type { + SyncStrategy, + ConflictResolution, + WebhookEvent, + WebhookSignatureAlgorithm, + RateLimitStrategy, + RetryStrategy, +}; diff --git a/packages/spec/src/system/connector/database.zod.ts b/packages/spec/src/system/connector/database.zod.ts new file mode 100644 index 000000000..ab88aa404 --- /dev/null +++ b/packages/spec/src/system/connector/database.zod.ts @@ -0,0 +1,342 @@ +import { z } from 'zod'; +import { + ConnectorSchema, + DataSyncConfigSchema, + FieldMappingSchema, +} from '../connector.zod'; + +/** + * Database Connector Protocol Template + * + * Specialized connector for database systems (PostgreSQL, MySQL, SQL Server, etc.) + * Extends the base connector with database-specific features like schema discovery, + * CDC (Change Data Capture), and connection pooling. + */ + +/** + * Database Provider Types + */ +export const DatabaseProviderSchema = z.enum([ + 'postgresql', + 'mysql', + 'mariadb', + 'mssql', + 'oracle', + 'mongodb', + 'redis', + 'cassandra', + 'snowflake', + 'bigquery', + 'redshift', + 'custom', +]).describe('Database provider type'); + +export type DatabaseProvider = z.infer; + +/** + * Database Connection Pool Configuration + */ +export const DatabasePoolConfigSchema = z.object({ + min: z.number().min(0).default(2).describe('Minimum connections in pool'), + max: z.number().min(1).default(10).describe('Maximum connections in pool'), + idleTimeoutMs: z.number().min(1000).default(30000).describe('Idle connection timeout in ms'), + connectionTimeoutMs: z.number().min(1000).default(10000).describe('Connection establishment timeout in ms'), + acquireTimeoutMs: z.number().min(1000).default(30000).describe('Connection acquisition timeout in ms'), + evictionRunIntervalMs: z.number().min(1000).default(30000).describe('Connection eviction check interval in ms'), + testOnBorrow: z.boolean().default(true).describe('Test connection before use'), +}); + +export type DatabasePoolConfig = z.infer; + +/** + * SSL/TLS Configuration + */ +export const SslConfigSchema = z.object({ + enabled: z.boolean().default(false).describe('Enable SSL/TLS'), + rejectUnauthorized: z.boolean().default(true).describe('Reject unauthorized certificates'), + ca: z.string().optional().describe('Certificate Authority certificate'), + cert: z.string().optional().describe('Client certificate'), + key: z.string().optional().describe('Client private key'), +}); + +export type SslConfig = z.infer; + +/** + * Change Data Capture (CDC) Configuration + */ +export const CdcConfigSchema = z.object({ + enabled: z.boolean().default(false).describe('Enable CDC'), + + method: z.enum([ + 'log_based', // Transaction log parsing (e.g., PostgreSQL logical replication) + 'trigger_based', // Database triggers for change tracking + 'query_based', // Timestamp-based queries + 'custom', // Custom CDC implementation + ]).describe('CDC method'), + + slotName: z.string().optional().describe('Replication slot name (for log-based CDC)'), + + publicationName: z.string().optional().describe('Publication name (for PostgreSQL)'), + + startPosition: z.string().optional().describe('Starting position/LSN for CDC stream'), + + batchSize: z.number().min(1).max(10000).default(1000).describe('CDC batch size'), + + pollIntervalMs: z.number().min(100).default(1000).describe('CDC polling interval in ms'), +}); + +export type CdcConfig = z.infer; + +/** + * Database Table Configuration + */ +export const DatabaseTableSchema = z.object({ + name: z.string().regex(/^[a-z_][a-z0-9_]*$/).describe('Table name in ObjectStack (snake_case)'), + label: z.string().describe('Display label'), + schema: z.string().optional().describe('Database schema name'), + tableName: z.string().describe('Actual table name in database'), + primaryKey: z.string().describe('Primary key column'), + enabled: z.boolean().default(true).describe('Enable sync for this table'), + fieldMappings: z.array(FieldMappingSchema).optional().describe('Table-specific field mappings'), + whereClause: z.string().optional().describe('SQL WHERE clause for filtering'), +}); + +export type DatabaseTable = z.infer; + +/** + * Database Connector Configuration Schema + */ +export const DatabaseConnectorSchema = ConnectorSchema.extend({ + type: z.literal('database'), + + /** + * Database provider + */ + provider: DatabaseProviderSchema.describe('Database provider type'), + + /** + * Connection configuration + */ + connectionConfig: z.object({ + host: z.string().describe('Database host'), + port: z.number().min(1).max(65535).describe('Database port'), + database: z.string().describe('Database name'), + username: z.string().describe('Database username'), + password: z.string().describe('Database password (typically from ENV)'), + options: z.record(z.any()).optional().describe('Driver-specific connection options'), + }).describe('Database connection configuration'), + + /** + * Connection pool configuration + */ + poolConfig: DatabasePoolConfigSchema.optional().describe('Connection pool configuration'), + + /** + * SSL/TLS configuration + */ + sslConfig: SslConfigSchema.optional().describe('SSL/TLS configuration'), + + /** + * Tables to sync + */ + tables: z.array(DatabaseTableSchema).describe('Tables to sync'), + + /** + * Change Data Capture configuration + */ + cdcConfig: CdcConfigSchema.optional().describe('CDC configuration'), + + /** + * Read replica configuration + */ + readReplicaConfig: z.object({ + enabled: z.boolean().default(false).describe('Use read replicas'), + hosts: z.array(z.object({ + host: z.string().describe('Replica host'), + port: z.number().min(1).max(65535).describe('Replica port'), + weight: z.number().min(0).max(1).default(1).describe('Load balancing weight'), + })).describe('Read replica hosts'), + }).optional().describe('Read replica configuration'), + + /** + * Query timeout + */ + queryTimeoutMs: z.number().min(1000).max(300000).default(30000).describe('Query timeout in ms'), + + /** + * Enable query logging + */ + enableQueryLogging: z.boolean().default(false).describe('Enable SQL query logging'), +}); + +export type DatabaseConnector = z.infer; + +// ============================================================================ +// Helper Functions & Examples +// ============================================================================ + +/** + * Example: PostgreSQL Connector Configuration + */ +export const postgresConnectorExample: DatabaseConnector = { + name: 'postgres_production', + label: 'Production PostgreSQL', + type: 'database', + provider: 'postgresql', + authentication: { + type: 'basic', + username: '${DB_USERNAME}', + password: '${DB_PASSWORD}', + }, + connectionConfig: { + host: 'db.example.com', + port: 5432, + database: 'production', + username: '${DB_USERNAME}', + password: '${DB_PASSWORD}', + }, + poolConfig: { + min: 2, + max: 20, + idleTimeoutMs: 30000, + connectionTimeoutMs: 10000, + acquireTimeoutMs: 30000, + evictionRunIntervalMs: 30000, + testOnBorrow: true, + }, + sslConfig: { + enabled: true, + rejectUnauthorized: true, + }, + tables: [ + { + name: 'customer', + label: 'Customer', + schema: 'public', + tableName: 'customers', + primaryKey: 'id', + enabled: true, + }, + { + name: 'order', + label: 'Order', + schema: 'public', + tableName: 'orders', + primaryKey: 'id', + enabled: true, + whereClause: 'status != \'archived\'', + }, + ], + cdcConfig: { + enabled: true, + method: 'log_based', + slotName: 'objectstack_replication_slot', + publicationName: 'objectstack_publication', + batchSize: 1000, + pollIntervalMs: 1000, + }, + syncConfig: { + strategy: 'incremental', + direction: 'bidirectional', + realtimeSync: true, + conflictResolution: 'latest_wins', + batchSize: 1000, + deleteMode: 'soft_delete', + }, + status: 'active', + enabled: true, +}; + +/** + * Example: MongoDB Connector Configuration + */ +export const mongoConnectorExample: DatabaseConnector = { + name: 'mongodb_analytics', + label: 'MongoDB Analytics', + type: 'database', + provider: 'mongodb', + authentication: { + type: 'basic', + username: '${MONGO_USERNAME}', + password: '${MONGO_PASSWORD}', + }, + connectionConfig: { + host: 'mongodb.example.com', + port: 27017, + database: 'analytics', + username: '${MONGO_USERNAME}', + password: '${MONGO_PASSWORD}', + options: { + authSource: 'admin', + replicaSet: 'rs0', + }, + }, + tables: [ + { + name: 'event', + label: 'Event', + tableName: 'events', + primaryKey: '_id', + enabled: true, + }, + ], + cdcConfig: { + enabled: true, + method: 'log_based', + batchSize: 1000, + pollIntervalMs: 500, + }, + syncConfig: { + strategy: 'incremental', + direction: 'import', + batchSize: 1000, + }, + status: 'active', + enabled: true, +}; + +/** + * Example: Snowflake Connector Configuration + */ +export const snowflakeConnectorExample: DatabaseConnector = { + name: 'snowflake_warehouse', + label: 'Snowflake Data Warehouse', + type: 'database', + provider: 'snowflake', + authentication: { + type: 'basic', + username: '${SNOWFLAKE_USERNAME}', + password: '${SNOWFLAKE_PASSWORD}', + }, + connectionConfig: { + host: 'account.snowflakecomputing.com', + port: 443, + database: 'ANALYTICS_DB', + username: '${SNOWFLAKE_USERNAME}', + password: '${SNOWFLAKE_PASSWORD}', + options: { + warehouse: 'COMPUTE_WH', + schema: 'PUBLIC', + role: 'ANALYST', + }, + }, + tables: [ + { + name: 'sales_summary', + label: 'Sales Summary', + schema: 'PUBLIC', + tableName: 'SALES_SUMMARY', + primaryKey: 'ID', + enabled: true, + }, + ], + syncConfig: { + strategy: 'full', + direction: 'import', + schedule: '0 2 * * *', // Daily at 2 AM + batchSize: 5000, + }, + queryTimeoutMs: 60000, + status: 'active', + enabled: true, +}; diff --git a/packages/spec/src/system/connector/file-storage.zod.ts b/packages/spec/src/system/connector/file-storage.zod.ts new file mode 100644 index 000000000..71b24dff8 --- /dev/null +++ b/packages/spec/src/system/connector/file-storage.zod.ts @@ -0,0 +1,398 @@ +import { z } from 'zod'; +import { + ConnectorSchema, + DataSyncConfigSchema, +} from '../connector.zod'; + +/** + * File Storage Connector Protocol Template + * + * Specialized connector for file storage systems (S3, Azure Blob, Google Cloud Storage, etc.) + * Extends the base connector with file-specific features like multipart uploads, + * versioning, and metadata extraction. + */ + +/** + * File Storage Provider Types + */ +export const FileStorageProviderSchema = z.enum([ + 's3', // Amazon S3 + 'azure_blob', // Azure Blob Storage + 'gcs', // Google Cloud Storage + 'dropbox', // Dropbox + 'box', // Box + 'onedrive', // Microsoft OneDrive + 'google_drive', // Google Drive + 'sharepoint', // SharePoint + 'ftp', // FTP/SFTP + 'local', // Local file system + 'custom', // Custom file storage +]).describe('File storage provider type'); + +export type FileStorageProvider = z.infer; + +/** + * File Access Pattern + */ +export const FileAccessPatternSchema = z.enum([ + 'public_read', // Public read access + 'private', // Private access + 'authenticated_read', // Requires authentication + 'bucket_owner_read', // Bucket owner has read access + 'bucket_owner_full', // Bucket owner has full control +]).describe('File access pattern'); + +export type FileAccessPattern = z.infer; + +/** + * File Metadata Configuration + */ +export const FileMetadataConfigSchema = z.object({ + extractMetadata: z.boolean().default(true).describe('Extract file metadata'), + + metadataFields: z.array(z.enum([ + 'content_type', + 'file_size', + 'last_modified', + 'etag', + 'checksum', + 'creator', + 'created_at', + 'custom', + ])).optional().describe('Metadata fields to extract'), + + customMetadata: z.record(z.string()).optional().describe('Custom metadata key-value pairs'), +}); + +export type FileMetadataConfig = z.infer; + +/** + * Multipart Upload Configuration + */ +export const MultipartUploadConfigSchema = z.object({ + enabled: z.boolean().default(true).describe('Enable multipart uploads'), + + partSize: z.number().min(5 * 1024 * 1024).default(5 * 1024 * 1024).describe('Part size in bytes (min 5MB)'), + + maxConcurrentParts: z.number().min(1).max(10).default(5).describe('Maximum concurrent part uploads'), + + threshold: z.number().min(5 * 1024 * 1024).default(100 * 1024 * 1024).describe('File size threshold for multipart upload in bytes'), +}); + +export type MultipartUploadConfig = z.infer; + +/** + * File Versioning Configuration + */ +export const FileVersioningConfigSchema = z.object({ + enabled: z.boolean().default(false).describe('Enable file versioning'), + + maxVersions: z.number().min(1).max(100).optional().describe('Maximum versions to retain'), + + retentionDays: z.number().min(1).optional().describe('Version retention period in days'), +}); + +export type FileVersioningConfig = z.infer; + +/** + * File Filter Configuration + */ +export const FileFilterConfigSchema = z.object({ + includePatterns: z.array(z.string()).optional().describe('File patterns to include (glob)'), + + excludePatterns: z.array(z.string()).optional().describe('File patterns to exclude (glob)'), + + minFileSize: z.number().min(0).optional().describe('Minimum file size in bytes'), + + maxFileSize: z.number().min(1).optional().describe('Maximum file size in bytes'), + + allowedExtensions: z.array(z.string()).optional().describe('Allowed file extensions'), + + blockedExtensions: z.array(z.string()).optional().describe('Blocked file extensions'), +}); + +export type FileFilterConfig = z.infer; + +/** + * File Storage Bucket/Container Configuration + */ +export const StorageBucketSchema = z.object({ + name: z.string().regex(/^[a-z_][a-z0-9_]*$/).describe('Bucket identifier in ObjectStack (snake_case)'), + label: z.string().describe('Display label'), + bucketName: z.string().describe('Actual bucket/container name in storage system'), + region: z.string().optional().describe('Storage region'), + enabled: z.boolean().default(true).describe('Enable sync for this bucket'), + prefix: z.string().optional().describe('Prefix/path within bucket'), + accessPattern: FileAccessPatternSchema.optional().describe('Access pattern'), + fileFilters: FileFilterConfigSchema.optional().describe('File filter configuration'), +}); + +export type StorageBucket = z.infer; + +/** + * File Storage Connector Configuration Schema + */ +export const FileStorageConnectorSchema = ConnectorSchema.extend({ + type: z.literal('file_storage'), + + /** + * File storage provider + */ + provider: FileStorageProviderSchema.describe('File storage provider type'), + + /** + * Storage configuration + */ + storageConfig: z.object({ + endpoint: z.string().url().optional().describe('Custom endpoint URL'), + region: z.string().optional().describe('Default region'), + pathStyle: z.boolean().default(false).describe('Use path-style URLs (for S3-compatible)'), + }).optional().describe('Storage configuration'), + + /** + * Buckets/containers to sync + */ + buckets: z.array(StorageBucketSchema).describe('Buckets/containers to sync'), + + /** + * File metadata configuration + */ + metadataConfig: FileMetadataConfigSchema.optional().describe('Metadata extraction configuration'), + + /** + * Multipart upload configuration + */ + multipartConfig: MultipartUploadConfigSchema.optional().describe('Multipart upload configuration'), + + /** + * File versioning configuration + */ + versioningConfig: FileVersioningConfigSchema.optional().describe('File versioning configuration'), + + /** + * Enable server-side encryption + */ + encryption: z.object({ + enabled: z.boolean().default(false).describe('Enable server-side encryption'), + algorithm: z.enum(['AES256', 'aws:kms', 'custom']).optional().describe('Encryption algorithm'), + kmsKeyId: z.string().optional().describe('KMS key ID (for aws:kms)'), + }).optional().describe('Encryption configuration'), + + /** + * Lifecycle policy + */ + lifecyclePolicy: z.object({ + enabled: z.boolean().default(false).describe('Enable lifecycle policy'), + deleteAfterDays: z.number().min(1).optional().describe('Delete files after N days'), + archiveAfterDays: z.number().min(1).optional().describe('Archive files after N days'), + }).optional().describe('Lifecycle policy'), + + /** + * Content processing configuration + */ + contentProcessing: z.object({ + extractText: z.boolean().default(false).describe('Extract text from documents'), + generateThumbnails: z.boolean().default(false).describe('Generate image thumbnails'), + thumbnailSizes: z.array(z.object({ + width: z.number().min(1), + height: z.number().min(1), + })).optional().describe('Thumbnail sizes'), + virusScan: z.boolean().default(false).describe('Scan for viruses'), + }).optional().describe('Content processing configuration'), + + /** + * Download/upload buffer size + */ + bufferSize: z.number().min(1024).default(64 * 1024).describe('Buffer size in bytes'), + + /** + * Enable transfer acceleration (for supported providers) + */ + transferAcceleration: z.boolean().default(false).describe('Enable transfer acceleration'), +}); + +export type FileStorageConnector = z.infer; + +// ============================================================================ +// Helper Functions & Examples +// ============================================================================ + +/** + * Example: Amazon S3 Connector Configuration + */ +export const s3ConnectorExample: FileStorageConnector = { + name: 's3_production_assets', + label: 'Production S3 Assets', + type: 'file_storage', + provider: 's3', + authentication: { + type: 'api_key', + apiKey: '${AWS_ACCESS_KEY_ID}:${AWS_SECRET_ACCESS_KEY}', + headerName: 'Authorization', + }, + storageConfig: { + region: 'us-east-1', + pathStyle: false, + }, + buckets: [ + { + name: 'product_images', + label: 'Product Images', + bucketName: 'my-company-product-images', + region: 'us-east-1', + enabled: true, + prefix: 'products/', + accessPattern: 'public_read', + fileFilters: { + allowedExtensions: ['.jpg', '.jpeg', '.png', '.webp'], + maxFileSize: 10 * 1024 * 1024, // 10MB + }, + }, + { + name: 'customer_documents', + label: 'Customer Documents', + bucketName: 'my-company-customer-docs', + region: 'us-east-1', + enabled: true, + accessPattern: 'private', + fileFilters: { + allowedExtensions: ['.pdf', '.docx', '.xlsx'], + maxFileSize: 50 * 1024 * 1024, // 50MB + }, + }, + ], + metadataConfig: { + extractMetadata: true, + metadataFields: ['content_type', 'file_size', 'last_modified', 'etag'], + }, + multipartConfig: { + enabled: true, + partSize: 5 * 1024 * 1024, // 5MB + maxConcurrentParts: 5, + threshold: 100 * 1024 * 1024, // 100MB + }, + versioningConfig: { + enabled: true, + maxVersions: 10, + }, + encryption: { + enabled: true, + algorithm: 'aws:kms', + kmsKeyId: '${AWS_KMS_KEY_ID}', + }, + contentProcessing: { + extractText: true, + generateThumbnails: true, + thumbnailSizes: [ + { width: 150, height: 150 }, + { width: 300, height: 300 }, + { width: 600, height: 600 }, + ], + virusScan: true, + }, + syncConfig: { + strategy: 'incremental', + direction: 'bidirectional', + realtimeSync: true, + conflictResolution: 'latest_wins', + batchSize: 100, + }, + transferAcceleration: true, + status: 'active', + enabled: true, +}; + +/** + * Example: Google Drive Connector Configuration + */ +export const googleDriveConnectorExample: FileStorageConnector = { + name: 'google_drive_team', + label: 'Google Drive Team Folder', + type: 'file_storage', + provider: 'google_drive', + authentication: { + type: 'oauth2', + clientId: '${GOOGLE_CLIENT_ID}', + clientSecret: '${GOOGLE_CLIENT_SECRET}', + authorizationUrl: 'https://accounts.google.com/o/oauth2/v2/auth', + tokenUrl: 'https://oauth2.googleapis.com/token', + grantType: 'authorization_code', + scopes: ['https://www.googleapis.com/auth/drive.file'], + }, + buckets: [ + { + name: 'team_drive', + label: 'Team Drive', + bucketName: 'shared-team-drive', + enabled: true, + fileFilters: { + excludePatterns: ['*.tmp', '~$*'], + }, + }, + ], + metadataConfig: { + extractMetadata: true, + metadataFields: ['content_type', 'file_size', 'last_modified', 'creator', 'created_at'], + }, + versioningConfig: { + enabled: true, + maxVersions: 5, + }, + syncConfig: { + strategy: 'incremental', + direction: 'bidirectional', + realtimeSync: true, + conflictResolution: 'latest_wins', + batchSize: 50, + }, + status: 'active', + enabled: true, +}; + +/** + * Example: Azure Blob Storage Connector Configuration + */ +export const azureBlobConnectorExample: FileStorageConnector = { + name: 'azure_blob_storage', + label: 'Azure Blob Storage', + type: 'file_storage', + provider: 'azure_blob', + authentication: { + type: 'api_key', + apiKey: '${AZURE_STORAGE_ACCOUNT_KEY}', + headerName: 'x-ms-blob-type', + }, + storageConfig: { + endpoint: 'https://myaccount.blob.core.windows.net', + }, + buckets: [ + { + name: 'archive_container', + label: 'Archive Container', + bucketName: 'archive', + enabled: true, + accessPattern: 'private', + }, + ], + metadataConfig: { + extractMetadata: true, + metadataFields: ['content_type', 'file_size', 'last_modified', 'etag'], + }, + encryption: { + enabled: true, + algorithm: 'AES256', + }, + lifecyclePolicy: { + enabled: true, + archiveAfterDays: 90, + deleteAfterDays: 365, + }, + syncConfig: { + strategy: 'incremental', + direction: 'import', + schedule: '0 1 * * *', // Daily at 1 AM + batchSize: 200, + }, + status: 'active', + enabled: true, +}; diff --git a/packages/spec/src/system/connector/message-queue.zod.ts b/packages/spec/src/system/connector/message-queue.zod.ts new file mode 100644 index 000000000..889e20bc8 --- /dev/null +++ b/packages/spec/src/system/connector/message-queue.zod.ts @@ -0,0 +1,499 @@ +import { z } from 'zod'; +import { + ConnectorSchema, + DataSyncConfigSchema, +} from '../connector.zod'; + +/** + * Message Queue Connector Protocol Template + * + * Specialized connector for message queue systems (RabbitMQ, Kafka, SQS, etc.) + * Extends the base connector with message queue-specific features like topics, + * consumer groups, and message acknowledgment patterns. + */ + +/** + * Message Queue Provider Types + */ +export const MessageQueueProviderSchema = z.enum([ + 'rabbitmq', // RabbitMQ + 'kafka', // Apache Kafka + 'redis_pubsub', // Redis Pub/Sub + 'redis_streams', // Redis Streams + 'aws_sqs', // Amazon SQS + 'aws_sns', // Amazon SNS + 'google_pubsub', // Google Cloud Pub/Sub + 'azure_service_bus', // Azure Service Bus + 'azure_event_hubs', // Azure Event Hubs + 'nats', // NATS + 'pulsar', // Apache Pulsar + 'activemq', // Apache ActiveMQ + 'custom', // Custom message queue +]).describe('Message queue provider type'); + +export type MessageQueueProvider = z.infer; + +/** + * Message Format + */ +export const MessageFormatSchema = z.enum([ + 'json', + 'xml', + 'protobuf', + 'avro', + 'text', + 'binary', +]).describe('Message format/serialization'); + +export type MessageFormat = z.infer; + +/** + * Message Acknowledgment Mode + */ +export const AckModeSchema = z.enum([ + 'auto', // Auto-acknowledge + 'manual', // Manual acknowledge after processing + 'client', // Client-controlled acknowledge +]).describe('Message acknowledgment mode'); + +export type AckMode = z.infer; + +/** + * Delivery Guarantee + */ +export const DeliveryGuaranteeSchema = z.enum([ + 'at_most_once', // Fire and forget + 'at_least_once', // May deliver duplicates + 'exactly_once', // Guaranteed exactly once delivery +]).describe('Message delivery guarantee'); + +export type DeliveryGuarantee = z.infer; + +/** + * Consumer Configuration + */ +export const ConsumerConfigSchema = z.object({ + enabled: z.boolean().default(true).describe('Enable consumer'), + + consumerGroup: z.string().optional().describe('Consumer group ID'), + + concurrency: z.number().min(1).max(100).default(1).describe('Number of concurrent consumers'), + + prefetchCount: z.number().min(1).max(1000).default(10).describe('Prefetch count'), + + ackMode: AckModeSchema.default('manual'), + + autoCommit: z.boolean().default(false).describe('Auto-commit offsets'), + + autoCommitIntervalMs: z.number().min(100).default(5000).describe('Auto-commit interval in ms'), + + sessionTimeoutMs: z.number().min(1000).default(30000).describe('Session timeout in ms'), + + rebalanceTimeoutMs: z.number().min(1000).optional().describe('Rebalance timeout in ms'), +}); + +export type ConsumerConfig = z.infer; + +/** + * Producer Configuration + */ +export const ProducerConfigSchema = z.object({ + enabled: z.boolean().default(true).describe('Enable producer'), + + acks: z.enum(['0', '1', 'all']).default('all').describe('Acknowledgment level'), + + compressionType: z.enum(['none', 'gzip', 'snappy', 'lz4', 'zstd']).default('none').describe('Compression type'), + + batchSize: z.number().min(1).default(16384).describe('Batch size in bytes'), + + lingerMs: z.number().min(0).default(0).describe('Linger time in ms'), + + maxInFlightRequests: z.number().min(1).default(5).describe('Max in-flight requests'), + + idempotence: z.boolean().default(true).describe('Enable idempotent producer'), + + transactional: z.boolean().default(false).describe('Enable transactional producer'), + + transactionTimeoutMs: z.number().min(1000).optional().describe('Transaction timeout in ms'), +}); + +export type ProducerConfig = z.infer; + +/** + * Dead Letter Queue Configuration + */ +export const DlqConfigSchema = z.object({ + enabled: z.boolean().default(false).describe('Enable DLQ'), + + queueName: z.string().describe('Dead letter queue/topic name'), + + maxRetries: z.number().min(0).max(100).default(3).describe('Max retries before DLQ'), + + retryDelayMs: z.number().min(0).default(60000).describe('Retry delay in ms'), +}); + +export type DlqConfig = z.infer; + +/** + * Topic/Queue Configuration + */ +export const TopicQueueSchema = z.object({ + name: z.string().regex(/^[a-z_][a-z0-9_]*$/).describe('Topic/queue identifier in ObjectStack (snake_case)'), + label: z.string().describe('Display label'), + topicName: z.string().describe('Actual topic/queue name in message queue system'), + enabled: z.boolean().default(true).describe('Enable sync for this topic/queue'), + + /** + * Consumer or Producer + */ + mode: z.enum(['consumer', 'producer', 'both']).default('both').describe('Consumer, producer, or both'), + + /** + * Message format + */ + messageFormat: MessageFormatSchema.default('json'), + + /** + * Partition/shard configuration + */ + partitions: z.number().min(1).optional().describe('Number of partitions (for Kafka)'), + + /** + * Replication factor + */ + replicationFactor: z.number().min(1).optional().describe('Replication factor (for Kafka)'), + + /** + * Consumer configuration + */ + consumerConfig: ConsumerConfigSchema.optional().describe('Consumer-specific configuration'), + + /** + * Producer configuration + */ + producerConfig: ProducerConfigSchema.optional().describe('Producer-specific configuration'), + + /** + * Dead letter queue configuration + */ + dlqConfig: DlqConfigSchema.optional().describe('Dead letter queue configuration'), + + /** + * Message routing key (for RabbitMQ) + */ + routingKey: z.string().optional().describe('Routing key pattern'), + + /** + * Message filter + */ + messageFilter: z.object({ + headers: z.record(z.string()).optional().describe('Filter by message headers'), + attributes: z.record(z.any()).optional().describe('Filter by message attributes'), + }).optional().describe('Message filter criteria'), +}); + +export type TopicQueue = z.infer; + +/** + * Message Queue Connector Configuration Schema + */ +export const MessageQueueConnectorSchema = ConnectorSchema.extend({ + type: z.literal('message_queue'), + + /** + * Message queue provider + */ + provider: MessageQueueProviderSchema.describe('Message queue provider type'), + + /** + * Broker configuration + */ + brokerConfig: z.object({ + brokers: z.array(z.string()).describe('Broker addresses (host:port)'), + clientId: z.string().optional().describe('Client ID'), + connectionTimeoutMs: z.number().min(1000).default(30000).describe('Connection timeout in ms'), + requestTimeoutMs: z.number().min(1000).default(30000).describe('Request timeout in ms'), + }).describe('Broker connection configuration'), + + /** + * Topics/queues to sync + */ + topics: z.array(TopicQueueSchema).describe('Topics/queues to sync'), + + /** + * Delivery guarantee + */ + deliveryGuarantee: DeliveryGuaranteeSchema.default('at_least_once'), + + /** + * SSL/TLS configuration + */ + sslConfig: z.object({ + enabled: z.boolean().default(false).describe('Enable SSL/TLS'), + rejectUnauthorized: z.boolean().default(true).describe('Reject unauthorized certificates'), + ca: z.string().optional().describe('CA certificate'), + cert: z.string().optional().describe('Client certificate'), + key: z.string().optional().describe('Client private key'), + }).optional().describe('SSL/TLS configuration'), + + /** + * SASL authentication (for Kafka) + */ + saslConfig: z.object({ + mechanism: z.enum(['plain', 'scram-sha-256', 'scram-sha-512', 'aws']).describe('SASL mechanism'), + username: z.string().optional().describe('SASL username'), + password: z.string().optional().describe('SASL password'), + }).optional().describe('SASL authentication configuration'), + + /** + * Schema registry configuration (for Kafka/Avro) + */ + schemaRegistry: z.object({ + url: z.string().url().describe('Schema registry URL'), + auth: z.object({ + username: z.string().optional(), + password: z.string().optional(), + }).optional(), + }).optional().describe('Schema registry configuration'), + + /** + * Message ordering + */ + preserveOrder: z.boolean().default(true).describe('Preserve message ordering'), + + /** + * Enable metrics + */ + enableMetrics: z.boolean().default(true).describe('Enable message queue metrics'), + + /** + * Enable distributed tracing + */ + enableTracing: z.boolean().default(false).describe('Enable distributed tracing'), +}); + +export type MessageQueueConnector = z.infer; + +// ============================================================================ +// Helper Functions & Examples +// ============================================================================ + +/** + * Example: Apache Kafka Connector Configuration + */ +export const kafkaConnectorExample: MessageQueueConnector = { + name: 'kafka_production', + label: 'Production Kafka Cluster', + type: 'message_queue', + provider: 'kafka', + authentication: { + type: 'none', + }, + brokerConfig: { + brokers: ['kafka-1.example.com:9092', 'kafka-2.example.com:9092', 'kafka-3.example.com:9092'], + clientId: 'objectstack-client', + connectionTimeoutMs: 30000, + requestTimeoutMs: 30000, + }, + topics: [ + { + name: 'order_events', + label: 'Order Events', + topicName: 'orders', + enabled: true, + mode: 'consumer', + messageFormat: 'json', + partitions: 10, + replicationFactor: 3, + consumerConfig: { + enabled: true, + consumerGroup: 'objectstack-consumer-group', + concurrency: 5, + prefetchCount: 100, + ackMode: 'manual', + autoCommit: false, + sessionTimeoutMs: 30000, + }, + dlqConfig: { + enabled: true, + queueName: 'orders-dlq', + maxRetries: 3, + retryDelayMs: 60000, + }, + }, + { + name: 'user_activity', + label: 'User Activity', + topicName: 'user-activity', + enabled: true, + mode: 'producer', + messageFormat: 'json', + partitions: 5, + replicationFactor: 3, + producerConfig: { + enabled: true, + acks: 'all', + compressionType: 'snappy', + batchSize: 16384, + lingerMs: 10, + maxInFlightRequests: 5, + idempotence: true, + }, + }, + ], + deliveryGuarantee: 'at_least_once', + saslConfig: { + mechanism: 'scram-sha-256', + username: '${KAFKA_USERNAME}', + password: '${KAFKA_PASSWORD}', + }, + sslConfig: { + enabled: true, + rejectUnauthorized: true, + }, + preserveOrder: true, + enableMetrics: true, + enableTracing: true, + status: 'active', + enabled: true, +}; + +/** + * Example: RabbitMQ Connector Configuration + */ +export const rabbitmqConnectorExample: MessageQueueConnector = { + name: 'rabbitmq_events', + label: 'RabbitMQ Event Bus', + type: 'message_queue', + provider: 'rabbitmq', + authentication: { + type: 'basic', + username: '${RABBITMQ_USERNAME}', + password: '${RABBITMQ_PASSWORD}', + }, + brokerConfig: { + brokers: ['amqp://rabbitmq.example.com:5672'], + clientId: 'objectstack-rabbitmq-client', + }, + topics: [ + { + name: 'notifications', + label: 'Notifications', + topicName: 'notifications', + enabled: true, + mode: 'both', + messageFormat: 'json', + routingKey: 'notification.*', + consumerConfig: { + enabled: true, + prefetchCount: 10, + ackMode: 'manual', + }, + producerConfig: { + enabled: true, + }, + dlqConfig: { + enabled: true, + queueName: 'notifications-dlq', + maxRetries: 3, + retryDelayMs: 30000, + }, + }, + ], + deliveryGuarantee: 'at_least_once', + status: 'active', + enabled: true, +}; + +/** + * Example: AWS SQS Connector Configuration + */ +export const sqsConnectorExample: MessageQueueConnector = { + name: 'aws_sqs_queue', + label: 'AWS SQS Queue', + type: 'message_queue', + provider: 'aws_sqs', + authentication: { + type: 'api_key', + apiKey: '${AWS_ACCESS_KEY_ID}:${AWS_SECRET_ACCESS_KEY}', + headerName: 'Authorization', + }, + brokerConfig: { + brokers: ['https://sqs.us-east-1.amazonaws.com'], + }, + topics: [ + { + name: 'task_queue', + label: 'Task Queue', + topicName: 'task-queue', + enabled: true, + mode: 'consumer', + messageFormat: 'json', + consumerConfig: { + enabled: true, + concurrency: 10, + prefetchCount: 10, + ackMode: 'manual', + }, + dlqConfig: { + enabled: true, + queueName: 'task-queue-dlq', + maxRetries: 3, + retryDelayMs: 120000, + }, + }, + ], + deliveryGuarantee: 'at_least_once', + retryConfig: { + strategy: 'exponential_backoff', + maxAttempts: 3, + initialDelayMs: 1000, + maxDelayMs: 60000, + backoffMultiplier: 2, + }, + status: 'active', + enabled: true, +}; + +/** + * Example: Google Cloud Pub/Sub Connector Configuration + */ +export const pubsubConnectorExample: MessageQueueConnector = { + name: 'gcp_pubsub', + label: 'Google Cloud Pub/Sub', + type: 'message_queue', + provider: 'google_pubsub', + authentication: { + type: 'oauth2', + clientId: '${GCP_CLIENT_ID}', + clientSecret: '${GCP_CLIENT_SECRET}', + authorizationUrl: 'https://accounts.google.com/o/oauth2/v2/auth', + tokenUrl: 'https://oauth2.googleapis.com/token', + grantType: 'client_credentials', + scopes: ['https://www.googleapis.com/auth/pubsub'], + }, + brokerConfig: { + brokers: ['pubsub.googleapis.com'], + }, + topics: [ + { + name: 'analytics_events', + label: 'Analytics Events', + topicName: 'projects/my-project/topics/analytics-events', + enabled: true, + mode: 'both', + messageFormat: 'json', + consumerConfig: { + enabled: true, + consumerGroup: 'objectstack-subscription', + concurrency: 5, + prefetchCount: 100, + ackMode: 'manual', + }, + }, + ], + deliveryGuarantee: 'at_least_once', + enableMetrics: true, + status: 'active', + enabled: true, +}; diff --git a/packages/spec/src/system/connector/saas.zod.ts b/packages/spec/src/system/connector/saas.zod.ts new file mode 100644 index 000000000..7de5610c4 --- /dev/null +++ b/packages/spec/src/system/connector/saas.zod.ts @@ -0,0 +1,253 @@ +import { z } from 'zod'; +import { + ConnectorSchema, + AuthenticationSchema, + DataSyncConfigSchema, + FieldMappingSchema, + WebhookConfigSchema, + RateLimitConfigSchema, + RetryConfigSchema, +} from '../connector.zod'; + +/** + * SaaS Connector Protocol Template + * + * Specialized connector for SaaS applications (Salesforce, HubSpot, Stripe, etc.) + * Extends the base connector with SaaS-specific features like OAuth flows, + * object type discovery, and API version management. + */ + +/** + * SaaS Provider Types + */ +export const SaasProviderSchema = z.enum([ + 'salesforce', + 'hubspot', + 'stripe', + 'shopify', + 'zendesk', + 'intercom', + 'mailchimp', + 'slack', + 'microsoft_dynamics', + 'servicenow', + 'netsuite', + 'custom', +]).describe('SaaS provider type'); + +export type SaasProvider = z.infer; + +/** + * API Version Configuration + */ +export const ApiVersionConfigSchema = z.object({ + version: z.string().describe('API version (e.g., "v2", "2023-10-01")'), + isDefault: z.boolean().default(false).describe('Is this the default version'), + deprecationDate: z.string().optional().describe('API version deprecation date (ISO 8601)'), + sunsetDate: z.string().optional().describe('API version sunset date (ISO 8601)'), +}); + +export type ApiVersionConfig = z.infer; + +/** + * SaaS Object Type Schema + * Represents a syncable entity in the SaaS system (e.g., Account, Contact, Deal) + */ +export const SaasObjectTypeSchema = z.object({ + name: z.string().regex(/^[a-z_][a-z0-9_]*$/).describe('Object type name (snake_case)'), + label: z.string().describe('Display label'), + apiName: z.string().describe('API name in external system'), + enabled: z.boolean().default(true).describe('Enable sync for this object'), + supportsCreate: z.boolean().default(true).describe('Supports record creation'), + supportsUpdate: z.boolean().default(true).describe('Supports record updates'), + supportsDelete: z.boolean().default(true).describe('Supports record deletion'), + fieldMappings: z.array(FieldMappingSchema).optional().describe('Object-specific field mappings'), +}); + +export type SaasObjectType = z.infer; + +/** + * SaaS Connector Configuration Schema + */ +export const SaasConnectorSchema = ConnectorSchema.extend({ + type: z.literal('saas'), + + /** + * SaaS provider + */ + provider: SaasProviderSchema.describe('SaaS provider type'), + + /** + * Base URL for API requests + */ + baseUrl: z.string().url().describe('API base URL'), + + /** + * API version configuration + */ + apiVersion: ApiVersionConfigSchema.optional().describe('API version configuration'), + + /** + * Supported object types to sync + */ + objectTypes: z.array(SaasObjectTypeSchema).describe('Syncable object types'), + + /** + * OAuth-specific settings + */ + oauthSettings: z.object({ + scopes: z.array(z.string()).describe('Required OAuth scopes'), + refreshTokenUrl: z.string().url().optional().describe('Token refresh endpoint'), + revokeTokenUrl: z.string().url().optional().describe('Token revocation endpoint'), + autoRefresh: z.boolean().default(true).describe('Automatically refresh expired tokens'), + }).optional().describe('OAuth-specific configuration'), + + /** + * Pagination settings + */ + paginationConfig: z.object({ + type: z.enum(['cursor', 'offset', 'page']).default('cursor').describe('Pagination type'), + defaultPageSize: z.number().min(1).max(1000).default(100).describe('Default page size'), + maxPageSize: z.number().min(1).max(10000).default(1000).describe('Maximum page size'), + }).optional().describe('Pagination configuration'), + + /** + * Sandbox/test environment settings + */ + sandboxConfig: z.object({ + enabled: z.boolean().default(false).describe('Use sandbox environment'), + baseUrl: z.string().url().optional().describe('Sandbox API base URL'), + }).optional().describe('Sandbox environment configuration'), + + /** + * Custom request headers + */ + customHeaders: z.record(z.string()).optional().describe('Custom HTTP headers for all requests'), +}); + +export type SaasConnector = z.infer; + +// ============================================================================ +// Helper Functions & Examples +// ============================================================================ + +/** + * Example: Salesforce Connector Configuration + */ +export const salesforceConnectorExample: SaasConnector = { + name: 'salesforce_production', + label: 'Salesforce Production', + type: 'saas', + provider: 'salesforce', + baseUrl: 'https://example.my.salesforce.com', + apiVersion: { + version: 'v59.0', + isDefault: true, + }, + authentication: { + type: 'oauth2', + clientId: '${SALESFORCE_CLIENT_ID}', + clientSecret: '${SALESFORCE_CLIENT_SECRET}', + authorizationUrl: 'https://login.salesforce.com/services/oauth2/authorize', + tokenUrl: 'https://login.salesforce.com/services/oauth2/token', + grantType: 'authorization_code', + scopes: ['api', 'refresh_token', 'offline_access'], + }, + objectTypes: [ + { + name: 'account', + label: 'Account', + apiName: 'Account', + enabled: true, + supportsCreate: true, + supportsUpdate: true, + supportsDelete: true, + }, + { + name: 'contact', + label: 'Contact', + apiName: 'Contact', + enabled: true, + supportsCreate: true, + supportsUpdate: true, + supportsDelete: true, + }, + ], + syncConfig: { + strategy: 'incremental', + direction: 'bidirectional', + schedule: '0 */6 * * *', // Every 6 hours + realtimeSync: true, + conflictResolution: 'latest_wins', + batchSize: 200, + deleteMode: 'soft_delete', + }, + rateLimitConfig: { + strategy: 'token_bucket', + maxRequests: 100, + windowSeconds: 20, + respectUpstreamLimits: true, + }, + retryConfig: { + strategy: 'exponential_backoff', + maxAttempts: 3, + initialDelayMs: 1000, + maxDelayMs: 30000, + backoffMultiplier: 2, + retryableStatusCodes: [408, 429, 500, 502, 503, 504], + retryOnNetworkError: true, + jitter: true, + }, + status: 'active', + enabled: true, +}; + +/** + * Example: HubSpot Connector Configuration + */ +export const hubspotConnectorExample: SaasConnector = { + name: 'hubspot_crm', + label: 'HubSpot CRM', + type: 'saas', + provider: 'hubspot', + baseUrl: 'https://api.hubapi.com', + authentication: { + type: 'api_key', + apiKey: '${HUBSPOT_API_KEY}', + headerName: 'Authorization', + }, + objectTypes: [ + { + name: 'company', + label: 'Company', + apiName: 'companies', + enabled: true, + supportsCreate: true, + supportsUpdate: true, + supportsDelete: true, + }, + { + name: 'deal', + label: 'Deal', + apiName: 'deals', + enabled: true, + supportsCreate: true, + supportsUpdate: true, + supportsDelete: true, + }, + ], + syncConfig: { + strategy: 'incremental', + direction: 'import', + schedule: '0 */4 * * *', // Every 4 hours + conflictResolution: 'source_wins', + batchSize: 100, + }, + rateLimitConfig: { + strategy: 'token_bucket', + maxRequests: 100, + windowSeconds: 10, + }, + status: 'active', + enabled: true, +}; diff --git a/packages/spec/src/system/index.ts b/packages/spec/src/system/index.ts index e1cc8f019..5c05903cc 100644 --- a/packages/spec/src/system/index.ts +++ b/packages/spec/src/system/index.ts @@ -32,5 +32,12 @@ export * from './driver/postgres.zod'; // Data Engine Protocol export * from './data-engine.zod'; +// Connector Protocol +export * from './connector.zod'; +export * from './connector/saas.zod'; +export * from './connector/database.zod'; +export * from './connector/file-storage.zod'; +export * from './connector/message-queue.zod'; + // Note: Auth, Identity, Policy, Role, Organization moved to @objectstack/spec/auth // Note: Territory moved to @objectstack/spec/permission From 82522e9ede9e08342260f295be496182d1513a24 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 08:13:37 +0000 Subject: [PATCH 3/4] Fix Zod schema defaults and TypeScript compilation issues Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- content/docs/references/auth/config.mdx | 18 +- content/docs/references/auth/connector.mdx | 35 + .../docs/references/automation/connector.mdx | 58 +- .../docs/references/automation/mapping.mdx | 35 - content/docs/references/automation/sync.mdx | 46 +- content/docs/references/system/connector.mdx | 355 +++++ content/docs/references/system/index.mdx | 1 + content/docs/references/system/meta.json | 1 + content/docs/references/system/misc.mdx | 514 +++++++- packages/spec/json-schema/system/AckMode.json | 15 + .../spec/json-schema/system/ApiKeyAuth.json | 34 + .../json-schema/system/ApiVersionConfig.json | 32 + .../json-schema/system/Authentication.json | 280 ++++ .../spec/json-schema/system/BasicAuth.json | 30 + .../json-schema/system/BearerTokenAuth.json | 25 + .../spec/json-schema/system/CdcConfig.json | 55 + .../system/ConflictResolution.json | 16 + .../spec/json-schema/system/Connector.json | 744 +++++++++++ .../json-schema/system/ConnectorStatus.json | 16 + .../json-schema/system/ConnectorType.json | 18 + .../json-schema/system/ConsumerConfig.json | 67 + .../json-schema/system/DataSyncConfig.json | 79 ++ .../json-schema/system/DatabaseConnector.json | 1114 ++++++++++++++++ .../system/DatabasePoolConfig.json | 53 + .../json-schema/system/DatabaseProvider.json | 24 + .../json-schema/system/DatabaseTable.json | 133 ++ .../json-schema/system/DeliveryGuarantee.json | 15 + .../spec/json-schema/system/DlqConfig.json | 37 + .../spec/json-schema/system/FieldMapping.json | 87 ++ .../json-schema/system/FieldTransform.json | 36 + .../json-schema/system/FileAccessPattern.json | 17 + .../json-schema/system/FileFilterConfig.json | 50 + .../system/FileMetadataConfig.json | 41 + .../system/FileStorageConnector.json | 1065 +++++++++++++++ .../system/FileStorageProvider.json | 23 + .../system/FileVersioningConfig.json | 28 + packages/spec/json-schema/system/JwtAuth.json | 66 + .../json-schema/system/MessageFormat.json | 18 + .../system/MessageQueueConnector.json | 1150 +++++++++++++++++ .../system/MessageQueueProvider.json | 25 + .../system/MultipartUploadConfig.json | 36 + packages/spec/json-schema/system/NoAuth.json | 20 + .../spec/json-schema/system/OAuth2Auth.json | 73 ++ .../json-schema/system/ProducerConfig.json | 72 ++ .../json-schema/system/RateLimitConfig.json | 69 + .../json-schema/system/RateLimitStrategy.json | 16 + .../spec/json-schema/system/RetryConfig.json | 73 ++ .../json-schema/system/RetryStrategy.json | 16 + .../json-schema/system/SaasConnector.json | 1009 +++++++++++++++ .../json-schema/system/SaasObjectType.json | 135 ++ .../spec/json-schema/system/SaasProvider.json | 24 + .../spec/json-schema/system/SamlAuth.json | 64 + .../spec/json-schema/system/SslConfig.json | 34 + .../json-schema/system/StorageBucket.json | 99 ++ .../spec/json-schema/system/SyncStrategy.json | 16 + .../spec/json-schema/system/TopicQueue.json | 252 ++++ .../json-schema/system/WebhookConfig.json | 98 ++ .../spec/json-schema/system/WebhookEvent.json | 20 + .../system/WebhookSignatureAlgorithm.json | 15 + packages/spec/src/system/connector.zod.ts | 71 +- .../spec/src/system/connector/database.zod.ts | 11 +- .../src/system/connector/file-storage.zod.ts | 9 +- .../src/system/connector/message-queue.zod.ts | 67 +- .../spec/src/system/connector/saas.zod.ts | 9 +- 64 files changed, 8571 insertions(+), 193 deletions(-) create mode 100644 content/docs/references/auth/connector.mdx delete mode 100644 content/docs/references/automation/mapping.mdx create mode 100644 content/docs/references/system/connector.mdx create mode 100644 packages/spec/json-schema/system/AckMode.json create mode 100644 packages/spec/json-schema/system/ApiKeyAuth.json create mode 100644 packages/spec/json-schema/system/ApiVersionConfig.json create mode 100644 packages/spec/json-schema/system/Authentication.json create mode 100644 packages/spec/json-schema/system/BasicAuth.json create mode 100644 packages/spec/json-schema/system/BearerTokenAuth.json create mode 100644 packages/spec/json-schema/system/CdcConfig.json create mode 100644 packages/spec/json-schema/system/ConflictResolution.json create mode 100644 packages/spec/json-schema/system/Connector.json create mode 100644 packages/spec/json-schema/system/ConnectorStatus.json create mode 100644 packages/spec/json-schema/system/ConnectorType.json create mode 100644 packages/spec/json-schema/system/ConsumerConfig.json create mode 100644 packages/spec/json-schema/system/DataSyncConfig.json create mode 100644 packages/spec/json-schema/system/DatabaseConnector.json create mode 100644 packages/spec/json-schema/system/DatabasePoolConfig.json create mode 100644 packages/spec/json-schema/system/DatabaseProvider.json create mode 100644 packages/spec/json-schema/system/DatabaseTable.json create mode 100644 packages/spec/json-schema/system/DeliveryGuarantee.json create mode 100644 packages/spec/json-schema/system/DlqConfig.json create mode 100644 packages/spec/json-schema/system/FieldMapping.json create mode 100644 packages/spec/json-schema/system/FieldTransform.json create mode 100644 packages/spec/json-schema/system/FileAccessPattern.json create mode 100644 packages/spec/json-schema/system/FileFilterConfig.json create mode 100644 packages/spec/json-schema/system/FileMetadataConfig.json create mode 100644 packages/spec/json-schema/system/FileStorageConnector.json create mode 100644 packages/spec/json-schema/system/FileStorageProvider.json create mode 100644 packages/spec/json-schema/system/FileVersioningConfig.json create mode 100644 packages/spec/json-schema/system/JwtAuth.json create mode 100644 packages/spec/json-schema/system/MessageFormat.json create mode 100644 packages/spec/json-schema/system/MessageQueueConnector.json create mode 100644 packages/spec/json-schema/system/MessageQueueProvider.json create mode 100644 packages/spec/json-schema/system/MultipartUploadConfig.json create mode 100644 packages/spec/json-schema/system/NoAuth.json create mode 100644 packages/spec/json-schema/system/OAuth2Auth.json create mode 100644 packages/spec/json-schema/system/ProducerConfig.json create mode 100644 packages/spec/json-schema/system/RateLimitConfig.json create mode 100644 packages/spec/json-schema/system/RateLimitStrategy.json create mode 100644 packages/spec/json-schema/system/RetryConfig.json create mode 100644 packages/spec/json-schema/system/RetryStrategy.json create mode 100644 packages/spec/json-schema/system/SaasConnector.json create mode 100644 packages/spec/json-schema/system/SaasObjectType.json create mode 100644 packages/spec/json-schema/system/SaasProvider.json create mode 100644 packages/spec/json-schema/system/SamlAuth.json create mode 100644 packages/spec/json-schema/system/SslConfig.json create mode 100644 packages/spec/json-schema/system/StorageBucket.json create mode 100644 packages/spec/json-schema/system/SyncStrategy.json create mode 100644 packages/spec/json-schema/system/TopicQueue.json create mode 100644 packages/spec/json-schema/system/WebhookConfig.json create mode 100644 packages/spec/json-schema/system/WebhookEvent.json create mode 100644 packages/spec/json-schema/system/WebhookSignatureAlgorithm.json diff --git a/content/docs/references/auth/config.mdx b/content/docs/references/auth/config.mdx index f78bdb912..a5268eb2d 100644 --- a/content/docs/references/auth/config.mdx +++ b/content/docs/references/auth/config.mdx @@ -12,8 +12,8 @@ description: Config protocol schemas ## TypeScript Usage ```typescript -import { AccountLinkingConfigSchema, AuthConfigSchema, AuthPluginConfigSchema, AuthStrategySchema, CSRFConfigSchema, DatabaseAdapterSchema, DatabaseMappingSchema, EmailPasswordConfigSchema, EnterpriseAuthConfigSchema, LDAPConfigSchema, MagicLinkConfigSchema, OAuthProviderSchema, OIDCConfigSchema, PasskeyConfigSchema, RateLimitConfigSchema, SAMLConfigSchema, SessionConfigSchema, StandardAuthProviderSchema, TwoFactorConfigSchema, UserFieldMappingSchema } from '@objectstack/spec/auth'; -import type { AccountLinkingConfig, AuthConfig, AuthPluginConfig, AuthStrategy, CSRFConfig, DatabaseAdapter, DatabaseMapping, EmailPasswordConfig, EnterpriseAuthConfig, LDAPConfig, MagicLinkConfig, OAuthProvider, OIDCConfig, PasskeyConfig, RateLimitConfig, SAMLConfig, SessionConfig, StandardAuthProvider, TwoFactorConfig, UserFieldMapping } from '@objectstack/spec/auth'; +import { AccountLinkingConfigSchema, AuthConfigSchema, AuthPluginConfigSchema, AuthStrategySchema, CSRFConfigSchema, DatabaseAdapterSchema, DatabaseMappingSchema, EmailPasswordConfigSchema, EnterpriseAuthConfigSchema, LDAPConfigSchema, MagicLinkConfigSchema, OAuthProviderSchema, OIDCConfigSchema, PasskeyConfigSchema, SAMLConfigSchema, SessionConfigSchema, StandardAuthProviderSchema, TwoFactorConfigSchema, UserFieldMappingSchema } from '@objectstack/spec/auth'; +import type { AccountLinkingConfig, AuthConfig, AuthPluginConfig, AuthStrategy, CSRFConfig, DatabaseAdapter, DatabaseMapping, EmailPasswordConfig, EnterpriseAuthConfig, LDAPConfig, MagicLinkConfig, OAuthProvider, OIDCConfig, PasskeyConfig, SAMLConfig, SessionConfig, StandardAuthProvider, TwoFactorConfig, UserFieldMapping } from '@objectstack/spec/auth'; // Validate data const result = AccountLinkingConfigSchema.parse(data); @@ -238,20 +238,6 @@ const result = AccountLinkingConfigSchema.parse(data); --- -## RateLimitConfig - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **enabled** | `boolean` | optional | | -| **maxAttempts** | `number` | optional | Maximum login attempts | -| **windowMs** | `number` | optional | Time window in milliseconds (default 15 min) | -| **blockDuration** | `number` | optional | Block duration after max attempts in ms | -| **skipSuccessfulRequests** | `boolean` | optional | Only count failed requests | - ---- - ## SAMLConfig ### Properties diff --git a/content/docs/references/auth/connector.mdx b/content/docs/references/auth/connector.mdx new file mode 100644 index 000000000..91607ac82 --- /dev/null +++ b/content/docs/references/auth/connector.mdx @@ -0,0 +1,35 @@ +--- +title: Connector +description: Connector protocol schemas +--- + +# Connector + + +**Source:** `packages/spec/src/auth/connector.zod.ts` + + +## TypeScript Usage + +```typescript +import { RateLimitConfigSchema } from '@objectstack/spec/auth'; +import type { RateLimitConfig } from '@objectstack/spec/auth'; + +// Validate data +const result = RateLimitConfigSchema.parse(data); +``` + +--- + +## RateLimitConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **enabled** | `boolean` | optional | | +| **maxAttempts** | `number` | optional | Maximum login attempts | +| **windowMs** | `number` | optional | Time window in milliseconds (default 15 min) | +| **blockDuration** | `number` | optional | Block duration after max attempts in ms | +| **skipSuccessfulRequests** | `boolean` | optional | Only count failed requests | + diff --git a/content/docs/references/automation/connector.mdx b/content/docs/references/automation/connector.mdx index a0363065b..7b9e0dfb6 100644 --- a/content/docs/references/automation/connector.mdx +++ b/content/docs/references/automation/connector.mdx @@ -12,8 +12,8 @@ description: Connector protocol schemas ## TypeScript Usage ```typescript -import { AuthFieldSchema, AuthenticationSchema, AuthenticationTypeSchema, ConnectorSchema, ConnectorCategorySchema, ConnectorInstanceSchema, ConnectorOperationSchema, ConnectorTriggerSchema, OAuth2ConfigSchema, OperationParameterSchema, OperationTypeSchema } from '@objectstack/spec/automation'; -import type { AuthField, Authentication, AuthenticationType, Connector, ConnectorCategory, ConnectorInstance, ConnectorOperation, ConnectorTrigger, OAuth2Config, OperationParameter, OperationType } from '@objectstack/spec/automation'; +import { AuthFieldSchema, AuthenticationSchema, AuthenticationTypeSchema, ConflictResolutionSchema, ConnectorSchema, ConnectorCategorySchema, ConnectorInstanceSchema, ConnectorOperationSchema, ConnectorTriggerSchema, DataSyncConfigSchema, FieldMappingSchema, OAuth2ConfigSchema, OperationParameterSchema, OperationTypeSchema } from '@objectstack/spec/automation'; +import type { AuthField, Authentication, AuthenticationType, ConflictResolution, Connector, ConnectorCategory, ConnectorInstance, ConnectorOperation, ConnectorTrigger, DataSyncConfig, FieldMapping, OAuth2Config, OperationParameter, OperationType } from '@objectstack/spec/automation'; // Validate data const result = AuthFieldSchema.parse(data); @@ -65,6 +65,18 @@ const result = AuthFieldSchema.parse(data); --- +## ConflictResolution + +### Allowed Values + +* `source_wins` +* `destination_wins` +* `latest_wins` +* `manual` +* `merge` + +--- + ## Connector ### Properties @@ -167,6 +179,48 @@ const result = AuthFieldSchema.parse(data); --- +## DataSyncConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Sync configuration name (snake_case) | +| **label** | `string` | optional | Sync display name | +| **description** | `string` | optional | Sync description | +| **source** | `object` | ✅ | Data source | +| **destination** | `object` | ✅ | Data destination | +| **direction** | `Enum<'push' \| 'pull' \| 'bidirectional'>` | optional | Sync direction | +| **syncMode** | `Enum<'full' \| 'incremental' \| 'realtime'>` | optional | Sync mode | +| **conflictResolution** | `Enum<'source_wins' \| 'destination_wins' \| 'latest_wins' \| 'manual' \| 'merge'>` | optional | Conflict resolution | +| **schedule** | `string` | optional | Cron schedule | +| **enabled** | `boolean` | optional | Sync enabled | +| **changeTrackingField** | `string` | optional | Field for change tracking | +| **batchSize** | `integer` | optional | Batch size for processing | +| **retry** | `object` | optional | Retry configuration | +| **validation** | `object` | optional | Validation rules | +| **errorHandling** | `object` | optional | Error handling | +| **optimization** | `object` | optional | Performance optimization | +| **audit** | `object` | optional | Audit configuration | +| **tags** | `string[]` | optional | Sync tags | +| **metadata** | `Record` | optional | Custom metadata | + +--- + +## FieldMapping + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **sourceField** | `string` | ✅ | Source field name | +| **destinationField** | `string` | ✅ | Destination field name | +| **transform** | `string` | optional | Transformation formula | +| **default** | `any` | optional | Default value | +| **syncNull** | `boolean` | optional | Sync null values | + +--- + ## OAuth2Config ### Properties diff --git a/content/docs/references/automation/mapping.mdx b/content/docs/references/automation/mapping.mdx deleted file mode 100644 index b20c29daf..000000000 --- a/content/docs/references/automation/mapping.mdx +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Mapping -description: Mapping protocol schemas ---- - -# Mapping - - -**Source:** `packages/spec/src/automation/mapping.zod.ts` - - -## TypeScript Usage - -```typescript -import { FieldMappingSchema } from '@objectstack/spec/automation'; -import type { FieldMapping } from '@objectstack/spec/automation'; - -// Validate data -const result = FieldMappingSchema.parse(data); -``` - ---- - -## FieldMapping - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **sourceField** | `string` | ✅ | Source field name | -| **destinationField** | `string` | ✅ | Destination field name | -| **transform** | `string` | optional | Transformation formula | -| **default** | `any` | optional | Default value | -| **syncNull** | `boolean` | optional | Sync null values | - diff --git a/content/docs/references/automation/sync.mdx b/content/docs/references/automation/sync.mdx index 89a4a0762..6169fc73c 100644 --- a/content/docs/references/automation/sync.mdx +++ b/content/docs/references/automation/sync.mdx @@ -12,27 +12,15 @@ description: Sync protocol schemas ## TypeScript Usage ```typescript -import { ConflictResolutionSchema, DataDestinationConfigSchema, DataSourceConfigSchema, DataSyncConfigSchema, SyncDirectionSchema, SyncExecutionResultSchema, SyncExecutionStatusSchema, SyncModeSchema } from '@objectstack/spec/automation'; -import type { ConflictResolution, DataDestinationConfig, DataSourceConfig, DataSyncConfig, SyncDirection, SyncExecutionResult, SyncExecutionStatus, SyncMode } from '@objectstack/spec/automation'; +import { DataDestinationConfigSchema, DataSourceConfigSchema, SyncDirectionSchema, SyncExecutionResultSchema, SyncExecutionStatusSchema, SyncModeSchema } from '@objectstack/spec/automation'; +import type { DataDestinationConfig, DataSourceConfig, SyncDirection, SyncExecutionResult, SyncExecutionStatus, SyncMode } from '@objectstack/spec/automation'; // Validate data -const result = ConflictResolutionSchema.parse(data); +const result = DataDestinationConfigSchema.parse(data); ``` --- -## ConflictResolution - -### Allowed Values - -* `source_wins` -* `destination_wins` -* `latest_wins` -* `manual` -* `merge` - ---- - ## DataDestinationConfig ### Properties @@ -62,34 +50,6 @@ const result = ConflictResolutionSchema.parse(data); --- -## DataSyncConfig - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **name** | `string` | ✅ | Sync configuration name (snake_case) | -| **label** | `string` | optional | Sync display name | -| **description** | `string` | optional | Sync description | -| **source** | `object` | ✅ | Data source | -| **destination** | `object` | ✅ | Data destination | -| **direction** | `Enum<'push' \| 'pull' \| 'bidirectional'>` | optional | Sync direction | -| **syncMode** | `Enum<'full' \| 'incremental' \| 'realtime'>` | optional | Sync mode | -| **conflictResolution** | `Enum<'source_wins' \| 'destination_wins' \| 'latest_wins' \| 'manual' \| 'merge'>` | optional | Conflict resolution | -| **schedule** | `string` | optional | Cron schedule | -| **enabled** | `boolean` | optional | Sync enabled | -| **changeTrackingField** | `string` | optional | Field for change tracking | -| **batchSize** | `integer` | optional | Batch size for processing | -| **retry** | `object` | optional | Retry configuration | -| **validation** | `object` | optional | Validation rules | -| **errorHandling** | `object` | optional | Error handling | -| **optimization** | `object` | optional | Performance optimization | -| **audit** | `object` | optional | Audit configuration | -| **tags** | `string[]` | optional | Sync tags | -| **metadata** | `Record` | optional | Custom metadata | - ---- - ## SyncDirection ### Allowed Values diff --git a/content/docs/references/system/connector.mdx b/content/docs/references/system/connector.mdx new file mode 100644 index 000000000..43037d3f5 --- /dev/null +++ b/content/docs/references/system/connector.mdx @@ -0,0 +1,355 @@ +--- +title: Connector +description: Connector protocol schemas +--- + +# Connector + + +**Source:** `packages/spec/src/system/connector.zod.ts` + + +## TypeScript Usage + +```typescript +import { ApiKeyAuthSchema, AuthenticationSchema, BasicAuthSchema, BearerTokenAuthSchema, ConflictResolutionSchema, ConnectorSchema, ConnectorStatusSchema, ConnectorTypeSchema, DataSyncConfigSchema, FieldMappingSchema, FieldTransformSchema, JwtAuthSchema, NoAuthSchema, OAuth2AuthSchema, RateLimitConfigSchema, RateLimitStrategySchema, RetryConfigSchema, RetryStrategySchema, SamlAuthSchema, SyncStrategySchema, WebhookConfigSchema, WebhookEventSchema, WebhookSignatureAlgorithmSchema } from '@objectstack/spec/system'; +import type { ApiKeyAuth, Authentication, BasicAuth, BearerTokenAuth, ConflictResolution, Connector, ConnectorStatus, ConnectorType, DataSyncConfig, FieldMapping, FieldTransform, JwtAuth, NoAuth, OAuth2Auth, RateLimitConfig, RateLimitStrategy, RetryConfig, RetryStrategy, SamlAuth, SyncStrategy, WebhookConfig, WebhookEvent, WebhookSignatureAlgorithm } from '@objectstack/spec/system'; + +// Validate data +const result = ApiKeyAuthSchema.parse(data); +``` + +--- + +## ApiKeyAuth + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **type** | `string` | ✅ | Authentication type | +| **apiKey** | `string` | ✅ | API key (typically from ENV) | +| **headerName** | `string` | optional | HTTP header name for API key | +| **paramName** | `string` | optional | Query parameter name (alternative to header) | + +--- + +## Authentication + +--- + +## BasicAuth + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **type** | `string` | ✅ | Authentication type | +| **username** | `string` | ✅ | Username | +| **password** | `string` | ✅ | Password (typically from ENV) | + +--- + +## BearerTokenAuth + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **type** | `string` | ✅ | Authentication type | +| **token** | `string` | ✅ | Bearer token | + +--- + +## ConflictResolution + +Conflict resolution strategy + +### Allowed Values + +* `source_wins` +* `target_wins` +* `latest_wins` +* `manual` + +--- + +## Connector + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Unique connector identifier | +| **label** | `string` | ✅ | Display label | +| **type** | `Enum<'saas' \| 'database' \| 'file_storage' \| 'message_queue' \| 'api' \| 'custom'>` | ✅ | Connector type | +| **description** | `string` | optional | Connector description | +| **icon** | `string` | optional | Icon identifier | +| **authentication** | `object \| object \| object \| object \| object \| object \| object` | ✅ | Authentication configuration | +| **syncConfig** | `object` | optional | Data sync configuration | +| **fieldMappings** | `object[]` | optional | Field mapping rules | +| **webhooks** | `object[]` | optional | Webhook configurations | +| **rateLimitConfig** | `object` | optional | Rate limiting configuration | +| **retryConfig** | `object` | optional | Retry configuration | +| **connectionTimeoutMs** | `number` | optional | Connection timeout in ms | +| **requestTimeoutMs** | `number` | optional | Request timeout in ms | +| **status** | `Enum<'active' \| 'inactive' \| 'error' \| 'configuring'>` | optional | Connector status | +| **enabled** | `boolean` | optional | Enable connector | +| **metadata** | `Record` | optional | Custom connector metadata | + +--- + +## ConnectorStatus + +Connector status + +### Allowed Values + +* `active` +* `inactive` +* `error` +* `configuring` + +--- + +## ConnectorType + +Connector type + +### Allowed Values + +* `saas` +* `database` +* `file_storage` +* `message_queue` +* `api` +* `custom` + +--- + +## DataSyncConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **strategy** | `Enum<'full' \| 'incremental' \| 'upsert' \| 'append_only'>` | optional | Synchronization strategy | +| **direction** | `Enum<'import' \| 'export' \| 'bidirectional'>` | optional | Sync direction | +| **schedule** | `string` | optional | Cron expression for scheduled sync | +| **realtimeSync** | `boolean` | optional | Enable real-time sync | +| **timestampField** | `string` | optional | Field to track last modification time | +| **conflictResolution** | `Enum<'source_wins' \| 'target_wins' \| 'latest_wins' \| 'manual'>` | optional | Conflict resolution strategy | +| **batchSize** | `number` | optional | Records per batch | +| **deleteMode** | `Enum<'hard_delete' \| 'soft_delete' \| 'ignore'>` | optional | Delete handling mode | +| **filters** | `Record` | optional | Filter criteria for selective sync | + +--- + +## FieldMapping + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **sourceField** | `string` | ✅ | Field name in external system | +| **targetField** | `string` | ✅ | Field name in ObjectStack (snake_case) | +| **dataType** | `Enum<'string' \| 'number' \| 'boolean' \| 'date' \| 'datetime' \| 'json' \| 'array'>` | optional | Target data type | +| **required** | `boolean` | optional | Field is required | +| **defaultValue** | `any` | optional | Default value | +| **transform** | `object` | optional | Field transformation | +| **syncMode** | `Enum<'read_only' \| 'write_only' \| 'bidirectional'>` | optional | Sync mode | + +--- + +## FieldTransform + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **type** | `Enum<'uppercase' \| 'lowercase' \| 'trim' \| 'date_format' \| 'number_format' \| 'custom'>` | ✅ | Transformation type | +| **params** | `Record` | optional | Transformation parameters | +| **function** | `string` | optional | Custom JavaScript function for transformation | + +--- + +## JwtAuth + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **type** | `string` | ✅ | Authentication type | +| **token** | `string` | optional | Pre-generated JWT token | +| **secretKey** | `string` | optional | Secret key for JWT signing | +| **algorithm** | `Enum<'HS256' \| 'HS384' \| 'HS512' \| 'RS256' \| 'RS384' \| 'RS512' \| 'ES256' \| 'ES384' \| 'ES512'>` | optional | JWT signing algorithm | +| **issuer** | `string` | optional | JWT issuer claim | +| **audience** | `string` | optional | JWT audience claim | +| **subject** | `string` | optional | JWT subject claim | +| **expiresIn** | `number` | optional | Token expiry in seconds | +| **claims** | `Record` | optional | Additional JWT claims | + +--- + +## NoAuth + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **type** | `string` | ✅ | No authentication required | + +--- + +## OAuth2Auth + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **type** | `string` | ✅ | Authentication type | +| **clientId** | `string` | ✅ | OAuth2 client ID | +| **clientSecret** | `string` | ✅ | OAuth2 client secret (typically from ENV) | +| **authorizationUrl** | `string` | ✅ | OAuth2 authorization endpoint | +| **tokenUrl** | `string` | ✅ | OAuth2 token endpoint | +| **scopes** | `string[]` | optional | Requested OAuth2 scopes | +| **redirectUri** | `string` | optional | OAuth2 callback URL | +| **grantType** | `Enum<'authorization_code' \| 'client_credentials' \| 'password' \| 'refresh_token'>` | optional | OAuth2 grant type | +| **refreshToken** | `string` | optional | Refresh token for token renewal | +| **tokenExpiry** | `number` | optional | Token expiry timestamp | + +--- + +## RateLimitConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **strategy** | `Enum<'fixed_window' \| 'sliding_window' \| 'token_bucket' \| 'leaky_bucket'>` | optional | Rate limiting strategy | +| **maxRequests** | `number` | ✅ | Maximum requests per window | +| **windowSeconds** | `number` | ✅ | Time window in seconds | +| **burstCapacity** | `number` | optional | Burst capacity | +| **respectUpstreamLimits** | `boolean` | optional | Respect external rate limit headers | +| **rateLimitHeaders** | `object` | optional | Custom rate limit headers | + +--- + +## RateLimitStrategy + +Rate limiting strategy + +### Allowed Values + +* `fixed_window` +* `sliding_window` +* `token_bucket` +* `leaky_bucket` + +--- + +## RetryConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **strategy** | `Enum<'exponential_backoff' \| 'linear_backoff' \| 'fixed_delay' \| 'no_retry'>` | optional | Retry strategy | +| **maxAttempts** | `number` | optional | Maximum retry attempts | +| **initialDelayMs** | `number` | optional | Initial retry delay in ms | +| **maxDelayMs** | `number` | optional | Maximum retry delay in ms | +| **backoffMultiplier** | `number` | optional | Exponential backoff multiplier | +| **retryableStatusCodes** | `number[]` | optional | HTTP status codes to retry | +| **retryOnNetworkError** | `boolean` | optional | Retry on network errors | +| **jitter** | `boolean` | optional | Add jitter to retry delays | + +--- + +## RetryStrategy + +Retry strategy + +### Allowed Values + +* `exponential_backoff` +* `linear_backoff` +* `fixed_delay` +* `no_retry` + +--- + +## SamlAuth + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **type** | `string` | ✅ | Authentication type | +| **entryPoint** | `string` | ✅ | SAML IdP entry point URL | +| **issuer** | `string` | ✅ | SAML service provider issuer | +| **certificate** | `string` | ✅ | SAML IdP certificate (X.509) | +| **privateKey** | `string` | optional | SAML service provider private key | +| **callbackUrl** | `string` | optional | SAML assertion consumer service URL | +| **signatureAlgorithm** | `Enum<'sha1' \| 'sha256' \| 'sha512'>` | optional | SAML signature algorithm | +| **wantAssertionsSigned** | `boolean` | optional | Require signed SAML assertions | +| **identifierFormat** | `string` | optional | SAML NameID format | + +--- + +## SyncStrategy + +Synchronization strategy + +### Allowed Values + +* `full` +* `incremental` +* `upsert` +* `append_only` + +--- + +## WebhookConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **url** | `string` | ✅ | Webhook endpoint URL | +| **events** | `Enum<'record.created' \| 'record.updated' \| 'record.deleted' \| 'sync.started' \| 'sync.completed' \| 'sync.failed' \| 'auth.expired' \| 'rate_limit.exceeded'>[]` | ✅ | Events to subscribe to | +| **secret** | `string` | optional | Secret for HMAC signature | +| **signatureAlgorithm** | `Enum<'hmac_sha256' \| 'hmac_sha512' \| 'none'>` | optional | Webhook signature algorithm | +| **headers** | `Record` | optional | Custom HTTP headers | +| **retryConfig** | `object` | optional | Retry configuration | +| **timeoutMs** | `number` | optional | Request timeout in ms | +| **enabled** | `boolean` | optional | Enable webhook | + +--- + +## WebhookEvent + +Webhook event type + +### Allowed Values + +* `record.created` +* `record.updated` +* `record.deleted` +* `sync.started` +* `sync.completed` +* `sync.failed` +* `auth.expired` +* `rate_limit.exceeded` + +--- + +## WebhookSignatureAlgorithm + +Webhook signature algorithm + +### Allowed Values + +* `hmac_sha256` +* `hmac_sha512` +* `none` + diff --git a/content/docs/references/system/index.mdx b/content/docs/references/system/index.mdx index 9fcdb2f8f..2317abcc0 100644 --- a/content/docs/references/system/index.mdx +++ b/content/docs/references/system/index.mdx @@ -10,6 +10,7 @@ This section contains all protocol schemas for the system layer of ObjectStack. + diff --git a/content/docs/references/system/meta.json b/content/docs/references/system/meta.json index d4a87c4ba..ac5122f8a 100644 --- a/content/docs/references/system/meta.json +++ b/content/docs/references/system/meta.json @@ -3,6 +3,7 @@ "pages": [ "audit", "collaboration", + "connector", "context", "data-engine", "datasource", diff --git a/content/docs/references/system/misc.mdx b/content/docs/references/system/misc.mdx index a7e0b7ff2..5a7df618c 100644 --- a/content/docs/references/system/misc.mdx +++ b/content/docs/references/system/misc.mdx @@ -12,15 +12,368 @@ description: Misc protocol schemas ## TypeScript Usage ```typescript -import { MongoConfigSchema, PostgresConfigSchema } from '@objectstack/spec/system'; -import type { MongoConfig, PostgresConfig } from '@objectstack/spec/system'; +import { AckModeSchema, ApiVersionConfigSchema, CdcConfigSchema, ConsumerConfigSchema, DatabaseConnectorSchema, DatabasePoolConfigSchema, DatabaseProviderSchema, DatabaseTableSchema, DeliveryGuaranteeSchema, DlqConfigSchema, FileAccessPatternSchema, FileFilterConfigSchema, FileMetadataConfigSchema, FileStorageConnectorSchema, FileStorageProviderSchema, FileVersioningConfigSchema, MessageFormatSchema, MessageQueueConnectorSchema, MessageQueueProviderSchema, MongoConfigSchema, MultipartUploadConfigSchema, PostgresConfigSchema, ProducerConfigSchema, SaasConnectorSchema, SaasObjectTypeSchema, SaasProviderSchema, SslConfigSchema, StorageBucketSchema, TopicQueueSchema } from '@objectstack/spec/system'; +import type { AckMode, ApiVersionConfig, CdcConfig, ConsumerConfig, DatabaseConnector, DatabasePoolConfig, DatabaseProvider, DatabaseTable, DeliveryGuarantee, DlqConfig, FileAccessPattern, FileFilterConfig, FileMetadataConfig, FileStorageConnector, FileStorageProvider, FileVersioningConfig, MessageFormat, MessageQueueConnector, MessageQueueProvider, MongoConfig, MultipartUploadConfig, PostgresConfig, ProducerConfig, SaasConnector, SaasObjectType, SaasProvider, SslConfig, StorageBucket, TopicQueue } from '@objectstack/spec/system'; // Validate data -const result = MongoConfigSchema.parse(data); +const result = AckModeSchema.parse(data); ``` --- +## AckMode + +Message acknowledgment mode + +### Allowed Values + +* `auto` +* `manual` +* `client` + +--- + +## ApiVersionConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **version** | `string` | ✅ | API version (e.g., "v2", "2023-10-01") | +| **isDefault** | `boolean` | optional | Is this the default version | +| **deprecationDate** | `string` | optional | API version deprecation date (ISO 8601) | +| **sunsetDate** | `string` | optional | API version sunset date (ISO 8601) | + +--- + +## CdcConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **enabled** | `boolean` | optional | Enable CDC | +| **method** | `Enum<'log_based' \| 'trigger_based' \| 'query_based' \| 'custom'>` | ✅ | CDC method | +| **slotName** | `string` | optional | Replication slot name (for log-based CDC) | +| **publicationName** | `string` | optional | Publication name (for PostgreSQL) | +| **startPosition** | `string` | optional | Starting position/LSN for CDC stream | +| **batchSize** | `number` | optional | CDC batch size | +| **pollIntervalMs** | `number` | optional | CDC polling interval in ms | + +--- + +## ConsumerConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **enabled** | `boolean` | optional | Enable consumer | +| **consumerGroup** | `string` | optional | Consumer group ID | +| **concurrency** | `number` | optional | Number of concurrent consumers | +| **prefetchCount** | `number` | optional | Prefetch count | +| **ackMode** | `Enum<'auto' \| 'manual' \| 'client'>` | optional | Message acknowledgment mode | +| **autoCommit** | `boolean` | optional | Auto-commit offsets | +| **autoCommitIntervalMs** | `number` | optional | Auto-commit interval in ms | +| **sessionTimeoutMs** | `number` | optional | Session timeout in ms | +| **rebalanceTimeoutMs** | `number` | optional | Rebalance timeout in ms | + +--- + +## DatabaseConnector + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Unique connector identifier | +| **label** | `string` | ✅ | Display label | +| **type** | `string` | ✅ | | +| **description** | `string` | optional | Connector description | +| **icon** | `string` | optional | Icon identifier | +| **authentication** | `object \| object \| object \| object \| object \| object \| object` | ✅ | Authentication configuration | +| **syncConfig** | `object` | optional | Data sync configuration | +| **fieldMappings** | `object[]` | optional | Field mapping rules | +| **webhooks** | `object[]` | optional | Webhook configurations | +| **rateLimitConfig** | `object` | optional | Rate limiting configuration | +| **retryConfig** | `object` | optional | Retry configuration | +| **connectionTimeoutMs** | `number` | optional | Connection timeout in ms | +| **requestTimeoutMs** | `number` | optional | Request timeout in ms | +| **status** | `Enum<'active' \| 'inactive' \| 'error' \| 'configuring'>` | optional | Connector status | +| **enabled** | `boolean` | optional | Enable connector | +| **metadata** | `Record` | optional | Custom connector metadata | +| **provider** | `Enum<'postgresql' \| 'mysql' \| 'mariadb' \| 'mssql' \| 'oracle' \| 'mongodb' \| 'redis' \| 'cassandra' \| 'snowflake' \| 'bigquery' \| 'redshift' \| 'custom'>` | ✅ | Database provider type | +| **connectionConfig** | `object` | ✅ | Database connection configuration | +| **poolConfig** | `object` | optional | Connection pool configuration | +| **sslConfig** | `object` | optional | SSL/TLS configuration | +| **tables** | `object[]` | ✅ | Tables to sync | +| **cdcConfig** | `object` | optional | CDC configuration | +| **readReplicaConfig** | `object` | optional | Read replica configuration | +| **queryTimeoutMs** | `number` | optional | Query timeout in ms | +| **enableQueryLogging** | `boolean` | optional | Enable SQL query logging | + +--- + +## DatabasePoolConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **min** | `number` | optional | Minimum connections in pool | +| **max** | `number` | optional | Maximum connections in pool | +| **idleTimeoutMs** | `number` | optional | Idle connection timeout in ms | +| **connectionTimeoutMs** | `number` | optional | Connection establishment timeout in ms | +| **acquireTimeoutMs** | `number` | optional | Connection acquisition timeout in ms | +| **evictionRunIntervalMs** | `number` | optional | Connection eviction check interval in ms | +| **testOnBorrow** | `boolean` | optional | Test connection before use | + +--- + +## DatabaseProvider + +Database provider type + +### Allowed Values + +* `postgresql` +* `mysql` +* `mariadb` +* `mssql` +* `oracle` +* `mongodb` +* `redis` +* `cassandra` +* `snowflake` +* `bigquery` +* `redshift` +* `custom` + +--- + +## DatabaseTable + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Table name in ObjectStack (snake_case) | +| **label** | `string` | ✅ | Display label | +| **schema** | `string` | optional | Database schema name | +| **tableName** | `string` | ✅ | Actual table name in database | +| **primaryKey** | `string` | ✅ | Primary key column | +| **enabled** | `boolean` | optional | Enable sync for this table | +| **fieldMappings** | `object[]` | optional | Table-specific field mappings | +| **whereClause** | `string` | optional | SQL WHERE clause for filtering | + +--- + +## DeliveryGuarantee + +Message delivery guarantee + +### Allowed Values + +* `at_most_once` +* `at_least_once` +* `exactly_once` + +--- + +## DlqConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **enabled** | `boolean` | optional | Enable DLQ | +| **queueName** | `string` | ✅ | Dead letter queue/topic name | +| **maxRetries** | `number` | optional | Max retries before DLQ | +| **retryDelayMs** | `number` | optional | Retry delay in ms | + +--- + +## FileAccessPattern + +File access pattern + +### Allowed Values + +* `public_read` +* `private` +* `authenticated_read` +* `bucket_owner_read` +* `bucket_owner_full` + +--- + +## FileFilterConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **includePatterns** | `string[]` | optional | File patterns to include (glob) | +| **excludePatterns** | `string[]` | optional | File patterns to exclude (glob) | +| **minFileSize** | `number` | optional | Minimum file size in bytes | +| **maxFileSize** | `number` | optional | Maximum file size in bytes | +| **allowedExtensions** | `string[]` | optional | Allowed file extensions | +| **blockedExtensions** | `string[]` | optional | Blocked file extensions | + +--- + +## FileMetadataConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **extractMetadata** | `boolean` | optional | Extract file metadata | +| **metadataFields** | `Enum<'content_type' \| 'file_size' \| 'last_modified' \| 'etag' \| 'checksum' \| 'creator' \| 'created_at' \| 'custom'>[]` | optional | Metadata fields to extract | +| **customMetadata** | `Record` | optional | Custom metadata key-value pairs | + +--- + +## FileStorageConnector + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Unique connector identifier | +| **label** | `string` | ✅ | Display label | +| **type** | `string` | ✅ | | +| **description** | `string` | optional | Connector description | +| **icon** | `string` | optional | Icon identifier | +| **authentication** | `object \| object \| object \| object \| object \| object \| object` | ✅ | Authentication configuration | +| **syncConfig** | `object` | optional | Data sync configuration | +| **fieldMappings** | `object[]` | optional | Field mapping rules | +| **webhooks** | `object[]` | optional | Webhook configurations | +| **rateLimitConfig** | `object` | optional | Rate limiting configuration | +| **retryConfig** | `object` | optional | Retry configuration | +| **connectionTimeoutMs** | `number` | optional | Connection timeout in ms | +| **requestTimeoutMs** | `number` | optional | Request timeout in ms | +| **status** | `Enum<'active' \| 'inactive' \| 'error' \| 'configuring'>` | optional | Connector status | +| **enabled** | `boolean` | optional | Enable connector | +| **metadata** | `Record` | optional | Custom connector metadata | +| **provider** | `Enum<'s3' \| 'azure_blob' \| 'gcs' \| 'dropbox' \| 'box' \| 'onedrive' \| 'google_drive' \| 'sharepoint' \| 'ftp' \| 'local' \| 'custom'>` | ✅ | File storage provider type | +| **storageConfig** | `object` | optional | Storage configuration | +| **buckets** | `object[]` | ✅ | Buckets/containers to sync | +| **metadataConfig** | `object` | optional | Metadata extraction configuration | +| **multipartConfig** | `object` | optional | Multipart upload configuration | +| **versioningConfig** | `object` | optional | File versioning configuration | +| **encryption** | `object` | optional | Encryption configuration | +| **lifecyclePolicy** | `object` | optional | Lifecycle policy | +| **contentProcessing** | `object` | optional | Content processing configuration | +| **bufferSize** | `number` | optional | Buffer size in bytes | +| **transferAcceleration** | `boolean` | optional | Enable transfer acceleration | + +--- + +## FileStorageProvider + +File storage provider type + +### Allowed Values + +* `s3` +* `azure_blob` +* `gcs` +* `dropbox` +* `box` +* `onedrive` +* `google_drive` +* `sharepoint` +* `ftp` +* `local` +* `custom` + +--- + +## FileVersioningConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **enabled** | `boolean` | optional | Enable file versioning | +| **maxVersions** | `number` | optional | Maximum versions to retain | +| **retentionDays** | `number` | optional | Version retention period in days | + +--- + +## MessageFormat + +Message format/serialization + +### Allowed Values + +* `json` +* `xml` +* `protobuf` +* `avro` +* `text` +* `binary` + +--- + +## MessageQueueConnector + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Unique connector identifier | +| **label** | `string` | ✅ | Display label | +| **type** | `string` | ✅ | | +| **description** | `string` | optional | Connector description | +| **icon** | `string` | optional | Icon identifier | +| **authentication** | `object \| object \| object \| object \| object \| object \| object` | ✅ | Authentication configuration | +| **syncConfig** | `object` | optional | Data sync configuration | +| **fieldMappings** | `object[]` | optional | Field mapping rules | +| **webhooks** | `object[]` | optional | Webhook configurations | +| **rateLimitConfig** | `object` | optional | Rate limiting configuration | +| **retryConfig** | `object` | optional | Retry configuration | +| **connectionTimeoutMs** | `number` | optional | Connection timeout in ms | +| **requestTimeoutMs** | `number` | optional | Request timeout in ms | +| **status** | `Enum<'active' \| 'inactive' \| 'error' \| 'configuring'>` | optional | Connector status | +| **enabled** | `boolean` | optional | Enable connector | +| **metadata** | `Record` | optional | Custom connector metadata | +| **provider** | `Enum<'rabbitmq' \| 'kafka' \| 'redis_pubsub' \| 'redis_streams' \| 'aws_sqs' \| 'aws_sns' \| 'google_pubsub' \| 'azure_service_bus' \| 'azure_event_hubs' \| 'nats' \| 'pulsar' \| 'activemq' \| 'custom'>` | ✅ | Message queue provider type | +| **brokerConfig** | `object` | ✅ | Broker connection configuration | +| **topics** | `object[]` | ✅ | Topics/queues to sync | +| **deliveryGuarantee** | `Enum<'at_most_once' \| 'at_least_once' \| 'exactly_once'>` | optional | Message delivery guarantee | +| **sslConfig** | `object` | optional | SSL/TLS configuration | +| **saslConfig** | `object` | optional | SASL authentication configuration | +| **schemaRegistry** | `object` | optional | Schema registry configuration | +| **preserveOrder** | `boolean` | optional | Preserve message ordering | +| **enableMetrics** | `boolean` | optional | Enable message queue metrics | +| **enableTracing** | `boolean` | optional | Enable distributed tracing | + +--- + +## MessageQueueProvider + +Message queue provider type + +### Allowed Values + +* `rabbitmq` +* `kafka` +* `redis_pubsub` +* `redis_streams` +* `aws_sqs` +* `aws_sns` +* `google_pubsub` +* `azure_service_bus` +* `azure_event_hubs` +* `nats` +* `pulsar` +* `activemq` +* `custom` + +--- + ## MongoConfig ### Properties @@ -44,6 +397,19 @@ const result = MongoConfigSchema.parse(data); --- +## MultipartUploadConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **enabled** | `boolean` | optional | Enable multipart uploads | +| **partSize** | `number` | optional | Part size in bytes (min 5MB) | +| **maxConcurrentParts** | `number` | optional | Maximum concurrent part uploads | +| **threshold** | `number` | optional | File size threshold for multipart upload in bytes | + +--- + ## PostgresConfig ### Properties @@ -65,3 +431,145 @@ const result = MongoConfigSchema.parse(data); | **connectionTimeoutMillis** | `number` | optional | Connection Timeout (ms) | | **statementTimeout** | `number` | optional | Statement Timeout (ms) | +--- + +## ProducerConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **enabled** | `boolean` | optional | Enable producer | +| **acks** | `Enum<'0' \| '1' \| 'all'>` | optional | Acknowledgment level | +| **compressionType** | `Enum<'none' \| 'gzip' \| 'snappy' \| 'lz4' \| 'zstd'>` | optional | Compression type | +| **batchSize** | `number` | optional | Batch size in bytes | +| **lingerMs** | `number` | optional | Linger time in ms | +| **maxInFlightRequests** | `number` | optional | Max in-flight requests | +| **idempotence** | `boolean` | optional | Enable idempotent producer | +| **transactional** | `boolean` | optional | Enable transactional producer | +| **transactionTimeoutMs** | `number` | optional | Transaction timeout in ms | + +--- + +## SaasConnector + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Unique connector identifier | +| **label** | `string` | ✅ | Display label | +| **type** | `string` | ✅ | | +| **description** | `string` | optional | Connector description | +| **icon** | `string` | optional | Icon identifier | +| **authentication** | `object \| object \| object \| object \| object \| object \| object` | ✅ | Authentication configuration | +| **syncConfig** | `object` | optional | Data sync configuration | +| **fieldMappings** | `object[]` | optional | Field mapping rules | +| **webhooks** | `object[]` | optional | Webhook configurations | +| **rateLimitConfig** | `object` | optional | Rate limiting configuration | +| **retryConfig** | `object` | optional | Retry configuration | +| **connectionTimeoutMs** | `number` | optional | Connection timeout in ms | +| **requestTimeoutMs** | `number` | optional | Request timeout in ms | +| **status** | `Enum<'active' \| 'inactive' \| 'error' \| 'configuring'>` | optional | Connector status | +| **enabled** | `boolean` | optional | Enable connector | +| **metadata** | `Record` | optional | Custom connector metadata | +| **provider** | `Enum<'salesforce' \| 'hubspot' \| 'stripe' \| 'shopify' \| 'zendesk' \| 'intercom' \| 'mailchimp' \| 'slack' \| 'microsoft_dynamics' \| 'servicenow' \| 'netsuite' \| 'custom'>` | ✅ | SaaS provider type | +| **baseUrl** | `string` | ✅ | API base URL | +| **apiVersion** | `object` | optional | API version configuration | +| **objectTypes** | `object[]` | ✅ | Syncable object types | +| **oauthSettings** | `object` | optional | OAuth-specific configuration | +| **paginationConfig** | `object` | optional | Pagination configuration | +| **sandboxConfig** | `object` | optional | Sandbox environment configuration | +| **customHeaders** | `Record` | optional | Custom HTTP headers for all requests | + +--- + +## SaasObjectType + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Object type name (snake_case) | +| **label** | `string` | ✅ | Display label | +| **apiName** | `string` | ✅ | API name in external system | +| **enabled** | `boolean` | optional | Enable sync for this object | +| **supportsCreate** | `boolean` | optional | Supports record creation | +| **supportsUpdate** | `boolean` | optional | Supports record updates | +| **supportsDelete** | `boolean` | optional | Supports record deletion | +| **fieldMappings** | `object[]` | optional | Object-specific field mappings | + +--- + +## SaasProvider + +SaaS provider type + +### Allowed Values + +* `salesforce` +* `hubspot` +* `stripe` +* `shopify` +* `zendesk` +* `intercom` +* `mailchimp` +* `slack` +* `microsoft_dynamics` +* `servicenow` +* `netsuite` +* `custom` + +--- + +## SslConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **enabled** | `boolean` | optional | Enable SSL/TLS | +| **rejectUnauthorized** | `boolean` | optional | Reject unauthorized certificates | +| **ca** | `string` | optional | Certificate Authority certificate | +| **cert** | `string` | optional | Client certificate | +| **key** | `string` | optional | Client private key | + +--- + +## StorageBucket + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Bucket identifier in ObjectStack (snake_case) | +| **label** | `string` | ✅ | Display label | +| **bucketName** | `string` | ✅ | Actual bucket/container name in storage system | +| **region** | `string` | optional | Storage region | +| **enabled** | `boolean` | optional | Enable sync for this bucket | +| **prefix** | `string` | optional | Prefix/path within bucket | +| **accessPattern** | `Enum<'public_read' \| 'private' \| 'authenticated_read' \| 'bucket_owner_read' \| 'bucket_owner_full'>` | optional | Access pattern | +| **fileFilters** | `object` | optional | File filter configuration | + +--- + +## TopicQueue + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Topic/queue identifier in ObjectStack (snake_case) | +| **label** | `string` | ✅ | Display label | +| **topicName** | `string` | ✅ | Actual topic/queue name in message queue system | +| **enabled** | `boolean` | optional | Enable sync for this topic/queue | +| **mode** | `Enum<'consumer' \| 'producer' \| 'both'>` | optional | Consumer, producer, or both | +| **messageFormat** | `Enum<'json' \| 'xml' \| 'protobuf' \| 'avro' \| 'text' \| 'binary'>` | optional | Message format/serialization | +| **partitions** | `number` | optional | Number of partitions (for Kafka) | +| **replicationFactor** | `number` | optional | Replication factor (for Kafka) | +| **consumerConfig** | `object` | optional | Consumer-specific configuration | +| **producerConfig** | `object` | optional | Producer-specific configuration | +| **dlqConfig** | `object` | optional | Dead letter queue configuration | +| **routingKey** | `string` | optional | Routing key pattern | +| **messageFilter** | `object` | optional | Message filter criteria | + diff --git a/packages/spec/json-schema/system/AckMode.json b/packages/spec/json-schema/system/AckMode.json new file mode 100644 index 000000000..5328349c3 --- /dev/null +++ b/packages/spec/json-schema/system/AckMode.json @@ -0,0 +1,15 @@ +{ + "$ref": "#/definitions/AckMode", + "definitions": { + "AckMode": { + "type": "string", + "enum": [ + "auto", + "manual", + "client" + ], + "description": "Message acknowledgment mode" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/ApiKeyAuth.json b/packages/spec/json-schema/system/ApiKeyAuth.json new file mode 100644 index 000000000..9aa189132 --- /dev/null +++ b/packages/spec/json-schema/system/ApiKeyAuth.json @@ -0,0 +1,34 @@ +{ + "$ref": "#/definitions/ApiKeyAuth", + "definitions": { + "ApiKeyAuth": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "api_key", + "description": "Authentication type" + }, + "apiKey": { + "type": "string", + "description": "API key (typically from ENV)" + }, + "headerName": { + "type": "string", + "default": "X-API-Key", + "description": "HTTP header name for API key" + }, + "paramName": { + "type": "string", + "description": "Query parameter name (alternative to header)" + } + }, + "required": [ + "type", + "apiKey" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/ApiVersionConfig.json b/packages/spec/json-schema/system/ApiVersionConfig.json new file mode 100644 index 000000000..d73530305 --- /dev/null +++ b/packages/spec/json-schema/system/ApiVersionConfig.json @@ -0,0 +1,32 @@ +{ + "$ref": "#/definitions/ApiVersionConfig", + "definitions": { + "ApiVersionConfig": { + "type": "object", + "properties": { + "version": { + "type": "string", + "description": "API version (e.g., \"v2\", \"2023-10-01\")" + }, + "isDefault": { + "type": "boolean", + "default": false, + "description": "Is this the default version" + }, + "deprecationDate": { + "type": "string", + "description": "API version deprecation date (ISO 8601)" + }, + "sunsetDate": { + "type": "string", + "description": "API version sunset date (ISO 8601)" + } + }, + "required": [ + "version" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/Authentication.json b/packages/spec/json-schema/system/Authentication.json new file mode 100644 index 000000000..dd8b4df1d --- /dev/null +++ b/packages/spec/json-schema/system/Authentication.json @@ -0,0 +1,280 @@ +{ + "$ref": "#/definitions/Authentication", + "definitions": { + "Authentication": { + "anyOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "api_key", + "description": "Authentication type" + }, + "apiKey": { + "type": "string", + "description": "API key (typically from ENV)" + }, + "headerName": { + "type": "string", + "default": "X-API-Key", + "description": "HTTP header name for API key" + }, + "paramName": { + "type": "string", + "description": "Query parameter name (alternative to header)" + } + }, + "required": [ + "type", + "apiKey" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "oauth2", + "description": "Authentication type" + }, + "clientId": { + "type": "string", + "description": "OAuth2 client ID" + }, + "clientSecret": { + "type": "string", + "description": "OAuth2 client secret (typically from ENV)" + }, + "authorizationUrl": { + "type": "string", + "format": "uri", + "description": "OAuth2 authorization endpoint" + }, + "tokenUrl": { + "type": "string", + "format": "uri", + "description": "OAuth2 token endpoint" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Requested OAuth2 scopes" + }, + "redirectUri": { + "type": "string", + "format": "uri", + "description": "OAuth2 callback URL" + }, + "grantType": { + "type": "string", + "enum": [ + "authorization_code", + "client_credentials", + "password", + "refresh_token" + ], + "default": "authorization_code", + "description": "OAuth2 grant type" + }, + "refreshToken": { + "type": "string", + "description": "Refresh token for token renewal" + }, + "tokenExpiry": { + "type": "number", + "description": "Token expiry timestamp" + } + }, + "required": [ + "type", + "clientId", + "clientSecret", + "authorizationUrl", + "tokenUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "jwt", + "description": "Authentication type" + }, + "token": { + "type": "string", + "description": "Pre-generated JWT token" + }, + "secretKey": { + "type": "string", + "description": "Secret key for JWT signing" + }, + "algorithm": { + "type": "string", + "enum": [ + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512" + ], + "default": "HS256", + "description": "JWT signing algorithm" + }, + "issuer": { + "type": "string", + "description": "JWT issuer claim" + }, + "audience": { + "type": "string", + "description": "JWT audience claim" + }, + "subject": { + "type": "string", + "description": "JWT subject claim" + }, + "expiresIn": { + "type": "number", + "default": 3600, + "description": "Token expiry in seconds" + }, + "claims": { + "type": "object", + "additionalProperties": {}, + "description": "Additional JWT claims" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "saml", + "description": "Authentication type" + }, + "entryPoint": { + "type": "string", + "format": "uri", + "description": "SAML IdP entry point URL" + }, + "issuer": { + "type": "string", + "description": "SAML service provider issuer" + }, + "certificate": { + "type": "string", + "description": "SAML IdP certificate (X.509)" + }, + "privateKey": { + "type": "string", + "description": "SAML service provider private key" + }, + "callbackUrl": { + "type": "string", + "format": "uri", + "description": "SAML assertion consumer service URL" + }, + "signatureAlgorithm": { + "type": "string", + "enum": [ + "sha1", + "sha256", + "sha512" + ], + "default": "sha256", + "description": "SAML signature algorithm" + }, + "wantAssertionsSigned": { + "type": "boolean", + "default": true, + "description": "Require signed SAML assertions" + }, + "identifierFormat": { + "type": "string", + "description": "SAML NameID format" + } + }, + "required": [ + "type", + "entryPoint", + "issuer", + "certificate" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "basic", + "description": "Authentication type" + }, + "username": { + "type": "string", + "description": "Username" + }, + "password": { + "type": "string", + "description": "Password (typically from ENV)" + } + }, + "required": [ + "type", + "username", + "password" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "bearer", + "description": "Authentication type" + }, + "token": { + "type": "string", + "description": "Bearer token" + } + }, + "required": [ + "type", + "token" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "none", + "description": "No authentication required" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/BasicAuth.json b/packages/spec/json-schema/system/BasicAuth.json new file mode 100644 index 000000000..a0c27be00 --- /dev/null +++ b/packages/spec/json-schema/system/BasicAuth.json @@ -0,0 +1,30 @@ +{ + "$ref": "#/definitions/BasicAuth", + "definitions": { + "BasicAuth": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "basic", + "description": "Authentication type" + }, + "username": { + "type": "string", + "description": "Username" + }, + "password": { + "type": "string", + "description": "Password (typically from ENV)" + } + }, + "required": [ + "type", + "username", + "password" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/BearerTokenAuth.json b/packages/spec/json-schema/system/BearerTokenAuth.json new file mode 100644 index 000000000..d688756bc --- /dev/null +++ b/packages/spec/json-schema/system/BearerTokenAuth.json @@ -0,0 +1,25 @@ +{ + "$ref": "#/definitions/BearerTokenAuth", + "definitions": { + "BearerTokenAuth": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "bearer", + "description": "Authentication type" + }, + "token": { + "type": "string", + "description": "Bearer token" + } + }, + "required": [ + "type", + "token" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/CdcConfig.json b/packages/spec/json-schema/system/CdcConfig.json new file mode 100644 index 000000000..2b59c2f59 --- /dev/null +++ b/packages/spec/json-schema/system/CdcConfig.json @@ -0,0 +1,55 @@ +{ + "$ref": "#/definitions/CdcConfig", + "definitions": { + "CdcConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Enable CDC" + }, + "method": { + "type": "string", + "enum": [ + "log_based", + "trigger_based", + "query_based", + "custom" + ], + "description": "CDC method" + }, + "slotName": { + "type": "string", + "description": "Replication slot name (for log-based CDC)" + }, + "publicationName": { + "type": "string", + "description": "Publication name (for PostgreSQL)" + }, + "startPosition": { + "type": "string", + "description": "Starting position/LSN for CDC stream" + }, + "batchSize": { + "type": "number", + "minimum": 1, + "maximum": 10000, + "default": 1000, + "description": "CDC batch size" + }, + "pollIntervalMs": { + "type": "number", + "minimum": 100, + "default": 1000, + "description": "CDC polling interval in ms" + } + }, + "required": [ + "method" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/ConflictResolution.json b/packages/spec/json-schema/system/ConflictResolution.json new file mode 100644 index 000000000..eea0fc6b6 --- /dev/null +++ b/packages/spec/json-schema/system/ConflictResolution.json @@ -0,0 +1,16 @@ +{ + "$ref": "#/definitions/ConflictResolution", + "definitions": { + "ConflictResolution": { + "type": "string", + "enum": [ + "source_wins", + "target_wins", + "latest_wins", + "manual" + ], + "description": "Conflict resolution strategy" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/Connector.json b/packages/spec/json-schema/system/Connector.json new file mode 100644 index 000000000..ad19b3653 --- /dev/null +++ b/packages/spec/json-schema/system/Connector.json @@ -0,0 +1,744 @@ +{ + "$ref": "#/definitions/Connector", + "definitions": { + "Connector": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Unique connector identifier" + }, + "label": { + "type": "string", + "description": "Display label" + }, + "type": { + "type": "string", + "enum": [ + "saas", + "database", + "file_storage", + "message_queue", + "api", + "custom" + ], + "description": "Connector type" + }, + "description": { + "type": "string", + "description": "Connector description" + }, + "icon": { + "type": "string", + "description": "Icon identifier" + }, + "authentication": { + "anyOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "api_key", + "description": "Authentication type" + }, + "apiKey": { + "type": "string", + "description": "API key (typically from ENV)" + }, + "headerName": { + "type": "string", + "default": "X-API-Key", + "description": "HTTP header name for API key" + }, + "paramName": { + "type": "string", + "description": "Query parameter name (alternative to header)" + } + }, + "required": [ + "type", + "apiKey" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "oauth2", + "description": "Authentication type" + }, + "clientId": { + "type": "string", + "description": "OAuth2 client ID" + }, + "clientSecret": { + "type": "string", + "description": "OAuth2 client secret (typically from ENV)" + }, + "authorizationUrl": { + "type": "string", + "format": "uri", + "description": "OAuth2 authorization endpoint" + }, + "tokenUrl": { + "type": "string", + "format": "uri", + "description": "OAuth2 token endpoint" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Requested OAuth2 scopes" + }, + "redirectUri": { + "type": "string", + "format": "uri", + "description": "OAuth2 callback URL" + }, + "grantType": { + "type": "string", + "enum": [ + "authorization_code", + "client_credentials", + "password", + "refresh_token" + ], + "default": "authorization_code", + "description": "OAuth2 grant type" + }, + "refreshToken": { + "type": "string", + "description": "Refresh token for token renewal" + }, + "tokenExpiry": { + "type": "number", + "description": "Token expiry timestamp" + } + }, + "required": [ + "type", + "clientId", + "clientSecret", + "authorizationUrl", + "tokenUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "jwt", + "description": "Authentication type" + }, + "token": { + "type": "string", + "description": "Pre-generated JWT token" + }, + "secretKey": { + "type": "string", + "description": "Secret key for JWT signing" + }, + "algorithm": { + "type": "string", + "enum": [ + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512" + ], + "default": "HS256", + "description": "JWT signing algorithm" + }, + "issuer": { + "type": "string", + "description": "JWT issuer claim" + }, + "audience": { + "type": "string", + "description": "JWT audience claim" + }, + "subject": { + "type": "string", + "description": "JWT subject claim" + }, + "expiresIn": { + "type": "number", + "default": 3600, + "description": "Token expiry in seconds" + }, + "claims": { + "type": "object", + "additionalProperties": {}, + "description": "Additional JWT claims" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "saml", + "description": "Authentication type" + }, + "entryPoint": { + "type": "string", + "format": "uri", + "description": "SAML IdP entry point URL" + }, + "issuer": { + "type": "string", + "description": "SAML service provider issuer" + }, + "certificate": { + "type": "string", + "description": "SAML IdP certificate (X.509)" + }, + "privateKey": { + "type": "string", + "description": "SAML service provider private key" + }, + "callbackUrl": { + "type": "string", + "format": "uri", + "description": "SAML assertion consumer service URL" + }, + "signatureAlgorithm": { + "type": "string", + "enum": [ + "sha1", + "sha256", + "sha512" + ], + "default": "sha256", + "description": "SAML signature algorithm" + }, + "wantAssertionsSigned": { + "type": "boolean", + "default": true, + "description": "Require signed SAML assertions" + }, + "identifierFormat": { + "type": "string", + "description": "SAML NameID format" + } + }, + "required": [ + "type", + "entryPoint", + "issuer", + "certificate" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "basic", + "description": "Authentication type" + }, + "username": { + "type": "string", + "description": "Username" + }, + "password": { + "type": "string", + "description": "Password (typically from ENV)" + } + }, + "required": [ + "type", + "username", + "password" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "bearer", + "description": "Authentication type" + }, + "token": { + "type": "string", + "description": "Bearer token" + } + }, + "required": [ + "type", + "token" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "none", + "description": "No authentication required" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + ], + "description": "Authentication configuration" + }, + "syncConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "full", + "incremental", + "upsert", + "append_only" + ], + "description": "Synchronization strategy", + "default": "incremental" + }, + "direction": { + "type": "string", + "enum": [ + "import", + "export", + "bidirectional" + ], + "default": "import", + "description": "Sync direction" + }, + "schedule": { + "type": "string", + "description": "Cron expression for scheduled sync" + }, + "realtimeSync": { + "type": "boolean", + "default": false, + "description": "Enable real-time sync" + }, + "timestampField": { + "type": "string", + "description": "Field to track last modification time" + }, + "conflictResolution": { + "type": "string", + "enum": [ + "source_wins", + "target_wins", + "latest_wins", + "manual" + ], + "description": "Conflict resolution strategy", + "default": "latest_wins" + }, + "batchSize": { + "type": "number", + "minimum": 1, + "maximum": 10000, + "default": 1000, + "description": "Records per batch" + }, + "deleteMode": { + "type": "string", + "enum": [ + "hard_delete", + "soft_delete", + "ignore" + ], + "default": "soft_delete", + "description": "Delete handling mode" + }, + "filters": { + "type": "object", + "additionalProperties": {}, + "description": "Filter criteria for selective sync" + } + }, + "additionalProperties": false, + "description": "Data sync configuration" + }, + "fieldMappings": { + "type": "array", + "items": { + "type": "object", + "properties": { + "sourceField": { + "type": "string", + "description": "Field name in external system" + }, + "targetField": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Field name in ObjectStack (snake_case)" + }, + "dataType": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "date", + "datetime", + "json", + "array" + ], + "description": "Target data type" + }, + "required": { + "type": "boolean", + "default": false, + "description": "Field is required" + }, + "defaultValue": { + "description": "Default value" + }, + "transform": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "uppercase", + "lowercase", + "trim", + "date_format", + "number_format", + "custom" + ], + "description": "Transformation type" + }, + "params": { + "type": "object", + "additionalProperties": {}, + "description": "Transformation parameters" + }, + "function": { + "type": "string", + "description": "Custom JavaScript function for transformation" + } + }, + "required": [ + "type" + ], + "additionalProperties": false, + "description": "Field transformation" + }, + "syncMode": { + "type": "string", + "enum": [ + "read_only", + "write_only", + "bidirectional" + ], + "default": "bidirectional", + "description": "Sync mode" + } + }, + "required": [ + "sourceField", + "targetField" + ], + "additionalProperties": false + }, + "description": "Field mapping rules" + }, + "webhooks": { + "type": "array", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "Webhook endpoint URL" + }, + "events": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "record.created", + "record.updated", + "record.deleted", + "sync.started", + "sync.completed", + "sync.failed", + "auth.expired", + "rate_limit.exceeded" + ], + "description": "Webhook event type" + }, + "description": "Events to subscribe to" + }, + "secret": { + "type": "string", + "description": "Secret for HMAC signature" + }, + "signatureAlgorithm": { + "type": "string", + "enum": [ + "hmac_sha256", + "hmac_sha512", + "none" + ], + "description": "Webhook signature algorithm", + "default": "hmac_sha256" + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Custom HTTP headers" + }, + "retryConfig": { + "type": "object", + "properties": { + "maxAttempts": { + "type": "number", + "minimum": 0, + "maximum": 10, + "default": 3, + "description": "Maximum retry attempts" + }, + "backoffMultiplier": { + "type": "number", + "minimum": 1, + "default": 2, + "description": "Exponential backoff multiplier" + }, + "initialDelayMs": { + "type": "number", + "minimum": 100, + "default": 1000, + "description": "Initial retry delay in ms" + } + }, + "additionalProperties": false, + "description": "Retry configuration" + }, + "timeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 60000, + "default": 30000, + "description": "Request timeout in ms" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable webhook" + } + }, + "required": [ + "url", + "events" + ], + "additionalProperties": false + }, + "description": "Webhook configurations" + }, + "rateLimitConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "fixed_window", + "sliding_window", + "token_bucket", + "leaky_bucket" + ], + "description": "Rate limiting strategy", + "default": "token_bucket" + }, + "maxRequests": { + "type": "number", + "minimum": 1, + "description": "Maximum requests per window" + }, + "windowSeconds": { + "type": "number", + "minimum": 1, + "description": "Time window in seconds" + }, + "burstCapacity": { + "type": "number", + "minimum": 1, + "description": "Burst capacity" + }, + "respectUpstreamLimits": { + "type": "boolean", + "default": true, + "description": "Respect external rate limit headers" + }, + "rateLimitHeaders": { + "type": "object", + "properties": { + "remaining": { + "type": "string", + "default": "X-RateLimit-Remaining", + "description": "Header for remaining requests" + }, + "limit": { + "type": "string", + "default": "X-RateLimit-Limit", + "description": "Header for rate limit" + }, + "reset": { + "type": "string", + "default": "X-RateLimit-Reset", + "description": "Header for reset time" + } + }, + "additionalProperties": false, + "description": "Custom rate limit headers" + } + }, + "required": [ + "maxRequests", + "windowSeconds" + ], + "additionalProperties": false, + "description": "Rate limiting configuration" + }, + "retryConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "exponential_backoff", + "linear_backoff", + "fixed_delay", + "no_retry" + ], + "description": "Retry strategy", + "default": "exponential_backoff" + }, + "maxAttempts": { + "type": "number", + "minimum": 0, + "maximum": 10, + "default": 3, + "description": "Maximum retry attempts" + }, + "initialDelayMs": { + "type": "number", + "minimum": 100, + "default": 1000, + "description": "Initial retry delay in ms" + }, + "maxDelayMs": { + "type": "number", + "minimum": 1000, + "default": 60000, + "description": "Maximum retry delay in ms" + }, + "backoffMultiplier": { + "type": "number", + "minimum": 1, + "default": 2, + "description": "Exponential backoff multiplier" + }, + "retryableStatusCodes": { + "type": "array", + "items": { + "type": "number" + }, + "default": [ + 408, + 429, + 500, + 502, + 503, + 504 + ], + "description": "HTTP status codes to retry" + }, + "retryOnNetworkError": { + "type": "boolean", + "default": true, + "description": "Retry on network errors" + }, + "jitter": { + "type": "boolean", + "default": true, + "description": "Add jitter to retry delays" + } + }, + "additionalProperties": false, + "description": "Retry configuration" + }, + "connectionTimeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 300000, + "default": 30000, + "description": "Connection timeout in ms" + }, + "requestTimeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 300000, + "default": 30000, + "description": "Request timeout in ms" + }, + "status": { + "type": "string", + "enum": [ + "active", + "inactive", + "error", + "configuring" + ], + "description": "Connector status", + "default": "inactive" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable connector" + }, + "metadata": { + "type": "object", + "additionalProperties": {}, + "description": "Custom connector metadata" + } + }, + "required": [ + "name", + "label", + "type", + "authentication" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/ConnectorStatus.json b/packages/spec/json-schema/system/ConnectorStatus.json new file mode 100644 index 000000000..fd0d99f53 --- /dev/null +++ b/packages/spec/json-schema/system/ConnectorStatus.json @@ -0,0 +1,16 @@ +{ + "$ref": "#/definitions/ConnectorStatus", + "definitions": { + "ConnectorStatus": { + "type": "string", + "enum": [ + "active", + "inactive", + "error", + "configuring" + ], + "description": "Connector status" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/ConnectorType.json b/packages/spec/json-schema/system/ConnectorType.json new file mode 100644 index 000000000..2af49a983 --- /dev/null +++ b/packages/spec/json-schema/system/ConnectorType.json @@ -0,0 +1,18 @@ +{ + "$ref": "#/definitions/ConnectorType", + "definitions": { + "ConnectorType": { + "type": "string", + "enum": [ + "saas", + "database", + "file_storage", + "message_queue", + "api", + "custom" + ], + "description": "Connector type" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/ConsumerConfig.json b/packages/spec/json-schema/system/ConsumerConfig.json new file mode 100644 index 000000000..cf7fbc71f --- /dev/null +++ b/packages/spec/json-schema/system/ConsumerConfig.json @@ -0,0 +1,67 @@ +{ + "$ref": "#/definitions/ConsumerConfig", + "definitions": { + "ConsumerConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable consumer" + }, + "consumerGroup": { + "type": "string", + "description": "Consumer group ID" + }, + "concurrency": { + "type": "number", + "minimum": 1, + "maximum": 100, + "default": 1, + "description": "Number of concurrent consumers" + }, + "prefetchCount": { + "type": "number", + "minimum": 1, + "maximum": 1000, + "default": 10, + "description": "Prefetch count" + }, + "ackMode": { + "type": "string", + "enum": [ + "auto", + "manual", + "client" + ], + "description": "Message acknowledgment mode", + "default": "manual" + }, + "autoCommit": { + "type": "boolean", + "default": false, + "description": "Auto-commit offsets" + }, + "autoCommitIntervalMs": { + "type": "number", + "minimum": 100, + "default": 5000, + "description": "Auto-commit interval in ms" + }, + "sessionTimeoutMs": { + "type": "number", + "minimum": 1000, + "default": 30000, + "description": "Session timeout in ms" + }, + "rebalanceTimeoutMs": { + "type": "number", + "minimum": 1000, + "description": "Rebalance timeout in ms" + } + }, + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/DataSyncConfig.json b/packages/spec/json-schema/system/DataSyncConfig.json new file mode 100644 index 000000000..17fbf42cf --- /dev/null +++ b/packages/spec/json-schema/system/DataSyncConfig.json @@ -0,0 +1,79 @@ +{ + "$ref": "#/definitions/DataSyncConfig", + "definitions": { + "DataSyncConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "full", + "incremental", + "upsert", + "append_only" + ], + "description": "Synchronization strategy", + "default": "incremental" + }, + "direction": { + "type": "string", + "enum": [ + "import", + "export", + "bidirectional" + ], + "default": "import", + "description": "Sync direction" + }, + "schedule": { + "type": "string", + "description": "Cron expression for scheduled sync" + }, + "realtimeSync": { + "type": "boolean", + "default": false, + "description": "Enable real-time sync" + }, + "timestampField": { + "type": "string", + "description": "Field to track last modification time" + }, + "conflictResolution": { + "type": "string", + "enum": [ + "source_wins", + "target_wins", + "latest_wins", + "manual" + ], + "description": "Conflict resolution strategy", + "default": "latest_wins" + }, + "batchSize": { + "type": "number", + "minimum": 1, + "maximum": 10000, + "default": 1000, + "description": "Records per batch" + }, + "deleteMode": { + "type": "string", + "enum": [ + "hard_delete", + "soft_delete", + "ignore" + ], + "default": "soft_delete", + "description": "Delete handling mode" + }, + "filters": { + "type": "object", + "additionalProperties": {}, + "description": "Filter criteria for selective sync" + } + }, + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/DatabaseConnector.json b/packages/spec/json-schema/system/DatabaseConnector.json new file mode 100644 index 000000000..de017214b --- /dev/null +++ b/packages/spec/json-schema/system/DatabaseConnector.json @@ -0,0 +1,1114 @@ +{ + "$ref": "#/definitions/DatabaseConnector", + "definitions": { + "DatabaseConnector": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Unique connector identifier" + }, + "label": { + "type": "string", + "description": "Display label" + }, + "type": { + "type": "string", + "const": "database" + }, + "description": { + "type": "string", + "description": "Connector description" + }, + "icon": { + "type": "string", + "description": "Icon identifier" + }, + "authentication": { + "anyOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "api_key", + "description": "Authentication type" + }, + "apiKey": { + "type": "string", + "description": "API key (typically from ENV)" + }, + "headerName": { + "type": "string", + "default": "X-API-Key", + "description": "HTTP header name for API key" + }, + "paramName": { + "type": "string", + "description": "Query parameter name (alternative to header)" + } + }, + "required": [ + "type", + "apiKey" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "oauth2", + "description": "Authentication type" + }, + "clientId": { + "type": "string", + "description": "OAuth2 client ID" + }, + "clientSecret": { + "type": "string", + "description": "OAuth2 client secret (typically from ENV)" + }, + "authorizationUrl": { + "type": "string", + "format": "uri", + "description": "OAuth2 authorization endpoint" + }, + "tokenUrl": { + "type": "string", + "format": "uri", + "description": "OAuth2 token endpoint" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Requested OAuth2 scopes" + }, + "redirectUri": { + "type": "string", + "format": "uri", + "description": "OAuth2 callback URL" + }, + "grantType": { + "type": "string", + "enum": [ + "authorization_code", + "client_credentials", + "password", + "refresh_token" + ], + "default": "authorization_code", + "description": "OAuth2 grant type" + }, + "refreshToken": { + "type": "string", + "description": "Refresh token for token renewal" + }, + "tokenExpiry": { + "type": "number", + "description": "Token expiry timestamp" + } + }, + "required": [ + "type", + "clientId", + "clientSecret", + "authorizationUrl", + "tokenUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "jwt", + "description": "Authentication type" + }, + "token": { + "type": "string", + "description": "Pre-generated JWT token" + }, + "secretKey": { + "type": "string", + "description": "Secret key for JWT signing" + }, + "algorithm": { + "type": "string", + "enum": [ + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512" + ], + "default": "HS256", + "description": "JWT signing algorithm" + }, + "issuer": { + "type": "string", + "description": "JWT issuer claim" + }, + "audience": { + "type": "string", + "description": "JWT audience claim" + }, + "subject": { + "type": "string", + "description": "JWT subject claim" + }, + "expiresIn": { + "type": "number", + "default": 3600, + "description": "Token expiry in seconds" + }, + "claims": { + "type": "object", + "additionalProperties": {}, + "description": "Additional JWT claims" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "saml", + "description": "Authentication type" + }, + "entryPoint": { + "type": "string", + "format": "uri", + "description": "SAML IdP entry point URL" + }, + "issuer": { + "type": "string", + "description": "SAML service provider issuer" + }, + "certificate": { + "type": "string", + "description": "SAML IdP certificate (X.509)" + }, + "privateKey": { + "type": "string", + "description": "SAML service provider private key" + }, + "callbackUrl": { + "type": "string", + "format": "uri", + "description": "SAML assertion consumer service URL" + }, + "signatureAlgorithm": { + "type": "string", + "enum": [ + "sha1", + "sha256", + "sha512" + ], + "default": "sha256", + "description": "SAML signature algorithm" + }, + "wantAssertionsSigned": { + "type": "boolean", + "default": true, + "description": "Require signed SAML assertions" + }, + "identifierFormat": { + "type": "string", + "description": "SAML NameID format" + } + }, + "required": [ + "type", + "entryPoint", + "issuer", + "certificate" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "basic", + "description": "Authentication type" + }, + "username": { + "type": "string", + "description": "Username" + }, + "password": { + "type": "string", + "description": "Password (typically from ENV)" + } + }, + "required": [ + "type", + "username", + "password" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "bearer", + "description": "Authentication type" + }, + "token": { + "type": "string", + "description": "Bearer token" + } + }, + "required": [ + "type", + "token" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "none", + "description": "No authentication required" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + ], + "description": "Authentication configuration" + }, + "syncConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "full", + "incremental", + "upsert", + "append_only" + ], + "description": "Synchronization strategy", + "default": "incremental" + }, + "direction": { + "type": "string", + "enum": [ + "import", + "export", + "bidirectional" + ], + "default": "import", + "description": "Sync direction" + }, + "schedule": { + "type": "string", + "description": "Cron expression for scheduled sync" + }, + "realtimeSync": { + "type": "boolean", + "default": false, + "description": "Enable real-time sync" + }, + "timestampField": { + "type": "string", + "description": "Field to track last modification time" + }, + "conflictResolution": { + "type": "string", + "enum": [ + "source_wins", + "target_wins", + "latest_wins", + "manual" + ], + "description": "Conflict resolution strategy", + "default": "latest_wins" + }, + "batchSize": { + "type": "number", + "minimum": 1, + "maximum": 10000, + "default": 1000, + "description": "Records per batch" + }, + "deleteMode": { + "type": "string", + "enum": [ + "hard_delete", + "soft_delete", + "ignore" + ], + "default": "soft_delete", + "description": "Delete handling mode" + }, + "filters": { + "type": "object", + "additionalProperties": {}, + "description": "Filter criteria for selective sync" + } + }, + "additionalProperties": false, + "description": "Data sync configuration" + }, + "fieldMappings": { + "type": "array", + "items": { + "type": "object", + "properties": { + "sourceField": { + "type": "string", + "description": "Field name in external system" + }, + "targetField": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Field name in ObjectStack (snake_case)" + }, + "dataType": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "date", + "datetime", + "json", + "array" + ], + "description": "Target data type" + }, + "required": { + "type": "boolean", + "default": false, + "description": "Field is required" + }, + "defaultValue": { + "description": "Default value" + }, + "transform": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "uppercase", + "lowercase", + "trim", + "date_format", + "number_format", + "custom" + ], + "description": "Transformation type" + }, + "params": { + "type": "object", + "additionalProperties": {}, + "description": "Transformation parameters" + }, + "function": { + "type": "string", + "description": "Custom JavaScript function for transformation" + } + }, + "required": [ + "type" + ], + "additionalProperties": false, + "description": "Field transformation" + }, + "syncMode": { + "type": "string", + "enum": [ + "read_only", + "write_only", + "bidirectional" + ], + "default": "bidirectional", + "description": "Sync mode" + } + }, + "required": [ + "sourceField", + "targetField" + ], + "additionalProperties": false + }, + "description": "Field mapping rules" + }, + "webhooks": { + "type": "array", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "Webhook endpoint URL" + }, + "events": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "record.created", + "record.updated", + "record.deleted", + "sync.started", + "sync.completed", + "sync.failed", + "auth.expired", + "rate_limit.exceeded" + ], + "description": "Webhook event type" + }, + "description": "Events to subscribe to" + }, + "secret": { + "type": "string", + "description": "Secret for HMAC signature" + }, + "signatureAlgorithm": { + "type": "string", + "enum": [ + "hmac_sha256", + "hmac_sha512", + "none" + ], + "description": "Webhook signature algorithm", + "default": "hmac_sha256" + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Custom HTTP headers" + }, + "retryConfig": { + "type": "object", + "properties": { + "maxAttempts": { + "type": "number", + "minimum": 0, + "maximum": 10, + "default": 3, + "description": "Maximum retry attempts" + }, + "backoffMultiplier": { + "type": "number", + "minimum": 1, + "default": 2, + "description": "Exponential backoff multiplier" + }, + "initialDelayMs": { + "type": "number", + "minimum": 100, + "default": 1000, + "description": "Initial retry delay in ms" + } + }, + "additionalProperties": false, + "description": "Retry configuration" + }, + "timeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 60000, + "default": 30000, + "description": "Request timeout in ms" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable webhook" + } + }, + "required": [ + "url", + "events" + ], + "additionalProperties": false + }, + "description": "Webhook configurations" + }, + "rateLimitConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "fixed_window", + "sliding_window", + "token_bucket", + "leaky_bucket" + ], + "description": "Rate limiting strategy", + "default": "token_bucket" + }, + "maxRequests": { + "type": "number", + "minimum": 1, + "description": "Maximum requests per window" + }, + "windowSeconds": { + "type": "number", + "minimum": 1, + "description": "Time window in seconds" + }, + "burstCapacity": { + "type": "number", + "minimum": 1, + "description": "Burst capacity" + }, + "respectUpstreamLimits": { + "type": "boolean", + "default": true, + "description": "Respect external rate limit headers" + }, + "rateLimitHeaders": { + "type": "object", + "properties": { + "remaining": { + "type": "string", + "default": "X-RateLimit-Remaining", + "description": "Header for remaining requests" + }, + "limit": { + "type": "string", + "default": "X-RateLimit-Limit", + "description": "Header for rate limit" + }, + "reset": { + "type": "string", + "default": "X-RateLimit-Reset", + "description": "Header for reset time" + } + }, + "additionalProperties": false, + "description": "Custom rate limit headers" + } + }, + "required": [ + "maxRequests", + "windowSeconds" + ], + "additionalProperties": false, + "description": "Rate limiting configuration" + }, + "retryConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "exponential_backoff", + "linear_backoff", + "fixed_delay", + "no_retry" + ], + "description": "Retry strategy", + "default": "exponential_backoff" + }, + "maxAttempts": { + "type": "number", + "minimum": 0, + "maximum": 10, + "default": 3, + "description": "Maximum retry attempts" + }, + "initialDelayMs": { + "type": "number", + "minimum": 100, + "default": 1000, + "description": "Initial retry delay in ms" + }, + "maxDelayMs": { + "type": "number", + "minimum": 1000, + "default": 60000, + "description": "Maximum retry delay in ms" + }, + "backoffMultiplier": { + "type": "number", + "minimum": 1, + "default": 2, + "description": "Exponential backoff multiplier" + }, + "retryableStatusCodes": { + "type": "array", + "items": { + "type": "number" + }, + "default": [ + 408, + 429, + 500, + 502, + 503, + 504 + ], + "description": "HTTP status codes to retry" + }, + "retryOnNetworkError": { + "type": "boolean", + "default": true, + "description": "Retry on network errors" + }, + "jitter": { + "type": "boolean", + "default": true, + "description": "Add jitter to retry delays" + } + }, + "additionalProperties": false, + "description": "Retry configuration" + }, + "connectionTimeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 300000, + "default": 30000, + "description": "Connection timeout in ms" + }, + "requestTimeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 300000, + "default": 30000, + "description": "Request timeout in ms" + }, + "status": { + "type": "string", + "enum": [ + "active", + "inactive", + "error", + "configuring" + ], + "description": "Connector status", + "default": "inactive" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable connector" + }, + "metadata": { + "type": "object", + "additionalProperties": {}, + "description": "Custom connector metadata" + }, + "provider": { + "type": "string", + "enum": [ + "postgresql", + "mysql", + "mariadb", + "mssql", + "oracle", + "mongodb", + "redis", + "cassandra", + "snowflake", + "bigquery", + "redshift", + "custom" + ], + "description": "Database provider type" + }, + "connectionConfig": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "Database host" + }, + "port": { + "type": "number", + "minimum": 1, + "maximum": 65535, + "description": "Database port" + }, + "database": { + "type": "string", + "description": "Database name" + }, + "username": { + "type": "string", + "description": "Database username" + }, + "password": { + "type": "string", + "description": "Database password (typically from ENV)" + }, + "options": { + "type": "object", + "additionalProperties": {}, + "description": "Driver-specific connection options" + } + }, + "required": [ + "host", + "port", + "database", + "username", + "password" + ], + "additionalProperties": false, + "description": "Database connection configuration" + }, + "poolConfig": { + "type": "object", + "properties": { + "min": { + "type": "number", + "minimum": 0, + "default": 2, + "description": "Minimum connections in pool" + }, + "max": { + "type": "number", + "minimum": 1, + "default": 10, + "description": "Maximum connections in pool" + }, + "idleTimeoutMs": { + "type": "number", + "minimum": 1000, + "default": 30000, + "description": "Idle connection timeout in ms" + }, + "connectionTimeoutMs": { + "type": "number", + "minimum": 1000, + "default": 10000, + "description": "Connection establishment timeout in ms" + }, + "acquireTimeoutMs": { + "type": "number", + "minimum": 1000, + "default": 30000, + "description": "Connection acquisition timeout in ms" + }, + "evictionRunIntervalMs": { + "type": "number", + "minimum": 1000, + "default": 30000, + "description": "Connection eviction check interval in ms" + }, + "testOnBorrow": { + "type": "boolean", + "default": true, + "description": "Test connection before use" + } + }, + "additionalProperties": false, + "description": "Connection pool configuration" + }, + "sslConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Enable SSL/TLS" + }, + "rejectUnauthorized": { + "type": "boolean", + "default": true, + "description": "Reject unauthorized certificates" + }, + "ca": { + "type": "string", + "description": "Certificate Authority certificate" + }, + "cert": { + "type": "string", + "description": "Client certificate" + }, + "key": { + "type": "string", + "description": "Client private key" + } + }, + "additionalProperties": false, + "description": "SSL/TLS configuration" + }, + "tables": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Table name in ObjectStack (snake_case)" + }, + "label": { + "type": "string", + "description": "Display label" + }, + "schema": { + "type": "string", + "description": "Database schema name" + }, + "tableName": { + "type": "string", + "description": "Actual table name in database" + }, + "primaryKey": { + "type": "string", + "description": "Primary key column" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable sync for this table" + }, + "fieldMappings": { + "type": "array", + "items": { + "type": "object", + "properties": { + "sourceField": { + "type": "string", + "description": "Field name in external system" + }, + "targetField": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Field name in ObjectStack (snake_case)" + }, + "dataType": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "date", + "datetime", + "json", + "array" + ], + "description": "Target data type" + }, + "required": { + "type": "boolean", + "default": false, + "description": "Field is required" + }, + "defaultValue": { + "description": "Default value" + }, + "transform": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "uppercase", + "lowercase", + "trim", + "date_format", + "number_format", + "custom" + ], + "description": "Transformation type" + }, + "params": { + "type": "object", + "additionalProperties": {}, + "description": "Transformation parameters" + }, + "function": { + "type": "string", + "description": "Custom JavaScript function for transformation" + } + }, + "required": [ + "type" + ], + "additionalProperties": false, + "description": "Field transformation" + }, + "syncMode": { + "type": "string", + "enum": [ + "read_only", + "write_only", + "bidirectional" + ], + "default": "bidirectional", + "description": "Sync mode" + } + }, + "required": [ + "sourceField", + "targetField" + ], + "additionalProperties": false + }, + "description": "Table-specific field mappings" + }, + "whereClause": { + "type": "string", + "description": "SQL WHERE clause for filtering" + } + }, + "required": [ + "name", + "label", + "tableName", + "primaryKey" + ], + "additionalProperties": false + }, + "description": "Tables to sync" + }, + "cdcConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Enable CDC" + }, + "method": { + "type": "string", + "enum": [ + "log_based", + "trigger_based", + "query_based", + "custom" + ], + "description": "CDC method" + }, + "slotName": { + "type": "string", + "description": "Replication slot name (for log-based CDC)" + }, + "publicationName": { + "type": "string", + "description": "Publication name (for PostgreSQL)" + }, + "startPosition": { + "type": "string", + "description": "Starting position/LSN for CDC stream" + }, + "batchSize": { + "type": "number", + "minimum": 1, + "maximum": 10000, + "default": 1000, + "description": "CDC batch size" + }, + "pollIntervalMs": { + "type": "number", + "minimum": 100, + "default": 1000, + "description": "CDC polling interval in ms" + } + }, + "required": [ + "method" + ], + "additionalProperties": false, + "description": "CDC configuration" + }, + "readReplicaConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Use read replicas" + }, + "hosts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "Replica host" + }, + "port": { + "type": "number", + "minimum": 1, + "maximum": 65535, + "description": "Replica port" + }, + "weight": { + "type": "number", + "minimum": 0, + "maximum": 1, + "default": 1, + "description": "Load balancing weight" + } + }, + "required": [ + "host", + "port" + ], + "additionalProperties": false + }, + "description": "Read replica hosts" + } + }, + "required": [ + "hosts" + ], + "additionalProperties": false, + "description": "Read replica configuration" + }, + "queryTimeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 300000, + "default": 30000, + "description": "Query timeout in ms" + }, + "enableQueryLogging": { + "type": "boolean", + "default": false, + "description": "Enable SQL query logging" + } + }, + "required": [ + "name", + "label", + "type", + "authentication", + "provider", + "connectionConfig", + "tables" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/DatabasePoolConfig.json b/packages/spec/json-schema/system/DatabasePoolConfig.json new file mode 100644 index 000000000..8b6fba409 --- /dev/null +++ b/packages/spec/json-schema/system/DatabasePoolConfig.json @@ -0,0 +1,53 @@ +{ + "$ref": "#/definitions/DatabasePoolConfig", + "definitions": { + "DatabasePoolConfig": { + "type": "object", + "properties": { + "min": { + "type": "number", + "minimum": 0, + "default": 2, + "description": "Minimum connections in pool" + }, + "max": { + "type": "number", + "minimum": 1, + "default": 10, + "description": "Maximum connections in pool" + }, + "idleTimeoutMs": { + "type": "number", + "minimum": 1000, + "default": 30000, + "description": "Idle connection timeout in ms" + }, + "connectionTimeoutMs": { + "type": "number", + "minimum": 1000, + "default": 10000, + "description": "Connection establishment timeout in ms" + }, + "acquireTimeoutMs": { + "type": "number", + "minimum": 1000, + "default": 30000, + "description": "Connection acquisition timeout in ms" + }, + "evictionRunIntervalMs": { + "type": "number", + "minimum": 1000, + "default": 30000, + "description": "Connection eviction check interval in ms" + }, + "testOnBorrow": { + "type": "boolean", + "default": true, + "description": "Test connection before use" + } + }, + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/DatabaseProvider.json b/packages/spec/json-schema/system/DatabaseProvider.json new file mode 100644 index 000000000..6eb33b9ff --- /dev/null +++ b/packages/spec/json-schema/system/DatabaseProvider.json @@ -0,0 +1,24 @@ +{ + "$ref": "#/definitions/DatabaseProvider", + "definitions": { + "DatabaseProvider": { + "type": "string", + "enum": [ + "postgresql", + "mysql", + "mariadb", + "mssql", + "oracle", + "mongodb", + "redis", + "cassandra", + "snowflake", + "bigquery", + "redshift", + "custom" + ], + "description": "Database provider type" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/DatabaseTable.json b/packages/spec/json-schema/system/DatabaseTable.json new file mode 100644 index 000000000..0d106d38b --- /dev/null +++ b/packages/spec/json-schema/system/DatabaseTable.json @@ -0,0 +1,133 @@ +{ + "$ref": "#/definitions/DatabaseTable", + "definitions": { + "DatabaseTable": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Table name in ObjectStack (snake_case)" + }, + "label": { + "type": "string", + "description": "Display label" + }, + "schema": { + "type": "string", + "description": "Database schema name" + }, + "tableName": { + "type": "string", + "description": "Actual table name in database" + }, + "primaryKey": { + "type": "string", + "description": "Primary key column" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable sync for this table" + }, + "fieldMappings": { + "type": "array", + "items": { + "type": "object", + "properties": { + "sourceField": { + "type": "string", + "description": "Field name in external system" + }, + "targetField": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Field name in ObjectStack (snake_case)" + }, + "dataType": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "date", + "datetime", + "json", + "array" + ], + "description": "Target data type" + }, + "required": { + "type": "boolean", + "default": false, + "description": "Field is required" + }, + "defaultValue": { + "description": "Default value" + }, + "transform": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "uppercase", + "lowercase", + "trim", + "date_format", + "number_format", + "custom" + ], + "description": "Transformation type" + }, + "params": { + "type": "object", + "additionalProperties": {}, + "description": "Transformation parameters" + }, + "function": { + "type": "string", + "description": "Custom JavaScript function for transformation" + } + }, + "required": [ + "type" + ], + "additionalProperties": false, + "description": "Field transformation" + }, + "syncMode": { + "type": "string", + "enum": [ + "read_only", + "write_only", + "bidirectional" + ], + "default": "bidirectional", + "description": "Sync mode" + } + }, + "required": [ + "sourceField", + "targetField" + ], + "additionalProperties": false + }, + "description": "Table-specific field mappings" + }, + "whereClause": { + "type": "string", + "description": "SQL WHERE clause for filtering" + } + }, + "required": [ + "name", + "label", + "tableName", + "primaryKey" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/DeliveryGuarantee.json b/packages/spec/json-schema/system/DeliveryGuarantee.json new file mode 100644 index 000000000..05a05f0aa --- /dev/null +++ b/packages/spec/json-schema/system/DeliveryGuarantee.json @@ -0,0 +1,15 @@ +{ + "$ref": "#/definitions/DeliveryGuarantee", + "definitions": { + "DeliveryGuarantee": { + "type": "string", + "enum": [ + "at_most_once", + "at_least_once", + "exactly_once" + ], + "description": "Message delivery guarantee" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/DlqConfig.json b/packages/spec/json-schema/system/DlqConfig.json new file mode 100644 index 000000000..8ca5879ad --- /dev/null +++ b/packages/spec/json-schema/system/DlqConfig.json @@ -0,0 +1,37 @@ +{ + "$ref": "#/definitions/DlqConfig", + "definitions": { + "DlqConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Enable DLQ" + }, + "queueName": { + "type": "string", + "description": "Dead letter queue/topic name" + }, + "maxRetries": { + "type": "number", + "minimum": 0, + "maximum": 100, + "default": 3, + "description": "Max retries before DLQ" + }, + "retryDelayMs": { + "type": "number", + "minimum": 0, + "default": 60000, + "description": "Retry delay in ms" + } + }, + "required": [ + "queueName" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/FieldMapping.json b/packages/spec/json-schema/system/FieldMapping.json new file mode 100644 index 000000000..d8782c613 --- /dev/null +++ b/packages/spec/json-schema/system/FieldMapping.json @@ -0,0 +1,87 @@ +{ + "$ref": "#/definitions/FieldMapping", + "definitions": { + "FieldMapping": { + "type": "object", + "properties": { + "sourceField": { + "type": "string", + "description": "Field name in external system" + }, + "targetField": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Field name in ObjectStack (snake_case)" + }, + "dataType": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "date", + "datetime", + "json", + "array" + ], + "description": "Target data type" + }, + "required": { + "type": "boolean", + "default": false, + "description": "Field is required" + }, + "defaultValue": { + "description": "Default value" + }, + "transform": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "uppercase", + "lowercase", + "trim", + "date_format", + "number_format", + "custom" + ], + "description": "Transformation type" + }, + "params": { + "type": "object", + "additionalProperties": {}, + "description": "Transformation parameters" + }, + "function": { + "type": "string", + "description": "Custom JavaScript function for transformation" + } + }, + "required": [ + "type" + ], + "additionalProperties": false, + "description": "Field transformation" + }, + "syncMode": { + "type": "string", + "enum": [ + "read_only", + "write_only", + "bidirectional" + ], + "default": "bidirectional", + "description": "Sync mode" + } + }, + "required": [ + "sourceField", + "targetField" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/FieldTransform.json b/packages/spec/json-schema/system/FieldTransform.json new file mode 100644 index 000000000..6d8ce629f --- /dev/null +++ b/packages/spec/json-schema/system/FieldTransform.json @@ -0,0 +1,36 @@ +{ + "$ref": "#/definitions/FieldTransform", + "definitions": { + "FieldTransform": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "uppercase", + "lowercase", + "trim", + "date_format", + "number_format", + "custom" + ], + "description": "Transformation type" + }, + "params": { + "type": "object", + "additionalProperties": {}, + "description": "Transformation parameters" + }, + "function": { + "type": "string", + "description": "Custom JavaScript function for transformation" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/FileAccessPattern.json b/packages/spec/json-schema/system/FileAccessPattern.json new file mode 100644 index 000000000..72e82ae87 --- /dev/null +++ b/packages/spec/json-schema/system/FileAccessPattern.json @@ -0,0 +1,17 @@ +{ + "$ref": "#/definitions/FileAccessPattern", + "definitions": { + "FileAccessPattern": { + "type": "string", + "enum": [ + "public_read", + "private", + "authenticated_read", + "bucket_owner_read", + "bucket_owner_full" + ], + "description": "File access pattern" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/FileFilterConfig.json b/packages/spec/json-schema/system/FileFilterConfig.json new file mode 100644 index 000000000..261beffff --- /dev/null +++ b/packages/spec/json-schema/system/FileFilterConfig.json @@ -0,0 +1,50 @@ +{ + "$ref": "#/definitions/FileFilterConfig", + "definitions": { + "FileFilterConfig": { + "type": "object", + "properties": { + "includePatterns": { + "type": "array", + "items": { + "type": "string" + }, + "description": "File patterns to include (glob)" + }, + "excludePatterns": { + "type": "array", + "items": { + "type": "string" + }, + "description": "File patterns to exclude (glob)" + }, + "minFileSize": { + "type": "number", + "minimum": 0, + "description": "Minimum file size in bytes" + }, + "maxFileSize": { + "type": "number", + "minimum": 1, + "description": "Maximum file size in bytes" + }, + "allowedExtensions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Allowed file extensions" + }, + "blockedExtensions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Blocked file extensions" + } + }, + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/FileMetadataConfig.json b/packages/spec/json-schema/system/FileMetadataConfig.json new file mode 100644 index 000000000..b6e18bab5 --- /dev/null +++ b/packages/spec/json-schema/system/FileMetadataConfig.json @@ -0,0 +1,41 @@ +{ + "$ref": "#/definitions/FileMetadataConfig", + "definitions": { + "FileMetadataConfig": { + "type": "object", + "properties": { + "extractMetadata": { + "type": "boolean", + "default": true, + "description": "Extract file metadata" + }, + "metadataFields": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "content_type", + "file_size", + "last_modified", + "etag", + "checksum", + "creator", + "created_at", + "custom" + ] + }, + "description": "Metadata fields to extract" + }, + "customMetadata": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Custom metadata key-value pairs" + } + }, + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/FileStorageConnector.json b/packages/spec/json-schema/system/FileStorageConnector.json new file mode 100644 index 000000000..ff454c3a7 --- /dev/null +++ b/packages/spec/json-schema/system/FileStorageConnector.json @@ -0,0 +1,1065 @@ +{ + "$ref": "#/definitions/FileStorageConnector", + "definitions": { + "FileStorageConnector": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Unique connector identifier" + }, + "label": { + "type": "string", + "description": "Display label" + }, + "type": { + "type": "string", + "const": "file_storage" + }, + "description": { + "type": "string", + "description": "Connector description" + }, + "icon": { + "type": "string", + "description": "Icon identifier" + }, + "authentication": { + "anyOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "api_key", + "description": "Authentication type" + }, + "apiKey": { + "type": "string", + "description": "API key (typically from ENV)" + }, + "headerName": { + "type": "string", + "default": "X-API-Key", + "description": "HTTP header name for API key" + }, + "paramName": { + "type": "string", + "description": "Query parameter name (alternative to header)" + } + }, + "required": [ + "type", + "apiKey" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "oauth2", + "description": "Authentication type" + }, + "clientId": { + "type": "string", + "description": "OAuth2 client ID" + }, + "clientSecret": { + "type": "string", + "description": "OAuth2 client secret (typically from ENV)" + }, + "authorizationUrl": { + "type": "string", + "format": "uri", + "description": "OAuth2 authorization endpoint" + }, + "tokenUrl": { + "type": "string", + "format": "uri", + "description": "OAuth2 token endpoint" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Requested OAuth2 scopes" + }, + "redirectUri": { + "type": "string", + "format": "uri", + "description": "OAuth2 callback URL" + }, + "grantType": { + "type": "string", + "enum": [ + "authorization_code", + "client_credentials", + "password", + "refresh_token" + ], + "default": "authorization_code", + "description": "OAuth2 grant type" + }, + "refreshToken": { + "type": "string", + "description": "Refresh token for token renewal" + }, + "tokenExpiry": { + "type": "number", + "description": "Token expiry timestamp" + } + }, + "required": [ + "type", + "clientId", + "clientSecret", + "authorizationUrl", + "tokenUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "jwt", + "description": "Authentication type" + }, + "token": { + "type": "string", + "description": "Pre-generated JWT token" + }, + "secretKey": { + "type": "string", + "description": "Secret key for JWT signing" + }, + "algorithm": { + "type": "string", + "enum": [ + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512" + ], + "default": "HS256", + "description": "JWT signing algorithm" + }, + "issuer": { + "type": "string", + "description": "JWT issuer claim" + }, + "audience": { + "type": "string", + "description": "JWT audience claim" + }, + "subject": { + "type": "string", + "description": "JWT subject claim" + }, + "expiresIn": { + "type": "number", + "default": 3600, + "description": "Token expiry in seconds" + }, + "claims": { + "type": "object", + "additionalProperties": {}, + "description": "Additional JWT claims" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "saml", + "description": "Authentication type" + }, + "entryPoint": { + "type": "string", + "format": "uri", + "description": "SAML IdP entry point URL" + }, + "issuer": { + "type": "string", + "description": "SAML service provider issuer" + }, + "certificate": { + "type": "string", + "description": "SAML IdP certificate (X.509)" + }, + "privateKey": { + "type": "string", + "description": "SAML service provider private key" + }, + "callbackUrl": { + "type": "string", + "format": "uri", + "description": "SAML assertion consumer service URL" + }, + "signatureAlgorithm": { + "type": "string", + "enum": [ + "sha1", + "sha256", + "sha512" + ], + "default": "sha256", + "description": "SAML signature algorithm" + }, + "wantAssertionsSigned": { + "type": "boolean", + "default": true, + "description": "Require signed SAML assertions" + }, + "identifierFormat": { + "type": "string", + "description": "SAML NameID format" + } + }, + "required": [ + "type", + "entryPoint", + "issuer", + "certificate" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "basic", + "description": "Authentication type" + }, + "username": { + "type": "string", + "description": "Username" + }, + "password": { + "type": "string", + "description": "Password (typically from ENV)" + } + }, + "required": [ + "type", + "username", + "password" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "bearer", + "description": "Authentication type" + }, + "token": { + "type": "string", + "description": "Bearer token" + } + }, + "required": [ + "type", + "token" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "none", + "description": "No authentication required" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + ], + "description": "Authentication configuration" + }, + "syncConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "full", + "incremental", + "upsert", + "append_only" + ], + "description": "Synchronization strategy", + "default": "incremental" + }, + "direction": { + "type": "string", + "enum": [ + "import", + "export", + "bidirectional" + ], + "default": "import", + "description": "Sync direction" + }, + "schedule": { + "type": "string", + "description": "Cron expression for scheduled sync" + }, + "realtimeSync": { + "type": "boolean", + "default": false, + "description": "Enable real-time sync" + }, + "timestampField": { + "type": "string", + "description": "Field to track last modification time" + }, + "conflictResolution": { + "type": "string", + "enum": [ + "source_wins", + "target_wins", + "latest_wins", + "manual" + ], + "description": "Conflict resolution strategy", + "default": "latest_wins" + }, + "batchSize": { + "type": "number", + "minimum": 1, + "maximum": 10000, + "default": 1000, + "description": "Records per batch" + }, + "deleteMode": { + "type": "string", + "enum": [ + "hard_delete", + "soft_delete", + "ignore" + ], + "default": "soft_delete", + "description": "Delete handling mode" + }, + "filters": { + "type": "object", + "additionalProperties": {}, + "description": "Filter criteria for selective sync" + } + }, + "additionalProperties": false, + "description": "Data sync configuration" + }, + "fieldMappings": { + "type": "array", + "items": { + "type": "object", + "properties": { + "sourceField": { + "type": "string", + "description": "Field name in external system" + }, + "targetField": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Field name in ObjectStack (snake_case)" + }, + "dataType": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "date", + "datetime", + "json", + "array" + ], + "description": "Target data type" + }, + "required": { + "type": "boolean", + "default": false, + "description": "Field is required" + }, + "defaultValue": { + "description": "Default value" + }, + "transform": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "uppercase", + "lowercase", + "trim", + "date_format", + "number_format", + "custom" + ], + "description": "Transformation type" + }, + "params": { + "type": "object", + "additionalProperties": {}, + "description": "Transformation parameters" + }, + "function": { + "type": "string", + "description": "Custom JavaScript function for transformation" + } + }, + "required": [ + "type" + ], + "additionalProperties": false, + "description": "Field transformation" + }, + "syncMode": { + "type": "string", + "enum": [ + "read_only", + "write_only", + "bidirectional" + ], + "default": "bidirectional", + "description": "Sync mode" + } + }, + "required": [ + "sourceField", + "targetField" + ], + "additionalProperties": false + }, + "description": "Field mapping rules" + }, + "webhooks": { + "type": "array", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "Webhook endpoint URL" + }, + "events": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "record.created", + "record.updated", + "record.deleted", + "sync.started", + "sync.completed", + "sync.failed", + "auth.expired", + "rate_limit.exceeded" + ], + "description": "Webhook event type" + }, + "description": "Events to subscribe to" + }, + "secret": { + "type": "string", + "description": "Secret for HMAC signature" + }, + "signatureAlgorithm": { + "type": "string", + "enum": [ + "hmac_sha256", + "hmac_sha512", + "none" + ], + "description": "Webhook signature algorithm", + "default": "hmac_sha256" + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Custom HTTP headers" + }, + "retryConfig": { + "type": "object", + "properties": { + "maxAttempts": { + "type": "number", + "minimum": 0, + "maximum": 10, + "default": 3, + "description": "Maximum retry attempts" + }, + "backoffMultiplier": { + "type": "number", + "minimum": 1, + "default": 2, + "description": "Exponential backoff multiplier" + }, + "initialDelayMs": { + "type": "number", + "minimum": 100, + "default": 1000, + "description": "Initial retry delay in ms" + } + }, + "additionalProperties": false, + "description": "Retry configuration" + }, + "timeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 60000, + "default": 30000, + "description": "Request timeout in ms" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable webhook" + } + }, + "required": [ + "url", + "events" + ], + "additionalProperties": false + }, + "description": "Webhook configurations" + }, + "rateLimitConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "fixed_window", + "sliding_window", + "token_bucket", + "leaky_bucket" + ], + "description": "Rate limiting strategy", + "default": "token_bucket" + }, + "maxRequests": { + "type": "number", + "minimum": 1, + "description": "Maximum requests per window" + }, + "windowSeconds": { + "type": "number", + "minimum": 1, + "description": "Time window in seconds" + }, + "burstCapacity": { + "type": "number", + "minimum": 1, + "description": "Burst capacity" + }, + "respectUpstreamLimits": { + "type": "boolean", + "default": true, + "description": "Respect external rate limit headers" + }, + "rateLimitHeaders": { + "type": "object", + "properties": { + "remaining": { + "type": "string", + "default": "X-RateLimit-Remaining", + "description": "Header for remaining requests" + }, + "limit": { + "type": "string", + "default": "X-RateLimit-Limit", + "description": "Header for rate limit" + }, + "reset": { + "type": "string", + "default": "X-RateLimit-Reset", + "description": "Header for reset time" + } + }, + "additionalProperties": false, + "description": "Custom rate limit headers" + } + }, + "required": [ + "maxRequests", + "windowSeconds" + ], + "additionalProperties": false, + "description": "Rate limiting configuration" + }, + "retryConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "exponential_backoff", + "linear_backoff", + "fixed_delay", + "no_retry" + ], + "description": "Retry strategy", + "default": "exponential_backoff" + }, + "maxAttempts": { + "type": "number", + "minimum": 0, + "maximum": 10, + "default": 3, + "description": "Maximum retry attempts" + }, + "initialDelayMs": { + "type": "number", + "minimum": 100, + "default": 1000, + "description": "Initial retry delay in ms" + }, + "maxDelayMs": { + "type": "number", + "minimum": 1000, + "default": 60000, + "description": "Maximum retry delay in ms" + }, + "backoffMultiplier": { + "type": "number", + "minimum": 1, + "default": 2, + "description": "Exponential backoff multiplier" + }, + "retryableStatusCodes": { + "type": "array", + "items": { + "type": "number" + }, + "default": [ + 408, + 429, + 500, + 502, + 503, + 504 + ], + "description": "HTTP status codes to retry" + }, + "retryOnNetworkError": { + "type": "boolean", + "default": true, + "description": "Retry on network errors" + }, + "jitter": { + "type": "boolean", + "default": true, + "description": "Add jitter to retry delays" + } + }, + "additionalProperties": false, + "description": "Retry configuration" + }, + "connectionTimeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 300000, + "default": 30000, + "description": "Connection timeout in ms" + }, + "requestTimeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 300000, + "default": 30000, + "description": "Request timeout in ms" + }, + "status": { + "type": "string", + "enum": [ + "active", + "inactive", + "error", + "configuring" + ], + "description": "Connector status", + "default": "inactive" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable connector" + }, + "metadata": { + "type": "object", + "additionalProperties": {}, + "description": "Custom connector metadata" + }, + "provider": { + "type": "string", + "enum": [ + "s3", + "azure_blob", + "gcs", + "dropbox", + "box", + "onedrive", + "google_drive", + "sharepoint", + "ftp", + "local", + "custom" + ], + "description": "File storage provider type" + }, + "storageConfig": { + "type": "object", + "properties": { + "endpoint": { + "type": "string", + "format": "uri", + "description": "Custom endpoint URL" + }, + "region": { + "type": "string", + "description": "Default region" + }, + "pathStyle": { + "type": "boolean", + "default": false, + "description": "Use path-style URLs (for S3-compatible)" + } + }, + "additionalProperties": false, + "description": "Storage configuration" + }, + "buckets": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Bucket identifier in ObjectStack (snake_case)" + }, + "label": { + "type": "string", + "description": "Display label" + }, + "bucketName": { + "type": "string", + "description": "Actual bucket/container name in storage system" + }, + "region": { + "type": "string", + "description": "Storage region" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable sync for this bucket" + }, + "prefix": { + "type": "string", + "description": "Prefix/path within bucket" + }, + "accessPattern": { + "type": "string", + "enum": [ + "public_read", + "private", + "authenticated_read", + "bucket_owner_read", + "bucket_owner_full" + ], + "description": "Access pattern" + }, + "fileFilters": { + "type": "object", + "properties": { + "includePatterns": { + "type": "array", + "items": { + "type": "string" + }, + "description": "File patterns to include (glob)" + }, + "excludePatterns": { + "type": "array", + "items": { + "type": "string" + }, + "description": "File patterns to exclude (glob)" + }, + "minFileSize": { + "type": "number", + "minimum": 0, + "description": "Minimum file size in bytes" + }, + "maxFileSize": { + "type": "number", + "minimum": 1, + "description": "Maximum file size in bytes" + }, + "allowedExtensions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Allowed file extensions" + }, + "blockedExtensions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Blocked file extensions" + } + }, + "additionalProperties": false, + "description": "File filter configuration" + } + }, + "required": [ + "name", + "label", + "bucketName" + ], + "additionalProperties": false + }, + "description": "Buckets/containers to sync" + }, + "metadataConfig": { + "type": "object", + "properties": { + "extractMetadata": { + "type": "boolean", + "default": true, + "description": "Extract file metadata" + }, + "metadataFields": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "content_type", + "file_size", + "last_modified", + "etag", + "checksum", + "creator", + "created_at", + "custom" + ] + }, + "description": "Metadata fields to extract" + }, + "customMetadata": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Custom metadata key-value pairs" + } + }, + "additionalProperties": false, + "description": "Metadata extraction configuration" + }, + "multipartConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable multipart uploads" + }, + "partSize": { + "type": "number", + "minimum": 5242880, + "default": 5242880, + "description": "Part size in bytes (min 5MB)" + }, + "maxConcurrentParts": { + "type": "number", + "minimum": 1, + "maximum": 10, + "default": 5, + "description": "Maximum concurrent part uploads" + }, + "threshold": { + "type": "number", + "minimum": 5242880, + "default": 104857600, + "description": "File size threshold for multipart upload in bytes" + } + }, + "additionalProperties": false, + "description": "Multipart upload configuration" + }, + "versioningConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Enable file versioning" + }, + "maxVersions": { + "type": "number", + "minimum": 1, + "maximum": 100, + "description": "Maximum versions to retain" + }, + "retentionDays": { + "type": "number", + "minimum": 1, + "description": "Version retention period in days" + } + }, + "additionalProperties": false, + "description": "File versioning configuration" + }, + "encryption": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Enable server-side encryption" + }, + "algorithm": { + "type": "string", + "enum": [ + "AES256", + "aws:kms", + "custom" + ], + "description": "Encryption algorithm" + }, + "kmsKeyId": { + "type": "string", + "description": "KMS key ID (for aws:kms)" + } + }, + "additionalProperties": false, + "description": "Encryption configuration" + }, + "lifecyclePolicy": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Enable lifecycle policy" + }, + "deleteAfterDays": { + "type": "number", + "minimum": 1, + "description": "Delete files after N days" + }, + "archiveAfterDays": { + "type": "number", + "minimum": 1, + "description": "Archive files after N days" + } + }, + "additionalProperties": false, + "description": "Lifecycle policy" + }, + "contentProcessing": { + "type": "object", + "properties": { + "extractText": { + "type": "boolean", + "default": false, + "description": "Extract text from documents" + }, + "generateThumbnails": { + "type": "boolean", + "default": false, + "description": "Generate image thumbnails" + }, + "thumbnailSizes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "width": { + "type": "number", + "minimum": 1 + }, + "height": { + "type": "number", + "minimum": 1 + } + }, + "required": [ + "width", + "height" + ], + "additionalProperties": false + }, + "description": "Thumbnail sizes" + }, + "virusScan": { + "type": "boolean", + "default": false, + "description": "Scan for viruses" + } + }, + "additionalProperties": false, + "description": "Content processing configuration" + }, + "bufferSize": { + "type": "number", + "minimum": 1024, + "default": 65536, + "description": "Buffer size in bytes" + }, + "transferAcceleration": { + "type": "boolean", + "default": false, + "description": "Enable transfer acceleration" + } + }, + "required": [ + "name", + "label", + "type", + "authentication", + "provider", + "buckets" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/FileStorageProvider.json b/packages/spec/json-schema/system/FileStorageProvider.json new file mode 100644 index 000000000..6dbef63e2 --- /dev/null +++ b/packages/spec/json-schema/system/FileStorageProvider.json @@ -0,0 +1,23 @@ +{ + "$ref": "#/definitions/FileStorageProvider", + "definitions": { + "FileStorageProvider": { + "type": "string", + "enum": [ + "s3", + "azure_blob", + "gcs", + "dropbox", + "box", + "onedrive", + "google_drive", + "sharepoint", + "ftp", + "local", + "custom" + ], + "description": "File storage provider type" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/FileVersioningConfig.json b/packages/spec/json-schema/system/FileVersioningConfig.json new file mode 100644 index 000000000..fc12b87f4 --- /dev/null +++ b/packages/spec/json-schema/system/FileVersioningConfig.json @@ -0,0 +1,28 @@ +{ + "$ref": "#/definitions/FileVersioningConfig", + "definitions": { + "FileVersioningConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Enable file versioning" + }, + "maxVersions": { + "type": "number", + "minimum": 1, + "maximum": 100, + "description": "Maximum versions to retain" + }, + "retentionDays": { + "type": "number", + "minimum": 1, + "description": "Version retention period in days" + } + }, + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/JwtAuth.json b/packages/spec/json-schema/system/JwtAuth.json new file mode 100644 index 000000000..7d482903d --- /dev/null +++ b/packages/spec/json-schema/system/JwtAuth.json @@ -0,0 +1,66 @@ +{ + "$ref": "#/definitions/JwtAuth", + "definitions": { + "JwtAuth": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "jwt", + "description": "Authentication type" + }, + "token": { + "type": "string", + "description": "Pre-generated JWT token" + }, + "secretKey": { + "type": "string", + "description": "Secret key for JWT signing" + }, + "algorithm": { + "type": "string", + "enum": [ + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512" + ], + "default": "HS256", + "description": "JWT signing algorithm" + }, + "issuer": { + "type": "string", + "description": "JWT issuer claim" + }, + "audience": { + "type": "string", + "description": "JWT audience claim" + }, + "subject": { + "type": "string", + "description": "JWT subject claim" + }, + "expiresIn": { + "type": "number", + "default": 3600, + "description": "Token expiry in seconds" + }, + "claims": { + "type": "object", + "additionalProperties": {}, + "description": "Additional JWT claims" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/MessageFormat.json b/packages/spec/json-schema/system/MessageFormat.json new file mode 100644 index 000000000..a4090f8cc --- /dev/null +++ b/packages/spec/json-schema/system/MessageFormat.json @@ -0,0 +1,18 @@ +{ + "$ref": "#/definitions/MessageFormat", + "definitions": { + "MessageFormat": { + "type": "string", + "enum": [ + "json", + "xml", + "protobuf", + "avro", + "text", + "binary" + ], + "description": "Message format/serialization" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/MessageQueueConnector.json b/packages/spec/json-schema/system/MessageQueueConnector.json new file mode 100644 index 000000000..6ebaa45fc --- /dev/null +++ b/packages/spec/json-schema/system/MessageQueueConnector.json @@ -0,0 +1,1150 @@ +{ + "$ref": "#/definitions/MessageQueueConnector", + "definitions": { + "MessageQueueConnector": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Unique connector identifier" + }, + "label": { + "type": "string", + "description": "Display label" + }, + "type": { + "type": "string", + "const": "message_queue" + }, + "description": { + "type": "string", + "description": "Connector description" + }, + "icon": { + "type": "string", + "description": "Icon identifier" + }, + "authentication": { + "anyOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "api_key", + "description": "Authentication type" + }, + "apiKey": { + "type": "string", + "description": "API key (typically from ENV)" + }, + "headerName": { + "type": "string", + "default": "X-API-Key", + "description": "HTTP header name for API key" + }, + "paramName": { + "type": "string", + "description": "Query parameter name (alternative to header)" + } + }, + "required": [ + "type", + "apiKey" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "oauth2", + "description": "Authentication type" + }, + "clientId": { + "type": "string", + "description": "OAuth2 client ID" + }, + "clientSecret": { + "type": "string", + "description": "OAuth2 client secret (typically from ENV)" + }, + "authorizationUrl": { + "type": "string", + "format": "uri", + "description": "OAuth2 authorization endpoint" + }, + "tokenUrl": { + "type": "string", + "format": "uri", + "description": "OAuth2 token endpoint" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Requested OAuth2 scopes" + }, + "redirectUri": { + "type": "string", + "format": "uri", + "description": "OAuth2 callback URL" + }, + "grantType": { + "type": "string", + "enum": [ + "authorization_code", + "client_credentials", + "password", + "refresh_token" + ], + "default": "authorization_code", + "description": "OAuth2 grant type" + }, + "refreshToken": { + "type": "string", + "description": "Refresh token for token renewal" + }, + "tokenExpiry": { + "type": "number", + "description": "Token expiry timestamp" + } + }, + "required": [ + "type", + "clientId", + "clientSecret", + "authorizationUrl", + "tokenUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "jwt", + "description": "Authentication type" + }, + "token": { + "type": "string", + "description": "Pre-generated JWT token" + }, + "secretKey": { + "type": "string", + "description": "Secret key for JWT signing" + }, + "algorithm": { + "type": "string", + "enum": [ + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512" + ], + "default": "HS256", + "description": "JWT signing algorithm" + }, + "issuer": { + "type": "string", + "description": "JWT issuer claim" + }, + "audience": { + "type": "string", + "description": "JWT audience claim" + }, + "subject": { + "type": "string", + "description": "JWT subject claim" + }, + "expiresIn": { + "type": "number", + "default": 3600, + "description": "Token expiry in seconds" + }, + "claims": { + "type": "object", + "additionalProperties": {}, + "description": "Additional JWT claims" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "saml", + "description": "Authentication type" + }, + "entryPoint": { + "type": "string", + "format": "uri", + "description": "SAML IdP entry point URL" + }, + "issuer": { + "type": "string", + "description": "SAML service provider issuer" + }, + "certificate": { + "type": "string", + "description": "SAML IdP certificate (X.509)" + }, + "privateKey": { + "type": "string", + "description": "SAML service provider private key" + }, + "callbackUrl": { + "type": "string", + "format": "uri", + "description": "SAML assertion consumer service URL" + }, + "signatureAlgorithm": { + "type": "string", + "enum": [ + "sha1", + "sha256", + "sha512" + ], + "default": "sha256", + "description": "SAML signature algorithm" + }, + "wantAssertionsSigned": { + "type": "boolean", + "default": true, + "description": "Require signed SAML assertions" + }, + "identifierFormat": { + "type": "string", + "description": "SAML NameID format" + } + }, + "required": [ + "type", + "entryPoint", + "issuer", + "certificate" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "basic", + "description": "Authentication type" + }, + "username": { + "type": "string", + "description": "Username" + }, + "password": { + "type": "string", + "description": "Password (typically from ENV)" + } + }, + "required": [ + "type", + "username", + "password" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "bearer", + "description": "Authentication type" + }, + "token": { + "type": "string", + "description": "Bearer token" + } + }, + "required": [ + "type", + "token" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "none", + "description": "No authentication required" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + ], + "description": "Authentication configuration" + }, + "syncConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "full", + "incremental", + "upsert", + "append_only" + ], + "description": "Synchronization strategy", + "default": "incremental" + }, + "direction": { + "type": "string", + "enum": [ + "import", + "export", + "bidirectional" + ], + "default": "import", + "description": "Sync direction" + }, + "schedule": { + "type": "string", + "description": "Cron expression for scheduled sync" + }, + "realtimeSync": { + "type": "boolean", + "default": false, + "description": "Enable real-time sync" + }, + "timestampField": { + "type": "string", + "description": "Field to track last modification time" + }, + "conflictResolution": { + "type": "string", + "enum": [ + "source_wins", + "target_wins", + "latest_wins", + "manual" + ], + "description": "Conflict resolution strategy", + "default": "latest_wins" + }, + "batchSize": { + "type": "number", + "minimum": 1, + "maximum": 10000, + "default": 1000, + "description": "Records per batch" + }, + "deleteMode": { + "type": "string", + "enum": [ + "hard_delete", + "soft_delete", + "ignore" + ], + "default": "soft_delete", + "description": "Delete handling mode" + }, + "filters": { + "type": "object", + "additionalProperties": {}, + "description": "Filter criteria for selective sync" + } + }, + "additionalProperties": false, + "description": "Data sync configuration" + }, + "fieldMappings": { + "type": "array", + "items": { + "type": "object", + "properties": { + "sourceField": { + "type": "string", + "description": "Field name in external system" + }, + "targetField": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Field name in ObjectStack (snake_case)" + }, + "dataType": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "date", + "datetime", + "json", + "array" + ], + "description": "Target data type" + }, + "required": { + "type": "boolean", + "default": false, + "description": "Field is required" + }, + "defaultValue": { + "description": "Default value" + }, + "transform": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "uppercase", + "lowercase", + "trim", + "date_format", + "number_format", + "custom" + ], + "description": "Transformation type" + }, + "params": { + "type": "object", + "additionalProperties": {}, + "description": "Transformation parameters" + }, + "function": { + "type": "string", + "description": "Custom JavaScript function for transformation" + } + }, + "required": [ + "type" + ], + "additionalProperties": false, + "description": "Field transformation" + }, + "syncMode": { + "type": "string", + "enum": [ + "read_only", + "write_only", + "bidirectional" + ], + "default": "bidirectional", + "description": "Sync mode" + } + }, + "required": [ + "sourceField", + "targetField" + ], + "additionalProperties": false + }, + "description": "Field mapping rules" + }, + "webhooks": { + "type": "array", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "Webhook endpoint URL" + }, + "events": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "record.created", + "record.updated", + "record.deleted", + "sync.started", + "sync.completed", + "sync.failed", + "auth.expired", + "rate_limit.exceeded" + ], + "description": "Webhook event type" + }, + "description": "Events to subscribe to" + }, + "secret": { + "type": "string", + "description": "Secret for HMAC signature" + }, + "signatureAlgorithm": { + "type": "string", + "enum": [ + "hmac_sha256", + "hmac_sha512", + "none" + ], + "description": "Webhook signature algorithm", + "default": "hmac_sha256" + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Custom HTTP headers" + }, + "retryConfig": { + "type": "object", + "properties": { + "maxAttempts": { + "type": "number", + "minimum": 0, + "maximum": 10, + "default": 3, + "description": "Maximum retry attempts" + }, + "backoffMultiplier": { + "type": "number", + "minimum": 1, + "default": 2, + "description": "Exponential backoff multiplier" + }, + "initialDelayMs": { + "type": "number", + "minimum": 100, + "default": 1000, + "description": "Initial retry delay in ms" + } + }, + "additionalProperties": false, + "description": "Retry configuration" + }, + "timeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 60000, + "default": 30000, + "description": "Request timeout in ms" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable webhook" + } + }, + "required": [ + "url", + "events" + ], + "additionalProperties": false + }, + "description": "Webhook configurations" + }, + "rateLimitConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "fixed_window", + "sliding_window", + "token_bucket", + "leaky_bucket" + ], + "description": "Rate limiting strategy", + "default": "token_bucket" + }, + "maxRequests": { + "type": "number", + "minimum": 1, + "description": "Maximum requests per window" + }, + "windowSeconds": { + "type": "number", + "minimum": 1, + "description": "Time window in seconds" + }, + "burstCapacity": { + "type": "number", + "minimum": 1, + "description": "Burst capacity" + }, + "respectUpstreamLimits": { + "type": "boolean", + "default": true, + "description": "Respect external rate limit headers" + }, + "rateLimitHeaders": { + "type": "object", + "properties": { + "remaining": { + "type": "string", + "default": "X-RateLimit-Remaining", + "description": "Header for remaining requests" + }, + "limit": { + "type": "string", + "default": "X-RateLimit-Limit", + "description": "Header for rate limit" + }, + "reset": { + "type": "string", + "default": "X-RateLimit-Reset", + "description": "Header for reset time" + } + }, + "additionalProperties": false, + "description": "Custom rate limit headers" + } + }, + "required": [ + "maxRequests", + "windowSeconds" + ], + "additionalProperties": false, + "description": "Rate limiting configuration" + }, + "retryConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "exponential_backoff", + "linear_backoff", + "fixed_delay", + "no_retry" + ], + "description": "Retry strategy", + "default": "exponential_backoff" + }, + "maxAttempts": { + "type": "number", + "minimum": 0, + "maximum": 10, + "default": 3, + "description": "Maximum retry attempts" + }, + "initialDelayMs": { + "type": "number", + "minimum": 100, + "default": 1000, + "description": "Initial retry delay in ms" + }, + "maxDelayMs": { + "type": "number", + "minimum": 1000, + "default": 60000, + "description": "Maximum retry delay in ms" + }, + "backoffMultiplier": { + "type": "number", + "minimum": 1, + "default": 2, + "description": "Exponential backoff multiplier" + }, + "retryableStatusCodes": { + "type": "array", + "items": { + "type": "number" + }, + "default": [ + 408, + 429, + 500, + 502, + 503, + 504 + ], + "description": "HTTP status codes to retry" + }, + "retryOnNetworkError": { + "type": "boolean", + "default": true, + "description": "Retry on network errors" + }, + "jitter": { + "type": "boolean", + "default": true, + "description": "Add jitter to retry delays" + } + }, + "additionalProperties": false, + "description": "Retry configuration" + }, + "connectionTimeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 300000, + "default": 30000, + "description": "Connection timeout in ms" + }, + "requestTimeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 300000, + "default": 30000, + "description": "Request timeout in ms" + }, + "status": { + "type": "string", + "enum": [ + "active", + "inactive", + "error", + "configuring" + ], + "description": "Connector status", + "default": "inactive" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable connector" + }, + "metadata": { + "type": "object", + "additionalProperties": {}, + "description": "Custom connector metadata" + }, + "provider": { + "type": "string", + "enum": [ + "rabbitmq", + "kafka", + "redis_pubsub", + "redis_streams", + "aws_sqs", + "aws_sns", + "google_pubsub", + "azure_service_bus", + "azure_event_hubs", + "nats", + "pulsar", + "activemq", + "custom" + ], + "description": "Message queue provider type" + }, + "brokerConfig": { + "type": "object", + "properties": { + "brokers": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Broker addresses (host:port)" + }, + "clientId": { + "type": "string", + "description": "Client ID" + }, + "connectionTimeoutMs": { + "type": "number", + "minimum": 1000, + "default": 30000, + "description": "Connection timeout in ms" + }, + "requestTimeoutMs": { + "type": "number", + "minimum": 1000, + "default": 30000, + "description": "Request timeout in ms" + } + }, + "required": [ + "brokers" + ], + "additionalProperties": false, + "description": "Broker connection configuration" + }, + "topics": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Topic/queue identifier in ObjectStack (snake_case)" + }, + "label": { + "type": "string", + "description": "Display label" + }, + "topicName": { + "type": "string", + "description": "Actual topic/queue name in message queue system" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable sync for this topic/queue" + }, + "mode": { + "type": "string", + "enum": [ + "consumer", + "producer", + "both" + ], + "default": "both", + "description": "Consumer, producer, or both" + }, + "messageFormat": { + "type": "string", + "enum": [ + "json", + "xml", + "protobuf", + "avro", + "text", + "binary" + ], + "description": "Message format/serialization", + "default": "json" + }, + "partitions": { + "type": "number", + "minimum": 1, + "description": "Number of partitions (for Kafka)" + }, + "replicationFactor": { + "type": "number", + "minimum": 1, + "description": "Replication factor (for Kafka)" + }, + "consumerConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable consumer" + }, + "consumerGroup": { + "type": "string", + "description": "Consumer group ID" + }, + "concurrency": { + "type": "number", + "minimum": 1, + "maximum": 100, + "default": 1, + "description": "Number of concurrent consumers" + }, + "prefetchCount": { + "type": "number", + "minimum": 1, + "maximum": 1000, + "default": 10, + "description": "Prefetch count" + }, + "ackMode": { + "type": "string", + "enum": [ + "auto", + "manual", + "client" + ], + "description": "Message acknowledgment mode", + "default": "manual" + }, + "autoCommit": { + "type": "boolean", + "default": false, + "description": "Auto-commit offsets" + }, + "autoCommitIntervalMs": { + "type": "number", + "minimum": 100, + "default": 5000, + "description": "Auto-commit interval in ms" + }, + "sessionTimeoutMs": { + "type": "number", + "minimum": 1000, + "default": 30000, + "description": "Session timeout in ms" + }, + "rebalanceTimeoutMs": { + "type": "number", + "minimum": 1000, + "description": "Rebalance timeout in ms" + } + }, + "additionalProperties": false, + "description": "Consumer-specific configuration" + }, + "producerConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable producer" + }, + "acks": { + "type": "string", + "enum": [ + "0", + "1", + "all" + ], + "default": "all", + "description": "Acknowledgment level" + }, + "compressionType": { + "type": "string", + "enum": [ + "none", + "gzip", + "snappy", + "lz4", + "zstd" + ], + "default": "none", + "description": "Compression type" + }, + "batchSize": { + "type": "number", + "minimum": 1, + "default": 16384, + "description": "Batch size in bytes" + }, + "lingerMs": { + "type": "number", + "minimum": 0, + "default": 0, + "description": "Linger time in ms" + }, + "maxInFlightRequests": { + "type": "number", + "minimum": 1, + "default": 5, + "description": "Max in-flight requests" + }, + "idempotence": { + "type": "boolean", + "default": true, + "description": "Enable idempotent producer" + }, + "transactional": { + "type": "boolean", + "default": false, + "description": "Enable transactional producer" + }, + "transactionTimeoutMs": { + "type": "number", + "minimum": 1000, + "description": "Transaction timeout in ms" + } + }, + "additionalProperties": false, + "description": "Producer-specific configuration" + }, + "dlqConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Enable DLQ" + }, + "queueName": { + "type": "string", + "description": "Dead letter queue/topic name" + }, + "maxRetries": { + "type": "number", + "minimum": 0, + "maximum": 100, + "default": 3, + "description": "Max retries before DLQ" + }, + "retryDelayMs": { + "type": "number", + "minimum": 0, + "default": 60000, + "description": "Retry delay in ms" + } + }, + "required": [ + "queueName" + ], + "additionalProperties": false, + "description": "Dead letter queue configuration" + }, + "routingKey": { + "type": "string", + "description": "Routing key pattern" + }, + "messageFilter": { + "type": "object", + "properties": { + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Filter by message headers" + }, + "attributes": { + "type": "object", + "additionalProperties": {}, + "description": "Filter by message attributes" + } + }, + "additionalProperties": false, + "description": "Message filter criteria" + } + }, + "required": [ + "name", + "label", + "topicName" + ], + "additionalProperties": false + }, + "description": "Topics/queues to sync" + }, + "deliveryGuarantee": { + "type": "string", + "enum": [ + "at_most_once", + "at_least_once", + "exactly_once" + ], + "description": "Message delivery guarantee", + "default": "at_least_once" + }, + "sslConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Enable SSL/TLS" + }, + "rejectUnauthorized": { + "type": "boolean", + "default": true, + "description": "Reject unauthorized certificates" + }, + "ca": { + "type": "string", + "description": "CA certificate" + }, + "cert": { + "type": "string", + "description": "Client certificate" + }, + "key": { + "type": "string", + "description": "Client private key" + } + }, + "additionalProperties": false, + "description": "SSL/TLS configuration" + }, + "saslConfig": { + "type": "object", + "properties": { + "mechanism": { + "type": "string", + "enum": [ + "plain", + "scram-sha-256", + "scram-sha-512", + "aws" + ], + "description": "SASL mechanism" + }, + "username": { + "type": "string", + "description": "SASL username" + }, + "password": { + "type": "string", + "description": "SASL password" + } + }, + "required": [ + "mechanism" + ], + "additionalProperties": false, + "description": "SASL authentication configuration" + }, + "schemaRegistry": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "Schema registry URL" + }, + "auth": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "password": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "required": [ + "url" + ], + "additionalProperties": false, + "description": "Schema registry configuration" + }, + "preserveOrder": { + "type": "boolean", + "default": true, + "description": "Preserve message ordering" + }, + "enableMetrics": { + "type": "boolean", + "default": true, + "description": "Enable message queue metrics" + }, + "enableTracing": { + "type": "boolean", + "default": false, + "description": "Enable distributed tracing" + } + }, + "required": [ + "name", + "label", + "type", + "authentication", + "provider", + "brokerConfig", + "topics" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/MessageQueueProvider.json b/packages/spec/json-schema/system/MessageQueueProvider.json new file mode 100644 index 000000000..748908f29 --- /dev/null +++ b/packages/spec/json-schema/system/MessageQueueProvider.json @@ -0,0 +1,25 @@ +{ + "$ref": "#/definitions/MessageQueueProvider", + "definitions": { + "MessageQueueProvider": { + "type": "string", + "enum": [ + "rabbitmq", + "kafka", + "redis_pubsub", + "redis_streams", + "aws_sqs", + "aws_sns", + "google_pubsub", + "azure_service_bus", + "azure_event_hubs", + "nats", + "pulsar", + "activemq", + "custom" + ], + "description": "Message queue provider type" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/MultipartUploadConfig.json b/packages/spec/json-schema/system/MultipartUploadConfig.json new file mode 100644 index 000000000..118f67295 --- /dev/null +++ b/packages/spec/json-schema/system/MultipartUploadConfig.json @@ -0,0 +1,36 @@ +{ + "$ref": "#/definitions/MultipartUploadConfig", + "definitions": { + "MultipartUploadConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable multipart uploads" + }, + "partSize": { + "type": "number", + "minimum": 5242880, + "default": 5242880, + "description": "Part size in bytes (min 5MB)" + }, + "maxConcurrentParts": { + "type": "number", + "minimum": 1, + "maximum": 10, + "default": 5, + "description": "Maximum concurrent part uploads" + }, + "threshold": { + "type": "number", + "minimum": 5242880, + "default": 104857600, + "description": "File size threshold for multipart upload in bytes" + } + }, + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/NoAuth.json b/packages/spec/json-schema/system/NoAuth.json new file mode 100644 index 000000000..e363a3b90 --- /dev/null +++ b/packages/spec/json-schema/system/NoAuth.json @@ -0,0 +1,20 @@ +{ + "$ref": "#/definitions/NoAuth", + "definitions": { + "NoAuth": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "none", + "description": "No authentication required" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/OAuth2Auth.json b/packages/spec/json-schema/system/OAuth2Auth.json new file mode 100644 index 000000000..668dc3137 --- /dev/null +++ b/packages/spec/json-schema/system/OAuth2Auth.json @@ -0,0 +1,73 @@ +{ + "$ref": "#/definitions/OAuth2Auth", + "definitions": { + "OAuth2Auth": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "oauth2", + "description": "Authentication type" + }, + "clientId": { + "type": "string", + "description": "OAuth2 client ID" + }, + "clientSecret": { + "type": "string", + "description": "OAuth2 client secret (typically from ENV)" + }, + "authorizationUrl": { + "type": "string", + "format": "uri", + "description": "OAuth2 authorization endpoint" + }, + "tokenUrl": { + "type": "string", + "format": "uri", + "description": "OAuth2 token endpoint" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Requested OAuth2 scopes" + }, + "redirectUri": { + "type": "string", + "format": "uri", + "description": "OAuth2 callback URL" + }, + "grantType": { + "type": "string", + "enum": [ + "authorization_code", + "client_credentials", + "password", + "refresh_token" + ], + "default": "authorization_code", + "description": "OAuth2 grant type" + }, + "refreshToken": { + "type": "string", + "description": "Refresh token for token renewal" + }, + "tokenExpiry": { + "type": "number", + "description": "Token expiry timestamp" + } + }, + "required": [ + "type", + "clientId", + "clientSecret", + "authorizationUrl", + "tokenUrl" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/ProducerConfig.json b/packages/spec/json-schema/system/ProducerConfig.json new file mode 100644 index 000000000..fee6dd42e --- /dev/null +++ b/packages/spec/json-schema/system/ProducerConfig.json @@ -0,0 +1,72 @@ +{ + "$ref": "#/definitions/ProducerConfig", + "definitions": { + "ProducerConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable producer" + }, + "acks": { + "type": "string", + "enum": [ + "0", + "1", + "all" + ], + "default": "all", + "description": "Acknowledgment level" + }, + "compressionType": { + "type": "string", + "enum": [ + "none", + "gzip", + "snappy", + "lz4", + "zstd" + ], + "default": "none", + "description": "Compression type" + }, + "batchSize": { + "type": "number", + "minimum": 1, + "default": 16384, + "description": "Batch size in bytes" + }, + "lingerMs": { + "type": "number", + "minimum": 0, + "default": 0, + "description": "Linger time in ms" + }, + "maxInFlightRequests": { + "type": "number", + "minimum": 1, + "default": 5, + "description": "Max in-flight requests" + }, + "idempotence": { + "type": "boolean", + "default": true, + "description": "Enable idempotent producer" + }, + "transactional": { + "type": "boolean", + "default": false, + "description": "Enable transactional producer" + }, + "transactionTimeoutMs": { + "type": "number", + "minimum": 1000, + "description": "Transaction timeout in ms" + } + }, + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/RateLimitConfig.json b/packages/spec/json-schema/system/RateLimitConfig.json new file mode 100644 index 000000000..144648410 --- /dev/null +++ b/packages/spec/json-schema/system/RateLimitConfig.json @@ -0,0 +1,69 @@ +{ + "$ref": "#/definitions/RateLimitConfig", + "definitions": { + "RateLimitConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "fixed_window", + "sliding_window", + "token_bucket", + "leaky_bucket" + ], + "description": "Rate limiting strategy", + "default": "token_bucket" + }, + "maxRequests": { + "type": "number", + "minimum": 1, + "description": "Maximum requests per window" + }, + "windowSeconds": { + "type": "number", + "minimum": 1, + "description": "Time window in seconds" + }, + "burstCapacity": { + "type": "number", + "minimum": 1, + "description": "Burst capacity" + }, + "respectUpstreamLimits": { + "type": "boolean", + "default": true, + "description": "Respect external rate limit headers" + }, + "rateLimitHeaders": { + "type": "object", + "properties": { + "remaining": { + "type": "string", + "default": "X-RateLimit-Remaining", + "description": "Header for remaining requests" + }, + "limit": { + "type": "string", + "default": "X-RateLimit-Limit", + "description": "Header for rate limit" + }, + "reset": { + "type": "string", + "default": "X-RateLimit-Reset", + "description": "Header for reset time" + } + }, + "additionalProperties": false, + "description": "Custom rate limit headers" + } + }, + "required": [ + "maxRequests", + "windowSeconds" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/RateLimitStrategy.json b/packages/spec/json-schema/system/RateLimitStrategy.json new file mode 100644 index 000000000..c4fae0815 --- /dev/null +++ b/packages/spec/json-schema/system/RateLimitStrategy.json @@ -0,0 +1,16 @@ +{ + "$ref": "#/definitions/RateLimitStrategy", + "definitions": { + "RateLimitStrategy": { + "type": "string", + "enum": [ + "fixed_window", + "sliding_window", + "token_bucket", + "leaky_bucket" + ], + "description": "Rate limiting strategy" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/RetryConfig.json b/packages/spec/json-schema/system/RetryConfig.json new file mode 100644 index 000000000..8dd7fca6e --- /dev/null +++ b/packages/spec/json-schema/system/RetryConfig.json @@ -0,0 +1,73 @@ +{ + "$ref": "#/definitions/RetryConfig", + "definitions": { + "RetryConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "exponential_backoff", + "linear_backoff", + "fixed_delay", + "no_retry" + ], + "description": "Retry strategy", + "default": "exponential_backoff" + }, + "maxAttempts": { + "type": "number", + "minimum": 0, + "maximum": 10, + "default": 3, + "description": "Maximum retry attempts" + }, + "initialDelayMs": { + "type": "number", + "minimum": 100, + "default": 1000, + "description": "Initial retry delay in ms" + }, + "maxDelayMs": { + "type": "number", + "minimum": 1000, + "default": 60000, + "description": "Maximum retry delay in ms" + }, + "backoffMultiplier": { + "type": "number", + "minimum": 1, + "default": 2, + "description": "Exponential backoff multiplier" + }, + "retryableStatusCodes": { + "type": "array", + "items": { + "type": "number" + }, + "default": [ + 408, + 429, + 500, + 502, + 503, + 504 + ], + "description": "HTTP status codes to retry" + }, + "retryOnNetworkError": { + "type": "boolean", + "default": true, + "description": "Retry on network errors" + }, + "jitter": { + "type": "boolean", + "default": true, + "description": "Add jitter to retry delays" + } + }, + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/RetryStrategy.json b/packages/spec/json-schema/system/RetryStrategy.json new file mode 100644 index 000000000..ebb0f30ce --- /dev/null +++ b/packages/spec/json-schema/system/RetryStrategy.json @@ -0,0 +1,16 @@ +{ + "$ref": "#/definitions/RetryStrategy", + "definitions": { + "RetryStrategy": { + "type": "string", + "enum": [ + "exponential_backoff", + "linear_backoff", + "fixed_delay", + "no_retry" + ], + "description": "Retry strategy" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/SaasConnector.json b/packages/spec/json-schema/system/SaasConnector.json new file mode 100644 index 000000000..857143334 --- /dev/null +++ b/packages/spec/json-schema/system/SaasConnector.json @@ -0,0 +1,1009 @@ +{ + "$ref": "#/definitions/SaasConnector", + "definitions": { + "SaasConnector": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Unique connector identifier" + }, + "label": { + "type": "string", + "description": "Display label" + }, + "type": { + "type": "string", + "const": "saas" + }, + "description": { + "type": "string", + "description": "Connector description" + }, + "icon": { + "type": "string", + "description": "Icon identifier" + }, + "authentication": { + "anyOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "api_key", + "description": "Authentication type" + }, + "apiKey": { + "type": "string", + "description": "API key (typically from ENV)" + }, + "headerName": { + "type": "string", + "default": "X-API-Key", + "description": "HTTP header name for API key" + }, + "paramName": { + "type": "string", + "description": "Query parameter name (alternative to header)" + } + }, + "required": [ + "type", + "apiKey" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "oauth2", + "description": "Authentication type" + }, + "clientId": { + "type": "string", + "description": "OAuth2 client ID" + }, + "clientSecret": { + "type": "string", + "description": "OAuth2 client secret (typically from ENV)" + }, + "authorizationUrl": { + "type": "string", + "format": "uri", + "description": "OAuth2 authorization endpoint" + }, + "tokenUrl": { + "type": "string", + "format": "uri", + "description": "OAuth2 token endpoint" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Requested OAuth2 scopes" + }, + "redirectUri": { + "type": "string", + "format": "uri", + "description": "OAuth2 callback URL" + }, + "grantType": { + "type": "string", + "enum": [ + "authorization_code", + "client_credentials", + "password", + "refresh_token" + ], + "default": "authorization_code", + "description": "OAuth2 grant type" + }, + "refreshToken": { + "type": "string", + "description": "Refresh token for token renewal" + }, + "tokenExpiry": { + "type": "number", + "description": "Token expiry timestamp" + } + }, + "required": [ + "type", + "clientId", + "clientSecret", + "authorizationUrl", + "tokenUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "jwt", + "description": "Authentication type" + }, + "token": { + "type": "string", + "description": "Pre-generated JWT token" + }, + "secretKey": { + "type": "string", + "description": "Secret key for JWT signing" + }, + "algorithm": { + "type": "string", + "enum": [ + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512" + ], + "default": "HS256", + "description": "JWT signing algorithm" + }, + "issuer": { + "type": "string", + "description": "JWT issuer claim" + }, + "audience": { + "type": "string", + "description": "JWT audience claim" + }, + "subject": { + "type": "string", + "description": "JWT subject claim" + }, + "expiresIn": { + "type": "number", + "default": 3600, + "description": "Token expiry in seconds" + }, + "claims": { + "type": "object", + "additionalProperties": {}, + "description": "Additional JWT claims" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "saml", + "description": "Authentication type" + }, + "entryPoint": { + "type": "string", + "format": "uri", + "description": "SAML IdP entry point URL" + }, + "issuer": { + "type": "string", + "description": "SAML service provider issuer" + }, + "certificate": { + "type": "string", + "description": "SAML IdP certificate (X.509)" + }, + "privateKey": { + "type": "string", + "description": "SAML service provider private key" + }, + "callbackUrl": { + "type": "string", + "format": "uri", + "description": "SAML assertion consumer service URL" + }, + "signatureAlgorithm": { + "type": "string", + "enum": [ + "sha1", + "sha256", + "sha512" + ], + "default": "sha256", + "description": "SAML signature algorithm" + }, + "wantAssertionsSigned": { + "type": "boolean", + "default": true, + "description": "Require signed SAML assertions" + }, + "identifierFormat": { + "type": "string", + "description": "SAML NameID format" + } + }, + "required": [ + "type", + "entryPoint", + "issuer", + "certificate" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "basic", + "description": "Authentication type" + }, + "username": { + "type": "string", + "description": "Username" + }, + "password": { + "type": "string", + "description": "Password (typically from ENV)" + } + }, + "required": [ + "type", + "username", + "password" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "bearer", + "description": "Authentication type" + }, + "token": { + "type": "string", + "description": "Bearer token" + } + }, + "required": [ + "type", + "token" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "none", + "description": "No authentication required" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + ], + "description": "Authentication configuration" + }, + "syncConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "full", + "incremental", + "upsert", + "append_only" + ], + "description": "Synchronization strategy", + "default": "incremental" + }, + "direction": { + "type": "string", + "enum": [ + "import", + "export", + "bidirectional" + ], + "default": "import", + "description": "Sync direction" + }, + "schedule": { + "type": "string", + "description": "Cron expression for scheduled sync" + }, + "realtimeSync": { + "type": "boolean", + "default": false, + "description": "Enable real-time sync" + }, + "timestampField": { + "type": "string", + "description": "Field to track last modification time" + }, + "conflictResolution": { + "type": "string", + "enum": [ + "source_wins", + "target_wins", + "latest_wins", + "manual" + ], + "description": "Conflict resolution strategy", + "default": "latest_wins" + }, + "batchSize": { + "type": "number", + "minimum": 1, + "maximum": 10000, + "default": 1000, + "description": "Records per batch" + }, + "deleteMode": { + "type": "string", + "enum": [ + "hard_delete", + "soft_delete", + "ignore" + ], + "default": "soft_delete", + "description": "Delete handling mode" + }, + "filters": { + "type": "object", + "additionalProperties": {}, + "description": "Filter criteria for selective sync" + } + }, + "additionalProperties": false, + "description": "Data sync configuration" + }, + "fieldMappings": { + "type": "array", + "items": { + "type": "object", + "properties": { + "sourceField": { + "type": "string", + "description": "Field name in external system" + }, + "targetField": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Field name in ObjectStack (snake_case)" + }, + "dataType": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "date", + "datetime", + "json", + "array" + ], + "description": "Target data type" + }, + "required": { + "type": "boolean", + "default": false, + "description": "Field is required" + }, + "defaultValue": { + "description": "Default value" + }, + "transform": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "uppercase", + "lowercase", + "trim", + "date_format", + "number_format", + "custom" + ], + "description": "Transformation type" + }, + "params": { + "type": "object", + "additionalProperties": {}, + "description": "Transformation parameters" + }, + "function": { + "type": "string", + "description": "Custom JavaScript function for transformation" + } + }, + "required": [ + "type" + ], + "additionalProperties": false, + "description": "Field transformation" + }, + "syncMode": { + "type": "string", + "enum": [ + "read_only", + "write_only", + "bidirectional" + ], + "default": "bidirectional", + "description": "Sync mode" + } + }, + "required": [ + "sourceField", + "targetField" + ], + "additionalProperties": false + }, + "description": "Field mapping rules" + }, + "webhooks": { + "type": "array", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "Webhook endpoint URL" + }, + "events": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "record.created", + "record.updated", + "record.deleted", + "sync.started", + "sync.completed", + "sync.failed", + "auth.expired", + "rate_limit.exceeded" + ], + "description": "Webhook event type" + }, + "description": "Events to subscribe to" + }, + "secret": { + "type": "string", + "description": "Secret for HMAC signature" + }, + "signatureAlgorithm": { + "type": "string", + "enum": [ + "hmac_sha256", + "hmac_sha512", + "none" + ], + "description": "Webhook signature algorithm", + "default": "hmac_sha256" + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Custom HTTP headers" + }, + "retryConfig": { + "type": "object", + "properties": { + "maxAttempts": { + "type": "number", + "minimum": 0, + "maximum": 10, + "default": 3, + "description": "Maximum retry attempts" + }, + "backoffMultiplier": { + "type": "number", + "minimum": 1, + "default": 2, + "description": "Exponential backoff multiplier" + }, + "initialDelayMs": { + "type": "number", + "minimum": 100, + "default": 1000, + "description": "Initial retry delay in ms" + } + }, + "additionalProperties": false, + "description": "Retry configuration" + }, + "timeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 60000, + "default": 30000, + "description": "Request timeout in ms" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable webhook" + } + }, + "required": [ + "url", + "events" + ], + "additionalProperties": false + }, + "description": "Webhook configurations" + }, + "rateLimitConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "fixed_window", + "sliding_window", + "token_bucket", + "leaky_bucket" + ], + "description": "Rate limiting strategy", + "default": "token_bucket" + }, + "maxRequests": { + "type": "number", + "minimum": 1, + "description": "Maximum requests per window" + }, + "windowSeconds": { + "type": "number", + "minimum": 1, + "description": "Time window in seconds" + }, + "burstCapacity": { + "type": "number", + "minimum": 1, + "description": "Burst capacity" + }, + "respectUpstreamLimits": { + "type": "boolean", + "default": true, + "description": "Respect external rate limit headers" + }, + "rateLimitHeaders": { + "type": "object", + "properties": { + "remaining": { + "type": "string", + "default": "X-RateLimit-Remaining", + "description": "Header for remaining requests" + }, + "limit": { + "type": "string", + "default": "X-RateLimit-Limit", + "description": "Header for rate limit" + }, + "reset": { + "type": "string", + "default": "X-RateLimit-Reset", + "description": "Header for reset time" + } + }, + "additionalProperties": false, + "description": "Custom rate limit headers" + } + }, + "required": [ + "maxRequests", + "windowSeconds" + ], + "additionalProperties": false, + "description": "Rate limiting configuration" + }, + "retryConfig": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "exponential_backoff", + "linear_backoff", + "fixed_delay", + "no_retry" + ], + "description": "Retry strategy", + "default": "exponential_backoff" + }, + "maxAttempts": { + "type": "number", + "minimum": 0, + "maximum": 10, + "default": 3, + "description": "Maximum retry attempts" + }, + "initialDelayMs": { + "type": "number", + "minimum": 100, + "default": 1000, + "description": "Initial retry delay in ms" + }, + "maxDelayMs": { + "type": "number", + "minimum": 1000, + "default": 60000, + "description": "Maximum retry delay in ms" + }, + "backoffMultiplier": { + "type": "number", + "minimum": 1, + "default": 2, + "description": "Exponential backoff multiplier" + }, + "retryableStatusCodes": { + "type": "array", + "items": { + "type": "number" + }, + "default": [ + 408, + 429, + 500, + 502, + 503, + 504 + ], + "description": "HTTP status codes to retry" + }, + "retryOnNetworkError": { + "type": "boolean", + "default": true, + "description": "Retry on network errors" + }, + "jitter": { + "type": "boolean", + "default": true, + "description": "Add jitter to retry delays" + } + }, + "additionalProperties": false, + "description": "Retry configuration" + }, + "connectionTimeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 300000, + "default": 30000, + "description": "Connection timeout in ms" + }, + "requestTimeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 300000, + "default": 30000, + "description": "Request timeout in ms" + }, + "status": { + "type": "string", + "enum": [ + "active", + "inactive", + "error", + "configuring" + ], + "description": "Connector status", + "default": "inactive" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable connector" + }, + "metadata": { + "type": "object", + "additionalProperties": {}, + "description": "Custom connector metadata" + }, + "provider": { + "type": "string", + "enum": [ + "salesforce", + "hubspot", + "stripe", + "shopify", + "zendesk", + "intercom", + "mailchimp", + "slack", + "microsoft_dynamics", + "servicenow", + "netsuite", + "custom" + ], + "description": "SaaS provider type" + }, + "baseUrl": { + "type": "string", + "format": "uri", + "description": "API base URL" + }, + "apiVersion": { + "type": "object", + "properties": { + "version": { + "type": "string", + "description": "API version (e.g., \"v2\", \"2023-10-01\")" + }, + "isDefault": { + "type": "boolean", + "default": false, + "description": "Is this the default version" + }, + "deprecationDate": { + "type": "string", + "description": "API version deprecation date (ISO 8601)" + }, + "sunsetDate": { + "type": "string", + "description": "API version sunset date (ISO 8601)" + } + }, + "required": [ + "version" + ], + "additionalProperties": false, + "description": "API version configuration" + }, + "objectTypes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Object type name (snake_case)" + }, + "label": { + "type": "string", + "description": "Display label" + }, + "apiName": { + "type": "string", + "description": "API name in external system" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable sync for this object" + }, + "supportsCreate": { + "type": "boolean", + "default": true, + "description": "Supports record creation" + }, + "supportsUpdate": { + "type": "boolean", + "default": true, + "description": "Supports record updates" + }, + "supportsDelete": { + "type": "boolean", + "default": true, + "description": "Supports record deletion" + }, + "fieldMappings": { + "type": "array", + "items": { + "type": "object", + "properties": { + "sourceField": { + "type": "string", + "description": "Field name in external system" + }, + "targetField": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Field name in ObjectStack (snake_case)" + }, + "dataType": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "date", + "datetime", + "json", + "array" + ], + "description": "Target data type" + }, + "required": { + "type": "boolean", + "default": false, + "description": "Field is required" + }, + "defaultValue": { + "description": "Default value" + }, + "transform": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "uppercase", + "lowercase", + "trim", + "date_format", + "number_format", + "custom" + ], + "description": "Transformation type" + }, + "params": { + "type": "object", + "additionalProperties": {}, + "description": "Transformation parameters" + }, + "function": { + "type": "string", + "description": "Custom JavaScript function for transformation" + } + }, + "required": [ + "type" + ], + "additionalProperties": false, + "description": "Field transformation" + }, + "syncMode": { + "type": "string", + "enum": [ + "read_only", + "write_only", + "bidirectional" + ], + "default": "bidirectional", + "description": "Sync mode" + } + }, + "required": [ + "sourceField", + "targetField" + ], + "additionalProperties": false + }, + "description": "Object-specific field mappings" + } + }, + "required": [ + "name", + "label", + "apiName" + ], + "additionalProperties": false + }, + "description": "Syncable object types" + }, + "oauthSettings": { + "type": "object", + "properties": { + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Required OAuth scopes" + }, + "refreshTokenUrl": { + "type": "string", + "format": "uri", + "description": "Token refresh endpoint" + }, + "revokeTokenUrl": { + "type": "string", + "format": "uri", + "description": "Token revocation endpoint" + }, + "autoRefresh": { + "type": "boolean", + "default": true, + "description": "Automatically refresh expired tokens" + } + }, + "required": [ + "scopes" + ], + "additionalProperties": false, + "description": "OAuth-specific configuration" + }, + "paginationConfig": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "cursor", + "offset", + "page" + ], + "default": "cursor", + "description": "Pagination type" + }, + "defaultPageSize": { + "type": "number", + "minimum": 1, + "maximum": 1000, + "default": 100, + "description": "Default page size" + }, + "maxPageSize": { + "type": "number", + "minimum": 1, + "maximum": 10000, + "default": 1000, + "description": "Maximum page size" + } + }, + "additionalProperties": false, + "description": "Pagination configuration" + }, + "sandboxConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Use sandbox environment" + }, + "baseUrl": { + "type": "string", + "format": "uri", + "description": "Sandbox API base URL" + } + }, + "additionalProperties": false, + "description": "Sandbox environment configuration" + }, + "customHeaders": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Custom HTTP headers for all requests" + } + }, + "required": [ + "name", + "label", + "type", + "authentication", + "provider", + "baseUrl", + "objectTypes" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/SaasObjectType.json b/packages/spec/json-schema/system/SaasObjectType.json new file mode 100644 index 000000000..def5803c5 --- /dev/null +++ b/packages/spec/json-schema/system/SaasObjectType.json @@ -0,0 +1,135 @@ +{ + "$ref": "#/definitions/SaasObjectType", + "definitions": { + "SaasObjectType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Object type name (snake_case)" + }, + "label": { + "type": "string", + "description": "Display label" + }, + "apiName": { + "type": "string", + "description": "API name in external system" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable sync for this object" + }, + "supportsCreate": { + "type": "boolean", + "default": true, + "description": "Supports record creation" + }, + "supportsUpdate": { + "type": "boolean", + "default": true, + "description": "Supports record updates" + }, + "supportsDelete": { + "type": "boolean", + "default": true, + "description": "Supports record deletion" + }, + "fieldMappings": { + "type": "array", + "items": { + "type": "object", + "properties": { + "sourceField": { + "type": "string", + "description": "Field name in external system" + }, + "targetField": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Field name in ObjectStack (snake_case)" + }, + "dataType": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "date", + "datetime", + "json", + "array" + ], + "description": "Target data type" + }, + "required": { + "type": "boolean", + "default": false, + "description": "Field is required" + }, + "defaultValue": { + "description": "Default value" + }, + "transform": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "uppercase", + "lowercase", + "trim", + "date_format", + "number_format", + "custom" + ], + "description": "Transformation type" + }, + "params": { + "type": "object", + "additionalProperties": {}, + "description": "Transformation parameters" + }, + "function": { + "type": "string", + "description": "Custom JavaScript function for transformation" + } + }, + "required": [ + "type" + ], + "additionalProperties": false, + "description": "Field transformation" + }, + "syncMode": { + "type": "string", + "enum": [ + "read_only", + "write_only", + "bidirectional" + ], + "default": "bidirectional", + "description": "Sync mode" + } + }, + "required": [ + "sourceField", + "targetField" + ], + "additionalProperties": false + }, + "description": "Object-specific field mappings" + } + }, + "required": [ + "name", + "label", + "apiName" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/SaasProvider.json b/packages/spec/json-schema/system/SaasProvider.json new file mode 100644 index 000000000..d73280ee2 --- /dev/null +++ b/packages/spec/json-schema/system/SaasProvider.json @@ -0,0 +1,24 @@ +{ + "$ref": "#/definitions/SaasProvider", + "definitions": { + "SaasProvider": { + "type": "string", + "enum": [ + "salesforce", + "hubspot", + "stripe", + "shopify", + "zendesk", + "intercom", + "mailchimp", + "slack", + "microsoft_dynamics", + "servicenow", + "netsuite", + "custom" + ], + "description": "SaaS provider type" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/SamlAuth.json b/packages/spec/json-schema/system/SamlAuth.json new file mode 100644 index 000000000..8994c177b --- /dev/null +++ b/packages/spec/json-schema/system/SamlAuth.json @@ -0,0 +1,64 @@ +{ + "$ref": "#/definitions/SamlAuth", + "definitions": { + "SamlAuth": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "saml", + "description": "Authentication type" + }, + "entryPoint": { + "type": "string", + "format": "uri", + "description": "SAML IdP entry point URL" + }, + "issuer": { + "type": "string", + "description": "SAML service provider issuer" + }, + "certificate": { + "type": "string", + "description": "SAML IdP certificate (X.509)" + }, + "privateKey": { + "type": "string", + "description": "SAML service provider private key" + }, + "callbackUrl": { + "type": "string", + "format": "uri", + "description": "SAML assertion consumer service URL" + }, + "signatureAlgorithm": { + "type": "string", + "enum": [ + "sha1", + "sha256", + "sha512" + ], + "default": "sha256", + "description": "SAML signature algorithm" + }, + "wantAssertionsSigned": { + "type": "boolean", + "default": true, + "description": "Require signed SAML assertions" + }, + "identifierFormat": { + "type": "string", + "description": "SAML NameID format" + } + }, + "required": [ + "type", + "entryPoint", + "issuer", + "certificate" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/SslConfig.json b/packages/spec/json-schema/system/SslConfig.json new file mode 100644 index 000000000..27688e971 --- /dev/null +++ b/packages/spec/json-schema/system/SslConfig.json @@ -0,0 +1,34 @@ +{ + "$ref": "#/definitions/SslConfig", + "definitions": { + "SslConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Enable SSL/TLS" + }, + "rejectUnauthorized": { + "type": "boolean", + "default": true, + "description": "Reject unauthorized certificates" + }, + "ca": { + "type": "string", + "description": "Certificate Authority certificate" + }, + "cert": { + "type": "string", + "description": "Client certificate" + }, + "key": { + "type": "string", + "description": "Client private key" + } + }, + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/StorageBucket.json b/packages/spec/json-schema/system/StorageBucket.json new file mode 100644 index 000000000..a42780be9 --- /dev/null +++ b/packages/spec/json-schema/system/StorageBucket.json @@ -0,0 +1,99 @@ +{ + "$ref": "#/definitions/StorageBucket", + "definitions": { + "StorageBucket": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Bucket identifier in ObjectStack (snake_case)" + }, + "label": { + "type": "string", + "description": "Display label" + }, + "bucketName": { + "type": "string", + "description": "Actual bucket/container name in storage system" + }, + "region": { + "type": "string", + "description": "Storage region" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable sync for this bucket" + }, + "prefix": { + "type": "string", + "description": "Prefix/path within bucket" + }, + "accessPattern": { + "type": "string", + "enum": [ + "public_read", + "private", + "authenticated_read", + "bucket_owner_read", + "bucket_owner_full" + ], + "description": "Access pattern" + }, + "fileFilters": { + "type": "object", + "properties": { + "includePatterns": { + "type": "array", + "items": { + "type": "string" + }, + "description": "File patterns to include (glob)" + }, + "excludePatterns": { + "type": "array", + "items": { + "type": "string" + }, + "description": "File patterns to exclude (glob)" + }, + "minFileSize": { + "type": "number", + "minimum": 0, + "description": "Minimum file size in bytes" + }, + "maxFileSize": { + "type": "number", + "minimum": 1, + "description": "Maximum file size in bytes" + }, + "allowedExtensions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Allowed file extensions" + }, + "blockedExtensions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Blocked file extensions" + } + }, + "additionalProperties": false, + "description": "File filter configuration" + } + }, + "required": [ + "name", + "label", + "bucketName" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/SyncStrategy.json b/packages/spec/json-schema/system/SyncStrategy.json new file mode 100644 index 000000000..f48df7c84 --- /dev/null +++ b/packages/spec/json-schema/system/SyncStrategy.json @@ -0,0 +1,16 @@ +{ + "$ref": "#/definitions/SyncStrategy", + "definitions": { + "SyncStrategy": { + "type": "string", + "enum": [ + "full", + "incremental", + "upsert", + "append_only" + ], + "description": "Synchronization strategy" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/TopicQueue.json b/packages/spec/json-schema/system/TopicQueue.json new file mode 100644 index 000000000..0860da236 --- /dev/null +++ b/packages/spec/json-schema/system/TopicQueue.json @@ -0,0 +1,252 @@ +{ + "$ref": "#/definitions/TopicQueue", + "definitions": { + "TopicQueue": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Topic/queue identifier in ObjectStack (snake_case)" + }, + "label": { + "type": "string", + "description": "Display label" + }, + "topicName": { + "type": "string", + "description": "Actual topic/queue name in message queue system" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable sync for this topic/queue" + }, + "mode": { + "type": "string", + "enum": [ + "consumer", + "producer", + "both" + ], + "default": "both", + "description": "Consumer, producer, or both" + }, + "messageFormat": { + "type": "string", + "enum": [ + "json", + "xml", + "protobuf", + "avro", + "text", + "binary" + ], + "description": "Message format/serialization", + "default": "json" + }, + "partitions": { + "type": "number", + "minimum": 1, + "description": "Number of partitions (for Kafka)" + }, + "replicationFactor": { + "type": "number", + "minimum": 1, + "description": "Replication factor (for Kafka)" + }, + "consumerConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable consumer" + }, + "consumerGroup": { + "type": "string", + "description": "Consumer group ID" + }, + "concurrency": { + "type": "number", + "minimum": 1, + "maximum": 100, + "default": 1, + "description": "Number of concurrent consumers" + }, + "prefetchCount": { + "type": "number", + "minimum": 1, + "maximum": 1000, + "default": 10, + "description": "Prefetch count" + }, + "ackMode": { + "type": "string", + "enum": [ + "auto", + "manual", + "client" + ], + "description": "Message acknowledgment mode", + "default": "manual" + }, + "autoCommit": { + "type": "boolean", + "default": false, + "description": "Auto-commit offsets" + }, + "autoCommitIntervalMs": { + "type": "number", + "minimum": 100, + "default": 5000, + "description": "Auto-commit interval in ms" + }, + "sessionTimeoutMs": { + "type": "number", + "minimum": 1000, + "default": 30000, + "description": "Session timeout in ms" + }, + "rebalanceTimeoutMs": { + "type": "number", + "minimum": 1000, + "description": "Rebalance timeout in ms" + } + }, + "additionalProperties": false, + "description": "Consumer-specific configuration" + }, + "producerConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable producer" + }, + "acks": { + "type": "string", + "enum": [ + "0", + "1", + "all" + ], + "default": "all", + "description": "Acknowledgment level" + }, + "compressionType": { + "type": "string", + "enum": [ + "none", + "gzip", + "snappy", + "lz4", + "zstd" + ], + "default": "none", + "description": "Compression type" + }, + "batchSize": { + "type": "number", + "minimum": 1, + "default": 16384, + "description": "Batch size in bytes" + }, + "lingerMs": { + "type": "number", + "minimum": 0, + "default": 0, + "description": "Linger time in ms" + }, + "maxInFlightRequests": { + "type": "number", + "minimum": 1, + "default": 5, + "description": "Max in-flight requests" + }, + "idempotence": { + "type": "boolean", + "default": true, + "description": "Enable idempotent producer" + }, + "transactional": { + "type": "boolean", + "default": false, + "description": "Enable transactional producer" + }, + "transactionTimeoutMs": { + "type": "number", + "minimum": 1000, + "description": "Transaction timeout in ms" + } + }, + "additionalProperties": false, + "description": "Producer-specific configuration" + }, + "dlqConfig": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "Enable DLQ" + }, + "queueName": { + "type": "string", + "description": "Dead letter queue/topic name" + }, + "maxRetries": { + "type": "number", + "minimum": 0, + "maximum": 100, + "default": 3, + "description": "Max retries before DLQ" + }, + "retryDelayMs": { + "type": "number", + "minimum": 0, + "default": 60000, + "description": "Retry delay in ms" + } + }, + "required": [ + "queueName" + ], + "additionalProperties": false, + "description": "Dead letter queue configuration" + }, + "routingKey": { + "type": "string", + "description": "Routing key pattern" + }, + "messageFilter": { + "type": "object", + "properties": { + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Filter by message headers" + }, + "attributes": { + "type": "object", + "additionalProperties": {}, + "description": "Filter by message attributes" + } + }, + "additionalProperties": false, + "description": "Message filter criteria" + } + }, + "required": [ + "name", + "label", + "topicName" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/WebhookConfig.json b/packages/spec/json-schema/system/WebhookConfig.json new file mode 100644 index 000000000..cccf0050c --- /dev/null +++ b/packages/spec/json-schema/system/WebhookConfig.json @@ -0,0 +1,98 @@ +{ + "$ref": "#/definitions/WebhookConfig", + "definitions": { + "WebhookConfig": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "Webhook endpoint URL" + }, + "events": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "record.created", + "record.updated", + "record.deleted", + "sync.started", + "sync.completed", + "sync.failed", + "auth.expired", + "rate_limit.exceeded" + ], + "description": "Webhook event type" + }, + "description": "Events to subscribe to" + }, + "secret": { + "type": "string", + "description": "Secret for HMAC signature" + }, + "signatureAlgorithm": { + "type": "string", + "enum": [ + "hmac_sha256", + "hmac_sha512", + "none" + ], + "description": "Webhook signature algorithm", + "default": "hmac_sha256" + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Custom HTTP headers" + }, + "retryConfig": { + "type": "object", + "properties": { + "maxAttempts": { + "type": "number", + "minimum": 0, + "maximum": 10, + "default": 3, + "description": "Maximum retry attempts" + }, + "backoffMultiplier": { + "type": "number", + "minimum": 1, + "default": 2, + "description": "Exponential backoff multiplier" + }, + "initialDelayMs": { + "type": "number", + "minimum": 100, + "default": 1000, + "description": "Initial retry delay in ms" + } + }, + "additionalProperties": false, + "description": "Retry configuration" + }, + "timeoutMs": { + "type": "number", + "minimum": 1000, + "maximum": 60000, + "default": 30000, + "description": "Request timeout in ms" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Enable webhook" + } + }, + "required": [ + "url", + "events" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/WebhookEvent.json b/packages/spec/json-schema/system/WebhookEvent.json new file mode 100644 index 000000000..6deaf08e6 --- /dev/null +++ b/packages/spec/json-schema/system/WebhookEvent.json @@ -0,0 +1,20 @@ +{ + "$ref": "#/definitions/WebhookEvent", + "definitions": { + "WebhookEvent": { + "type": "string", + "enum": [ + "record.created", + "record.updated", + "record.deleted", + "sync.started", + "sync.completed", + "sync.failed", + "auth.expired", + "rate_limit.exceeded" + ], + "description": "Webhook event type" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/system/WebhookSignatureAlgorithm.json b/packages/spec/json-schema/system/WebhookSignatureAlgorithm.json new file mode 100644 index 000000000..6d6ba3efd --- /dev/null +++ b/packages/spec/json-schema/system/WebhookSignatureAlgorithm.json @@ -0,0 +1,15 @@ +{ + "$ref": "#/definitions/WebhookSignatureAlgorithm", + "definitions": { + "WebhookSignatureAlgorithm": { + "type": "string", + "enum": [ + "hmac_sha256", + "hmac_sha512", + "none" + ], + "description": "Webhook signature algorithm" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/src/system/connector.zod.ts b/packages/spec/src/system/connector.zod.ts index e8d56b592..65bdb7396 100644 --- a/packages/spec/src/system/connector.zod.ts +++ b/packages/spec/src/system/connector.zod.ts @@ -275,7 +275,7 @@ export const DataSyncConfigSchema = z.object({ /** * Sync strategy */ - strategy: SyncStrategySchema.default('incremental'), + strategy: SyncStrategySchema.optional().default('incremental'), /** * Sync direction @@ -284,7 +284,7 @@ export const DataSyncConfigSchema = z.object({ 'import', // External → ObjectStack 'export', // ObjectStack → External 'bidirectional', // Both ways - ]).default('import').describe('Sync direction'), + ]).optional().default('import').describe('Sync direction'), /** * Sync frequency (cron expression) @@ -294,7 +294,7 @@ export const DataSyncConfigSchema = z.object({ /** * Enable real-time sync via webhooks */ - realtimeSync: z.boolean().default(false).describe('Enable real-time sync'), + realtimeSync: z.boolean().optional().default(false).describe('Enable real-time sync'), /** * Field to track last sync timestamp @@ -304,12 +304,12 @@ export const DataSyncConfigSchema = z.object({ /** * Conflict resolution strategy */ - conflictResolution: ConflictResolutionSchema.default('latest_wins'), + conflictResolution: ConflictResolutionSchema.optional().default('latest_wins'), /** * Batch size for bulk operations */ - batchSize: z.number().min(1).max(10000).default(1000).describe('Records per batch'), + batchSize: z.number().min(1).max(10000).optional().default(1000).describe('Records per batch'), /** * Delete handling @@ -318,7 +318,7 @@ export const DataSyncConfigSchema = z.object({ 'hard_delete', // Permanently delete 'soft_delete', // Mark as deleted 'ignore', // Don't sync deletions - ]).default('soft_delete').describe('Delete handling mode'), + ]).optional().default('soft_delete').describe('Delete handling mode'), /** * Filter criteria for selective sync @@ -381,7 +381,7 @@ export const WebhookConfigSchema = z.object({ /** * Signature algorithm */ - signatureAlgorithm: WebhookSignatureAlgorithmSchema.default('hmac_sha256'), + signatureAlgorithm: WebhookSignatureAlgorithmSchema.optional().default('hmac_sha256'), /** * Custom headers to include in webhook requests @@ -392,20 +392,20 @@ export const WebhookConfigSchema = z.object({ * Retry configuration for failed webhook deliveries */ retryConfig: z.object({ - maxAttempts: z.number().min(0).max(10).default(3).describe('Maximum retry attempts'), - backoffMultiplier: z.number().min(1).default(2).describe('Exponential backoff multiplier'), - initialDelayMs: z.number().min(100).default(1000).describe('Initial retry delay in ms'), + maxAttempts: z.number().min(0).max(10).optional().default(3).describe('Maximum retry attempts'), + backoffMultiplier: z.number().min(1).optional().default(2).describe('Exponential backoff multiplier'), + initialDelayMs: z.number().min(100).optional().default(1000).describe('Initial retry delay in ms'), }).optional().describe('Retry configuration'), /** * Timeout for webhook requests */ - timeoutMs: z.number().min(1000).max(60000).default(30000).describe('Request timeout in ms'), + timeoutMs: z.number().min(1000).max(60000).optional().default(30000).describe('Request timeout in ms'), /** * Enable webhook */ - enabled: z.boolean().default(true).describe('Enable webhook'), + enabled: z.boolean().optional().default(true).describe('Enable webhook'), }); export type WebhookConfig = z.infer; @@ -433,7 +433,7 @@ export const RateLimitConfigSchema = z.object({ /** * Rate limiting strategy */ - strategy: RateLimitStrategySchema.default('token_bucket'), + strategy: RateLimitStrategySchema.optional().default('token_bucket'), /** * Maximum requests per window @@ -453,15 +453,15 @@ export const RateLimitConfigSchema = z.object({ /** * Respect external system rate limits */ - respectUpstreamLimits: z.boolean().default(true).describe('Respect external rate limit headers'), + respectUpstreamLimits: z.boolean().optional().default(true).describe('Respect external rate limit headers'), /** * Custom rate limit headers to check */ rateLimitHeaders: z.object({ - remaining: z.string().default('X-RateLimit-Remaining').describe('Header for remaining requests'), - limit: z.string().default('X-RateLimit-Limit').describe('Header for rate limit'), - reset: z.string().default('X-RateLimit-Reset').describe('Header for reset time'), + remaining: z.string().optional().default('X-RateLimit-Remaining').describe('Header for remaining requests'), + limit: z.string().optional().default('X-RateLimit-Limit').describe('Header for rate limit'), + reset: z.string().optional().default('X-RateLimit-Reset').describe('Header for reset time'), }).optional().describe('Custom rate limit headers'), }); @@ -486,42 +486,42 @@ export const RetryConfigSchema = z.object({ /** * Retry strategy */ - strategy: RetryStrategySchema.default('exponential_backoff'), + strategy: RetryStrategySchema.optional().default('exponential_backoff'), /** * Maximum retry attempts */ - maxAttempts: z.number().min(0).max(10).default(3).describe('Maximum retry attempts'), + maxAttempts: z.number().min(0).max(10).optional().default(3).describe('Maximum retry attempts'), /** * Initial delay in milliseconds */ - initialDelayMs: z.number().min(100).default(1000).describe('Initial retry delay in ms'), + initialDelayMs: z.number().min(100).optional().default(1000).describe('Initial retry delay in ms'), /** * Maximum delay in milliseconds */ - maxDelayMs: z.number().min(1000).default(60000).describe('Maximum retry delay in ms'), + maxDelayMs: z.number().min(1000).optional().default(60000).describe('Maximum retry delay in ms'), /** * Backoff multiplier (for exponential backoff) */ - backoffMultiplier: z.number().min(1).default(2).describe('Exponential backoff multiplier'), + backoffMultiplier: z.number().min(1).optional().default(2).describe('Exponential backoff multiplier'), /** * HTTP status codes to retry */ - retryableStatusCodes: z.array(z.number()).default([408, 429, 500, 502, 503, 504]).describe('HTTP status codes to retry'), + retryableStatusCodes: z.array(z.number()).optional().default([408, 429, 500, 502, 503, 504]).describe('HTTP status codes to retry'), /** * Retry on network errors */ - retryOnNetworkError: z.boolean().default(true).describe('Retry on network errors'), + retryOnNetworkError: z.boolean().optional().default(true).describe('Retry on network errors'), /** * Jitter to add randomness to retry delays */ - jitter: z.boolean().default(true).describe('Add jitter to retry delays'), + jitter: z.boolean().optional().default(true).describe('Add jitter to retry delays'), }); export type RetryConfig = z.infer; @@ -619,22 +619,22 @@ export const ConnectorSchema = z.object({ /** * Connection timeout in milliseconds */ - connectionTimeoutMs: z.number().min(1000).max(300000).default(30000).describe('Connection timeout in ms'), + connectionTimeoutMs: z.number().min(1000).max(300000).optional().default(30000).describe('Connection timeout in ms'), /** * Request timeout in milliseconds */ - requestTimeoutMs: z.number().min(1000).max(300000).default(30000).describe('Request timeout in ms'), + requestTimeoutMs: z.number().min(1000).max(300000).optional().default(30000).describe('Request timeout in ms'), /** * Connector status */ - status: ConnectorStatusSchema.default('inactive').describe('Connector status'), + status: ConnectorStatusSchema.optional().default('inactive').describe('Connector status'), /** * Enable connector */ - enabled: z.boolean().default(true).describe('Enable connector'), + enabled: z.boolean().optional().default(true).describe('Enable connector'), /** * Custom metadata @@ -643,16 +643,3 @@ export const ConnectorSchema = z.object({ }); export type Connector = z.infer; - -// ============================================================================ -// TypeScript Exports -// ============================================================================ - -export type { - SyncStrategy, - ConflictResolution, - WebhookEvent, - WebhookSignatureAlgorithm, - RateLimitStrategy, - RetryStrategy, -}; diff --git a/packages/spec/src/system/connector/database.zod.ts b/packages/spec/src/system/connector/database.zod.ts index ab88aa404..ff12bfd39 100644 --- a/packages/spec/src/system/connector/database.zod.ts +++ b/packages/spec/src/system/connector/database.zod.ts @@ -1,7 +1,6 @@ import { z } from 'zod'; import { ConnectorSchema, - DataSyncConfigSchema, FieldMappingSchema, } from '../connector.zod'; @@ -161,12 +160,12 @@ export const DatabaseConnectorSchema = ConnectorSchema.extend({ /** * Query timeout */ - queryTimeoutMs: z.number().min(1000).max(300000).default(30000).describe('Query timeout in ms'), + queryTimeoutMs: z.number().min(1000).max(300000).optional().default(30000).describe('Query timeout in ms'), /** * Enable query logging */ - enableQueryLogging: z.boolean().default(false).describe('Enable SQL query logging'), + enableQueryLogging: z.boolean().optional().default(false).describe('Enable SQL query logging'), }); export type DatabaseConnector = z.infer; @@ -178,7 +177,7 @@ export type DatabaseConnector = z.infer; /** * Example: PostgreSQL Connector Configuration */ -export const postgresConnectorExample: DatabaseConnector = { +export const postgresConnectorExample = { name: 'postgres_production', label: 'Production PostgreSQL', type: 'database', @@ -250,7 +249,7 @@ export const postgresConnectorExample: DatabaseConnector = { /** * Example: MongoDB Connector Configuration */ -export const mongoConnectorExample: DatabaseConnector = { +export const mongoConnectorExample = { name: 'mongodb_analytics', label: 'MongoDB Analytics', type: 'database', @@ -298,7 +297,7 @@ export const mongoConnectorExample: DatabaseConnector = { /** * Example: Snowflake Connector Configuration */ -export const snowflakeConnectorExample: DatabaseConnector = { +export const snowflakeConnectorExample = { name: 'snowflake_warehouse', label: 'Snowflake Data Warehouse', type: 'database', diff --git a/packages/spec/src/system/connector/file-storage.zod.ts b/packages/spec/src/system/connector/file-storage.zod.ts index 71b24dff8..daa665023 100644 --- a/packages/spec/src/system/connector/file-storage.zod.ts +++ b/packages/spec/src/system/connector/file-storage.zod.ts @@ -1,7 +1,6 @@ import { z } from 'zod'; import { ConnectorSchema, - DataSyncConfigSchema, } from '../connector.zod'; /** @@ -146,7 +145,7 @@ export const FileStorageConnectorSchema = ConnectorSchema.extend({ storageConfig: z.object({ endpoint: z.string().url().optional().describe('Custom endpoint URL'), region: z.string().optional().describe('Default region'), - pathStyle: z.boolean().default(false).describe('Use path-style URLs (for S3-compatible)'), + pathStyle: z.boolean().optional().default(false).describe('Use path-style URLs (for S3-compatible)'), }).optional().describe('Storage configuration'), /** @@ -220,7 +219,7 @@ export type FileStorageConnector = z.infer; /** * Example: Amazon S3 Connector Configuration */ -export const s3ConnectorExample: FileStorageConnector = { +export const s3ConnectorExample = { name: 's3_production_assets', label: 'Production S3 Assets', type: 'file_storage', @@ -305,7 +304,7 @@ export const s3ConnectorExample: FileStorageConnector = { /** * Example: Google Drive Connector Configuration */ -export const googleDriveConnectorExample: FileStorageConnector = { +export const googleDriveConnectorExample = { name: 'google_drive_team', label: 'Google Drive Team Folder', type: 'file_storage', @@ -352,7 +351,7 @@ export const googleDriveConnectorExample: FileStorageConnector = { /** * Example: Azure Blob Storage Connector Configuration */ -export const azureBlobConnectorExample: FileStorageConnector = { +export const azureBlobConnectorExample = { name: 'azure_blob_storage', label: 'Azure Blob Storage', type: 'file_storage', diff --git a/packages/spec/src/system/connector/message-queue.zod.ts b/packages/spec/src/system/connector/message-queue.zod.ts index 889e20bc8..4532aae11 100644 --- a/packages/spec/src/system/connector/message-queue.zod.ts +++ b/packages/spec/src/system/connector/message-queue.zod.ts @@ -1,7 +1,6 @@ import { z } from 'zod'; import { ConnectorSchema, - DataSyncConfigSchema, } from '../connector.zod'; /** @@ -73,21 +72,21 @@ export type DeliveryGuarantee = z.infer; * Consumer Configuration */ export const ConsumerConfigSchema = z.object({ - enabled: z.boolean().default(true).describe('Enable consumer'), + enabled: z.boolean().optional().default(true).describe('Enable consumer'), consumerGroup: z.string().optional().describe('Consumer group ID'), - concurrency: z.number().min(1).max(100).default(1).describe('Number of concurrent consumers'), + concurrency: z.number().min(1).max(100).optional().default(1).describe('Number of concurrent consumers'), - prefetchCount: z.number().min(1).max(1000).default(10).describe('Prefetch count'), + prefetchCount: z.number().min(1).max(1000).optional().default(10).describe('Prefetch count'), - ackMode: AckModeSchema.default('manual'), + ackMode: AckModeSchema.optional().default('manual'), - autoCommit: z.boolean().default(false).describe('Auto-commit offsets'), + autoCommit: z.boolean().optional().default(false).describe('Auto-commit offsets'), - autoCommitIntervalMs: z.number().min(100).default(5000).describe('Auto-commit interval in ms'), + autoCommitIntervalMs: z.number().min(100).optional().default(5000).describe('Auto-commit interval in ms'), - sessionTimeoutMs: z.number().min(1000).default(30000).describe('Session timeout in ms'), + sessionTimeoutMs: z.number().min(1000).optional().default(30000).describe('Session timeout in ms'), rebalanceTimeoutMs: z.number().min(1000).optional().describe('Rebalance timeout in ms'), }); @@ -98,21 +97,21 @@ export type ConsumerConfig = z.infer; * Producer Configuration */ export const ProducerConfigSchema = z.object({ - enabled: z.boolean().default(true).describe('Enable producer'), + enabled: z.boolean().optional().default(true).describe('Enable producer'), - acks: z.enum(['0', '1', 'all']).default('all').describe('Acknowledgment level'), + acks: z.enum(['0', '1', 'all']).optional().default('all').describe('Acknowledgment level'), - compressionType: z.enum(['none', 'gzip', 'snappy', 'lz4', 'zstd']).default('none').describe('Compression type'), + compressionType: z.enum(['none', 'gzip', 'snappy', 'lz4', 'zstd']).optional().default('none').describe('Compression type'), - batchSize: z.number().min(1).default(16384).describe('Batch size in bytes'), + batchSize: z.number().min(1).optional().default(16384).describe('Batch size in bytes'), - lingerMs: z.number().min(0).default(0).describe('Linger time in ms'), + lingerMs: z.number().min(0).optional().default(0).describe('Linger time in ms'), - maxInFlightRequests: z.number().min(1).default(5).describe('Max in-flight requests'), + maxInFlightRequests: z.number().min(1).optional().default(5).describe('Max in-flight requests'), - idempotence: z.boolean().default(true).describe('Enable idempotent producer'), + idempotence: z.boolean().optional().default(true).describe('Enable idempotent producer'), - transactional: z.boolean().default(false).describe('Enable transactional producer'), + transactional: z.boolean().optional().default(false).describe('Enable transactional producer'), transactionTimeoutMs: z.number().min(1000).optional().describe('Transaction timeout in ms'), }); @@ -123,13 +122,13 @@ export type ProducerConfig = z.infer; * Dead Letter Queue Configuration */ export const DlqConfigSchema = z.object({ - enabled: z.boolean().default(false).describe('Enable DLQ'), + enabled: z.boolean().optional().default(false).describe('Enable DLQ'), queueName: z.string().describe('Dead letter queue/topic name'), - maxRetries: z.number().min(0).max(100).default(3).describe('Max retries before DLQ'), + maxRetries: z.number().min(0).max(100).optional().default(3).describe('Max retries before DLQ'), - retryDelayMs: z.number().min(0).default(60000).describe('Retry delay in ms'), + retryDelayMs: z.number().min(0).optional().default(60000).describe('Retry delay in ms'), }); export type DlqConfig = z.infer; @@ -141,17 +140,17 @@ export const TopicQueueSchema = z.object({ name: z.string().regex(/^[a-z_][a-z0-9_]*$/).describe('Topic/queue identifier in ObjectStack (snake_case)'), label: z.string().describe('Display label'), topicName: z.string().describe('Actual topic/queue name in message queue system'), - enabled: z.boolean().default(true).describe('Enable sync for this topic/queue'), + enabled: z.boolean().optional().default(true).describe('Enable sync for this topic/queue'), /** * Consumer or Producer */ - mode: z.enum(['consumer', 'producer', 'both']).default('both').describe('Consumer, producer, or both'), + mode: z.enum(['consumer', 'producer', 'both']).optional().default('both').describe('Consumer, producer, or both'), /** * Message format */ - messageFormat: MessageFormatSchema.default('json'), + messageFormat: MessageFormatSchema.optional().default('json'), /** * Partition/shard configuration @@ -211,8 +210,8 @@ export const MessageQueueConnectorSchema = ConnectorSchema.extend({ brokerConfig: z.object({ brokers: z.array(z.string()).describe('Broker addresses (host:port)'), clientId: z.string().optional().describe('Client ID'), - connectionTimeoutMs: z.number().min(1000).default(30000).describe('Connection timeout in ms'), - requestTimeoutMs: z.number().min(1000).default(30000).describe('Request timeout in ms'), + connectionTimeoutMs: z.number().min(1000).optional().default(30000).describe('Connection timeout in ms'), + requestTimeoutMs: z.number().min(1000).optional().default(30000).describe('Request timeout in ms'), }).describe('Broker connection configuration'), /** @@ -223,14 +222,14 @@ export const MessageQueueConnectorSchema = ConnectorSchema.extend({ /** * Delivery guarantee */ - deliveryGuarantee: DeliveryGuaranteeSchema.default('at_least_once'), + deliveryGuarantee: DeliveryGuaranteeSchema.optional().default('at_least_once'), /** * SSL/TLS configuration */ sslConfig: z.object({ - enabled: z.boolean().default(false).describe('Enable SSL/TLS'), - rejectUnauthorized: z.boolean().default(true).describe('Reject unauthorized certificates'), + enabled: z.boolean().optional().default(false).describe('Enable SSL/TLS'), + rejectUnauthorized: z.boolean().optional().default(true).describe('Reject unauthorized certificates'), ca: z.string().optional().describe('CA certificate'), cert: z.string().optional().describe('Client certificate'), key: z.string().optional().describe('Client private key'), @@ -259,17 +258,17 @@ export const MessageQueueConnectorSchema = ConnectorSchema.extend({ /** * Message ordering */ - preserveOrder: z.boolean().default(true).describe('Preserve message ordering'), + preserveOrder: z.boolean().optional().default(true).describe('Preserve message ordering'), /** * Enable metrics */ - enableMetrics: z.boolean().default(true).describe('Enable message queue metrics'), + enableMetrics: z.boolean().optional().default(true).describe('Enable message queue metrics'), /** * Enable distributed tracing */ - enableTracing: z.boolean().default(false).describe('Enable distributed tracing'), + enableTracing: z.boolean().optional().default(false).describe('Enable distributed tracing'), }); export type MessageQueueConnector = z.infer; @@ -281,7 +280,7 @@ export type MessageQueueConnector = z.infer; /** * Example: Apache Kafka Connector Configuration */ -export const kafkaConnectorExample: MessageQueueConnector = { +export const kafkaConnectorExample = { name: 'kafka_production', label: 'Production Kafka Cluster', type: 'message_queue', @@ -361,7 +360,7 @@ export const kafkaConnectorExample: MessageQueueConnector = { /** * Example: RabbitMQ Connector Configuration */ -export const rabbitmqConnectorExample: MessageQueueConnector = { +export const rabbitmqConnectorExample = { name: 'rabbitmq_events', label: 'RabbitMQ Event Bus', type: 'message_queue', @@ -408,7 +407,7 @@ export const rabbitmqConnectorExample: MessageQueueConnector = { /** * Example: AWS SQS Connector Configuration */ -export const sqsConnectorExample: MessageQueueConnector = { +export const sqsConnectorExample = { name: 'aws_sqs_queue', label: 'AWS SQS Queue', type: 'message_queue', @@ -458,7 +457,7 @@ export const sqsConnectorExample: MessageQueueConnector = { /** * Example: Google Cloud Pub/Sub Connector Configuration */ -export const pubsubConnectorExample: MessageQueueConnector = { +export const pubsubConnectorExample = { name: 'gcp_pubsub', label: 'Google Cloud Pub/Sub', type: 'message_queue', diff --git a/packages/spec/src/system/connector/saas.zod.ts b/packages/spec/src/system/connector/saas.zod.ts index 7de5610c4..4f003b8a2 100644 --- a/packages/spec/src/system/connector/saas.zod.ts +++ b/packages/spec/src/system/connector/saas.zod.ts @@ -1,12 +1,7 @@ import { z } from 'zod'; import { ConnectorSchema, - AuthenticationSchema, - DataSyncConfigSchema, FieldMappingSchema, - WebhookConfigSchema, - RateLimitConfigSchema, - RetryConfigSchema, } from '../connector.zod'; /** @@ -134,7 +129,7 @@ export type SaasConnector = z.infer; /** * Example: Salesforce Connector Configuration */ -export const salesforceConnectorExample: SaasConnector = { +export const salesforceConnectorExample = { name: 'salesforce_production', label: 'Salesforce Production', type: 'saas', @@ -205,7 +200,7 @@ export const salesforceConnectorExample: SaasConnector = { /** * Example: HubSpot Connector Configuration */ -export const hubspotConnectorExample: SaasConnector = { +export const hubspotConnectorExample = { name: 'hubspot_crm', label: 'HubSpot CRM', type: 'saas', From 95a23eb3ed37d029cfd6b14c0d8ce20cb6d978c8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 08:49:58 +0000 Subject: [PATCH 4/4] Refactor: Move connector protocols from system to new integration directory Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- .../{system => integration}/connector.mdx | 6 +- content/docs/references/integration/index.mdx | 13 + content/docs/references/integration/meta.json | 6 + content/docs/references/integration/misc.mdx | 529 ++++++++++++++++++ content/docs/references/system/index.mdx | 1 - content/docs/references/system/meta.json | 1 - content/docs/references/system/misc.mdx | 514 +---------------- .../{system => integration}/AckMode.json | 0 .../{system => integration}/ApiKeyAuth.json | 0 .../ApiVersionConfig.json | 0 .../Authentication.json | 0 .../{system => integration}/BasicAuth.json | 0 .../BearerTokenAuth.json | 0 .../{system => integration}/CdcConfig.json | 0 .../ConflictResolution.json | 0 .../{system => integration}/Connector.json | 0 .../ConnectorStatus.json | 0 .../ConnectorType.json | 0 .../ConsumerConfig.json | 0 .../DataSyncConfig.json | 0 .../DatabaseConnector.json | 0 .../DatabasePoolConfig.json | 0 .../DatabaseProvider.json | 0 .../DatabaseTable.json | 0 .../DeliveryGuarantee.json | 0 .../{system => integration}/DlqConfig.json | 0 .../{system => integration}/FieldMapping.json | 0 .../FieldTransform.json | 0 .../FileAccessPattern.json | 0 .../FileFilterConfig.json | 0 .../FileMetadataConfig.json | 0 .../FileStorageConnector.json | 0 .../FileStorageProvider.json | 0 .../FileVersioningConfig.json | 0 .../{system => integration}/JwtAuth.json | 0 .../MessageFormat.json | 0 .../MessageQueueConnector.json | 0 .../MessageQueueProvider.json | 0 .../MultipartUploadConfig.json | 0 .../{system => integration}/NoAuth.json | 0 .../{system => integration}/OAuth2Auth.json | 0 .../ProducerConfig.json | 0 .../RateLimitConfig.json | 0 .../RateLimitStrategy.json | 0 .../{system => integration}/RetryConfig.json | 0 .../RetryStrategy.json | 0 .../SaasConnector.json | 0 .../SaasObjectType.json | 0 .../{system => integration}/SaasProvider.json | 0 .../{system => integration}/SamlAuth.json | 0 .../{system => integration}/SslConfig.json | 0 .../StorageBucket.json | 0 .../{system => integration}/SyncStrategy.json | 0 .../{system => integration}/TopicQueue.json | 0 .../WebhookConfig.json | 0 .../{system => integration}/WebhookEvent.json | 0 .../WebhookSignatureAlgorithm.json | 0 packages/spec/src/index.ts | 1 + .../{system => integration}/connector.test.ts | 0 .../{system => integration}/connector.zod.ts | 0 .../connector/database.zod.ts | 0 .../connector/file-storage.zod.ts | 0 .../connector/message-queue.zod.ts | 0 .../connector/saas.zod.ts | 0 packages/spec/src/integration/index.ts | 18 + packages/spec/src/system/index.ts | 8 +- 66 files changed, 574 insertions(+), 523 deletions(-) rename content/docs/references/{system => integration}/connector.mdx (98%) create mode 100644 content/docs/references/integration/index.mdx create mode 100644 content/docs/references/integration/meta.json create mode 100644 content/docs/references/integration/misc.mdx rename packages/spec/json-schema/{system => integration}/AckMode.json (100%) rename packages/spec/json-schema/{system => integration}/ApiKeyAuth.json (100%) rename packages/spec/json-schema/{system => integration}/ApiVersionConfig.json (100%) rename packages/spec/json-schema/{system => integration}/Authentication.json (100%) rename packages/spec/json-schema/{system => integration}/BasicAuth.json (100%) rename packages/spec/json-schema/{system => integration}/BearerTokenAuth.json (100%) rename packages/spec/json-schema/{system => integration}/CdcConfig.json (100%) rename packages/spec/json-schema/{system => integration}/ConflictResolution.json (100%) rename packages/spec/json-schema/{system => integration}/Connector.json (100%) rename packages/spec/json-schema/{system => integration}/ConnectorStatus.json (100%) rename packages/spec/json-schema/{system => integration}/ConnectorType.json (100%) rename packages/spec/json-schema/{system => integration}/ConsumerConfig.json (100%) rename packages/spec/json-schema/{system => integration}/DataSyncConfig.json (100%) rename packages/spec/json-schema/{system => integration}/DatabaseConnector.json (100%) rename packages/spec/json-schema/{system => integration}/DatabasePoolConfig.json (100%) rename packages/spec/json-schema/{system => integration}/DatabaseProvider.json (100%) rename packages/spec/json-schema/{system => integration}/DatabaseTable.json (100%) rename packages/spec/json-schema/{system => integration}/DeliveryGuarantee.json (100%) rename packages/spec/json-schema/{system => integration}/DlqConfig.json (100%) rename packages/spec/json-schema/{system => integration}/FieldMapping.json (100%) rename packages/spec/json-schema/{system => integration}/FieldTransform.json (100%) rename packages/spec/json-schema/{system => integration}/FileAccessPattern.json (100%) rename packages/spec/json-schema/{system => integration}/FileFilterConfig.json (100%) rename packages/spec/json-schema/{system => integration}/FileMetadataConfig.json (100%) rename packages/spec/json-schema/{system => integration}/FileStorageConnector.json (100%) rename packages/spec/json-schema/{system => integration}/FileStorageProvider.json (100%) rename packages/spec/json-schema/{system => integration}/FileVersioningConfig.json (100%) rename packages/spec/json-schema/{system => integration}/JwtAuth.json (100%) rename packages/spec/json-schema/{system => integration}/MessageFormat.json (100%) rename packages/spec/json-schema/{system => integration}/MessageQueueConnector.json (100%) rename packages/spec/json-schema/{system => integration}/MessageQueueProvider.json (100%) rename packages/spec/json-schema/{system => integration}/MultipartUploadConfig.json (100%) rename packages/spec/json-schema/{system => integration}/NoAuth.json (100%) rename packages/spec/json-schema/{system => integration}/OAuth2Auth.json (100%) rename packages/spec/json-schema/{system => integration}/ProducerConfig.json (100%) rename packages/spec/json-schema/{system => integration}/RateLimitConfig.json (100%) rename packages/spec/json-schema/{system => integration}/RateLimitStrategy.json (100%) rename packages/spec/json-schema/{system => integration}/RetryConfig.json (100%) rename packages/spec/json-schema/{system => integration}/RetryStrategy.json (100%) rename packages/spec/json-schema/{system => integration}/SaasConnector.json (100%) rename packages/spec/json-schema/{system => integration}/SaasObjectType.json (100%) rename packages/spec/json-schema/{system => integration}/SaasProvider.json (100%) rename packages/spec/json-schema/{system => integration}/SamlAuth.json (100%) rename packages/spec/json-schema/{system => integration}/SslConfig.json (100%) rename packages/spec/json-schema/{system => integration}/StorageBucket.json (100%) rename packages/spec/json-schema/{system => integration}/SyncStrategy.json (100%) rename packages/spec/json-schema/{system => integration}/TopicQueue.json (100%) rename packages/spec/json-schema/{system => integration}/WebhookConfig.json (100%) rename packages/spec/json-schema/{system => integration}/WebhookEvent.json (100%) rename packages/spec/json-schema/{system => integration}/WebhookSignatureAlgorithm.json (100%) rename packages/spec/src/{system => integration}/connector.test.ts (100%) rename packages/spec/src/{system => integration}/connector.zod.ts (100%) rename packages/spec/src/{system => integration}/connector/database.zod.ts (100%) rename packages/spec/src/{system => integration}/connector/file-storage.zod.ts (100%) rename packages/spec/src/{system => integration}/connector/message-queue.zod.ts (100%) rename packages/spec/src/{system => integration}/connector/saas.zod.ts (100%) create mode 100644 packages/spec/src/integration/index.ts diff --git a/content/docs/references/system/connector.mdx b/content/docs/references/integration/connector.mdx similarity index 98% rename from content/docs/references/system/connector.mdx rename to content/docs/references/integration/connector.mdx index 43037d3f5..be140f015 100644 --- a/content/docs/references/system/connector.mdx +++ b/content/docs/references/integration/connector.mdx @@ -6,14 +6,14 @@ description: Connector protocol schemas # Connector -**Source:** `packages/spec/src/system/connector.zod.ts` +**Source:** `packages/spec/src/integration/connector.zod.ts` ## TypeScript Usage ```typescript -import { ApiKeyAuthSchema, AuthenticationSchema, BasicAuthSchema, BearerTokenAuthSchema, ConflictResolutionSchema, ConnectorSchema, ConnectorStatusSchema, ConnectorTypeSchema, DataSyncConfigSchema, FieldMappingSchema, FieldTransformSchema, JwtAuthSchema, NoAuthSchema, OAuth2AuthSchema, RateLimitConfigSchema, RateLimitStrategySchema, RetryConfigSchema, RetryStrategySchema, SamlAuthSchema, SyncStrategySchema, WebhookConfigSchema, WebhookEventSchema, WebhookSignatureAlgorithmSchema } from '@objectstack/spec/system'; -import type { ApiKeyAuth, Authentication, BasicAuth, BearerTokenAuth, ConflictResolution, Connector, ConnectorStatus, ConnectorType, DataSyncConfig, FieldMapping, FieldTransform, JwtAuth, NoAuth, OAuth2Auth, RateLimitConfig, RateLimitStrategy, RetryConfig, RetryStrategy, SamlAuth, SyncStrategy, WebhookConfig, WebhookEvent, WebhookSignatureAlgorithm } from '@objectstack/spec/system'; +import { ApiKeyAuthSchema, AuthenticationSchema, BasicAuthSchema, BearerTokenAuthSchema, ConflictResolutionSchema, ConnectorSchema, ConnectorStatusSchema, ConnectorTypeSchema, DataSyncConfigSchema, FieldMappingSchema, FieldTransformSchema, JwtAuthSchema, NoAuthSchema, OAuth2AuthSchema, RateLimitConfigSchema, RateLimitStrategySchema, RetryConfigSchema, RetryStrategySchema, SamlAuthSchema, SyncStrategySchema, WebhookConfigSchema, WebhookEventSchema, WebhookSignatureAlgorithmSchema } from '@objectstack/spec/integration'; +import type { ApiKeyAuth, Authentication, BasicAuth, BearerTokenAuth, ConflictResolution, Connector, ConnectorStatus, ConnectorType, DataSyncConfig, FieldMapping, FieldTransform, JwtAuth, NoAuth, OAuth2Auth, RateLimitConfig, RateLimitStrategy, RetryConfig, RetryStrategy, SamlAuth, SyncStrategy, WebhookConfig, WebhookEvent, WebhookSignatureAlgorithm } from '@objectstack/spec/integration'; // Validate data const result = ApiKeyAuthSchema.parse(data); diff --git a/content/docs/references/integration/index.mdx b/content/docs/references/integration/index.mdx new file mode 100644 index 000000000..a9e78c5a5 --- /dev/null +++ b/content/docs/references/integration/index.mdx @@ -0,0 +1,13 @@ +--- +title: Integration Protocol Overview +description: Complete reference for all integration protocol schemas +--- + +# Integration Protocol + +This section contains all protocol schemas for the integration layer of ObjectStack. + + + + + diff --git a/content/docs/references/integration/meta.json b/content/docs/references/integration/meta.json new file mode 100644 index 000000000..c07e1f0e2 --- /dev/null +++ b/content/docs/references/integration/meta.json @@ -0,0 +1,6 @@ +{ + "title": "Integration Protocol", + "pages": [ + "connector" + ] +} \ No newline at end of file diff --git a/content/docs/references/integration/misc.mdx b/content/docs/references/integration/misc.mdx new file mode 100644 index 000000000..a002a9d45 --- /dev/null +++ b/content/docs/references/integration/misc.mdx @@ -0,0 +1,529 @@ +--- +title: Misc +description: Misc protocol schemas +--- + +# Misc + + +**Source:** `packages/spec/src/integration/misc.zod.ts` + + +## TypeScript Usage + +```typescript +import { AckModeSchema, ApiVersionConfigSchema, CdcConfigSchema, ConsumerConfigSchema, DatabaseConnectorSchema, DatabasePoolConfigSchema, DatabaseProviderSchema, DatabaseTableSchema, DeliveryGuaranteeSchema, DlqConfigSchema, FileAccessPatternSchema, FileFilterConfigSchema, FileMetadataConfigSchema, FileStorageConnectorSchema, FileStorageProviderSchema, FileVersioningConfigSchema, MessageFormatSchema, MessageQueueConnectorSchema, MessageQueueProviderSchema, MultipartUploadConfigSchema, ProducerConfigSchema, SaasConnectorSchema, SaasObjectTypeSchema, SaasProviderSchema, SslConfigSchema, StorageBucketSchema, TopicQueueSchema } from '@objectstack/spec/integration'; +import type { AckMode, ApiVersionConfig, CdcConfig, ConsumerConfig, DatabaseConnector, DatabasePoolConfig, DatabaseProvider, DatabaseTable, DeliveryGuarantee, DlqConfig, FileAccessPattern, FileFilterConfig, FileMetadataConfig, FileStorageConnector, FileStorageProvider, FileVersioningConfig, MessageFormat, MessageQueueConnector, MessageQueueProvider, MultipartUploadConfig, ProducerConfig, SaasConnector, SaasObjectType, SaasProvider, SslConfig, StorageBucket, TopicQueue } from '@objectstack/spec/integration'; + +// Validate data +const result = AckModeSchema.parse(data); +``` + +--- + +## AckMode + +Message acknowledgment mode + +### Allowed Values + +* `auto` +* `manual` +* `client` + +--- + +## ApiVersionConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **version** | `string` | ✅ | API version (e.g., "v2", "2023-10-01") | +| **isDefault** | `boolean` | optional | Is this the default version | +| **deprecationDate** | `string` | optional | API version deprecation date (ISO 8601) | +| **sunsetDate** | `string` | optional | API version sunset date (ISO 8601) | + +--- + +## CdcConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **enabled** | `boolean` | optional | Enable CDC | +| **method** | `Enum<'log_based' \| 'trigger_based' \| 'query_based' \| 'custom'>` | ✅ | CDC method | +| **slotName** | `string` | optional | Replication slot name (for log-based CDC) | +| **publicationName** | `string` | optional | Publication name (for PostgreSQL) | +| **startPosition** | `string` | optional | Starting position/LSN for CDC stream | +| **batchSize** | `number` | optional | CDC batch size | +| **pollIntervalMs** | `number` | optional | CDC polling interval in ms | + +--- + +## ConsumerConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **enabled** | `boolean` | optional | Enable consumer | +| **consumerGroup** | `string` | optional | Consumer group ID | +| **concurrency** | `number` | optional | Number of concurrent consumers | +| **prefetchCount** | `number` | optional | Prefetch count | +| **ackMode** | `Enum<'auto' \| 'manual' \| 'client'>` | optional | Message acknowledgment mode | +| **autoCommit** | `boolean` | optional | Auto-commit offsets | +| **autoCommitIntervalMs** | `number` | optional | Auto-commit interval in ms | +| **sessionTimeoutMs** | `number` | optional | Session timeout in ms | +| **rebalanceTimeoutMs** | `number` | optional | Rebalance timeout in ms | + +--- + +## DatabaseConnector + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Unique connector identifier | +| **label** | `string` | ✅ | Display label | +| **type** | `string` | ✅ | | +| **description** | `string` | optional | Connector description | +| **icon** | `string` | optional | Icon identifier | +| **authentication** | `object \| object \| object \| object \| object \| object \| object` | ✅ | Authentication configuration | +| **syncConfig** | `object` | optional | Data sync configuration | +| **fieldMappings** | `object[]` | optional | Field mapping rules | +| **webhooks** | `object[]` | optional | Webhook configurations | +| **rateLimitConfig** | `object` | optional | Rate limiting configuration | +| **retryConfig** | `object` | optional | Retry configuration | +| **connectionTimeoutMs** | `number` | optional | Connection timeout in ms | +| **requestTimeoutMs** | `number` | optional | Request timeout in ms | +| **status** | `Enum<'active' \| 'inactive' \| 'error' \| 'configuring'>` | optional | Connector status | +| **enabled** | `boolean` | optional | Enable connector | +| **metadata** | `Record` | optional | Custom connector metadata | +| **provider** | `Enum<'postgresql' \| 'mysql' \| 'mariadb' \| 'mssql' \| 'oracle' \| 'mongodb' \| 'redis' \| 'cassandra' \| 'snowflake' \| 'bigquery' \| 'redshift' \| 'custom'>` | ✅ | Database provider type | +| **connectionConfig** | `object` | ✅ | Database connection configuration | +| **poolConfig** | `object` | optional | Connection pool configuration | +| **sslConfig** | `object` | optional | SSL/TLS configuration | +| **tables** | `object[]` | ✅ | Tables to sync | +| **cdcConfig** | `object` | optional | CDC configuration | +| **readReplicaConfig** | `object` | optional | Read replica configuration | +| **queryTimeoutMs** | `number` | optional | Query timeout in ms | +| **enableQueryLogging** | `boolean` | optional | Enable SQL query logging | + +--- + +## DatabasePoolConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **min** | `number` | optional | Minimum connections in pool | +| **max** | `number` | optional | Maximum connections in pool | +| **idleTimeoutMs** | `number` | optional | Idle connection timeout in ms | +| **connectionTimeoutMs** | `number` | optional | Connection establishment timeout in ms | +| **acquireTimeoutMs** | `number` | optional | Connection acquisition timeout in ms | +| **evictionRunIntervalMs** | `number` | optional | Connection eviction check interval in ms | +| **testOnBorrow** | `boolean` | optional | Test connection before use | + +--- + +## DatabaseProvider + +Database provider type + +### Allowed Values + +* `postgresql` +* `mysql` +* `mariadb` +* `mssql` +* `oracle` +* `mongodb` +* `redis` +* `cassandra` +* `snowflake` +* `bigquery` +* `redshift` +* `custom` + +--- + +## DatabaseTable + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Table name in ObjectStack (snake_case) | +| **label** | `string` | ✅ | Display label | +| **schema** | `string` | optional | Database schema name | +| **tableName** | `string` | ✅ | Actual table name in database | +| **primaryKey** | `string` | ✅ | Primary key column | +| **enabled** | `boolean` | optional | Enable sync for this table | +| **fieldMappings** | `object[]` | optional | Table-specific field mappings | +| **whereClause** | `string` | optional | SQL WHERE clause for filtering | + +--- + +## DeliveryGuarantee + +Message delivery guarantee + +### Allowed Values + +* `at_most_once` +* `at_least_once` +* `exactly_once` + +--- + +## DlqConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **enabled** | `boolean` | optional | Enable DLQ | +| **queueName** | `string` | ✅ | Dead letter queue/topic name | +| **maxRetries** | `number` | optional | Max retries before DLQ | +| **retryDelayMs** | `number` | optional | Retry delay in ms | + +--- + +## FileAccessPattern + +File access pattern + +### Allowed Values + +* `public_read` +* `private` +* `authenticated_read` +* `bucket_owner_read` +* `bucket_owner_full` + +--- + +## FileFilterConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **includePatterns** | `string[]` | optional | File patterns to include (glob) | +| **excludePatterns** | `string[]` | optional | File patterns to exclude (glob) | +| **minFileSize** | `number` | optional | Minimum file size in bytes | +| **maxFileSize** | `number` | optional | Maximum file size in bytes | +| **allowedExtensions** | `string[]` | optional | Allowed file extensions | +| **blockedExtensions** | `string[]` | optional | Blocked file extensions | + +--- + +## FileMetadataConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **extractMetadata** | `boolean` | optional | Extract file metadata | +| **metadataFields** | `Enum<'content_type' \| 'file_size' \| 'last_modified' \| 'etag' \| 'checksum' \| 'creator' \| 'created_at' \| 'custom'>[]` | optional | Metadata fields to extract | +| **customMetadata** | `Record` | optional | Custom metadata key-value pairs | + +--- + +## FileStorageConnector + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Unique connector identifier | +| **label** | `string` | ✅ | Display label | +| **type** | `string` | ✅ | | +| **description** | `string` | optional | Connector description | +| **icon** | `string` | optional | Icon identifier | +| **authentication** | `object \| object \| object \| object \| object \| object \| object` | ✅ | Authentication configuration | +| **syncConfig** | `object` | optional | Data sync configuration | +| **fieldMappings** | `object[]` | optional | Field mapping rules | +| **webhooks** | `object[]` | optional | Webhook configurations | +| **rateLimitConfig** | `object` | optional | Rate limiting configuration | +| **retryConfig** | `object` | optional | Retry configuration | +| **connectionTimeoutMs** | `number` | optional | Connection timeout in ms | +| **requestTimeoutMs** | `number` | optional | Request timeout in ms | +| **status** | `Enum<'active' \| 'inactive' \| 'error' \| 'configuring'>` | optional | Connector status | +| **enabled** | `boolean` | optional | Enable connector | +| **metadata** | `Record` | optional | Custom connector metadata | +| **provider** | `Enum<'s3' \| 'azure_blob' \| 'gcs' \| 'dropbox' \| 'box' \| 'onedrive' \| 'google_drive' \| 'sharepoint' \| 'ftp' \| 'local' \| 'custom'>` | ✅ | File storage provider type | +| **storageConfig** | `object` | optional | Storage configuration | +| **buckets** | `object[]` | ✅ | Buckets/containers to sync | +| **metadataConfig** | `object` | optional | Metadata extraction configuration | +| **multipartConfig** | `object` | optional | Multipart upload configuration | +| **versioningConfig** | `object` | optional | File versioning configuration | +| **encryption** | `object` | optional | Encryption configuration | +| **lifecyclePolicy** | `object` | optional | Lifecycle policy | +| **contentProcessing** | `object` | optional | Content processing configuration | +| **bufferSize** | `number` | optional | Buffer size in bytes | +| **transferAcceleration** | `boolean` | optional | Enable transfer acceleration | + +--- + +## FileStorageProvider + +File storage provider type + +### Allowed Values + +* `s3` +* `azure_blob` +* `gcs` +* `dropbox` +* `box` +* `onedrive` +* `google_drive` +* `sharepoint` +* `ftp` +* `local` +* `custom` + +--- + +## FileVersioningConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **enabled** | `boolean` | optional | Enable file versioning | +| **maxVersions** | `number` | optional | Maximum versions to retain | +| **retentionDays** | `number` | optional | Version retention period in days | + +--- + +## MessageFormat + +Message format/serialization + +### Allowed Values + +* `json` +* `xml` +* `protobuf` +* `avro` +* `text` +* `binary` + +--- + +## MessageQueueConnector + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Unique connector identifier | +| **label** | `string` | ✅ | Display label | +| **type** | `string` | ✅ | | +| **description** | `string` | optional | Connector description | +| **icon** | `string` | optional | Icon identifier | +| **authentication** | `object \| object \| object \| object \| object \| object \| object` | ✅ | Authentication configuration | +| **syncConfig** | `object` | optional | Data sync configuration | +| **fieldMappings** | `object[]` | optional | Field mapping rules | +| **webhooks** | `object[]` | optional | Webhook configurations | +| **rateLimitConfig** | `object` | optional | Rate limiting configuration | +| **retryConfig** | `object` | optional | Retry configuration | +| **connectionTimeoutMs** | `number` | optional | Connection timeout in ms | +| **requestTimeoutMs** | `number` | optional | Request timeout in ms | +| **status** | `Enum<'active' \| 'inactive' \| 'error' \| 'configuring'>` | optional | Connector status | +| **enabled** | `boolean` | optional | Enable connector | +| **metadata** | `Record` | optional | Custom connector metadata | +| **provider** | `Enum<'rabbitmq' \| 'kafka' \| 'redis_pubsub' \| 'redis_streams' \| 'aws_sqs' \| 'aws_sns' \| 'google_pubsub' \| 'azure_service_bus' \| 'azure_event_hubs' \| 'nats' \| 'pulsar' \| 'activemq' \| 'custom'>` | ✅ | Message queue provider type | +| **brokerConfig** | `object` | ✅ | Broker connection configuration | +| **topics** | `object[]` | ✅ | Topics/queues to sync | +| **deliveryGuarantee** | `Enum<'at_most_once' \| 'at_least_once' \| 'exactly_once'>` | optional | Message delivery guarantee | +| **sslConfig** | `object` | optional | SSL/TLS configuration | +| **saslConfig** | `object` | optional | SASL authentication configuration | +| **schemaRegistry** | `object` | optional | Schema registry configuration | +| **preserveOrder** | `boolean` | optional | Preserve message ordering | +| **enableMetrics** | `boolean` | optional | Enable message queue metrics | +| **enableTracing** | `boolean` | optional | Enable distributed tracing | + +--- + +## MessageQueueProvider + +Message queue provider type + +### Allowed Values + +* `rabbitmq` +* `kafka` +* `redis_pubsub` +* `redis_streams` +* `aws_sqs` +* `aws_sns` +* `google_pubsub` +* `azure_service_bus` +* `azure_event_hubs` +* `nats` +* `pulsar` +* `activemq` +* `custom` + +--- + +## MultipartUploadConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **enabled** | `boolean` | optional | Enable multipart uploads | +| **partSize** | `number` | optional | Part size in bytes (min 5MB) | +| **maxConcurrentParts** | `number` | optional | Maximum concurrent part uploads | +| **threshold** | `number` | optional | File size threshold for multipart upload in bytes | + +--- + +## ProducerConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **enabled** | `boolean` | optional | Enable producer | +| **acks** | `Enum<'0' \| '1' \| 'all'>` | optional | Acknowledgment level | +| **compressionType** | `Enum<'none' \| 'gzip' \| 'snappy' \| 'lz4' \| 'zstd'>` | optional | Compression type | +| **batchSize** | `number` | optional | Batch size in bytes | +| **lingerMs** | `number` | optional | Linger time in ms | +| **maxInFlightRequests** | `number` | optional | Max in-flight requests | +| **idempotence** | `boolean` | optional | Enable idempotent producer | +| **transactional** | `boolean` | optional | Enable transactional producer | +| **transactionTimeoutMs** | `number` | optional | Transaction timeout in ms | + +--- + +## SaasConnector + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Unique connector identifier | +| **label** | `string` | ✅ | Display label | +| **type** | `string` | ✅ | | +| **description** | `string` | optional | Connector description | +| **icon** | `string` | optional | Icon identifier | +| **authentication** | `object \| object \| object \| object \| object \| object \| object` | ✅ | Authentication configuration | +| **syncConfig** | `object` | optional | Data sync configuration | +| **fieldMappings** | `object[]` | optional | Field mapping rules | +| **webhooks** | `object[]` | optional | Webhook configurations | +| **rateLimitConfig** | `object` | optional | Rate limiting configuration | +| **retryConfig** | `object` | optional | Retry configuration | +| **connectionTimeoutMs** | `number` | optional | Connection timeout in ms | +| **requestTimeoutMs** | `number` | optional | Request timeout in ms | +| **status** | `Enum<'active' \| 'inactive' \| 'error' \| 'configuring'>` | optional | Connector status | +| **enabled** | `boolean` | optional | Enable connector | +| **metadata** | `Record` | optional | Custom connector metadata | +| **provider** | `Enum<'salesforce' \| 'hubspot' \| 'stripe' \| 'shopify' \| 'zendesk' \| 'intercom' \| 'mailchimp' \| 'slack' \| 'microsoft_dynamics' \| 'servicenow' \| 'netsuite' \| 'custom'>` | ✅ | SaaS provider type | +| **baseUrl** | `string` | ✅ | API base URL | +| **apiVersion** | `object` | optional | API version configuration | +| **objectTypes** | `object[]` | ✅ | Syncable object types | +| **oauthSettings** | `object` | optional | OAuth-specific configuration | +| **paginationConfig** | `object` | optional | Pagination configuration | +| **sandboxConfig** | `object` | optional | Sandbox environment configuration | +| **customHeaders** | `Record` | optional | Custom HTTP headers for all requests | + +--- + +## SaasObjectType + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Object type name (snake_case) | +| **label** | `string` | ✅ | Display label | +| **apiName** | `string` | ✅ | API name in external system | +| **enabled** | `boolean` | optional | Enable sync for this object | +| **supportsCreate** | `boolean` | optional | Supports record creation | +| **supportsUpdate** | `boolean` | optional | Supports record updates | +| **supportsDelete** | `boolean` | optional | Supports record deletion | +| **fieldMappings** | `object[]` | optional | Object-specific field mappings | + +--- + +## SaasProvider + +SaaS provider type + +### Allowed Values + +* `salesforce` +* `hubspot` +* `stripe` +* `shopify` +* `zendesk` +* `intercom` +* `mailchimp` +* `slack` +* `microsoft_dynamics` +* `servicenow` +* `netsuite` +* `custom` + +--- + +## SslConfig + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **enabled** | `boolean` | optional | Enable SSL/TLS | +| **rejectUnauthorized** | `boolean` | optional | Reject unauthorized certificates | +| **ca** | `string` | optional | Certificate Authority certificate | +| **cert** | `string` | optional | Client certificate | +| **key** | `string` | optional | Client private key | + +--- + +## StorageBucket + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Bucket identifier in ObjectStack (snake_case) | +| **label** | `string` | ✅ | Display label | +| **bucketName** | `string` | ✅ | Actual bucket/container name in storage system | +| **region** | `string` | optional | Storage region | +| **enabled** | `boolean` | optional | Enable sync for this bucket | +| **prefix** | `string` | optional | Prefix/path within bucket | +| **accessPattern** | `Enum<'public_read' \| 'private' \| 'authenticated_read' \| 'bucket_owner_read' \| 'bucket_owner_full'>` | optional | Access pattern | +| **fileFilters** | `object` | optional | File filter configuration | + +--- + +## TopicQueue + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **name** | `string` | ✅ | Topic/queue identifier in ObjectStack (snake_case) | +| **label** | `string` | ✅ | Display label | +| **topicName** | `string` | ✅ | Actual topic/queue name in message queue system | +| **enabled** | `boolean` | optional | Enable sync for this topic/queue | +| **mode** | `Enum<'consumer' \| 'producer' \| 'both'>` | optional | Consumer, producer, or both | +| **messageFormat** | `Enum<'json' \| 'xml' \| 'protobuf' \| 'avro' \| 'text' \| 'binary'>` | optional | Message format/serialization | +| **partitions** | `number` | optional | Number of partitions (for Kafka) | +| **replicationFactor** | `number` | optional | Replication factor (for Kafka) | +| **consumerConfig** | `object` | optional | Consumer-specific configuration | +| **producerConfig** | `object` | optional | Producer-specific configuration | +| **dlqConfig** | `object` | optional | Dead letter queue configuration | +| **routingKey** | `string` | optional | Routing key pattern | +| **messageFilter** | `object` | optional | Message filter criteria | + diff --git a/content/docs/references/system/index.mdx b/content/docs/references/system/index.mdx index 2317abcc0..9fcdb2f8f 100644 --- a/content/docs/references/system/index.mdx +++ b/content/docs/references/system/index.mdx @@ -10,7 +10,6 @@ This section contains all protocol schemas for the system layer of ObjectStack. - diff --git a/content/docs/references/system/meta.json b/content/docs/references/system/meta.json index ac5122f8a..d4a87c4ba 100644 --- a/content/docs/references/system/meta.json +++ b/content/docs/references/system/meta.json @@ -3,7 +3,6 @@ "pages": [ "audit", "collaboration", - "connector", "context", "data-engine", "datasource", diff --git a/content/docs/references/system/misc.mdx b/content/docs/references/system/misc.mdx index 5a7df618c..a7e0b7ff2 100644 --- a/content/docs/references/system/misc.mdx +++ b/content/docs/references/system/misc.mdx @@ -12,368 +12,15 @@ description: Misc protocol schemas ## TypeScript Usage ```typescript -import { AckModeSchema, ApiVersionConfigSchema, CdcConfigSchema, ConsumerConfigSchema, DatabaseConnectorSchema, DatabasePoolConfigSchema, DatabaseProviderSchema, DatabaseTableSchema, DeliveryGuaranteeSchema, DlqConfigSchema, FileAccessPatternSchema, FileFilterConfigSchema, FileMetadataConfigSchema, FileStorageConnectorSchema, FileStorageProviderSchema, FileVersioningConfigSchema, MessageFormatSchema, MessageQueueConnectorSchema, MessageQueueProviderSchema, MongoConfigSchema, MultipartUploadConfigSchema, PostgresConfigSchema, ProducerConfigSchema, SaasConnectorSchema, SaasObjectTypeSchema, SaasProviderSchema, SslConfigSchema, StorageBucketSchema, TopicQueueSchema } from '@objectstack/spec/system'; -import type { AckMode, ApiVersionConfig, CdcConfig, ConsumerConfig, DatabaseConnector, DatabasePoolConfig, DatabaseProvider, DatabaseTable, DeliveryGuarantee, DlqConfig, FileAccessPattern, FileFilterConfig, FileMetadataConfig, FileStorageConnector, FileStorageProvider, FileVersioningConfig, MessageFormat, MessageQueueConnector, MessageQueueProvider, MongoConfig, MultipartUploadConfig, PostgresConfig, ProducerConfig, SaasConnector, SaasObjectType, SaasProvider, SslConfig, StorageBucket, TopicQueue } from '@objectstack/spec/system'; +import { MongoConfigSchema, PostgresConfigSchema } from '@objectstack/spec/system'; +import type { MongoConfig, PostgresConfig } from '@objectstack/spec/system'; // Validate data -const result = AckModeSchema.parse(data); +const result = MongoConfigSchema.parse(data); ``` --- -## AckMode - -Message acknowledgment mode - -### Allowed Values - -* `auto` -* `manual` -* `client` - ---- - -## ApiVersionConfig - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **version** | `string` | ✅ | API version (e.g., "v2", "2023-10-01") | -| **isDefault** | `boolean` | optional | Is this the default version | -| **deprecationDate** | `string` | optional | API version deprecation date (ISO 8601) | -| **sunsetDate** | `string` | optional | API version sunset date (ISO 8601) | - ---- - -## CdcConfig - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **enabled** | `boolean` | optional | Enable CDC | -| **method** | `Enum<'log_based' \| 'trigger_based' \| 'query_based' \| 'custom'>` | ✅ | CDC method | -| **slotName** | `string` | optional | Replication slot name (for log-based CDC) | -| **publicationName** | `string` | optional | Publication name (for PostgreSQL) | -| **startPosition** | `string` | optional | Starting position/LSN for CDC stream | -| **batchSize** | `number` | optional | CDC batch size | -| **pollIntervalMs** | `number` | optional | CDC polling interval in ms | - ---- - -## ConsumerConfig - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **enabled** | `boolean` | optional | Enable consumer | -| **consumerGroup** | `string` | optional | Consumer group ID | -| **concurrency** | `number` | optional | Number of concurrent consumers | -| **prefetchCount** | `number` | optional | Prefetch count | -| **ackMode** | `Enum<'auto' \| 'manual' \| 'client'>` | optional | Message acknowledgment mode | -| **autoCommit** | `boolean` | optional | Auto-commit offsets | -| **autoCommitIntervalMs** | `number` | optional | Auto-commit interval in ms | -| **sessionTimeoutMs** | `number` | optional | Session timeout in ms | -| **rebalanceTimeoutMs** | `number` | optional | Rebalance timeout in ms | - ---- - -## DatabaseConnector - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **name** | `string` | ✅ | Unique connector identifier | -| **label** | `string` | ✅ | Display label | -| **type** | `string` | ✅ | | -| **description** | `string` | optional | Connector description | -| **icon** | `string` | optional | Icon identifier | -| **authentication** | `object \| object \| object \| object \| object \| object \| object` | ✅ | Authentication configuration | -| **syncConfig** | `object` | optional | Data sync configuration | -| **fieldMappings** | `object[]` | optional | Field mapping rules | -| **webhooks** | `object[]` | optional | Webhook configurations | -| **rateLimitConfig** | `object` | optional | Rate limiting configuration | -| **retryConfig** | `object` | optional | Retry configuration | -| **connectionTimeoutMs** | `number` | optional | Connection timeout in ms | -| **requestTimeoutMs** | `number` | optional | Request timeout in ms | -| **status** | `Enum<'active' \| 'inactive' \| 'error' \| 'configuring'>` | optional | Connector status | -| **enabled** | `boolean` | optional | Enable connector | -| **metadata** | `Record` | optional | Custom connector metadata | -| **provider** | `Enum<'postgresql' \| 'mysql' \| 'mariadb' \| 'mssql' \| 'oracle' \| 'mongodb' \| 'redis' \| 'cassandra' \| 'snowflake' \| 'bigquery' \| 'redshift' \| 'custom'>` | ✅ | Database provider type | -| **connectionConfig** | `object` | ✅ | Database connection configuration | -| **poolConfig** | `object` | optional | Connection pool configuration | -| **sslConfig** | `object` | optional | SSL/TLS configuration | -| **tables** | `object[]` | ✅ | Tables to sync | -| **cdcConfig** | `object` | optional | CDC configuration | -| **readReplicaConfig** | `object` | optional | Read replica configuration | -| **queryTimeoutMs** | `number` | optional | Query timeout in ms | -| **enableQueryLogging** | `boolean` | optional | Enable SQL query logging | - ---- - -## DatabasePoolConfig - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **min** | `number` | optional | Minimum connections in pool | -| **max** | `number` | optional | Maximum connections in pool | -| **idleTimeoutMs** | `number` | optional | Idle connection timeout in ms | -| **connectionTimeoutMs** | `number` | optional | Connection establishment timeout in ms | -| **acquireTimeoutMs** | `number` | optional | Connection acquisition timeout in ms | -| **evictionRunIntervalMs** | `number` | optional | Connection eviction check interval in ms | -| **testOnBorrow** | `boolean` | optional | Test connection before use | - ---- - -## DatabaseProvider - -Database provider type - -### Allowed Values - -* `postgresql` -* `mysql` -* `mariadb` -* `mssql` -* `oracle` -* `mongodb` -* `redis` -* `cassandra` -* `snowflake` -* `bigquery` -* `redshift` -* `custom` - ---- - -## DatabaseTable - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **name** | `string` | ✅ | Table name in ObjectStack (snake_case) | -| **label** | `string` | ✅ | Display label | -| **schema** | `string` | optional | Database schema name | -| **tableName** | `string` | ✅ | Actual table name in database | -| **primaryKey** | `string` | ✅ | Primary key column | -| **enabled** | `boolean` | optional | Enable sync for this table | -| **fieldMappings** | `object[]` | optional | Table-specific field mappings | -| **whereClause** | `string` | optional | SQL WHERE clause for filtering | - ---- - -## DeliveryGuarantee - -Message delivery guarantee - -### Allowed Values - -* `at_most_once` -* `at_least_once` -* `exactly_once` - ---- - -## DlqConfig - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **enabled** | `boolean` | optional | Enable DLQ | -| **queueName** | `string` | ✅ | Dead letter queue/topic name | -| **maxRetries** | `number` | optional | Max retries before DLQ | -| **retryDelayMs** | `number` | optional | Retry delay in ms | - ---- - -## FileAccessPattern - -File access pattern - -### Allowed Values - -* `public_read` -* `private` -* `authenticated_read` -* `bucket_owner_read` -* `bucket_owner_full` - ---- - -## FileFilterConfig - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **includePatterns** | `string[]` | optional | File patterns to include (glob) | -| **excludePatterns** | `string[]` | optional | File patterns to exclude (glob) | -| **minFileSize** | `number` | optional | Minimum file size in bytes | -| **maxFileSize** | `number` | optional | Maximum file size in bytes | -| **allowedExtensions** | `string[]` | optional | Allowed file extensions | -| **blockedExtensions** | `string[]` | optional | Blocked file extensions | - ---- - -## FileMetadataConfig - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **extractMetadata** | `boolean` | optional | Extract file metadata | -| **metadataFields** | `Enum<'content_type' \| 'file_size' \| 'last_modified' \| 'etag' \| 'checksum' \| 'creator' \| 'created_at' \| 'custom'>[]` | optional | Metadata fields to extract | -| **customMetadata** | `Record` | optional | Custom metadata key-value pairs | - ---- - -## FileStorageConnector - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **name** | `string` | ✅ | Unique connector identifier | -| **label** | `string` | ✅ | Display label | -| **type** | `string` | ✅ | | -| **description** | `string` | optional | Connector description | -| **icon** | `string` | optional | Icon identifier | -| **authentication** | `object \| object \| object \| object \| object \| object \| object` | ✅ | Authentication configuration | -| **syncConfig** | `object` | optional | Data sync configuration | -| **fieldMappings** | `object[]` | optional | Field mapping rules | -| **webhooks** | `object[]` | optional | Webhook configurations | -| **rateLimitConfig** | `object` | optional | Rate limiting configuration | -| **retryConfig** | `object` | optional | Retry configuration | -| **connectionTimeoutMs** | `number` | optional | Connection timeout in ms | -| **requestTimeoutMs** | `number` | optional | Request timeout in ms | -| **status** | `Enum<'active' \| 'inactive' \| 'error' \| 'configuring'>` | optional | Connector status | -| **enabled** | `boolean` | optional | Enable connector | -| **metadata** | `Record` | optional | Custom connector metadata | -| **provider** | `Enum<'s3' \| 'azure_blob' \| 'gcs' \| 'dropbox' \| 'box' \| 'onedrive' \| 'google_drive' \| 'sharepoint' \| 'ftp' \| 'local' \| 'custom'>` | ✅ | File storage provider type | -| **storageConfig** | `object` | optional | Storage configuration | -| **buckets** | `object[]` | ✅ | Buckets/containers to sync | -| **metadataConfig** | `object` | optional | Metadata extraction configuration | -| **multipartConfig** | `object` | optional | Multipart upload configuration | -| **versioningConfig** | `object` | optional | File versioning configuration | -| **encryption** | `object` | optional | Encryption configuration | -| **lifecyclePolicy** | `object` | optional | Lifecycle policy | -| **contentProcessing** | `object` | optional | Content processing configuration | -| **bufferSize** | `number` | optional | Buffer size in bytes | -| **transferAcceleration** | `boolean` | optional | Enable transfer acceleration | - ---- - -## FileStorageProvider - -File storage provider type - -### Allowed Values - -* `s3` -* `azure_blob` -* `gcs` -* `dropbox` -* `box` -* `onedrive` -* `google_drive` -* `sharepoint` -* `ftp` -* `local` -* `custom` - ---- - -## FileVersioningConfig - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **enabled** | `boolean` | optional | Enable file versioning | -| **maxVersions** | `number` | optional | Maximum versions to retain | -| **retentionDays** | `number` | optional | Version retention period in days | - ---- - -## MessageFormat - -Message format/serialization - -### Allowed Values - -* `json` -* `xml` -* `protobuf` -* `avro` -* `text` -* `binary` - ---- - -## MessageQueueConnector - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **name** | `string` | ✅ | Unique connector identifier | -| **label** | `string` | ✅ | Display label | -| **type** | `string` | ✅ | | -| **description** | `string` | optional | Connector description | -| **icon** | `string` | optional | Icon identifier | -| **authentication** | `object \| object \| object \| object \| object \| object \| object` | ✅ | Authentication configuration | -| **syncConfig** | `object` | optional | Data sync configuration | -| **fieldMappings** | `object[]` | optional | Field mapping rules | -| **webhooks** | `object[]` | optional | Webhook configurations | -| **rateLimitConfig** | `object` | optional | Rate limiting configuration | -| **retryConfig** | `object` | optional | Retry configuration | -| **connectionTimeoutMs** | `number` | optional | Connection timeout in ms | -| **requestTimeoutMs** | `number` | optional | Request timeout in ms | -| **status** | `Enum<'active' \| 'inactive' \| 'error' \| 'configuring'>` | optional | Connector status | -| **enabled** | `boolean` | optional | Enable connector | -| **metadata** | `Record` | optional | Custom connector metadata | -| **provider** | `Enum<'rabbitmq' \| 'kafka' \| 'redis_pubsub' \| 'redis_streams' \| 'aws_sqs' \| 'aws_sns' \| 'google_pubsub' \| 'azure_service_bus' \| 'azure_event_hubs' \| 'nats' \| 'pulsar' \| 'activemq' \| 'custom'>` | ✅ | Message queue provider type | -| **brokerConfig** | `object` | ✅ | Broker connection configuration | -| **topics** | `object[]` | ✅ | Topics/queues to sync | -| **deliveryGuarantee** | `Enum<'at_most_once' \| 'at_least_once' \| 'exactly_once'>` | optional | Message delivery guarantee | -| **sslConfig** | `object` | optional | SSL/TLS configuration | -| **saslConfig** | `object` | optional | SASL authentication configuration | -| **schemaRegistry** | `object` | optional | Schema registry configuration | -| **preserveOrder** | `boolean` | optional | Preserve message ordering | -| **enableMetrics** | `boolean` | optional | Enable message queue metrics | -| **enableTracing** | `boolean` | optional | Enable distributed tracing | - ---- - -## MessageQueueProvider - -Message queue provider type - -### Allowed Values - -* `rabbitmq` -* `kafka` -* `redis_pubsub` -* `redis_streams` -* `aws_sqs` -* `aws_sns` -* `google_pubsub` -* `azure_service_bus` -* `azure_event_hubs` -* `nats` -* `pulsar` -* `activemq` -* `custom` - ---- - ## MongoConfig ### Properties @@ -397,19 +44,6 @@ Message queue provider type --- -## MultipartUploadConfig - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **enabled** | `boolean` | optional | Enable multipart uploads | -| **partSize** | `number` | optional | Part size in bytes (min 5MB) | -| **maxConcurrentParts** | `number` | optional | Maximum concurrent part uploads | -| **threshold** | `number` | optional | File size threshold for multipart upload in bytes | - ---- - ## PostgresConfig ### Properties @@ -431,145 +65,3 @@ Message queue provider type | **connectionTimeoutMillis** | `number` | optional | Connection Timeout (ms) | | **statementTimeout** | `number` | optional | Statement Timeout (ms) | ---- - -## ProducerConfig - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **enabled** | `boolean` | optional | Enable producer | -| **acks** | `Enum<'0' \| '1' \| 'all'>` | optional | Acknowledgment level | -| **compressionType** | `Enum<'none' \| 'gzip' \| 'snappy' \| 'lz4' \| 'zstd'>` | optional | Compression type | -| **batchSize** | `number` | optional | Batch size in bytes | -| **lingerMs** | `number` | optional | Linger time in ms | -| **maxInFlightRequests** | `number` | optional | Max in-flight requests | -| **idempotence** | `boolean` | optional | Enable idempotent producer | -| **transactional** | `boolean` | optional | Enable transactional producer | -| **transactionTimeoutMs** | `number` | optional | Transaction timeout in ms | - ---- - -## SaasConnector - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **name** | `string` | ✅ | Unique connector identifier | -| **label** | `string` | ✅ | Display label | -| **type** | `string` | ✅ | | -| **description** | `string` | optional | Connector description | -| **icon** | `string` | optional | Icon identifier | -| **authentication** | `object \| object \| object \| object \| object \| object \| object` | ✅ | Authentication configuration | -| **syncConfig** | `object` | optional | Data sync configuration | -| **fieldMappings** | `object[]` | optional | Field mapping rules | -| **webhooks** | `object[]` | optional | Webhook configurations | -| **rateLimitConfig** | `object` | optional | Rate limiting configuration | -| **retryConfig** | `object` | optional | Retry configuration | -| **connectionTimeoutMs** | `number` | optional | Connection timeout in ms | -| **requestTimeoutMs** | `number` | optional | Request timeout in ms | -| **status** | `Enum<'active' \| 'inactive' \| 'error' \| 'configuring'>` | optional | Connector status | -| **enabled** | `boolean` | optional | Enable connector | -| **metadata** | `Record` | optional | Custom connector metadata | -| **provider** | `Enum<'salesforce' \| 'hubspot' \| 'stripe' \| 'shopify' \| 'zendesk' \| 'intercom' \| 'mailchimp' \| 'slack' \| 'microsoft_dynamics' \| 'servicenow' \| 'netsuite' \| 'custom'>` | ✅ | SaaS provider type | -| **baseUrl** | `string` | ✅ | API base URL | -| **apiVersion** | `object` | optional | API version configuration | -| **objectTypes** | `object[]` | ✅ | Syncable object types | -| **oauthSettings** | `object` | optional | OAuth-specific configuration | -| **paginationConfig** | `object` | optional | Pagination configuration | -| **sandboxConfig** | `object` | optional | Sandbox environment configuration | -| **customHeaders** | `Record` | optional | Custom HTTP headers for all requests | - ---- - -## SaasObjectType - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **name** | `string` | ✅ | Object type name (snake_case) | -| **label** | `string` | ✅ | Display label | -| **apiName** | `string` | ✅ | API name in external system | -| **enabled** | `boolean` | optional | Enable sync for this object | -| **supportsCreate** | `boolean` | optional | Supports record creation | -| **supportsUpdate** | `boolean` | optional | Supports record updates | -| **supportsDelete** | `boolean` | optional | Supports record deletion | -| **fieldMappings** | `object[]` | optional | Object-specific field mappings | - ---- - -## SaasProvider - -SaaS provider type - -### Allowed Values - -* `salesforce` -* `hubspot` -* `stripe` -* `shopify` -* `zendesk` -* `intercom` -* `mailchimp` -* `slack` -* `microsoft_dynamics` -* `servicenow` -* `netsuite` -* `custom` - ---- - -## SslConfig - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **enabled** | `boolean` | optional | Enable SSL/TLS | -| **rejectUnauthorized** | `boolean` | optional | Reject unauthorized certificates | -| **ca** | `string` | optional | Certificate Authority certificate | -| **cert** | `string` | optional | Client certificate | -| **key** | `string` | optional | Client private key | - ---- - -## StorageBucket - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **name** | `string` | ✅ | Bucket identifier in ObjectStack (snake_case) | -| **label** | `string` | ✅ | Display label | -| **bucketName** | `string` | ✅ | Actual bucket/container name in storage system | -| **region** | `string` | optional | Storage region | -| **enabled** | `boolean` | optional | Enable sync for this bucket | -| **prefix** | `string` | optional | Prefix/path within bucket | -| **accessPattern** | `Enum<'public_read' \| 'private' \| 'authenticated_read' \| 'bucket_owner_read' \| 'bucket_owner_full'>` | optional | Access pattern | -| **fileFilters** | `object` | optional | File filter configuration | - ---- - -## TopicQueue - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **name** | `string` | ✅ | Topic/queue identifier in ObjectStack (snake_case) | -| **label** | `string` | ✅ | Display label | -| **topicName** | `string` | ✅ | Actual topic/queue name in message queue system | -| **enabled** | `boolean` | optional | Enable sync for this topic/queue | -| **mode** | `Enum<'consumer' \| 'producer' \| 'both'>` | optional | Consumer, producer, or both | -| **messageFormat** | `Enum<'json' \| 'xml' \| 'protobuf' \| 'avro' \| 'text' \| 'binary'>` | optional | Message format/serialization | -| **partitions** | `number` | optional | Number of partitions (for Kafka) | -| **replicationFactor** | `number` | optional | Replication factor (for Kafka) | -| **consumerConfig** | `object` | optional | Consumer-specific configuration | -| **producerConfig** | `object` | optional | Producer-specific configuration | -| **dlqConfig** | `object` | optional | Dead letter queue configuration | -| **routingKey** | `string` | optional | Routing key pattern | -| **messageFilter** | `object` | optional | Message filter criteria | - diff --git a/packages/spec/json-schema/system/AckMode.json b/packages/spec/json-schema/integration/AckMode.json similarity index 100% rename from packages/spec/json-schema/system/AckMode.json rename to packages/spec/json-schema/integration/AckMode.json diff --git a/packages/spec/json-schema/system/ApiKeyAuth.json b/packages/spec/json-schema/integration/ApiKeyAuth.json similarity index 100% rename from packages/spec/json-schema/system/ApiKeyAuth.json rename to packages/spec/json-schema/integration/ApiKeyAuth.json diff --git a/packages/spec/json-schema/system/ApiVersionConfig.json b/packages/spec/json-schema/integration/ApiVersionConfig.json similarity index 100% rename from packages/spec/json-schema/system/ApiVersionConfig.json rename to packages/spec/json-schema/integration/ApiVersionConfig.json diff --git a/packages/spec/json-schema/system/Authentication.json b/packages/spec/json-schema/integration/Authentication.json similarity index 100% rename from packages/spec/json-schema/system/Authentication.json rename to packages/spec/json-schema/integration/Authentication.json diff --git a/packages/spec/json-schema/system/BasicAuth.json b/packages/spec/json-schema/integration/BasicAuth.json similarity index 100% rename from packages/spec/json-schema/system/BasicAuth.json rename to packages/spec/json-schema/integration/BasicAuth.json diff --git a/packages/spec/json-schema/system/BearerTokenAuth.json b/packages/spec/json-schema/integration/BearerTokenAuth.json similarity index 100% rename from packages/spec/json-schema/system/BearerTokenAuth.json rename to packages/spec/json-schema/integration/BearerTokenAuth.json diff --git a/packages/spec/json-schema/system/CdcConfig.json b/packages/spec/json-schema/integration/CdcConfig.json similarity index 100% rename from packages/spec/json-schema/system/CdcConfig.json rename to packages/spec/json-schema/integration/CdcConfig.json diff --git a/packages/spec/json-schema/system/ConflictResolution.json b/packages/spec/json-schema/integration/ConflictResolution.json similarity index 100% rename from packages/spec/json-schema/system/ConflictResolution.json rename to packages/spec/json-schema/integration/ConflictResolution.json diff --git a/packages/spec/json-schema/system/Connector.json b/packages/spec/json-schema/integration/Connector.json similarity index 100% rename from packages/spec/json-schema/system/Connector.json rename to packages/spec/json-schema/integration/Connector.json diff --git a/packages/spec/json-schema/system/ConnectorStatus.json b/packages/spec/json-schema/integration/ConnectorStatus.json similarity index 100% rename from packages/spec/json-schema/system/ConnectorStatus.json rename to packages/spec/json-schema/integration/ConnectorStatus.json diff --git a/packages/spec/json-schema/system/ConnectorType.json b/packages/spec/json-schema/integration/ConnectorType.json similarity index 100% rename from packages/spec/json-schema/system/ConnectorType.json rename to packages/spec/json-schema/integration/ConnectorType.json diff --git a/packages/spec/json-schema/system/ConsumerConfig.json b/packages/spec/json-schema/integration/ConsumerConfig.json similarity index 100% rename from packages/spec/json-schema/system/ConsumerConfig.json rename to packages/spec/json-schema/integration/ConsumerConfig.json diff --git a/packages/spec/json-schema/system/DataSyncConfig.json b/packages/spec/json-schema/integration/DataSyncConfig.json similarity index 100% rename from packages/spec/json-schema/system/DataSyncConfig.json rename to packages/spec/json-schema/integration/DataSyncConfig.json diff --git a/packages/spec/json-schema/system/DatabaseConnector.json b/packages/spec/json-schema/integration/DatabaseConnector.json similarity index 100% rename from packages/spec/json-schema/system/DatabaseConnector.json rename to packages/spec/json-schema/integration/DatabaseConnector.json diff --git a/packages/spec/json-schema/system/DatabasePoolConfig.json b/packages/spec/json-schema/integration/DatabasePoolConfig.json similarity index 100% rename from packages/spec/json-schema/system/DatabasePoolConfig.json rename to packages/spec/json-schema/integration/DatabasePoolConfig.json diff --git a/packages/spec/json-schema/system/DatabaseProvider.json b/packages/spec/json-schema/integration/DatabaseProvider.json similarity index 100% rename from packages/spec/json-schema/system/DatabaseProvider.json rename to packages/spec/json-schema/integration/DatabaseProvider.json diff --git a/packages/spec/json-schema/system/DatabaseTable.json b/packages/spec/json-schema/integration/DatabaseTable.json similarity index 100% rename from packages/spec/json-schema/system/DatabaseTable.json rename to packages/spec/json-schema/integration/DatabaseTable.json diff --git a/packages/spec/json-schema/system/DeliveryGuarantee.json b/packages/spec/json-schema/integration/DeliveryGuarantee.json similarity index 100% rename from packages/spec/json-schema/system/DeliveryGuarantee.json rename to packages/spec/json-schema/integration/DeliveryGuarantee.json diff --git a/packages/spec/json-schema/system/DlqConfig.json b/packages/spec/json-schema/integration/DlqConfig.json similarity index 100% rename from packages/spec/json-schema/system/DlqConfig.json rename to packages/spec/json-schema/integration/DlqConfig.json diff --git a/packages/spec/json-schema/system/FieldMapping.json b/packages/spec/json-schema/integration/FieldMapping.json similarity index 100% rename from packages/spec/json-schema/system/FieldMapping.json rename to packages/spec/json-schema/integration/FieldMapping.json diff --git a/packages/spec/json-schema/system/FieldTransform.json b/packages/spec/json-schema/integration/FieldTransform.json similarity index 100% rename from packages/spec/json-schema/system/FieldTransform.json rename to packages/spec/json-schema/integration/FieldTransform.json diff --git a/packages/spec/json-schema/system/FileAccessPattern.json b/packages/spec/json-schema/integration/FileAccessPattern.json similarity index 100% rename from packages/spec/json-schema/system/FileAccessPattern.json rename to packages/spec/json-schema/integration/FileAccessPattern.json diff --git a/packages/spec/json-schema/system/FileFilterConfig.json b/packages/spec/json-schema/integration/FileFilterConfig.json similarity index 100% rename from packages/spec/json-schema/system/FileFilterConfig.json rename to packages/spec/json-schema/integration/FileFilterConfig.json diff --git a/packages/spec/json-schema/system/FileMetadataConfig.json b/packages/spec/json-schema/integration/FileMetadataConfig.json similarity index 100% rename from packages/spec/json-schema/system/FileMetadataConfig.json rename to packages/spec/json-schema/integration/FileMetadataConfig.json diff --git a/packages/spec/json-schema/system/FileStorageConnector.json b/packages/spec/json-schema/integration/FileStorageConnector.json similarity index 100% rename from packages/spec/json-schema/system/FileStorageConnector.json rename to packages/spec/json-schema/integration/FileStorageConnector.json diff --git a/packages/spec/json-schema/system/FileStorageProvider.json b/packages/spec/json-schema/integration/FileStorageProvider.json similarity index 100% rename from packages/spec/json-schema/system/FileStorageProvider.json rename to packages/spec/json-schema/integration/FileStorageProvider.json diff --git a/packages/spec/json-schema/system/FileVersioningConfig.json b/packages/spec/json-schema/integration/FileVersioningConfig.json similarity index 100% rename from packages/spec/json-schema/system/FileVersioningConfig.json rename to packages/spec/json-schema/integration/FileVersioningConfig.json diff --git a/packages/spec/json-schema/system/JwtAuth.json b/packages/spec/json-schema/integration/JwtAuth.json similarity index 100% rename from packages/spec/json-schema/system/JwtAuth.json rename to packages/spec/json-schema/integration/JwtAuth.json diff --git a/packages/spec/json-schema/system/MessageFormat.json b/packages/spec/json-schema/integration/MessageFormat.json similarity index 100% rename from packages/spec/json-schema/system/MessageFormat.json rename to packages/spec/json-schema/integration/MessageFormat.json diff --git a/packages/spec/json-schema/system/MessageQueueConnector.json b/packages/spec/json-schema/integration/MessageQueueConnector.json similarity index 100% rename from packages/spec/json-schema/system/MessageQueueConnector.json rename to packages/spec/json-schema/integration/MessageQueueConnector.json diff --git a/packages/spec/json-schema/system/MessageQueueProvider.json b/packages/spec/json-schema/integration/MessageQueueProvider.json similarity index 100% rename from packages/spec/json-schema/system/MessageQueueProvider.json rename to packages/spec/json-schema/integration/MessageQueueProvider.json diff --git a/packages/spec/json-schema/system/MultipartUploadConfig.json b/packages/spec/json-schema/integration/MultipartUploadConfig.json similarity index 100% rename from packages/spec/json-schema/system/MultipartUploadConfig.json rename to packages/spec/json-schema/integration/MultipartUploadConfig.json diff --git a/packages/spec/json-schema/system/NoAuth.json b/packages/spec/json-schema/integration/NoAuth.json similarity index 100% rename from packages/spec/json-schema/system/NoAuth.json rename to packages/spec/json-schema/integration/NoAuth.json diff --git a/packages/spec/json-schema/system/OAuth2Auth.json b/packages/spec/json-schema/integration/OAuth2Auth.json similarity index 100% rename from packages/spec/json-schema/system/OAuth2Auth.json rename to packages/spec/json-schema/integration/OAuth2Auth.json diff --git a/packages/spec/json-schema/system/ProducerConfig.json b/packages/spec/json-schema/integration/ProducerConfig.json similarity index 100% rename from packages/spec/json-schema/system/ProducerConfig.json rename to packages/spec/json-schema/integration/ProducerConfig.json diff --git a/packages/spec/json-schema/system/RateLimitConfig.json b/packages/spec/json-schema/integration/RateLimitConfig.json similarity index 100% rename from packages/spec/json-schema/system/RateLimitConfig.json rename to packages/spec/json-schema/integration/RateLimitConfig.json diff --git a/packages/spec/json-schema/system/RateLimitStrategy.json b/packages/spec/json-schema/integration/RateLimitStrategy.json similarity index 100% rename from packages/spec/json-schema/system/RateLimitStrategy.json rename to packages/spec/json-schema/integration/RateLimitStrategy.json diff --git a/packages/spec/json-schema/system/RetryConfig.json b/packages/spec/json-schema/integration/RetryConfig.json similarity index 100% rename from packages/spec/json-schema/system/RetryConfig.json rename to packages/spec/json-schema/integration/RetryConfig.json diff --git a/packages/spec/json-schema/system/RetryStrategy.json b/packages/spec/json-schema/integration/RetryStrategy.json similarity index 100% rename from packages/spec/json-schema/system/RetryStrategy.json rename to packages/spec/json-schema/integration/RetryStrategy.json diff --git a/packages/spec/json-schema/system/SaasConnector.json b/packages/spec/json-schema/integration/SaasConnector.json similarity index 100% rename from packages/spec/json-schema/system/SaasConnector.json rename to packages/spec/json-schema/integration/SaasConnector.json diff --git a/packages/spec/json-schema/system/SaasObjectType.json b/packages/spec/json-schema/integration/SaasObjectType.json similarity index 100% rename from packages/spec/json-schema/system/SaasObjectType.json rename to packages/spec/json-schema/integration/SaasObjectType.json diff --git a/packages/spec/json-schema/system/SaasProvider.json b/packages/spec/json-schema/integration/SaasProvider.json similarity index 100% rename from packages/spec/json-schema/system/SaasProvider.json rename to packages/spec/json-schema/integration/SaasProvider.json diff --git a/packages/spec/json-schema/system/SamlAuth.json b/packages/spec/json-schema/integration/SamlAuth.json similarity index 100% rename from packages/spec/json-schema/system/SamlAuth.json rename to packages/spec/json-schema/integration/SamlAuth.json diff --git a/packages/spec/json-schema/system/SslConfig.json b/packages/spec/json-schema/integration/SslConfig.json similarity index 100% rename from packages/spec/json-schema/system/SslConfig.json rename to packages/spec/json-schema/integration/SslConfig.json diff --git a/packages/spec/json-schema/system/StorageBucket.json b/packages/spec/json-schema/integration/StorageBucket.json similarity index 100% rename from packages/spec/json-schema/system/StorageBucket.json rename to packages/spec/json-schema/integration/StorageBucket.json diff --git a/packages/spec/json-schema/system/SyncStrategy.json b/packages/spec/json-schema/integration/SyncStrategy.json similarity index 100% rename from packages/spec/json-schema/system/SyncStrategy.json rename to packages/spec/json-schema/integration/SyncStrategy.json diff --git a/packages/spec/json-schema/system/TopicQueue.json b/packages/spec/json-schema/integration/TopicQueue.json similarity index 100% rename from packages/spec/json-schema/system/TopicQueue.json rename to packages/spec/json-schema/integration/TopicQueue.json diff --git a/packages/spec/json-schema/system/WebhookConfig.json b/packages/spec/json-schema/integration/WebhookConfig.json similarity index 100% rename from packages/spec/json-schema/system/WebhookConfig.json rename to packages/spec/json-schema/integration/WebhookConfig.json diff --git a/packages/spec/json-schema/system/WebhookEvent.json b/packages/spec/json-schema/integration/WebhookEvent.json similarity index 100% rename from packages/spec/json-schema/system/WebhookEvent.json rename to packages/spec/json-schema/integration/WebhookEvent.json diff --git a/packages/spec/json-schema/system/WebhookSignatureAlgorithm.json b/packages/spec/json-schema/integration/WebhookSignatureAlgorithm.json similarity index 100% rename from packages/spec/json-schema/system/WebhookSignatureAlgorithm.json rename to packages/spec/json-schema/integration/WebhookSignatureAlgorithm.json diff --git a/packages/spec/src/index.ts b/packages/spec/src/index.ts index 4e8c8fc99..c478621a9 100644 --- a/packages/spec/src/index.ts +++ b/packages/spec/src/index.ts @@ -52,6 +52,7 @@ export * as Hub from './hub'; export * as AI from './ai'; export * as API from './api'; export * as Automation from './automation'; +export * as Integration from './integration'; export { defineStack, diff --git a/packages/spec/src/system/connector.test.ts b/packages/spec/src/integration/connector.test.ts similarity index 100% rename from packages/spec/src/system/connector.test.ts rename to packages/spec/src/integration/connector.test.ts diff --git a/packages/spec/src/system/connector.zod.ts b/packages/spec/src/integration/connector.zod.ts similarity index 100% rename from packages/spec/src/system/connector.zod.ts rename to packages/spec/src/integration/connector.zod.ts diff --git a/packages/spec/src/system/connector/database.zod.ts b/packages/spec/src/integration/connector/database.zod.ts similarity index 100% rename from packages/spec/src/system/connector/database.zod.ts rename to packages/spec/src/integration/connector/database.zod.ts diff --git a/packages/spec/src/system/connector/file-storage.zod.ts b/packages/spec/src/integration/connector/file-storage.zod.ts similarity index 100% rename from packages/spec/src/system/connector/file-storage.zod.ts rename to packages/spec/src/integration/connector/file-storage.zod.ts diff --git a/packages/spec/src/system/connector/message-queue.zod.ts b/packages/spec/src/integration/connector/message-queue.zod.ts similarity index 100% rename from packages/spec/src/system/connector/message-queue.zod.ts rename to packages/spec/src/integration/connector/message-queue.zod.ts diff --git a/packages/spec/src/system/connector/saas.zod.ts b/packages/spec/src/integration/connector/saas.zod.ts similarity index 100% rename from packages/spec/src/system/connector/saas.zod.ts rename to packages/spec/src/integration/connector/saas.zod.ts diff --git a/packages/spec/src/integration/index.ts b/packages/spec/src/integration/index.ts new file mode 100644 index 000000000..e513e4418 --- /dev/null +++ b/packages/spec/src/integration/index.ts @@ -0,0 +1,18 @@ +/** + * Integration Protocol Exports + * + * External System Connection Protocols + * - Connector configurations for SaaS, databases, file storage, message queues + * - Authentication methods (OAuth2, API Key, JWT, SAML) + * - Data synchronization and field mapping + * - Webhooks, rate limiting, and retry strategies + */ + +// Core Connector Protocol +export * from './connector.zod'; + +// Connector Templates +export * from './connector/saas.zod'; +export * from './connector/database.zod'; +export * from './connector/file-storage.zod'; +export * from './connector/message-queue.zod'; diff --git a/packages/spec/src/system/index.ts b/packages/spec/src/system/index.ts index 5c05903cc..8764ca28b 100644 --- a/packages/spec/src/system/index.ts +++ b/packages/spec/src/system/index.ts @@ -32,12 +32,6 @@ export * from './driver/postgres.zod'; // Data Engine Protocol export * from './data-engine.zod'; -// Connector Protocol -export * from './connector.zod'; -export * from './connector/saas.zod'; -export * from './connector/database.zod'; -export * from './connector/file-storage.zod'; -export * from './connector/message-queue.zod'; - // Note: Auth, Identity, Policy, Role, Organization moved to @objectstack/spec/auth // Note: Territory moved to @objectstack/spec/permission +// Note: Connector Protocol moved to @objectstack/spec/integration