@akashnetwork/chain-sdk 1.0.0-alpha.34 → 1.0.0-alpha.36

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.
Files changed (58) hide show
  1. package/dist/cjs/generated/createProviderSDK.cjs +10 -1
  2. package/dist/cjs/generated/createProviderSDK.cjs.map +2 -2
  3. package/dist/cjs/generated/protos/akash/manifest/v2beta3/service.cjs +85 -3
  4. package/dist/cjs/generated/protos/akash/manifest/v2beta3/service.cjs.map +2 -2
  5. package/dist/cjs/generated/protos/akash/provider/lease/v1/service.cjs +276 -0
  6. package/dist/cjs/generated/protos/akash/provider/lease/v1/service.cjs.map +2 -2
  7. package/dist/cjs/generated/protos/akash/provider/lease/v1/service_akash.cjs +10 -0
  8. package/dist/cjs/generated/protos/akash/provider/lease/v1/service_akash.cjs.map +2 -2
  9. package/dist/cjs/generated/protos/akash/provider/v1/status.cjs +19 -2
  10. package/dist/cjs/generated/protos/akash/provider/v1/status.cjs.map +2 -2
  11. package/dist/cjs/generated/protos/index.provider.akash.v1.cjs +3 -0
  12. package/dist/cjs/generated/protos/index.provider.akash.v1.cjs.map +2 -2
  13. package/dist/cjs/generated/protos/index.provider.akash.v2beta3.cjs +2 -1
  14. package/dist/cjs/generated/protos/index.provider.akash.v2beta3.cjs.map +2 -2
  15. package/dist/cjs/sdk/provider/auth/jwt/validateJwtPayload.cjs +5 -5
  16. package/dist/cjs/sdk/provider/auth/jwt/validateJwtPayload.cjs.map +2 -2
  17. package/dist/cjs/sdl/manifest/generateManifest.cjs +3 -0
  18. package/dist/cjs/sdl/manifest/generateManifest.cjs.map +2 -2
  19. package/dist/cjs/sdl/manifest/generateManifestVersion.cjs +1 -1
  20. package/dist/cjs/sdl/manifest/generateManifestVersion.cjs.map +2 -2
  21. package/dist/cjs/sdl/validateSDL/validateSDL.cjs +24 -1
  22. package/dist/cjs/sdl/validateSDL/validateSDL.cjs.map +2 -2
  23. package/dist/cjs/sdl/validateSDL/validateSDLInput.cjs +67 -46
  24. package/dist/cjs/sdl/validateSDL/validateSDLInput.cjs.map +2 -2
  25. package/dist/esm/{chunk-W25EJ3NI.js → chunk-MLIW7FIZ.js} +22 -3
  26. package/dist/esm/chunk-MLIW7FIZ.js.map +7 -0
  27. package/dist/esm/{chunk-2ZDOXCM3.js → chunk-P2FARPRM.js} +104 -56
  28. package/dist/esm/chunk-P2FARPRM.js.map +7 -0
  29. package/dist/esm/{chunk-HBXYMZWF.js → chunk-SQUBF6EZ.js} +279 -3
  30. package/dist/esm/chunk-SQUBF6EZ.js.map +7 -0
  31. package/dist/esm/{chunk-COR2HJ6D.js → chunk-UZXCPKLQ.js} +85 -3
  32. package/dist/esm/chunk-UZXCPKLQ.js.map +7 -0
  33. package/dist/esm/generated/protos/index.provider.akash.v1.js +9 -3
  34. package/dist/esm/generated/protos/index.provider.akash.v2beta3.js +5 -3
  35. package/dist/esm/index.js +14 -5
  36. package/dist/esm/index.js.map +2 -2
  37. package/dist/esm/index.web.js +2 -2
  38. package/dist/esm/{service_akash-AAROYIZB.js → service_akash-BILCZWQI.js} +15 -3
  39. package/dist/esm/service_akash-BILCZWQI.js.map +7 -0
  40. package/dist/esm/{service_akash-5RIOE2CY.js → service_akash-LXXUUD6O.js} +3 -2
  41. package/dist/esm/{service_akash-5RIOE2CY.js.map → service_akash-LXXUUD6O.js.map} +1 -1
  42. package/dist/sdl-schema.yaml +5 -0
  43. package/dist/tsconfig.build.tsbuildinfo +1 -1
  44. package/dist/types/generated/createProviderSDK.d.ts +14 -0
  45. package/dist/types/generated/protos/akash/manifest/v2beta3/service.d.ts +19 -0
  46. package/dist/types/generated/protos/akash/provider/lease/v1/service.d.ts +43 -0
  47. package/dist/types/generated/protos/akash/provider/lease/v1/service_akash.d.ts +9 -1
  48. package/dist/types/generated/protos/akash/provider/v1/status.d.ts +2 -0
  49. package/dist/types/generated/protos/index.provider.akash.v1.d.ts +1 -1
  50. package/dist/types/generated/protos/index.provider.akash.v2beta3.d.ts +1 -1
  51. package/dist/types/sdk/provider/auth/jwt/validateJwtPayload.d.ts +3 -3
  52. package/dist/types/sdl/validateSDL/validateSDLInput.d.ts +5 -0
  53. package/package.json +1 -1
  54. package/dist/esm/chunk-2ZDOXCM3.js.map +0 -7
  55. package/dist/esm/chunk-COR2HJ6D.js.map +0 -7
  56. package/dist/esm/chunk-HBXYMZWF.js.map +0 -7
  57. package/dist/esm/chunk-W25EJ3NI.js.map +0 -7
  58. package/dist/esm/service_akash-AAROYIZB.js.map +0 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/sdl/manifest/generateManifest.ts"],
4
- "sourcesContent": ["import { PlacementRequirements, SignedBy } from \"../../generated/protos/akash/base/attributes/v1/attribute.ts\";\nimport { CPU } from \"../../generated/protos/akash/base/resources/v1beta4/cpu.ts\";\nimport { GPU } from \"../../generated/protos/akash/base/resources/v1beta4/gpu.ts\";\nimport { Memory } from \"../../generated/protos/akash/base/resources/v1beta4/memory.ts\";\nimport { Resources } from \"../../generated/protos/akash/base/resources/v1beta4/resources.ts\";\nimport { Storage } from \"../../generated/protos/akash/base/resources/v1beta4/storage.ts\";\nimport { DeploymentReclamation } from \"../../generated/protos/akash/deployment/v1/deployment.ts\";\nimport { GroupSpec } from \"../../generated/protos/akash/deployment/v1beta4/groupspec.ts\";\nimport { ResourceUnit } from \"../../generated/protos/akash/deployment/v1beta4/resourceunit.ts\";\nimport { Group } from \"../../generated/protos/akash/manifest/v2beta3/group.ts\";\nimport { ImageCredentials, Service, ServiceParams, StorageParams } from \"../../generated/protos/akash/manifest/v2beta3/service.ts\";\nimport { ServiceExpose } from \"../../generated/protos/akash/manifest/v2beta3/serviceexpose.ts\";\nimport type { ValidationError } from \"../../utils/jsonSchemaValidation.ts\";\nimport { castArray } from \"../utils.ts\";\nimport type { SDLInput } from \"../validateSDL/validateSDL.ts\";\nimport { validateSDL } from \"../validateSDL/validateSDL.ts\";\nimport {\n buildHttpOptions,\n buildResourceAttributes,\n buildServiceEndpoints,\n buildStorageAttributes,\n computeEndpointSequenceNumbers,\n encodeResourceValue,\n parseCpuUnits,\n parseGpuUnits,\n parseMemoryBytes,\n parseServiceProto,\n parseStorageBytes,\n type SDLCompute,\n type SDLService,\n transformGpuAttributes,\n} from \"./manifestUtils.ts\";\nimport { minWindowToDuration } from \"./reclamationDuration.ts\";\n\nexport interface GenerateManifestOkResult {\n groups: Group[];\n groupSpecs: GroupSpec[];\n reclamation?: DeploymentReclamation;\n}\n\nexport type Manifest = GenerateManifestOkResult[\"groups\"];\nexport type GenerateManifestResult =\n | { ok?: false; value: ValidationError[] }\n | { ok: true; value: GenerateManifestOkResult };\nexport function generateManifest(sdl: SDLInput): GenerateManifestResult {\n const errors = validateSDL(sdl);\n if (errors) return { ok: false, value: errors };\n\n const endpointSequenceNumbers = computeEndpointSequenceNumbers(sdl.services);\n const groupsMap = new Map<string, {\n dgroup: GroupSpec;\n boundComputes: Record<string, number>;\n }>();\n const resourceIds = new Map<string, number>();\n\n const deploymentsByPlacement = new Map<string, [string, { profile: string; count: number }][]>();\n for (const [svcName, placements] of Object.entries(sdl.deployment)) {\n for (const [placementName, deployment] of Object.entries(placements)) {\n let list = deploymentsByPlacement.get(placementName);\n if (!list) {\n list = [];\n deploymentsByPlacement.set(placementName, list);\n }\n list.push([svcName, deployment]);\n }\n }\n for (const list of deploymentsByPlacement.values()) {\n list.sort(([a], [b]) => a.localeCompare(b));\n }\n\n const services = Object.entries(sdl.services).sort(([a], [b]) => a.localeCompare(b));\n\n for (const [svcName, service] of services) {\n for (const [placementName, svcdepl] of Object.entries(sdl.deployment[svcName])) {\n const compute = sdl.profiles.compute[svcdepl.profile];\n const infra = sdl.profiles.placement[placementName];\n const pricing = infra.pricing[svcdepl.profile];\n const price = {\n denom: pricing.denom,\n amount: pricing.amount?.toString(),\n };\n\n let group = groupsMap.get(placementName);\n\n if (!group) {\n group = {\n dgroup: GroupSpec.fromPartial({\n name: placementName,\n resources: [],\n requirements: PlacementRequirements.fromPartial({\n attributes: buildResourceAttributes(infra.attributes),\n signedBy: SignedBy.fromPartial({\n allOf: infra.signedBy?.allOf,\n anyOf: infra.signedBy?.anyOf,\n }),\n }),\n }),\n boundComputes: {},\n };\n\n groupsMap.set(placementName, group);\n }\n\n const profileKey = `${placementName}:${svcdepl.profile}`;\n const location = group.boundComputes[svcdepl.profile];\n\n if (location === undefined) {\n const resId = group.dgroup.resources.length > 0\n ? group.dgroup.resources.length + 1\n : 1;\n\n resourceIds.set(profileKey, resId);\n\n const resources = buildResources(resId, compute, service, endpointSequenceNumbers);\n\n group.dgroup.resources.push(\n ResourceUnit.fromPartial({\n resource: resources,\n count: svcdepl.count,\n price,\n }),\n );\n\n group.boundComputes[svcdepl.profile] = group.dgroup.resources.length - 1;\n } else {\n if (!resourceIds.has(profileKey)) {\n resourceIds.set(profileKey, group.dgroup.resources[location].resource!.id);\n }\n\n group.dgroup.resources[location].count += svcdepl.count;\n group.dgroup.resources[location].resource!.endpoints.push(\n ...buildServiceEndpoints(service, endpointSequenceNumbers),\n );\n }\n }\n }\n\n for (const group of groupsMap.values()) {\n for (const resourceUnit of group.dgroup.resources) {\n resourceUnit.resource!.endpoints.sort(\n (a, b) => a.kind - b.kind || a.sequenceNumber - b.sequenceNumber,\n );\n }\n }\n\n const sortedGroupNames = [...groupsMap.keys()].sort();\n let groups: Group[] | undefined;\n let groupSpecs: GroupSpec[] | undefined;\n let reclamation: DeploymentReclamation | undefined;\n\n const manifest = {\n // reclamation is a `MsgCreateDeployment` field, not a manifest group, and is\n // not needed in every call \u2014 so it's lazy like `groups`/`groupSpecs`.\n // `validateSDL` (run above) already guaranteed `min_window` is valid, so\n // `minWindowToDuration` never throws here.\n get reclamation() {\n if (sdl.reclamation && !reclamation) {\n reclamation = DeploymentReclamation.fromPartial({\n minWindow: minWindowToDuration(sdl.reclamation.min_window),\n });\n }\n return reclamation;\n },\n get groups() {\n groups ??= sortedGroupNames.map((placementName) => {\n const deployments = deploymentsByPlacement.get(placementName)!;\n\n return Group.fromPartial({\n name: placementName,\n services: deployments.map(([svcName]) => {\n const service = sdl.services[svcName];\n const deployment = sdl.deployment[svcName][placementName];\n const compute = sdl.profiles.compute[deployment.profile];\n const resourceId = resourceIds.get(`${placementName}:${deployment.profile}`) || 1;\n\n return buildManifestService(\n resourceId,\n svcName,\n service,\n compute,\n deployment.count,\n endpointSequenceNumbers,\n );\n }),\n });\n });\n return groups;\n },\n get groupSpecs() {\n groupSpecs ??= sortedGroupNames.map((name) => groupsMap.get(name)!.dgroup);\n return groupSpecs;\n },\n };\n\n return { ok: true, value: manifest };\n}\n\nfunction buildResources(\n id: number,\n compute: SDLCompute,\n service: SDLService,\n endpointSequenceNumbers: Record<string, number>,\n): Resources {\n const res = compute.resources;\n const cpuAttributes = buildResourceAttributes(res.cpu.attributes);\n const gpuAttributes = res.gpu?.attributes ? transformGpuAttributes(res.gpu.attributes) : [];\n\n return Resources.fromPartial({\n id,\n cpu: CPU.fromPartial({\n units: { val: encodeResourceValue(parseCpuUnits(res.cpu)) },\n attributes: cpuAttributes,\n }),\n memory: Memory.fromPartial({\n quantity: { val: encodeResourceValue(parseMemoryBytes(res.memory)) },\n }),\n storage: castArray(res.storage).map((s) =>\n Storage.fromPartial({\n name: s.name || \"default\",\n quantity: { val: encodeResourceValue(parseStorageBytes(s.size)) },\n attributes: buildStorageAttributes(s.attributes),\n }),\n ),\n gpu: GPU.fromPartial({\n units: { val: encodeResourceValue(parseGpuUnits(res.gpu)) },\n attributes: gpuAttributes,\n }),\n endpoints: buildServiceEndpoints(service, endpointSequenceNumbers),\n });\n}\n\nfunction buildManifestService(\n resourceId: number,\n name: string,\n service: SDLService,\n compute: SDLCompute,\n count: number,\n endpointSequenceNumbers: Record<string, number>,\n): Service {\n const credentials = service.credentials\n ? ImageCredentials.fromPartial({\n host: service.credentials.host,\n email: service.credentials.email || \"\",\n username: service.credentials.username,\n password: service.credentials.password,\n })\n : undefined;\n\n const params = buildParams(service);\n\n return Service.fromPartial({\n name,\n image: service.image,\n command: service.command || [],\n args: service.args || [],\n env: service.env || [],\n resources: buildResources(resourceId, compute, service, endpointSequenceNumbers),\n count,\n expose: buildManifestExpose(service, endpointSequenceNumbers),\n params,\n credentials,\n });\n}\n\nfunction buildParams(service: SDLService): ServiceParams | undefined {\n if (!service.params) return undefined;\n\n const storage = service.params.storage || {};\n const storageNames = service.params.storage ? Object.keys(storage).sort() : [];\n const result = ServiceParams.fromPartial({\n storage: storageNames.map((name) => {\n const config = storage[name];\n return StorageParams.fromPartial({\n name,\n mount: config.mount || \"\",\n readOnly: config.readOnly || false,\n });\n }),\n });\n\n // Permissions are not in the protobuf type but need to be preserved\n if (service.params.permissions) {\n (result as unknown as Record<string, unknown>).permissions = service.params.permissions;\n }\n\n return result;\n}\n\nfunction buildManifestExpose(\n service: SDLService,\n endpointSequenceNumbers: Record<string, number>,\n): ServiceExpose[] {\n return (service.expose ?? [])\n .flatMap((expose) =>\n (expose.to ?? []).map((to) =>\n ServiceExpose.fromPartial({\n port: expose.port,\n externalPort: expose.as,\n proto: parseServiceProto(expose.proto),\n service: to.service || \"\",\n global: to.global || false,\n hosts: expose.accept || [],\n httpOptions: buildHttpOptions(expose.http_options),\n ip: to.ip || \"\",\n endpointSequenceNumber: endpointSequenceNumbers[to.ip!],\n }),\n ),\n )\n .sort((a, b) => {\n if (a.service !== b.service) return a.service.localeCompare(b.service);\n if (a.port !== b.port) return a.port - b.port;\n if (a.proto !== b.proto) return a.proto.localeCompare(b.proto);\n if (a.global !== b.global) return a.global ? -1 : 1;\n return 0;\n });\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { PlacementRequirements, SignedBy } from \"../../generated/protos/akash/base/attributes/v1/attribute.ts\";\nimport { CPU } from \"../../generated/protos/akash/base/resources/v1beta4/cpu.ts\";\nimport { GPU } from \"../../generated/protos/akash/base/resources/v1beta4/gpu.ts\";\nimport { Memory } from \"../../generated/protos/akash/base/resources/v1beta4/memory.ts\";\nimport { Resources } from \"../../generated/protos/akash/base/resources/v1beta4/resources.ts\";\nimport { Storage } from \"../../generated/protos/akash/base/resources/v1beta4/storage.ts\";\nimport { DeploymentReclamation } from \"../../generated/protos/akash/deployment/v1/deployment.ts\";\nimport { GroupSpec } from \"../../generated/protos/akash/deployment/v1beta4/groupspec.ts\";\nimport { ResourceUnit } from \"../../generated/protos/akash/deployment/v1beta4/resourceunit.ts\";\nimport { Group } from \"../../generated/protos/akash/manifest/v2beta3/group.ts\";\nimport { ImageCredentials, Service, ServiceParams, StorageParams, TEEParams } from \"../../generated/protos/akash/manifest/v2beta3/service.ts\";\nimport { ServiceExpose } from \"../../generated/protos/akash/manifest/v2beta3/serviceexpose.ts\";\nimport type { ValidationError } from \"../../utils/jsonSchemaValidation.ts\";\nimport { castArray } from \"../utils.ts\";\nimport type { SDLInput } from \"../validateSDL/validateSDL.ts\";\nimport { validateSDL } from \"../validateSDL/validateSDL.ts\";\nimport {\n buildHttpOptions,\n buildResourceAttributes,\n buildServiceEndpoints,\n buildStorageAttributes,\n computeEndpointSequenceNumbers,\n encodeResourceValue,\n parseCpuUnits,\n parseGpuUnits,\n parseMemoryBytes,\n parseServiceProto,\n parseStorageBytes,\n type SDLCompute,\n type SDLService,\n transformGpuAttributes,\n} from \"./manifestUtils.ts\";\nimport { minWindowToDuration } from \"./reclamationDuration.ts\";\n\nexport interface GenerateManifestOkResult {\n groups: Group[];\n groupSpecs: GroupSpec[];\n reclamation?: DeploymentReclamation;\n}\n\nexport type Manifest = GenerateManifestOkResult[\"groups\"];\nexport type GenerateManifestResult =\n | { ok?: false; value: ValidationError[] }\n | { ok: true; value: GenerateManifestOkResult };\nexport function generateManifest(sdl: SDLInput): GenerateManifestResult {\n const errors = validateSDL(sdl);\n if (errors) return { ok: false, value: errors };\n\n const endpointSequenceNumbers = computeEndpointSequenceNumbers(sdl.services);\n const groupsMap = new Map<string, {\n dgroup: GroupSpec;\n boundComputes: Record<string, number>;\n }>();\n const resourceIds = new Map<string, number>();\n\n const deploymentsByPlacement = new Map<string, [string, { profile: string; count: number }][]>();\n for (const [svcName, placements] of Object.entries(sdl.deployment)) {\n for (const [placementName, deployment] of Object.entries(placements)) {\n let list = deploymentsByPlacement.get(placementName);\n if (!list) {\n list = [];\n deploymentsByPlacement.set(placementName, list);\n }\n list.push([svcName, deployment]);\n }\n }\n for (const list of deploymentsByPlacement.values()) {\n list.sort(([a], [b]) => a.localeCompare(b));\n }\n\n const services = Object.entries(sdl.services).sort(([a], [b]) => a.localeCompare(b));\n\n for (const [svcName, service] of services) {\n for (const [placementName, svcdepl] of Object.entries(sdl.deployment[svcName])) {\n const compute = sdl.profiles.compute[svcdepl.profile];\n const infra = sdl.profiles.placement[placementName];\n const pricing = infra.pricing[svcdepl.profile];\n const price = {\n denom: pricing.denom,\n amount: pricing.amount?.toString(),\n };\n\n let group = groupsMap.get(placementName);\n\n if (!group) {\n group = {\n dgroup: GroupSpec.fromPartial({\n name: placementName,\n resources: [],\n requirements: PlacementRequirements.fromPartial({\n attributes: buildResourceAttributes(infra.attributes),\n signedBy: SignedBy.fromPartial({\n allOf: infra.signedBy?.allOf,\n anyOf: infra.signedBy?.anyOf,\n }),\n }),\n }),\n boundComputes: {},\n };\n\n groupsMap.set(placementName, group);\n }\n\n const profileKey = `${placementName}:${svcdepl.profile}`;\n const location = group.boundComputes[svcdepl.profile];\n\n if (location === undefined) {\n const resId = group.dgroup.resources.length > 0\n ? group.dgroup.resources.length + 1\n : 1;\n\n resourceIds.set(profileKey, resId);\n\n const resources = buildResources(resId, compute, service, endpointSequenceNumbers);\n\n group.dgroup.resources.push(\n ResourceUnit.fromPartial({\n resource: resources,\n count: svcdepl.count,\n price,\n }),\n );\n\n group.boundComputes[svcdepl.profile] = group.dgroup.resources.length - 1;\n } else {\n if (!resourceIds.has(profileKey)) {\n resourceIds.set(profileKey, group.dgroup.resources[location].resource!.id);\n }\n\n group.dgroup.resources[location].count += svcdepl.count;\n group.dgroup.resources[location].resource!.endpoints.push(\n ...buildServiceEndpoints(service, endpointSequenceNumbers),\n );\n }\n }\n }\n\n for (const group of groupsMap.values()) {\n for (const resourceUnit of group.dgroup.resources) {\n resourceUnit.resource!.endpoints.sort(\n (a, b) => a.kind - b.kind || a.sequenceNumber - b.sequenceNumber,\n );\n }\n }\n\n const sortedGroupNames = [...groupsMap.keys()].sort();\n let groups: Group[] | undefined;\n let groupSpecs: GroupSpec[] | undefined;\n let reclamation: DeploymentReclamation | undefined;\n\n const manifest = {\n // reclamation is a `MsgCreateDeployment` field, not a manifest group, and is\n // not needed in every call \u2014 so it's lazy like `groups`/`groupSpecs`.\n // `validateSDL` (run above) already guaranteed `min_window` is valid, so\n // `minWindowToDuration` never throws here.\n get reclamation() {\n if (sdl.reclamation && !reclamation) {\n reclamation = DeploymentReclamation.fromPartial({\n minWindow: minWindowToDuration(sdl.reclamation.min_window),\n });\n }\n return reclamation;\n },\n get groups() {\n groups ??= sortedGroupNames.map((placementName) => {\n const deployments = deploymentsByPlacement.get(placementName)!;\n\n return Group.fromPartial({\n name: placementName,\n services: deployments.map(([svcName]) => {\n const service = sdl.services[svcName];\n const deployment = sdl.deployment[svcName][placementName];\n const compute = sdl.profiles.compute[deployment.profile];\n const resourceId = resourceIds.get(`${placementName}:${deployment.profile}`) || 1;\n\n return buildManifestService(\n resourceId,\n svcName,\n service,\n compute,\n deployment.count,\n endpointSequenceNumbers,\n );\n }),\n });\n });\n return groups;\n },\n get groupSpecs() {\n groupSpecs ??= sortedGroupNames.map((name) => groupsMap.get(name)!.dgroup);\n return groupSpecs;\n },\n };\n\n return { ok: true, value: manifest };\n}\n\nfunction buildResources(\n id: number,\n compute: SDLCompute,\n service: SDLService,\n endpointSequenceNumbers: Record<string, number>,\n): Resources {\n const res = compute.resources;\n const cpuAttributes = buildResourceAttributes(res.cpu.attributes);\n const gpuAttributes = res.gpu?.attributes ? transformGpuAttributes(res.gpu.attributes) : [];\n\n return Resources.fromPartial({\n id,\n cpu: CPU.fromPartial({\n units: { val: encodeResourceValue(parseCpuUnits(res.cpu)) },\n attributes: cpuAttributes,\n }),\n memory: Memory.fromPartial({\n quantity: { val: encodeResourceValue(parseMemoryBytes(res.memory)) },\n }),\n storage: castArray(res.storage).map((s) =>\n Storage.fromPartial({\n name: s.name || \"default\",\n quantity: { val: encodeResourceValue(parseStorageBytes(s.size)) },\n attributes: buildStorageAttributes(s.attributes),\n }),\n ),\n gpu: GPU.fromPartial({\n units: { val: encodeResourceValue(parseGpuUnits(res.gpu)) },\n attributes: gpuAttributes,\n }),\n endpoints: buildServiceEndpoints(service, endpointSequenceNumbers),\n });\n}\n\nfunction buildManifestService(\n resourceId: number,\n name: string,\n service: SDLService,\n compute: SDLCompute,\n count: number,\n endpointSequenceNumbers: Record<string, number>,\n): Service {\n const credentials = service.credentials\n ? ImageCredentials.fromPartial({\n host: service.credentials.host,\n email: service.credentials.email || \"\",\n username: service.credentials.username,\n password: service.credentials.password,\n })\n : undefined;\n\n const params = buildParams(service);\n\n return Service.fromPartial({\n name,\n image: service.image,\n command: service.command || [],\n args: service.args || [],\n env: service.env || [],\n resources: buildResources(resourceId, compute, service, endpointSequenceNumbers),\n count,\n expose: buildManifestExpose(service, endpointSequenceNumbers),\n params,\n credentials,\n });\n}\n\nfunction buildParams(service: SDLService): ServiceParams | undefined {\n if (!service.params) return undefined;\n\n const storage = service.params.storage || {};\n const storageNames = service.params.storage ? Object.keys(storage).sort() : [];\n const result = ServiceParams.fromPartial({\n storage: storageNames.map((name) => {\n const config = storage[name];\n return StorageParams.fromPartial({\n name,\n mount: config.mount || \"\",\n readOnly: config.readOnly || false,\n });\n }),\n });\n\n // Permissions are not in the protobuf type but need to be preserved\n if (service.params.permissions) {\n (result as unknown as Record<string, unknown>).permissions = service.params.permissions;\n }\n\n // Project TEE onto the manifest, mirroring Go's groupBuilder\n // (params.TEE = {Type, Attestation: true}). `attestation` is hard-coded true\n // (not an input knob); the provider injects the attestation sidecar.\n if (service.params.tee) {\n result.tee = TEEParams.fromPartial({ type: service.params.tee, attestation: true });\n }\n\n return result;\n}\n\nfunction buildManifestExpose(\n service: SDLService,\n endpointSequenceNumbers: Record<string, number>,\n): ServiceExpose[] {\n return (service.expose ?? [])\n .flatMap((expose) =>\n (expose.to ?? []).map((to) =>\n ServiceExpose.fromPartial({\n port: expose.port,\n externalPort: expose.as,\n proto: parseServiceProto(expose.proto),\n service: to.service || \"\",\n global: to.global || false,\n hosts: expose.accept || [],\n httpOptions: buildHttpOptions(expose.http_options),\n ip: to.ip || \"\",\n endpointSequenceNumber: endpointSequenceNumbers[to.ip!],\n }),\n ),\n )\n .sort((a, b) => {\n if (a.service !== b.service) return a.service.localeCompare(b.service);\n if (a.port !== b.port) return a.port - b.port;\n if (a.proto !== b.proto) return a.proto.localeCompare(b.proto);\n if (a.global !== b.global) return a.global ? -1 : 1;\n return 0;\n });\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -35,7 +35,7 @@ module.exports = __toCommonJS(generateManifestVersion_exports);
35
35
  var import_json_stable_stringify = __toESM(require("json-stable-stringify"), 1);
36
36
  const decoder = new TextDecoder();
37
37
  const encoder = new TextEncoder();
38
- const NULLABLE_MANIFEST_KEYS = /* @__PURE__ */ new Set(["command", "args", "env", "hosts"]);
38
+ const NULLABLE_MANIFEST_KEYS = /* @__PURE__ */ new Set(["command", "args", "env", "hosts", "storage"]);
39
39
  const OMITTED_MANIFEST_KEYS = /* @__PURE__ */ new Set(["kind", "attributes"]);
40
40
  async function generateManifestVersion(manifest) {
41
41
  const jsonStr = manifestToSortedJSON(manifest);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/sdl/manifest/generateManifestVersion.ts"],
4
- "sourcesContent": ["import { default as stableStringify } from \"json-stable-stringify\";\n\nimport type { GenerateManifestOkResult, Manifest } from \"./generateManifest.ts\";\n\nconst decoder = new TextDecoder();\nconst encoder = new TextEncoder();\nconst NULLABLE_MANIFEST_KEYS = new Set([\"command\", \"args\", \"env\", \"hosts\"]);\nconst OMITTED_MANIFEST_KEYS = new Set([\"kind\", \"attributes\"]);\n\nexport async function generateManifestVersion(manifest: Manifest): Promise<Uint8Array> {\n const jsonStr = manifestToSortedJSON(manifest);\n const sortedBytes = encoder.encode(jsonStr);\n const sum = await crypto.subtle.digest(\"SHA-256\", sortedBytes);\n return new Uint8Array(sum);\n}\n\nexport function manifestToSortedJSON(manifest: Manifest | GenerateManifestOkResult[\"groupSpecs\"]): string {\n const json = stableStringify(manifest, { replacer: manifestReplacer }) || \"\";\n return escapeHtml(renameFields(json));\n}\n\nfunction manifestReplacer(this: unknown, key: string | number, value: unknown): unknown {\n if (value && value instanceof Uint8Array) {\n return decoder.decode(value);\n }\n\n if (typeof key !== \"string\") {\n return value;\n }\n\n // only top-level \"credentials\" field can be null, credentials in params should be omitted\n if (typeof this === \"object\" && this && Object.hasOwn(this, \"command\") && key === \"credentials\" && value == null) {\n return null;\n }\n\n if (NULLABLE_MANIFEST_KEYS.has(key) && ((Array.isArray(value) && value.length === 0) || value == null)) {\n return null;\n }\n\n if (OMITTED_MANIFEST_KEYS.has(key) && ((Array.isArray(value) && value.length === 0) || value === 0)) {\n return undefined;\n }\n\n return value;\n}\n\nconst MANIFEST_VERSION_FIELD_MAPPING: Record<string, string> = { quantity: \"size\", sequenceNumber: \"sequence_number\" };\nconst MANIFEST_VERSION_FIELD_REGEX = new RegExp(`\"(${Object.keys(MANIFEST_VERSION_FIELD_MAPPING).join(\"|\")})\":`, \"g\");\nfunction renameFields(jsonStr: string): string {\n MANIFEST_VERSION_FIELD_REGEX.lastIndex = 0; // reset regex state\n return jsonStr.replace(MANIFEST_VERSION_FIELD_REGEX, (_, field) => `\"${MANIFEST_VERSION_FIELD_MAPPING[field]}\":`);\n}\n\nconst htmlEscapes: Record<string, string> = {\n \"<\": \"\\\\u003c\",\n \">\": \"\\\\u003e\",\n \"&\": \"\\\\u0026\",\n};\n\nconst HTML_SPECIAL_CHARS_REGEX = new RegExp(`[${Object.keys(htmlEscapes).join(\"\")}]`, \"g\");\nfunction escapeHtml(raw: string): string {\n HTML_SPECIAL_CHARS_REGEX.lastIndex = 0; // reset regex state\n return raw.replace(HTML_SPECIAL_CHARS_REGEX, (ch) => htmlEscapes[ch]);\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCAA2C;AAI3C,MAAM,UAAU,IAAI,YAAY;AAChC,MAAM,UAAU,IAAI,YAAY;AAChC,MAAM,yBAAyB,oBAAI,IAAI,CAAC,WAAW,QAAQ,OAAO,OAAO,CAAC;AAC1E,MAAM,wBAAwB,oBAAI,IAAI,CAAC,QAAQ,YAAY,CAAC;AAE5D,eAAsB,wBAAwB,UAAyC;AACrF,QAAM,UAAU,qBAAqB,QAAQ;AAC7C,QAAM,cAAc,QAAQ,OAAO,OAAO;AAC1C,QAAM,MAAM,MAAM,OAAO,OAAO,OAAO,WAAW,WAAW;AAC7D,SAAO,IAAI,WAAW,GAAG;AAC3B;AAEO,SAAS,qBAAqB,UAAqE;AACxG,QAAM,WAAO,6BAAAA,SAAgB,UAAU,EAAE,UAAU,iBAAiB,CAAC,KAAK;AAC1E,SAAO,WAAW,aAAa,IAAI,CAAC;AACtC;AAEA,SAAS,iBAAgC,KAAsB,OAAyB;AACtF,MAAI,SAAS,iBAAiB,YAAY;AACxC,WAAO,QAAQ,OAAO,KAAK;AAAA,EAC7B;AAEA,MAAI,OAAO,QAAQ,UAAU;AAC3B,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,SAAS,YAAY,QAAQ,OAAO,OAAO,MAAM,SAAS,KAAK,QAAQ,iBAAiB,SAAS,MAAM;AAChH,WAAO;AAAA,EACT;AAEA,MAAI,uBAAuB,IAAI,GAAG,MAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,KAAM,SAAS,OAAO;AACtG,WAAO;AAAA,EACT;AAEA,MAAI,sBAAsB,IAAI,GAAG,MAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,KAAM,UAAU,IAAI;AACnG,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,MAAM,iCAAyD,EAAE,UAAU,QAAQ,gBAAgB,kBAAkB;AACrH,MAAM,+BAA+B,IAAI,OAAO,KAAK,OAAO,KAAK,8BAA8B,EAAE,KAAK,GAAG,CAAC,OAAO,GAAG;AACpH,SAAS,aAAa,SAAyB;AAC7C,+BAA6B,YAAY;AACzC,SAAO,QAAQ,QAAQ,8BAA8B,CAAC,GAAG,UAAU,IAAI,+BAA+B,KAAK,CAAC,IAAI;AAClH;AAEA,MAAM,cAAsC;AAAA,EAC1C,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;AAEA,MAAM,2BAA2B,IAAI,OAAO,IAAI,OAAO,KAAK,WAAW,EAAE,KAAK,EAAE,CAAC,KAAK,GAAG;AACzF,SAAS,WAAW,KAAqB;AACvC,2BAAyB,YAAY;AACrC,SAAO,IAAI,QAAQ,0BAA0B,CAAC,OAAO,YAAY,EAAE,CAAC;AACtE;",
4
+ "sourcesContent": ["import { default as stableStringify } from \"json-stable-stringify\";\n\nimport type { GenerateManifestOkResult, Manifest } from \"./generateManifest.ts\";\n\nconst decoder = new TextDecoder();\nconst encoder = new TextEncoder();\n// Go marshals nil slices as `null`, so empty manifest arrays must serialize to\n// `null` to stay byte-compatible with the Go SDK's manifest. `storage` covers\n// `params.storage` when a service sets other params (e.g. `tee`) but no storage;\n// resource-level storage is schema-required and never empty, so it is unaffected.\nconst NULLABLE_MANIFEST_KEYS = new Set([\"command\", \"args\", \"env\", \"hosts\", \"storage\"]);\nconst OMITTED_MANIFEST_KEYS = new Set([\"kind\", \"attributes\"]);\n\nexport async function generateManifestVersion(manifest: Manifest): Promise<Uint8Array> {\n const jsonStr = manifestToSortedJSON(manifest);\n const sortedBytes = encoder.encode(jsonStr);\n const sum = await crypto.subtle.digest(\"SHA-256\", sortedBytes);\n return new Uint8Array(sum);\n}\n\nexport function manifestToSortedJSON(manifest: Manifest | GenerateManifestOkResult[\"groupSpecs\"]): string {\n const json = stableStringify(manifest, { replacer: manifestReplacer }) || \"\";\n return escapeHtml(renameFields(json));\n}\n\nfunction manifestReplacer(this: unknown, key: string | number, value: unknown): unknown {\n if (value && value instanceof Uint8Array) {\n return decoder.decode(value);\n }\n\n if (typeof key !== \"string\") {\n return value;\n }\n\n // only top-level \"credentials\" field can be null, credentials in params should be omitted\n if (typeof this === \"object\" && this && Object.hasOwn(this, \"command\") && key === \"credentials\" && value == null) {\n return null;\n }\n\n if (NULLABLE_MANIFEST_KEYS.has(key) && ((Array.isArray(value) && value.length === 0) || value == null)) {\n return null;\n }\n\n if (OMITTED_MANIFEST_KEYS.has(key) && ((Array.isArray(value) && value.length === 0) || value === 0)) {\n return undefined;\n }\n\n return value;\n}\n\nconst MANIFEST_VERSION_FIELD_MAPPING: Record<string, string> = { quantity: \"size\", sequenceNumber: \"sequence_number\" };\nconst MANIFEST_VERSION_FIELD_REGEX = new RegExp(`\"(${Object.keys(MANIFEST_VERSION_FIELD_MAPPING).join(\"|\")})\":`, \"g\");\nfunction renameFields(jsonStr: string): string {\n MANIFEST_VERSION_FIELD_REGEX.lastIndex = 0; // reset regex state\n return jsonStr.replace(MANIFEST_VERSION_FIELD_REGEX, (_, field) => `\"${MANIFEST_VERSION_FIELD_MAPPING[field]}\":`);\n}\n\nconst htmlEscapes: Record<string, string> = {\n \"<\": \"\\\\u003c\",\n \">\": \"\\\\u003e\",\n \"&\": \"\\\\u0026\",\n};\n\nconst HTML_SPECIAL_CHARS_REGEX = new RegExp(`[${Object.keys(htmlEscapes).join(\"\")}]`, \"g\");\nfunction escapeHtml(raw: string): string {\n HTML_SPECIAL_CHARS_REGEX.lastIndex = 0; // reset regex state\n return raw.replace(HTML_SPECIAL_CHARS_REGEX, (ch) => htmlEscapes[ch]);\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCAA2C;AAI3C,MAAM,UAAU,IAAI,YAAY;AAChC,MAAM,UAAU,IAAI,YAAY;AAKhC,MAAM,yBAAyB,oBAAI,IAAI,CAAC,WAAW,QAAQ,OAAO,SAAS,SAAS,CAAC;AACrF,MAAM,wBAAwB,oBAAI,IAAI,CAAC,QAAQ,YAAY,CAAC;AAE5D,eAAsB,wBAAwB,UAAyC;AACrF,QAAM,UAAU,qBAAqB,QAAQ;AAC7C,QAAM,cAAc,QAAQ,OAAO,OAAO;AAC1C,QAAM,MAAM,MAAM,OAAO,OAAO,OAAO,WAAW,WAAW;AAC7D,SAAO,IAAI,WAAW,GAAG;AAC3B;AAEO,SAAS,qBAAqB,UAAqE;AACxG,QAAM,WAAO,6BAAAA,SAAgB,UAAU,EAAE,UAAU,iBAAiB,CAAC,KAAK;AAC1E,SAAO,WAAW,aAAa,IAAI,CAAC;AACtC;AAEA,SAAS,iBAAgC,KAAsB,OAAyB;AACtF,MAAI,SAAS,iBAAiB,YAAY;AACxC,WAAO,QAAQ,OAAO,KAAK;AAAA,EAC7B;AAEA,MAAI,OAAO,QAAQ,UAAU;AAC3B,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,SAAS,YAAY,QAAQ,OAAO,OAAO,MAAM,SAAS,KAAK,QAAQ,iBAAiB,SAAS,MAAM;AAChH,WAAO;AAAA,EACT;AAEA,MAAI,uBAAuB,IAAI,GAAG,MAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,KAAM,SAAS,OAAO;AACtG,WAAO;AAAA,EACT;AAEA,MAAI,sBAAsB,IAAI,GAAG,MAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,KAAM,UAAU,IAAI;AACnG,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,MAAM,iCAAyD,EAAE,UAAU,QAAQ,gBAAgB,kBAAkB;AACrH,MAAM,+BAA+B,IAAI,OAAO,KAAK,OAAO,KAAK,8BAA8B,EAAE,KAAK,GAAG,CAAC,OAAO,GAAG;AACpH,SAAS,aAAa,SAAyB;AAC7C,+BAA6B,YAAY;AACzC,SAAO,QAAQ,QAAQ,8BAA8B,CAAC,GAAG,UAAU,IAAI,+BAA+B,KAAK,CAAC,IAAI;AAClH;AAEA,MAAM,cAAsC;AAAA,EAC1C,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;AAEA,MAAM,2BAA2B,IAAI,OAAO,IAAI,OAAO,KAAK,WAAW,EAAE,KAAK,EAAE,CAAC,KAAK,GAAG;AACzF,SAAS,WAAW,KAAqB;AACvC,2BAAyB,YAAY;AACrC,SAAO,IAAI,QAAQ,0BAA0B,CAAC,OAAO,YAAY,EAAE,CAAC;AACtE;",
6
6
  "names": ["stableStringify"]
7
7
  }
@@ -33,7 +33,7 @@ module.exports = __toCommonJS(validateSDL_exports);
33
33
  var import_jsonSchemaValidation = require("../../utils/jsonSchemaValidation.cjs");
34
34
  var import_utils = require("../utils.cjs");
35
35
  var import_validateSDLInput = require("./validateSDLInput.cjs");
36
- var _endpointsUsed, _portsUsed, _sdl, _errors, _SDLValidator_instances, validateDeploymentWithRelations_fn, validateDeploymentRelations_fn, validateServiceStorages_fn, validateStorages_fn, validateGPU_fn, validateLeaseIP_fn, validateEndpoints_fn;
36
+ var _endpointsUsed, _portsUsed, _sdl, _errors, _SDLValidator_instances, validateDeploymentWithRelations_fn, validateDeploymentRelations_fn, validateServiceStorages_fn, validateStorages_fn, validateGPU_fn, validateTEE_fn, validateLeaseIP_fn, validateEndpoints_fn;
37
37
  const ERROR_MESSAGES = {
38
38
  "#/definitions/storageRamClassMustNotBePersistent"(error) {
39
39
  return `"ram" storage${(0, import_jsonSchemaValidation.getErrorLocation)((0, import_jsonSchemaValidation.dirname)(error.instancePath))} cannot be persistent`;
@@ -101,6 +101,7 @@ validateDeploymentWithRelations_fn = function(serviceName) {
101
101
  __privateMethod(this, _SDLValidator_instances, validateServiceStorages_fn).call(this, serviceName, deploymentName);
102
102
  __privateMethod(this, _SDLValidator_instances, validateStorages_fn).call(this, serviceName, deploymentName);
103
103
  __privateMethod(this, _SDLValidator_instances, validateGPU_fn).call(this, serviceName, deploymentName);
104
+ __privateMethod(this, _SDLValidator_instances, validateTEE_fn).call(this, serviceName, deploymentName);
104
105
  });
105
106
  };
106
107
  validateDeploymentRelations_fn = function(serviceName, deploymentName) {
@@ -267,6 +268,28 @@ validateGPU_fn = function(serviceName, deploymentName) {
267
268
  });
268
269
  }
269
270
  };
271
+ // Mirrors Go `validateTEEWithGPU` (go/sdl/tee.go): the `cpu-gpu` TEE type
272
+ // requires GPU resources on the resolved compute profile. `cpu` (and absent)
273
+ // need no GPU. Unsupported tee values are rejected structurally by the input
274
+ // schema (`tee` enum in validateSDLInput.ts) before this runs.
275
+ validateTEE_fn = function(serviceName, deploymentName) {
276
+ const tee = __privateGet(this, _sdl).services?.[serviceName]?.params?.tee;
277
+ if (tee !== "cpu-gpu") return;
278
+ const profile = __privateGet(this, _sdl).deployment[serviceName]?.[deploymentName]?.profile;
279
+ const gpu = __privateGet(this, _sdl).profiles?.compute?.[profile]?.resources.gpu;
280
+ const hasGpu = gpu?.units !== void 0 && gpu.units !== 0;
281
+ if (!hasGpu) {
282
+ __privateGet(this, _errors).push({
283
+ message: `Service "${serviceName}" tee type requires gpu resources.`,
284
+ instancePath: `/services/${serviceName}/params/tee`,
285
+ schemaPath: "#/properties/services/additionalProperties/properties/params/properties/tee",
286
+ keyword: "required",
287
+ params: {
288
+ missingProperty: "gpu"
289
+ }
290
+ });
291
+ }
292
+ };
270
293
  validateLeaseIP_fn = function(serviceName) {
271
294
  __privateGet(this, _sdl).services?.[serviceName]?.expose?.forEach((expose, exposeIndex) => {
272
295
  const proto = expose.proto?.toUpperCase() || "TCP";
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/sdl/validateSDL/validateSDL.ts"],
4
- "sourcesContent": ["import type { ErrorMessages, ValidationError, ValidationFunction } from \"../../utils/jsonSchemaValidation.ts\";\nimport { dirname, getErrorLocation, humanizeErrors } from \"../../utils/jsonSchemaValidation.ts\";\nimport { castArray, stringToBoolean } from \"../utils.ts\";\nimport { schema as validationSDLSchema, type SDLInput, validate as validateSDLInput } from \"./validateSDLInput.ts\";\n\nexport { validationSDLSchema };\nexport type { SDLInput };\n\nconst ERROR_MESSAGES: ErrorMessages = {\n \"#/definitions/storageRamClassMustNotBePersistent\"(error) {\n return `\"ram\" storage${getErrorLocation(dirname(error.instancePath))} cannot be persistent`;\n },\n \"#/definitions/exposeToWithIpEnforcesGlobal\"() {\n return `If an IP is declared, the directive must be declared as global.`;\n },\n // Mirrors the shared schema's `min_window` pattern (`^[1-9][0-9]*(s|m|h)$`).\n // Go stays the lenient layer (`go/sdl/reclamation.go` accepts any `> 0`\n // `time.ParseDuration`), so this is a sanctioned schema-only-stricter rule.\n \"#/properties/reclamation/properties/min_window/pattern\"() {\n return `Reclamation min_window must be a whole number followed by s, m, or h (e.g. \"24h\", \"30m\").`;\n },\n};\n\nexport function validateSDL(sdl: SDLInput): undefined | ValidationError[] {\n validateSDLInput(sdl);\n const schemaErrors = humanizeErrors((validateSDLInput as ValidationFunction).errors, validationSDLSchema, ERROR_MESSAGES);\n if (schemaErrors.length) return schemaErrors;\n\n const validator = new SDLValidator(sdl);\n const errors = validator.validate();\n\n const allErrors = schemaErrors.concat(errors);\n return allErrors.length ? allErrors : undefined;\n}\n\nclass SDLValidator {\n readonly #endpointsUsed = new Set<string>();\n readonly #portsUsed = new Map<string, string>();\n readonly #sdl: SDLInput;\n readonly #errors: ValidationError[] = [];\n\n constructor(sdl: SDLInput) {\n this.#sdl = sdl;\n }\n\n validate() {\n if (this.#sdl.services) {\n Object.keys(this.#sdl.services).forEach((serviceName) => {\n this.#validateDeploymentWithRelations(serviceName);\n this.#validateLeaseIP(serviceName);\n });\n }\n\n this.#validateEndpoints();\n return this.#errors;\n }\n\n #validateDeploymentWithRelations(serviceName: string) {\n const deployment = this.#sdl.deployment[serviceName];\n if (!deployment) {\n this.#errors.push({\n message: `Service \"${serviceName}\" is not defined at \"/deployment\" section.`,\n instancePath: `/deployment`,\n schemaPath: \"#/properties/deployment\",\n keyword: \"required\",\n params: {\n missingProperty: serviceName,\n },\n });\n return;\n }\n\n Object.keys(this.#sdl.deployment[serviceName]).forEach((deploymentName) => {\n this.#validateDeploymentRelations(serviceName, deploymentName);\n this.#validateServiceStorages(serviceName, deploymentName);\n this.#validateStorages(serviceName, deploymentName);\n this.#validateGPU(serviceName, deploymentName);\n });\n }\n\n #validateDeploymentRelations(serviceName: string, deploymentName: string) {\n const serviceDeployment = this.#sdl.deployment?.[serviceName]?.[deploymentName];\n const compute = this.#sdl.profiles?.compute?.[serviceDeployment?.profile];\n const infra = this.#sdl.profiles?.placement?.[deploymentName];\n\n if (!infra) {\n this.#errors.push({\n message: `The placement \"${deploymentName}\" is not defined in the \"placement\" section.`,\n instancePath: `/profiles/placement`,\n schemaPath: \"#/properties/profiles/properties/placement\",\n keyword: \"required\",\n params: {\n missingProperty: deploymentName,\n },\n });\n }\n\n if (infra && !infra.pricing?.[serviceDeployment?.profile]) {\n this.#errors.push({\n message: `The pricing for the \"${serviceDeployment?.profile}\" profile is not defined in the \"${deploymentName}\" placement.`,\n instancePath: `/profiles/placement/${deploymentName}/pricing`,\n schemaPath: \"#/properties/profiles/properties/placement/additionalProperties/properties/pricing\",\n keyword: \"required\",\n params: {\n missingProperty: serviceDeployment?.profile,\n },\n });\n }\n\n if (!compute) {\n this.#errors.push({\n message: `The compute requirements for the \"${serviceDeployment?.profile}\" profile are not defined in the \"compute\" section.`,\n instancePath: `/profiles/compute`,\n schemaPath: \"#/properties/profiles/properties/compute\",\n keyword: \"required\",\n params: {\n missingProperty: serviceDeployment?.profile,\n },\n });\n }\n }\n\n #validateServiceStorages(serviceName: string, deploymentName: string) {\n const service = this.#sdl.services?.[serviceName];\n const mounts: Record<string, string> = {};\n const serviceDeployment = this.#sdl.deployment[serviceName][deploymentName];\n const compute = this.#sdl.profiles?.compute?.[serviceDeployment.profile];\n const storages = castArray(compute?.resources.storage);\n\n if (!service?.params?.storage) {\n return;\n }\n\n Object.entries(service.params.storage).forEach(([storageName, storage]) => {\n if (!storage) {\n this.#errors.push({\n message: `Storage \"${storageName}\" is not configured.`,\n instancePath: `/services/${serviceName}/params/storage/${storageName}`,\n schemaPath: \"#/properties/services/additionalProperties/properties/params/properties/storage/additionalProperties\",\n keyword: \"required\",\n params: {\n missingProperty: storageName,\n },\n });\n return;\n }\n const storageNameExists = storages.some(({ name }) => name === storageName);\n if (!storageNameExists) {\n this.#errors.push({\n message: `Service \"${serviceName}\" references non-existing compute volume \"${storageName}\".`,\n instancePath: `/profiles/compute/${serviceDeployment.profile}/resources/storage`,\n schemaPath: \"#/properties/profiles/properties/compute/additionalProperties/properties/resources/properties/storage\",\n keyword: \"required\",\n params: {\n missingProperty: storageName,\n },\n });\n return;\n }\n\n const mount = String(storage.mount);\n const volumeName = mounts[mount];\n\n if (volumeName && !storage.mount) {\n this.#errors.push({\n message: \"Multiple root ephemeral storages are not allowed.\",\n instancePath: `/services/${serviceName}/params/storage/${storageName}`,\n schemaPath: \"#/properties/services/additionalProperties/properties/params/properties/storage\",\n keyword: \"uniqueItems\",\n params: {\n duplicate: volumeName,\n },\n });\n }\n if (volumeName && storage.mount) {\n this.#errors.push({\n message: `Mount \"${mount}\" already in use by volume \"${volumeName}\".`,\n instancePath: `/services/${serviceName}/params/storage/${storageName}/mount`,\n schemaPath: \"#/properties/services/additionalProperties/properties/params/properties/storage/additionalProperties/properties/mount\",\n keyword: \"uniqueItems\",\n params: {\n duplicate: mount,\n },\n });\n }\n\n mounts[mount] = storageName;\n });\n }\n\n #validateStorages(serviceName: string, deploymentName: string) {\n const service = this.#sdl.services?.[serviceName];\n const serviceDeployment = this.#sdl.deployment[serviceName][deploymentName];\n const compute = this.#sdl.profiles?.compute?.[serviceDeployment.profile];\n const storages = castArray(compute?.resources.storage);\n\n storages.forEach((storage) => {\n const persistent = stringToBoolean(storage.attributes?.persistent as string | boolean || false);\n\n if (persistent && !service?.params?.storage?.[storage.name || \"\"]?.mount) {\n this.#errors.push({\n message: `Persistent storage \"${storage.name || \"default\"}\" requires a mount path in /services/${serviceName}/params/storage/${storage.name || \"default\"}/mount.`,\n instancePath: `/services/${serviceName}/params/storage/${storage.name || \"default\"}`,\n schemaPath: \"#/properties/services/additionalProperties/properties/params/properties/storage/additionalProperties/properties/mount\",\n keyword: \"required\",\n params: {\n missingProperty: \"mount\",\n },\n });\n }\n });\n }\n\n #validateGPU(serviceName: string, deploymentName: string) {\n const deployment = this.#sdl.deployment[serviceName];\n const compute = this.#sdl.profiles?.compute?.[deployment[deploymentName]?.profile];\n const gpu = compute?.resources.gpu;\n if (!gpu) return;\n\n const hasUnits = gpu.units !== undefined && gpu.units !== 0;\n const hasAttributes = typeof gpu.attributes !== \"undefined\";\n const hasVendor = hasAttributes && typeof gpu.attributes?.vendor !== \"undefined\";\n\n const profile = deployment[deploymentName]?.profile;\n const gpuPath = `/profiles/compute/${profile}/resources/gpu`;\n\n if (!hasUnits && hasAttributes) {\n this.#errors.push({\n message: \"GPU must not have attributes if units is 0.\",\n instancePath: `${gpuPath}/attributes`,\n schemaPath: \"#/properties/profiles/properties/compute/additionalProperties/properties/resources/properties/gpu/properties/attributes\",\n keyword: \"additionalProperties\",\n params: {\n additionalProperty: \"attributes\",\n },\n });\n }\n if (hasUnits && !hasAttributes) {\n this.#errors.push({\n message: \"GPU must have attributes if units is not 0.\",\n instancePath: gpuPath,\n schemaPath: \"#/properties/profiles/properties/compute/additionalProperties/properties/resources/properties/gpu\",\n keyword: \"required\",\n params: {\n missingProperty: \"attributes\",\n },\n });\n }\n if (hasUnits && !hasVendor) {\n this.#errors.push({\n message: \"GPU must specify a vendor if units is not 0.\",\n instancePath: `${gpuPath}/attributes`,\n schemaPath: \"#/properties/profiles/properties/compute/additionalProperties/properties/resources/properties/gpu/properties/attributes/properties/vendor\",\n keyword: \"required\",\n params: {\n missingProperty: \"vendor\",\n },\n });\n }\n }\n\n #validateLeaseIP(serviceName: string) {\n this.#sdl.services?.[serviceName]?.expose?.forEach((expose, exposeIndex) => {\n const proto = expose.proto?.toUpperCase() || \"TCP\";\n\n expose.to?.forEach((to, toIndex) => {\n if (to.ip?.length) {\n const toPath = `/services/${serviceName}/expose/${exposeIndex}/to/${toIndex}`;\n\n if (!to.global) {\n this.#errors.push({\n message: `If an IP is declared, the directive must be declared as global.`,\n instancePath: `${toPath}/global`,\n schemaPath: \"#/definitions/exposeToWithIpEnforcesGlobal/then/properties/global/const\",\n keyword: \"const\",\n params: {\n allowedValue: true,\n },\n });\n }\n if (!this.#sdl.endpoints?.[to.ip]) {\n this.#errors.push({\n message: `Unknown endpoint \"${to.ip}\" for service \"${serviceName}\". Add it to the \"endpoints\" section.`,\n instancePath: `/endpoints/${to.ip}`,\n schemaPath: \"#/properties/endpoints\",\n keyword: \"required\",\n params: {\n missingProperty: to.ip,\n },\n });\n }\n\n this.#endpointsUsed.add(to.ip);\n\n const externalPort = expose.as ?? expose.port;\n const portKey = `${to.ip}-${externalPort}-${proto}`;\n const otherServiceName = this.#portsUsed.get(portKey);\n\n if (this.#portsUsed.has(portKey)) {\n this.#errors.push({\n message: `IP endpoint \"${to.ip}\" port ${externalPort} protocol ${proto} already in use by service \"${otherServiceName}\".`,\n instancePath: `${toPath}/ip`,\n schemaPath: \"#/properties/services/additionalProperties/properties/expose/items/properties/to/items\",\n keyword: \"uniqueItems\",\n params: {\n duplicate: portKey,\n },\n });\n }\n this.#portsUsed.set(portKey, serviceName);\n }\n });\n });\n }\n\n #validateEndpoints() {\n if (!this.#sdl.endpoints) return;\n\n Object.keys(this.#sdl.endpoints).forEach((endpoint) => {\n if (!this.#endpointsUsed.has(endpoint)) {\n this.#errors.push({\n message: `Endpoint \"${endpoint}\" declared but never used.`,\n instancePath: `/endpoints/${endpoint}`,\n schemaPath: \"#/properties/endpoints\",\n keyword: \"additionalProperties\",\n params: {\n additionalProperty: endpoint,\n },\n });\n }\n });\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { ErrorMessages, ValidationError, ValidationFunction } from \"../../utils/jsonSchemaValidation.ts\";\nimport { dirname, getErrorLocation, humanizeErrors } from \"../../utils/jsonSchemaValidation.ts\";\nimport { castArray, stringToBoolean } from \"../utils.ts\";\nimport { schema as validationSDLSchema, type SDLInput, validate as validateSDLInput } from \"./validateSDLInput.ts\";\n\nexport { validationSDLSchema };\nexport type { SDLInput };\n\nconst ERROR_MESSAGES: ErrorMessages = {\n \"#/definitions/storageRamClassMustNotBePersistent\"(error) {\n return `\"ram\" storage${getErrorLocation(dirname(error.instancePath))} cannot be persistent`;\n },\n \"#/definitions/exposeToWithIpEnforcesGlobal\"() {\n return `If an IP is declared, the directive must be declared as global.`;\n },\n // Mirrors the shared schema's `min_window` pattern (`^[1-9][0-9]*(s|m|h)$`).\n // Go stays the lenient layer (`go/sdl/reclamation.go` accepts any `> 0`\n // `time.ParseDuration`), so this is a sanctioned schema-only-stricter rule.\n \"#/properties/reclamation/properties/min_window/pattern\"() {\n return `Reclamation min_window must be a whole number followed by s, m, or h (e.g. \"24h\", \"30m\").`;\n },\n};\n\nexport function validateSDL(sdl: SDLInput): undefined | ValidationError[] {\n validateSDLInput(sdl);\n const schemaErrors = humanizeErrors((validateSDLInput as ValidationFunction).errors, validationSDLSchema, ERROR_MESSAGES);\n if (schemaErrors.length) return schemaErrors;\n\n const validator = new SDLValidator(sdl);\n const errors = validator.validate();\n\n const allErrors = schemaErrors.concat(errors);\n return allErrors.length ? allErrors : undefined;\n}\n\nclass SDLValidator {\n readonly #endpointsUsed = new Set<string>();\n readonly #portsUsed = new Map<string, string>();\n readonly #sdl: SDLInput;\n readonly #errors: ValidationError[] = [];\n\n constructor(sdl: SDLInput) {\n this.#sdl = sdl;\n }\n\n validate() {\n if (this.#sdl.services) {\n Object.keys(this.#sdl.services).forEach((serviceName) => {\n this.#validateDeploymentWithRelations(serviceName);\n this.#validateLeaseIP(serviceName);\n });\n }\n\n this.#validateEndpoints();\n return this.#errors;\n }\n\n #validateDeploymentWithRelations(serviceName: string) {\n const deployment = this.#sdl.deployment[serviceName];\n if (!deployment) {\n this.#errors.push({\n message: `Service \"${serviceName}\" is not defined at \"/deployment\" section.`,\n instancePath: `/deployment`,\n schemaPath: \"#/properties/deployment\",\n keyword: \"required\",\n params: {\n missingProperty: serviceName,\n },\n });\n return;\n }\n\n Object.keys(this.#sdl.deployment[serviceName]).forEach((deploymentName) => {\n this.#validateDeploymentRelations(serviceName, deploymentName);\n this.#validateServiceStorages(serviceName, deploymentName);\n this.#validateStorages(serviceName, deploymentName);\n this.#validateGPU(serviceName, deploymentName);\n this.#validateTEE(serviceName, deploymentName);\n });\n }\n\n #validateDeploymentRelations(serviceName: string, deploymentName: string) {\n const serviceDeployment = this.#sdl.deployment?.[serviceName]?.[deploymentName];\n const compute = this.#sdl.profiles?.compute?.[serviceDeployment?.profile];\n const infra = this.#sdl.profiles?.placement?.[deploymentName];\n\n if (!infra) {\n this.#errors.push({\n message: `The placement \"${deploymentName}\" is not defined in the \"placement\" section.`,\n instancePath: `/profiles/placement`,\n schemaPath: \"#/properties/profiles/properties/placement\",\n keyword: \"required\",\n params: {\n missingProperty: deploymentName,\n },\n });\n }\n\n if (infra && !infra.pricing?.[serviceDeployment?.profile]) {\n this.#errors.push({\n message: `The pricing for the \"${serviceDeployment?.profile}\" profile is not defined in the \"${deploymentName}\" placement.`,\n instancePath: `/profiles/placement/${deploymentName}/pricing`,\n schemaPath: \"#/properties/profiles/properties/placement/additionalProperties/properties/pricing\",\n keyword: \"required\",\n params: {\n missingProperty: serviceDeployment?.profile,\n },\n });\n }\n\n if (!compute) {\n this.#errors.push({\n message: `The compute requirements for the \"${serviceDeployment?.profile}\" profile are not defined in the \"compute\" section.`,\n instancePath: `/profiles/compute`,\n schemaPath: \"#/properties/profiles/properties/compute\",\n keyword: \"required\",\n params: {\n missingProperty: serviceDeployment?.profile,\n },\n });\n }\n }\n\n #validateServiceStorages(serviceName: string, deploymentName: string) {\n const service = this.#sdl.services?.[serviceName];\n const mounts: Record<string, string> = {};\n const serviceDeployment = this.#sdl.deployment[serviceName][deploymentName];\n const compute = this.#sdl.profiles?.compute?.[serviceDeployment.profile];\n const storages = castArray(compute?.resources.storage);\n\n if (!service?.params?.storage) {\n return;\n }\n\n Object.entries(service.params.storage).forEach(([storageName, storage]) => {\n if (!storage) {\n this.#errors.push({\n message: `Storage \"${storageName}\" is not configured.`,\n instancePath: `/services/${serviceName}/params/storage/${storageName}`,\n schemaPath: \"#/properties/services/additionalProperties/properties/params/properties/storage/additionalProperties\",\n keyword: \"required\",\n params: {\n missingProperty: storageName,\n },\n });\n return;\n }\n const storageNameExists = storages.some(({ name }) => name === storageName);\n if (!storageNameExists) {\n this.#errors.push({\n message: `Service \"${serviceName}\" references non-existing compute volume \"${storageName}\".`,\n instancePath: `/profiles/compute/${serviceDeployment.profile}/resources/storage`,\n schemaPath: \"#/properties/profiles/properties/compute/additionalProperties/properties/resources/properties/storage\",\n keyword: \"required\",\n params: {\n missingProperty: storageName,\n },\n });\n return;\n }\n\n const mount = String(storage.mount);\n const volumeName = mounts[mount];\n\n if (volumeName && !storage.mount) {\n this.#errors.push({\n message: \"Multiple root ephemeral storages are not allowed.\",\n instancePath: `/services/${serviceName}/params/storage/${storageName}`,\n schemaPath: \"#/properties/services/additionalProperties/properties/params/properties/storage\",\n keyword: \"uniqueItems\",\n params: {\n duplicate: volumeName,\n },\n });\n }\n if (volumeName && storage.mount) {\n this.#errors.push({\n message: `Mount \"${mount}\" already in use by volume \"${volumeName}\".`,\n instancePath: `/services/${serviceName}/params/storage/${storageName}/mount`,\n schemaPath: \"#/properties/services/additionalProperties/properties/params/properties/storage/additionalProperties/properties/mount\",\n keyword: \"uniqueItems\",\n params: {\n duplicate: mount,\n },\n });\n }\n\n mounts[mount] = storageName;\n });\n }\n\n #validateStorages(serviceName: string, deploymentName: string) {\n const service = this.#sdl.services?.[serviceName];\n const serviceDeployment = this.#sdl.deployment[serviceName][deploymentName];\n const compute = this.#sdl.profiles?.compute?.[serviceDeployment.profile];\n const storages = castArray(compute?.resources.storage);\n\n storages.forEach((storage) => {\n const persistent = stringToBoolean(storage.attributes?.persistent as string | boolean || false);\n\n if (persistent && !service?.params?.storage?.[storage.name || \"\"]?.mount) {\n this.#errors.push({\n message: `Persistent storage \"${storage.name || \"default\"}\" requires a mount path in /services/${serviceName}/params/storage/${storage.name || \"default\"}/mount.`,\n instancePath: `/services/${serviceName}/params/storage/${storage.name || \"default\"}`,\n schemaPath: \"#/properties/services/additionalProperties/properties/params/properties/storage/additionalProperties/properties/mount\",\n keyword: \"required\",\n params: {\n missingProperty: \"mount\",\n },\n });\n }\n });\n }\n\n #validateGPU(serviceName: string, deploymentName: string) {\n const deployment = this.#sdl.deployment[serviceName];\n const compute = this.#sdl.profiles?.compute?.[deployment[deploymentName]?.profile];\n const gpu = compute?.resources.gpu;\n if (!gpu) return;\n\n const hasUnits = gpu.units !== undefined && gpu.units !== 0;\n const hasAttributes = typeof gpu.attributes !== \"undefined\";\n const hasVendor = hasAttributes && typeof gpu.attributes?.vendor !== \"undefined\";\n\n const profile = deployment[deploymentName]?.profile;\n const gpuPath = `/profiles/compute/${profile}/resources/gpu`;\n\n if (!hasUnits && hasAttributes) {\n this.#errors.push({\n message: \"GPU must not have attributes if units is 0.\",\n instancePath: `${gpuPath}/attributes`,\n schemaPath: \"#/properties/profiles/properties/compute/additionalProperties/properties/resources/properties/gpu/properties/attributes\",\n keyword: \"additionalProperties\",\n params: {\n additionalProperty: \"attributes\",\n },\n });\n }\n if (hasUnits && !hasAttributes) {\n this.#errors.push({\n message: \"GPU must have attributes if units is not 0.\",\n instancePath: gpuPath,\n schemaPath: \"#/properties/profiles/properties/compute/additionalProperties/properties/resources/properties/gpu\",\n keyword: \"required\",\n params: {\n missingProperty: \"attributes\",\n },\n });\n }\n if (hasUnits && !hasVendor) {\n this.#errors.push({\n message: \"GPU must specify a vendor if units is not 0.\",\n instancePath: `${gpuPath}/attributes`,\n schemaPath: \"#/properties/profiles/properties/compute/additionalProperties/properties/resources/properties/gpu/properties/attributes/properties/vendor\",\n keyword: \"required\",\n params: {\n missingProperty: \"vendor\",\n },\n });\n }\n }\n\n // Mirrors Go `validateTEEWithGPU` (go/sdl/tee.go): the `cpu-gpu` TEE type\n // requires GPU resources on the resolved compute profile. `cpu` (and absent)\n // need no GPU. Unsupported tee values are rejected structurally by the input\n // schema (`tee` enum in validateSDLInput.ts) before this runs.\n #validateTEE(serviceName: string, deploymentName: string) {\n const tee = this.#sdl.services?.[serviceName]?.params?.tee;\n if (tee !== \"cpu-gpu\") return;\n\n const profile = this.#sdl.deployment[serviceName]?.[deploymentName]?.profile;\n const gpu = this.#sdl.profiles?.compute?.[profile]?.resources.gpu;\n const hasGpu = gpu?.units !== undefined && gpu.units !== 0;\n\n if (!hasGpu) {\n this.#errors.push({\n message: `Service \"${serviceName}\" tee type requires gpu resources.`,\n instancePath: `/services/${serviceName}/params/tee`,\n schemaPath: \"#/properties/services/additionalProperties/properties/params/properties/tee\",\n keyword: \"required\",\n params: {\n missingProperty: \"gpu\",\n },\n });\n }\n }\n\n #validateLeaseIP(serviceName: string) {\n this.#sdl.services?.[serviceName]?.expose?.forEach((expose, exposeIndex) => {\n const proto = expose.proto?.toUpperCase() || \"TCP\";\n\n expose.to?.forEach((to, toIndex) => {\n if (to.ip?.length) {\n const toPath = `/services/${serviceName}/expose/${exposeIndex}/to/${toIndex}`;\n\n if (!to.global) {\n this.#errors.push({\n message: `If an IP is declared, the directive must be declared as global.`,\n instancePath: `${toPath}/global`,\n schemaPath: \"#/definitions/exposeToWithIpEnforcesGlobal/then/properties/global/const\",\n keyword: \"const\",\n params: {\n allowedValue: true,\n },\n });\n }\n if (!this.#sdl.endpoints?.[to.ip]) {\n this.#errors.push({\n message: `Unknown endpoint \"${to.ip}\" for service \"${serviceName}\". Add it to the \"endpoints\" section.`,\n instancePath: `/endpoints/${to.ip}`,\n schemaPath: \"#/properties/endpoints\",\n keyword: \"required\",\n params: {\n missingProperty: to.ip,\n },\n });\n }\n\n this.#endpointsUsed.add(to.ip);\n\n const externalPort = expose.as ?? expose.port;\n const portKey = `${to.ip}-${externalPort}-${proto}`;\n const otherServiceName = this.#portsUsed.get(portKey);\n\n if (this.#portsUsed.has(portKey)) {\n this.#errors.push({\n message: `IP endpoint \"${to.ip}\" port ${externalPort} protocol ${proto} already in use by service \"${otherServiceName}\".`,\n instancePath: `${toPath}/ip`,\n schemaPath: \"#/properties/services/additionalProperties/properties/expose/items/properties/to/items\",\n keyword: \"uniqueItems\",\n params: {\n duplicate: portKey,\n },\n });\n }\n this.#portsUsed.set(portKey, serviceName);\n }\n });\n });\n }\n\n #validateEndpoints() {\n if (!this.#sdl.endpoints) return;\n\n Object.keys(this.#sdl.endpoints).forEach((endpoint) => {\n if (!this.#endpointsUsed.has(endpoint)) {\n this.#errors.push({\n message: `Endpoint \"${endpoint}\" declared but never used.`,\n instancePath: `/endpoints/${endpoint}`,\n schemaPath: \"#/properties/endpoints\",\n keyword: \"additionalProperties\",\n params: {\n additionalProperty: endpoint,\n },\n });\n }\n });\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,qDAAAA;AAAA;AAAA;AACA,kCAA0D;AAC1D,mBAA2C;AAC3C,8BAA2F;AAH3F;AAQA,MAAM,iBAAgC;AAAA,EACpC,mDAAmD,OAAO;AACxD,WAAO,oBAAgB,kDAAiB,qCAAQ,MAAM,YAAY,CAAC,CAAC;AAAA,EACtE;AAAA,EACA,+CAA+C;AAC7C,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAIA,2DAA2D;AACzD,WAAO;AAAA,EACT;AACF;AAEO,SAAS,YAAY,KAA8C;AACxE,8BAAAC,UAAiB,GAAG;AACpB,QAAM,mBAAe,4CAAgB,wBAAAA,SAAwC,QAAQ,wBAAAC,QAAqB,cAAc;AACxH,MAAI,aAAa,OAAQ,QAAO;AAEhC,QAAM,YAAY,IAAI,aAAa,GAAG;AACtC,QAAM,SAAS,UAAU,SAAS;AAElC,QAAM,YAAY,aAAa,OAAO,MAAM;AAC5C,SAAO,UAAU,SAAS,YAAY;AACxC;AAEA,MAAM,aAAa;AAAA,EAMjB,YAAY,KAAe;AAN7B;AACE,uBAAS,gBAAiB,oBAAI,IAAY;AAC1C,uBAAS,YAAa,oBAAI,IAAoB;AAC9C,uBAAS;AACT,uBAAS,SAA6B,CAAC;AAGrC,uBAAK,MAAO;AAAA,EACd;AAAA,EAEA,WAAW;AACT,QAAI,mBAAK,MAAK,UAAU;AACtB,aAAO,KAAK,mBAAK,MAAK,QAAQ,EAAE,QAAQ,CAAC,gBAAgB;AACvD,8BAAK,6DAAL,WAAsC;AACtC,8BAAK,6CAAL,WAAsB;AAAA,MACxB,CAAC;AAAA,IACH;AAEA,0BAAK,+CAAL;AACA,WAAO,mBAAK;AAAA,EACd;AA+SF;AAlUW;AACA;AACA;AACA;AAJX;AAsBE,qCAAgC,SAAC,aAAqB;AACpD,QAAM,aAAa,mBAAK,MAAK,WAAW,WAAW;AACnD,MAAI,CAAC,YAAY;AACf,uBAAK,SAAQ,KAAK;AAAA,MAChB,SAAS,YAAY,WAAW;AAAA,MAChC,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,iBAAiB;AAAA,MACnB;AAAA,IACF,CAAC;AACD;AAAA,EACF;AAEA,SAAO,KAAK,mBAAK,MAAK,WAAW,WAAW,CAAC,EAAE,QAAQ,CAAC,mBAAmB;AACzE,0BAAK,yDAAL,WAAkC,aAAa;AAC/C,0BAAK,qDAAL,WAA8B,aAAa;AAC3C,0BAAK,8CAAL,WAAuB,aAAa;AACpC,0BAAK,yCAAL,WAAkB,aAAa;AAC/B,0BAAK,yCAAL,WAAkB,aAAa;AAAA,EACjC,CAAC;AACH;AAEA,iCAA4B,SAAC,aAAqB,gBAAwB;AACxE,QAAM,oBAAoB,mBAAK,MAAK,aAAa,WAAW,IAAI,cAAc;AAC9E,QAAM,UAAU,mBAAK,MAAK,UAAU,UAAU,mBAAmB,OAAO;AACxE,QAAM,QAAQ,mBAAK,MAAK,UAAU,YAAY,cAAc;AAE5D,MAAI,CAAC,OAAO;AACV,uBAAK,SAAQ,KAAK;AAAA,MAChB,SAAS,kBAAkB,cAAc;AAAA,MACzC,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,iBAAiB;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,SAAS,CAAC,MAAM,UAAU,mBAAmB,OAAO,GAAG;AACzD,uBAAK,SAAQ,KAAK;AAAA,MAChB,SAAS,wBAAwB,mBAAmB,OAAO,oCAAoC,cAAc;AAAA,MAC7G,cAAc,uBAAuB,cAAc;AAAA,MACnD,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,iBAAiB,mBAAmB;AAAA,MACtC;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,CAAC,SAAS;AACZ,uBAAK,SAAQ,KAAK;AAAA,MAChB,SAAS,qCAAqC,mBAAmB,OAAO;AAAA,MACxE,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,iBAAiB,mBAAmB;AAAA,MACtC;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,6BAAwB,SAAC,aAAqB,gBAAwB;AACpE,QAAM,UAAU,mBAAK,MAAK,WAAW,WAAW;AAChD,QAAM,SAAiC,CAAC;AACxC,QAAM,oBAAoB,mBAAK,MAAK,WAAW,WAAW,EAAE,cAAc;AAC1E,QAAM,UAAU,mBAAK,MAAK,UAAU,UAAU,kBAAkB,OAAO;AACvE,QAAM,eAAW,wBAAU,SAAS,UAAU,OAAO;AAErD,MAAI,CAAC,SAAS,QAAQ,SAAS;AAC7B;AAAA,EACF;AAEA,SAAO,QAAQ,QAAQ,OAAO,OAAO,EAAE,QAAQ,CAAC,CAAC,aAAa,OAAO,MAAM;AACzE,QAAI,CAAC,SAAS;AACZ,yBAAK,SAAQ,KAAK;AAAA,QAChB,SAAS,YAAY,WAAW;AAAA,QAChC,cAAc,aAAa,WAAW,mBAAmB,WAAW;AAAA,QACpE,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,QAAQ;AAAA,UACN,iBAAiB;AAAA,QACnB;AAAA,MACF,CAAC;AACD;AAAA,IACF;AACA,UAAM,oBAAoB,SAAS,KAAK,CAAC,EAAE,KAAK,MAAM,SAAS,WAAW;AAC1E,QAAI,CAAC,mBAAmB;AACtB,yBAAK,SAAQ,KAAK;AAAA,QAChB,SAAS,YAAY,WAAW,6CAA6C,WAAW;AAAA,QACxF,cAAc,qBAAqB,kBAAkB,OAAO;AAAA,QAC5D,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,QAAQ;AAAA,UACN,iBAAiB;AAAA,QACnB;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,UAAM,QAAQ,OAAO,QAAQ,KAAK;AAClC,UAAM,aAAa,OAAO,KAAK;AAE/B,QAAI,cAAc,CAAC,QAAQ,OAAO;AAChC,yBAAK,SAAQ,KAAK;AAAA,QAChB,SAAS;AAAA,QACT,cAAc,aAAa,WAAW,mBAAmB,WAAW;AAAA,QACpE,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,QAAQ;AAAA,UACN,WAAW;AAAA,QACb;AAAA,MACF,CAAC;AAAA,IACH;AACA,QAAI,cAAc,QAAQ,OAAO;AAC/B,yBAAK,SAAQ,KAAK;AAAA,QAChB,SAAS,UAAU,KAAK,+BAA+B,UAAU;AAAA,QACjE,cAAc,aAAa,WAAW,mBAAmB,WAAW;AAAA,QACpE,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,QAAQ;AAAA,UACN,WAAW;AAAA,QACb;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO,KAAK,IAAI;AAAA,EAClB,CAAC;AACH;AAEA,sBAAiB,SAAC,aAAqB,gBAAwB;AAC7D,QAAM,UAAU,mBAAK,MAAK,WAAW,WAAW;AAChD,QAAM,oBAAoB,mBAAK,MAAK,WAAW,WAAW,EAAE,cAAc;AAC1E,QAAM,UAAU,mBAAK,MAAK,UAAU,UAAU,kBAAkB,OAAO;AACvE,QAAM,eAAW,wBAAU,SAAS,UAAU,OAAO;AAErD,WAAS,QAAQ,CAAC,YAAY;AAC5B,UAAM,iBAAa,8BAAgB,QAAQ,YAAY,cAAkC,KAAK;AAE9F,QAAI,cAAc,CAAC,SAAS,QAAQ,UAAU,QAAQ,QAAQ,EAAE,GAAG,OAAO;AACxE,yBAAK,SAAQ,KAAK;AAAA,QAChB,SAAS,uBAAuB,QAAQ,QAAQ,SAAS,wCAAwC,WAAW,mBAAmB,QAAQ,QAAQ,SAAS;AAAA,QACxJ,cAAc,aAAa,WAAW,mBAAmB,QAAQ,QAAQ,SAAS;AAAA,QAClF,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,QAAQ;AAAA,UACN,iBAAiB;AAAA,QACnB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AACH;AAEA,iBAAY,SAAC,aAAqB,gBAAwB;AACxD,QAAM,aAAa,mBAAK,MAAK,WAAW,WAAW;AACnD,QAAM,UAAU,mBAAK,MAAK,UAAU,UAAU,WAAW,cAAc,GAAG,OAAO;AACjF,QAAM,MAAM,SAAS,UAAU;AAC/B,MAAI,CAAC,IAAK;AAEV,QAAM,WAAW,IAAI,UAAU,UAAa,IAAI,UAAU;AAC1D,QAAM,gBAAgB,OAAO,IAAI,eAAe;AAChD,QAAM,YAAY,iBAAiB,OAAO,IAAI,YAAY,WAAW;AAErE,QAAM,UAAU,WAAW,cAAc,GAAG;AAC5C,QAAM,UAAU,qBAAqB,OAAO;AAE5C,MAAI,CAAC,YAAY,eAAe;AAC9B,uBAAK,SAAQ,KAAK;AAAA,MAChB,SAAS;AAAA,MACT,cAAc,GAAG,OAAO;AAAA,MACxB,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,oBAAoB;AAAA,MACtB;AAAA,IACF,CAAC;AAAA,EACH;AACA,MAAI,YAAY,CAAC,eAAe;AAC9B,uBAAK,SAAQ,KAAK;AAAA,MAChB,SAAS;AAAA,MACT,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,iBAAiB;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACH;AACA,MAAI,YAAY,CAAC,WAAW;AAC1B,uBAAK,SAAQ,KAAK;AAAA,MAChB,SAAS;AAAA,MACT,cAAc,GAAG,OAAO;AAAA,MACxB,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,iBAAiB;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAAA;AAAA;AAAA;AAAA;AAMA,iBAAY,SAAC,aAAqB,gBAAwB;AACxD,QAAM,MAAM,mBAAK,MAAK,WAAW,WAAW,GAAG,QAAQ;AACvD,MAAI,QAAQ,UAAW;AAEvB,QAAM,UAAU,mBAAK,MAAK,WAAW,WAAW,IAAI,cAAc,GAAG;AACrE,QAAM,MAAM,mBAAK,MAAK,UAAU,UAAU,OAAO,GAAG,UAAU;AAC9D,QAAM,SAAS,KAAK,UAAU,UAAa,IAAI,UAAU;AAEzD,MAAI,CAAC,QAAQ;AACX,uBAAK,SAAQ,KAAK;AAAA,MAChB,SAAS,YAAY,WAAW;AAAA,MAChC,cAAc,aAAa,WAAW;AAAA,MACtC,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,iBAAiB;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,qBAAgB,SAAC,aAAqB;AACpC,qBAAK,MAAK,WAAW,WAAW,GAAG,QAAQ,QAAQ,CAAC,QAAQ,gBAAgB;AAC1E,UAAM,QAAQ,OAAO,OAAO,YAAY,KAAK;AAE7C,WAAO,IAAI,QAAQ,CAAC,IAAI,YAAY;AAClC,UAAI,GAAG,IAAI,QAAQ;AACjB,cAAM,SAAS,aAAa,WAAW,WAAW,WAAW,OAAO,OAAO;AAE3E,YAAI,CAAC,GAAG,QAAQ;AACd,6BAAK,SAAQ,KAAK;AAAA,YAChB,SAAS;AAAA,YACT,cAAc,GAAG,MAAM;AAAA,YACvB,YAAY;AAAA,YACZ,SAAS;AAAA,YACT,QAAQ;AAAA,cACN,cAAc;AAAA,YAChB;AAAA,UACF,CAAC;AAAA,QACH;AACA,YAAI,CAAC,mBAAK,MAAK,YAAY,GAAG,EAAE,GAAG;AACjC,6BAAK,SAAQ,KAAK;AAAA,YAChB,SAAS,qBAAqB,GAAG,EAAE,kBAAkB,WAAW;AAAA,YAChE,cAAc,cAAc,GAAG,EAAE;AAAA,YACjC,YAAY;AAAA,YACZ,SAAS;AAAA,YACT,QAAQ;AAAA,cACN,iBAAiB,GAAG;AAAA,YACtB;AAAA,UACF,CAAC;AAAA,QACH;AAEA,2BAAK,gBAAe,IAAI,GAAG,EAAE;AAE7B,cAAM,eAAe,OAAO,MAAM,OAAO;AACzC,cAAM,UAAU,GAAG,GAAG,EAAE,IAAI,YAAY,IAAI,KAAK;AACjD,cAAM,mBAAmB,mBAAK,YAAW,IAAI,OAAO;AAEpD,YAAI,mBAAK,YAAW,IAAI,OAAO,GAAG;AAChC,6BAAK,SAAQ,KAAK;AAAA,YAChB,SAAS,gBAAgB,GAAG,EAAE,UAAU,YAAY,aAAa,KAAK,+BAA+B,gBAAgB;AAAA,YACrH,cAAc,GAAG,MAAM;AAAA,YACvB,YAAY;AAAA,YACZ,SAAS;AAAA,YACT,QAAQ;AAAA,cACN,WAAW;AAAA,YACb;AAAA,UACF,CAAC;AAAA,QACH;AACA,2BAAK,YAAW,IAAI,SAAS,WAAW;AAAA,MAC1C;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;AAEA,uBAAkB,WAAG;AACnB,MAAI,CAAC,mBAAK,MAAK,UAAW;AAE1B,SAAO,KAAK,mBAAK,MAAK,SAAS,EAAE,QAAQ,CAAC,aAAa;AACrD,QAAI,CAAC,mBAAK,gBAAe,IAAI,QAAQ,GAAG;AACtC,yBAAK,SAAQ,KAAK;AAAA,QAChB,SAAS,aAAa,QAAQ;AAAA,QAC9B,cAAc,cAAc,QAAQ;AAAA,QACpC,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,QAAQ;AAAA,UACN,oBAAoB;AAAA,QACtB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AACH;",
6
6
  "names": ["validationSDLSchema", "validateSDLInput", "validationSDLSchema"]
7
7
  }
@@ -53,7 +53,7 @@ var require_ucs2length = __commonJS({
53
53
  });
54
54
  var validate = validate27;
55
55
  var stdin_default = validate27;
56
- var schema28 = { "$schema": "http://json-schema.org/draft-07/schema#", "additionalProperties": false, "description": "Schema for Akash Stack Definition Language (SDL) YAML input files.\n\nNote: This schema validates structure only. Semantic validations (cross-references,\nunused endpoints, profile references, etc.) are performed at runtime by the Go parser.\nSee README.md for details.\n", "definitions": { "stringArrayOrNull": { "description": "String array or null value (used for command args and env vars)", "oneOf": [{ "items": { "type": "string" }, "type": "array" }, { "type": "null" }] }, "portNumber": { "description": "Valid TCP/UDP port number (1-65535)", "type": "integer", "minimum": 1, "maximum": 65535 }, "httpErrorCode": { "description": "HTTP error codes for proxy retry logic", "enum": ["error", "timeout", "500", "502", "503", "504", "403", "404", "429", "off"], "type": "string" }, "priceCoin": { "description": "Price definition with amount and denomination", "additionalProperties": false, "properties": { "amount": { "oneOf": [{ "type": "string", "pattern": "^[0-9]+(\\.[0-9]+)?$", "description": "Positive number as string" }, { "type": "number", "minimum": 0, "description": "Positive number" }] }, "denom": { "enum": ["uakt", "uact"], "type": "string" } }, "required": ["denom", "amount"], "type": "object" }, "storageRamClassMustNotBePersistent": { "description": "RAM storage class must not have persistent=true", "not": { "properties": { "class": { "const": "ram" }, "persistent": { "oneOf": [{ "const": true }, { "const": "true" }] } }, "required": ["class", "persistent"] } }, "storageNonRamClassRequiresPersistent": { "description": "Non-RAM storage classes (beta1, beta2, beta3, default) require persistent=true", "if": { "properties": { "class": { "enum": ["beta1", "beta2", "beta3", "default"] } }, "required": ["class"] }, "then": { "properties": { "persistent": { "oneOf": [{ "const": true }, { "const": "true" }] } }, "required": ["persistent"] } }, "storageAttributesValidation": { "description": "Storage attributes validation:\n1. RAM class must not be persistent\n2. Non-RAM classes (beta1, beta2, beta3, default) require persistent=true\n", "additionalProperties": false, "properties": { "class": { "type": "string" }, "persistent": { "oneOf": [{ "type": "boolean" }, { "type": "string" }] } }, "allOf": [{ "$ref": "#/definitions/storageRamClassMustNotBePersistent" }, { "$ref": "#/definitions/storageNonRamClassRequiresPersistent" }], "required": ["class", "persistent"], "type": "object" }, "storageVolume": { "description": "Storage volume definition with size and optional attributes", "additionalProperties": false, "properties": { "attributes": { "$ref": "#/definitions/storageAttributesValidation" }, "name": { "type": "string" }, "size": { "type": "string" } }, "required": ["size"], "type": "object" }, "absolutePath": { "description": "Absolute filesystem path starting with /", "type": "string", "minLength": 1, "pattern": "^/" }, "gpuUnitsGt0RequiresAttributes": { "description": "GPU units > 0 requires attributes to be present", "if": { "properties": { "units": { "oneOf": [{ "type": "number", "exclusiveMinimum": 0 }, { "type": "string", "not": { "pattern": "^0+(\\.0+)?$" } }] } }, "required": ["units"] }, "then": { "required": ["attributes"] } }, "gpuAttributesRequireUnitsGt0": { "description": "GPU attributes present requires units > 0", "if": { "required": ["attributes"] }, "then": { "properties": { "units": { "oneOf": [{ "type": "number", "exclusiveMinimum": 0 }, { "type": "string", "not": { "pattern": "^0+(\\.0+)?$" } }] } }, "required": ["units"] } }, "exposeToWithIpEnforcesGlobal": { "description": "Expose to with IP enforces global", "if": { "properties": { "ip": { "type": "string", "minLength": 1 } }, "required": ["ip"] }, "then": { "properties": { "global": { "const": true } }, "required": ["global"] } } }, "properties": { "deployment": { "additionalProperties": { "additionalProperties": { "additionalProperties": false, "properties": { "count": { "minimum": 1, "type": "integer" }, "profile": { "type": "string" } }, "required": ["profile", "count"], "type": "object" }, "type": "object" }, "type": "object" }, "endpoints": { "additionalProperties": false, "patternProperties": { "^[a-z]+[-_0-9a-z]+$": { "additionalProperties": false, "properties": { "kind": { "enum": ["ip"], "type": "string" } }, "required": ["kind"], "type": "object" } }, "type": "object" }, "include": { "description": "Optional list of files to include", "items": { "type": "string" }, "type": "array" }, "profiles": { "additionalProperties": false, "properties": { "compute": { "additionalProperties": { "additionalProperties": false, "properties": { "resources": { "additionalProperties": false, "properties": { "cpu": { "additionalProperties": false, "properties": { "attributes": { "type": "object" }, "units": { "oneOf": [{ "type": "string", "pattern": "^[0-9]+(\\.[0-9]+)?[a-zA-Z]*$", "not": { "pattern": "^0+(\\.0+)?m?$" } }, { "type": "number", "exclusiveMinimum": 0 }] } }, "required": ["units"], "type": "object" }, "gpu": { "description": "GPU resource specification.\n- units defaults to 0 if omitted\n- Bidirectional validation: units > 0 requires attributes, and attributes require units > 0\n", "additionalProperties": false, "properties": { "attributes": { "additionalProperties": false, "properties": { "vendor": { "additionalProperties": false, "minProperties": 1, "properties": { "nvidia": { "oneOf": [{ "type": "array", "items": { "additionalProperties": false, "properties": { "interface": { "enum": ["pcie", "sxm"], "type": "string" }, "model": { "type": "string" }, "ram": { "type": "string" } }, "type": "object" } }, { "type": "null" }] } }, "type": "object" } }, "type": "object" }, "units": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "allOf": [{ "$ref": "#/definitions/gpuUnitsGt0RequiresAttributes" }, { "$ref": "#/definitions/gpuAttributesRequireUnitsGt0" }], "type": "object" }, "memory": { "additionalProperties": false, "properties": { "size": { "type": "string" } }, "required": ["size"], "type": "object" }, "storage": { "oneOf": [{ "$ref": "#/definitions/storageVolume" }, { "items": { "$ref": "#/definitions/storageVolume" }, "type": "array" }] } }, "required": ["cpu", "memory", "storage"], "type": "object" } }, "required": ["resources"], "type": "object" }, "type": "object" }, "placement": { "additionalProperties": { "additionalProperties": false, "properties": { "attributes": { "type": "object" }, "pricing": { "additionalProperties": { "$ref": "#/definitions/priceCoin" }, "type": "object" }, "signedBy": { "additionalProperties": false, "properties": { "allOf": { "items": { "type": "string" }, "type": "array" }, "anyOf": { "items": { "type": "string" }, "type": "array" } }, "type": "object" } }, "required": ["pricing"], "type": "object" }, "type": "object" } }, "required": ["compute", "placement"], "type": "object" }, "services": { "additionalProperties": { "properties": { "args": { "$ref": "#/definitions/stringArrayOrNull" }, "command": { "$ref": "#/definitions/stringArrayOrNull" }, "credentials": { "additionalProperties": false, "properties": { "email": { "type": "string", "minLength": 5 }, "host": { "type": "string", "minLength": 1 }, "password": { "type": "string", "minLength": 6 }, "username": { "type": "string", "minLength": 1 } }, "required": ["host", "username", "password"], "type": "object" }, "dependencies": { "items": { "additionalProperties": false, "properties": { "service": { "type": "string" } }, "type": "object" }, "type": "array" }, "env": { "$ref": "#/definitions/stringArrayOrNull" }, "expose": { "oneOf": [{ "type": "array", "items": { "additionalProperties": false, "properties": { "accept": { "items": { "type": "string" }, "type": "array" }, "as": { "$ref": "#/definitions/portNumber" }, "http_options": { "additionalProperties": false, "properties": { "max_body_size": { "type": "integer", "minimum": 0, "maximum": 104857600, "description": "Maximum body size in bytes (max 100 MB)" }, "next_cases": { "oneOf": [{ "type": "array", "items": { "$ref": "#/definitions/httpErrorCode" }, "contains": { "const": "off" }, "maxItems": 1, "minItems": 1 }, { "type": "array", "items": { "$ref": "#/definitions/httpErrorCode" }, "not": { "contains": { "const": "off" } } }] }, "next_timeout": { "type": "integer", "minimum": 0 }, "next_tries": { "type": "integer", "minimum": 0 }, "read_timeout": { "type": "integer", "minimum": 0, "maximum": 6e4, "description": "Read timeout in milliseconds (max 60 seconds)" }, "send_timeout": { "type": "integer", "minimum": 0, "maximum": 6e4, "description": "Send timeout in milliseconds (max 60 seconds)" } }, "type": "object" }, "port": { "$ref": "#/definitions/portNumber" }, "proto": { "enum": ["TCP", "UDP", "tcp", "udp"], "type": "string" }, "to": { "items": { "additionalProperties": false, "properties": { "global": { "type": "boolean" }, "ip": { "minLength": 1, "type": "string" }, "service": { "type": "string" } }, "allOf": [{ "$ref": "#/definitions/exposeToWithIpEnforcesGlobal" }], "type": "object" }, "type": "array" } }, "required": ["port"], "type": "object" } }, { "type": "null" }] }, "image": { "type": "string", "minLength": 1 }, "params": { "additionalProperties": false, "properties": { "storage": { "additionalProperties": { "additionalProperties": false, "properties": { "mount": { "$ref": "#/definitions/absolutePath" }, "readOnly": { "type": "boolean" } }, "type": "object" }, "type": "object" }, "permissions": { "additionalProperties": false, "properties": { "read": { "items": { "type": "string", "enum": ["deployment", "logs", "events"] }, "type": "array" } }, "type": "object" } }, "type": "object" } }, "required": ["image"], "type": "object", "additionalProperties": false }, "type": "object" }, "reclamation": { "description": "Deployment-level reclamation requirements (optional). When set, providers must offer a reclamation window meeting or exceeding the specified minimum to bid on this deployment.", "additionalProperties": false, "properties": { "min_window": { "type": "string", "pattern": "^[1-9][0-9]*(s|m|h)$", "description": 'Minimum reclamation window the tenant requires, as a whole number followed by a unit (s, m, or h). E.g. "1h", "24h", "720h".' } }, "required": ["min_window"], "type": "object" }, "version": { "description": "SDL version", "enum": ["2.0", "2.1"], "type": "string" } }, "required": ["version", "services", "profiles", "deployment"], "title": "Akash SDL Input Schema", "type": "object" };
56
+ var schema28 = { "$schema": "http://json-schema.org/draft-07/schema#", "additionalProperties": false, "description": "Schema for Akash Stack Definition Language (SDL) YAML input files.\n\nNote: This schema validates structure only. Semantic validations (cross-references,\nunused endpoints, profile references, etc.) are performed at runtime by the Go parser.\nSee README.md for details.\n", "definitions": { "stringArrayOrNull": { "description": "String array or null value (used for command args and env vars)", "oneOf": [{ "items": { "type": "string" }, "type": "array" }, { "type": "null" }] }, "portNumber": { "description": "Valid TCP/UDP port number (1-65535)", "type": "integer", "minimum": 1, "maximum": 65535 }, "httpErrorCode": { "description": "HTTP error codes for proxy retry logic", "enum": ["error", "timeout", "500", "502", "503", "504", "403", "404", "429", "off"], "type": "string" }, "priceCoin": { "description": "Price definition with amount and denomination", "additionalProperties": false, "properties": { "amount": { "oneOf": [{ "type": "string", "pattern": "^[0-9]+(\\.[0-9]+)?$", "description": "Positive number as string" }, { "type": "number", "minimum": 0, "description": "Positive number" }] }, "denom": { "enum": ["uakt", "uact"], "type": "string" } }, "required": ["denom", "amount"], "type": "object" }, "storageRamClassMustNotBePersistent": { "description": "RAM storage class must not have persistent=true", "not": { "properties": { "class": { "const": "ram" }, "persistent": { "oneOf": [{ "const": true }, { "const": "true" }] } }, "required": ["class", "persistent"] } }, "storageNonRamClassRequiresPersistent": { "description": "Non-RAM storage classes (beta1, beta2, beta3, default) require persistent=true", "if": { "properties": { "class": { "enum": ["beta1", "beta2", "beta3", "default"] } }, "required": ["class"] }, "then": { "properties": { "persistent": { "oneOf": [{ "const": true }, { "const": "true" }] } }, "required": ["persistent"] } }, "storageAttributesValidation": { "description": "Storage attributes validation:\n1. RAM class must not be persistent\n2. Non-RAM classes (beta1, beta2, beta3, default) require persistent=true\n", "additionalProperties": false, "properties": { "class": { "type": "string" }, "persistent": { "oneOf": [{ "type": "boolean" }, { "type": "string" }] } }, "allOf": [{ "$ref": "#/definitions/storageRamClassMustNotBePersistent" }, { "$ref": "#/definitions/storageNonRamClassRequiresPersistent" }], "required": ["class", "persistent"], "type": "object" }, "storageVolume": { "description": "Storage volume definition with size and optional attributes", "additionalProperties": false, "properties": { "attributes": { "$ref": "#/definitions/storageAttributesValidation" }, "name": { "type": "string" }, "size": { "type": "string" } }, "required": ["size"], "type": "object" }, "absolutePath": { "description": "Absolute filesystem path starting with /", "type": "string", "minLength": 1, "pattern": "^/" }, "gpuUnitsGt0RequiresAttributes": { "description": "GPU units > 0 requires attributes to be present", "if": { "properties": { "units": { "oneOf": [{ "type": "number", "exclusiveMinimum": 0 }, { "type": "string", "not": { "pattern": "^0+(\\.0+)?$" } }] } }, "required": ["units"] }, "then": { "required": ["attributes"] } }, "gpuAttributesRequireUnitsGt0": { "description": "GPU attributes present requires units > 0", "if": { "required": ["attributes"] }, "then": { "properties": { "units": { "oneOf": [{ "type": "number", "exclusiveMinimum": 0 }, { "type": "string", "not": { "pattern": "^0+(\\.0+)?$" } }] } }, "required": ["units"] } }, "exposeToWithIpEnforcesGlobal": { "description": "Expose to with IP enforces global", "if": { "properties": { "ip": { "type": "string", "minLength": 1 } }, "required": ["ip"] }, "then": { "properties": { "global": { "const": true } }, "required": ["global"] } } }, "properties": { "deployment": { "additionalProperties": { "additionalProperties": { "additionalProperties": false, "properties": { "count": { "minimum": 1, "type": "integer" }, "profile": { "type": "string" } }, "required": ["profile", "count"], "type": "object" }, "type": "object" }, "type": "object" }, "endpoints": { "additionalProperties": false, "patternProperties": { "^[a-z]+[-_0-9a-z]+$": { "additionalProperties": false, "properties": { "kind": { "enum": ["ip"], "type": "string" } }, "required": ["kind"], "type": "object" } }, "type": "object" }, "include": { "description": "Optional list of files to include", "items": { "type": "string" }, "type": "array" }, "profiles": { "additionalProperties": false, "properties": { "compute": { "additionalProperties": { "additionalProperties": false, "properties": { "resources": { "additionalProperties": false, "properties": { "cpu": { "additionalProperties": false, "properties": { "attributes": { "type": "object" }, "units": { "oneOf": [{ "type": "string", "pattern": "^[0-9]+(\\.[0-9]+)?[a-zA-Z]*$", "not": { "pattern": "^0+(\\.0+)?m?$" } }, { "type": "number", "exclusiveMinimum": 0 }] } }, "required": ["units"], "type": "object" }, "gpu": { "description": "GPU resource specification.\n- units defaults to 0 if omitted\n- Bidirectional validation: units > 0 requires attributes, and attributes require units > 0\n", "additionalProperties": false, "properties": { "attributes": { "additionalProperties": false, "properties": { "vendor": { "additionalProperties": false, "minProperties": 1, "properties": { "nvidia": { "oneOf": [{ "type": "array", "items": { "additionalProperties": false, "properties": { "interface": { "enum": ["pcie", "sxm"], "type": "string" }, "model": { "type": "string" }, "ram": { "type": "string" } }, "type": "object" } }, { "type": "null" }] } }, "type": "object" } }, "type": "object" }, "units": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "allOf": [{ "$ref": "#/definitions/gpuUnitsGt0RequiresAttributes" }, { "$ref": "#/definitions/gpuAttributesRequireUnitsGt0" }], "type": "object" }, "memory": { "additionalProperties": false, "properties": { "size": { "type": "string" } }, "required": ["size"], "type": "object" }, "storage": { "oneOf": [{ "$ref": "#/definitions/storageVolume" }, { "items": { "$ref": "#/definitions/storageVolume" }, "type": "array" }] } }, "required": ["cpu", "memory", "storage"], "type": "object" } }, "required": ["resources"], "type": "object" }, "type": "object" }, "placement": { "additionalProperties": { "additionalProperties": false, "properties": { "attributes": { "type": "object" }, "pricing": { "additionalProperties": { "$ref": "#/definitions/priceCoin" }, "type": "object" }, "signedBy": { "additionalProperties": false, "properties": { "allOf": { "items": { "type": "string" }, "type": "array" }, "anyOf": { "items": { "type": "string" }, "type": "array" } }, "type": "object" } }, "required": ["pricing"], "type": "object" }, "type": "object" } }, "required": ["compute", "placement"], "type": "object" }, "services": { "additionalProperties": { "properties": { "args": { "$ref": "#/definitions/stringArrayOrNull" }, "command": { "$ref": "#/definitions/stringArrayOrNull" }, "credentials": { "additionalProperties": false, "properties": { "email": { "type": "string", "minLength": 5 }, "host": { "type": "string", "minLength": 1 }, "password": { "type": "string", "minLength": 6 }, "username": { "type": "string", "minLength": 1 } }, "required": ["host", "username", "password"], "type": "object" }, "dependencies": { "items": { "additionalProperties": false, "properties": { "service": { "type": "string" } }, "type": "object" }, "type": "array" }, "env": { "$ref": "#/definitions/stringArrayOrNull" }, "expose": { "oneOf": [{ "type": "array", "items": { "additionalProperties": false, "properties": { "accept": { "items": { "type": "string" }, "type": "array" }, "as": { "$ref": "#/definitions/portNumber" }, "http_options": { "additionalProperties": false, "properties": { "max_body_size": { "type": "integer", "minimum": 0, "maximum": 104857600, "description": "Maximum body size in bytes (max 100 MB)" }, "next_cases": { "oneOf": [{ "type": "array", "items": { "$ref": "#/definitions/httpErrorCode" }, "contains": { "const": "off" }, "maxItems": 1, "minItems": 1 }, { "type": "array", "items": { "$ref": "#/definitions/httpErrorCode" }, "not": { "contains": { "const": "off" } } }] }, "next_timeout": { "type": "integer", "minimum": 0 }, "next_tries": { "type": "integer", "minimum": 0 }, "read_timeout": { "type": "integer", "minimum": 0, "maximum": 6e4, "description": "Read timeout in milliseconds (max 60 seconds)" }, "send_timeout": { "type": "integer", "minimum": 0, "maximum": 6e4, "description": "Send timeout in milliseconds (max 60 seconds)" } }, "type": "object" }, "port": { "$ref": "#/definitions/portNumber" }, "proto": { "enum": ["TCP", "UDP", "tcp", "udp"], "type": "string" }, "to": { "items": { "additionalProperties": false, "properties": { "global": { "type": "boolean" }, "ip": { "minLength": 1, "type": "string" }, "service": { "type": "string" } }, "allOf": [{ "$ref": "#/definitions/exposeToWithIpEnforcesGlobal" }], "type": "object" }, "type": "array" } }, "required": ["port"], "type": "object" } }, { "type": "null" }] }, "image": { "type": "string", "minLength": 1 }, "params": { "additionalProperties": false, "properties": { "storage": { "additionalProperties": { "additionalProperties": false, "properties": { "mount": { "$ref": "#/definitions/absolutePath" }, "readOnly": { "type": "boolean" } }, "type": "object" }, "type": "object" }, "permissions": { "additionalProperties": false, "properties": { "read": { "items": { "type": "string", "enum": ["deployment", "logs", "events"] }, "type": "array" } }, "type": "object" }, "tee": { "type": "string", "enum": ["cpu", "cpu-gpu"] } }, "type": "object" } }, "required": ["image"], "type": "object", "additionalProperties": false }, "type": "object" }, "reclamation": { "description": "Deployment-level reclamation requirements (optional). When set, providers must offer a reclamation window meeting or exceeding the specified minimum to bid on this deployment.", "additionalProperties": false, "properties": { "min_window": { "type": "string", "pattern": "^[1-9][0-9]*(s|m|h)$", "description": 'Minimum reclamation window the tenant requires, as a whole number followed by a unit (s, m, or h). E.g. "1h", "24h", "720h".' } }, "required": ["min_window"], "type": "object" }, "version": { "description": "SDL version", "enum": ["2.0", "2.1"], "type": "string" } }, "required": ["version", "services", "profiles", "deployment"], "title": "Akash SDL Input Schema", "type": "object" };
57
57
  var schema35 = { "description": "Price definition with amount and denomination", "additionalProperties": false, "properties": { "amount": { "oneOf": [{ "type": "string", "pattern": "^[0-9]+(\\.[0-9]+)?$", "description": "Positive number as string" }, { "type": "number", "minimum": 0, "description": "Positive number" }] }, "denom": { "enum": ["uakt", "uact"], "type": "string" } }, "required": ["denom", "amount"], "type": "object" };
58
58
  var schema40 = { "description": "HTTP error codes for proxy retry logic", "enum": ["error", "timeout", "500", "502", "503", "504", "403", "404", "429", "off"], "type": "string" };
59
59
  var pattern4 = new RegExp("^[a-z]+[-_0-9a-z]+$", "u");
@@ -3207,7 +3207,7 @@ function validate27(data, { instancePath = "", parentData, parentDataProperty, r
3207
3207
  let data86 = data45.params;
3208
3208
  if (data86 && typeof data86 == "object" && !Array.isArray(data86)) {
3209
3209
  for (const key29 in data86) {
3210
- if (!(key29 === "storage" || key29 === "permissions")) {
3210
+ if (!(key29 === "storage" || key29 === "permissions" || key29 === "tee")) {
3211
3211
  const err204 = { instancePath: instancePath + "/services/" + key22.replace(/~/g, "~0").replace(/\//g, "~1") + "/params", schemaPath: "#/properties/services/additionalProperties/properties/params/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key29 }, message: "must NOT have additional properties" };
3212
3212
  if (vErrors === null) {
3213
3213
  vErrors = [err204];
@@ -3355,118 +3355,139 @@ function validate27(data, { instancePath = "", parentData, parentDataProperty, r
3355
3355
  errors++;
3356
3356
  }
3357
3357
  }
3358
+ if (data86.tee !== void 0) {
3359
+ let data94 = data86.tee;
3360
+ if (typeof data94 !== "string") {
3361
+ const err217 = { instancePath: instancePath + "/services/" + key22.replace(/~/g, "~0").replace(/\//g, "~1") + "/params/tee", schemaPath: "#/properties/services/additionalProperties/properties/params/properties/tee/type", keyword: "type", params: { type: "string" }, message: "must be string" };
3362
+ if (vErrors === null) {
3363
+ vErrors = [err217];
3364
+ } else {
3365
+ vErrors.push(err217);
3366
+ }
3367
+ errors++;
3368
+ }
3369
+ if (!(data94 === "cpu" || data94 === "cpu-gpu")) {
3370
+ const err218 = { instancePath: instancePath + "/services/" + key22.replace(/~/g, "~0").replace(/\//g, "~1") + "/params/tee", schemaPath: "#/properties/services/additionalProperties/properties/params/properties/tee/enum", keyword: "enum", params: { allowedValues: schema28.properties.services.additionalProperties.properties.params.properties.tee.enum }, message: "must be equal to one of the allowed values" };
3371
+ if (vErrors === null) {
3372
+ vErrors = [err218];
3373
+ } else {
3374
+ vErrors.push(err218);
3375
+ }
3376
+ errors++;
3377
+ }
3378
+ }
3358
3379
  } else {
3359
- const err217 = { instancePath: instancePath + "/services/" + key22.replace(/~/g, "~0").replace(/\//g, "~1") + "/params", schemaPath: "#/properties/services/additionalProperties/properties/params/type", keyword: "type", params: { type: "object" }, message: "must be object" };
3380
+ const err219 = { instancePath: instancePath + "/services/" + key22.replace(/~/g, "~0").replace(/\//g, "~1") + "/params", schemaPath: "#/properties/services/additionalProperties/properties/params/type", keyword: "type", params: { type: "object" }, message: "must be object" };
3360
3381
  if (vErrors === null) {
3361
- vErrors = [err217];
3382
+ vErrors = [err219];
3362
3383
  } else {
3363
- vErrors.push(err217);
3384
+ vErrors.push(err219);
3364
3385
  }
3365
3386
  errors++;
3366
3387
  }
3367
3388
  }
3368
3389
  } else {
3369
- const err218 = { instancePath: instancePath + "/services/" + key22.replace(/~/g, "~0").replace(/\//g, "~1"), schemaPath: "#/properties/services/additionalProperties/type", keyword: "type", params: { type: "object" }, message: "must be object" };
3390
+ const err220 = { instancePath: instancePath + "/services/" + key22.replace(/~/g, "~0").replace(/\//g, "~1"), schemaPath: "#/properties/services/additionalProperties/type", keyword: "type", params: { type: "object" }, message: "must be object" };
3370
3391
  if (vErrors === null) {
3371
- vErrors = [err218];
3392
+ vErrors = [err220];
3372
3393
  } else {
3373
- vErrors.push(err218);
3394
+ vErrors.push(err220);
3374
3395
  }
3375
3396
  errors++;
3376
3397
  }
3377
3398
  }
3378
3399
  } else {
3379
- const err219 = { instancePath: instancePath + "/services", schemaPath: "#/properties/services/type", keyword: "type", params: { type: "object" }, message: "must be object" };
3400
+ const err221 = { instancePath: instancePath + "/services", schemaPath: "#/properties/services/type", keyword: "type", params: { type: "object" }, message: "must be object" };
3380
3401
  if (vErrors === null) {
3381
- vErrors = [err219];
3402
+ vErrors = [err221];
3382
3403
  } else {
3383
- vErrors.push(err219);
3404
+ vErrors.push(err221);
3384
3405
  }
3385
3406
  errors++;
3386
3407
  }
3387
3408
  }
3388
3409
  if (data.reclamation !== void 0) {
3389
- let data94 = data.reclamation;
3390
- if (data94 && typeof data94 == "object" && !Array.isArray(data94)) {
3391
- if (data94.min_window === void 0) {
3392
- const err220 = { instancePath: instancePath + "/reclamation", schemaPath: "#/properties/reclamation/required", keyword: "required", params: { missingProperty: "min_window" }, message: "must have required property 'min_window'" };
3410
+ let data95 = data.reclamation;
3411
+ if (data95 && typeof data95 == "object" && !Array.isArray(data95)) {
3412
+ if (data95.min_window === void 0) {
3413
+ const err222 = { instancePath: instancePath + "/reclamation", schemaPath: "#/properties/reclamation/required", keyword: "required", params: { missingProperty: "min_window" }, message: "must have required property 'min_window'" };
3393
3414
  if (vErrors === null) {
3394
- vErrors = [err220];
3415
+ vErrors = [err222];
3395
3416
  } else {
3396
- vErrors.push(err220);
3417
+ vErrors.push(err222);
3397
3418
  }
3398
3419
  errors++;
3399
3420
  }
3400
- for (const key33 in data94) {
3421
+ for (const key33 in data95) {
3401
3422
  if (!(key33 === "min_window")) {
3402
- const err221 = { instancePath: instancePath + "/reclamation", schemaPath: "#/properties/reclamation/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key33 }, message: "must NOT have additional properties" };
3423
+ const err223 = { instancePath: instancePath + "/reclamation", schemaPath: "#/properties/reclamation/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key33 }, message: "must NOT have additional properties" };
3403
3424
  if (vErrors === null) {
3404
- vErrors = [err221];
3425
+ vErrors = [err223];
3405
3426
  } else {
3406
- vErrors.push(err221);
3427
+ vErrors.push(err223);
3407
3428
  }
3408
3429
  errors++;
3409
3430
  }
3410
3431
  }
3411
- if (data94.min_window !== void 0) {
3412
- let data95 = data94.min_window;
3413
- if (typeof data95 === "string") {
3414
- if (!pattern12.test(data95)) {
3415
- const err222 = { instancePath: instancePath + "/reclamation/min_window", schemaPath: "#/properties/reclamation/properties/min_window/pattern", keyword: "pattern", params: { pattern: "^[1-9][0-9]*(s|m|h)$" }, message: 'must match pattern "^[1-9][0-9]*(s|m|h)$"' };
3432
+ if (data95.min_window !== void 0) {
3433
+ let data96 = data95.min_window;
3434
+ if (typeof data96 === "string") {
3435
+ if (!pattern12.test(data96)) {
3436
+ const err224 = { instancePath: instancePath + "/reclamation/min_window", schemaPath: "#/properties/reclamation/properties/min_window/pattern", keyword: "pattern", params: { pattern: "^[1-9][0-9]*(s|m|h)$" }, message: 'must match pattern "^[1-9][0-9]*(s|m|h)$"' };
3416
3437
  if (vErrors === null) {
3417
- vErrors = [err222];
3438
+ vErrors = [err224];
3418
3439
  } else {
3419
- vErrors.push(err222);
3440
+ vErrors.push(err224);
3420
3441
  }
3421
3442
  errors++;
3422
3443
  }
3423
3444
  } else {
3424
- const err223 = { instancePath: instancePath + "/reclamation/min_window", schemaPath: "#/properties/reclamation/properties/min_window/type", keyword: "type", params: { type: "string" }, message: "must be string" };
3445
+ const err225 = { instancePath: instancePath + "/reclamation/min_window", schemaPath: "#/properties/reclamation/properties/min_window/type", keyword: "type", params: { type: "string" }, message: "must be string" };
3425
3446
  if (vErrors === null) {
3426
- vErrors = [err223];
3447
+ vErrors = [err225];
3427
3448
  } else {
3428
- vErrors.push(err223);
3449
+ vErrors.push(err225);
3429
3450
  }
3430
3451
  errors++;
3431
3452
  }
3432
3453
  }
3433
3454
  } else {
3434
- const err224 = { instancePath: instancePath + "/reclamation", schemaPath: "#/properties/reclamation/type", keyword: "type", params: { type: "object" }, message: "must be object" };
3455
+ const err226 = { instancePath: instancePath + "/reclamation", schemaPath: "#/properties/reclamation/type", keyword: "type", params: { type: "object" }, message: "must be object" };
3435
3456
  if (vErrors === null) {
3436
- vErrors = [err224];
3457
+ vErrors = [err226];
3437
3458
  } else {
3438
- vErrors.push(err224);
3459
+ vErrors.push(err226);
3439
3460
  }
3440
3461
  errors++;
3441
3462
  }
3442
3463
  }
3443
3464
  if (data.version !== void 0) {
3444
- let data96 = data.version;
3445
- if (typeof data96 !== "string") {
3446
- const err225 = { instancePath: instancePath + "/version", schemaPath: "#/properties/version/type", keyword: "type", params: { type: "string" }, message: "must be string" };
3465
+ let data97 = data.version;
3466
+ if (typeof data97 !== "string") {
3467
+ const err227 = { instancePath: instancePath + "/version", schemaPath: "#/properties/version/type", keyword: "type", params: { type: "string" }, message: "must be string" };
3447
3468
  if (vErrors === null) {
3448
- vErrors = [err225];
3469
+ vErrors = [err227];
3449
3470
  } else {
3450
- vErrors.push(err225);
3471
+ vErrors.push(err227);
3451
3472
  }
3452
3473
  errors++;
3453
3474
  }
3454
- if (!(data96 === "2.0" || data96 === "2.1")) {
3455
- const err226 = { instancePath: instancePath + "/version", schemaPath: "#/properties/version/enum", keyword: "enum", params: { allowedValues: schema28.properties.version.enum }, message: "must be equal to one of the allowed values" };
3475
+ if (!(data97 === "2.0" || data97 === "2.1")) {
3476
+ const err228 = { instancePath: instancePath + "/version", schemaPath: "#/properties/version/enum", keyword: "enum", params: { allowedValues: schema28.properties.version.enum }, message: "must be equal to one of the allowed values" };
3456
3477
  if (vErrors === null) {
3457
- vErrors = [err226];
3478
+ vErrors = [err228];
3458
3479
  } else {
3459
- vErrors.push(err226);
3480
+ vErrors.push(err228);
3460
3481
  }
3461
3482
  errors++;
3462
3483
  }
3463
3484
  }
3464
3485
  } else {
3465
- const err227 = { instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" };
3486
+ const err229 = { instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" };
3466
3487
  if (vErrors === null) {
3467
- vErrors = [err227];
3488
+ vErrors = [err229];
3468
3489
  } else {
3469
- vErrors.push(err227);
3490
+ vErrors.push(err229);
3470
3491
  }
3471
3492
  errors++;
3472
3493
  }