import {z} from 'zod' export type GetApiApiProjectIdArgs = {projectId: number, impulseId?: number | undefined, truncateLabels?: boolean | undefined, datasetVersionId?: number | undefined}; export type GetApiApiProjectIdOptions = {baseUrl?: string | undefined, ApiKeyAuthentication?: string | undefined, fetch?: typeof fetch | undefined}; export const staffInfo = z.object({isStaff: z.boolean(), hasSudoRights: z.boolean(), companyName: z.string().optional()}); export const permission = z.enum(["admin:infra:datasetVersioning:queue:write", "admin:infra:disallowedEmailDomains:read", "admin:infra:disallowedEmailDomains:write", "admin:infra:featureFlags:read", "admin:infra:featureFlags:write", "admin:infra:config:read", "admin:infra:config:write", "admin:infra:migrations:read", "admin:infra:migrations:write", "admin:metrics:read", "admin:metrics:write", "admin:oauth:read", "admin:oauth:write", "admin:organizations:extensions:write", "admin:organizations:read", "admin:organizations:write", "admin:organizations:members:write", "admin:projects:members:write", "admin:projects:read", "admin:projects:write", "admin:trashbin:write", "admin:trials:read", "admin:trials:write", "admin:users:permissions:write", "admin:users:read", "admin:users:signupApprovals:read", "admin:users:signupApprovals:write", "admin:users:write", "admin:jobs:read", "admin:emails:verification:code:read", "admin:sso:read", "admin:sso:domainIdps:write", "admin:vlm:model:read", "admin:vlm:model:write", "projects:limits:write", "projects:training:keras:write", "projects:data:versioning:write", "users:emails:read", "whitelabels:read", "whitelabels:write", "test:data:write", "test:users:read", "test:users:write"]); export const userTierEnum = z.enum(["free", "community-plus", "professional", "enterprise"]); export const projectCollaborator = z.object({id: z.number().int(), username: z.string(), name: z.string(), email: z.string(), photo: z.string().optional(), created: z.string(), lastSeen: z.string().optional(), staffInfo: staffInfo, pending: z.boolean(), jobTitle: z.string().optional(), permissions: z.array(permission).optional(), companyName: z.string().optional(), activated: z.boolean(), mfaConfigured: z.boolean(), stripeCustomerId: z.string().optional(), hasPendingPayments: z.boolean().optional(), tier: userTierEnum.optional(), idps: z.array(z.string()).optional(), isOwner: z.boolean()}); export const projectLabelingMethod = z.enum(["single_label", "object_detection", "label_map"]); export const publicProjectLicense = z.enum(["Apache-2.0", "BSD-3-Clause", "BSD-3-Clause-Clear"]); export const projectTierEnum = z.enum(["free", "community-plus", "professional", "enterprise"]); export const project = z.object({id: z.number().int(), name: z.string(), description: z.string(), created: z.string(), owner: z.string(), lastAccessed: z.string().optional(), lastModified: z.string().optional(), lastModificationDetails: z.string().optional(), logo: z.string().optional(), ownerUserId: z.number().int().optional(), ownerOrganizationId: z.number().int().optional(), ownerAvatar: z.string().optional(), ownerIsDeveloperProfile: z.boolean(), developerProfileUserId: z.number().int().optional(), collaborators: z.array(projectCollaborator), labelingMethod: projectLabelingMethod, metadata: z.object({}), dataExplorerScreenshot: z.string().optional(), isEnterpriseProject: z.boolean(), whitelabelId: z.number().int().nullable(), whitelabelName: z.string().optional(), tags: z.array(z.string()).optional(), category: z.enum(["Accelerometer", "Audio", "Images", "Keyword spotting", "Object detection", "Other"]).optional(), license: publicProjectLicense.optional(), tier: projectTierEnum, hasPublicVersion: z.boolean(), isPublic: z.boolean(), allowsLivePublicAccess: z.boolean(), indPauseProcessingSamples: z.boolean(), publicProjectListed: z.boolean(), deletedDate: z.string().optional(), fullDeletionDate: z.string().optional(), scheduledFullDeletionDate: z.string().optional()}); export const developmentKeys = z.object({apiKey: z.string().optional(), hmacKey: z.string().optional()}); export const device = z.object({id: z.number().int(), deviceId: z.string(), created: z.string(), lastSeen: z.string(), name: z.string(), deviceType: z.string(), sensors: z.array(z.object({name: z.string(), maxSampleLengthS: z.number().int(), frequencies: z.array(z.number())})), remote_mgmt_connected: z.boolean(), remote_mgmt_host: z.string().optional(), supportsSnapshotStreaming: z.boolean(), remoteMgmtMode: z.enum(["disconnected", "ingestion", "inference"]), inferenceInfo: z.object({projectId: z.number().int(), projectOwner: z.string(), projectName: z.string(), deployedVersion: z.number().int(), modelType: z.enum(["classification", "objectDetection", "constrainedObjectDetection"]).optional()}).optional()}); export const projectDataSummary = z.object({totalLengthMs: z.number(), labels: z.array(z.string()), totalLabels: z.number().int(), min: z.number().int().optional(), max: z.number().int().optional(), mean: z.number().optional(), dataCount: z.number().int()}); export const user = z.object({id: z.number().int(), username: z.string(), name: z.string(), email: z.string(), photo: z.string().optional(), created: z.string(), lastSeen: z.string().optional(), staffInfo: staffInfo, pending: z.boolean(), jobTitle: z.string().optional(), permissions: z.array(permission).optional(), companyName: z.string().optional(), activated: z.boolean(), mfaConfigured: z.boolean(), stripeCustomerId: z.string().optional(), hasPendingPayments: z.boolean().optional(), tier: userTierEnum.optional(), idps: z.array(z.string()).optional()}); export const modelEngineShortEnum = z.enum(["tflite-eon", "tflite-eon-ram-optimized", "tflite"]); export const latencyDevice = z.object({mcu: z.string(), name: z.string(), selected: z.boolean(), int8Latency: z.number(), int8ConvLatency: z.number(), float32Latency: z.number(), float32ConvLatency: z.number(), helpText: z.string()}); export const tutorialType = z.enum(["kws", "cv"]); export const resourceRange = z.object({minimum: z.number().optional(), maximum: z.number().optional()}); export const memorySpec = z.object({fastBytes: resourceRange.optional(), slowBytes: resourceRange.optional()}); export const targetMemory = z.object({ram: memorySpec.optional(), rom: memorySpec.optional()}); export const targetProcessor = z.object({part: z.string().optional(), format: z.string().optional(), architecture: z.string().optional(), specificArchitecture: z.string().optional(), accelerator: z.string().optional(), fpu: z.boolean().optional(), clockRateMhz: resourceRange.optional(), memory: targetMemory.optional()}); export const targetConstraintsDevice = z.object({processors: z.array(targetProcessor).optional(), board: z.string().optional(), name: z.string().optional(), latencyDevice: z.string().optional()}); export const applicationBudget = z.object({latencyPerInferenceMs: resourceRange.optional(), energyPerInferenceJoules: resourceRange.optional(), memoryOverhead: targetMemory.optional()}); export const targetConstraints = z.object({selectedTargetBasedOn: z.enum(["user-configured", "default", "default-accepted", "recent-project", "connected-device"]).optional(), targetDevices: z.array(targetConstraintsDevice), applicationBudgets: z.array(applicationBudget)}); export const anomalyLabelsConfig = z.object({anomalyLabels: z.array(z.string()), noAnomalyLabels: z.array(z.string())}); export const datasetSplitOptions = z.object({trainingSplitRatio: z.number(), testingSplitRatio: z.number(), validationSplitRatio: z.number().optional(), excludeDisabledSamples: z.boolean().optional(), stratifyBy: z.object({label: z.boolean().optional(), metadataKeys: z.array(z.string()).optional()}).optional(), keepTogetherMetadataKeys: z.array(z.string()).optional()}); export const projectInfoResponse = z.object({success: z.boolean(), error: z.string().optional(), project: project, developmentKeys: developmentKeys, impulse: z.object({created: z.boolean(), configured: z.boolean(), complete: z.boolean()}), devices: z.array(device), dataSummary: projectDataSummary, dataSummaryPerCategory: z.object({training: projectDataSummary, testing: z.object({totalLengthMs: z.number(), labels: z.array(z.string()), totalLabels: z.number().int(), min: z.number().int().optional(), max: z.number().int().optional(), mean: z.number().optional(), dataCount: z.number().int()}), validation: z.object({totalLengthMs: z.number(), labels: z.array(z.string()), totalLabels: z.number().int(), min: z.number().int().optional(), max: z.number().int().optional(), mean: z.number().optional(), dataCount: z.number().int()}), postProcessing: z.object({totalLengthMs: z.number(), labels: z.array(z.string()), totalLabels: z.number().int(), min: z.number().int().optional(), max: z.number().int().optional(), mean: z.number().optional(), dataCount: z.number().int()})}), computeTime: z.object({periodStartDate: z.string(), periodEndDate: z.string(), timeUsedMs: z.number().int(), timeLeftMs: z.number().int()}), acquisitionSettings: z.object({intervalMs: z.number(), lengthMs: z.number().int(), sensor: z.string().optional(), label: z.string().optional(), segmentLength: z.number().optional(), segmentShift: z.boolean(), defaultPageSize: z.number().int(), viewType: z.enum(["list", "grid"]), gridColumnCount: z.number().int(), gridColumnCountDetailed: z.number().int(), showExactSampleLength: z.boolean(), inlineEditBoundingBoxes: z.boolean()}), collaborators: z.array(user), deploySettings: z.object({eonCompiler: z.boolean(), sensor: z.enum(["accelerometer", "microphone", "camera", "positional", "environmental", "fusion", "unknown"]), arduinoLibraryName: z.string(), tinkergenLibraryName: z.string(), particleLibraryName: z.string(), lastDeployModelEngine: modelEngineShortEnum.optional()}), experiments: z.array(z.object({type: z.string(), title: z.string(), help: z.string().optional(), enabled: z.boolean(), showToUser: z.boolean()})), latencyDevices: z.array(latencyDevice), urls: z.object({mobileClient: z.string().optional(), mobileClientComputer: z.string().optional(), mobileClientInference: z.string().optional()}), showCreateFirstImpulse: z.boolean(), showGettingStartedWizard: z.object({showWizard: z.boolean(), step: z.number().int(), tutorial: tutorialType.optional(), classes: z.array(z.string()).optional()}), performance: z.object({gpu: z.boolean(), jobLimitM: z.number().int(), dspFileSizeMb: z.number().int(), enterprisePerformance: z.boolean(), trainJobRamMb: z.number().int()}), readme: z.object({markdown: z.string(), html: z.string()}).optional(), trainJobNotificationUids: z.array(z.number().int()), dspJobNotificationUids: z.array(z.number().int()), modelTestingJobNotificationUids: z.array(z.number().int()), exportJobNotificationUids: z.array(z.number().int()), hasNewTrainingData: z.boolean(), csvImportConfig: z.object({}).optional(), studioUrl: z.string(), inPretrainedModelFlow: z.boolean(), dspPageSize: z.number().int().optional(), windowJobConcurrency: z.number().int().optional(), showSensorDataInAcquisitionGraph: z.boolean(), targetConstraints: targetConstraints.optional(), notifications: z.array(z.string()), defaultImpulseId: z.number().int().optional(), lastShownModelEngine: modelEngineShortEnum.optional(), versioningStorageSizeMib: z.number().int().optional(), anomalyLabelsConfig: anomalyLabelsConfig.optional(), datasetSplitOptions: datasetSplitOptions.optional(), explicitValidationEnabled: z.boolean().optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Project information * * GET /api/{projectId} * * Also accepts auth: JWTAuthentication, JWTHttpHeaderAuthentication, OAuth2 */ export const getApiApiProjectId = async (args: GetApiApiProjectIdArgs, options?: GetApiApiProjectIdOptions) => { const {baseUrl = "https://studio.edgeimpulse.com/v1", fetch: fetchFn = fetch, ApiKeyAuthentication} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.impulseId != null) query.append("impulseId", String(args.impulseId)) if (args.truncateLabels != null) query.append("truncateLabels", String(args.truncateLabels)) if (args.datasetVersionId != null) query.append("datasetVersionId", String(args.datasetVersionId)) if (ApiKeyAuthentication !== undefined) headers.set("x-api-key", ApiKeyAuthentication) const url = `${baseUrl.replace(/\/+$/, '')}/api/${encodeURIComponent(String(args.projectId))}${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(projectInfoResponse, await res.json()) };