@apito-io/js-admin-sdk 3.0.0 → 3.1.0
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 +5 -12
- package/dist/index.d.mts +13 -39
- package/dist/index.d.ts +13 -39
- package/dist/index.js +16 -46
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +16 -46
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +13 -69
- package/src/index.ts +4 -4
- package/src/types.ts +8 -32
- package/src/version.ts +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/types.ts","../src/typed-operations.ts","../src/version.ts"],"sourcesContent":["import axios, { AxiosInstance } from 'axios';\nimport {\n ClientConfig,\n DefaultDocumentStructure,\n SearchResult,\n TypedDocumentStructure,\n TypedSearchResult,\n CreateAndUpdateRequest,\n GraphQLResponse,\n GraphQLError as SDKGraphQLError,\n ApitoError,\n ValidationError,\n InjectedDBOperationInterface,\n LoginUserResponse,\n User,\n UsersResponse,\n TenantByDomainResponse,\n TenantCatalogSearchRow,\n LoginUserParams,\n CreateUserParams,\n UpdateUserParams,\n GoogleOAuthStateResponse,\n ProjectStorageSettings,\n UpdateProjectStorageInput,\n SystemFile,\n SystemFilesListResponse,\n SystemFileUploadParams,\n DeleteSystemFilesResponse,\n} from './types';\n\nfunction deriveRestBaseURL(graphqlURL: string): string {\n const u = graphqlURL.trim().replace(/\\/$/, '');\n if (u.endsWith('/graphql')) {\n return u.slice(0, -'/graphql'.length);\n }\n return u;\n}\n\n/**\n * Apito SDK Client - JavaScript implementation matching the Go SDK\n */\nexport class ApitoClient implements InjectedDBOperationInterface {\n private httpClient: AxiosInstance;\n private baseURL: string;\n private restBaseURL: string;\n private apiKey: string;\n private tenantId?: string;\n\n constructor(config: ClientConfig) {\n this.baseURL = config.baseURL;\n this.restBaseURL = (config.restBaseURL ?? '').trim() || deriveRestBaseURL(config.baseURL);\n this.apiKey = config.apiKey;\n this.tenantId = config.tenantId;\n\n // Create axios instance with default configuration\n this.httpClient = axios.create({\n timeout: config.timeout || 30000,\n headers: {\n 'Content-Type': 'application/json',\n ...(this.apiKey.startsWith('cli-') || this.apiKey.startsWith('sdk-')\n ? { 'X-Apito-Sync-Key': this.apiKey }\n : { 'X-Apito-Key': this.apiKey }),\n },\n ...config.httpClient,\n });\n\n // Add tenant ID to headers if provided\n if (this.tenantId) {\n this.httpClient.defaults.headers['X-Apito-Tenant-ID'] = this.tenantId;\n }\n }\n\n /**\n * Execute an arbitrary GraphQL query or mutation against the Apito admin (system) endpoint.\n * Use for plugin-registered operations (e.g. processLedger, plg_closeOrder) when not wrapped by dedicated SDK methods.\n */\n async executeGraphQL(\n query: string,\n variables?: Record<string, any>,\n options?: { tenantId?: string }\n ): Promise<GraphQLResponse> {\n try {\n const payload = {\n query,\n variables: variables || {},\n };\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(this.apiKey.startsWith('cli-') || this.apiKey.startsWith('sdk-')\n ? { 'X-Apito-Sync-Key': this.apiKey }\n : { 'X-Apito-Key': this.apiKey }),\n };\n\n if (options?.tenantId || this.tenantId) {\n headers['X-Apito-Tenant-ID'] = options?.tenantId || this.tenantId!;\n }\n\n const response = await this.httpClient.post<GraphQLResponse>(\n this.baseURL,\n payload,\n { headers }\n );\n\n if (response.data.errors && response.data.errors.length > 0) {\n throw new SDKGraphQLError(\n 'GraphQL query failed',\n response.data.errors,\n response.data\n );\n }\n\n return response.data;\n } catch (error) {\n if (axios.isAxiosError(error)) {\n throw new ApitoError(\n error.response?.data?.message || error.message,\n 'HTTP_ERROR',\n error.response?.status,\n error.response?.data\n );\n }\n throw error;\n }\n }\n\n /**\n * Generate a tenant-scoped API key. Matches engine `generateTenantToken`: `tenant_id`, `duration`, optional `role`.\n * Auth uses `X-Apito-Key` (client `apiKey`).\n *\n * @param tenantId Catalog tenant id (`tenant_id` in the mutation).\n * @param duration Expiry calendar day `YYYY-MM-DD`. If omitted/empty, defaults to one year ahead in UTC.\n * @param role Optional token role; if omitted/empty, the engine defaults to `admin`.\n */\n async generateTenantToken(tenantId: string, duration?: string, role?: string): Promise<string> {\n let dur = (duration ?? '').trim();\n if (!dur) {\n const d = new Date();\n dur = `${d.getUTCFullYear() + 1}-${String(d.getUTCMonth() + 1).padStart(2, '0')}-${String(\n d.getUTCDate()\n ).padStart(2, '0')}`;\n }\n\n const query = `\n mutation GenerateTenantToken($tenantId: String!, $duration: String!, $role: String) {\n generateTenantToken(tenant_id: $tenantId, duration: $duration, role: $role) {\n token\n }\n }\n `;\n\n const variables: Record<string, any> = {\n tenantId,\n duration: dur,\n role: role !== undefined && role.trim() !== '' ? role.trim() : null,\n };\n const response = await this.executeGraphQL(query, variables, { tenantId });\n\n const data = response.data?.generateTenantToken;\n if (!data?.token) {\n throw new ValidationError('Invalid response format for tenant token');\n }\n\n return data.token;\n }\n\n private authHeaders(tenantId?: string): Record<string, string> {\n const headers: Record<string, string> = {\n ...(this.apiKey.startsWith('cli-') || this.apiKey.startsWith('sdk-')\n ? { 'X-Apito-Sync-Key': this.apiKey }\n : { 'X-Apito-Key': this.apiKey }),\n };\n const tid = tenantId ?? this.tenantId;\n if (tid) {\n headers['X-Apito-Tenant-ID'] = tid;\n }\n return headers;\n }\n\n private async executeREST<T>(\n method: 'GET' | 'POST',\n path: string,\n options?: {\n query?: Record<string, string | number | undefined>;\n jsonBody?: Record<string, unknown>;\n formData?: FormData;\n allowFailure?: boolean;\n }\n ): Promise<T> {\n const url = new URL(`${this.restBaseURL.replace(/\\/$/, '')}${path}`);\n if (options?.query) {\n for (const [k, v] of Object.entries(options.query)) {\n if (v !== undefined && v !== '') {\n url.searchParams.set(k, String(v));\n }\n }\n }\n const headers = this.authHeaders();\n let data: FormData | Record<string, unknown> | undefined;\n if (options?.formData) {\n data = options.formData;\n } else if (options?.jsonBody) {\n headers['Content-Type'] = 'application/json';\n data = options.jsonBody;\n }\n try {\n const response = await this.httpClient.request({\n method,\n url: url.toString(),\n headers,\n data,\n maxBodyLength: Infinity,\n maxContentLength: Infinity,\n });\n const body = response.data as Record<string, unknown>;\n if (body.success === false && !options?.allowFailure) {\n throw new ValidationError(String(body.message ?? 'request failed'));\n }\n return body as T;\n } catch (error) {\n if (axios.isAxiosError(error)) {\n const msg =\n (error.response?.data as { message?: string })?.message ?? error.message;\n throw new ApitoError(msg, 'HTTP_ERROR', error.response?.status, error.response?.data);\n }\n throw error;\n }\n }\n\n /**\n * Project user login (system GraphQL `loginUser`). Password path: pass `password` and `email` or `phone` per project Authentication settings. Google OAuth path: `authMethod: 'google'` with `code` and `state` from the redirect; call `googleOAuthState(projectId)` before opening Google to obtain `state`.\n */\n async loginUser(params: LoginUserParams): Promise<LoginUserResponse> {\n const authMethod = (params.authMethod ?? 'general').trim().toLowerCase() || 'general';\n const variables: Record<string, any> = {\n project_id: params.projectId,\n };\n\n if (authMethod === 'google') {\n variables.auth_method = 'google';\n const code = (params.code ?? '').trim();\n const state = (params.state ?? '').trim();\n if (!code || !state) {\n throw new ValidationError('code and state are required for Google login');\n }\n variables.code = code;\n variables.state = state;\n } else {\n const password = (params.password ?? '').trim();\n if (!password) {\n throw new ValidationError('password is required');\n }\n variables.password = password;\n const email = (params.email ?? '').trim();\n const phone = (params.phone ?? '').trim();\n if (!email && !phone) {\n throw new ValidationError('email or phone is required');\n }\n if (email) variables.email = email;\n if (phone) variables.phone = phone;\n }\n\n const query = `\n query LoginUser($project_id: String!, $password: String, $auth_method: String, $email: String, $phone: String, $code: String, $state: String) {\n loginUser(project_id: $project_id, password: $password, auth_method: $auth_method, email: $email, phone: $phone, code: $code, state: $state) {\n token\n user {\n id\n email\n phone\n role\n provider\n tenant_id\n status\n created_at\n updated_at\n }\n }\n }\n `;\n const response = await this.executeGraphQL(query, variables);\n const raw = response.data?.loginUser;\n if (!raw?.token) {\n throw new ValidationError('Invalid response format for loginUser');\n }\n return {\n token: raw.token as string,\n user: raw.user as User | undefined,\n };\n }\n\n /**\n * Signed OAuth state for Google login (system query `googleOAuthState`). Use in the authorize URL together with project `google_client_id` and the configured redirect URI.\n */\n async googleOAuthState(projectId: string): Promise<GoogleOAuthStateResponse> {\n const query = `\n query GoogleOAuthState($project_id: String!) {\n googleOAuthState(project_id: $project_id) {\n state\n }\n }\n `;\n const variables = { project_id: projectId };\n const response = await this.executeGraphQL(query, variables);\n const raw = response.data?.googleOAuthState;\n const state = typeof raw?.state === 'string' ? raw.state.trim() : '';\n if (!state) {\n throw new ValidationError('Invalid response format for googleOAuthState');\n }\n return { state };\n }\n\n /**\n * Search project end-users.\n */\n async searchUsers(\n projectId: string,\n limit?: number,\n offset?: number\n ): Promise<UsersResponse> {\n const query = `\n query SearchUsers($project_id: String!, $limit: Int, $offset: Int) {\n searchUsers(project_id: $project_id, limit: $limit, offset: $offset) {\n count\n users {\n id\n email\n phone\n role\n provider\n tenant_id\n status\n created_at\n updated_at\n }\n }\n }\n `;\n const variables: Record<string, any> = { project_id: projectId };\n if (limit !== undefined) variables.limit = limit;\n if (offset !== undefined) variables.offset = offset;\n const response = await this.executeGraphQL(query, variables);\n const raw = response.data?.searchUsers;\n if (!raw) {\n throw new ValidationError('Invalid response format for searchUsers');\n }\n let count = 0;\n if (typeof raw.count === 'number') {\n count = raw.count;\n }\n const users = (raw.users ?? []) as User[];\n return { users, count };\n }\n\n /**\n * Resolve the single SaaS catalog tenant for an exact domain match in the project (`tenant` null if none).\n */\n async searchTenantsByDomain(projectId: string, domain: string): Promise<TenantByDomainResponse> {\n const query = `\n query SearchTenantsByDomain($project_id: String!, $domain: String!) {\n searchTenantsByDomain(project_id: $project_id, domain: $domain) {\n tenant {\n id\n name\n status\n domain\n data\n }\n }\n }\n `;\n const variables: Record<string, any> = {\n project_id: projectId,\n domain,\n };\n const response = await this.executeGraphQL(query, variables);\n const raw = response.data?.searchTenantsByDomain;\n if (!raw) {\n throw new ValidationError('Invalid response format for searchTenantsByDomain');\n }\n const tenant = (raw.tenant ?? null) as TenantCatalogSearchRow | null;\n return { tenant };\n }\n\n /**\n * Create a project user (local password). Use `email` and/or `phone` per engine validation for the project identifier mode.\n */\n async createUser(projectId: string, params: CreateUserParams): Promise<User> {\n const password = (params.password ?? '').trim();\n if (!password) {\n throw new ValidationError('password is required');\n }\n const query = `\n mutation CreateUser($project_id: String!, $password: String!, $role: String, $email: String, $phone: String) {\n createUser(project_id: $project_id, password: $password, role: $role, email: $email, phone: $phone) {\n id\n email\n phone\n role\n provider\n tenant_id\n status\n created_at\n updated_at\n }\n }\n `;\n const variables: Record<string, any> = {\n project_id: projectId,\n password,\n };\n const role = (params.role ?? '').trim();\n if (role) variables.role = role;\n const email = (params.email ?? '').trim();\n if (email) variables.email = email;\n const phone = (params.phone ?? '').trim();\n if (phone) variables.phone = phone;\n const response = await this.executeGraphQL(query, variables);\n const u = response.data?.createUser;\n if (!u?.id) {\n throw new ValidationError('Invalid response format for createUser');\n }\n return u as User;\n }\n\n /**\n * Update a project user. Project scope is implied by the API key. Only include fields to change.\n */\n async updateUser(userId: string, params: UpdateUserParams): Promise<User> {\n const uid = (userId ?? '').trim();\n if (!uid) {\n throw new ValidationError('userId is required');\n }\n if (params.email === undefined && params.phone === undefined && params.role === undefined) {\n throw new ValidationError('at least one field must be provided');\n }\n const query = `\n mutation UpdateUser($user_id: String!, $email: String, $phone: String, $role: String) {\n updateUser(user_id: $user_id, email: $email, phone: $phone, role: $role) {\n id\n email\n phone\n role\n provider\n tenant_id\n status\n created_at\n updated_at\n }\n }\n `;\n const variables: Record<string, any> = { user_id: uid };\n if (params.email !== undefined) variables.email = params.email;\n if (params.phone !== undefined) variables.phone = params.phone;\n if (params.role !== undefined) variables.role = params.role;\n const response = await this.executeGraphQL(query, variables);\n const u = response.data?.updateUser;\n if (!u?.id) {\n throw new ValidationError('Invalid response format for updateUser');\n }\n return u as User;\n }\n\n /** Set a new password for a project user (admin mutation resetUserPassword). */\n async resetUserPassword(userId: string, password: string): Promise<boolean> {\n const uid = (userId ?? '').trim();\n if (!uid) {\n throw new ValidationError('userId is required');\n }\n if (!(password ?? '').trim()) {\n throw new ValidationError('password is required');\n }\n const query = `\n mutation ResetUserPassword($user_id: String!, $password: String!) {\n resetUserPassword(user_id: $user_id, password: $password)\n }\n `;\n const response = await this.executeGraphQL(query, { user_id: uid, password });\n const ok = response.data?.resetUserPassword;\n if (typeof ok !== 'boolean') {\n throw new ValidationError('Invalid response format for resetUserPassword');\n }\n return ok;\n }\n\n /**\n * Delete a project user by id. Project scope is implied by the API key.\n */\n async deleteUser(userId: string): Promise<boolean> {\n const uid = (userId ?? '').trim();\n if (!uid) {\n throw new ValidationError('userId is required');\n }\n const query = `\n mutation DeleteUser($user_id: String!) {\n deleteUser(user_id: $user_id)\n }\n `;\n const response = await this.executeGraphQL(query, { user_id: uid });\n const ok = response.data?.deleteUser;\n if (typeof ok !== 'boolean') {\n throw new ValidationError('Invalid response format for deleteUser');\n }\n return ok;\n }\n\n /** Read project storage settings via getProject. */\n async getProjectStorageSettings(projectId: string): Promise<ProjectStorageSettings> {\n const query = `\n query GetProjectStorageSettings($_id: String!) {\n getProject(_id: $_id) {\n storage_settings {\n use_free_cloud_storage\n endpoint\n region\n bucket\n access_key_id\n has_secret_access_key\n public_base_url\n force_path_style\n }\n }\n }\n `;\n const response = await this.executeGraphQL(query, { _id: projectId });\n const settings = response.data?.getProject?.storage_settings;\n if (!settings) {\n throw new ValidationError('Invalid response format for getProjectStorageSettings');\n }\n return settings as ProjectStorageSettings;\n }\n\n /** Persist project storage settings. */\n async updateProjectStorageSettings(\n input: UpdateProjectStorageInput\n ): Promise<ProjectStorageSettings> {\n const query = `\n mutation UpdateProjectStorageSettings($input: UpdateProjectStorageInput!) {\n updateProjectStorageSettings(input: $input) {\n storage_settings {\n use_free_cloud_storage\n endpoint\n region\n bucket\n access_key_id\n has_secret_access_key\n public_base_url\n force_path_style\n }\n }\n }\n `;\n const response = await this.executeGraphQL(query, { input });\n const settings = response.data?.updateProjectStorageSettings?.storage_settings;\n if (!settings) {\n throw new ValidationError('Invalid response format for updateProjectStorageSettings');\n }\n return settings as ProjectStorageSettings;\n }\n\n /** Upload a file via POST /system/files/upload. */\n async uploadSystemFile(params: SystemFileUploadParams): Promise<SystemFile> {\n const size =\n params.content instanceof ArrayBuffer\n ? params.content.byteLength\n : params.content.byteLength;\n if (!params.content || size === 0) {\n throw new ValidationError('file content is required');\n }\n const fileName = (params.fileName ?? '').trim() || 'upload';\n const form = new FormData();\n const bytes =\n params.content instanceof ArrayBuffer ? new Uint8Array(params.content) : params.content;\n const blob = new Blob([bytes as BlobPart]);\n form.append('file', blob, fileName);\n if (params.fileType?.trim()) {\n form.append('file_type', params.fileType.trim());\n }\n const body = await this.executeREST<{ file: SystemFile }>('POST', '/files/upload', {\n formData: form,\n });\n if (!body.file?.id) {\n throw new ValidationError('Invalid response format for uploadSystemFile');\n }\n return body.file;\n }\n\n /** List files via GET /system/files/list. */\n async listSystemFiles(\n fileType?: string,\n limit?: number,\n offset?: number\n ): Promise<SystemFilesListResponse> {\n const body = await this.executeREST<{\n files: SystemFile[];\n total: number;\n }>('GET', '/files/list', {\n query: {\n file_type: fileType,\n limit,\n offset,\n },\n });\n return {\n files: body.files ?? [],\n total: body.total ?? 0,\n };\n }\n\n /** Delete files via POST /system/files/delete. */\n async deleteSystemFiles(ids: string[]): Promise<DeleteSystemFilesResponse> {\n if (!ids?.length) {\n throw new ValidationError('ids are required');\n }\n const body = await this.executeREST<DeleteSystemFilesResponse>('POST', '/files/delete', {\n jsonBody: { ids },\n allowFailure: true,\n });\n const result: DeleteSystemFilesResponse = {\n success: !!body.success,\n deleted_ids: body.deleted_ids ?? [],\n storage_failed: body.storage_failed,\n message: body.message,\n };\n if (!result.success && result.message) {\n throw new ValidationError(result.message);\n }\n return result;\n }\n\n /**\n * Get a single resource by model and ID\n */\n async getSingleResource(\n model: string,\n id: string,\n singlePageData: boolean = false\n ): Promise<DefaultDocumentStructure> {\n const query = `\n query GetSingleData($model: String, $_id: String!, $single_page_data: Boolean) {\n getSingleData(model: $model, _id: $_id, single_page_data: $single_page_data) {\n _key\n data\n meta {\n created_at\n updated_at\n status\n revision\n revision_at\n }\n id\n expire_at\n relation_doc_id\n type\n }\n }\n `;\n\n const variables = {\n model,\n _id: id,\n single_page_data: singlePageData,\n };\n\n const response = await this.executeGraphQL(query, variables);\n\n if (!response.data?.getSingleData) {\n throw new ValidationError('Resource not found');\n }\n\n return response.data.getSingleData;\n }\n\n /**\n * Search resources in a model\n */\n async searchResources(\n model: string,\n filter: Record<string, any> = {},\n aggregate: boolean = false\n ): Promise<SearchResult> {\n const query = `\n query GetModelData(\n $model: String!\n $page: Int\n $limit: Int\n $_key: JSON\n $where: JSON\n $search: String\n ) {\n getModelData(\n model: $model\n page: $page\n limit: $limit\n _key: $_key\n where: $where\n search: $search\n ) {\n results {\n id\n relation_doc_id\n data\n type\n expire_at\n meta {\n created_at\n updated_at\n status\n root_revision_id\n }\n }\n count\n }\n }\n `;\n\n // Only forward keys declared on the GraphQL operation (matches go-internal-sdk)\n const variables: Record<string, any> = { model };\n if (filter && typeof filter === 'object') {\n if (filter._key !== undefined) {\n variables._key = filter._key;\n }\n if (filter.page !== undefined) {\n variables.page = filter.page;\n }\n if (filter.limit !== undefined) {\n variables.limit = filter.limit;\n }\n if (filter.where !== undefined) {\n variables.where = filter.where;\n }\n if (filter.search !== undefined) {\n variables.search = filter.search;\n }\n }\n\n const response = await this.executeGraphQL(query, variables);\n\n if (!response.data?.getModelData) {\n throw new ValidationError('Invalid search response format');\n }\n\n return response.data.getModelData;\n }\n\n /**\n * Get related documents\n */\n async getRelationDocuments(\n id: string,\n connection: Record<string, any>\n ): Promise<SearchResult> {\n const query = `\n query GetModelData($model: String!, $page: Int, $limit: Int, $where: JSON, $search: String, $connection : ListAllDataDetailedOfAModelConnectionPayload) {\n getModelData(model: $model, page: $page, limit: $limit, where: $where, search: $search, connection: $connection) {\n results {\n id\n relation_doc_id\n data\n type\n expire_at\n meta {\n created_at\n updated_at\n status\n root_revision_id\n }\n }\n count\n }\n }\n `;\n\n const variables: Record<string, any> = {\n connection,\n };\n\n // Extract model from connection if available\n if (connection.model) {\n variables.model = connection.model;\n } else {\n throw new ValidationError('model is required in connection parameters');\n }\n\n // Add filter parameters if provided in connection\n if (connection.filter) {\n const filter = connection.filter;\n if (filter.page !== undefined) {\n variables.page = filter.page;\n }\n if (filter.limit !== undefined) {\n variables.limit = filter.limit;\n }\n if (filter.where !== undefined) {\n variables.where = filter.where;\n }\n if (filter.search !== undefined) {\n variables.search = filter.search;\n }\n }\n\n const response = await this.executeGraphQL(query, variables);\n\n if (!response.data?.getModelData) {\n throw new ValidationError('Invalid relation documents response format');\n }\n\n return response.data.getModelData;\n }\n\n /**\n * Create a new resource\n */\n async createNewResource(request: CreateAndUpdateRequest): Promise<DefaultDocumentStructure> {\n if (!request.model) {\n throw new ValidationError('model is required');\n }\n\n if (!request.payload) {\n throw new ValidationError('payload is required');\n }\n\n const query = `\n mutation CreateNewData($model: String!, $single_page_data: Boolean, $payload: JSON!, $connect: JSON) {\n upsertModelData(\n connect: $connect\n model_name: $model\n single_page_data: $single_page_data\n payload: $payload\n ) {\n id\n type\n data\n meta {\n created_at\n updated_at\n status\n revision\n revision_at\n }\n }\n }\n `;\n\n const variables: Record<string, any> = {\n model: request.model,\n payload: request.payload,\n single_page_data: request.singlePageData || false,\n };\n\n if (request.connect) {\n variables.connect = request.connect;\n }\n\n const response = await this.executeGraphQL(query, variables);\n\n if (!response.data?.upsertModelData) {\n throw new ValidationError('Invalid create response format');\n }\n\n return response.data.upsertModelData;\n }\n\n /**\n * Update an existing resource\n */\n async updateResource(request: CreateAndUpdateRequest): Promise<DefaultDocumentStructure> {\n if (!request.id) {\n throw new ValidationError('id is required');\n }\n\n if (!request.model) {\n throw new ValidationError('model is required');\n }\n\n if (!request.payload) {\n throw new ValidationError('payload is required');\n }\n\n const query = `\n mutation UpdateModelData($_id: String!, $model: String!, $single_page_data: Boolean, $force_update: Boolean, $payload: JSON!, $connect: JSON, $disconnect: JSON) {\n upsertModelData(\n connect: $connect\n model_name: $model\n single_page_data: $single_page_data\n force_update: $force_update\n disconnect: $disconnect\n _id: $_id\n payload: $payload\n ) {\n id\n type\n data\n meta {\n created_at\n updated_at\n status\n revision\n revision_at\n }\n }\n }\n `;\n\n const variables: Record<string, any> = {\n _id: request.id,\n model: request.model,\n payload: request.payload,\n single_page_data: request.singlePageData || false,\n force_update: request.forceUpdate || false,\n };\n\n if (request.connect) {\n variables.connect = request.connect;\n }\n if (request.disconnect) {\n variables.disconnect = request.disconnect;\n }\n\n const response = await this.executeGraphQL(query, variables);\n\n if (!response.data?.upsertModelData) {\n throw new ValidationError('Invalid update response format');\n }\n\n return response.data.upsertModelData;\n }\n\n /**\n * Delete a resource by model and ID\n */\n async deleteResource(model: string, id: string): Promise<void> {\n const query = `\n mutation DeleteData($model: String!, $_id: String!) {\n deleteModelData(model_name: $model, _id: $_id) {\n id\n }\n }\n `;\n\n const variables = {\n model,\n _id: id,\n };\n\n await this.executeGraphQL(query, variables);\n }\n\n /**\n * Debug is used to debug the plugin, you can pass data here to debug the plugin\n */\n async debug(stage: string, ...data: any[]): Promise<any> {\n const query = `\n mutation Debug($stage: String!, $data: JSON) {\n debug(stage: $stage, data: $data) {\n message\n data\n }\n }\n `;\n\n const variables = {\n stage,\n data,\n };\n\n const response = await this.executeGraphQL(query, variables);\n\n return response.data?.debug;\n }\n}\n\n/**\n * Factory function to create a new Apito client\n */\nexport function createClient(config: ClientConfig): ApitoClient {\n return new ApitoClient(config);\n}\n","/**\n * Type definitions for the Apito JavaScript SDK\n */\n\nexport interface MetaField {\n created_at: string;\n updated_at: string;\n status: string;\n revision?: string;\n revision_at?: string;\n root_revision_id?: string;\n}\n\nexport interface DefaultDocumentStructure {\n _key?: string;\n _id?: string;\n data: any;\n meta?: MetaField;\n id: string;\n expire_at?: string | number;\n relation_doc_id?: string;\n last_revision_doc_id?: string;\n type?: string;\n tenant_id?: string;\n tenant_model?: string;\n}\n\nexport interface SearchResult {\n results: DefaultDocumentStructure[];\n count: number;\n}\n\nexport interface TypedDocumentStructure<T> {\n _key?: string;\n _id?: string;\n data: T;\n meta?: MetaField;\n id: string;\n expire_at?: string | number;\n relation_doc_id?: string;\n last_revision_doc_id?: string;\n type?: string;\n tenant_id?: string;\n tenant_model?: string;\n}\n\nexport interface TypedSearchResult<T> {\n results: TypedDocumentStructure<T>[];\n count: number;\n}\n\nexport interface Filter {\n page?: number;\n offset?: number;\n limit?: number;\n order?: string;\n min?: number;\n max?: number;\n category?: string;\n}\n\nexport interface GraphQLErrorLocation {\n line: number;\n column: number;\n}\n\nexport interface GraphQLError {\n message: string;\n locations?: GraphQLErrorLocation[];\n path?: (string | number)[];\n extensions?: Record<string, any>;\n}\n\nexport interface GraphQLResponse {\n data?: any;\n errors?: GraphQLError[];\n}\n\nexport interface CreateAndUpdateRequest {\n id?: string;\n model: string;\n payload: any;\n connect?: Record<string, any>;\n disconnect?: Record<string, any>;\n singlePageData?: boolean;\n forceUpdate?: boolean;\n}\n\n/** Project end-user from engine system DB (table project_users). */\nexport interface User {\n id: string;\n email?: string;\n phone?: string;\n role: string;\n tenant_id?: string;\n provider?: string;\n status?: string;\n created_at?: string;\n updated_at?: string;\n}\n\n/** Login via system GraphQL `loginUser`. Password path: use `email` or `phone` per project settings. Google OAuth code path: `authMethod: 'google'`, `code`, `state` from redirect (get `state` first via `googleOAuthState`). */\nexport interface LoginUserParams {\n projectId: string;\n password?: string;\n email?: string;\n phone?: string;\n authMethod?: string;\n code?: string;\n state?: string;\n}\n\nexport interface GoogleOAuthStateResponse {\n state: string;\n}\n\nexport interface CreateUserParams {\n password: string;\n role?: string;\n email?: string;\n phone?: string;\n}\n\n/** Optional fields for `updateUser`; omitted keys are not sent. */\nexport interface UpdateUserParams {\n email?: string;\n phone?: string;\n role?: string;\n}\n\nexport interface LoginUserResponse {\n token: string;\n user?: User;\n}\n\nexport interface UsersResponse {\n users: User[];\n count: number;\n}\n\nexport interface ProjectStorageSettings {\n use_free_cloud_storage: boolean;\n endpoint?: string | null;\n region?: string | null;\n bucket?: string | null;\n access_key_id?: string | null;\n has_secret_access_key: boolean;\n public_base_url?: string | null;\n force_path_style?: boolean | null;\n}\n\nexport interface UpdateProjectStorageInput {\n use_free_cloud_storage?: boolean;\n endpoint?: string;\n region?: string;\n bucket?: string;\n access_key_id?: string;\n secret_access_key?: string;\n public_base_url?: string;\n force_path_style?: boolean;\n}\n\nexport interface SystemFile {\n id: string;\n file_type: string;\n file_name: string;\n file_extension?: string;\n content_type?: string;\n size: number;\n url: string;\n created_by?: string;\n created_at?: string;\n}\n\nexport interface SystemFilesListResponse {\n files: SystemFile[];\n total: number;\n}\n\nexport interface SystemFileUploadParams {\n fileName: string;\n content: Uint8Array | ArrayBuffer;\n fileType?: string;\n}\n\nexport interface DeleteSystemFilesResponse {\n success: boolean;\n deleted_ids: string[];\n storage_failed?: string[];\n message?: string;\n}\n\n/** One SaaS catalog tenant row from searchTenantsByDomain. */\nexport interface TenantCatalogSearchRow {\n id: string;\n name: string;\n status?: string;\n domain?: string;\n data?: string;\n}\n\nexport interface TenantByDomainResponse {\n tenant: TenantCatalogSearchRow | null;\n}\n\nexport interface ClientConfig {\n baseURL: string;\n /** REST base (e.g. http://host:5050/system); derived from baseURL when omitted */\n restBaseURL?: string;\n apiKey: string;\n timeout?: number;\n httpClient?: any;\n tenantId?: string;\n}\n\nexport interface RequestOptions {\n headers?: Record<string, string>;\n timeout?: number;\n}\n\nexport interface SearchOptions {\n limit?: number;\n page?: number;\n offset?: number;\n where?: Record<string, any>;\n search?: string;\n sort?: Record<string, 1 | -1>;\n}\n\nexport interface ConnectionOptions {\n model: string;\n filter?: SearchOptions;\n}\n\n// Plugin interface matching the Go SDK\nexport interface InjectedDBOperationInterface {\n executeGraphQL(\n query: string,\n variables?: Record<string, any>,\n options?: { tenantId?: string }\n ): Promise<GraphQLResponse>;\n /** @param token Legacy; ignored. Auth uses client API key. */\n generateTenantToken(tenantId: string, duration?: string, role?: string): Promise<string>;\n loginUser(params: LoginUserParams): Promise<LoginUserResponse>;\n googleOAuthState(projectId: string): Promise<GoogleOAuthStateResponse>;\n searchUsers(projectId: string, limit?: number, offset?: number): Promise<UsersResponse>;\n searchTenantsByDomain(projectId: string, domain: string): Promise<TenantByDomainResponse>;\n createUser(projectId: string, params: CreateUserParams): Promise<User>;\n updateUser(userId: string, params: UpdateUserParams): Promise<User>;\n resetUserPassword(userId: string, password: string): Promise<boolean>;\n deleteUser(userId: string): Promise<boolean>;\n getProjectStorageSettings(projectId: string): Promise<ProjectStorageSettings>;\n updateProjectStorageSettings(input: UpdateProjectStorageInput): Promise<ProjectStorageSettings>;\n uploadSystemFile(params: SystemFileUploadParams): Promise<SystemFile>;\n listSystemFiles(fileType?: string, limit?: number, offset?: number): Promise<SystemFilesListResponse>;\n deleteSystemFiles(ids: string[]): Promise<DeleteSystemFilesResponse>;\n getSingleResource(model: string, id: string, singlePageData?: boolean): Promise<DefaultDocumentStructure>;\n searchResources(model: string, filter?: Record<string, any>, aggregate?: boolean): Promise<SearchResult>;\n getRelationDocuments(id: string, connection: Record<string, any>): Promise<SearchResult>;\n createNewResource(request: CreateAndUpdateRequest): Promise<DefaultDocumentStructure>;\n updateResource(request: CreateAndUpdateRequest): Promise<DefaultDocumentStructure>;\n deleteResource(model: string, id: string): Promise<void>;\n debug(stage: string, ...data: any[]): Promise<any>;\n}\n\n// Typed operations interface\nexport interface TypedOperations {\n getSingleResourceTyped<T>(model: string, id: string, singlePageData?: boolean): Promise<TypedDocumentStructure<T>>;\n searchResourcesTyped<T>(model: string, filter?: Record<string, any>, aggregate?: boolean): Promise<TypedSearchResult<T>>;\n getRelationDocumentsTyped<T>(id: string, connection: Record<string, any>): Promise<TypedSearchResult<T>>;\n createNewResourceTyped<T>(request: CreateAndUpdateRequest): Promise<TypedDocumentStructure<T>>;\n updateResourceTyped<T>(request: CreateAndUpdateRequest): Promise<TypedDocumentStructure<T>>;\n}\n\n// Error classes\nexport class ApitoError extends Error {\n constructor(\n message: string,\n public code?: string,\n public statusCode?: number,\n public details?: any\n ) {\n super(message);\n this.name = 'ApitoError';\n }\n}\n\nexport class GraphQLError extends ApitoError {\n constructor(\n message: string,\n public graphQLErrors: GraphQLError[],\n public response?: any\n ) {\n super(message, 'GRAPHQL_ERROR');\n this.name = 'GraphQLError';\n }\n\n get partialData(): any {\n return this.response?.data;\n }\n}\n\nexport class ValidationError extends ApitoError {\n constructor(message: string, public field?: string) {\n super(message, 'VALIDATION_ERROR');\n this.name = 'ValidationError';\n }\n}\n","import {\n DefaultDocumentStructure,\n TypedDocumentStructure,\n TypedSearchResult,\n CreateAndUpdateRequest,\n} from './types';\nimport { ApitoClient } from './client';\n\n/**\n * Typed operations wrapper for the Apito SDK\n * Provides type-safe methods for working with typed data\n */\nexport class TypedOperations {\n constructor(private client: ApitoClient) {}\n\n private static toTypedDocument<T>(raw: DefaultDocumentStructure): TypedDocumentStructure<T> {\n const data = JSON.parse(JSON.stringify(raw.data)) as T;\n return {\n _key: raw._key,\n _id: raw._id,\n data,\n meta: raw.meta,\n id: raw.id,\n expire_at: raw.expire_at,\n relation_doc_id: raw.relation_doc_id,\n last_revision_doc_id: raw.last_revision_doc_id,\n type: raw.type,\n tenant_id: raw.tenant_id,\n tenant_model: raw.tenant_model,\n };\n }\n\n /**\n * Get a single resource with type safety\n */\n async getSingleResourceTyped<T>(\n model: string,\n id: string,\n singlePageData: boolean = false\n ): Promise<TypedDocumentStructure<T>> {\n const result = await this.client.getSingleResource(model, id, singlePageData);\n return TypedOperations.toTypedDocument<T>(result);\n }\n\n /**\n * Search resources with type safety\n */\n async searchResourcesTyped<T>(\n model: string,\n filter: Record<string, any> = {},\n aggregate: boolean = false\n ): Promise<TypedSearchResult<T>> {\n const result = await this.client.searchResources(model, filter, aggregate);\n return {\n results: result.results.map((doc) => TypedOperations.toTypedDocument<T>(doc)),\n count: result.count,\n };\n }\n\n /**\n * Get related documents with type safety\n */\n async getRelationDocumentsTyped<T>(\n id: string,\n connection: Record<string, any>\n ): Promise<TypedSearchResult<T>> {\n const result = await this.client.getRelationDocuments(id, connection);\n return {\n results: result.results.map((doc) => TypedOperations.toTypedDocument<T>(doc)),\n count: result.count,\n };\n }\n\n /**\n * Create a new resource with type safety\n */\n async createNewResourceTyped<T>(\n request: CreateAndUpdateRequest\n ): Promise<TypedDocumentStructure<T>> {\n const result = await this.client.createNewResource(request);\n return TypedOperations.toTypedDocument<T>(result);\n }\n\n /**\n * Update a resource with type safety\n */\n async updateResourceTyped<T>(\n request: CreateAndUpdateRequest\n ): Promise<TypedDocumentStructure<T>> {\n const result = await this.client.updateResource(request);\n return TypedOperations.toTypedDocument<T>(result);\n }\n}\n","/**\n * Apito JavaScript internal SDK version (kept in sync with package.json for releases)\n */\nexport const Version = '3.0.0';\n\n/**\n * GetVersion returns the current version of the SDK\n */\nexport function getVersion(): string {\n return Version;\n}\n"],"mappings":"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","names":["axios","ApitoError","message","code","statusCode","details","GraphQLError","graphQLErrors","response","ValidationError","field","deriveRestBaseURL","graphqlURL","u","ApitoClient","config","axios","query","variables","options","payload","headers","response","GraphQLError","error","ApitoError","tenantId","duration","role","dur","d","data","ValidationError","tid","method","path","url","k","v","body","msg","params","authMethod","code","state","password","email","phone","raw","projectId","limit","offset","count","domain","userId","uid","ok","settings","input","size","fileName","form","bytes","blob","fileType","ids","result","model","id","singlePageData","filter","aggregate","connection","request","stage","createClient","TypedOperations","_TypedOperations","client","raw","data","model","id","singlePageData","result","filter","aggregate","doc","connection","request","Version","getVersion"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/types.ts","../src/typed-operations.ts","../src/version.ts"],"sourcesContent":["import axios, { AxiosInstance } from 'axios';\nimport {\n ClientConfig,\n DefaultDocumentStructure,\n SearchResult,\n TypedDocumentStructure,\n TypedSearchResult,\n CreateAndUpdateRequest,\n GraphQLResponse,\n GraphQLError as SDKGraphQLError,\n ApitoError,\n ValidationError,\n InjectedDBOperationInterface,\n LoginUserResponse,\n User,\n UsersResponse,\n TenantByDomainResponse,\n TenantCatalogSearchRow,\n LoginUserParams,\n CreateUserParams,\n UpdateUserParams,\n GoogleOAuthStateResponse,\n File,\n FilesListResponse,\n UploadFileParams,\n DeleteFilesResponse,\n} from './types';\n\nfunction deriveRestBaseURL(graphqlURL: string): string {\n const u = graphqlURL.trim().replace(/\\/$/, '');\n if (u.endsWith('/graphql')) {\n return u.slice(0, -'/graphql'.length);\n }\n return u;\n}\n\n/**\n * Apito SDK Client - JavaScript implementation matching the Go SDK\n */\nexport class ApitoClient implements InjectedDBOperationInterface {\n private httpClient: AxiosInstance;\n private baseURL: string;\n private restBaseURL: string;\n private apiKey: string;\n private tenantId?: string;\n\n constructor(config: ClientConfig) {\n this.baseURL = config.baseURL;\n this.restBaseURL = (config.restBaseURL ?? '').trim() || deriveRestBaseURL(config.baseURL);\n this.apiKey = config.apiKey;\n this.tenantId = config.tenantId;\n\n // Create axios instance with default configuration\n this.httpClient = axios.create({\n timeout: config.timeout || 30000,\n headers: {\n 'Content-Type': 'application/json',\n ...(this.apiKey.startsWith('cli-') || this.apiKey.startsWith('sdk-')\n ? { 'X-Apito-Sync-Key': this.apiKey }\n : { 'X-Apito-Key': this.apiKey }),\n },\n ...config.httpClient,\n });\n\n // Add tenant ID to headers if provided\n if (this.tenantId) {\n this.httpClient.defaults.headers['X-Apito-Tenant-ID'] = this.tenantId;\n }\n }\n\n /**\n * Execute an arbitrary GraphQL query or mutation against the Apito admin (system) endpoint.\n * Use for plugin-registered operations (e.g. processLedger, plg_closeOrder) when not wrapped by dedicated SDK methods.\n */\n async executeGraphQL(\n query: string,\n variables?: Record<string, any>,\n options?: { tenantId?: string }\n ): Promise<GraphQLResponse> {\n try {\n const payload = {\n query,\n variables: variables || {},\n };\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(this.apiKey.startsWith('cli-') || this.apiKey.startsWith('sdk-')\n ? { 'X-Apito-Sync-Key': this.apiKey }\n : { 'X-Apito-Key': this.apiKey }),\n };\n\n if (options?.tenantId || this.tenantId) {\n headers['X-Apito-Tenant-ID'] = options?.tenantId || this.tenantId!;\n }\n\n const response = await this.httpClient.post<GraphQLResponse>(\n this.baseURL,\n payload,\n { headers }\n );\n\n if (response.data.errors && response.data.errors.length > 0) {\n throw new SDKGraphQLError(\n 'GraphQL query failed',\n response.data.errors,\n response.data\n );\n }\n\n return response.data;\n } catch (error) {\n if (axios.isAxiosError(error)) {\n throw new ApitoError(\n error.response?.data?.message || error.message,\n 'HTTP_ERROR',\n error.response?.status,\n error.response?.data\n );\n }\n throw error;\n }\n }\n\n /**\n * Generate a tenant-scoped API key. Matches engine `generateTenantToken`: `tenant_id`, `duration`, optional `role`.\n * Auth uses `X-Apito-Key` (client `apiKey`).\n *\n * @param tenantId Catalog tenant id (`tenant_id` in the mutation).\n * @param duration Expiry calendar day `YYYY-MM-DD`. If omitted/empty, defaults to one year ahead in UTC.\n * @param role Optional token role; if omitted/empty, the engine defaults to `admin`.\n */\n async generateTenantToken(tenantId: string, duration?: string, role?: string): Promise<string> {\n let dur = (duration ?? '').trim();\n if (!dur) {\n const d = new Date();\n dur = `${d.getUTCFullYear() + 1}-${String(d.getUTCMonth() + 1).padStart(2, '0')}-${String(\n d.getUTCDate()\n ).padStart(2, '0')}`;\n }\n\n const query = `\n mutation GenerateTenantToken($tenantId: String!, $duration: String!, $role: String) {\n generateTenantToken(tenant_id: $tenantId, duration: $duration, role: $role) {\n token\n }\n }\n `;\n\n const variables: Record<string, any> = {\n tenantId,\n duration: dur,\n role: role !== undefined && role.trim() !== '' ? role.trim() : null,\n };\n const response = await this.executeGraphQL(query, variables, { tenantId });\n\n const data = response.data?.generateTenantToken;\n if (!data?.token) {\n throw new ValidationError('Invalid response format for tenant token');\n }\n\n return data.token;\n }\n\n private authHeaders(tenantId?: string): Record<string, string> {\n const headers: Record<string, string> = {\n ...(this.apiKey.startsWith('cli-') || this.apiKey.startsWith('sdk-')\n ? { 'X-Apito-Sync-Key': this.apiKey }\n : { 'X-Apito-Key': this.apiKey }),\n };\n const tid = tenantId ?? this.tenantId;\n if (tid) {\n headers['X-Apito-Tenant-ID'] = tid;\n }\n return headers;\n }\n\n private async executeREST<T>(\n method: 'GET' | 'POST',\n path: string,\n options?: {\n query?: Record<string, string | number | undefined>;\n jsonBody?: Record<string, unknown>;\n formData?: FormData;\n allowFailure?: boolean;\n }\n ): Promise<T> {\n const url = new URL(`${this.restBaseURL.replace(/\\/$/, '')}${path}`);\n if (options?.query) {\n for (const [k, v] of Object.entries(options.query)) {\n if (v !== undefined && v !== '') {\n url.searchParams.set(k, String(v));\n }\n }\n }\n const headers = this.authHeaders();\n let data: FormData | Record<string, unknown> | undefined;\n if (options?.formData) {\n data = options.formData;\n } else if (options?.jsonBody) {\n headers['Content-Type'] = 'application/json';\n data = options.jsonBody;\n }\n try {\n const response = await this.httpClient.request({\n method,\n url: url.toString(),\n headers,\n data,\n maxBodyLength: Infinity,\n maxContentLength: Infinity,\n });\n const body = response.data as Record<string, unknown>;\n if (body.success === false && !options?.allowFailure) {\n throw new ValidationError(String(body.message ?? 'request failed'));\n }\n return body as T;\n } catch (error) {\n if (axios.isAxiosError(error)) {\n const msg =\n (error.response?.data as { message?: string })?.message ?? error.message;\n throw new ApitoError(msg, 'HTTP_ERROR', error.response?.status, error.response?.data);\n }\n throw error;\n }\n }\n\n /**\n * Project user login (system GraphQL `loginUser`). Password path: pass `password` and `email` or `phone` per project Authentication settings. Google OAuth path: `authMethod: 'google'` with `code` and `state` from the redirect; call `googleOAuthState(projectId)` before opening Google to obtain `state`.\n */\n async loginUser(params: LoginUserParams): Promise<LoginUserResponse> {\n const authMethod = (params.authMethod ?? 'general').trim().toLowerCase() || 'general';\n const variables: Record<string, any> = {\n project_id: params.projectId,\n };\n\n if (authMethod === 'google') {\n variables.auth_method = 'google';\n const code = (params.code ?? '').trim();\n const state = (params.state ?? '').trim();\n if (!code || !state) {\n throw new ValidationError('code and state are required for Google login');\n }\n variables.code = code;\n variables.state = state;\n } else {\n const password = (params.password ?? '').trim();\n if (!password) {\n throw new ValidationError('password is required');\n }\n variables.password = password;\n const email = (params.email ?? '').trim();\n const phone = (params.phone ?? '').trim();\n if (!email && !phone) {\n throw new ValidationError('email or phone is required');\n }\n if (email) variables.email = email;\n if (phone) variables.phone = phone;\n }\n\n const query = `\n query LoginUser($project_id: String!, $password: String, $auth_method: String, $email: String, $phone: String, $code: String, $state: String) {\n loginUser(project_id: $project_id, password: $password, auth_method: $auth_method, email: $email, phone: $phone, code: $code, state: $state) {\n token\n user {\n id\n email\n phone\n role\n provider\n tenant_id\n status\n created_at\n updated_at\n }\n }\n }\n `;\n const response = await this.executeGraphQL(query, variables);\n const raw = response.data?.loginUser;\n if (!raw?.token) {\n throw new ValidationError('Invalid response format for loginUser');\n }\n return {\n token: raw.token as string,\n user: raw.user as User | undefined,\n };\n }\n\n /**\n * Signed OAuth state for Google login (system query `googleOAuthState`). Use in the authorize URL together with project `google_client_id` and the configured redirect URI.\n */\n async googleOAuthState(projectId: string): Promise<GoogleOAuthStateResponse> {\n const query = `\n query GoogleOAuthState($project_id: String!) {\n googleOAuthState(project_id: $project_id) {\n state\n }\n }\n `;\n const variables = { project_id: projectId };\n const response = await this.executeGraphQL(query, variables);\n const raw = response.data?.googleOAuthState;\n const state = typeof raw?.state === 'string' ? raw.state.trim() : '';\n if (!state) {\n throw new ValidationError('Invalid response format for googleOAuthState');\n }\n return { state };\n }\n\n /**\n * Search project end-users.\n */\n async searchUsers(\n projectId: string,\n limit?: number,\n offset?: number\n ): Promise<UsersResponse> {\n const query = `\n query SearchUsers($project_id: String!, $limit: Int, $offset: Int) {\n searchUsers(project_id: $project_id, limit: $limit, offset: $offset) {\n count\n users {\n id\n email\n phone\n role\n provider\n tenant_id\n status\n created_at\n updated_at\n }\n }\n }\n `;\n const variables: Record<string, any> = { project_id: projectId };\n if (limit !== undefined) variables.limit = limit;\n if (offset !== undefined) variables.offset = offset;\n const response = await this.executeGraphQL(query, variables);\n const raw = response.data?.searchUsers;\n if (!raw) {\n throw new ValidationError('Invalid response format for searchUsers');\n }\n let count = 0;\n if (typeof raw.count === 'number') {\n count = raw.count;\n }\n const users = (raw.users ?? []) as User[];\n return { users, count };\n }\n\n /**\n * Resolve the single SaaS catalog tenant for an exact domain match in the project (`tenant` null if none).\n */\n async searchTenantsByDomain(projectId: string, domain: string): Promise<TenantByDomainResponse> {\n const query = `\n query SearchTenantsByDomain($project_id: String!, $domain: String!) {\n searchTenantsByDomain(project_id: $project_id, domain: $domain) {\n tenant {\n id\n name\n status\n domain\n data\n }\n }\n }\n `;\n const variables: Record<string, any> = {\n project_id: projectId,\n domain,\n };\n const response = await this.executeGraphQL(query, variables);\n const raw = response.data?.searchTenantsByDomain;\n if (!raw) {\n throw new ValidationError('Invalid response format for searchTenantsByDomain');\n }\n const tenant = (raw.tenant ?? null) as TenantCatalogSearchRow | null;\n return { tenant };\n }\n\n /**\n * Create a project user (local password). Use `email` and/or `phone` per engine validation for the project identifier mode.\n */\n async createUser(projectId: string, params: CreateUserParams): Promise<User> {\n const password = (params.password ?? '').trim();\n if (!password) {\n throw new ValidationError('password is required');\n }\n const query = `\n mutation CreateUser($project_id: String!, $password: String!, $role: String, $email: String, $phone: String) {\n createUser(project_id: $project_id, password: $password, role: $role, email: $email, phone: $phone) {\n id\n email\n phone\n role\n provider\n tenant_id\n status\n created_at\n updated_at\n }\n }\n `;\n const variables: Record<string, any> = {\n project_id: projectId,\n password,\n };\n const role = (params.role ?? '').trim();\n if (role) variables.role = role;\n const email = (params.email ?? '').trim();\n if (email) variables.email = email;\n const phone = (params.phone ?? '').trim();\n if (phone) variables.phone = phone;\n const response = await this.executeGraphQL(query, variables);\n const u = response.data?.createUser;\n if (!u?.id) {\n throw new ValidationError('Invalid response format for createUser');\n }\n return u as User;\n }\n\n /**\n * Update a project user. Project scope is implied by the API key. Only include fields to change.\n */\n async updateUser(userId: string, params: UpdateUserParams): Promise<User> {\n const uid = (userId ?? '').trim();\n if (!uid) {\n throw new ValidationError('userId is required');\n }\n if (params.email === undefined && params.phone === undefined && params.role === undefined) {\n throw new ValidationError('at least one field must be provided');\n }\n const query = `\n mutation UpdateUser($user_id: String!, $email: String, $phone: String, $role: String) {\n updateUser(user_id: $user_id, email: $email, phone: $phone, role: $role) {\n id\n email\n phone\n role\n provider\n tenant_id\n status\n created_at\n updated_at\n }\n }\n `;\n const variables: Record<string, any> = { user_id: uid };\n if (params.email !== undefined) variables.email = params.email;\n if (params.phone !== undefined) variables.phone = params.phone;\n if (params.role !== undefined) variables.role = params.role;\n const response = await this.executeGraphQL(query, variables);\n const u = response.data?.updateUser;\n if (!u?.id) {\n throw new ValidationError('Invalid response format for updateUser');\n }\n return u as User;\n }\n\n /** Set a new password for a project user (admin mutation resetUserPassword). */\n async resetUserPassword(userId: string, password: string): Promise<boolean> {\n const uid = (userId ?? '').trim();\n if (!uid) {\n throw new ValidationError('userId is required');\n }\n if (!(password ?? '').trim()) {\n throw new ValidationError('password is required');\n }\n const query = `\n mutation ResetUserPassword($user_id: String!, $password: String!) {\n resetUserPassword(user_id: $user_id, password: $password)\n }\n `;\n const response = await this.executeGraphQL(query, { user_id: uid, password });\n const ok = response.data?.resetUserPassword;\n if (typeof ok !== 'boolean') {\n throw new ValidationError('Invalid response format for resetUserPassword');\n }\n return ok;\n }\n\n /**\n * Delete a project user by id. Project scope is implied by the API key.\n */\n async deleteUser(userId: string): Promise<boolean> {\n const uid = (userId ?? '').trim();\n if (!uid) {\n throw new ValidationError('userId is required');\n }\n const query = `\n mutation DeleteUser($user_id: String!) {\n deleteUser(user_id: $user_id)\n }\n `;\n const response = await this.executeGraphQL(query, { user_id: uid });\n const ok = response.data?.deleteUser;\n if (typeof ok !== 'boolean') {\n throw new ValidationError('Invalid response format for deleteUser');\n }\n return ok;\n }\n\n /** Upload a file via POST /system/files/upload. */\n async uploadFile(params: UploadFileParams): Promise<File> {\n const size =\n params.content instanceof ArrayBuffer\n ? params.content.byteLength\n : params.content.byteLength;\n if (!params.content || size === 0) {\n throw new ValidationError('file content is required');\n }\n const fileName = (params.fileName ?? '').trim() || 'upload';\n const form = new FormData();\n const bytes =\n params.content instanceof ArrayBuffer ? new Uint8Array(params.content) : params.content;\n const blob = new Blob([bytes as BlobPart]);\n form.append('file', blob, fileName);\n if (params.fileType?.trim()) {\n form.append('file_type', params.fileType.trim());\n }\n const body = await this.executeREST<{ file: File }>('POST', '/files/upload', {\n formData: form,\n });\n if (!body.file?.id) {\n throw new ValidationError('Invalid response format for uploadFile');\n }\n return body.file;\n }\n\n /** List files via GET /system/files/list. */\n async listFiles(\n fileType?: string,\n limit?: number,\n offset?: number\n ): Promise<FilesListResponse> {\n const body = await this.executeREST<{\n files: File[];\n total: number;\n }>('GET', '/files/list', {\n query: {\n file_type: fileType,\n limit,\n offset,\n },\n });\n return {\n files: body.files ?? [],\n total: body.total ?? 0,\n };\n }\n\n /** Delete files via POST /system/files/delete. */\n async deleteFiles(ids: string[]): Promise<DeleteFilesResponse> {\n if (!ids?.length) {\n throw new ValidationError('ids are required');\n }\n const body = await this.executeREST<DeleteFilesResponse>('POST', '/files/delete', {\n jsonBody: { ids },\n allowFailure: true,\n });\n const result: DeleteFilesResponse = {\n success: !!body.success,\n deleted_ids: body.deleted_ids ?? [],\n storage_failed: body.storage_failed,\n message: body.message,\n };\n if (!result.success && result.message) {\n throw new ValidationError(result.message);\n }\n return result;\n }\n\n /**\n * Get a single resource by model and ID\n */\n async getSingleResource(\n model: string,\n id: string,\n singlePageData: boolean = false\n ): Promise<DefaultDocumentStructure> {\n const query = `\n query GetSingleData($model: String, $_id: String!, $single_page_data: Boolean) {\n getSingleData(model: $model, _id: $_id, single_page_data: $single_page_data) {\n _key\n data\n meta {\n created_at\n updated_at\n status\n revision\n revision_at\n }\n id\n expire_at\n relation_doc_id\n type\n }\n }\n `;\n\n const variables = {\n model,\n _id: id,\n single_page_data: singlePageData,\n };\n\n const response = await this.executeGraphQL(query, variables);\n\n if (!response.data?.getSingleData) {\n throw new ValidationError('Resource not found');\n }\n\n return response.data.getSingleData;\n }\n\n /**\n * Search resources in a model\n */\n async searchResources(\n model: string,\n filter: Record<string, any> = {},\n aggregate: boolean = false\n ): Promise<SearchResult> {\n const query = `\n query GetModelData(\n $model: String!\n $page: Int\n $limit: Int\n $_key: JSON\n $where: JSON\n $search: String\n ) {\n getModelData(\n model: $model\n page: $page\n limit: $limit\n _key: $_key\n where: $where\n search: $search\n ) {\n results {\n id\n relation_doc_id\n data\n type\n expire_at\n meta {\n created_at\n updated_at\n status\n root_revision_id\n }\n }\n count\n }\n }\n `;\n\n // Only forward keys declared on the GraphQL operation (matches go-internal-sdk)\n const variables: Record<string, any> = { model };\n if (filter && typeof filter === 'object') {\n if (filter._key !== undefined) {\n variables._key = filter._key;\n }\n if (filter.page !== undefined) {\n variables.page = filter.page;\n }\n if (filter.limit !== undefined) {\n variables.limit = filter.limit;\n }\n if (filter.where !== undefined) {\n variables.where = filter.where;\n }\n if (filter.search !== undefined) {\n variables.search = filter.search;\n }\n }\n\n const response = await this.executeGraphQL(query, variables);\n\n if (!response.data?.getModelData) {\n throw new ValidationError('Invalid search response format');\n }\n\n return response.data.getModelData;\n }\n\n /**\n * Get related documents\n */\n async getRelationDocuments(\n id: string,\n connection: Record<string, any>\n ): Promise<SearchResult> {\n const query = `\n query GetModelData($model: String!, $page: Int, $limit: Int, $where: JSON, $search: String, $connection : ListAllDataDetailedOfAModelConnectionPayload) {\n getModelData(model: $model, page: $page, limit: $limit, where: $where, search: $search, connection: $connection) {\n results {\n id\n relation_doc_id\n data\n type\n expire_at\n meta {\n created_at\n updated_at\n status\n root_revision_id\n }\n }\n count\n }\n }\n `;\n\n const variables: Record<string, any> = {\n connection,\n };\n\n // Extract model from connection if available\n if (connection.model) {\n variables.model = connection.model;\n } else {\n throw new ValidationError('model is required in connection parameters');\n }\n\n // Add filter parameters if provided in connection\n if (connection.filter) {\n const filter = connection.filter;\n if (filter.page !== undefined) {\n variables.page = filter.page;\n }\n if (filter.limit !== undefined) {\n variables.limit = filter.limit;\n }\n if (filter.where !== undefined) {\n variables.where = filter.where;\n }\n if (filter.search !== undefined) {\n variables.search = filter.search;\n }\n }\n\n const response = await this.executeGraphQL(query, variables);\n\n if (!response.data?.getModelData) {\n throw new ValidationError('Invalid relation documents response format');\n }\n\n return response.data.getModelData;\n }\n\n /**\n * Create a new resource\n */\n async createNewResource(request: CreateAndUpdateRequest): Promise<DefaultDocumentStructure> {\n if (!request.model) {\n throw new ValidationError('model is required');\n }\n\n if (!request.payload) {\n throw new ValidationError('payload is required');\n }\n\n const query = `\n mutation CreateNewData($model: String!, $single_page_data: Boolean, $payload: JSON!, $connect: JSON) {\n upsertModelData(\n connect: $connect\n model_name: $model\n single_page_data: $single_page_data\n payload: $payload\n ) {\n id\n type\n data\n meta {\n created_at\n updated_at\n status\n revision\n revision_at\n }\n }\n }\n `;\n\n const variables: Record<string, any> = {\n model: request.model,\n payload: request.payload,\n single_page_data: request.singlePageData || false,\n };\n\n if (request.connect) {\n variables.connect = request.connect;\n }\n\n const response = await this.executeGraphQL(query, variables);\n\n if (!response.data?.upsertModelData) {\n throw new ValidationError('Invalid create response format');\n }\n\n return response.data.upsertModelData;\n }\n\n /**\n * Update an existing resource\n */\n async updateResource(request: CreateAndUpdateRequest): Promise<DefaultDocumentStructure> {\n if (!request.id) {\n throw new ValidationError('id is required');\n }\n\n if (!request.model) {\n throw new ValidationError('model is required');\n }\n\n if (!request.payload) {\n throw new ValidationError('payload is required');\n }\n\n const query = `\n mutation UpdateModelData($_id: String!, $model: String!, $single_page_data: Boolean, $force_update: Boolean, $payload: JSON!, $connect: JSON, $disconnect: JSON) {\n upsertModelData(\n connect: $connect\n model_name: $model\n single_page_data: $single_page_data\n force_update: $force_update\n disconnect: $disconnect\n _id: $_id\n payload: $payload\n ) {\n id\n type\n data\n meta {\n created_at\n updated_at\n status\n revision\n revision_at\n }\n }\n }\n `;\n\n const variables: Record<string, any> = {\n _id: request.id,\n model: request.model,\n payload: request.payload,\n single_page_data: request.singlePageData || false,\n force_update: request.forceUpdate || false,\n };\n\n if (request.connect) {\n variables.connect = request.connect;\n }\n if (request.disconnect) {\n variables.disconnect = request.disconnect;\n }\n\n const response = await this.executeGraphQL(query, variables);\n\n if (!response.data?.upsertModelData) {\n throw new ValidationError('Invalid update response format');\n }\n\n return response.data.upsertModelData;\n }\n\n /**\n * Delete a resource by model and ID\n */\n async deleteResource(model: string, id: string): Promise<void> {\n const query = `\n mutation DeleteData($model: String!, $_id: String!) {\n deleteModelData(model_name: $model, _id: $_id) {\n id\n }\n }\n `;\n\n const variables = {\n model,\n _id: id,\n };\n\n await this.executeGraphQL(query, variables);\n }\n\n /**\n * Debug is used to debug the plugin, you can pass data here to debug the plugin\n */\n async debug(stage: string, ...data: any[]): Promise<any> {\n const query = `\n mutation Debug($stage: String!, $data: JSON) {\n debug(stage: $stage, data: $data) {\n message\n data\n }\n }\n `;\n\n const variables = {\n stage,\n data,\n };\n\n const response = await this.executeGraphQL(query, variables);\n\n return response.data?.debug;\n }\n}\n\n/**\n * Factory function to create a new Apito client\n */\nexport function createClient(config: ClientConfig): ApitoClient {\n return new ApitoClient(config);\n}\n","/**\n * Type definitions for the Apito JavaScript SDK\n */\n\nexport interface MetaField {\n created_at: string;\n updated_at: string;\n status: string;\n revision?: string;\n revision_at?: string;\n root_revision_id?: string;\n}\n\nexport interface DefaultDocumentStructure {\n _key?: string;\n _id?: string;\n data: any;\n meta?: MetaField;\n id: string;\n expire_at?: string | number;\n relation_doc_id?: string;\n last_revision_doc_id?: string;\n type?: string;\n tenant_id?: string;\n tenant_model?: string;\n}\n\nexport interface SearchResult {\n results: DefaultDocumentStructure[];\n count: number;\n}\n\nexport interface TypedDocumentStructure<T> {\n _key?: string;\n _id?: string;\n data: T;\n meta?: MetaField;\n id: string;\n expire_at?: string | number;\n relation_doc_id?: string;\n last_revision_doc_id?: string;\n type?: string;\n tenant_id?: string;\n tenant_model?: string;\n}\n\nexport interface TypedSearchResult<T> {\n results: TypedDocumentStructure<T>[];\n count: number;\n}\n\nexport interface Filter {\n page?: number;\n offset?: number;\n limit?: number;\n order?: string;\n min?: number;\n max?: number;\n category?: string;\n}\n\nexport interface GraphQLErrorLocation {\n line: number;\n column: number;\n}\n\nexport interface GraphQLError {\n message: string;\n locations?: GraphQLErrorLocation[];\n path?: (string | number)[];\n extensions?: Record<string, any>;\n}\n\nexport interface GraphQLResponse {\n data?: any;\n errors?: GraphQLError[];\n}\n\nexport interface CreateAndUpdateRequest {\n id?: string;\n model: string;\n payload: any;\n connect?: Record<string, any>;\n disconnect?: Record<string, any>;\n singlePageData?: boolean;\n forceUpdate?: boolean;\n}\n\n/** Project end-user from engine system DB (table project_users). */\nexport interface User {\n id: string;\n email?: string;\n phone?: string;\n role: string;\n tenant_id?: string;\n provider?: string;\n status?: string;\n created_at?: string;\n updated_at?: string;\n}\n\n/** Login via system GraphQL `loginUser`. Password path: use `email` or `phone` per project settings. Google OAuth code path: `authMethod: 'google'`, `code`, `state` from redirect (get `state` first via `googleOAuthState`). */\nexport interface LoginUserParams {\n projectId: string;\n password?: string;\n email?: string;\n phone?: string;\n authMethod?: string;\n code?: string;\n state?: string;\n}\n\nexport interface GoogleOAuthStateResponse {\n state: string;\n}\n\nexport interface CreateUserParams {\n password: string;\n role?: string;\n email?: string;\n phone?: string;\n}\n\n/** Optional fields for `updateUser`; omitted keys are not sent. */\nexport interface UpdateUserParams {\n email?: string;\n phone?: string;\n role?: string;\n}\n\nexport interface LoginUserResponse {\n token: string;\n user?: User;\n}\n\nexport interface UsersResponse {\n users: User[];\n count: number;\n}\n\nexport interface File {\n id: string;\n file_type: string;\n file_name: string;\n file_extension?: string;\n content_type?: string;\n size: number;\n url: string;\n created_by?: string;\n created_at?: string;\n}\n\nexport interface FilesListResponse {\n files: File[];\n total: number;\n}\n\nexport interface UploadFileParams {\n fileName: string;\n content: Uint8Array | ArrayBuffer;\n fileType?: string;\n}\n\nexport interface DeleteFilesResponse {\n success: boolean;\n deleted_ids: string[];\n storage_failed?: string[];\n message?: string;\n}\n\n/** One SaaS catalog tenant row from searchTenantsByDomain. */\nexport interface TenantCatalogSearchRow {\n id: string;\n name: string;\n status?: string;\n domain?: string;\n data?: string;\n}\n\nexport interface TenantByDomainResponse {\n tenant: TenantCatalogSearchRow | null;\n}\n\nexport interface ClientConfig {\n baseURL: string;\n /** REST base (e.g. http://host:5050/system); derived from baseURL when omitted */\n restBaseURL?: string;\n apiKey: string;\n timeout?: number;\n httpClient?: any;\n tenantId?: string;\n}\n\nexport interface RequestOptions {\n headers?: Record<string, string>;\n timeout?: number;\n}\n\nexport interface SearchOptions {\n limit?: number;\n page?: number;\n offset?: number;\n where?: Record<string, any>;\n search?: string;\n sort?: Record<string, 1 | -1>;\n}\n\nexport interface ConnectionOptions {\n model: string;\n filter?: SearchOptions;\n}\n\n// Plugin interface matching the Go SDK\nexport interface InjectedDBOperationInterface {\n executeGraphQL(\n query: string,\n variables?: Record<string, any>,\n options?: { tenantId?: string }\n ): Promise<GraphQLResponse>;\n /** @param token Legacy; ignored. Auth uses client API key. */\n generateTenantToken(tenantId: string, duration?: string, role?: string): Promise<string>;\n loginUser(params: LoginUserParams): Promise<LoginUserResponse>;\n googleOAuthState(projectId: string): Promise<GoogleOAuthStateResponse>;\n searchUsers(projectId: string, limit?: number, offset?: number): Promise<UsersResponse>;\n searchTenantsByDomain(projectId: string, domain: string): Promise<TenantByDomainResponse>;\n createUser(projectId: string, params: CreateUserParams): Promise<User>;\n updateUser(userId: string, params: UpdateUserParams): Promise<User>;\n resetUserPassword(userId: string, password: string): Promise<boolean>;\n deleteUser(userId: string): Promise<boolean>;\n uploadFile(params: UploadFileParams): Promise<File>;\n listFiles(fileType?: string, limit?: number, offset?: number): Promise<FilesListResponse>;\n deleteFiles(ids: string[]): Promise<DeleteFilesResponse>;\n getSingleResource(model: string, id: string, singlePageData?: boolean): Promise<DefaultDocumentStructure>;\n searchResources(model: string, filter?: Record<string, any>, aggregate?: boolean): Promise<SearchResult>;\n getRelationDocuments(id: string, connection: Record<string, any>): Promise<SearchResult>;\n createNewResource(request: CreateAndUpdateRequest): Promise<DefaultDocumentStructure>;\n updateResource(request: CreateAndUpdateRequest): Promise<DefaultDocumentStructure>;\n deleteResource(model: string, id: string): Promise<void>;\n debug(stage: string, ...data: any[]): Promise<any>;\n}\n\n// Typed operations interface\nexport interface TypedOperations {\n getSingleResourceTyped<T>(model: string, id: string, singlePageData?: boolean): Promise<TypedDocumentStructure<T>>;\n searchResourcesTyped<T>(model: string, filter?: Record<string, any>, aggregate?: boolean): Promise<TypedSearchResult<T>>;\n getRelationDocumentsTyped<T>(id: string, connection: Record<string, any>): Promise<TypedSearchResult<T>>;\n createNewResourceTyped<T>(request: CreateAndUpdateRequest): Promise<TypedDocumentStructure<T>>;\n updateResourceTyped<T>(request: CreateAndUpdateRequest): Promise<TypedDocumentStructure<T>>;\n}\n\n// Error classes\nexport class ApitoError extends Error {\n constructor(\n message: string,\n public code?: string,\n public statusCode?: number,\n public details?: any\n ) {\n super(message);\n this.name = 'ApitoError';\n }\n}\n\nexport class GraphQLError extends ApitoError {\n constructor(\n message: string,\n public graphQLErrors: GraphQLError[],\n public response?: any\n ) {\n super(message, 'GRAPHQL_ERROR');\n this.name = 'GraphQLError';\n }\n\n get partialData(): any {\n return this.response?.data;\n }\n}\n\nexport class ValidationError extends ApitoError {\n constructor(message: string, public field?: string) {\n super(message, 'VALIDATION_ERROR');\n this.name = 'ValidationError';\n }\n}\n","import {\n DefaultDocumentStructure,\n TypedDocumentStructure,\n TypedSearchResult,\n CreateAndUpdateRequest,\n} from './types';\nimport { ApitoClient } from './client';\n\n/**\n * Typed operations wrapper for the Apito SDK\n * Provides type-safe methods for working with typed data\n */\nexport class TypedOperations {\n constructor(private client: ApitoClient) {}\n\n private static toTypedDocument<T>(raw: DefaultDocumentStructure): TypedDocumentStructure<T> {\n const data = JSON.parse(JSON.stringify(raw.data)) as T;\n return {\n _key: raw._key,\n _id: raw._id,\n data,\n meta: raw.meta,\n id: raw.id,\n expire_at: raw.expire_at,\n relation_doc_id: raw.relation_doc_id,\n last_revision_doc_id: raw.last_revision_doc_id,\n type: raw.type,\n tenant_id: raw.tenant_id,\n tenant_model: raw.tenant_model,\n };\n }\n\n /**\n * Get a single resource with type safety\n */\n async getSingleResourceTyped<T>(\n model: string,\n id: string,\n singlePageData: boolean = false\n ): Promise<TypedDocumentStructure<T>> {\n const result = await this.client.getSingleResource(model, id, singlePageData);\n return TypedOperations.toTypedDocument<T>(result);\n }\n\n /**\n * Search resources with type safety\n */\n async searchResourcesTyped<T>(\n model: string,\n filter: Record<string, any> = {},\n aggregate: boolean = false\n ): Promise<TypedSearchResult<T>> {\n const result = await this.client.searchResources(model, filter, aggregate);\n return {\n results: result.results.map((doc) => TypedOperations.toTypedDocument<T>(doc)),\n count: result.count,\n };\n }\n\n /**\n * Get related documents with type safety\n */\n async getRelationDocumentsTyped<T>(\n id: string,\n connection: Record<string, any>\n ): Promise<TypedSearchResult<T>> {\n const result = await this.client.getRelationDocuments(id, connection);\n return {\n results: result.results.map((doc) => TypedOperations.toTypedDocument<T>(doc)),\n count: result.count,\n };\n }\n\n /**\n * Create a new resource with type safety\n */\n async createNewResourceTyped<T>(\n request: CreateAndUpdateRequest\n ): Promise<TypedDocumentStructure<T>> {\n const result = await this.client.createNewResource(request);\n return TypedOperations.toTypedDocument<T>(result);\n }\n\n /**\n * Update a resource with type safety\n */\n async updateResourceTyped<T>(\n request: CreateAndUpdateRequest\n ): Promise<TypedDocumentStructure<T>> {\n const result = await this.client.updateResource(request);\n return TypedOperations.toTypedDocument<T>(result);\n }\n}\n","/**\n * Apito JavaScript internal SDK version (kept in sync with package.json for releases)\n */\nexport const Version = '3.1.0';\n\n/**\n * GetVersion returns the current version of the SDK\n */\nexport function getVersion(): string {\n return Version;\n}\n"],"mappings":"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","names":["axios","ApitoError","message","code","statusCode","details","GraphQLError","graphQLErrors","response","ValidationError","field","deriveRestBaseURL","graphqlURL","u","ApitoClient","config","axios","query","variables","options","payload","headers","response","GraphQLError","error","ApitoError","tenantId","duration","role","dur","d","data","ValidationError","tid","method","path","url","k","v","body","msg","params","authMethod","code","state","password","email","phone","raw","projectId","limit","offset","count","domain","userId","uid","ok","size","fileName","form","bytes","blob","fileType","ids","result","model","id","singlePageData","filter","aggregate","connection","request","stage","createClient","TypedOperations","_TypedOperations","client","raw","data","model","id","singlePageData","result","filter","aggregate","doc","connection","request","Version","getVersion"]}
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -20,12 +20,10 @@ import {
|
|
|
20
20
|
CreateUserParams,
|
|
21
21
|
UpdateUserParams,
|
|
22
22
|
GoogleOAuthStateResponse,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
SystemFileUploadParams,
|
|
28
|
-
DeleteSystemFilesResponse,
|
|
23
|
+
File,
|
|
24
|
+
FilesListResponse,
|
|
25
|
+
UploadFileParams,
|
|
26
|
+
DeleteFilesResponse,
|
|
29
27
|
} from './types';
|
|
30
28
|
|
|
31
29
|
function deriveRestBaseURL(graphqlURL: string): string {
|
|
@@ -504,62 +502,8 @@ export class ApitoClient implements InjectedDBOperationInterface {
|
|
|
504
502
|
return ok;
|
|
505
503
|
}
|
|
506
504
|
|
|
507
|
-
/** Read project storage settings via getProject. */
|
|
508
|
-
async getProjectStorageSettings(projectId: string): Promise<ProjectStorageSettings> {
|
|
509
|
-
const query = `
|
|
510
|
-
query GetProjectStorageSettings($_id: String!) {
|
|
511
|
-
getProject(_id: $_id) {
|
|
512
|
-
storage_settings {
|
|
513
|
-
use_free_cloud_storage
|
|
514
|
-
endpoint
|
|
515
|
-
region
|
|
516
|
-
bucket
|
|
517
|
-
access_key_id
|
|
518
|
-
has_secret_access_key
|
|
519
|
-
public_base_url
|
|
520
|
-
force_path_style
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
`;
|
|
525
|
-
const response = await this.executeGraphQL(query, { _id: projectId });
|
|
526
|
-
const settings = response.data?.getProject?.storage_settings;
|
|
527
|
-
if (!settings) {
|
|
528
|
-
throw new ValidationError('Invalid response format for getProjectStorageSettings');
|
|
529
|
-
}
|
|
530
|
-
return settings as ProjectStorageSettings;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
/** Persist project storage settings. */
|
|
534
|
-
async updateProjectStorageSettings(
|
|
535
|
-
input: UpdateProjectStorageInput
|
|
536
|
-
): Promise<ProjectStorageSettings> {
|
|
537
|
-
const query = `
|
|
538
|
-
mutation UpdateProjectStorageSettings($input: UpdateProjectStorageInput!) {
|
|
539
|
-
updateProjectStorageSettings(input: $input) {
|
|
540
|
-
storage_settings {
|
|
541
|
-
use_free_cloud_storage
|
|
542
|
-
endpoint
|
|
543
|
-
region
|
|
544
|
-
bucket
|
|
545
|
-
access_key_id
|
|
546
|
-
has_secret_access_key
|
|
547
|
-
public_base_url
|
|
548
|
-
force_path_style
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
`;
|
|
553
|
-
const response = await this.executeGraphQL(query, { input });
|
|
554
|
-
const settings = response.data?.updateProjectStorageSettings?.storage_settings;
|
|
555
|
-
if (!settings) {
|
|
556
|
-
throw new ValidationError('Invalid response format for updateProjectStorageSettings');
|
|
557
|
-
}
|
|
558
|
-
return settings as ProjectStorageSettings;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
505
|
/** Upload a file via POST /system/files/upload. */
|
|
562
|
-
async
|
|
506
|
+
async uploadFile(params: UploadFileParams): Promise<File> {
|
|
563
507
|
const size =
|
|
564
508
|
params.content instanceof ArrayBuffer
|
|
565
509
|
? params.content.byteLength
|
|
@@ -576,23 +520,23 @@ export class ApitoClient implements InjectedDBOperationInterface {
|
|
|
576
520
|
if (params.fileType?.trim()) {
|
|
577
521
|
form.append('file_type', params.fileType.trim());
|
|
578
522
|
}
|
|
579
|
-
const body = await this.executeREST<{ file:
|
|
523
|
+
const body = await this.executeREST<{ file: File }>('POST', '/files/upload', {
|
|
580
524
|
formData: form,
|
|
581
525
|
});
|
|
582
526
|
if (!body.file?.id) {
|
|
583
|
-
throw new ValidationError('Invalid response format for
|
|
527
|
+
throw new ValidationError('Invalid response format for uploadFile');
|
|
584
528
|
}
|
|
585
529
|
return body.file;
|
|
586
530
|
}
|
|
587
531
|
|
|
588
532
|
/** List files via GET /system/files/list. */
|
|
589
|
-
async
|
|
533
|
+
async listFiles(
|
|
590
534
|
fileType?: string,
|
|
591
535
|
limit?: number,
|
|
592
536
|
offset?: number
|
|
593
|
-
): Promise<
|
|
537
|
+
): Promise<FilesListResponse> {
|
|
594
538
|
const body = await this.executeREST<{
|
|
595
|
-
files:
|
|
539
|
+
files: File[];
|
|
596
540
|
total: number;
|
|
597
541
|
}>('GET', '/files/list', {
|
|
598
542
|
query: {
|
|
@@ -608,15 +552,15 @@ export class ApitoClient implements InjectedDBOperationInterface {
|
|
|
608
552
|
}
|
|
609
553
|
|
|
610
554
|
/** Delete files via POST /system/files/delete. */
|
|
611
|
-
async
|
|
555
|
+
async deleteFiles(ids: string[]): Promise<DeleteFilesResponse> {
|
|
612
556
|
if (!ids?.length) {
|
|
613
557
|
throw new ValidationError('ids are required');
|
|
614
558
|
}
|
|
615
|
-
const body = await this.executeREST<
|
|
559
|
+
const body = await this.executeREST<DeleteFilesResponse>('POST', '/files/delete', {
|
|
616
560
|
jsonBody: { ids },
|
|
617
561
|
allowFailure: true,
|
|
618
562
|
});
|
|
619
|
-
const result:
|
|
563
|
+
const result: DeleteFilesResponse = {
|
|
620
564
|
success: !!body.success,
|
|
621
565
|
deleted_ids: body.deleted_ids ?? [],
|
|
622
566
|
storage_failed: body.storage_failed,
|
package/src/index.ts
CHANGED
|
@@ -28,10 +28,10 @@ export type {
|
|
|
28
28
|
CreateUserParams,
|
|
29
29
|
UpdateUserParams,
|
|
30
30
|
User,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
File,
|
|
32
|
+
UploadFileParams,
|
|
33
|
+
FilesListResponse,
|
|
34
|
+
DeleteFilesResponse,
|
|
35
35
|
} from './types';
|
|
36
36
|
|
|
37
37
|
// Default export for convenience
|
package/src/types.ts
CHANGED
|
@@ -138,29 +138,7 @@ export interface UsersResponse {
|
|
|
138
138
|
count: number;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
export interface
|
|
142
|
-
use_free_cloud_storage: boolean;
|
|
143
|
-
endpoint?: string | null;
|
|
144
|
-
region?: string | null;
|
|
145
|
-
bucket?: string | null;
|
|
146
|
-
access_key_id?: string | null;
|
|
147
|
-
has_secret_access_key: boolean;
|
|
148
|
-
public_base_url?: string | null;
|
|
149
|
-
force_path_style?: boolean | null;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export interface UpdateProjectStorageInput {
|
|
153
|
-
use_free_cloud_storage?: boolean;
|
|
154
|
-
endpoint?: string;
|
|
155
|
-
region?: string;
|
|
156
|
-
bucket?: string;
|
|
157
|
-
access_key_id?: string;
|
|
158
|
-
secret_access_key?: string;
|
|
159
|
-
public_base_url?: string;
|
|
160
|
-
force_path_style?: boolean;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export interface SystemFile {
|
|
141
|
+
export interface File {
|
|
164
142
|
id: string;
|
|
165
143
|
file_type: string;
|
|
166
144
|
file_name: string;
|
|
@@ -172,18 +150,18 @@ export interface SystemFile {
|
|
|
172
150
|
created_at?: string;
|
|
173
151
|
}
|
|
174
152
|
|
|
175
|
-
export interface
|
|
176
|
-
files:
|
|
153
|
+
export interface FilesListResponse {
|
|
154
|
+
files: File[];
|
|
177
155
|
total: number;
|
|
178
156
|
}
|
|
179
157
|
|
|
180
|
-
export interface
|
|
158
|
+
export interface UploadFileParams {
|
|
181
159
|
fileName: string;
|
|
182
160
|
content: Uint8Array | ArrayBuffer;
|
|
183
161
|
fileType?: string;
|
|
184
162
|
}
|
|
185
163
|
|
|
186
|
-
export interface
|
|
164
|
+
export interface DeleteFilesResponse {
|
|
187
165
|
success: boolean;
|
|
188
166
|
deleted_ids: string[];
|
|
189
167
|
storage_failed?: string[];
|
|
@@ -249,11 +227,9 @@ export interface InjectedDBOperationInterface {
|
|
|
249
227
|
updateUser(userId: string, params: UpdateUserParams): Promise<User>;
|
|
250
228
|
resetUserPassword(userId: string, password: string): Promise<boolean>;
|
|
251
229
|
deleteUser(userId: string): Promise<boolean>;
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
listSystemFiles(fileType?: string, limit?: number, offset?: number): Promise<SystemFilesListResponse>;
|
|
256
|
-
deleteSystemFiles(ids: string[]): Promise<DeleteSystemFilesResponse>;
|
|
230
|
+
uploadFile(params: UploadFileParams): Promise<File>;
|
|
231
|
+
listFiles(fileType?: string, limit?: number, offset?: number): Promise<FilesListResponse>;
|
|
232
|
+
deleteFiles(ids: string[]): Promise<DeleteFilesResponse>;
|
|
257
233
|
getSingleResource(model: string, id: string, singlePageData?: boolean): Promise<DefaultDocumentStructure>;
|
|
258
234
|
searchResources(model: string, filter?: Record<string, any>, aggregate?: boolean): Promise<SearchResult>;
|
|
259
235
|
getRelationDocuments(id: string, connection: Record<string, any>): Promise<SearchResult>;
|