@aerostack/core 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,13 @@
1
+ # @aerostack/core
2
+
3
+ Shared core types and utilities for Aerostack SDKs.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @aerostack/core
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ This package is used internally by other Aerostack SDKs.
@@ -0,0 +1,163 @@
1
+ import { Product, Cart, AerostackRPC, CollectionItem, StoreConfig, ProductVariant, Category } from './types';
2
+ export interface AerocallConfig {
3
+ baseUrl?: string;
4
+ apiKey?: string;
5
+ jwt?: string;
6
+ projectId?: string;
7
+ }
8
+ export declare class AerocallClient implements AerostackRPC {
9
+ private baseUrl;
10
+ private apiKey?;
11
+ private jwt?;
12
+ private projectId?;
13
+ constructor(config: AerocallConfig);
14
+ private request;
15
+ get db(): {
16
+ query: <T = any>(sql: string, params?: any[]) => Promise<T[]>;
17
+ };
18
+ get cache(): {
19
+ get: <T = any>(key: string) => Promise<{
20
+ value: T | null;
21
+ exists: boolean;
22
+ }>;
23
+ set: (key: string, value: any, ttl?: number) => Promise<{
24
+ success: boolean;
25
+ }>;
26
+ delete: (key: string) => Promise<{
27
+ success: boolean;
28
+ }>;
29
+ };
30
+ get queue(): {
31
+ enqueue: (type: string, data: any) => Promise<{
32
+ success: boolean;
33
+ jobId: string;
34
+ }>;
35
+ };
36
+ get ai(): {
37
+ chat: (messages: {
38
+ role: "user" | "assistant" | "system";
39
+ content: string;
40
+ }[], model?: string) => Promise<{
41
+ response: string;
42
+ }>;
43
+ search: {
44
+ ingest: (content: string, metadata?: Record<string, any>, type?: string) => Promise<{
45
+ success: boolean;
46
+ }>;
47
+ query: (text: string, options?: {
48
+ limit?: number;
49
+ threshold?: number;
50
+ filter?: Record<string, any>;
51
+ }) => Promise<{
52
+ results: any[];
53
+ }>;
54
+ delete: (id: string) => Promise<{
55
+ success: boolean;
56
+ }>;
57
+ deleteByType: (type: string) => Promise<{
58
+ success: boolean;
59
+ }>;
60
+ listTypes: () => Promise<{
61
+ types: string[];
62
+ }>;
63
+ configure: (options: {
64
+ embeddingModel: string;
65
+ }) => Promise<{
66
+ success: boolean;
67
+ }>;
68
+ };
69
+ };
70
+ get storage(): {
71
+ upload: (key: string, file: File | Blob, contentType?: string) => Promise<{
72
+ url: string;
73
+ }>;
74
+ };
75
+ get services(): {
76
+ invoke: <T = any>(serviceName: string, data?: any) => Promise<{
77
+ success: true;
78
+ result: T;
79
+ }>;
80
+ };
81
+ get auth(): {
82
+ signup: (data: {
83
+ email: string;
84
+ password: string;
85
+ name?: string;
86
+ customFields?: Record<string, any>;
87
+ }) => Promise<{
88
+ token: string;
89
+ user: any;
90
+ }>;
91
+ signin: (data: {
92
+ email: string;
93
+ password: string;
94
+ }) => Promise<{
95
+ token: string;
96
+ user: any;
97
+ }>;
98
+ };
99
+ collections(slug: string): {
100
+ list: (options?: {
101
+ status?: "draft" | "published";
102
+ limit?: number;
103
+ }) => Promise<CollectionItem[]>;
104
+ get: (itemId: string) => Promise<CollectionItem>;
105
+ create: (item: {
106
+ slug: string;
107
+ data: Record<string, any>;
108
+ status?: "draft" | "published";
109
+ author_id?: string;
110
+ }) => Promise<CollectionItem>;
111
+ update: (itemId: string, item: Partial<{
112
+ slug: string;
113
+ data: Record<string, any>;
114
+ status: string;
115
+ author_id?: string;
116
+ }>) => Promise<{
117
+ success: boolean;
118
+ }>;
119
+ delete: (itemId: string) => Promise<{
120
+ success: boolean;
121
+ }>;
122
+ };
123
+ ecommerce(): {
124
+ config: () => Promise<StoreConfig>;
125
+ products: {
126
+ list: (options?: {
127
+ category?: string;
128
+ page?: number;
129
+ limit?: number;
130
+ search?: string;
131
+ }) => Promise<{
132
+ products: Product[];
133
+ total: number;
134
+ page: number;
135
+ limit: number;
136
+ }>;
137
+ get: (slugOrId: string) => Promise<{
138
+ product: Product & {
139
+ variants: ProductVariant[];
140
+ };
141
+ }>;
142
+ };
143
+ categories: {
144
+ list: () => Promise<{
145
+ categories: Category[];
146
+ total: number;
147
+ }>;
148
+ };
149
+ cart: (cartId: string) => {
150
+ get: () => Promise<Cart>;
151
+ addItem: (item: {
152
+ productId: string;
153
+ variant_id?: string;
154
+ quantity?: number;
155
+ }) => Promise<Cart>;
156
+ };
157
+ applyCoupon: (code: string) => Promise<{
158
+ valid: boolean;
159
+ discount_amount: number;
160
+ message?: string;
161
+ }>;
162
+ };
163
+ }
package/dist/client.js ADDED
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AerocallClient = void 0;
4
+ class AerocallClient {
5
+ constructor(config) {
6
+ this.baseUrl = config.baseUrl || 'https://api.aerocall.ai/v1';
7
+ this.apiKey = config.apiKey;
8
+ this.jwt = config.jwt;
9
+ this.projectId = config.projectId;
10
+ }
11
+ async request(path, method, body, isMultipart = false) {
12
+ const headers = {
13
+ 'X-SDK-Version': '0.4.0'
14
+ };
15
+ if (!isMultipart) {
16
+ headers['Content-Type'] = 'application/json';
17
+ }
18
+ if (this.apiKey)
19
+ headers['X-API-Key'] = this.apiKey;
20
+ if (this.jwt)
21
+ headers['Authorization'] = `Bearer ${this.jwt}`;
22
+ if (this.projectId)
23
+ headers['X-Project-Id'] = this.projectId;
24
+ headers['X-Request-ID'] = crypto.randomUUID();
25
+ const response = await fetch(`${this.baseUrl}${path}`, {
26
+ method,
27
+ headers,
28
+ body: isMultipart ? body : (body ? JSON.stringify(body) : undefined)
29
+ });
30
+ if (!response.ok) {
31
+ const err = await response.json().catch(() => ({ error: { message: response.statusText } }));
32
+ throw new Error(err.error?.message || 'Unknown error');
33
+ }
34
+ return response.json();
35
+ }
36
+ get db() {
37
+ return {
38
+ query: async (sql, params) => {
39
+ const res = await this.request('/db/query', 'POST', { sql, params });
40
+ return (res?.results ?? []);
41
+ }
42
+ };
43
+ }
44
+ get cache() {
45
+ return {
46
+ get: (key) => this.request('/cache/get', 'POST', { key }),
47
+ set: (key, value, ttl) => this.request('/cache/set', 'POST', { key, value, ttl }),
48
+ delete: (key) => this.request('/cache/delete', 'POST', { key })
49
+ };
50
+ }
51
+ get queue() {
52
+ return {
53
+ enqueue: (type, data) => this.request('/queue/enqueue', 'POST', { type, data })
54
+ };
55
+ }
56
+ get ai() {
57
+ return {
58
+ chat: (messages, model) => this.request('/ai/chat', 'POST', { messages, model }),
59
+ search: {
60
+ ingest: (content, metadata, type) => this.request('/ai/search/ingest', 'POST', { content, metadata, type }),
61
+ query: (text, options) => this.request('/ai/search/query', 'POST', { text, ...options }),
62
+ delete: (id) => this.request('/ai/search/delete', 'POST', { id }),
63
+ deleteByType: (type) => this.request('/ai/search/deleteByType', 'POST', { type }),
64
+ listTypes: () => this.request('/ai/search/listTypes', 'GET'),
65
+ configure: (options) => this.request('/ai/search/configure', 'POST', options)
66
+ }
67
+ };
68
+ }
69
+ get storage() {
70
+ return {
71
+ upload: (key, file, contentType) => {
72
+ const formData = new FormData();
73
+ formData.append('key', key);
74
+ formData.append('file', file);
75
+ if (contentType)
76
+ formData.append('contentType', contentType);
77
+ return this.request('/storage/upload', 'POST', formData, true);
78
+ }
79
+ };
80
+ }
81
+ get services() {
82
+ return {
83
+ invoke: (serviceName, data) => this.request('/services/invoke', 'POST', { serviceName, data })
84
+ };
85
+ }
86
+ get auth() {
87
+ return {
88
+ signup: (data) => this.request('/auth/signup', 'POST', data),
89
+ signin: (data) => this.request('/auth/signin', 'POST', data),
90
+ };
91
+ }
92
+ collections(slug) {
93
+ return {
94
+ list: (options) => this.request(`/collections/${slug}/items`, 'GET', options),
95
+ get: (itemId) => this.request(`/collections/${slug}/items/${itemId}`, 'GET'),
96
+ create: (item) => this.request(`/collections/${slug}/items`, 'POST', item),
97
+ update: (itemId, item) => this.request(`/collections/${slug}/items/${itemId}`, 'PUT', item),
98
+ delete: (itemId) => this.request(`/collections/${slug}/items/${itemId}`, 'DELETE'),
99
+ };
100
+ }
101
+ ecommerce() {
102
+ return {
103
+ config: () => this.request('/ecommerce/config', 'GET'),
104
+ products: {
105
+ list: (options) => this.request('/ecommerce/products', 'GET', options),
106
+ get: (slugOrId) => this.request(`/ecommerce/products/${slugOrId}`, 'GET'),
107
+ },
108
+ categories: {
109
+ list: () => this.request('/ecommerce/categories', 'GET'),
110
+ },
111
+ cart: (cartId) => ({
112
+ get: () => this.request(`/ecommerce/cart/${cartId}`, 'GET'),
113
+ addItem: (item) => this.request(`/ecommerce/cart/${cartId}/items`, 'POST', item),
114
+ }),
115
+ applyCoupon: (code) => this.request('/ecommerce/coupons/validate', 'POST', { code }),
116
+ };
117
+ }
118
+ }
119
+ exports.AerocallClient = AerocallClient;
@@ -0,0 +1,4 @@
1
+ export { AerocallClient, AerocallConfig } from './client';
2
+ export * from './types';
3
+ export * from './types/gateway';
4
+ export * from './schemas/registry';
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.AerocallClient = void 0;
18
+ var client_1 = require("./client");
19
+ Object.defineProperty(exports, "AerocallClient", { enumerable: true, get: function () { return client_1.AerocallClient; } });
20
+ __exportStar(require("./types"), exports);
21
+ __exportStar(require("./types/gateway"), exports);
22
+ __exportStar(require("./schemas/registry"), exports);
@@ -0,0 +1,76 @@
1
+ import { z } from 'zod';
2
+ export declare const RegistryConfigSchemaV1: z.ZodObject<{
3
+ $schema: z.ZodOptional<z.ZodString>;
4
+ name: z.ZodString;
5
+ version: z.ZodString;
6
+ description: z.ZodString;
7
+ author: z.ZodOptional<z.ZodString>;
8
+ type: z.ZodEnum<{
9
+ feature: "feature";
10
+ utility: "utility";
11
+ hook: "hook";
12
+ }>;
13
+ dependencies: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
14
+ registryDependencies: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
15
+ files: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
16
+ source: z.ZodString;
17
+ target: z.ZodString;
18
+ }, z.core.$strip>>>>;
19
+ configuration: z.ZodDefault<z.ZodOptional<z.ZodObject<{
20
+ api_route: z.ZodOptional<z.ZodString>;
21
+ env: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
22
+ }, z.core.$strip>>>;
23
+ }, z.core.$strip>;
24
+ export type RegistryConfigV1 = z.infer<typeof RegistryConfigSchemaV1>;
25
+ export declare const RegistryConfigSchema: z.ZodObject<{
26
+ $schema: z.ZodOptional<z.ZodString>;
27
+ name: z.ZodString;
28
+ version: z.ZodString;
29
+ description: z.ZodString;
30
+ author: z.ZodOptional<z.ZodString>;
31
+ type: z.ZodEnum<{
32
+ feature: "feature";
33
+ utility: "utility";
34
+ hook: "hook";
35
+ }>;
36
+ dependencies: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
37
+ registryDependencies: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
38
+ files: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
39
+ source: z.ZodString;
40
+ target: z.ZodString;
41
+ }, z.core.$strip>>>>;
42
+ configuration: z.ZodDefault<z.ZodOptional<z.ZodObject<{
43
+ api_route: z.ZodOptional<z.ZodString>;
44
+ env: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
45
+ }, z.core.$strip>>>;
46
+ }, z.core.$strip>;
47
+ export type RegistryConfig = z.infer<typeof RegistryConfigSchema>;
48
+ /**
49
+ * Validates a configuration payload against the registry schema.
50
+ * @param config The raw configuration object
51
+ * @returns The successfully parsed and validated configuration, or throws a ZodError
52
+ */
53
+ export declare function validateRegistryConfig(config: unknown): RegistryConfig;
54
+ /**
55
+ * Safely validates a configuration payload against the registry schema.
56
+ * @param config The raw configuration object
57
+ * @returns An object conforming to SafeParseReturnType indicating whether validation was successful
58
+ */
59
+ export declare function safeValidateRegistryConfig(config: unknown): z.ZodSafeParseResult<{
60
+ name: string;
61
+ version: string;
62
+ description: string;
63
+ type: "feature" | "utility" | "hook";
64
+ dependencies: string[];
65
+ registryDependencies: string[];
66
+ files: {
67
+ source: string;
68
+ target: string;
69
+ }[];
70
+ configuration: {
71
+ env: string[];
72
+ api_route?: string | undefined;
73
+ };
74
+ $schema?: string | undefined;
75
+ author?: string | undefined;
76
+ }>;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RegistryConfigSchema = exports.RegistryConfigSchemaV1 = void 0;
4
+ exports.validateRegistryConfig = validateRegistryConfig;
5
+ exports.safeValidateRegistryConfig = safeValidateRegistryConfig;
6
+ const zod_1 = require("zod");
7
+ // The schema is versioned to allow backwards compatibility
8
+ // Version 1 of the schema
9
+ exports.RegistryConfigSchemaV1 = zod_1.z.object({
10
+ $schema: zod_1.z.string().url().optional(),
11
+ name: zod_1.z.string()
12
+ .min(2, "Name must be at least 2 characters")
13
+ .max(50, "Name must be less than 50 characters")
14
+ .regex(/^[a-z0-9-]+$/, "Name can only contain lowercase letters, numbers, and hyphens"),
15
+ version: zod_1.z.string()
16
+ .regex(/^\d+\.\d+\.\d+$/, "Version must follow semantic versioning (e.g., 1.0.0)"),
17
+ description: zod_1.z.string().min(10, "Description must be at least 10 characters"),
18
+ author: zod_1.z.string().optional(),
19
+ type: zod_1.z.enum(['feature', 'utility', 'hook']),
20
+ dependencies: zod_1.z.array(zod_1.z.string()).optional().default([]),
21
+ registryDependencies: zod_1.z.array(zod_1.z.string()).optional().default([]),
22
+ files: zod_1.z.array(zod_1.z.object({
23
+ source: zod_1.z.string(),
24
+ target: zod_1.z.string(),
25
+ })).min(1, "At least one file mapping is required").optional().default([]),
26
+ configuration: zod_1.z.object({
27
+ api_route: zod_1.z.string().optional(),
28
+ env: zod_1.z.array(zod_1.z.string()).optional().default([]),
29
+ }).optional().default({ env: [] }),
30
+ });
31
+ // Current registry schema version
32
+ exports.RegistryConfigSchema = exports.RegistryConfigSchemaV1;
33
+ /**
34
+ * Validates a configuration payload against the registry schema.
35
+ * @param config The raw configuration object
36
+ * @returns The successfully parsed and validated configuration, or throws a ZodError
37
+ */
38
+ function validateRegistryConfig(config) {
39
+ return exports.RegistryConfigSchema.parse(config);
40
+ }
41
+ /**
42
+ * Safely validates a configuration payload against the registry schema.
43
+ * @param config The raw configuration object
44
+ * @returns An object conforming to SafeParseReturnType indicating whether validation was successful
45
+ */
46
+ function safeValidateRegistryConfig(config) {
47
+ return exports.RegistryConfigSchema.safeParse(config);
48
+ }
@@ -0,0 +1,42 @@
1
+ export interface AerostackGatewayConfig {
2
+ models?: Array<{
3
+ id: string;
4
+ provider: string;
5
+ model: string;
6
+ role: string;
7
+ system_prompt?: string;
8
+ max_tokens?: number;
9
+ temperature?: number;
10
+ endpoint?: string;
11
+ format?: string;
12
+ }>;
13
+ routing?: string;
14
+ }
15
+ export interface GatewayMonetizationConfig {
16
+ managed_in_dashboard?: boolean;
17
+ billing_model: 'subscription' | 'pay_as_you_go' | 'freemium' | 'per_token' | 'per_minute';
18
+ credit_topup_enabled?: boolean;
19
+ per_model_cost_tracking?: boolean;
20
+ pricePer1kTokens?: number;
21
+ monthlyPrice?: number;
22
+ includedTokens?: number;
23
+ }
24
+ export interface GatewaySecurityConfig {
25
+ require_api_key?: boolean;
26
+ rate_limit?: {
27
+ strategy: string;
28
+ requests_per_minute: number;
29
+ burst: number;
30
+ };
31
+ allowed_origins?: string[];
32
+ }
33
+ export interface GatewayBillingPayload {
34
+ consumerId: string;
35
+ developerApiId: string;
36
+ metric?: string;
37
+ units: number;
38
+ }
39
+ export interface ConsumerKeyResponse {
40
+ key: string;
41
+ name?: string;
42
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,288 @@
1
+ export interface User {
2
+ id: string;
3
+ email: string;
4
+ name?: string;
5
+ avatar_url?: string;
6
+ created_at: number;
7
+ last_login_at?: number;
8
+ project_id?: string | null;
9
+ email_verified_at?: number;
10
+ phone?: string | null;
11
+ phone_verified_at?: number | null;
12
+ }
13
+ export interface Project {
14
+ id: string;
15
+ user_id: string;
16
+ name: string;
17
+ slug: string;
18
+ description?: string;
19
+ created_at: number;
20
+ updated_at: number;
21
+ is_public: number;
22
+ plan: 'free' | 'pro' | 'enterprise';
23
+ subdomain?: string;
24
+ }
25
+ export interface Component {
26
+ id: string;
27
+ project_id: string;
28
+ name: string;
29
+ schema: any;
30
+ status: 'processing' | 'completed' | 'failed';
31
+ created_at: number;
32
+ updated_at: number;
33
+ }
34
+ export interface Page {
35
+ id: string;
36
+ project_id: string;
37
+ name: string;
38
+ slug: string;
39
+ description?: string;
40
+ type: 'static' | 'collection' | 'dynamic';
41
+ status: 'draft' | 'published' | 'archived';
42
+ meta_title?: string;
43
+ meta_description?: string;
44
+ published_at?: number;
45
+ created_at: number;
46
+ updated_at: number;
47
+ }
48
+ export interface Product {
49
+ id: string;
50
+ project_id: string;
51
+ name: string;
52
+ slug: string;
53
+ description?: string;
54
+ thumbnail_url?: string;
55
+ base_price: number;
56
+ compare_at_price?: number;
57
+ status: 'draft' | 'published' | 'archived';
58
+ product_type: 'simple' | 'variable';
59
+ data: string;
60
+ created_at: number;
61
+ updated_at: number;
62
+ }
63
+ export interface ProductVariant {
64
+ id: string;
65
+ product_id: string;
66
+ name: string;
67
+ price?: number;
68
+ stock_quantity: number;
69
+ attributes: string;
70
+ created_at: number;
71
+ }
72
+ export interface Order {
73
+ id: string;
74
+ project_id: string;
75
+ order_number: string;
76
+ email: string;
77
+ status: 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';
78
+ payment_status: 'unpaid' | 'paid' | 'partially_refunded' | 'refunded';
79
+ fulfillment_status: 'unfulfilled' | 'partially_fulfilled' | 'fulfilled' | 'cancelled';
80
+ currency: string;
81
+ subtotal: number;
82
+ grand_total: number;
83
+ created_at: number;
84
+ }
85
+ export interface Cart {
86
+ id: string;
87
+ project_id: string;
88
+ items: CartItem[];
89
+ created_at: number;
90
+ updated_at: number;
91
+ expires_at: number;
92
+ coupon_code?: string;
93
+ }
94
+ export interface CartItem {
95
+ id: string;
96
+ product_id: string;
97
+ variant_id?: string;
98
+ name: string;
99
+ price: number;
100
+ quantity: number;
101
+ thumbnail_url?: string;
102
+ }
103
+ export interface Customer {
104
+ id: string;
105
+ project_id: string;
106
+ email: string;
107
+ first_name?: string | null;
108
+ last_name?: string | null;
109
+ phone?: string | null;
110
+ created_at: number;
111
+ }
112
+ export interface AerostackRPC {
113
+ db: {
114
+ query<T = any>(sql: string, params?: any[]): Promise<T[]>;
115
+ };
116
+ cache: {
117
+ get<T = any>(key: string): Promise<{
118
+ value: T | null;
119
+ exists: boolean;
120
+ }>;
121
+ set(key: string, value: any, ttl?: number): Promise<{
122
+ success: boolean;
123
+ }>;
124
+ delete(key: string): Promise<{
125
+ success: boolean;
126
+ }>;
127
+ };
128
+ queue: {
129
+ enqueue(type: string, data: any): Promise<{
130
+ success: boolean;
131
+ jobId: string;
132
+ }>;
133
+ };
134
+ ai: {
135
+ chat(messages: Array<{
136
+ role: 'user' | 'assistant' | 'system';
137
+ content: string;
138
+ }>, model?: string): Promise<{
139
+ response: string;
140
+ }>;
141
+ search: {
142
+ ingest(content: string, metadata?: Record<string, any>, type?: string): Promise<{
143
+ success: boolean;
144
+ }>;
145
+ query(text: string, options?: {
146
+ limit?: number;
147
+ threshold?: number;
148
+ filter?: Record<string, any>;
149
+ }): Promise<{
150
+ results: any[];
151
+ }>;
152
+ delete(id: string): Promise<{
153
+ success: boolean;
154
+ }>;
155
+ deleteByType(type: string): Promise<{
156
+ success: boolean;
157
+ }>;
158
+ listTypes(): Promise<{
159
+ types: string[];
160
+ }>;
161
+ configure(options: {
162
+ embeddingModel: string;
163
+ }): Promise<{
164
+ success: boolean;
165
+ }>;
166
+ };
167
+ };
168
+ storage: {
169
+ upload(key: string, file: any, contentType?: string): Promise<{
170
+ url: string;
171
+ }>;
172
+ };
173
+ services: {
174
+ invoke<T = any>(serviceName: string, data?: any): Promise<{
175
+ success: true;
176
+ result: T;
177
+ }>;
178
+ };
179
+ auth: {
180
+ signup(data: {
181
+ email: string;
182
+ password: string;
183
+ name?: string;
184
+ customFields?: Record<string, any>;
185
+ }): Promise<{
186
+ token: string;
187
+ user: any;
188
+ }>;
189
+ signin(data: {
190
+ email: string;
191
+ password: string;
192
+ }): Promise<{
193
+ token: string;
194
+ user: any;
195
+ }>;
196
+ };
197
+ collections(slug: string): {
198
+ list(options?: {
199
+ status?: 'draft' | 'published';
200
+ limit?: number;
201
+ }): Promise<CollectionItem[]>;
202
+ get(itemId: string): Promise<CollectionItem>;
203
+ create(item: {
204
+ slug: string;
205
+ data: Record<string, any>;
206
+ status?: 'draft' | 'published';
207
+ author_id?: string;
208
+ }): Promise<CollectionItem>;
209
+ update(itemId: string, item: Partial<{
210
+ slug: string;
211
+ data: Record<string, any>;
212
+ status: string;
213
+ author_id?: string;
214
+ }>): Promise<{
215
+ success: boolean;
216
+ }>;
217
+ delete(itemId: string): Promise<{
218
+ success: boolean;
219
+ }>;
220
+ };
221
+ ecommerce(): {
222
+ config(): Promise<StoreConfig>;
223
+ products: {
224
+ list(options?: {
225
+ category?: string;
226
+ page?: number;
227
+ limit?: number;
228
+ search?: string;
229
+ }): Promise<{
230
+ products: Product[];
231
+ total: number;
232
+ page: number;
233
+ limit: number;
234
+ }>;
235
+ get(slugOrId: string): Promise<{
236
+ product: Product & {
237
+ variants: ProductVariant[];
238
+ };
239
+ }>;
240
+ };
241
+ categories: {
242
+ list(): Promise<{
243
+ categories: Category[];
244
+ total: number;
245
+ }>;
246
+ };
247
+ cart(cartId: string): {
248
+ get(): Promise<Cart>;
249
+ addItem(item: {
250
+ productId: string;
251
+ variant_id?: string;
252
+ quantity?: number;
253
+ }): Promise<Cart>;
254
+ };
255
+ applyCoupon(code: string): Promise<{
256
+ valid: boolean;
257
+ discount_amount: number;
258
+ message?: string;
259
+ }>;
260
+ };
261
+ }
262
+ export interface CollectionItem {
263
+ id: string;
264
+ collection_id: string;
265
+ slug: string;
266
+ data: any;
267
+ status: 'draft' | 'published';
268
+ author_id?: string;
269
+ created_at: number;
270
+ updated_at: number;
271
+ }
272
+ export interface StoreConfig {
273
+ default_currency: string;
274
+ currency_symbol: string;
275
+ tax_percentage: number;
276
+ flat_shipping_rate: number;
277
+ free_shipping_threshold?: number;
278
+ shipping_enabled: boolean;
279
+ payment_provider?: string;
280
+ }
281
+ export interface Category {
282
+ id: string;
283
+ name: string;
284
+ slug: string;
285
+ description?: string;
286
+ image_url?: string;
287
+ sort_order: number;
288
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "@aerostack/core",
3
+ "version": "0.6.1",
4
+ "description": "Shared types and RPC client for Aerostack SDKs",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "prepublishOnly": "npm run build"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "src"
14
+ ],
15
+ "dependencies": {
16
+ "zod": "^4.3.6"
17
+ },
18
+ "devDependencies": {
19
+ "typescript": "^5.3.0"
20
+ }
21
+ }
package/src/client.ts ADDED
@@ -0,0 +1,151 @@
1
+ import { Product, Order, Cart, Customer, AerostackRPC, CollectionItem, StoreConfig, ProductVariant, Category } from './types';
2
+
3
+ export interface AerocallConfig {
4
+ baseUrl?: string;
5
+ apiKey?: string;
6
+ jwt?: string;
7
+ projectId?: string;
8
+ }
9
+
10
+ export class AerocallClient implements AerostackRPC {
11
+ private baseUrl: string;
12
+ private apiKey?: string;
13
+ private jwt?: string;
14
+ private projectId?: string;
15
+
16
+ constructor(config: AerocallConfig) {
17
+ this.baseUrl = config.baseUrl || 'https://api.aerocall.ai/v1';
18
+ this.apiKey = config.apiKey;
19
+ this.jwt = config.jwt;
20
+ this.projectId = config.projectId;
21
+ }
22
+
23
+ private async request<T>(path: string, method: string, body?: any, isMultipart = false): Promise<T> {
24
+ const headers: Record<string, string> = {
25
+ 'X-SDK-Version': '0.4.0'
26
+ };
27
+ if (!isMultipart) {
28
+ headers['Content-Type'] = 'application/json';
29
+ }
30
+ if (this.apiKey) headers['X-API-Key'] = this.apiKey;
31
+ if (this.jwt) headers['Authorization'] = `Bearer ${this.jwt}`;
32
+ if (this.projectId) headers['X-Project-Id'] = this.projectId;
33
+
34
+ headers['X-Request-ID'] = crypto.randomUUID();
35
+
36
+ const response = await fetch(`${this.baseUrl}${path}`, {
37
+ method,
38
+ headers,
39
+ body: isMultipart ? body : (body ? JSON.stringify(body) : undefined)
40
+ });
41
+
42
+ if (!response.ok) {
43
+ const err = await response.json().catch(() => ({ error: { message: response.statusText } }));
44
+ throw new Error((err as any).error?.message || 'Unknown error');
45
+ }
46
+ return response.json() as Promise<T>;
47
+ }
48
+
49
+ public get db() {
50
+ return {
51
+ query: async <T = any>(sql: string, params?: any[]) => {
52
+ const res = await this.request<{ results: T[]; meta?: any }>('/db/query', 'POST', { sql, params });
53
+ return (res?.results ?? []) as T[];
54
+ }
55
+ };
56
+ }
57
+
58
+ public get cache() {
59
+ return {
60
+ get: <T = any>(key: string) => this.request<{ value: T | null, exists: boolean }>('/cache/get', 'POST', { key }),
61
+ set: (key: string, value: any, ttl?: number) => this.request<{ success: boolean }>('/cache/set', 'POST', { key, value, ttl }),
62
+ delete: (key: string) => this.request<{ success: boolean }>('/cache/delete', 'POST', { key })
63
+ };
64
+ }
65
+
66
+ public get queue() {
67
+ return {
68
+ enqueue: (type: string, data: any) => this.request<{ success: boolean; jobId: string }>('/queue/enqueue', 'POST', { type, data })
69
+ };
70
+ }
71
+
72
+ public get ai() {
73
+ return {
74
+ chat: (messages: { role: 'user' | 'assistant' | 'system'; content: string }[], model?: string) =>
75
+ this.request<{ response: string }>('/ai/chat', 'POST', { messages, model }),
76
+ search: {
77
+ ingest: (content: string, metadata?: Record<string, any>, type?: string) =>
78
+ this.request<{ success: boolean }>('/ai/search/ingest', 'POST', { content, metadata, type }),
79
+ query: (text: string, options?: { limit?: number; threshold?: number; filter?: Record<string, any> }) =>
80
+ this.request<{ results: any[] }>('/ai/search/query', 'POST', { text, ...options }),
81
+ delete: (id: string) => this.request<{ success: boolean }>('/ai/search/delete', 'POST', { id }),
82
+ deleteByType: (type: string) => this.request<{ success: boolean }>('/ai/search/deleteByType', 'POST', { type }),
83
+ listTypes: () => this.request<{ types: string[] }>('/ai/search/listTypes', 'GET'),
84
+ configure: (options: { embeddingModel: string }) => this.request<{ success: boolean }>('/ai/search/configure', 'POST', options)
85
+ }
86
+ };
87
+ }
88
+
89
+ public get storage() {
90
+ return {
91
+ upload: (key: string, file: File | Blob, contentType?: string) => {
92
+ const formData = new FormData();
93
+ formData.append('key', key);
94
+ formData.append('file', file);
95
+ if (contentType) formData.append('contentType', contentType);
96
+ return this.request<{ url: string }>('/storage/upload', 'POST', formData, true);
97
+ }
98
+ };
99
+ }
100
+
101
+ public get services() {
102
+ return {
103
+ invoke: <T = any>(serviceName: string, data?: any) => this.request<{ success: true, result: T }>('/services/invoke', 'POST', { serviceName, data })
104
+ };
105
+ }
106
+
107
+ public get auth() {
108
+ return {
109
+ signup: (data: { email: string; password: string; name?: string; customFields?: Record<string, any> }) =>
110
+ this.request<{ token: string; user: any }>('/auth/signup', 'POST', data),
111
+ signin: (data: { email: string; password: string }) =>
112
+ this.request<{ token: string; user: any }>('/auth/signin', 'POST', data),
113
+ };
114
+ }
115
+
116
+ public collections(slug: string) {
117
+ return {
118
+ list: (options?: { status?: 'draft' | 'published'; limit?: number }) =>
119
+ this.request<CollectionItem[]>(`/collections/${slug}/items`, 'GET', options),
120
+ get: (itemId: string) =>
121
+ this.request<CollectionItem>(`/collections/${slug}/items/${itemId}`, 'GET'),
122
+ create: (item: { slug: string; data: Record<string, any>; status?: 'draft' | 'published'; author_id?: string }) =>
123
+ this.request<CollectionItem>(`/collections/${slug}/items`, 'POST', item),
124
+ update: (itemId: string, item: Partial<{ slug: string; data: Record<string, any>; status: string; author_id?: string }>) =>
125
+ this.request<{ success: boolean }>(`/collections/${slug}/items/${itemId}`, 'PUT', item),
126
+ delete: (itemId: string) =>
127
+ this.request<{ success: boolean }>(`/collections/${slug}/items/${itemId}`, 'DELETE'),
128
+ };
129
+ }
130
+
131
+ public ecommerce() {
132
+ return {
133
+ config: () => this.request<StoreConfig>('/ecommerce/config', 'GET'),
134
+ products: {
135
+ list: (options?: { category?: string; page?: number; limit?: number; search?: string }) =>
136
+ this.request<{ products: Product[]; total: number; page: number; limit: number }>('/ecommerce/products', 'GET', options),
137
+ get: (slugOrId: string) =>
138
+ this.request<{ product: Product & { variants: ProductVariant[] } }>(`/ecommerce/products/${slugOrId}`, 'GET'),
139
+ },
140
+ categories: {
141
+ list: () => this.request<{ categories: Category[]; total: number }>('/ecommerce/categories', 'GET'),
142
+ },
143
+ cart: (cartId: string) => ({
144
+ get: () => this.request<Cart>(`/ecommerce/cart/${cartId}`, 'GET'),
145
+ addItem: (item: { productId: string; variant_id?: string; quantity?: number }) =>
146
+ this.request<Cart>(`/ecommerce/cart/${cartId}/items`, 'POST', item),
147
+ }),
148
+ applyCoupon: (code: string) => this.request<{ valid: boolean; discount_amount: number; message?: string }>('/ecommerce/coupons/validate', 'POST', { code }),
149
+ };
150
+ }
151
+ }
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export { AerocallClient, AerocallConfig } from './client';
2
+ export * from './types';
3
+ export * from './types/gateway';
4
+ export * from './schemas/registry';
@@ -0,0 +1,51 @@
1
+ import { z } from 'zod';
2
+
3
+ // The schema is versioned to allow backwards compatibility
4
+ // Version 1 of the schema
5
+ export const RegistryConfigSchemaV1 = z.object({
6
+ $schema: z.string().url().optional(),
7
+ name: z.string()
8
+ .min(2, "Name must be at least 2 characters")
9
+ .max(50, "Name must be less than 50 characters")
10
+ .regex(/^[a-z0-9-]+$/, "Name can only contain lowercase letters, numbers, and hyphens"),
11
+ version: z.string()
12
+ .regex(/^\d+\.\d+\.\d+$/, "Version must follow semantic versioning (e.g., 1.0.0)"),
13
+ description: z.string().min(10, "Description must be at least 10 characters"),
14
+ author: z.string().optional(),
15
+ type: z.enum(['feature', 'utility', 'hook']),
16
+ dependencies: z.array(z.string()).optional().default([]),
17
+ registryDependencies: z.array(z.string()).optional().default([]),
18
+ files: z.array(z.object({
19
+ source: z.string(),
20
+ target: z.string(),
21
+ })).min(1, "At least one file mapping is required").optional().default([]),
22
+ configuration: z.object({
23
+ api_route: z.string().optional(),
24
+ env: z.array(z.string()).optional().default([]),
25
+ }).optional().default({ env: [] }),
26
+ });
27
+
28
+ export type RegistryConfigV1 = z.infer<typeof RegistryConfigSchemaV1>;
29
+
30
+ // Current registry schema version
31
+ export const RegistryConfigSchema = RegistryConfigSchemaV1;
32
+
33
+ export type RegistryConfig = z.infer<typeof RegistryConfigSchema>;
34
+
35
+ /**
36
+ * Validates a configuration payload against the registry schema.
37
+ * @param config The raw configuration object
38
+ * @returns The successfully parsed and validated configuration, or throws a ZodError
39
+ */
40
+ export function validateRegistryConfig(config: unknown): RegistryConfig {
41
+ return RegistryConfigSchema.parse(config);
42
+ }
43
+
44
+ /**
45
+ * Safely validates a configuration payload against the registry schema.
46
+ * @param config The raw configuration object
47
+ * @returns An object conforming to SafeParseReturnType indicating whether validation was successful
48
+ */
49
+ export function safeValidateRegistryConfig(config: unknown) {
50
+ return RegistryConfigSchema.safeParse(config);
51
+ }
@@ -0,0 +1,46 @@
1
+ export interface AerostackGatewayConfig {
2
+ models?: Array<{
3
+ id: string;
4
+ provider: string;
5
+ model: string;
6
+ role: string;
7
+ system_prompt?: string;
8
+ max_tokens?: number;
9
+ temperature?: number;
10
+ endpoint?: string;
11
+ format?: string;
12
+ }>;
13
+ routing?: string;
14
+ }
15
+
16
+ export interface GatewayMonetizationConfig {
17
+ managed_in_dashboard?: boolean;
18
+ billing_model: 'subscription' | 'pay_as_you_go' | 'freemium' | 'per_token' | 'per_minute';
19
+ credit_topup_enabled?: boolean;
20
+ per_model_cost_tracking?: boolean;
21
+ pricePer1kTokens?: number;
22
+ monthlyPrice?: number;
23
+ includedTokens?: number;
24
+ }
25
+
26
+ export interface GatewaySecurityConfig {
27
+ require_api_key?: boolean;
28
+ rate_limit?: {
29
+ strategy: string;
30
+ requests_per_minute: number;
31
+ burst: number;
32
+ };
33
+ allowed_origins?: string[];
34
+ }
35
+
36
+ export interface GatewayBillingPayload {
37
+ consumerId: string;
38
+ developerApiId: string;
39
+ metric?: string;
40
+ units: number;
41
+ }
42
+
43
+ export interface ConsumerKeyResponse {
44
+ key: string;
45
+ name?: string;
46
+ }
package/src/types.ts ADDED
@@ -0,0 +1,207 @@
1
+ export interface User {
2
+ id: string;
3
+ email: string;
4
+ name?: string;
5
+ avatar_url?: string;
6
+ created_at: number;
7
+ last_login_at?: number;
8
+ project_id?: string | null;
9
+ email_verified_at?: number;
10
+ phone?: string | null;
11
+ phone_verified_at?: number | null;
12
+ }
13
+
14
+ export interface Project {
15
+ id: string;
16
+ user_id: string;
17
+ name: string;
18
+ slug: string;
19
+ description?: string;
20
+ created_at: number;
21
+ updated_at: number;
22
+ is_public: number;
23
+ plan: 'free' | 'pro' | 'enterprise';
24
+ subdomain?: string;
25
+ }
26
+
27
+ export interface Component {
28
+ id: string;
29
+ project_id: string;
30
+ name: string;
31
+ schema: any;
32
+ status: 'processing' | 'completed' | 'failed';
33
+ created_at: number;
34
+ updated_at: number;
35
+ }
36
+
37
+ export interface Page {
38
+ id: string;
39
+ project_id: string;
40
+ name: string;
41
+ slug: string;
42
+ description?: string;
43
+ type: 'static' | 'collection' | 'dynamic';
44
+ status: 'draft' | 'published' | 'archived';
45
+ meta_title?: string;
46
+ meta_description?: string;
47
+ published_at?: number;
48
+ created_at: number;
49
+ updated_at: number;
50
+ }
51
+
52
+ export interface Product {
53
+ id: string;
54
+ project_id: string;
55
+ name: string;
56
+ slug: string;
57
+ description?: string;
58
+ thumbnail_url?: string;
59
+ base_price: number;
60
+ compare_at_price?: number;
61
+ status: 'draft' | 'published' | 'archived';
62
+ product_type: 'simple' | 'variable';
63
+ data: string;
64
+ created_at: number;
65
+ updated_at: number;
66
+ }
67
+
68
+ export interface ProductVariant {
69
+ id: string;
70
+ product_id: string;
71
+ name: string;
72
+ price?: number;
73
+ stock_quantity: number;
74
+ attributes: string;
75
+ created_at: number;
76
+ }
77
+
78
+ export interface Order {
79
+ id: string;
80
+ project_id: string;
81
+ order_number: string;
82
+ email: string;
83
+ status: 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';
84
+ payment_status: 'unpaid' | 'paid' | 'partially_refunded' | 'refunded';
85
+ fulfillment_status: 'unfulfilled' | 'partially_fulfilled' | 'fulfilled' | 'cancelled';
86
+ currency: string;
87
+ subtotal: number;
88
+ grand_total: number;
89
+ created_at: number;
90
+ }
91
+
92
+ export interface Cart {
93
+ id: string;
94
+ project_id: string;
95
+ items: CartItem[];
96
+ created_at: number;
97
+ updated_at: number;
98
+ expires_at: number;
99
+ coupon_code?: string;
100
+ }
101
+
102
+ export interface CartItem {
103
+ id: string;
104
+ product_id: string;
105
+ variant_id?: string;
106
+ name: string;
107
+ price: number;
108
+ quantity: number;
109
+ thumbnail_url?: string;
110
+ }
111
+
112
+ export interface Customer {
113
+ id: string;
114
+ project_id: string;
115
+ email: string;
116
+ first_name?: string | null;
117
+ last_name?: string | null;
118
+ phone?: string | null;
119
+ created_at: number;
120
+ }
121
+
122
+ export interface AerostackRPC {
123
+ db: {
124
+ query<T = any>(sql: string, params?: any[]): Promise<T[]>;
125
+ };
126
+ cache: {
127
+ get<T = any>(key: string): Promise<{ value: T | null; exists: boolean }>;
128
+ set(key: string, value: any, ttl?: number): Promise<{ success: boolean }>;
129
+ delete(key: string): Promise<{ success: boolean }>;
130
+ };
131
+ queue: {
132
+ enqueue(type: string, data: any): Promise<{ success: boolean; jobId: string }>;
133
+ };
134
+ ai: {
135
+ chat(messages: Array<{ role: 'user' | 'assistant' | 'system'; content: string }>, model?: string): Promise<{ response: string }>;
136
+ search: {
137
+ ingest(content: string, metadata?: Record<string, any>, type?: string): Promise<{ success: boolean }>;
138
+ query(text: string, options?: { limit?: number; threshold?: number; filter?: Record<string, any> }): Promise<{ results: any[] }>;
139
+ delete(id: string): Promise<{ success: boolean }>;
140
+ deleteByType(type: string): Promise<{ success: boolean }>;
141
+ listTypes(): Promise<{ types: string[] }>;
142
+ configure(options: { embeddingModel: string }): Promise<{ success: boolean }>;
143
+ };
144
+ };
145
+ storage: {
146
+ upload(key: string, file: any, contentType?: string): Promise<{ url: string }>;
147
+ };
148
+ services: {
149
+ invoke<T = any>(serviceName: string, data?: any): Promise<{ success: true; result: T }>;
150
+ };
151
+ auth: {
152
+ signup(data: { email: string; password: string; name?: string; customFields?: Record<string, any> }): Promise<{ token: string; user: any }>;
153
+ signin(data: { email: string; password: string }): Promise<{ token: string; user: any }>;
154
+ };
155
+ collections(slug: string): {
156
+ list(options?: { status?: 'draft' | 'published'; limit?: number }): Promise<CollectionItem[]>;
157
+ get(itemId: string): Promise<CollectionItem>;
158
+ create(item: { slug: string; data: Record<string, any>; status?: 'draft' | 'published'; author_id?: string }): Promise<CollectionItem>;
159
+ update(itemId: string, item: Partial<{ slug: string; data: Record<string, any>; status: string; author_id?: string }>): Promise<{ success: boolean }>;
160
+ delete(itemId: string): Promise<{ success: boolean }>;
161
+ };
162
+ ecommerce(): {
163
+ config(): Promise<StoreConfig>;
164
+ products: {
165
+ list(options?: { category?: string; page?: number; limit?: number; search?: string }): Promise<{ products: Product[]; total: number; page: number; limit: number }>;
166
+ get(slugOrId: string): Promise<{ product: Product & { variants: ProductVariant[] } }>;
167
+ };
168
+ categories: {
169
+ list(): Promise<{ categories: Category[]; total: number }>;
170
+ };
171
+ cart(cartId: string): {
172
+ get(): Promise<Cart>;
173
+ addItem(item: { productId: string; variant_id?: string; quantity?: number }): Promise<Cart>;
174
+ };
175
+ applyCoupon(code: string): Promise<{ valid: boolean; discount_amount: number; message?: string }>;
176
+ };
177
+ }
178
+
179
+ export interface CollectionItem {
180
+ id: string;
181
+ collection_id: string;
182
+ slug: string;
183
+ data: any;
184
+ status: 'draft' | 'published';
185
+ author_id?: string;
186
+ created_at: number;
187
+ updated_at: number;
188
+ }
189
+
190
+ export interface StoreConfig {
191
+ default_currency: string;
192
+ currency_symbol: string;
193
+ tax_percentage: number;
194
+ flat_shipping_rate: number;
195
+ free_shipping_threshold?: number;
196
+ shipping_enabled: boolean;
197
+ payment_provider?: string;
198
+ }
199
+
200
+ export interface Category {
201
+ id: string;
202
+ name: string;
203
+ slug: string;
204
+ description?: string;
205
+ image_url?: string;
206
+ sort_order: number;
207
+ }